source

Git를 사용하여 전체 파일에서 '내 것' 또는 '내 것'을 수락하는 간단한 도구

nicesource 2023. 5. 29. 10:59
반응형

Git를 사용하여 전체 파일에서 '내 것' 또는 '내 것'을 수락하는 간단한 도구

시각적 병합 도구를 사용하지 않고 충돌한 파일을 사용하여 HEAD(내 것)와 가져온 변경 사항(내 것) 사이에서 수동으로 선택하지 않아도 됩니다.대부분의 경우 저는 그들의 모든 변화를 원하거나 저의 모든 변화를 원합니다.일반적으로 이것은 나의 변화가 그것을 만들어냈고 당김을 통해 나에게 돌아오고 있기 때문이지만, 다양한 장소에서 약간 수정될 수 있습니다.

충돌 마커를 제거하고 내 선택에 따라 모든 방법을 선택할 수 있는 명령줄 도구가 있습니까?또는 각각의 작업을 수행하기 위해 내 별명을 붙일 수 있는 일련의 git 명령입니다.

# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"

이렇게 하는 것은 다소 짜증나는 일입니다.'내 것을 받아 들이기'를 위해 시도했습니다.

randy@sabotage ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.

randy@sabotage ~/linus $ git checkout Makefile 
error: path 'Makefile' is unmerged

andy@sabotage ~/linus $ git reset --hard HEAD Makefile 
fatal: Cannot do hard reset with paths.

이 변화 표시들을 어떻게 없애야 합니까?

할 수 있습니다.

git reset HEAD Makefile; rm Makefile; git checkout Makefile

하지만 이것은 다소 우회적으로 보입니다. 더 나은 방법이 있을 것입니다.그리고 이 시점에서, 저는 Git이 합병이 일어났다고 생각하는지조차 확신할 수 없습니다. 그래서 저는 이것이 꼭 효과가 있다고 생각하지 않습니다.

반대로 '그들의 것을 받아들인다'는 것도 마찬가지로 지저분합니다.내가 알아낼 수 있는 유일한 방법은 다음과 같습니다.

git show test-branch:Makefile > Makefile; git add Makefile;

이것은 또한 충돌이 있는 엉망인 커밋 메시지를 제공합니다.파일을 두 번 작성합니다.

누가 위의 두 가지 행동을 어떻게 하면 더 간단한 방법으로 할 수 있는지 알려주실 수 있나요?감사해요.

해결책은 매우 간단합니다. git checkout <filename>인덱스에서 파일을 체크아웃하려고 하므로 병합 시 실패합니다.

수행해야 할 작업은 다음과 같습니다(: 커밋 확인).

자신의 버전을 체크아웃하려면 다음 중 하나를 사용할 수 있습니다.

git checkout HEAD -- <filename>

또는

git checkout --ours -- <filename>

(경고!:기준을 변경하는 경우--ours그리고.--theirs스왑됩니다.)

또는

git show :2:<filename> > <filename> # (stage 2 is ours)

다른 버전을 체크아웃하려면 다음 중 하나를 사용할 수 있습니다.

git checkout test-branch -- <filename>

또는

git checkout --theirs -- <filename>

또는

git show :3:<filename> > <filename> # (stage 3 is theirs)

확인됨으로 표시하려면 '추가'를 실행해야 합니다.

git add <filename>

사용해 보십시오.

  • 변경 내용 수락하기git merge --strategy-option theirs
  • 변경 내용 수락하기git merge --strategy-option ours

Jakub의 답변에 따라 편의를 위해 다음과 같은 Git 별칭을 구성할 수 있습니다.

accept-ours = "!f() { git checkout --ours -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
accept-theirs = "!f() { git checkout --theirs -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"

선택적으로 파일 경로를 하나 또는 여러 개 사용하여 확인할 수 있으며, 지정되지 않은 경우 현재 디렉터리 아래의 모든 항목을 확인할 수 있습니다.

을 합니다.[alias]의 의션 ~/.gitconfig또는 실행

git config --global alias.accept-ours '!f() { git checkout --ours -- "${@:-.}"; git add -u "${@:-.}"; }; f'
git config --global alias.accept-theirs '!f() { git checkout --theirs -- "${@:-.}"; git add -u "${@:-.}"; }; f'

kynan의 답변에 따라 파일 이름의 공백 및 초기 대시를 처리할 수 있도록 수정된 동일한 별칭이 있습니다.

