如何告诉git总是select我的本地版本的特定文件上的冲突合并?
假设我正在通过git仓库与某人合作,并且有一个特定的文件,我不想接受任何外部更改。
有没有办法让我设置我的本地回购,不要抱怨每次我混帐时发生冲突的合并? 我想在合并这个文件时总是select我的本地版本。
 在configuration文件的具体实例中,我会同意Ron的回答 : 
 一个configuration应该是“私人的”工作空间(因此“忽略”,如“在.gitignore文件中声明”)。 
 你可能有一个带有标记值的configuration文件模板 ,还有一个将config.template文件转换成私有的configuration文件的脚本。 
但是,这个具体的说法并不能回答什么是更广义的问题,即你的问题(!):
如何告诉git总是select我的本地版本的特定文件上的冲突合并? (用于任何文件或文件组)
这种合并是一个“复制合并”,在这种复制合并中,每当出现冲突时,您总是会复制文件的“我们的”或“他们的”版本。
(正如布莱恩·范登堡 在评论中指出的那样 , “
ours”和“theirs”在这里被用于合并 。
它们被颠倒过来了:参见“Why is the meaning of “ours” and “theirs” reversed with git-svn”使用“rebit”,“git rebase,跟踪“local”和“remote ”)来Why is the meaning of “ours” and “theirs” reversed with git-svn
 对于“一个文件”(通常是一个文件,而不是说“config”文件,因为这是一个不好的例子),你可以通过一个通过合并调用的自定义脚本来实现。 
  Git将调用该脚本,因为您将定义一个gitattributes值 ,它定义了一个自定义的合并驱动程序 。 
在这种情况下,“自定义合并驱动程序”是一个非常简单的脚本,基本上将保持当前版本不变,因此可以随时select本地版本。
我们来testing一个简单的场景,在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/ 
现在,我们来创build两个文件,这两个文件都会有冲突,但是会有不同的合并。
 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 
 我们在dirWithCopyMerge目录中定义了一个.gitattributes文件(只在合并发生的分支中定义: myBranch ),我们有一个.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文件中的指令)。
 在你的%PATH% (或者我们的Unix朋友的$PATH任意位置定义一个keepMine.sh ,当然我也有:在VirtualBox会话中有一个Ubuntu会话) 
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 
  (这是一个简单的合并驱动程序;)) 
  (如果您想保留其他版本,只需在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. 
(从Merge开始的行确实certificate了这一点)
考虑你可以定义,合并和/或覆盖合并驱动程序,因为Git将:
-  检查<dir>/.gitattributes(与所讨论path位于同一目录中):将占据目录中的其他.gitattributes
-  然后它检查.gitattributes(它在父目录中),只会设置指令,如果尚未设置
-  最后它检查$GIT_DIR/info/attributes。 该文件用于覆盖树中的设置。 它会覆盖<dir>/.gitattributes指令。
 通过“组合”,我的意思是“聚合”多重合并驱动程序。 
  Nick Green 在评论中尝试实际合并合并驱动程序:请参阅“ 通过python git驱动程序合并pom ”。 
 但是,正如他的另一个问题所提到的,只有在冲突的情况下才能起作用(两个分支同时修改)。 
我们有多个不想覆盖的configuration文件。 但是.gitignore和.gitattributes在我们的情况下不起作用。 我们的解决scheme是将configuration文件存储在configs分支中。 然后,允许在git合并期间更改文件,但在合并之后立即使用“git checkout分支 – ”。 每次合并后从configs分支复制我们的configuration文件。 详细的计算器答案在这里