首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么一个与两个提交者共享的git分支会有多个提交两次?(可能与git-svn交互)

为什么一个与两个提交者共享的git分支会有多个提交两次?(可能与git-svn交互)
EN

Stack Overflow用户
提问于 2012-03-03 01:26:04
回答 1查看 203关注 0票数 0

当我设置我的分支时,我做了:

代码语言:javascript
复制
git svn rebase
git checkout -b branch-a

然后,我将该分支推到远程git存储库,我的一位同事和我使用git commitgit pullgit push进行了工作。

现在,我想从subversion中引入所有新的更改,所以我做到了:

代码语言:javascript
复制
git checkout master
git svn rebase
git checkout branch-a
git rebase master

在这一点上我很困惑。似乎发生的情况是,git将与一个或更多的冲突达成承诺,并迫使我解决这些冲突。但是,冲突似乎是将头指向树梢(使用最新的代码),然后尝试将每个更改逐个应用到顶部,就像将它们应用到原始分支点一样。

感觉好像我再次重写了所有的代码,而大多数的解决方案都是保留头块并去掉提交块。

我的期望是,git rebase master命令将从分支之前的提交开始,从主服务器添加每个提交,然后在分支上添加每个提交。这样就会在树枝上产生一个与重基之前几乎完全相同的尖端。

有谁能解释我为什么不明白。如果做不到这一点,谁能建议如何找出git决定这么做的原因。我会在git log中寻找什么,看看它为什么要这么做。

编辑: 2012-03-06的进一步研究表明,在我们的分支和分支结构中,似乎有多个提交副本,而当我们认为只有一个分支时,git log --graph显示了多个分支。

片段(标识已删除的详细信息和提交消息已被message-n替换。Message-n指相同的消息):

代码语言:javascript
复制
| * | commit f5c48df66ed9d733364562d8f125866aa6483c1e
| | | Author: commiter-b
| | | Date:   Mon Feb 27 16:18:05 2012 -0800
| | | 
| | |     Message-4
| | |    
| * | commit e6115229e629c237b08d0b2e149353f33ff66bd1
| | | Author: commiter-a
| | | Date:   Mon Feb 27 15:49:02 2012 -0800
| | | 
| | |     Message-3
| | |    
| * | commit f85981736c59231dc34a7cef4fceab5cffdbdff2
| |/  Author: committer-a
| |   Date:   Mon Feb 27 14:20:56 2012 -0800
| |   
| |       Message-2
| |   
| * commit b09ba82e6290f5905d4c98fdcfbe2220d221e762
|   Author: committer-a
|   Date:   Mon Feb 27 14:04:13 2012 -0800
|   
|       Message-1
|  
* commit 4d2892c239acfab5c9845518fde98ba551f273e6
| Author: committer-a
| Date:   Mon Mar 5 09:13:19 2012 -0800
| 
|     UN-3710 Fixes after merge from svn

---8<----- snip

* commit 8307d1ae8214ebe3eac5bdc5b835c21f89d727bd
| Author: committer-b
| Date:   Mon Feb 27 16:18:05 2012 -0800
| 
|     Message-4
|  
* commit 859acc56de59877cb721914443c63ad97882cb41
| Author: committer-a
| Date:   Mon Feb 27 15:49:02 2012 -0800
| 
|     Message-3
|  
* commit 93e15921d735333194970cefc673a8b953e80838
| Author: committer-a
| Date:   Mon Feb 27 14:20:56 2012 -0800
| 
|     Message-2
|  
* commit 7a863bb44be5c5019a0e0958460324dc3cfb2e6b
  Author: committer-a
  Date:   Mon Feb 27 14:04:13 2012 -0800

      Message-1

我相信我们的git工作流程是保守的。我们使用git-svn来维护被推送到远程git存储库的master。我们将master分支,两个或多个提交者使用git pull origin branch-agit push origin对其进行工作。

既然我们已经注意到了问题的这一特点,我们将在未来仔细观察到底是什么事件造成了问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-03 05:04:23

首先,快速总结一下git rebase所做的工作。

如果你有这样的历史记录:

代码语言:javascript
复制
trunk  branch
  |   /
  B  C
  | /
  |/
  A
  |
  |

当你在git rebase trunk上玩branch的时候,你得到的是:

代码语言:javascript
复制
trunk/branch
   |
   C
   |
   B
   |
   A
   |
   |

这就是为什么它被称为rebase的原因--以前branch的基础是提交A --这就是它与“上游”分支trunk分离的地方。操作结束后,新的基础是B,新的HEAD of trunk。你已经重新建立了它。

git svn rebase只是自动地这样做,将您所做的更改移植到来自SVN的新提交中。

现在,有一个问题。对于歇斯底里的葡萄干,git-svn不使用git注释来存储其元数据。相反,它重写提交对象本身,在每个提交消息的末尾添加git-svn-id行。这将导致每个提交的SHA1标识符发生更改。因此,即使是相同的提交也是不同的--并且可能与自己的宇宙版本发生冲突!

这很可能是您尝试从git rebase masterbranch-a看到的:branch-a从以前的master状态的某个未提交到SVN版本中分离出来,所以现在当您试图合并时,您将看到两边事物之间的冲突。

这是git-svn的一个限制,一旦您将更改推送到SVN,您必须小心地只使用提交的推到SVN重写版本。不能将预提交和后提交的表单混合在一起,因为它们是“不同的”更改,内容相同。

您可以通过检查从git merge-base master branch-amasterbranch-a的更改来验证这一点。你很可能在双方都会看到同样的变化。

为了摆脱这种情况下的惯例,删除您的分支,从master中创建一个新分支,然后按照顺序从branch-a中删除更改,忽略master已经包含的更改。在未来,在使用还没有的SVN版本时要更加小心.

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9542549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档