将本地Git提交合并为一个提交以用于git-svn

28

目前,当我运行git svn dcommit时,git会为我自上次与SVN同步以来所做的每个本地提交在SVN中创建一个单独的提交。有没有办法让dcommit将我最近的所有本地提交合并为一个提交以供SVN使用?

6个回答

18
git rebase remotes/trunk --interactive 

应该会把你带到菜单上,你可以在其中选择提交(commit)或将它们全部压缩成一个提交(commit),以避免污染你的svn仓库。 这个 是一个关于如何使用git-svn的真的不错(但很短)的资源。


这似乎是一个非常好的解决方案。我不明白命令中remotes/trunk的影响是什么,最终结果是所有我的提交都被压缩在主分支内。我希望它们只会在发送到SVN时被压缩。在压缩完成后,有必要提交到SVN。 - MacRae Linton
@MacRae Linton:你的所有提交必须在主分支中合并。如果没有这样做,Git 就无法保持 Git 和 SVN 存储库同步。当你进行重新基于拉取最新更改时,SVN 将只有一个提交,但在 Git 中却有 n 个提交。 - Jason Punyon
@Jason Punyon:我遇到的问题是,在主分支中压缩提交后,再次将主分支与我的开发分支合并变得困难。几乎所有的更改都会成为合并冲突,这非常麻烦。这是否是将我的开发分支与压缩的主分支分开保持的不可避免的后果? - MacRae Linton
@MacRae Linton:是的,这是个问题。不建议对已经在其他地方复制的提交使用rebase。以这种方式重写历史会导致你描述的合并冲突问题。 - Jason Punyon
@Jason:所以,最终没有办法为git和svn维护单独的历史记录。如果我想要一个简略的svn历史记录,那么这个历史记录也必须是git中的历史记录吗? - MacRae Linton
对我来说不起作用。我认为它必须是“refs/remotes/trunk”。 - Martin Konicek

17
不行,但你可以很容易地把所有的提交压缩在一起。对于以下示例,我会假设你在与远程trunk分支对应的master分支上,并且想要将所有本地提交压缩在一起:
git tag local # create a temporary tag
git reset --hard trunk
git merge --squash local
git commit # write your single commit message here
git svn dcommit
git tag -d local # delete the temporary tag named local

你可以使用 reflog(即使用 master@{1} 替换 local)而不是使用临时标签。


这太酷了,这完全改变了我的工作流程,非常感谢。 - Fire Crow

3
当我使用git-svn并且想让一系列git提交显示为单个提交时,我会在一个主题分支上工作,然后在dcommit之前将其非快进合并到主分支中。
首先,对您的分支进行svn变基,并确保本地主分支是最新的:
git svn rebase && git push . remotes/trunk:master

然后切换到主分支,合并并提交更改:
git checkout master
git merge <branch> --no-ff -m "Message you want in svn"
git svn dcommit

这将显示为Subversion中的单个提交,但您仍将拥有到达该提交的本地历史记录。
                                       +--- Merge commit
                                       V
svn trunk  *---*---*-------------------*--- --- ---
                    \                 /
topic branch         *---*---*---*---*

3
一种更简单的方法是(如果您在本地系统上有多个提交):
git reset <hash tag of commit till which u need to combine>
git commit -am "your message"  // This will create one clubbed commit of all the commit till the hash tag used.

2
请确保您添加了任何新文件。 "git commit -am" 本身不会添加新文件。 - Akash Agrawal
1
另外,使用 reset --soft 命令将会保留所有已暂存的更改,这样您就不必担心添加文件或使用 -a 命令了。 - PeterJCLaw

2

0

这对我不起作用。我使用merge --no-ff --no-commit,但提交后,我得到了:

svntrunk                        54f35e4 [trunk: ahead 336] release 1

提交到主干 trunk 将会提交所有的336个commit。

重置、标记和压缩,就像回答#2中描述的那样:将本地Git提交合并为一个git-svn提交,这样做是可以的,但在下一次"合并"时,你可能会遇到一些困难,无法再次获得所有的提交!

对我来说,唯一有效的方法是:

git checkout -tb svntrunk remotes/trunk
git merge --no-commit --squash master

为了在未来使用相同的命令进行合并而不丢失历史记录,从主分支到svn获取所有提交

~ Marcel


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接