简体   繁体   中英

Removing a specific commit in git history that includes merges

I want to remove a specific commit, C, in git history, as well as some single-commit-merges.

The history looks like this. In this example, I want to remove the single-commit-merge m6 and a problematic commit C .

---m0-------------------m1---m2---m3-------------m4---m5----m6---m7---(...)
     \                 /            \           /       \  /
      b0---b1---b2---b3              b4--(C)--b5         b6

I want to wind up with this (changes highlighted):

                                                      vv 
---m0------------------m1---m2---m3---------m4---m5---b6---m7---(...)
    \                 /            \vvvvvvv/          ^^
     b0---b1---b2---b3              b4---b5
                                    ^^^^^^^

If I use "git rebase -i" to excise C and b6/m6 , this works, but I get:

---m0---b0---b1---b2---b3---m1---(...)---

and the history is flattened. I want to preserve the entire structure. Conversely, if I run with the --preserve-merges flag, then I get:

error: Commit <sha-1 corresponding to m6> is a merge but no -m option was given.
fatal: cherry-pick failed
Could not pick <sha-1 corresponding to m6>

and I can't remove b6/m6 (although I can remove C).

What's the right way to wind up with the desired result? I'm using git 1.8.4, if that matters.

(Note that the other questions on StackOverflow that I perused don't seem to account for this very specific case, so as nearly as I can tell, this is not a duplicate question.)

Looks like it may be a small bug in git-rebase--interactive :

            case "$new_parents" in
            ' '*' '*)
                    test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
            ... snip ...
            *)
                    output eval git cherry-pick "$strategy_args" "$@" ||
                            die_with_patch $sha1 "Could not pick $sha1"
                    ;;

When this hits m6 , the new set of parents is singular, so it tries to use cherry-pick , but m6 is a merge so cherry-pick requires a hint about which parent to use.

I'm not sure why it's trying to take m6 at all, though.

Solution/workaround: (for me, anyway) This seems to be a bug in git rebase . I reverted to git 1.7.9 and my problem was solved; git rebase --interactive --preserve-merges worked exactly as I wanted and produces the graph I indicated in my post.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM