我不需要一个可视化的合并工具,我也不希望必须vi冲突的文件,并手动在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;
这也给了我一个混乱的提交消息,其中两次包含Conflicts: Makefile。
谁能告诉我如何用更简单的方法来做以上两个动作?谢谢
根据Jakub的回答,你可以为方便配置以下git别名:
accept-ours = "!f() { git checkout --ours -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
accept-theirs = "!f() { git checkout --theirs -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
它们可以选择一个或多个文件路径来解析,如果没有给出,则默认解析当前目录下的所有文件。
将它们添加到~/的[alias]部分。Gitconfig或run
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'
根据Jakub的回答,你可以为方便配置以下git别名:
accept-ours = "!f() { git checkout --ours -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
accept-theirs = "!f() { git checkout --theirs -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
它们可以选择一个或多个文件路径来解析,如果没有给出,则默认解析当前目录下的所有文件。
将它们添加到~/的[alias]部分。Gitconfig或run
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'
解决冲突的理想情况是,您提前知道希望以哪种方式解决冲突,并且可以传递-Xours或- xtheir递归合并策略选项。除此之外,我可以看到三个场景:
您希望只保留文件的单个版本(这应该只用于不可合并的二进制文件,否则冲突文件和非冲突文件可能会彼此不同步)。
你只想把所有的冲突都确定在一个特定的方向上。
您需要手动解决一些冲突,然后按照特定的方向解决其余所有冲突。
为了解决这三种情况,你可以在你的.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(我们的|他们的)工具只保留文件的各自版本,并丢弃来自其他版本的所有更改(因此不会发生合并)。
The merge(ours|theirs) tool re-does the three way merge from the local, base, and remote versions of the file, choosing to resolve conflicts in the given direction. This has some caveats, specifically: it ignores the diff options that were passed to the merge command (such as algorithm and whitespace handling); does the merge cleanly from the original files (so any manual changes to the file are discarded, which could be good or bad); and has the advantage that it cannot be confused by diff markers that are supposed to be in the file.
keep(我们的|他们的)工具只是编辑出差异标记和封闭的部分,通过正则表达式检测它们。这样做的好处是保留了merge命令中的diff选项,并允许您手动解决一些冲突,然后自动解决其余冲突。它的缺点是,如果文件中有其他冲突标记,它可能会混淆。
这些都是通过运行git mergetool -t (get|merge|keep)(我们的|他们的)[<filename>]来使用的,如果没有提供<filename>,它会处理所有冲突的文件。
一般来说,假设您知道没有diff标记来混淆正则表达式,命令的keep*变体是最强大的。如果你离开合并工具。keepBackup选项未设置或为true,则合并后,您可以区分*。根据合并的结果来检查它是否有意义。作为一个例子,我在合并工具之后运行以下命令,只是为了在提交之前检查更改:
for f in `find . -name '*.orig'`; do vimdiff $f ${f%.orig}; done
注:如果合并。Conflictstyle不是diff3,那么sed规则中的/^|||||||/模式需要改为/^=======/。
解决办法很简单。Git checkout <filename>试图从索引中检出文件,因此合并失败。
你需要做的是(即签出一个提交):
要签出您自己的版本,您可以使用以下方法之一:
git checkout HEAD -- <filename>
or
git checkout --ours -- <filename>
(警告!:如果你要换基地,我们的和他们的就交换了。)
or
git show :2:<filename> > <filename> # (stage 2 is ours)
要签出另一个版本,您可以使用其中之一:
git checkout test-branch -- <filename>
or
git checkout --theirs -- <filename>
or
git show :3:<filename> > <filename> # (stage 3 is theirs)
你还需要运行'add'将其标记为已解决:
git add <filename>