我在此分支和屏幕上有功能/安装新功能并有11次提交。但所有提交都已合并提交。打算做这些提交。
我在日志历史记录中有合并提交的列表,需要压缩到单个提交中。
commit ac174b8dc1dc44e91b56c89c55003942070b9742
Merge: e9048249 e24218ee
Author: sanjay <sanjay@sanjay.com>
Date: Sun Dec 10 04:48:39 2017 +0000
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit e904824938f2e8517d3ad5a45a11ae4595157cf7
Merge: 41e1d616 a3128511
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 8 12:07:53 2017 +0000
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit e24218eeb60bcbfa92559cf174d3de40b93a6dbe
Merge: 41e1d616 a3128511
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 8 12:07:53 2017 +0000
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit 41e1d61609ea6d3c99d52efb3fb472a18924b2f1
Merge: ddc36e3b bdf8a179
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 8 09:14:59 2017 +0000
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit bdf8a17968543fccc3b02ffc59c2117448f586ff
Merge: d9fe3abd 7b630927
Author: sanjay <sanjay@sanjay.com>
Date: Tue Dec 12 14:53:19 2017 +0530
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit d9fe3abd0062475cfdff911ce58a967076d5aa08
Merge: 27ee100a 63113ae4
Author: sanjay <sanjay@sanjay.com>
Date: Tue Dec 12 14:52:34 2017 +0530
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit a3128511b3fd3746d4191794e7dcda52232e9458
Merge: ddc36e3b bdf8a179
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 8 09:14:59 2017 +0000
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit ddc36e3be2dd55b1ba880c307c8be0237ca52bce
Merge: d9fe3abd 7b630927
Author: sanjay <sanjay@sanjay.com>
Date: Tue Dec 12 14:53:19 2017 +0530
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit 7b630927be19a773414938a43702fe9cd0e7f854
Merge: 27ee100a 63113ae4
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 8 01:52:01 2017 +0000
Merge branch 'feature/Install New feature on this branch and screens' of https://github.com/service/dosomething.git into feature/Install New feature on this branch and screens
commit 27ee100ad29e8db7fb10ddc04824ccdc8a53d091
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 1 06:25:13 2017 +0000
Install New feature on this branch and screens
commit 63113ae404be96f113e1c9eb4f79d0de9fc4a90e
Author: sanjay <sanjay@sanjay.com>
Date: Fri Dec 1 06:25:13 2017 +0000
Install New feature on this branch
但是我做了一个git rebase -i branchname
它显示了这样的输出。我无法将其压缩成提交。输出是这样的
noop
# Rebase ac174b8..ac174b8 onto ac174b8 (1 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
如何使用上述提交来处理壁球。
答案 0 :(得分:0)
您无法通过git rebase
实现目标。您可能能够通过git merge --squash
达到您想要的效果,但除非您知道自己在做什么,否则通常根本不应使用git merge --squash
。 (也就是说,这可能是解决整体问题的错误方法。)
根据经验,在为某些提交运行git merge --squash
之后,您应该删除包含这些提交的分支,因为它们不再适合开发。 (可能存在特定的例外情况。)在这种情况下,这意味着删除已合并的每个分支。
作为evolutionxbox said in a comment,当您运行git rebase -i branchname
命令时,您选择根本不复制任何提交,将副本放在当前提交ac174b8dc1dc44e91b56c89c55003942070b9742
之后。
这可能是件好事,因为当你做选择要复制的一些提交时,将副本放在其他一些指定的提交之后,Git将复制的提交省略所有合并提交。这是因为复制合并提交既不可能,也常常是非生产性的。由于上面列表中的11个提交中有9个是合并,因此无法复制它们。
记住git rebase
做 copy 提交的做法非常重要,就像使用git cherry-pick
命令一样。一般来说,你将拥有一个Git存储库,其中包含一些提交,你可以而且应该绘制一张图片 - 这些提交的图表,或者至少是那些参与rebase的图片:
E--F--G <-- new-desired-base
/
...--*
\
A--B--C--D <-- four-commits
这里,只能从名称four-commits
访问的四个提交中的每一个都是普通(非合并)提交。提交D
的父级是提交C
; C
的父级是B
; B
的父级是A
; A
的父级是我用星号*
标记的提交。
如果您现在运行git checkout four-commits && git rebase new-desired-base
,Git将从four-commits
点(即D
)的提交开始,选择不是的提交可以从new-desired-base
点的提交开始,即G
。从G
可到达的提交为G
,F
,E
,*
,以及提交前*
的每次提交。因此,从列表D, C, B, A, *, ...
中减去该列表会留下D, C, B, A
。
Git现在将切换到由G
标识的提交new-desired-base
,并以相反的顺序复制四个提交中的每一个,即最祖先的A
伟大的-parent为D
,然后是祖父母B
,然后是父C
,最后是D
本身。每个副本都由{{1>} 完成, 1 如果一切顺利,结果如下:
git cherry-pick
其中 E--F--G <-- new-desired-base
/ \
...--* A'-B'-C'-D'
\
A--B--C--D <-- four-commits
(prime)标记表示哪个提交被复制到具有新哈希ID的新提交。
最后,如果一切顺利,Git将从原始链中取名'
,并将其粘贴到新链的末尾,在此过程中重新附加four-commits
:< / p>
HEAD
现在原始提交 E--F--G <-- new-desired-base
/ \
...--* A'-B'-C'-D' <-- four-commits (HEAD)
\
A--B--C--D [abandoned]
没有名称,它似乎完全消失了。这会占用整个链条,因此D
似乎已替换为A-B-C-D
:
A'-B'-C'-D'
原始提交链仍在您的存储库中,如果您已将其保存在某处(以及某些特殊隐藏名称,以防您未保存),则可通过其哈希ID进行检索,通常用于至少再过30天,以防你改变主意对于篮板。
请注意,如果任何 else 在其存储库中都有这些提交 - 即,具有这些哈希ID 并且具有自己的名称 - 这些提交将永远保留在<他们的存储库。你必须得到他们来删除那些提交的他们的名称,然后这些提交最终会离开他们的存储库。
1 交互式rebase确实在每个要复制的提交上运行 E--F--G <-- new-desired-base
/ \
...--* A'-B'-C'-D' <-- four-commits (HEAD)
。其他一些形式的rebase不是,但效果通常是相同的。
由于这就是rebase如何运作,所以记住它是个好主意。更重要的是要记住它没有复制合并提交,因此如果您要求它复制您的提交链,它将省略合并。但是,一般来说,要求Git重新定义包含合并的内容是个坏主意,因为选择要复制的提交往往包括要合并的提交。
考虑以下简化图:
git cherry-pick
请记住,如果他们是更为祖先(父母或祖父母),则提交在左侧,如果他们不是祖先(儿童),则提交到右侧。所以...--A--B----F <-- master
\ \
\ D <-- feature-B
\
C--E <-- feature-A
添加了一个提交,即master
,因为F
已分支。它已添加两个提交,即feature-B
和B
,因为F
已分支。同时feature-A
包含两个提交,feature-A
和C
,不在E
,master
包含一个提交,feature-B
,即不在D
。
如果您的目标是在master
上同时合并两个功能,则可以选择合并两个功能分支。您可以使用以下任一方式执行此操作:
master
或:
git checkout feature-A && git merge feature-B
如果成功,合并的结果将是新的提交git checkout feature-B && git merge feature-A
。这个新提交将基于(在合并库中)commit G
:
Git会将提交A
的快照内容与A
中的快照内容进行比较。实际上,这是自提交D
以来在功能B中发生的事情。请注意,此包含 A
中发生的事件,这是一个可以从B
的提示访问的提交(通过查看master
&#39}亲本)。
Git将分别将提交D
的快照内容与A
中的快照内容进行比较。实际上,这是自提交E
以来在功能A中发生的事情。比较A
与A
包括E
中发生的任何事情,因为C
中的快照包括E
中发生的任何事件(嗯,减去C
中所有的反转。
现在Git有两组更改,Git将组合它们,并将更大的更改应用于提交A
中的快照。这为它提供了生成新快照/提交A
所需的内容:
G
如果您使用...--A--B----F <-- master
\ \
\ D---G
\ /
C--E
执行此操作,则新提交git checkout feature-B && git merge feature-A
会添加到G
分支:
feature-B
如果您使用...--A--B----F <-- master
\ \
\ D---G <-- feature-B (HEAD)
\ /
C--E <-- feature-A
执行此操作,则会将新提交git checkout feature-A && git merge feature-B
添加到G
分支,因此我们可能会更像这样:
feature-A
无论哪种方式,...--A--B----F <-- master
\ \
\ D <-- feature-B
\ `--_
C--E--G <-- feature-A
都是合并提交,因此不能重新定位,这与提交G
或{{1}不同}。
D
然而,现在可以运行:
C--E
这里的git merge --squash
是产生新提交git checkout master && git merge --squash <something>
的哈希ID的任何东西。您可以输入原始哈希ID;或者,如果您进行了合并以便将提交<something>
添加到G
,则可以使用名称G
。
feature-B
步骤将feature-B
附加到git checkout master
,当然还会检查HEAD
的提示提交,即提交master
。因此,假设master
位于F
,这看起来像是:
G
feature-B
步骤执行...--A--B----F <-- master (HEAD)
\ \
\ D---G <-- feature-B
\ /
C--E <-- feature-A
的动词部分,即git merge --squash
将执行的工作:它找到与以前一样,合并基础,然后像以前一样运行两个git merge
命令。
提交git merge
和git diff --find-renames
的合并基础是提交F
。这是因为粗略地说,合并基础是从两个分支提示可以到达的第一个提交。从G
开始,我们退一步到B
。从F
开始,我们退一次到B
,一次退到G
,然后再退一次D
和E
到D
和E
。我们现在已达到共同点提交B
- 因此C
是合并基础。
因此,和以前一样,Git运行B
和B
,看看两个分支中发生了什么。然后,Git将这些更改组合在一起,将它们应用于快照git diff --find-renames B F
的内容,并准备新的快照git diff --find-renames B G
。
此处B
以两种方式偏离常规H
:
git merge --squash
选项一样,或者好像发生了合并冲突。所以当你现在运行git merge
时,你得到:
--no-commit
提交git commit
的内容,即快照,与您进行常规合并的情况相同;但是定期合并会将结果记录为:
...--A--B----F--H <-- master (HEAD)
\ \
\ D---G <-- feature-B
\ /
C--E <-- feature-A
由于壁球合并不记录额外的父母,Git稍后不知道H
已经拥有...--A--B----F--H <-- master (HEAD)
\ \ /
\ D---G <-- feature-B
\ /
C--E <-- feature-A
的所有作品。 (通过真正的合并,Git 将知道,因为合并基础将 提交H
。)
对于进行压缩合并的人来说,这意味着现在对 G
或 {{1}进行任何进一步开发会产生相反的效果因为缺少父链接,它们将更难以合并到G
中。因此,此时删除两个名称 feature-A
和 feature-B
可能是合适的:
master
与重新定位一样,额外提交feature-A
和feature-B
将会在短时间内(可能比rebase更短),即使名称消失,但最终它们会消失。但请记住,如果其他人拥有这些原始提交的名称,并保存在某些其他存储库中,那些提交 - 以及这些名称 - 将永远保留在他们的存储库中,除非您说服他们删除它们。如果他们将自己的工作建立在这些提交的基础上,他们可能会遇到麻烦,以后将他们的工作与你压扁的提交...--A--B----F--H <-- master (HEAD)
\ \
\ D---G [abandoned]
\ /
C--E [abandoned]
结合起来。