gpt4 book ai didi

git - 从另一个分支 cherry-pick 到特定的提交

转载 作者:行者123 更新时间:2023-12-02 05:32:40 28 4
gpt4 key购买 nike

这可能吗 ?从其他分支 cherry-pick 到主分支的特定提交。
例如:
说,我有两个分支:

 -> master : <commit1>, <commit2>, <commit3>
-> test: <c1>, <c2>, <c3>, <c4>

现在我想从 <c3> 中挑选一个提交(例如: test )分支到 <commit2>在主分支。

编辑 : 我知道可以通过 rebase 来完成命令,但可以通过 cherry-pick 完成只要?

最佳答案

您在思考 Git 的工作方式方面存在根本性错误。

Is this possible ? Cherry picking from other branch into specific commit of master branch.



否:Git 不能更改任何提交。您可以添加新提交,并且可以复制现有提交以从中进行新提交,即添加一个新提交,该提交是现有提交的副本(据推测,副本中至少有一个不同的内容)。后者是什么 git cherry-pick做。

您还可以更改任何分支名称为您记住的特定提交哈希 ID。

绘制分支

Say, I've two branch:

-> master : <commit1>, <commit2>, <commit3>
-> test: <c1>, <c2>, <c3>, <c4>


这不是绘制分支的好方法。这是一个更好的方法:
...--D--E--F--G   <-- master
\
H--I--J--K <-- test

提交 E这里对应你的 <commit1> ,我只是使用单个字母来使它们更短。同样, F就像你的 <commit2> , 和 J就像你的 <c3> .我还包括另一个较早的提交, D ,两个分支都从它延伸,表明在 E 之前可能有更早的提交。和 H .

请注意,每个提交都会记住其父提交: G 的父提交是 F ,所以我们说 G “点回”到 F . F点回 E , 指向 D , 等等。同样,提交 K点回 J指向 I指向 H .请注意 H ,仅在分支 test 上,也指向 D .

(Commit D 特别有趣:它在两个分支上。这也是 Git 所说的两个分支的 merge 基础。但这不是我们在这里关心的;这只是一个有趣的旁注,在 Git 中,提交可以是同时在多个分支上。)

分支名称,在本例中为 mastertest , 每个指向一个特定的提交。这里的名字 master提交点数 G ,和名称 test提交点数 K .这就是我们如何决定哪些提交在哪些分支上:我们开始,就像 Git 一样,使用分支名称来查找分支提示提交。从这些提示提交,我们或 Git 向后工作:我们从任何一个提交,到其父提交,然后到该提交的父提交,依此类推。只有当我们厌倦了跟随 parent (例如,退出 git log ),或者被告知停止时,这个过程才会停止——尽管我们不会在这里看到——或者我们击中了一个根提交,这是一个没有 parent 。您在存储库中所做的第一次提交是根提交,因为没有更早的提交可以用作父提交。 (可以进行额外的 root 提交,但我们不会在这里看到。)

cherry-pick 提交

And now I want to cherry pick a commit (eg: <c3>) from test branch to a <commit2> in master branch.



你可以挑选一个提交,但我用粗斜体(“提交”)的部分是无稽之谈。 cherry-pick 意味着复制提交。该副本是一个新提交,您通常会将其添加到分支中。

由于您的 <c3>是我的 J ,让我们看看如果你使用会发生什么:
git checkout master
git cherry-pick test~1

第一步让你“进入”分支 master ,即您现在添加的新提交将添加到 master , 通过制作名称 master指向他们。

第二步标识提交 Jtest的顶端向后走一步.姓名 test标识提交 K :分支名称“意味着”该分支的提示提交。 ~1后缀的意思是“计算一个父级”,所以我们从提交 K 开始提交 J .那就是我们要求 Git 复制的提交。

我们暂时将忽略执行此副本的确切机制,而只查看结果。 Git 进行了一个“类似”的新提交 J ;让我们称这个新提交 J' .与原来的 J有几个区别和新副本 J' ,目前重要的是副本的父级是 master 的现有提示。 ,即提交 G .所以 J'点回 G .

复制完成后,新的 J'永久存储,Git 更新 master指向我们刚刚所做的新提交:
...--D--E--F--G--J'  <-- master
\
H--I--J--K <-- test

请注意,现有提交不会受到影响。这是因为几乎不可能更改任何现有提交。

rebase

I know it can be done via rebase command ...



它不能,这确实很重要。 rebase 所做的不是修改提交。相反,它制作副本——可能是很多副本。

让我们考虑一下您拥有 D-E-F-G 的情况。序列在 master你想复制 J并将其插入到 F 之后但之前 G .也就是说,你想得到这个,即使这是不可能的:
...--D--E--F--J'-G   <-- master
\
H--I--J--K <-- test

不可能的原因是 G无法更改,并且 G已经指向 F .但是如果我们这样做呢:
             J'-G'  <-- new-master
/
...--D--E--F--G <-- old-master
\
H--I--J--K <-- test

换句话说,如果我们复制 J 会怎样?至 J'在新 new-master分支,与 J'以后 F ,然后复制 GG' , 与 G'以后 J' ?我们可以通过 git cherry-pick 做到这一点,我们只需要挑选两个提交, J先,然后 G , 到一个新的分支上:
git checkout -b new-master master~1    # make the new-master branch at F
git cherry-pick test~1 # copy J to J'
git cherry-pick master # copy G to G'

并且,假设一旦我们这样做了,我们就会删除旧的 master完全命名,只需调用新的 master , 像这样:
             J'-G'  <-- master
/
...--D--E--F--G [abandoned]
\
H--I--J--K <-- test

现在,如果我们停止绘制废弃的原件 G ,并绘制 master在一条直线上,看起来我们已经插入了 J'之间 FG ...但我们没有:我们复制了 GG' .
git rebase command 本质上是一个自动化的、高性能的“cherry pick a lot of commits”命令,最后是一些移动的分支名称。

为什么这一切都很重要

这只是有时很重要,但当它很重要时,它就很重要了。

假设我们从这个开始,这很像以前,除了还有另一个分支:
...--D--E--F--G   <-- master
\ \
\ L <-- develop
\
H--I--J--K <-- test

现在让我们复制 JJ' , 把它放在 F 之后,然后复制 GG'J'G'的父级,并命名为 master记住新提交的哈希 ID G' . (这与我们之前做的 rebase-with-copy 相同;我们只有这个额外的 develop 分支。)
             J'-G'  <-- master
/
...--D--E--F--G
\ \
\ L <-- develop
\
H--I--J--K <-- test

现在让我们重新绘制它,以减少布局中的奇怪之处:
...--D--E--F--J'-G'  <-- master
\ \
\ G--L <-- develop
\
H--I--J--K <-- test

即使我们让 Git“忘记”了最初的提交 Gmaster赞成 Shiny 的新 G'J'作为其父级,原始 G仍然在分支 develop .事实上,现在看起来好像 G一直在线 develop我们可能是精心挑选的 master从那里。

这里的关键是 你可以复制提交并忘记原件在那里,但如果是这样,你必须确保你真的忘记了它们。 如果这些原件在别处是已知的——通过你自己存储库中的另一个分支,或者(更糟糕的) git push ed 到另一个存储库 - 如果这是您想要的,您必须让所有其他用户使用新版本。您无法更改原件,您只能将它们复制到新的并让每个用户切换到新的。

关于git - 从另一个分支 cherry-pick 到特定的提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43448971/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com