git-svn:为master重置跟踪

时间:2010-05-14 16:23:35

标签: svn git merge git-svn

我正在使用git-svn来处理SVN存储库。我的工作副本是使用git svn clone -s http://foo.bar/myproject创建的,因此我的工作副本遵循SVN(主干,标签,分支)的默认目录方案。

最近,我一直致力于使用git-svn branch myremotebranch创建的分支,并使用git checkout --track -b mybranch myremotebranch签出。我需要在多个位置工作,所以从分支I git-svn dcommit - ed文件定期到SVN存储库。

完成更改后,我切换回主服务器并执行合并,提交合并,并尝试将成功合并提交到远程主干。

似乎在合并之后,主人的远程跟踪已切换到我正在处理的分支:

# git checkout master
# git merge mybranch
... (successful)
# git add .
# git commit -m '...'
# git svn dcommit
Committing to http://foo.bar/myproject/branches/myremotebranch ...
#

有没有办法可以更新主服务器,以便它在合并之前跟随remotes/trunk

我正在使用git 1.7.0.5,如果有任何帮助的话。

如果您还可以解释为什么发生这种情况会很有用,这样我就可以避免问题再次发生。谢谢!

修改

这是我当前的.git/config

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    autocrlf = false
[svn-remote "svn"]
    url = http://foo.bar/myproject
    fetch = trunk:refs/remotes/trunk
    branches = branches/*:refs/remotes/*
    tags = tags/*:refs/remotes/tags/*
[branch "mybranch"]
    remote = .
    merge = refs/remotes/myremotebranch

所以似乎行李箱指向正确的位置。但是,切换到分支然后回到主设备没有帮助;主人中的git svn dcommit仍然试图推送到myremotebranch

6 个答案:

答案 0 :(得分:22)

当trunk没有变化时,git会进行快进合并,只需将本地“master”分支设置为分支上的提交即可。 Git-svn不知道如何将快进合并提交回trunk,事实上它认为“master”现在指向svn分支。

要解决此问题,请在合并时使用git merge --no-ff。这将强制git创建一个合并提交,然后可以将其提交给svn。

答案 1 :(得分:13)

如果你在切换回master后使用git svn rebase并使用--squash,你可以避免这种情况。

# git checkout master
# git svn rebase   //(<--the missing step)
# git merge --squash mybranch // (<-- doesn't commit, more like an svn merge would do)
... (successful)
# git add . 
# git commit -m '...' 
# git svn dcommit
Committing to http://foo.bar/myproject/trunk...
#

解决当前状态(即主人指向SVN分支)

你可以'切换'到另一个分支,删除master,'切换'回到它然后再合并:

# git checkout mybranch
# git branch -D master
# git checkout -b master trunk
... continue with merge...
# git merge --squash mybranch

...您现在已将mybranch合并为master并准备好commit然后dcommit转为trunk

答案 2 :(得分:5)

如果您没有对master进行任何提交,则表示git merge mybranch是快进的:master HEAD只需移至mybranch HEAD

这可以解释为什么git svn dcommit将您的更改推送到SVN mybranch 它会:

  • 首先使用尚未提交的最后一个Git mybranch提交更新相应的SVN分支,
  • 在SVN端记录合并到中继
  • 然后它会在Git方面改变主人(没有什么可做的,已经存在)。

我不认为master没有改变它的引用,但是如果你有疑问(并且你的工作目录是干净的),你可以(如果master当前已经签出):

git reset --hard remotes/trunk

答案 3 :(得分:4)

一般情况下,不应将git mergegit svn一起使用,因为即使使用分支,svn也不支持git所做的合并跟踪。当你需要合并一个分支时,我已经取得了最大的成功(至少在最近的svn中)做了一个简单的svn签出/合并过程,然后使用git svn rebase来更新我的git-svn存储库。这保留了svn的原生合并跟踪元数据,(AFAIK)git-svn完全不知道。

我不完全确定你的svn存储库处于什么状态 - 我会检查以确保合并dcommit在主干上执行了你想要的操作。即使它做了, 我敢打赌,如果您查看回购邮件中refs/heads/masterrefs/remotes/trunk文件的内容,您会发现它们目前不同。如果是这种情况,我会(没有本地更改)执行git-svn fetch后跟git branch -f master remotes/trunk; git reset --hard master重新同步git分支与git-svn跟踪分支。如果您有本地更改,则必须提交并执行git rebase master^4 --onto remotes/trunk之类的操作,其中4是您需要保留的提交数。或者,如果他们都未提交,请先使用git stash隐藏它们。

如果做不到这一点,你可以随时把所有东西都放到svn中,然后擦拭回购并获得新的结账。

答案 4 :(得分:3)

我们已经在git-svn功能分支开发中成功使用了git merge --squash。 git-svn的问题在于,当你的本地git-svn克隆可以存储合并信息时,一旦你提交到svn存储库,它就会丢失。

因此,对于其他(git-)svn用户,合并提交看起来就像普通提交一样。壁球与git merge --no-ff相同(例如,在master上生成合并提交),但它还包括在合并的分支中进行的实际提交的列表,否则在提交时将丢失。

答案 5 :(得分:0)

我有同样的问题,我将remotes / trunk合并回master,之后git svn info指向trunk

当我离开项目时,我没有时间实施dcommit,而我的git-svn repo因我的恶化而死亡。我确实试过了dcommit --dry-run,它说它会回到trunk。

我会在我得到时间时重现设置和测试

欢呼声