1

通常,当您合并两个分支时,冲突会出现在文件中,如下所示:

<<<<<<<<<< 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

就是这样,您现在可以像往常一样合并、挑选,甚至使用您最喜欢的合并工具!

4

1 回答 1

4

这并不是 git-crypt 中的真正错误,它是 Git 合并方式与 git-crypt 加密方式的副作用。Git 只看到“已清理”的文件,即加密文件。因此, Git 实际上无法合并任何内容

但是,您可以提供自己的合并驱动程序,并且有一个出色的 GitHub 拉取请求声称可以这样做。它已经发布了一年多,没有任何动静(我看到你自己找到了它,并指出它对你不起作用)。它可能做得还不够。我还没有调查 git-crypt 本身的代码来说明一种或另一种方式。

正确版本的合并驱动程序将执行合并,如果结果不冲突,则以零状态退出。然后 Git 将使用生成的%A版本作为合并结果。如果文件发生冲突,合并驱动程序应在%A文件中留下冲突标记。为了使这项工作特别好(git mergetool例如使其工作),您甚至可能想要解密所有三个输入并使用git update-index将它们作为阶段 1、2 和 3 输入索引。请注意,这具有安全隐患,必须在附加文档中非常仔细地说明。(特别是这会留下未加密的松散对象;您可能希望将它们存储在备用对象目录中,在合并期间专门创建,并有一个合并后清理步骤来删除它们,但即便如此它们有成为打包对象的风险。为了减少但不是消除这种风险,在创建松散对象之前,您可以运行一个git gc.)

于 2018-01-27T19:48:42.287 回答