Git:压缩不是最近提交的连续提交,而不是从根开始

时间:2014-09-25 02:48:06

标签: git version-control jgit squash

我已经回顾了几个关于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的壁球,而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上正在进行rebase,其中E是HEAD提交。可以肯定的是,在开始时没有进行任何重组,并且在再次运行时调用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> and git 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,但它没有答案,我认为这个问题有点不清楚。

更新

这是对@yyenus的答案的回应:

I2提交I2,其中I---I2---J位于work,提取失败。当它失败时,我的D---E---Z分支的状态为git cherry-pick --abort,直到樱桃选择为止,然后是未提交的更改。调用Z会清除这些未提交的更改,并且我验证了提交F---G---H是正确的,这是Z的壁球。在提交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$ ,这会产生合并冲突并失败。有什么建议吗?

这是我的输出:

{{1}}

1 个答案:

答案 0 :(得分:5)

首先,如果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

    work

  2. 创建分支H
  3. git reset E

    现在work位于E

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

    F---G---H完成的更改提交为Z

  5. git cherry-pick I^..J

    接管I---J

  6. 现在work分支处于您想要的形状,只需重置master即可:

    # D---E---Z---I`---J` work
    
    git checkout master
    git reset work
    git branch -d work
    

    注意:提交范围已更正为I^..J,以表示提交系列I---J(从IJ,包括在内)。