Programming

git-merge가 줄 끝 차이점을 무시할 수 있습니까?

procodes 2020. 6. 16. 22:51
반응형

git-merge가 줄 끝 차이점을 무시할 수 있습니까?


git merge줄 끝의 차이점을 무시할 있습니까?

어쩌면 나는 잘못된 질문을하고 있습니다 ...하지만 :

나는 uisng을 시도 config.crlf input했지만 특히 사실 이후에 적용했을 때 상황이 약간 지저분하고 통제 불능 상태가 되었습니다 .

사실, 사실 이후에이 구성을 적용해도이 옵션을 적용하기 전에 리포지토리에 커밋 된 파일에는 영향을 미치지 않는 것 같습니다. 또 다른 것은 갑자기 모든 커밋이 CRLF가 LF로 변환되는 것에 대한 많은 성가신 경고 메시지를 초래한다는 것입니다.

솔직히 말해서 어떤 줄 끝이 사용되는지는 신경 쓰지 않고 개인적으로 유닉스 스타일을 선호 \n하지만 무엇이든간에 선호합니다 . 내가 걱정 git merge하는 것은 조금 더 똑똑하고 줄 끝의 차이점을 무시하는 것입니다.

때로는 두 개의 동일한 파일이 있지만 git은 단순히 다른 줄 끝 문자를 사용하기 때문에 충돌하는 것으로 표시합니다 (그리고 충돌은 전체 파일입니다).

최신 정보:

옵션 git diff허용 한다는 것을 알았습니다. 이 옵션도 사용할 --ignore-space-at-eolgit merge있습니까?


2013 년 업데이트 :

최신 git 버전은 전략 recursive및 전략 옵션 ( -X) 병합을 사용하여 권한을 부여합니다 .

git merge -s 재귀 -Xignore-space-at-eol

하지만 " -Xignore-space-change"를 사용 하는 것도 가능합니다


jakub.g 또한 코멘트 한다는 전략 체리 따기와도 작동 :

git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize 

이보다 훨씬 잘 작동합니다 ignore-all-space.


원래 답변 (2009 년 5 월)

eol 스타일을 무시하기위한 패치는 2007 년 6 월 에 제안 되었지만 git diff --ignore-space-at-eol, 그다지 중요 하지는 않습니다 git merge.

당시 질문이 제기되었습니다.

해야 --ignore-space-at-eol하는 옵션이 될 git-merge?
병합은이 기능이 중요한 부분입니다.
자동 해결 병합의 의미는 실제로 해당 옵션과 함께 적용됩니다. 이름 바꾸기 감지에만 사용됩니까, 아니면 공백 변경만으로 플래그 충돌이 발생하지 않습니까? 그렇지 않으면 어떤 버전을 자동으로 수락합니까?

Julio C Hamano는 정확히 열광적이지 않았습니다.

확실히 유혹적이지만, 나중의 라운드로 가야한다고 생각합니다.
나는 두 가지 다른 종류의 diff의 개념을 도입 할 것으로 의심됩니다. 하나는 기계적으로 처리되어야합니다 (즉, "git-merge-recursive"와의 병합에 사용하고 "git-am"과 함께 적용). 인간은 이해합니다.
Munged 입력 파일을 비교 한 결과를 기계 적용에 쉽게 사용할 수는 없지만 후자의 경우 입력을 조정하는 것이 종종 유용 할 수 있습니다.

일반적인 아이디어 git merge는 타사 병합 도구를 사용하는 것입니다.

예를 들어, DiffMerge 를 Git 병합 도구로 설정하여 해당 병합 도구가 특정 유형의 파일에 대한 eol을 무시하도록 규칙 세트설정했습니다 .


DysMerge 또는 KDiff3을 사용하여 DOS 또는 Git bash 세션에 대해 MSysGit1.6.3을 사용하여 Windows에서 설정 :

  • 디렉토리를 PATH에 설정하십시오 (여기 :) c:\HOMEWARE\cmd.
  • 해당 디렉토리에 스크립트 merge.sh (좋아하는 병합 도구의 래퍼)를 추가하십시오.

merge.sh :

#!/bin/sh

# Passing the following parameters to mergetool:
#  local base remote merge_result

alocal=$1
base=$2
remote=$3
result=$4

if [ -f $base ]
then
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$base" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # for merge respecting eol, KDiff3 is better than DiffMerge (which will always convert LF into CRLF)
    # KDiff3 will display eol choices (if Windows: CRLF, if Unix LF)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$alocal" "$remote" -o "$result"
else
    #there is not always a common ancestor: DiffMerge needing 3 files, BASE will be the result
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$result" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # KDiff3 however does know how to merge based on 2 files (not just 3)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$remote" -o "$result"
fi
  • Git의 병합 래퍼 선언

힘내 설정 명령 :

git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd "merge.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\"
git config --global mergetool.diffmerge.trustExitCode false
git config --global mergetool.diffmerge.keepBackup false
  • autoCRLF가 false인지 확인하십시오.

시스템 레벨에서의 git config :

git config ---system core.autoCRLF=false
  • 두 줄이 동일하지만 eol 문자 인 경우 DiffMerge 또는 KDiff3은 병합 중에 해당 줄을 무시합니다.

DOS 스크립트 (참고 : dos2unix 명령은 here 이며 Unix eol 스타일을 시뮬레이션하는 데 사용됩니다.이 명령은이 답변의 시작 부분에 언급 된 디렉토리에 복사되었습니다.) :

C:\HOMEWARE\git\test>mkdir test_merge C:\HOMEWARE\git\test>cd test_merge C:\HOMEWARE\git\test\test_merge>git init C:\HOMEWARE\git\test\test_merge>echo a1 > a.txt & echo a2 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "a.txt, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout -b windows Switched to a new branch 'windows' C:\HOMEWARE\git\test\test_merge>echo a3 >> a.txt & echo a4 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add two lines, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout master C:\HOMEWARE\git\test\test_merge>git checkout -b unix Switched to a new branch 'unix' C:\HOMEWARE\git\test\test_merge>echo au3 >> a.txt & echo au4 >> a.txt && echo au5 >> a.txt C:\HOMEWARE\git\test\test_merge>dos2unix a.txt Dos2Unix: Processing file a.txt ... C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add 3 lines, all file unix eol style" [unix c433a63] add 3 lines, all file unix eol style C:\HOMEWARE\git\test\test_merge>git merge windows Auto-merging a.txt CONFLICT (content): Merge conflict in a.txt Automatic merge failed; fix conflicts and then commit the result. C:\HOMEWARE\git\test\test_merge>git ls-files -u 100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1 a.txt 100644 28b3d018872c08b0696764118b76dd3d0b448fca 2 a.txt 100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3 a.txt C:\HOMEWARE\git\test\test_merge>git mergetool Merging the files: a.txt Normal merge conflict for 'a.txt': {local}: modified {remote}: modified Hit return to start merge resolution tool (diffmerge):

At this point (Hitting "return"), DiffMerge or KDiff3 will open, and you will see for yourself what lines are actually merged, and what lines are ignored.

Warning: the result file will always be in Windows eol mode (CRLF) with DiffMerge...
KDiff3 offers to save in one way or another.


I was looking for the same answer and I found out this

Merging branches with differing checkin/checkout attributes

If you have added attributes to a file that cause the canonical repository format for that file to change, such as adding a clean/smudge filter or text/eol/ident attributes, merging anything where the attribute is not in place would normally cause merge conflicts.

To prevent these unnecessary merge conflicts, git can be told to run a virtual check-out and check-in of all three stages of a file when resolving a three-way merge by setting the merge.renormalize configuration variable. This prevents changes caused by check-in conversion from causing spurious merge conflicts when a converted file is merged with an unconverted file.

As long as a "smudge→clean" results in the same output as a "clean" even on files that are already smudged, this strategy will automatically resolve all filter-related conflicts. Filters that do not act in this way may cause additional merge conflicts that must be resolved manually.

So running this command in any repository will do the trick:

git config merge.renormalize true

After reading https://stackoverflow.com/a/12194759/1441706 and https://stackoverflow.com/a/14195253/1441706

for me, this command did the trick perfectly:

git merge master -s recursive -X renormalize

As in this answer: https://stackoverflow.com/a/5262473/943928

You could try: git merge -s recursive -Xignore-space-at-eol


What I did was leave everything as default (i.e. autocrlf=true), touch all files (find . -exec touch {} \;), let git see them as 'modified' and commit them back, and be done with it. Otherwise you'll always either be plagued by annoying messages or surprising differences, or have to turn off all of git's whitespace features.

You'll lose blame information, but it's better to do it sooner rather than later :)


"git merge -Xrenormalize" works like a charm.


It doesn't look like this can be done directly but this post suggests a work around.

http://osdir.com/ml/git/2009-02/msg02532.html


http://stahlforce.com/dev/index.php?tool=remcrlf

I tried it, but if after the last line in your code you didn't already have CRLF it adds by itself a LF and the file looks changed in git. Other than that it works.


It seems to me now that the best way is to normalized the line endings on both branches (and commit) before merging them.

I googled "convert crlf to lf" and found this as the first results:
http://stahlforce.com/dev/index.php?tool=remcrlf

I downloaded it and used, seems like a nice tool.

>sfk remcr . .py

Be sure though to specify a directory and a file type (e.g. .py) otherwise it might try to mess with the contents of the .git directory!


AFAICT, (I haven't tried it) you could use git diff to compare the branch you want to merge to the common ancestor, then apply the results with git apply. Both commands have --ignore-whitespace options to ignore line ending and white space errors.

Unfortunately, if the patch doesn't apply cleanly, the whole operation is aborted. You can't fix merge conflicts. There is a --reject option to leave unpatchable hunks in .rej files, which helps, but isn't the same as having the merge conflicts shown in one file.


After reading Resolve merge conflicts: Force overwrite all files

I finally resolved my version of this issue. I was trying to pull updates from the upstream repo but my current one was having CRLF related issues and was unable to merge as result. It should be noted I had NO LOCAL CHANGES i needed to worry about. The following steps resolved my issue:

As per github's instructions on syncing forks (https://help.github.com/articles/syncing-a-fork/):

  1. git fetch upstream

  2. git reset --hard upstream/master
    My limited understanding of git tells me this is doing what i want-- rebasing my fork (with no actual uncommitted changes) to gain all the changes made to the upstream source. According to the source page, this step should normally not be required, but the CRLF issue made it required.

  3. git merge upstream/master

  4. git push

however i suggest to use tool like sed to achieve correct line endings, and then diff files. I spent couple hours on diffing projects with various line endings.

The best way was to:

  1. copy only project files (omit .git directory) to another directory create repository in it, then add files and commit them (should be on master branch in new repository).
  2. copy files from second project to same folder, but another branch for example dev (git checkout -b dev), commit files on this branch and run (if first project is in master): git diff master..dev --names-only to see names of changed files only

참고URL : https://stackoverflow.com/questions/861995/is-it-possible-for-git-merge-to-ignore-line-ending-differences

반응형