我有一个有点复杂的设置(如在git svn dcommit committing wrong file?中)看起来像这样(在Dia testrepo.dia中生成,在this gist中发布) - 并使用下面的脚本进行模拟,testrepo.sh
:
基本上,我在网络服务器(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
分支(点击查看完整大小):
我没有想太多,因为我没有想到origingit/master
作为一个分支;但这是一个子问题:git-svn
和git-svn
,哪一个是分支?
该部分在此结束:
请注意,最后,非失败的进程将日志图树显示为"压缩"或者"扁平化" (即没有分支突出) - 虽然此时失败的过程并没有抱怨错误,但是将日志图树显示为分支。
只有在第6次git提交后才会出现问题:
失败的进程实际上是由于某种原因启动的,并且应用第5个git commit',此时应该已经处理过了;并且在那时,发生合并冲突。
因此,如果我的系统(或更确切地说,origingit/master
)处于此失败状态,我该怎么做才能恢复它?
以下是myrepo_gitsvn
代码:
testrepo.sh
答案 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
时,它会添加一个所谓的本地远程跟踪分支,可以按删除(不添加“本地远程跟踪分支”,一个人显然应该打电话给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
还有一些提交,以测试恢复是否成立;看起来确实如此,因为对于最后一次提交,现在可以在日志比较中看到:
...除了轻微的重新排列外,日志图看起来几乎相同。另外,请注意,当添加的git svn info
告知时,每次有一个“倒带头来重放你的工作”时,git-svn实际上会将存储库提交到5(这是最后一个在迁移到git-svn之前,只在Subversion中完成;不知道为什么会这样。最后,当最终提交后显示压缩的日志图时,一切看起来都很好:
{{3}}
嗯,我希望这能帮助我修复我的实际存储库...