声明:通常我在执行git svn dcommit
之前都会运行git svn rebase
。我通常将我的更改保存在另一个git分支中,以便rebase没有任何失败的机会。我在我的主题分支中使用git rebase master
将其更新。然后我切换到master
分支,并使用git merge
将主题分支的更改合并到master
(由于rebase的原因,这是一个快进)。
下面的解释说明了为什么这不是机械上必要的,但我同意这是个好主意。你的更改可能不会造成差异和合并方面的冲突,但如果你在没有获取最新的svn更改并审查其影响的情况下dcommit
你的代码,那么你可能会向svn提交不正确的代码。
在运行git svn dcommit
之前,你不一定需要运行git svn rebase
。如果你要dcommit的修改是在svn自从你上次获取更改后没有变化的文件中,那么git-svn就不会显示冲突。这样,你可以使用一个没有所有来自svn的最新更改的git存储库向svn存储库提交更改。
假设我启动了一个包含两个文件foo.txt
和bar.txt
的svn存储库。它们到目前为止只有一个修订版。我执行git svn clone
以开始使用git跟踪svn存储库。
$ git log --oneline --decorate
7e72290 (git-svn, master) 初始提交。
你对foo.txt
进行更改并将其在本地的master
分支中git commit
,因此它超前于git-svn
。
$ git log --oneline --decorate
aa70eca (master) 添加了一行到foo。
7e72290(git-svn)初始提交。
你没有意识到,你的朋友已经在svn版本号为2时对bar.txt
进行了更改。
现在当你从master
运行git svn dcommit
时,git会查找从当前位置到git-svn
结束之间的更改集。在这种情况下,只有一个:aa70eca
。git试图将该差异发送到svn存储库。
$ git svn dcommit
正在提交至 [svn存储库地址] ...
M foo.txt
提交 r3
M bar.txt
r2 = 12b95b96e11f782f31b07a78756660cb82437ca2 (refs/remotes/git-svn)
M foo.txt
r3 = d4a7b84e0383f3af5fb0db439169c9f1b8af1152 (refs/remotes/git-svn)
W: aa70ecae4121854ac3754fb882a483b67d706a4a 与 refs/remotes/git-svn 不同,使用变基操作:
:100644 100644 5771152459bfaa7cc62caa3b6b4d24e52ab8e447 dbfaecb10330d0509e092f1891a4a7e673802413 M bar.txt
首先,倒回头来重播您的工作...
无事可做。
$ git log --oneline --decorate
d4a7b84(git-svn,master)向foo添加了一行。
12b95b9 添加到bar。
7e72290 初始提交。
你可以在svn修订版本3中看到提交成功了。当git-svn将本地svn历史与svn仓库同步时,它获取了所有新的提交,包括你刚刚提交到svn的更改。你会注意到这个更改(d4a7b84
)与你在git中使用的不同 (aa70eca
)。这是由于多种原因造成的:不同的提交时间戳、可能不同的作者名称、在从svn获取的提交日志中的git-svn-id
,以及不同的祖先 - 获取的svn r3 有r2作为其父级,但你的git提交是从r1继承下来的。
在这种情况下,在获取后当前的git头(master
)和SVN之间发现了差异,因为r2中的内容更改了foo.txt
。因此,git-svn
将进行rebase操作。
如果我进行了更改并且同时没有进行其他svn提交(或者我一直运行 git svn rebase
以保持最新状态),那么git-svn
将不会在头部和SVN之间找到差异,因此它只需重置:
$ git svn dcommit
正在提交至 [svn repo address] ...
M foo.txt
已提交 r4
M foo.txt
r4 = 533f7337999778628cf39fcd9155d085eb1c2b89 (refs/remotes/git-svn)
当前HEAD和refs/remotes/git-svn之间没有变化
重置到最新的refs/remotes/git-svn
git reset
的作用取决于你使用的形式。git reset HEAD foo.txt
会将对foo
的更改从索引中撤销。git reset [--soft|--mixed|--hard|...] <commit>
根据你给出的开关移动你的分支并更改索引/工作区。 - Mike Seplowitzgit svn dcommit
传递一个参数(“可以指定一个可选的修订版本或分支参数,使得 git svn 在该修订版本/分支上执行所有操作而不是 HEAD。”),但我自己从未使用过这个功能。 - Mike Seplowitz