git svn rebase 错过/丢失提交(在 rebase --continue 由于合并冲突)?

Posted

技术标签:

【中文标题】git svn rebase 错过/丢失提交(在 rebase --continue 由于合并冲突)?【英文标题】:git svn rebase misses/loses commits (on rebase --continue due merge conflict)? 【发布时间】:2015-03-15 00:13:55 【问题描述】:

我遇到了丢失提交的问题,其设置与Unexpected merge error in a git svn system? 中描述的设置非常相似(点击查看完整尺寸):

很遗憾,我无法在示例中重现此问题,因此我将尝试提供我认为相关的信息。我在myrepo_git_wc 本地工作,所以它代表“原始来源”;目前它具有最后几次提交的这种状态(所有这些提交的名称中都有“空编辑”,所以我在那之后是 grepping):

$ git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order | grep 'null edit'

* 03ed433 (HEAD, master) : damnit, null edit again
* de3bd53 (origin/master, origin/HEAD) : previous null edit passed
* 65bf738 : again null edit - no improvement
* 62ab3f6 : still bad; trying again w null edit
* 14f5aba : another null edit; previous was bad
* f0ef194 : null edit - starter

我把我的工作推到myrepo_git_LS.gitbare repo;然后使用post-update 钩子更新myrepo_gitsvn - 最终将dcommits 更新为myrepo_svn_WS

所以,目前,myrepo_git_LS.git 显示以下内容(使用与上面相同的 git log --graph... 命令):

* 03ed433 (HEAD, master) : damnit, null edit again
* de3bd53 : previous null edit passed
* 65bf738 : again null edit - no improvement
* 62ab3f6 : still bad; trying again w null edit
* 14f5aba : another null edit; previous was bad
* f0ef194 : null edit - starter

所以,myrepo_git_LS.gitmyrepo_git_wc 具有相同的提交,正如预期的那样 - 到目前为止一切都很好。

起初,myrepo_gitsvngit log --graph ... 显示此内容

* 964b300 (HEAD, git-svn, master) : null edit - starter

所以myrepo_gitsvn 是最旧的“空编辑”提交(尽管哈希值不一样);这与myrepo_svn_WS 所在的版本相同。我也想在myrepo_gitsvn repo 中添加新的提交——所以,从myrepo_gitsvn,我愿意:

git pull --rebase origingit master

... 它应该从myrepo_git_LS.git 中提取提交。现在,myrepo_gitsvn 显示了这个git log --graph...

* 03ed433 (HEAD, master) : damnit, null edit again
* de3bd53 : previous null edit passed
* 65bf738 : again null edit - no improvement
* 62ab3f6 : still bad; trying again w null edit
| * 964b300 (git-svn) : null edit - starter
...
* | 14f5aba : another null edit; previous was bad
* | f0ef194 : null edit - starter
...

有点奇怪,在这里我得到了最旧的“null edit - starter”提交两次;此处还显示了原始提交 SHA。此时,图树显示为拆分(即 git 和 SVN 提交分别显示)。

所以,我在想,如果我在这里 git svn rebase 这样做(就像我通常在我的工作流程中所做的那样,我以前没有遇到过问题),那么 repo 将能够“压缩”这些提交。不幸的是--verbose 没有在这里透露太多细节,但这是在myrepo_gitsvn 中运行此命令时的输出:

$ git svn rebase
user@ssh.server's password:
First, rewinding head to replay your work on top of it...
Applying: : still bad; trying again w null edit
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging folder/file.tex
CONFLICT (content): Merge conflict in folder/file.tex
Failed to merge in the changes.
Patch failed at 0001 : still bad; trying again w null edit

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".

rebase refs/remotes/git-svn: command returned error: 1

因为它说它在“仍然很糟糕;再次尝试 w null 编辑”时失败,这是提交 62ab3f6 - 我只是检查了文件的修订版(尽管如果我编辑文件也会发生同样的情况在文本编辑器中手动);然后在myrepo_gitsvn中问rebase--continue

