programing

git-merge가 줄바꿈 차이를 무시할 수 있습니까?

javamemo 2023. 7. 9. 09:32
반응형

git-merge가 줄바꿈 차이를 무시할 수 있습니까?

에 합니까?git merge줄 끝의 차이를 무시하는 것?

제가 질문을 잘못 한 것일 수도 있지만...

사용해 보았습니다.config.crlf input하지만 상황이 좀 엉망이 되고 통제할 수 없게 되었습니다. 특히 제가 사후에 그것을 적용했을 때 말이죠.

우선 이 구성을 적용한 후 이 옵션을 적용하기 전에 리포지토리에 커밋된 파일에 영향을 미치지 않는 것 같습니다.또 다른 것은 모든 커밋이 갑자기 CRLF가 LF로 변환된다는 성가신 경고 메시지가 많이 발생한다는 것입니다.

어떤 , 을 선호합니다. 저는 개인적으로 유닉스 스타일을 선호합니다.\n,뭐 아무렴.내가 신경쓰는건,git merge조금 더 똑똑해지고 선 끝의 차이를 무시하는 것.

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

업데이트:

는 그것을 되었습니다.git diff을 받아들입니다.--ignore-space-at-eol옵션, 허용할 수 있습니까?git merge이 옵션도 사용하시겠습니까?

2013년 업데이트:

strategy를 할 수 있습니다.recursive전략 옵션(-X):

하지만 "를 사용하는 것은-Xignore-space-change가능성도 있습니다.


jakub.g또한전략이 체리 소스에서도 작동한다고 언급합니다.

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

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


Git 2.29(2020년 4분기) 이전에는 내부적으로 병합-재귀적 기계를 사용하는 모든 "머지" 작업이 구성을 준수해야 했지만, 대부분은 그렇지 않았습니다.

커밋 00906d6, 커밋 8d55225, 커밋 6f6e7cf, 커밋 fe48efb(newren2020년 8월 3일) 참조.
(주니오 C 하마노에 의해 합병 -- -- 4339259, 2020년 8월 10일 커밋)

merge만듦merge.renormalize mechanics의 용도에 for all of merge mechanics.

사인 오프 바이: 엘리야 뉴렌

더'merge. 명령어로는 " 만명병것아닙다니이는합"가 있습니다. 다른 명령은 다음과 같습니다.checkout -m기본 재배치도 가능합니다.

유감스럽게도, 코드의 유일한 영역은 "에 대해 확인했습니다.merge.renormalize구성 설정은 에 있습니다. 즉, "에 의해 수행되는 병합에만 영향을 미칠 수 있습니다.merge지휘권

를 이구설처다이음동합니로 합니다.merge_recursive_config()다른 명령도 사용할 수 있습니다.


원답 (2009년 5월)

eol 스타일을 무시하는 패치는 2007년 6월에 제안되었지만, 그것은 단지 걱정입니다.git diff --ignore-space-at-eol,것은 아니다.git merge.

그 당시에 다음과 같은 질문이 제기되었습니다.

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

훌리오 C 하마노는 그다지 열성적이지 않았습니다.

이것은 확실히 유혹적이지만, 저는 그것이 나중에 진행될 것이라고 생각합니다.
저는 그것이 두 가지 다른 종류의 차이의 개념을 도입할 것이라고 생각합니다. 하나는 기계적으로 처리될 것이고(즉, "git-merge-recursive"와 병합하여 사용하고 "git-am"과 함께 적용), 다른 하나는 인간이 이해하기 위해 검사할 것입니다.
멍에가 있는 입력 파일을 비교한 결과 출력을 기계적 적용에 쉽게 사용할 수 없을 수도 있지만 후자의 경우에는 종종 멍에를 메우는 것이 유용할 수 있습니다.

은, ▁it,▁the,▁to.git merge타사 병합 도구에 의존합니다.

예를 들어, 나는 DiffMerge를 Git merge 도구가 특정 유형의 파일에 대해 eol을 무시할 수 있는 규칙 집합으로 설정했습니다.


MSysGit1.6.3을 사용하여 Windows에서 DiffMerge 또는 KDiff3를 사용하여 DOS 또는 Gitbash 세션 설정:

  • PATH에 합니다(여기서: "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 구성 명령:

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 구성:

git config ---system core.autoCRLF=false
  • 두 줄이 동일한 경우(단, eol 문자) DiffMerge 또는 KDiff3가 병합 중에 해당 줄을 무시하는지 테스트합니다.

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

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):

이때("반환"을 누르면) DiffMerge 또는 KDiff3가 열리고 실제로 병합되는 라인과 무시되는 라인을 직접 확인할 수 있습니다.

경고: 결과 파일은 항상 DiffMerge...를 사용하여 Windows eol 모드(CRLF)에 있게 됩니다.
KDIf3는 어떤 식으로든 저축을 제안합니다.

같은 답을 찾다가 이것을 알게 되었습니다.

체크인/체크아웃 특성이 다른 분기 병합

