通常,当您合并两个分支时,冲突会出现在文件中,例如:
<<<<<<<<<< HEAD
但是,我试图做的合并有冲突,但我不知道为什么文件根本没有改变,因此内部不包含任何<<<<<< HEAD
。
这是我试过的命令:
$ md5sum myfile.txt
76dd0814b656b23a61d7e8204cd776de myfile.txt
$ git merge --no-ff tmp_branch
warning: Cannot merge binary files: myfile.txt (HEAD vs. tmp_branch)
Auto-merging myfile.txt
CONFLICT (content): Merge conflict in myfile.txt
Automatic merge failed; fix conflicts and then commit the result.
$ md5sum myfile.txt
76dd0814b656b23a61d7e8204cd776de myfile.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: myfile.txt
no changes added to commit (use "git add" and/or "git commit -a")
我不知道它是否会产生任何影响,但我正在使用git-crypt
作为后端。
- 编辑01 - 我很确定这是git-crypt中的一个错误。我提出了一个非常肮脏的解决方案,但在此期间似乎有效:
首先,手动复制共同祖先提交中的文件:
git checkout <your commit>
cp yourfile.txt yourfile_base.txt
然后,手动复制外部分支中的文件:
git checkout <your branch>
cp yourfile.txt yourfile_other_branch.txt
最后回到你的主分支并使用git merge-file
这样的东西:
git checkout master
git merge-file yourfile.txt yourfile_base.txt yourfile_other_branch.txt
然后,您可以打开yourfile.txt
,搜索字符串<<<<<
并手动纠正冲突!如果您有更快的解决方法,请告诉我们!
- 编辑02 - 我找到了一个更快捷的方法:而不是结账和复制,你可以在一个命令中执行:
git show <your commit>:./yourfile.txt | git-crypt smudge > ./yourfile.txt<
- 编辑03 -
在torek的建议之后,我终于找到了解决问题的方法:
首先,为git-crypt管理的所有文件添加.gitattributes
选项merge=git-crypt
:
crypt/** filter=git-crypt diff=git-crypt merge=git-crypt
然后,在文件.git/config
的末尾添加以下内容:
[merge "git-crypt"]
name = A custom merge driver used to merge git-crypted files.
driver = ./my-merge-tool.sh %O %A %B
recursive = binary
最后在repo my-merge-tool.sh
的根目录下创建一个包含以下内容的文件:
ancestor_decrypted="$1__decrypt"
current_decrypted="$2__decrypt"
other_decrypted="$3__decrypt"
echo ""
echo "###########################"
echo "# Git crypt driver called #"
echo "###########################"
echo ""
echo "Decrypting ancestor file..."
cat $1 | git-crypt smudge > "${ancestor_decrypted}"
echo "Decrypting current file..."
cat $2 | git-crypt smudge > "${current_decrypted}"
echo "Decrypting other file..."
cat $3 | git-crypt smudge > "${other_decrypted}"
echo ""
echo "Merging ..."
git merge-file -L "current branch" -L "ancestor branch" -L "other branch" "${current_decrypted}" "${ancestor_decrypted}" "${other_decrypted}"
exit_code=$?
cat "${current_decrypted}" | git-crypt clean > $2
echo "Removing temporary files..."
rm "${other_decrypted}" "${ancestor_decrypted}" "${current_decrypted}"
if [ "$exit_code" -eq "0" ]
then
echo "@@@ No conflict!"
else
echo "@@@ You need to solve some conflicts..."
fi
exit $exit_code
并确保它是可执行的:
chmod +x my-merge-tool.sh
就是这样,你现在可以合并,挑选,甚至像往常一样使用你最喜欢的合并工具!
答案 0 :(得分:2)
它并不是git-crypt中的 bug ,它是Git合并方式与git-crypt加密方式的副作用。 Git只能看到“已清理”的文件,这些文件是加密文件。 Git字面意思不能合并任何因此。
但是,您可以提供自己的合并驱动程序,an outstanding GitHub pull request声称可以执行此操作。它已经超过一年了,没有任何动作(我看到你自己发现它,并注意到它对你不起作用)。它可能做得不够。我没有调查git-crypt本身的代码来说这种或那种方式。
合并驱动程序的正确版本将执行合并,如果结果未冲突,则以零状态退出。然后Git将使用生成的%A
版本作为合并结果。如果文件存在冲突,则合并驱动程序应在%A
文件中留下冲突标记。为了使这项工作特别好(例如,使其与git mergetool
一起使用),您甚至可能想要解密所有三个输入并使用git update-index
将它们作为第1,2和2阶段输入到索引中3.请注意,这具有安全隐患,必须在其他文档中非常仔细地说明。 (特别是这会留下未加密的松散对象;您可能希望将它们存储在备用对象目录中,在合并期间创建目的,并进行合并后清理步骤以删除它们,但即便如此在创建松散的对象之前,为了减少但不能消除这种风险,你可以运行git gc
。