git svn:重置主服务器的跟踪

git svn:重置主服务器的跟踪,svn,git,merge,git-svn,Svn,Git,Merge,Git Svn,我正在使用gitsvn来处理svn存储库。我的工作副本是使用git svn clone-s创建的http://foo.bar/myproject以便我的工作副本遵循SVN(主干、标记、分支)的默认目录方案 最近我一直在研究一个分支,它是使用git svn branch myremotebranch创建的,并使用git checkout--track-b mybranch myremotebranch签出的。我需要从多个位置工作,因此从分支Igit svn dcommit-ed文件到svn存储库是

我正在使用
gitsvn
来处理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

如果有帮助的话,我正在使用Git1.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
如果您还没有对主机进行任何提交,这意味着
git merge mybranch
是一个快速前进的版本:
主机头
只需移动到
mybranch头即可

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

它将:

  • 首先用最后一个Git
    mybranch
    committed(提交尚未提交)更新相应的SVN分支
  • 在SVN侧记录合并到主干
  • 然后它将在Git端重新设置master的基础(无需做,已经存在)
我不认为master没有更改它的引用,但是如果您有疑问(并且您的工作目录是干净的),您可以(如果master当前已签出):


当主干上没有更改时,git会进行快进合并,并简单地将本地“主”分支设置为分支上的提交。Git svn不知道如何将快进合并提交回主干,事实上它认为“master”现在指向svn分支


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

一般来说,您不应该将
git merge
git svn
一起使用,因为svn即使有分支,也不支持git所支持的那种合并跟踪。当您需要合并分支时,我最成功的做法是(至少在最近的svn中)执行简单的svn签出/合并过程,然后使用
git svn rebase
更新我的git svn存储库。这保留了svn的本机合并跟踪元数据,而(AFAIK)
git svn
完全不知道这些元数据

我不完全确定您的svn存储库处于什么状态——我会检查以确保合并dcommit在主干上实现了您想要的功能。即使有,, 我敢打赌,如果你查看repo中的
refs/heads/master
refs/remotes/trunk
文件的内容,你会发现它们目前是不同的。如果是这样的话,我会(在没有本地更改的情况下)执行一个
git svn fetch
,然后执行一个
git分支-f master remotes/trunk;git reset--硬主机
将git分支与git svn跟踪分支重新同步。如果您有本地更改,则必须提交并执行类似于git rebase master ^4的操作—到remotes/trunk
,其中4是需要保留的提交数量。或者,如果它们都未提交,则先用
git stash
将它们隐藏起来


如果做不到这一点,你总是可以把所有东西都放到svn中,只需删除回购协议,然后重新结账。

我也遇到了同样的问题,我将remotes/trunk合并回master,然后git svn信息指向trunk

当我离开项目时,我没有时间执行所有的dcommit,我的git svn repo也随着我的工作站一起死掉了。我试过了dcommit——试运行,它说它会回到trunk

当我有时间的时候,我会复制设置和测试


干杯

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

# 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...
#

。。。现在,您已经将mybranch合并到master中,并准备好提交,然后将mybranch提交到主干,我们已经成功地在git svn功能分支开发中使用了git merge--squash。git svn的问题是,虽然本地git svn克隆可以存储合并信息,但一旦您提交到svn存储库,它就会丢失


因此,对于其他(git-)svn用户,合并提交看起来就像普通提交。挤压的作用与git merge(无ff)相同(例如,在主服务器上生成合并提交),但它还包括在合并的分支中进行的实际提交的列表,否则在进行dcommit时会丢失这些提交。

似乎在主服务器上重置、更改某些内容,
dcommit
ing,然后重新合并以产生冲突,修复该冲突,然后
dcommit
ing修复该问题。但这并不令人愉快。@digitala:你是说仅仅重置还不够吗?重置后的第一次数据提交没有发生在SVN中继上?我同意这一分析+1为了澄清,如果我理解的话,git使用“主”指针所在的提交来决定提交到哪个SVN分支。这就是为什么SVN DCOMIT步骤失败的原因,因为在完成合并后
# 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...
#
# git checkout mybranch
# git branch -D master
# git checkout -b master trunk
... continue with merge...
# git merge --squash mybranch