accept-ours = "!f() { [ -z \"$@\" ] && set - '.'; git checkout --ours -- \"$@\"; git add -u -- \"$@\"; }; f"
accept-theirs = "!f() { [ -z \"$@\" ] && set - '.'; git checkout --theirs -- \"$@\"; git add -u -- \"$@\"; }; f"

충돌을 해결하기 위한 이상적인 상황은 충돌을 해결할 방법을 미리 알고 다음을 통과할 수 있는 경우입니다.-Xours또는-Xtheirs재귀 병합 전략 옵션입니다.이 밖에도 세 가지 시나리오를 볼 수 있습니다.

  1. 파일의 단일 버전만 유지하려고 합니다. 그렇지 않으면 충돌된 파일과 충돌되지 않은 파일이 서로 동기화되지 않을 수 있으므로 병합할 수 없는 이진 파일에서만 사용해야 합니다.
  2. 특정 방향으로 모든 충돌을 결정하려고 합니다.
  3. 일부 충돌을 수동으로 해결한 다음 나머지를 특정 방향으로 모두 해결해야 합니다.

세 다음 을 이세가시오를해위다다있수에 할 수 ..gitconfig파일(또는 동등한 파일):

[merge]
  conflictstyle = diff3
[mergetool.getours]
  cmd = git-checkout --ours ${MERGED}
  trustExitCode = true
[mergetool.mergeours]
  cmd = git-merge-file --ours ${LOCAL} ${BASE} ${REMOTE} -p > ${MERGED}
  trustExitCode = true
[mergetool.keepours]
  cmd = sed -i '' -e '/^<<<<<<</d' -e '/^|||||||/,/^>>>>>>>/d' ${MERGED}
  trustExitCode = true
[mergetool.gettheirs]
  cmd = git-checkout --theirs ${MERGED}
  trustExitCode = true
[mergetool.mergetheirs]
  cmd = git-merge-file --theirs ${LOCAL} ${BASE} ${REMOTE} -p > ${MERGED}
  trustExitCode = true
[mergetool.keeptheirs]
  cmd = sed -i '' -e '/^<<<<<<</,/^=======/d' -e '/^>>>>>>>/d' ${MERGED}
  trustExitCode = true

get(ours|theirs)도구는 파일의 해당 버전만 유지하고 다른 버전의 변경 사항은 모두 삭제합니다(따라서 병합은 발생하지 않습니다.

merge(ours|theirs)도구는 파일의 로컬, 기본 및 원격 버전에서 세 가지 방식으로 다시 병합하여 지정된 방향으로 충돌을 해결하도록 선택합니다. 몇 가지할 점이 명령에 예: 알고리즘 및 처리파일에서 사항은 폐기됩니다). 특히 병합 명령에 전달된 diff 옵션(예: 알고리즘 및 공백 처리)을 무시하고 원본 파일에서 완전히 병합합니다(따라서 파일에 대한 수동 변경 사항은 폐기됨).이는 좋거나 나쁠 수 있음); 그리고 파일에 있어야 하는 diff 마커로 혼동할 수 없다는 장점이 있습니다.

keep(ours|theirs)도구는 단순히 diff 마커와 닫힌 섹션을 편집하여 정규식으로 탐지합니다.이렇게 하면 병합 명령의 diff 옵션이 유지되고 일부 충돌을 수동으로 해결한 다음 나머지를 자동으로 해결할 수 있다는 장점이 있습니다.파일에 다른 충돌 마커가 있으면 혼동될 수 있다는 단점이 있습니다.

이것들은 모두 실행에 의해 사용됩니다.git mergetool -t (get|merge|keep)(ours|theirs) [<filename>]<filename>제공되지 않습니다. 충돌하는 모든 파일을(를) 제공하지 않습니다.

일반적으로 정규 표현을 혼동할 수 있는 디프 마커가 없다는 것을 알고 있다고 가정하면,keep*명령의 변형이 가장 강력합니다.만약 당신이 떠난다면,mergetool.keepBackup옵션 unset 또는 true를 선택하면 병합 후 디파짓할 수 있습니다.*.orig병합 결과에 대한 파일을 생성하여 해당 파일이 의미 있는지 확인합니다.예를 들어 다음을 실행합니다.mergetool다음을 수행하기 전에 변경 사항을 검사할 수 있습니다.

for f in `find . -name '*.orig'`; do vimdiff $f ${f%.orig}; done

참고: 만약merge.conflictstyle아닙니다diff3 다음에 그음에다./^|||||||/sed규칙은 다음과 같아야 합니다./^=======/대신.

언급URL : https://stackoverflow.com/questions/914939/simple-tool-to-accept-theirs-or-accept-mine-on-a-whole-file-using-git

반응형