在git svn dcommit之前需要git svn rebase吗?

时间:2010-04-22 23:01:37

标签: git git-svn

我正在阅读有关在这里使用git作为svn客户端的信息:

http://learn.github.com/p/git-svn.html

那个页面暗示你在git svn dcommit之前做了git svn rebase,这很有道理;这就像在执行svn commit之前进行svn更新。然后,我开始查看git svn dcommit的文档(我想知道'd'是关于什么的):

http://git-scm.com/docs/git-svn

你必须向下滚动才能看到关于dcommit的文档,其中说明了这一点:

  

将指定头部的每个差异直接提交到SVN存储库然后重新设置或重置(取决于SVN和头部之间是否存在差异)

这让我感到困惑,因为如果你按照第一页所说的那样,一旦dcommit的第一部分结束,就不会有从svn下拉的变化。

我也对谈到重置的部分感到困惑;是不是git重置是为了从暂存区域删除更改?

为什么会重新定义或重置(dcommit的第一部分)?

1 个答案:

答案 0 :(得分:19)

免责声明:我通常在执行git svn rebase之前往往会运行git svn dcommit。我通常将我的更改保存在另一个git分支中,这样rebase就没有任何失败的可能性。我在主题分支中使用git rebase master来更新它。然后我切换到master分支,并使用git merge将我的主题分支中的更改合并到master中(由于变基,这是一个快进)。

我在下面的解释解释了为什么这不是机械必要的,但我同意这是一个好主意。您的更改可能不会在差异和合并方面造成冲突,但如果您{s =}代码没有从svn获取最新更改并查看其效果,那么您可能会将代码提交给svn,而这些代码并没有真正做到正确的事情。


在运行dcommit之前,您 <{1}}。如果您想要提交的修改是在您上次获取更改后svn中没有更改的文件中,那么git-svn将不会显示冲突。通过这种方式,您可以使用git存储库提交对svn存储库的更改,该存储库没有来自svn的所有最新更改。

假设我启动了一个svn存储库,其中包含两个文件git svn rebasegit svn dcommit。到目前为止,他们只有一个修订版。我做了foo.txt以使用git开始跟踪svn存储库。

$ git log --oneline --decorate
7e72290 (git-svn, master) Initial commit.

您对bar.txtgit svn clone他们的本地foo.txt分支进行了更改,因此它超前于git commit

$ git log --oneline --decorate
aa70eca (master) Added a line to foo.
7e72290 (git-svn) Initial commit.

您没有意识到的是,您的朋友已经将master更改为svn修订版2。

现在,当您从git-svn运行bar.txt时,git会查找您所在位置和git svn dcommit停止位置之间的变更集。在这种情况下,您只有一个:master。 git尝试将该差异发送到您的svn存储库。

$ git svn dcommit
Committing to [svn repo address] ...
        M       foo.txt
Committed r3
        M       bar.txt
r2 = 12b95b96e11f782f31b07a78756660cb82437ca2 (refs/remotes/git-svn)
        M       foo.txt
r3 = d4a7b84e0383f3af5fb0db439169c9f1b8af1152 (refs/remotes/git-svn)
W: aa70ecae4121854ac3754fb882a483b67d706a4a and refs/remotes/git-svn differ, using rebase:
:100644 100644 5771152459bfaa7cc62caa3b6b4d24e52ab8e447 dbfaecb10330d0509e092f1891a4a7e673802413 M      bar.txt
First, rewinding head to replay your work on top of it...
Nothing to do.

$ git log --oneline --decorate
d4a7b84 (git-svn, master) Added a line to foo.
12b95b9 Added to bar.
7e72290 Initial commit.

您可以看到提交成功为svn修订版3.当git-svn然后将您的本地svn历史记录与svn存储库同步时,它获取了所有新提交,包括您刚刚提交给svn的更改< / em>的。您会注意到此更改(git-svn)与您之前在git(aa70eca)中使用的哈希哈希值不同。这是由于各种各样的事情:不同的提交时间戳,可能不同的作者名称,从svn提取的提交日志中的d4a7b84,以及不同的祖先 - 获取的svn r3将r2作为其父级,但是git commit来自r1。

在这种情况下,在当前git头(aa70eca)和SVN之间获取后发现了差异,因为r2中的内容发生了变化git-svn-id。因此,master将会重新定位。

如果我进行了更改并且在此期间没有发生其他svn提交(或者我一直在运行foo.txt以保持最新状态),那么git-svn将无法在头部之间找到差异和SVN,所以它可以重置:

$ git svn dcommit
Committing to [svn repo address] ...
        M       foo.txt
Committed r4
        M       foo.txt
r4 = 533f7337999778628cf39fcd9155d085eb1c2b89 (refs/remotes/git-svn)
No changes between current HEAD and refs/remotes/git-svn
Resetting to the latest refs/remotes/git-svn