git svn系统中出现意外的合并错误?

时间:2015-03-14 15:04:45

标签: git svn git-svn

我有一个有点复杂的设置(如在git svn dcommit committing wrong file?中)看起来像这样(在Dia testrepo.dia中生成,在this gist中发布) - 并使用下面的脚本进行模拟,testrepo.sh

/tmp/testrepo.png

基本上,我在网络服务器(myrepo_svn_WS)上有一个SVN存储库,最初我在本地PC(myrepo_svnco)上通过SVN工作副本工作。过了一会儿,我停下来,我搬到了git-svn;但不是直接从我的本地PC使用它 - 我在本地服务器上设置了myrepo_gitsvn;从它开始,在本地服务器myrepo_git_LS.git上创建一个简单的git repo,它被添加为myrepo_gitsvn的远程源。我的想法是,我可以在本地PC上使用myrepo_git_LS.git,并保持本地网络同步 - 即使svn Web服务器暂时脱机。

以下脚本testrepo.sh在本地模拟此过程 - 包括myrepo_svn_WS离线。如果按原样使用脚本,您会注意到系统可以恢复"恢复"来自SVN" WS"服务器脱机,在这种情况下的日志是testrepo_nofail.log。但是,如果您取消注释执行#~的{​​{1}}注释行,您会注意到该过程失败,日志为testrepo_fail.log

git fetch origingit

我在这里感到困惑(以及为什么我发现这是意料之外的) - 我是唯一的用户,因此我甚至根本不使用分支机构!在那种情况下,我怎么可能会发生"合并冲突"?

事情是 - 现在系统实际上已经处于这种失败的状态;所以我的问题是:如何将系统恢复到正常的工作状态,这样当我提交并从本地remote: Using index info to reconstruct a base tree... remote: Falling back to patching base and 3-way merge... remote: Auto-merging folder/file.txt remote: CONFLICT (content): Merge conflict in folder/file.txt remote: Failed to merge in the changes. remote: Patch failed at 0001 5th git commit remote: remote: When you have resolved this problem run "git rebase --continue". remote: If you would prefer to skip this patch, instead run "git rebase --skip". remote: To check out the original branch and stop rebasing run "git rebase --abort". 推送时,SVN Web服务器myrepo_git_wc会正确更新?

将日志与myrepo_svn_WS进行比较时的一些注意事项:

注意"通过git fetch模拟合并冲突"部分,该过程似乎正常进行 - 除了现在有一个meld分支(点击查看完整大小):

testrepo_meld_01.png

我没有想太多,因为我没有想到origingit/master作为一个分支;但这是一个子问题:git-svngit-svn,哪一个是分支?

该部分在此结束:

/testrepo_meld_02.png

请注意,最后,非失败的进程将日志图树显示为"压缩"或者"扁平化" (即没有分支突出) - 虽然此时失败的过程并没有抱怨错误,但是将日志图树显示为分支。

只有在第6次git提交后才会出现问题:

testrepo_meld_03.png

失败的进程实际上是由于某种原因启动的,并且应用第5个git commit',此时应该已经处理过了;并且在那时,发生合并冲突。

因此,如果我的系统(或更确切地说,origingit/master)处于此失败状态,我该怎么做才能恢复它?

以下是myrepo_gitsvn代码:

testrepo.sh

1 个答案:

答案 0 :(得分:0)

所以,我认为我到了某个地方 - 但我真的不确定这是否适用于所有边缘情况,所以最终会更加博学的答案。

首先,注意:您可以使用bash testrepo.sh 2>&1 | tee testrepo_MARK.log获取日志;您可以通过以下日志sed -i 's/\x1b\[\x4b//g' testrepo*.log remove the control characters inserted by git remote进行How do I delete a Git branch both locally and remotely?

无论如何 - 显然在做git fetch时,它会添加一个所谓的本地远程跟踪分支,可以按/tmp/testrepo_meld_04.png删除(不添加“本地远程跟踪分支”,一个人显然应该打电话给git fetch <remote> --prune。 但如果从破碎状态中恢复,那还不够;破碎的状态显然意味着有一个不成功的合并记录,应该被删除(可以使用git rebase --abort,如程序本身所推荐的那样)。简而言之,修复将是:

cd /tmp/myrepo_gitsvn
git branch --delete --remotes origingit/master
git rebase --abort

以上是对上述脚本的修改,允许模拟中断和恢复(只需替换OP脚本中的相应部分):

# ...
cd /tmp
cat > /tmp/myrepo_git_LS.git/hooks/post-update <<EOF
#!/usr/bin/env bash
export SSHPASS=${SSHPASS}
#export GIT_DIR="."
git update-server-info
export GIT_DIR=".git"
echo "post-update kicking in"
cd /tmp/myrepo_gitsvn
git svn info | grep Rev
git pull --rebase origingit master
git svn info | grep Rev
git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order
sshpass -e git svn rebase
sshpass -e git svn dcommit
sshpass -e git svn rebase
git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order
git svn info | grep Rev
EOF
chmod +x /tmp/myrepo_git_LS.git/hooks/post-update

# ...

echo "Simulating svn server back online; git wc commits get added"
mv /tmp/.myrepo_svn_WS /tmp/myrepo_svn_WS

DOCONFLICT=true
if [ "${DOCONFLICT}" = "true" ] ; then
echo "Simulating merge conflict via git fetch"
(cd /tmp/myrepo_gitsvn; git fetch origingit)
fi

echo lll >> folder/file.txt
git add folder/file.txt
git commit -m "5th git commit"
sshpass -e git push origin master

echo mmm >> folder/file.txt
git add folder/file.txt
git commit -m "6th git commit"
sshpass -e git push origin master

DOFIX=true
if [ "${DOCONFLICT}" = "true" ] ; then
if [ "${DOFIX}" = "true" ] ; then
  # https://stackoverflow.com/questions/2003505/delete-a-git-branch-both-locally-and-remotely/23961231#23961231
  (cd /tmp/myrepo_gitsvn;
  git branch --delete --remotes origingit/master;
  git rebase --abort;
  )
fi
fi

echo nnn >> folder/file.txt
git add folder/file.txt
git commit -m "7th git commit"
sshpass -e git push origin master

echo ooo >> folder/file.txt
git add folder/file.txt
git commit -m "8th git commit"
sshpass -e git push origin master

还有一些提交,以测试恢复是否成立;看起来确实如此,因为对于最后一次提交,现在可以在日志比较中看到:

testrepo_meld_05.png

...除了轻微的重新排列外,日志图看起来几乎相同。另外,请注意,当添加的git svn info告知时,每次有一个“倒带头来重放你的工作”时,git-svn实际上会将存储库提交到5(这是最后一个在迁移到git-svn之前,只在Subversion中完成;不知道为什么会这样。最后,当最终提交后显示压缩的日志图时,一切看起来都很好:

{{3}}

嗯,我希望这能帮助我修复我的实际存储库...