GIT에 항상 특정 파일의 충돌 병합에 대한 로컬 버전을 선택하도록하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/928646

  •  06-09-2019
  •  | 
  •  

문제

GIT 저장소를 통해 누군가와 협력하고 있으며 외부 변경을 수락하고 싶지 않은 특정 파일이 있다고 가정 해 봅시다.

내가 당기는 때마다 충돌 병합에 대해 불평하지 않기 위해 현지 리포를 설정할 수있는 방법이 있습니까? 이 파일을 병합 할 때 항상 로컬 버전을 선택하고 싶습니다.

도움이 되었습니까?

해결책

구성 파일의 특정 인스턴스에서 동의합니다. 론의 대답:
구성은 작업 공간에 "개인"이어야합니다 (따라서 "무시된다. .gitignore 파일").
구성 파일이있을 수 있습니다 주형 ~와 함께 토큰 화 된 값 그것에, 그리고 그것을 변형시키는 대본 config.template 프라이버시 (및 무시 된) 구성 파일로 파일을 파일로 파일을 파일하십시오.


그러나 그 구체적인 발언은 더 넓은 일반적인 질문, 즉 귀하의 질문에 답하지 않습니다 (!).

GIT에 항상 특정 파일의 충돌 병합에 대한 로컬 버전을 선택하도록하려면 어떻게해야합니까? (파일 또는 파일 그룹의 경우)

이러한 종류의 병합은 "복사 병합"이며, 충돌이있을 때마다 항상 '우리의'또는 '그들의'버전을 복사합니다.

(처럼 브라이언 반덴버그 메모 의견에서, 'ours' 그리고 'theirs'여기서 합병에 사용됩니다.
그들은 역전 a 레바 제: 보다 "Why is the meaning of “ours” and “theirs” reversed with git-svn",, 그것은 Rebase를 사용합니다."git rebase, '로컬'및 '원격'을 추적")

