Git Svn dcommit 错误 - 重新启动提交
Posted
技术标签:
【中文标题】Git Svn dcommit 错误 - 重新启动提交【英文标题】:Git Svn dcommit error - restart the commit 【发布时间】:2010-10-12 08:35:53 【问题描述】:上周,在周末离开城镇之前,我对当地的分支机构进行了一些更改。今天早上我想将所有这些更改提交到公司的 Svn 存储库,但我在一个文件中遇到了合并冲突:
提交期间的合并冲突:您的文件或目录“build.properties.sample”可能已过期:版本资源与事务中的资源不对应。请求的版本资源已过期(需要更新),或者请求的版本资源比事务根更新(重新启动提交)。
我不确定为什么我得到了这个,但是在尝试 dcommit 之前,我做了一个 git svn rebase。那“覆盖”了我的提交。为了从中恢复,我执行了 git reset --hard HEAD@1。现在我的工作副本似乎在我期望的位置,但我不知道如何克服合并冲突;实际上我找不到任何需要解决的冲突。
任何想法都将不胜感激。
编辑:只是想说明我在本地工作。我有一个引用 svn/trunk (远程分支)的主干本地分支。我所有的工作都是在本地主干上完成的:
$ git branch
maint-1.0.x
master
* trunk
$ git branch -r
svn/maintenance/my-project-1.0.0
svn/trunk
同样,git log 目前在我的本地主干上显示了自上次使用 Svn ID 提交以来的 10 次提交。
希望这能回答一些问题。
再次感谢。
【问题讨论】:
可能是“git svn rebase”(在您的本地主干上)首先可能允许您“git svn dcommit”?不过,请先备份您的数据;) 这就是我首先做的,实际上(我仍然习惯在提交之前做 svn update)。当然,它覆盖了我的本地提交。我使用 reflog 重置为我之前的提交(在 rebase 之前),现在我回到了我应该在的地方......除了我不能提交。 :-) 我在我的答案的评论中添加了精确度,但您应该保持本地主干不变(您的所有工作都应该在专门的开发分支上重播)。这样,您可以“svn rebase”您的主干,将其与远程主干同步,然后将该本地主干重新设置在专用的主分支上...... ... 然后使用本地提交更新该主(或开发)分支,然后是“svn dcommit”。我相信如果本地中继和远程中继不同步,“svn dcommit”将不起作用,并且由于您实际上正在处理它......它将*保持不同步 所以现在我有一个远程分支 (svn/trunk)、一个本地分支 (trunk) 和一个 工作 主干 (local-trunk)?这似乎是一个荒谬的分支数量,只是为了完成一些简单的工作。三合一的方法真的是最佳实践吗? (我的意思是作为一个诚实的问题) 【参考方案1】:你应该已经创建了一个本地分支,并完成了工作,然后当你回来时,你更新 master,rebase 到本地分支,合并回 master 然后 dcommit。
所以我会尝试复制更改,以备份它们。
从 has svn 同步点创建一个本地分支,在其中合并您的更改。然后撤出 master 分支中的更改,获取,rebase 到分支,从本地分支合并,修复任何冲突,然后 dcommit。
$ git checkout -b backup # create a local backup branch with all your work
$ git checkout master
$ git checkout -b backup2 # 2nd copy just to be safe
$ git checkout master
$ git reset --hard <this is the revision of the last svn-id> # clean up master to make the svn merge easier
$ git svn fetch # this should update to the current version on the svn server
$ git rebase master backup # may get a conflict here, fix and commit
... # after conflict is fixed and commited
$ git checkout master
$ git merge backup --ff # merge in your local commits
$ git svn dcommit # push back to the svn
您可以获取更多信息here
另一个你可能感兴趣的answer。
git-svn 工作流程文章
Article
【讨论】:
新的 git 用户,所以慢点。 :-) 我有一个本地分支trunk,从远程分支svn/trunk 签出。这项工作在我当地的主干分支上。大约有 12 个提交,其中许多带有共享文件。如果可能的话,我需要保留提交历史,而不是重建它。 运行git分支,如果你只有“master”,你就没有本地分支:P 做一个 git log 来找到最后一个被 svn id 标记的点。 我有: > $ git branch maint-1.0.x master * trunk git log 命令显示了我的 10 次本地提交,因为另一个团队成员上次提交 Svn。 (对上一条评论中的格式感到抱歉。我认为 markdown 也可以在 cmets 中使用)【参考方案2】:非常感谢 VonC 和 sfassen 对我的非凡耐心,解决方案本身就成功了。我不知道如何或为什么,但也许我最初的变基没有奏效。为了解决它,我最终再次变基。从我当地的主干分支:
$ git co -b backup # backup the commits to my local trunk
$ git co trunk # return to the local trunk
$ git svn rebase # rebase the trunk from the Svn server
$ git br -d backup # delete the backup branch
当然,关键是这次变基起作用了。我不知道为什么当我第一次这样做时它不起作用,但我不能让时钟倒退,所以我不会纠缠于此。
再次感谢大家的建议和对新手的耐心。
【讨论】:
是的!很高兴你解决了!但是,我会将本地主干保留为 svn/trunk 的本地镜像,而不对其进行任何修改:因为分支和(最重要的是)合并在 Git 中很便宜……如所述在“主”或本地开发分支上工作在我的回答中,dcommit 可能会“更容易” 很高兴它成功了。不过,您需要接受其中一个答案才能将其从未回答的问题中删除。 @sfossen:会的。 @VonC:我不确定我是否完全理解这条路。听起来我有一个远程分支和两个本地分支,出于某种原因,这对我来说没有意义。便宜与否,这对我来说就像是过度杀伤力。你能得到补救来概述推理吗? @Rob Wilkerson:将本地主干保留为 svn/trunk 的镜像的原因是,您有一个稳定的/易于更新/分支的点。拥有主干的第二个本地开发分支,可以更轻松地合并和备份。 ... 此外,如果您需要分支,对于特殊功能,您已经有了合适的点。我会在我的答案中添加一些文章。【参考方案3】:要完成sfossen的excellent answer,这里有一些细节:
使用git-svn
,默认情况下您会获得一个名为 master 的本地分支。你不应该对它做任何工作,只用 svn 主干分支保持它是最新的:
git svn fetch
从本地主干分支上的 svn 主干分支获取历史记录:它不会将这些修改应用于您的工作目录
git checkout master
打开主干分支(仅当您在另一个分支上时)
git rebase trunk
同步主干和主干。
但是,您的所有修改都应该在另一个本地分支上完成(我们称之为local-devel
)。
git branch local-devel
git checkout local-devel
如果您有紧急修复工作要做:
git checkout master
: 开启 master(),
git svn fetch
&& git rebase trunk
用 svn trunk 更新它
git branch fastfix && git checkout fastfix
,分支吧
修复bug,编译,测试,
git commit -a
:本地提交,
git svn dcommit
更新远程svn repo的修改
git checkout master && git rebase trunk
:再次更新master
git branch -D fastfix
:删除修补程序分支
git checkout local-devel && git rebase master
:返回 dev,在你的 dev 分支上重放 master 上完成的更新历史记录
一开始有点麻烦,但比文件中的svn diff
更舒服,稍后应用。
【讨论】:
我已对帖子进行了相应的编辑,但我正在当地分支机构工作。不过,我仍然无法 dcommit 我的本地提交。 git 抱怨的文件是我在本地提交中修改的文件。我怎样才能告诉它保留我的或至少看到差异? 是的,问题来自您在本地主干分支上的工作,而不是专用分支。 local/trunk 应该只用于与远处的 svn 中继同步。 可能是“git svn rebase”(在您的本地主干上)首先可能允许您在之后“git svn dcommit”? 嗯。我想我不明白。你是说我应该直接在我的 git 存储库的 svn/trunk 上工作吗?如“git co svn/trunk”? 我的意思是:它看起来像主干(你工作过的)和 svn/trunk 不同步,因此我建议在你的主干上创建一个“git svn rebase”(不是 svn /trunk),在从任何分支进行任何“git svn dcommit”之前。先同步本地和远程trunk,然后dcommit【参考方案4】:我也遇到过类似的情况。我正在通过糟糕的网络连接执行git svn dcommit
,但它在某些时候失败了。我发现问题是由于 Subversion 存储库已经有一个新的提交,但本地 git-svn 对应方认为提交不在 SVN 中。此处其他答案的解决方案没有帮助,但是这样做了:
git svn reset -r <last_svn_commit_git_was_aware_of>
git svn fetch
git svn rebase
在这之后,我终于能够做到git svn dcommit
没有任何错误。
【讨论】:
【参考方案5】:我打算发表评论,但认为这值得更多关注......
git svn rebase
应该重写你的提交。从描述和 cmets 中,我得到的印象是,在您重新设置基准后,您将旧的提交重新置于顶部。必须将提交替换为不冲突的较新版本。
为避免深入阅读 reflog,您可能需要养成在执行 git svn dcommit
之前快速标记的习惯。 dcommit 成功后,删除标签。如果标记失败,您可以执行git reset --hard
后跟git merge <tag>
。重新运行您的 rebase 以恢复您的历史记录,重新标记并再次重新提交。
【讨论】:
是的,我仍然在通过我的 svn 思维方式工作,所以在我提交之前我一直在做 Git 版本的 svn update。一旦我意识到我做了什么,它覆盖了我的提交这一事实并没有让我感到惊讶。但是,一旦完成,我就必须努力回到变基之前的位置。 你不应该在 rebase 后与任何东西战斗。如果你是,那是有问题的。您所有尚未推送到 svn 的本地提交应该仍然存在。如果你在 rebase 期间遇到冲突,那就是另一个问题了。 如果您还没有,请尝试使用 GUI 前端之一来可视化分支。我自己更喜欢 'gitk --all'。【参考方案6】:我在几个地方读到,使用 git svn 使用单独的分支是不好的做法。与 git 提交有关的内容未按您预期的方式显示在 svn 中。
http://progit.org/book/ch8-1.html 的以下回答似乎是最干净的方式:
git svn rebase
git svn dcommit
我也尝试了上面最受欢迎的选项,但它并不总是对我有用,因为 git rebase 不会回滚以匹配上游的 svn,而只是回到最后一个 git commit。
【讨论】:
以上是关于Git Svn dcommit 错误 - 重新启动提交的主要内容,如果未能解决你的问题,请参考以下文章