$ git checkout 62ab3f6 folder/file.tex 
$ git add folder/file.tex
$ git rebase --continue
Applying: : still bad; trying again w null edit
Applying: : again null edit - no improvement
Applying: : previous null edit passed
Applying: : damnit, null edit again

看起来不错;但是如果我现在在myrepo_gitsvn 中执行git log --graph ... 命令,我会得到:

* eef9e50 (HEAD, master) : damnit, null edit again
* 9b2af2d : previous null edit passed
* 380b0f9 : again null edit - no improvement
* a41db2b : still bad; trying again w null edit
* 964b300 (git-svn) : null edit - starter

如果你与原始状态进行比较——除了提交的 SHA 哈希值不一样,还有另一个问题:提交“another null edit; previous was bad”(应该是在“null edit - starter”和“仍然很糟糕;再次尝试 w null edit”之间)不再存在?!!基本上,我现在可以git svn dcommit这个状态——它会被上传到SVN服务器而不会出错;但我会丢失其中一个提交 - 这可能会在以后的变基期间导致问题!

因此,此时我通过像这样重置来删除myrepo_gitsvn 中的最新提交:

git reset --hard 964b300
git svn reset -r446
git svn rebase

...这带来了这篇文章开始时的状态(所以我可以无限期地循环这个过程)。

我的问题是——我能做什么,所以所有最初存在于 git 端的提交,也被 svn 端识别和集成;或者换句话说,我怎样才能强制git svn 也接收这个丢失/丢失的提交?

【问题讨论】:

具有不同哈希的提交是不同的提交。 如果您尝试仅列出特定点的提交,请告诉日志您要停止的位置。如果有任何你不期望的东西,grep 会隐藏它。只需执行 --all -50 或其他操作即可获得最新的 50。 回去根据以上两个再做一遍,注意日志显示的分支结构。 感谢@jthill - 您对列表的看法是正确的;但在这种情况下,这不是问题(我确实先检查了完整的日志,然后用 grep 重新检查以获得更紧凑的代码以在此处发布)。对于哈希, git svn 以某种方式在提交消息中集成了git-svn-id:,从而改变了哈希; - 一旦git svn dcommit 完成,那么所有提交都应该有一个git-svn-id:,并且图树不再分裂。 【参考方案1】:

只是一些笔记;看起来,这与“null edit - starter”提交存在两次有关。我在拆分树图中看到它的方式:

| * 表示 git-svn 提交,即带有“SVN”SHA 哈希的提交 顶部的 * 表示“普通 git”提交,它只有一个 git SHA 哈希 和* | 表示提交带有 git SHA 哈希 - 但显然也已经存在于 SVN 中!

这意味着,* | 14f5aba : another null edit; previous was bad 意味着不知何故,git-svn 得到了这个 存在于 SVN 中的信息 - 但这是 rev 447,“null 编辑 - starter”是 rev 446 - SVN 的头是 446。

但是 - 它是 446,因为在之前的尝试中,我试图 Manually deleting only the latest revision from online SVN repository? - 显然,SVN 树中有一个状态 also 是 447,所以 git-svn 以某种方式记录了那。

此时,我尝试了第一个 Remove specific commit - 14f5aba 一个,但这没有用;显然,git 和 SVN 提交之间的这种绑定记录在其他地方。所以我所做的是在 SVN 上“伪造”提交修订版 447(因为我已经拥有相同修订版的源 git,我可以执行相同的补丁和相同的提交消息,从而产生相同的 git 哈希) - 和这允许在下一次变基时最终找到提交。但是后来我在同一个回购中遇到了其他麻烦......所以,最终我不确定这是否就是它的全部......

【讨论】:

以上是关于git svn rebase 错过/丢失提交(在 rebase --continue 由于合并冲突)?的主要内容,如果未能解决你的问题,请参考以下文章

git rebase 压缩提交

git rebase需要每个提交的签名

git rebase -i 合并多次提交

【Git】rebase 用法小结

自定义 Git *Rebase* 提交消息模板

Git工作流程和rebase与合并问题