【问题标题】:Git: Squashing consecutive commits that are not the most recent commits, and do not start at the rootGit:挤压不是最近提交的连续提交,并且不从根开始
【发布时间】:2014-11-19 16:51:08
【问题描述】:

我已经查看了几个关于 squashing the most recent commitssquashing a commit at the root 的相关问题,但是这两个问题都无法帮助我解决非根目录下的非近期提交。

这是我的起始场景:

D---E---F---G---H---I---J master

和我想要的结果:

D---E---Z---I---J master

其中ZF---G---H 的squash,F---G---HD---EI---J 可以是任意长的非分支提交序列。

第一种方法:

[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---Hsquash,同时将最旧的提交(rebase 交互中的第一行)保留为pick。为什么这不起作用?

更新:在命令结束时,D 正在进行变基,E 是 HEAD 提交。可以肯定的是,一开始并没有进行 rebase 并且在再次运行时调用 git rebase --abort 具有相同的结果。根据上面的链接,当我在 root 或 HEAD 执行此操作时,一切正常。

第二种方法:

我再次尝试[通过合并一个新分支(论坛上的最后一篇帖子)][http://git.661346.n2.nabble.com/Non-interactive-squash-a-range-td5251049.html),它使用git checkout -b <clean-branch> <start-id> andgit merge --squash `,但我得到以下信息:

[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>

我有点难过,那么我该如何压缩这些提交?

最终,我计划在JGit 中实现它,所以JGit 实现也是可以接受的。

注意

可能有duplicate here,但它没有答案,我认为这个问题有点不清楚。

更新

这是对@ryenus 在下面的回答的回应:

cherry-pick 在提交 I2 时失败,其中 I2I---I2---J 中。当它失败时,我的work 分支的状态为D---E---Z,正如预期的那样,直到樱桃挑选,然后是未提交的更改。调用git cherry-pick --abort 会清除这些未提交的更改,并且我验证了提交Z 是正确的,这是F---G---H 的壁球。提交Z之后,然后cherry-picking,为什么cherry-pick在F失败了?

似乎git cherry-pick I...J 正在尝试挑选I2,这会产生合并冲突并失败。有什么建议吗?

这是我的输出:

[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$ 

【问题讨论】:

  • 您的第一种方法似乎是正确的开始,但看起来 git 认为您正处于 rebase 的中间。与直觉相反,变基和合并是有状态的,git 可以在合并/变基完成之前将控制权交还给您。尝试git rebase --abort,然后再次执行该命令。
  • 如果他为其中一个提交指定了“编辑”,它看起来更像git status 的输出。如果你在 rebase 进行时输入 git rebase,Git 会说 I wonder if you are in the middle of another rebase

标签: git version-control jgit squash


【解决方案1】:

首先,如果F---G---H 被压扁,那么I---J 将是I'---J'

鉴于此,我会先创建一个分支,然后使用 vanilla git reset,然后使用 git cherry-pick

# D---E---F---G---H---I---J master
  1. git checkout -b work H

    H创建分支work

  2. git reset E

    现在workE

  3. git commit -am "F-G-H squeezed as Z"

    F---G---H 所做的更改提交为Z

  4. git cherry-pick I^..J

    接管I---J

现在work 分支是你想要的形状,只需将master 重置为它:

# D---E---Z---I`---J` work

git checkout master
git reset work
git branch -d work

注意:提交范围已更正为I^..J,代表提交系列I---J(从IJ,含)。

【讨论】:

  • 有趣的方法,但樱桃挑选失败了。在提交Z 之后,它似乎试图将F 挑选到work 上。详细信息已在我上面的答案中更新。
  • @Lucas,请尝试git cherry-pick I^..J,如果可行,我会更新答案。
  • 在查看了 Git 的 revision selection 之后,现在这很有意义。谢谢!此外,cherry-pick 没有在F 失败,而是在I2 失败,其中I2I---I2---J 中(我相应地更新了我的帖子)
  • @Lucas,是的,它应该可以正常工作,因为这里 HZ 具有相同的内容,因此所有以下提交都应该完美适用。
  • @Lucas,不,提交哈希是提交本身及其父提交的结果。使用不同的父提交,新提交将不会具有相同的提交哈希。但除了提交哈希,I'---J'I---J 相同。
猜你喜欢
  • 2015-09-24
  • 2018-03-22
  • 2019-10-17
  • 2017-06-12
  • 2016-02-08
  • 2023-01-21
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
相关资源
最近更新 更多