如何注入中间分支?

时间:2019-01-11 02:44:38

标签: git

在修改了从公共存储库克隆的存储库的master分支之后,我创建了许多从修改后的master分支派生的功能分支。

现在我注意到,对于我要进行的一些新更改,不需要对master分支进行修改。

因此,我想将我的master分支还原为原来的未更改克隆master。而且,我想创建一个中间分支,其中包含我当前对主分支所做的更改。

同时,我想保留已经推送到远程存储库的功能分支。 (我也已经推送了修改后的master分支。)

要实现这一目标需要采取哪些步骤?

enter image description here

1 个答案:

答案 0 :(得分:0)

根本不需要做任何事情,但是如果您希望做某事,我建议您做些其他事情。

背景

在Git中,分支名称对Git本身意义不大。重要的是 commits 。 (当然,这些名称对人类很重要。)

商品通过其丑陋的哈希ID进行唯一标识。这些似乎是随机的,对人类来说几乎没有用,因此出于绘画目的,让我们在这里使用单个大写字母。

您从一个具有一系列提交的克隆开始,以一个我们称为H的提交结束,而不是使用其实际哈希值:

...--F--G--H   <-- master (HEAD), origin/master

然后,您在master上添加了自己的几个新提交。每个人都有一个新的大的丑陋哈希ID,我们将其替换为下一个字母:

...--F--G--H   <-- origin/master
            \
             I   <-- master (HEAD)

进行一次新的提交会告诉Git:请移动当前分支,即附加了HEAD的分支,以指向该新的提交,指向其先前的提交。现在,master个名称将提交I,不再提交H。不过,提交I会记住H的哈希。如果再提交两次,则图片变为:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master (HEAD)

在这一点上,您创建了功能分支-让我们来绘制一下:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master (HEAD), feature1, feature2

然后,通过将feature附加到其上的HEAD分支之一来创建新的提交。让我们选择feature1

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master, feature1 (HEAD), feature2

接下来,您创建了一个或两个提交:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master, feature2
                    \
                     L--M   <-- feature1 (HEAD)

也许,接下来,您选择了feature2作为当前分支(通过git checkout feature2)并创建了另一个提交:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master
                   |\
                   | L--M   <-- feature1
                   |
                    `--N   <-- feature2 (HEAD)

出于任何无法解释的原因,您现在要执行的操作是使您的master指向再次提交H。通过告诉Git:移动master,使其指向提交H,可以对自己的存储库完全没有任何影响。效果是:

...--F--G--H   <-- master, origin/master
            \
             I--J--K
                   |\
                   | L--M   <-- feature1
                   |
                    `--N   <-- feature2

提交IK的方法如下:

  • feature1的末尾开始并向后工作:MLKJI,{{1 }},...
  • H的末尾开始,然后倒退:feature2NKJI,...

您是否想记住提交H的哈希ID作为专有名称,以便您可以从此处启动 new 功能,只需创建一个指向提交K的新名称。这个新名称可以是分支名称标签名称,以您喜欢的为准。

您的目标

  

因此,我想将我的master分支还原为原来的未更改克隆master。而且,我想创建一个中间分支,其中包含我当前对主分支所做的更改。

您的K最初指向的提交仍在您的存储库中。提交master。当然,实际的提交哈希ID大而丑陋-并不是真正的H,它是一些无法记住的长十六进制数字字符串。不幸的是:

  

同时,我想保留已经推送到远程存储库的功能分支。 (我也已经推送了修改后的master分支。)

运行H时,您告诉Git发送提交git push origin master,并在更早的时候将提交发送到K(另一个Git存储库),然后询问管理{ 1}},将主节点设置为指向origin。接受此请求后,您的Git更新了您自己的origin来记住哈希ID K,而不是记住哈希ID origin/master。因此,在这一点上,您会有更多类似的东西:

K

如果您还记得从H开始倒数的确切次数 ,则可以找到...--F--G--H \ I--J--K <-- master, origin/master |\ | L--M <-- feature1 | `--N <-- feature2 。但是,如果您最近(在过去三个月内)进行了所有这些操作,那么您自己的Git 仍会记得三个月或更短的时间K指向的地方。这样就可以运行:

H

查看随着时间的推移,哪些origin/master 用于标识的提交。添加git reflog origin/master 以获取日期信息,您可能会发现日志回溯的时间远远超过了三个月。 Git清理它们的时间可能比较松懈,而且90天的有效期只是一个限制:当Git大力清理旧的reflog时,它将丢弃90天以上的东西(默认情况下,或丢弃30天以上的东西)有用的案例,不适用于此处。)

origin/master

因此要在您的存储库中找到--date=relative,请尝试使用$ git reflog --date=relative origin/master 3c31a20 (HEAD -> master, origin/master) refs/remotes/origin/master@{51 minutes ago}: update by push cf68824 refs/remotes/origin/master@{3 months ago}: update by push ... ce4f7f9 refs/remotes/origin/master@{1 year, 2 months ago}: update by push 命令。

找到H后,您可以为其附加新名称:

git reflog

将产生:

H

您现在可以使用这些不同的分支名称​​交换 git branch aha <hash-ID> ...--F--G--H <-- aha \ I--J--K <-- master, origin/master |\ | L--M <-- feature1 | `--N <-- feature2 (如果愿意)或进行其他操作。只要记住,如果有人 else 正在使用您的存储库或aha存储库的克隆,那么这些其他人可能期望分支名称仅获取 new 提交。如果将分支名称“向后”移动(到较早的提交),其他人可能对此感到困惑,并试图坚持要求您再次将名称向前移动。