Git是否在特定文件上发生合并冲突时选择本地版本? [英] Have Git Select Local Version On Merge Conflict on a Specific File?
问题描述
假设我正在通过Git存储库与某人协作,并且有一个我永远不想接受任何外部更改的特定文件。
有没有办法设置我的本地回购,使我每次退出时都不会抱怨冲突的合并?合并此文件时,我希望始终选择我的本地版本。
推荐答案
关于配置文件的具体实例,我同意Ron's answer:
配置对于您的工作区应该是"私有的"(因此"忽略",如"在.gitignore
文件中声明")。
您可能有一个模板,其中包含标记值,以及一个将config.template
文件转换为私有(已忽略)配置文件的脚本。
然而,这一具体评论并没有回答更广泛、更一般的问题,即您的问题(!):
如何告诉Git始终为特定文件上的冲突合并选择本地版本?(对于任何文件或文件组)
这种合并是一种"复制合并",每当发生冲突时,您总是会复制文件的"我们的"或"他们的"版本。
(因为Brian Vandenberg备注in the comments、‘
ours
’和‘theirs
’在这里用于合并。
对于rebase:请参阅"Why is the meaning of "ours" and "theirs" reversed with git-svn
",其中使用rebase,"git rebase
, keeping track of 'local' and 'remote'")
对于"一个文件"(通常是一个文件,不是"配置"文件,因为它是一个糟糕的示例),您可以使用一个通过合并调用的自定义脚本来实现这一点。
Git将调用该脚本,因为您已经定义了gitattributes value,它定义了自定义合并驱动程序。
在本例中,"定制合并驱动程序"是一个非常简单的脚本,它基本上将保持当前版本不变,因此允许您始终选择本地版本。
IE,ASnoted由Ciro Santilli:
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
让我们在一个简单的场景中进行测试,在Windows上使用msysgit 1.6.3,在一个DOS会话中:
cd f:proggit est
mkdir copyMergedirWithConflicts
mkdir copyMergedirWithCopyMerge
cd copyMerge
git init
Initialized empty Git repository in F:/prog/git/test/copyMerge/.git/
现在,让我们创建两个文件,这两个文件都有冲突,但合并方式不同。
echo a > dirWithConflictsa.txt
echo b > dirWithCopyMerge.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 >> dirWithConflictsa.txt
echo myLineForB >> dirWithCopyMerge.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 >> dirWithConflictsa.txt
echo hisLineForB >> dirWithCopyMerge.txt
git add -A
git commit -m "add modification in hisBranch"
[hisBranch 658c31c] add modification in hisBranch
现在,让我们尝试将"hisBranch"合并到"myBranch"上:
- 手动解决冲突合并
- 除用于
dirWithCopyMerge.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
),并且我们有一个.gitconfig
文件,其中现在包含合并驱动程序。
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
如果您尚未定义mitMine.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 dirWithConflictsa.txt
a
<<<<<<< HEAD:dirWithConflicts/a.txt
myLineForA
=======
hisLineForA
>>>>>>> hisBranch:dirWithConflicts/a.txt
这很好:
a.txt
已准备好合并,其中存在冲突b.txt
仍然保持不变,因为合并驱动程序应该处理它(由于其目录中的.gitattributes
文件中的指令)。
在%PATH%
中的任何位置定义keepMine.sh
(或为我们的Unix朋友定义$PATH
。当然,我两者都有:我在VirtualBox会话中有一个Ubuntu会话)
如commentedbylrkwz所述,并且在Customizing Git - Git Attributes的Merge Strategies一节中描述,您可以将外壳脚本替换为外壳命令true
。
git config merge.keepMine.driver true
但在一般情况下,您可以定义脚本文件:
mitMine.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.
合并失败...仅适用于.txt。编辑.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.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
指令。
"合并"指的是"聚合"多个合并驱动因素。
Nick Green尝试、in the comments实际合并驱动因素:请参阅"Merge pom's via python git driver"。
但是,如his other question中所述,只有在冲突(两个分支同时修改)的情况下才起作用。
这篇关于Git是否在特定文件上发生合并冲突时选择本地版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!