Git:压缩不是最近提交的连续提交,并且不从根开始 [英] Git: Squashing consecutive commits that are not the most recent commits, and do not start at the root
问题描述
我已经查看了几个关于挤压最近的提交和在根处压缩提交,但两者都不会帮助我压缩不在根目录下的非最近提交.
I have reviewed several related questions about squashing the most recent commits and squashing a commit at the root, but neither will help me squash non-recent commits that are not at the root.
这是我的起始场景:
D---E---F---G---H---I---J master
和我想要的结果:
D---E---Z---I---J master
其中 Z
是 F---G---H
和 F---G---H
的壁球、D---E
和 I---J
可以是任意长的非分支提交序列.
where Z
is the squash of F---G---H
, and F---G---H
, D---E
, and I---J
can be an arbitrarily long sequence of non-branching commits.
第一种方法:
[lucas]/home/blah/$ git rebase -i D
rebase in progress; onto D
You are currently editing a commit while rebasing branch 'master' on 'D'.
No changes
You asked to amend the most recent commit, but doing so would make
it empty. You can repeat your command with --allow-empty, or you can
remove the commit entirely with "git reset HEAD^".
Could not apply F... "Comments from commit F"
[1]+ Done gitk
[lucas]/home/blah/$
我选择提交 F---G---H
为 squash
的地方,同时保留最旧的提交——rebase 交互中的第一行——作为 <代码>选择代码>.为什么这不起作用?
where I select commits F---G---H
to be squash
, while leaving the oldest commit - the first line in the rebase interactive - as pick
. Why doesn't this work?
更新:在命令结束时,正在对 D
进行 rebase,其中 E
是 HEAD 提交.可以肯定的是,在开始时没有进行 rebase 并且在再次运行时调用 git rebase --abort
具有相同的结果.当我在 root 或 HEAD 上执行此操作时,根据上面的链接,一切正常.
Update: at the end of the command, a rebase is in progress on D
with E
being the HEAD commit. To be sure, there was no rebase in progress at the start and calling git rebase --abort
while running again has the same result. When I do this at root, or HEAD, according to the links above, everything works fine.
第二种方法:
我再次尝试[通过合并一个新分支(论坛上的最后一篇文章)][http://git.661346.n2.nabble.com/Non-interactive-squash-a-range-td5251049.html) 使用 gitcheckout -b
git merge --squash `,但我得到以下信息:
I made another attempt [via merging a new branch (last post on the forum)][http://git.661346.n2.nabble.com/Non-interactive-squash-a-range-td5251049.html) which uses git checkout -b <clean-branch> <start-id> and
git merge --squash `, but I get the following:
[lucas-ThinkPad-W520]/home/.../.Solstice_WS/7K_FGHF$ git checkout -b clean-branch D
Switched to branch 'clean-branch'
[lucas-ThinkPad-W520]/home/.../.Solstice_WS/7K_FGHF$ git merge --squash I
Updating D..I
Fast-forward
Squash commit -- not updating HEAD
.../GraphUtilities/impl/DAG.java | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
[lucas]/home/blah/$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
asdf/GraphUtilities//DAG.java
Please, commit your changes or stash them before you can switch branches.
Aborting
似乎有这个结果:
------------------- <clean-branch> with non-committed changes
/
D---E---F---G---H---I---J <master>
我有点困惑,那么我该如何压缩这些提交?
I am a bit stumped, so how can I squash these commits?
最终,我计划在 JGit
中实现它,因此 JGit
实现也是可以接受的.
Ultimately, I plan to implement this in JGit
, so a JGit
implementation would be acceptable as well.
注意
这里可能有重复,但它没有答案,我认为这个问题有点不清楚.
There may be a duplicate here, but it has no answers and I think the question is a bit unclear.
更新
这是对@ryenus 在下面的回答的回应:
This is in response to @ryenus's answer below:
cherry-pick 在提交 I2
时失败,其中 I2
在 I---I2---J
中.当它失败时,我的 work
分支的状态有 D---E---Z
,正如预期的那样,直到cherry-pick,然后是未提交变化.调用 git cherry-pick --abort
清除这些未提交的更改,我验证了 commit Z
是正确的,这是 F---G- 的壁球--H
.提交Z
后,然后cherry-pick,为什么cherry-pick在F
处失败?
The cherry-pick fails on the commit I2
, where I2
is in I---I2---J
. When it fails, the state of my work
branch has D---E---Z
, as intended up until the cherry-pick, and it is followed by uncommitted changes. Calling git cherry-pick --abort
clears these uncommitted changes, and I verified that commit Z
is correct, which is the squash of F---G---H
. After committing Z
, then cherry-picking, why does the cherry-pick fail at F
?
似乎 git cherry-pick I...J
正在尝试选择 I2
,这会导致合并冲突并失败.有什么建议吗?
It seems as though git cherry-pick I...J
is trying to cherry-pick I2
, which creates the merge conflict and fails. Any suggestions?
这是我的输出:
[lucas]/home$ git checkout -b work H
Switched to a new branch 'work'
[lucas]/home$ git reset E
Unstaged changes after reset:
M adf/GraphUtilities//graph/impl/DAG.java
[lucas]/home$ git commit -am "squashed commit here!"
[work Z] squashed commit here!
1 file changed, 2 insertions(+), 5 deletions(-)
[lucas]/home$ git cherry-pick I...J
error: could not apply I2... <Comments from commit I2>
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
[lucas]/home/$ git status
On branch work
You are currently cherry-picking commit I2.
(fix conflicts and run "git cherry-pick --continue")
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: 3b6863741967406c1888701eb139178187d429487b99787096441d67bed56/Gra
phUtilities/src/edu/washington/cs/utils/graph/impl/DAG.java
no changes added to commit (use "git add" and/or "git commit -a")
[lucas]/home$
推荐答案
首先,如果 F---G---H
被压缩,那么 I---J
将是 I'---J'
.
First of all, if F---G---H
are squashed, then I---J
would be I'---J'
.
鉴于此,我会先创建一个分支,然后使用 vanilla git reset
然后 git cherry-pick
:
Given that, I'd create a branch first then use vanilla git reset
then git cherry-pick
:
# D---E---F---G---H---I---J master
git checkout -b work H
在
H
git reset E
现在 work
在 E
git commit -am "F-G-H 挤压为 Z"
将 F---G---H
所做的更改提交为 Z
git cherry-pick I^..J
接管I---J
现在 work
分支是你想要的形状,只需将 master
重置为它:
Now the work
branch is in the shape you want, just reset master
to it:
# D---E---Z---I`---J` work
git checkout master
git reset work
git branch -d work
注意:提交范围已更正为I^..J
,代表提交系列I---J
(来自I
code> 到 J
,包括在内).
Note: the commit range has been corrected to I^..J
, to represent the commit series I---J
(from I
to J
, inclusive).
这篇关于Git:压缩不是最近提交的连续提交,并且不从根开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!