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

all*_*ode 14 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的文档,其中说明了这一点:

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

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

关于重置的部分我也很困惑; 是不是git重置删除暂存区域的更改?

为什么会改变或重置(d)的跟随(第一部分)?

Mik*_*itz 19

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

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


你不必git svn rebase运行前git svn dcommit.如果您要提交的修改位于自上次获取更改后svn中未更改的文件中,则git-svn将不会显示冲突.通过这种方式,您可以使用git存储库提交对svn存储库的更改,该存储库没有来自svn的所有最新更改.

假设我启动一个包含两个文件的svn存储库,foo.txt并且bar.txt.到目前为止,他们只有一个修订版.我做了一个git svn clone开始使用git跟踪svn存储库.

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

您更改foo.txtgit commit他们当地的master分支机构,因此它向前推进的git-svn.

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

你没有意识到的是你的朋友已经将修改改为bar.txtsvn修订版2.

现在当你运行git svn dcommitmaster,git会在你git-svn离开的地方和离开的地方寻找变化集.在这种情况下,你只有一个:aa70eca.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的更改.你会注意到这个change(d4a7b84)有一个不同于你曾经在git(aa70eca)中使用的SHA哈希.这是由于各种各样的事情:不同的提交时间戳,可能不同的作者名称,git-svn-id从svn获取的提交的日志中,以及不同的祖先 - 获取的svn r3将r2作为其父级,但是您的git提交来自于R1.

在这种情况下,在当前git head(master)和SVN 之间获取后发现了diff ,因为r2中的内容发生了变化foo.txt.结果,git-svn将会变形.

如果我做了一个更改并且在此期间没有发生其他svn提交(或者我一直在运行git svn rebase以保持最新),那么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

  • 重新#3:`git reset`的工作方式不同,具体取决于您使用的形式.`git reset HEAD foo.txt`从索引中取消对foo的更改.`git reset [--soft | --mixed | --hard | ...] <commit>`移动你的分支并根据你给出的开关改变索引/工作区. (2认同)
  • 回复4:我不认为这种情况经常发生,所以我并不是故意这样说.你可以给`git svn dcommit`一个参数("可以指定一个可选的修订或分支参数,并导致git svn在该修订/分支而不是HEAD上完成所有工作.")但是我从来没有用过这个我. (2认同)
  • 谢谢你的澄清,迈克。我想我现在明白了。dcommit 后进行变基(或重置)的原因是因为 dcommit 在将提交添加到(远程)svn 存储库后会拉取新的修订(包括刚刚在 dcommit 过程中早期创建的修订)。您将希望这些提交位于主分支上,这就是变基或重置的作用。只要远程 svn repo 没有领先于你(例如,你总是在 git svn dcommit 之前执行 git svn rebase ),那么它总是会在 dcommit 之后重置;否则,可能需要重新设置基准。 (2认同)