这听起来像是一个基本问题,但我似乎找不到类似的问题。也许我搜索了错误的关键字...如果有的话,请指出我的重复项。
我的远程存储库mybranchX
中有 2 个分支,mybranchY
个分支。
这两个分支都有一组单独的提交,例如
mybranchX : commitXA--commitXB--commitXC--commitXD--commitXE--HEAD
mybranchY : commitYP--commitYQ--commitYR--commitYS--HEAD
我想把commitXC
和更早地拉进mybranchY
怎么做?
附言我知道git cherry-pick commitXC
会选择特定提交的代码更改。但我希望整个历史直到commitXC
:
commitXA--commitXB--commitXC
之后就没有了,即我不想要commitXD--commitXE
不用说,在我的情况下,实际的提交数量很大(几十个),并且挑选每个提交都将是一项漫长的任务。
我认为你没有使用正确的术语。pull
正在与远程存储库同步并合并更改。
我相信cherry-pick
就是你要找的
git checkout mybranchY
git cherry-pick commitXC
更新要进行所有更改commitXA--commitXB--commitXC
可以合并它们
git checkout mybranchY
git merge commitXC
对于这种特殊情况,您只需要git merge
.
让我们重新绘制您的图表。 而不是:
mybranchX : commitXA--commitXB--commitXC--commitXD--commitXE--HEAD
mybranchY : commitYP--commitYQ--commitYR--commitYS--HEAD
让我们使用
A--B--C--D--E <-- mybranchX
/
...--* [this commit and all earlier commits are on BOTH branches]
P--Q--R--S <-- mybranchY (HEAD)
因为这(大概)是运行git checkout mybranchY
后存储库和当前分支状态的准确表示,它将名称HEAD
附加到mybranchY
。
(要验证这一点,请将此水平图形绘制与 Git 自己的垂直方向绘图进行比较,作为git log --all --decorate --oneline --graph
的输出。 请注意,这里重要的是,我标记的提交*
实际的合并基础,即两个分支分开的点。
由于您的HEAD
表示提交S
并且您希望与包括提交C
的所有提交合并,因此请找到一个标识提交C
的名称,例如其原始哈希ID或字符串mybranchX~2
。~2
后缀告诉 Git 向后(在此图中向左)倒数两次提交(在第一个父链接之后,但这些提交只有第一个父级)。 由于mybranchX
名称提交E
,如果我们倒数两次,我们可以提交C
。
然后只需运行:
git merge mybranchX~2 # or git merge <hash-id>
这将启动合并过程。 Git 会将提交*
(合并库)与提交C
进行比较,看看他们做了什么。 它将比较提交*
提交S
,以查看您做了什么:
git diff --find-renames <hash-of-*> HEAD # what we did: --ours
git diff --find-renames <hash-of-*> <hash-of-C> # what they did: --theirs
Git 现在将结合这两个差异,将更改应用于提交*
。 如果一切顺利,它将自动进行新的合并提交。 新合并提交的两个父级(我在这里称之为T
)将是提交S
(作为其第一个父级)和提交C
(作为其第二个父级):
A---B---C--D--E <-- mybranchX
/
...--*
P--Q--R--S--T <-- mybranchY (HEAD)
因此T~1
是S
,T~2
是R
,依此类推。 您现在可以通过mybranchX~2
(倒数两个第一父链接)或mybranchY^2
(取提交T
的第二个父链接)来命名提交C
。 提交A
、B
和C
现在都在mybranchY
上,并且仍在mybranchX
上。 提交D
和E
仅在mybranchX
上。