我在拉取之前做了一个 git svn dcommit - 如何修复我的存储库?



我的场景有:

  • 我的本地机器 git 存储库
  • GitHub 上的遥控器
  • 局域网上的SVN服务器

SVN服务器仍然是规范的,但与GitHub存储库保持平等。其他用户只使用 SVN,而我是唯一的 git+SVN 用户(这简化了事情(。

当我在其他计算机上工作时(例如我的笔记本电脑,从家里,在国外(,我使用 git 并使用 GitHub 存储库推送/拉取我的提交。直到我在办公室,我的提交才会放入SVN。

当我在办公室时,我会做一个git pull,从GitHub引入任何新的提交,然后做git svn dcommit,然后git push -f回GitHub,这样新的SVN注释提交成为GitHub上的佳能并完美匹配SVN。

但是,今天我在办公室计算机上有一些待处理的提交 - 但我也有非拉取提交 - 我不知道如何解决它。

今天早上 9 点,在运行任何命令之前,我的存储库如下所示:

o = Normal Git commit, lacking SVN annotation
* = SVN-annotated Git commit
GitHub
*---*---*---*---o---o---o---o---o
A   B   C   D   E   F   G   H   I
Local computer git repo
*---*---*---*---o---o
A   B   C   D   E   F
SVN
*---*---*---*
A   B   C   D

说明:我有两个提交,EF,它们在我的本地计算机存储库中,以前是从 GitHub 中提取的,这些提交尚未dcommit到 SVN。

我今天早上犯了一个错误,因为我立即在本地计算机上运行了git svn dcommit,而没有先运行git pull。运行git svn dcommit导致存储库进入此状态:

GitHub
*---*---*---*---o---o---o---o---o
A   B   C   D   E   F   G   H   I
Local computer git repo
*---*---*---*---*---*
A   B   C   D   E'  F'
SVN
*---*---*---*---*---*
A   B   C   D   E'  F'

请注意,EF现在E'F',因为它们已被git svn修改为SVN 注释的提交(因此它具有不同的提交哈希,即使它表示相同的代码库状态(。我的原始EF在 GitHub 中保持不变。

无论如何,我的计算机都会在后台进行git fetch,所以我现在在我的计算机上有 GitHub 提交EI,GitKraken 向我展示了我现在如何拥有在提交D后发散的并排分支:

Local computer git repo:
*---*---*---*---*---* (master)
A   B   C   D   E'  F'

-o---o---o---o---o (remote-master)
E   F   G   H   I

我该如何解决这个问题?(因为 Git-SVN 注释的提交实际上是不可变的(。

我想我想做的是在F'之后重新设置G父级,因此忽略EF,然后运行git svn dcommit,然后git push -f回到GitHub。

。问题是,我不知道如何重新设置G的父级 - 我正在查看像cherrypick这样的命令,但这似乎不是我想要的,GitKraken 不会让我rebase(它不是remote-master分支中任何内容的菜单选项(。

你能使用命令行吗?

git rebase F I --onto master

即从 F(不包括(之后到(包括(I 到 master 的变基提交。

有多种方法应该没问题。

git cherry-pick master..remote-master

将挑选所有remote-master但不在master中的提交,并且EF引入与E'F'相同的更改,提交将为空,您可以跳过它们。
当然也可以直接做

git cherry-pick F..remote-master

git rebase master remote-master

也应该工作。它尝试将所有remote-master但不master的提交应用到master上。不会更改任何E'F'的提交应自动跳过,因为它们的更改已在该分支中。
或者,您当然也可以这样做

git rebase --onto master F remote-master

git pull --rebase

也应该像git rebase master remote-master一样工作.

由于您始终需要重写的线性历史记录才能与SVN存储库进行干净的对话,因此您可能应该更改配置,以便pull自动执行rebase而不是merge。然后,您还可以生成干净的历史记录,以便在同时提交多个框时轻松dcommit

最新更新