繁体   English   中英

git:如何移动分支的根两个提交回来

[英]git: how to move a branch's root two commits back

比方说我有:

A - B - C - D - E - F  master
            \ 
             \- G - H  new feature branch

现在我意识到提交B和C实际上属于新功能,所以我想将它们移动到“新功能分支”。 换句话说,我希望“新功能分支”从A开始,包括提交B和C:

A - D - E - F  master
 \ 
  \- B - C - G - H  new feature branch

我该怎么做呢? 从我读过的内容来看,似乎rebase是我正在寻找的功能,但我想在我搞砸我的存储库之前确定。

(我搜索并发现了许多非常相似的问题和例子,但没有一个与我描述的场景完全相同 ,所以我要求确定(回购是一件珍贵的事情,毕竟毁了))。

Edmundo的答案是正确的(并且已经投票),但值得指出一些额外的项目。

首先,你的问题谈到“移动分支的根” - 但这是Git; 分支机构没有根,没有你在想反正方式。 我们来看看你的图形图:

A - B - C - D - E - F  master
            \ 
             \- G - H  new feature branch

我认为你和我一样,当我第一次开始使用Git时,想要将ABCDEF提交master分支,并将GH作为功​​能分支提交。 但这不是Git的工作方式。 让我们重新绘制它,而不更改任何提交链接:

           E--F   <-- master
          /
A--B--C--D
          \
           G--H   <-- feature

这应该更清楚地表明,就Git而言,承诺ABCD都在两个分支上。 只有一个根。 这是提交A :它是一个根,因为它没有父提交,链中没有从提交到父的反向链接。

其次,无论你如何处理这个问题,你最终都要复制一些提交。 原因是每个提交的父ID都是该提交的标识的一部分。 任何提交的“真实名称”是其哈希ID,并且通过读取提交的完整内容来构建哈希ID:源树,提交消息,作者姓名和日期等,但也始终包括父ID。 1您希望最终图形类似于:

  D--E--F   <-- master
 /
A
 \ 
  B--C--G--H   <-- feature

但是现有的D链接(或点)回到现有的C ,而不是A ,而现有的G点又回到了现有的D

这就是为什么cherry-pick有效: git cherry-pick基本上复制了一个提交。 新副本“与原始副本做同样的事情”,但有一些不同的东西 ,即使它像“我的父母是......”一样简单。 (通常它也有不同的附着对象,以及,它只是使浓度变化 ,相比其新的母公司时,相同的时候原来是相对于原来的母公司原来做的改变)。 这意味着你实际上无法获得你想要的东西,只需要你需要的东西

  D'-E'-F'  <-- master
 /
A
 \ 
  B--C--G'-H'  <-- feature

其中小刻度标记表示结果是原件的副本

原件会怎么样? 答案是:它们仍然存在于存储库中,以防您需要它们。 全貌更像是这样的:

    D'-E'-F'   <-- master
   /
  /        E--F   [abandoned]
 /        /
A--B--C--D
       \  \
        \  G--H   [abandoned]
         \
          G'-H'   <-- feature

虽然git cherry-pick有效,但git rebase - 特别是git rebase -i -does是以花哨的自动化方式完成这些副本,最后一步是移动分支名称,放弃原始提交。 所以git rebase -i有时候更容易实现。

如果你运行git rebase -i你会看到所有那些pick命令,而那些字面上运行git cherry-pick :它真的是在做一系列的挑选。 如果您自己进行这些操作,可能会更清楚地发生了什么,并且您可以更好地控制何时移动分支标签。


1对于合并提交,这是父s ,复数。 所有的父母都参与哈希。

修复大师:

git checkout A
git cherry-pick master~3..master # apply the changes we actually want to keep on master
git branch -f master # reposition master on new position
git checkout master

要从功能分支中删除提交D:

git checkout feature-branch~3 # or git checkout C
git cherry-pick feature-branch~2..feature-branch # apply the last 2 revisions
git branch -f feature-branch
git checkout feature-branch

你可以用git rebase做到这一点。

首先,让我们修改一些来自master提交:

$ git checkout master
$ git rebase --onto A C

这将把所有提交范围从C转换为master (但不包括C本身)到提交A.

现在rebase feature但抛出提交D:

$ git checkout feature
$ git rebase --onto C D

到前面的命令类似,这将在从d的范围内移动的提交到feature (不包括d本身)到C.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM