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 &amp;&amp; git checkout fastfix,分支吧 修复bug,编译,测试, git commit -a:本地提交, git svn dcommit 更新远程svn repo的修改 git checkout master &amp;&amp; git rebase trunk:再次更新master git branch -D fastfix:删除修补程序分支 git checkout local-devel &amp;&amp; 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 &lt;tag&gt;。重新运行您的 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 错误 - 重新启动提交的主要内容,如果未能解决你的问题,请参考以下文章

如何撤消 git svn dcommit?

将 svn 迁移到 git,分支名称中有空格

SVN 结帐失败,“块分隔符无效”

拾遗:Git 与 Svn hook 不执行问题

SVN自启动 OpenSCManager 失败 5解决方法

3配置中心