"파일"(일반적으로 "구성"파일에 대해 말하지 않은 파일은 나쁜 예제이므로, 합병을 통해 불리는 사용자 정의 스크립트로이를 달성 할 수 있습니다.
git은 당신이 gitattributes, 이는 정의합니다 사용자 정의 병합 드라이버.

"Custom Merge Driver"는이 경우 기본적으로 현재 버전을 변경하지 않아서 항상 로컬 버전을 선택할 수있는 매우 간단한 스크립트입니다.


단순한 시나리오에서 Windows에서 MSYSGIT 1.6.3, 단순한 DOS 세션에서 다음을 테스트 해 봅시다.

cd f:\prog\git\test
mkdir copyMerge\dirWithConflicts
mkdir copyMerge\dirWithCopyMerge
cd copyMerge
git init
Initialized empty Git repository in F:/prog/git/test/copyMerge/.git/

이제 둘 다 충돌이지만 다르게 병합 될 두 파일을 만들어 봅시다.

echo a > dirWithConflicts\a.txt
echo b > dirWithCopyMerge\b.txt
git add -A
git commit -m "first commit with 2 directories and 2 files"
[master (root-commit) 0adaf8e] first commit with 2 directories and 2 files

우리는 두 파일의 두 파일 내용에 두 개의 다른 git 브랜치에 "충돌"을 소개합니다.

git checkout -b myBranch
Switched to a new branch 'myBranch'
echo myLineForA >> dirWithConflicts\a.txt
echo myLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in myBranch"
[myBranch 97eac61] add modification in myBranch

git checkout master
Switched to branch 'master'
git checkout -b hisBranch
Switched to a new branch 'hisBranch'
echo hisLineForA >> dirWithConflicts\a.txt
echo hisLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in hisBranch"
[hisBranch 658c31c] add modification in hisBranch

이제 "MyBranch"에 "Hisbranch"를 병합하여 다음과 같이합시다.

  • 충돌 합병을위한 수동 해상도
  • 제외하고 ~을 위한 dirWithCopyMerge\b.txt 내가 항상 유지하고 싶은 곳 나의 버전 b.txt.

병합이 발생하기 때문에MyBranch', 우리는 그것으로 다시 전환하고'추가 할 것입니다. 'gitattributes'병합 동작을 사용자 정의 할 지시문.

git checkout myBranch
Switched to branch 'myBranch'
echo b.txt merge=keepMine > dirWithCopyMerge\.gitattributes
git config merge.keepMine.name "always keep mine during merge"
git config merge.keepMine.driver "keepMine.sh %O %A %B"
git add -A
git commit -m "prepare myBranch with .gitattributes merge strategy"
[myBranch ec202aa] prepare myBranch with .gitattributes merge strategy

우리는 a .gitattributes 파일에 정의 된 파일 dirWithCopyMerge 디렉토리 (병합이 발생하는 지점에서만 정의됩니다. myBranch), 그리고 우리는 a .git\config 이제 병합 드라이버가 포함 된 파일.

[merge "keepMine"]
        name = always keep mine during merge
        driver = keepMine.sh %O %A %B

아직 keepmine.sh를 정의하지 않고 어쨌든 합병을 시작하면 여기에 얻는 것이 있습니다.

git merge hisBranch
sh: keepMine.sh: command not found
fatal: Failed to execute internal merge
git st
# On branch myBranch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dirWithConflicts/a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

type dirWithConflicts\a.txt
a
<<<<<<< HEAD:dirWithConflicts/a.txt
myLineForA
=======
hisLineForA
>>>>>>> hisBranch:dirWithConflicts/a.txt

괜찮습니다 :

  • a.txt 합병 될 준비가되었고 충돌이 있습니다.
  • b.txt 병합 드라이버가 그것을 처리해야하기 때문에 ( .gitattributes 디렉토리에 파일).

정의 a keepMine.sh 당신의 어느 곳에서나 %PATH% (또는 $PATH 우리 유닉스 친구를 위해. 물론 두 가지 모두를합니다. 가상 박스 세션에서 우분투 세션이 있습니다)

처럼 댓글을 달았습니다 ~에 의해 lrkwz, "그리고"전략을 병합하십시오"섹션 GIT 사용자 정의 - git 속성, 쉘 스크립트를 쉘 명령으로 바꿀 수 있습니다. true.

git config merge.keepMine.driver true

그러나 일반적으로 스크립트 파일을 정의 할 수 있습니다.

Keepmine.sh

# I want to keep MY version when there is a conflict
# Nothing to do: %A (the second parameter) already contains my version
# Just indicate the merge has been successfully "resolved" with the exit status
exit 0

(하나의 간단한 병합 드라이버였습니다.) (이 경우 더 간단하게 사용하십시오. true)
(다른 버전을 유지하고 싶다면 앞에 추가하십시오. exit 0 선:
cp -f $3 $2.
그게 다야. 합병 드라이버는 다른 지점에서 버전을 계속 유지하여 지역 변경을 우선시합니다)

이제 처음부터 병합을 다시 시도해 봅시다.

git reset --hard
HEAD is now at ec202aa prepare myBranch with .gitattributes merge strategy

git merge hisBranch
Auto-merging dirWithConflicts/a.txt
CONFLICT (content): Merge conflict in dirWithConflicts/a.txt
Auto-merging dirWithCopyMerge/b.txt
Automatic merge failed; fix conflicts and then commit the result.

병합이 실패합니다 ... A.txt에만 해당됩니다.
A.txt를 편집하고 'Hisbranch'에서 줄을 남겨 두십시오.

git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version

이 병합 중에 B.txt가 보존되었는지 확인해 봅시다.

type dirWithCopyMerge\b.txt
b
myLineForB

마지막 커밋은 가득한 병합 :

git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.

(합병으로 시작하는 선은


GIT가있는대로 합병 드라이버를 정의, 결합 및/또는 덮어 쓸 수 있다고 생각합니다.

  • 조사하다 <dir>/.gitattributes (문제의 경로와 동일한 디렉토리에있는) : 다른 사람에게 우선합니다. .gitattributes 디렉토리에서
  • 그런 다음 검사합니다 .gitattributes (부모 디렉토리에있는), 아직 설정되지 않은 경우에만 지시를 설정합니다.
  • 마지막으로 검사합니다 $GIT_DIR/info/attributes. 이 파일은 트리 내 설정을 무시하는 데 사용됩니다. 덮어 쓰게됩니다 <dir>/.gitattributes 지침.

"결합"한다는 것은 "집계"다중 병합 드라이버를 의미합니다.
닉 그린 시도, 의견에서, 실제로 합병 드라이버를 결합하려면 : "참조"POM의 Python Git 드라이버를 병합하십시오".
그러나 언급했듯이 그의 다른 질문, 그것은 갈등의 경우에만 작동합니다 (두 가지에서 동시 수정).

다른 팁

덮어 쓰기를 원하지 않는 여러 구성 파일이 있습니다. 그러나 .gitignore와 .gitattributes는 우리 상황에서 효과가 없었습니다. 우리의 솔루션은 구성 파일을 구성 분기에 저장하는 것이 었습니다. 그런 다음 GIT 병합 중에 파일이 변경 될 수 있지만 병합 직후 "Git Checkout Branch-"를 사용하십시오. 모든 병합 후 구성 파일에서 구성 파일을 복사합니다.자세한 stackoverflow 답변

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top