git-svn:重置 master 的跟踪
我正在使用 git-svn 来处理 SVN 存储库。我的工作副本是使用 git svn clone -s http://foo.bar/myproject 创建的,以便我的工作副本遵循 SVN 的默认目录方案(主干、标签、分支)。
最近,我一直在研究一个使用 git-svnbranch myremotebranch 创建并使用 git checkout --track -b mybranch myremotebranch 签出的分支。我需要在多个位置工作,因此我经常从分支将 git-svn dcommit 文件发送到 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
所以看来主干指向正确的位置。然而,切换到分支然后返回主分支并没有帮助; master 中的 git svn dcommit 仍尝试推送到 myremotebranch。
I'm using git-svn
to work with an SVN repository. My working copies have been created using git svn clone -s http://foo.bar/myproject
so that my working copy follows the default directory scheme for SVN (trunk, tags, branches).
Recently I've been working on a branch which was created using git-svn branch myremotebranch
and checked-out using git checkout --track -b mybranch myremotebranch
. I needed to work from multiple locations, so from the branch I git-svn dcommit
-ed files to the SVN repository quite regularly.
After finishing my changes, I switched back to the master and executed a merge, committed the merge, and tried to dcommit the successful merge to the remote trunk.
It seems as though after the merge the remote tracking for the master has switched to the branch I was working on:
# git checkout master
# git merge mybranch
... (successful)
# git add .
# git commit -m '...'
# git svn dcommit
Committing to http://foo.bar/myproject/branches/myremotebranch ...
#
Is there a way I can update the master so that it's following remotes/trunk
as before the merge?
I'm using git 1.7.0.5, if that's any help.
It would be useful if you could also explain why this happened, so I can avoid the problem happening again. Thanks!
Edit:
Here is my current .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
So it seems that the trunk is pointing to the correct place. However, switching to the branch then back to the master doesn't help; git svn dcommit
in the master still tries to push to myremotebranch
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
当主干上没有更改时,git 会进行快进合并,并将本地“主”分支设置为您分支上的提交。 Git-svn 不知道如何将快进合并提交回主干,事实上它认为“master”现在指向 svn 分支。
要解决此问题,请在合并时使用 git merge --no-ff 。这将强制 git 创建一个合并提交,然后可以将其提交到 svn。
When there are no changes on trunk, git does a fast-forward merge and simply sets the local "master" branch to the commit on your branch. Git-svn doesn't know how to commit fast-forward merges back to trunk, in fact it thinks "master" now is pointing to the svn branch.
To work around this, use
git merge --no-ff
when merging. This will force git to create a merge commit, which can then be dcommitted to svn.如果您在切换回 master 后进行 git svn rebase 并使用 --squash ,则可以避免这种情况。
要解决当前状态(即您的 master 指向 SVN 分支),
您可以“切换”到另一个分支,删除 master,“切换”回它,然后再次合并:
...您现在已将 mybranch 合并到 master 中,并且准备好
commit
,然后dcommit
到trunk
If you
git svn rebase
after switching back to master and use --squash you can avoid this.To solve the current state (i.e. your master is pointing to an SVN branch)
You can 'switch' to another branch, delete master, 'switch' back to it and then merge again:
... you now have mybranch merged into master and ready to
commit
and thendcommit
totrunk
如果您尚未在 master 上进行任何提交,则意味着
git merge mybranch
是快进式的:master HEAD
只需移至mybranch HEAD
代码>.这可以解释为什么
git svn dcommit
将您的更改推送到SVN mybranch
。它会:
mybranch
提交更新相应的 SVN 分支,我不认为 master 没有改变它的引用,但如果你有疑问(并且你的工作目录是干净的),你可以(如果 master 当前已签出):
If you haven't made any commit on master, that means the
git merge mybranch
was a fast-forward one:master HEAD
simply move tomybranch HEAD
.That could explain why the
git svn dcommit
pushed your changes to theSVN mybranch
.It would:
mybranch
commits not yet dcommitted,I don't think master hasn't change its reference, but if you have a doubt (and your working directory is clean), you could (if master is currently checked out):
一般来说,您不应该将 git merge 与 git svn 一起使用,因为 svn 即使有分支也不支持 git 那样的合并跟踪。当您需要合并分支时,我最成功的方法是(至少在最近的 svn 中)执行简单的 svn 签出/合并过程,然后使用 git svn rebase 更新我的 git-svn 存储库。这保留了 svn 的本机合并跟踪元数据,而 (AFAIK) git-svn 完全不知道这一点。
我不完全确定你的 svn 存储库处于什么状态——我会检查以确保合并 dcommit 在主干上执行了你想要的操作。即使这样做了,
我敢打赌,如果您查看存储库中的 refs/heads/master 和 refs/remotes/trunk 文件的内容,您会发现它们在以下位置有所不同:那一刻。如果是这种情况,我会(不存在本地更改)执行 git-svn fetch ,然后执行 gitbranch -f masterremotes/trunk; git reset --hard master 将 git 分支与 git-svn 跟踪分支重新同步。如果您有本地更改,则必须提交并执行类似
git rebase master^4 --onto remotes/trunk
的操作,其中 4 是您需要保留的提交数量。或者,如果它们都未提交,请先使用 git stash 隐藏它们。如果做不到这一点,你总是可以将所有内容放入 svn 中,然后擦除存储库并重新签出。
In general, you should not use
git merge
withgit svn
, because svn, even with branches, doesn't support the kind of merge tracking that git does. When you need to merge a branch, I've had the most success (at least with recent svn) doing a plain svn checkout/merge process and then usinggit svn rebase
to update my git-svn repositories. This preserves svn's native merge tracking metadata, which (AFAIK)git-svn
is completely ignorant of.I'm not totally sure what state your svn repository is in -- I would check to make sure the merge dcommit did what you wanted it to on the trunk. Even if it did,
I bet if you look at the contents of the
refs/heads/master
andrefs/remotes/trunk
files in your repo, you'll see that they're different at the moment. If that's the case, I would (with no local changes present) do agit-svn fetch
followed by agit branch -f master remotes/trunk; git reset --hard master
to resync the git branch with the git-svn tracking branch. If you have local changes, you'll have to commit and do something likegit rebase master^4 --onto remotes/trunk
, where 4 is the number of commits you need to preserve. Alternatively, if they're all uncommitted, stash them withgit stash
first.Failing that, you can always get everything into svn and just wipe the repo and get a fresh checkout.
我们已经在 git-svn 功能分支开发中成功使用了 git merge --squash 。 git-svn 的问题是,虽然本地 git-svn 克隆可以存储合并信息,但一旦您提交到 svn 存储库,它就会丢失。
因此,对于其他 (git-)svn 用户来说,合并提交看起来就像普通提交一样。挤压与 git merge --no-ff 具有相同的作用(例如,在 master 上生成合并提交),但它还包含在正在合并的分支中进行的实际提交的列表,否则在 dcommitting 时会丢失。
We have successfully used
git merge --squash
in git-svn feature branch development. The problem with git-svn is that while your local git-svn clone can store the merge information, once you dcommit to the svn repository, it is lost.So for other (git-)svn users the merge commits look just like plain commits. The squash is good for the same thing as
git merge --no-ff
(eg. producing a merge commit on master), but it also includes a list of the actual commits made in the branch being merged, which would otherwise be lost when dcommitting.我遇到了同样的问题,我将遥控器/主干合并回主干,之后 git svn info 指向主干,
当我离开项目时,我没有时间实际进行 dcommit,并且我的 git-svn 存储库因我的糟糕而死亡。我确实尝试了 dcommit --dry-run ,它说它将提交回主干。
时,我会重现设置和测试
当我有时间欢呼
I had the same problem, and I merged remotes/trunk back into master after which git svn info pointed back to trunk
I didn't have the time to actuall dcommit as I was leaving the project and my git-svn repo died with my worstation. I did trythe dcommit --dry-run and it said it would commit back to trunk.
I'll reproduce the setup and test when I get the time
cheers