치료/스모그 필터 또는 텍스트/eol/ident 특성을 추가하는 것과 같이 해당 파일의 표준 리포지토리 형식을 변경하는 특성을 파일에 추가한 경우 일반적으로 해당 특성이 없는 곳을 병합하면 병합 충돌이 발생합니다.

이러한 불필요한 병합 충돌을 방지하기 위해 git는 merge.renormalize 구성 변수를 설정하여 3방향 병합을 해결할 때 파일의 세 단계 모두에 대한 가상 체크아웃 및 체크인을 실행하도록 지시할 수 있습니다.이렇게 하면 체크인 변환으로 인한 변경사항으로 인해 변환된 파일이 변환되지 않은 파일과 병합될 때 가상 병합 충돌이 발생하지 않습니다.

이미 스미지된 파일에서도 "스미지→정리"가 "정리"와 동일한 출력을 나타내는 한, 이 전략은 모든 필터 관련 충돌을 자동으로 해결합니다.이러한 방식으로 작동하지 않는 필터는 수동으로 해결해야 하는 추가 병합 충돌을 일으킬 수 있습니다.

따라서 저장소에서 이 명령을 실행하면 다음과 같은 이점이 있습니다.

git config merge.renormalize true

https://stackoverflow.com/a/12194759/1441706 https://stackoverflow.com/a/14195253/1441706 을 읽고 난 후에.

나에게, 이 명령은 완벽하게 트릭을 수행했습니다.

git merge master -s recursive -X renormalize

다음 답변과 같습니다. https://stackoverflow.com/a/5262473/943928

시도해 볼 수 있습니다.git merge -s recursive -Xignore-space-at-eol

제가 한 일은 모든 것을 기본값(예: autocolf=true)으로 유지하고 모든 파일을 터치(find . -exec touch {} \;)하고 '수정'으로 표시한 후 다시 커밋하고 완료하는 것이었습니다.그렇지 않으면 항상 성가신 메시지나 놀라운 차이로 인해 곤란을 겪거나 Git의 모든 공백 기능을 꺼야 합니다.

비난 정보를 잃게 되겠지만, 나중보다는 빨리 하는 것이 좋습니다 :)

"git merge-Xrenormalize"는 매력적으로 작동합니다.

이제 두 분기를 병합하기 전에 두 분기의 줄 끝을 정규화(및 커밋)하는 것이 가장 좋은 방법인 것 같습니다.

" 변환"을했더니 첫 번째 tolf"가 나왔습니다.
http://stahlforce.com/dev/index.php?tool=://stahlforce.com/dev/index.php?tool=remcrlf

제가 다운받아서 사용했는데, 좋은 도구인 것 같습니다.

>sfk remcr . .py

및 형식 .py "" " " " " " (" .py) " " " "의될 수 . 그렇지 않으면 파일의 내용을 엉망으로 만들 수 있습니다..git디렉토리!

(적이 AFAICT를 사용해도 .git diff병합할 분기를 공통 조상과 비교한 다음 결과를 적용합니다.git apply두 명령 모두 다음을 포함합니다.--ignore-whitespace줄 끝 및 공백 오류를 무시하는 옵션입니다.

패치가 제대로 적용되지 않으면 전체 작업이 중단됩니다.병합 충돌은 수정할 수 없습니다.이 .--reject가 적용되지 않는 를 패치할헝두옵에 남기는 .rej파일. 즉, 도움이 되지만 병합 충돌이 하나의 파일에 표시되는 것과 같지는 않습니다.

병합 충돌 해결을 읽은 후: 모든 파일 강제 덮어쓰기

저는 마침내 이 문제에 대한 제 버전을 해결했습니다.업스트림 레포에서 업데이트를 가져오려고 했지만 현재 레포에서 CRLF 관련 문제가 발생하여 병합할 수 없습니다.제가 걱정할 필요가 있는 지역적 변화는 없었다는 점에 유의해야 합니다.다음 단계를 통해 문제가 해결되었습니다.

포크 동기화에 대한 github의 지침에 따르면(https://help.github.com/articles/syncing-a-fork/) :

  1. git fetch upstream

  2. git reset --hard upstream/master
    Git에 대한 저의 제한된 이해는 이것이 제가 원하는 것을 하고 있다는 것을 알려줍니다. 즉, 업스트림 소스에 대한 모든 변경 사항을 얻기 위해 포크를 다시 사용합니다.원본 페이지에 따르면 이 단계는 일반적으로 필요하지 않지만 CRLF 문제로 인해 필요합니다.

  3. git merge upstream/master

  4. git push

하지만 저는 정확한 줄 끝맺기와 diff 파일을 얻기 위해 sed와 같은 도구를 사용할 것을 제안합니다.저는 여러 줄로 끝나는 여러 프로젝트에 몇 시간을 보냈습니다.

가장 좋은 방법은 다음과 같습니다.

  1. 합니다..git디렉터리)를 다른 디렉터리에 만든 다음 파일을 추가하고 커밋합니다(새 저장소의 마스터 분기에 있어야 함).
  2. 분기(예: " " ")를 복사합니다. 다른 분기 복사dev(git checkout -b dev 이첫 번째 git diff master..dev --names-only

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

반응형