Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git rebase, skip merge-commits

Tags:

git

rebase

Starting with

    hack---F1----M1----F2  (feature)
   /            /
  C1-----C2----C3  (master)

I would like to end up with

    hack---F1----M1----F2  (feature)
   /            /
  C1-----C2----C3---F1'---F2'  (master)

So far the best I have is

git checkout feature  
git checkout -b temp  
git rebase -i --onto master hack temp
   * Big drawback: manually remove the merged-in C2 and C3 from list of commits *
git checkout master  
git merge temp  
git branch -d temp  

I hope someone can answer even though this is a dubious workflow.

like image 523
Grastveit Avatar asked Sep 17 '14 08:09

Grastveit


People also ask

Does rebase ignore merge commits?

By default, a rebase will simply drop merge commits from the todo list, and put the rebased commits into a single, linear branch. With --rebase-merges, the rebase will instead try to preserve the branching structure within the commits that are to be rebased, by recreating the merge commits.

How do I rebase without merge commit?

You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". In fact, Git will list out every file that has a merge conflict in it with the CONFLICT flag!

What is git rebase -- skip?

@mittal: think of git rebase as copying commits from one branch onto another branch. So when you skip a commit, the original content of the commit is skipped and the patch is not applied (so all changes made to any file will not make it into your target branch).

Does rebase avoid merge conflicts?

Rebasing is not going to magically remove all merge conflicts. In fact, you may encounter conflicts while rebasing. Sometimes, you will have to repeatedly resolve the same conflict while rebasing. However, merge conflicts happen because multiple changes happen to the same chunk of code simultaneously.


2 Answers

Simple case

If the state of your repo is

  hack---F1----M1----F2 [feature]  /            / C1-----C2----C3 [master] 

and you want to arrive at

  hack---F1----M1----F2 [feature]  /            / C1-----C2----C3----F1'----F2' [HEAD=master] 

you should use git cherry-pick, not git rebase -i (no need to juggle with interactive rebase, here):

git checkout master git cherry-pick <commit-ID-of-F1> <commit-ID-of-F2> 

General case

Correct me if I'm wrong, but I understand what you mean by general case as

cherry-pick, on top of master, all the non-merge commits between hack (exclusive) and the tip of feature (inclusive).

In the following, I'm assuming that is indeed what you mean.

As you've rightfully noted in your comment, the approach outlined above doesn't scale very gracefully as the number of commits to manually cherry-pick increases:

  hack---F1---F2--- .... --- F68--M1---F67---...---F99 [feature]  /                               / C1-------------C2---------------C3 [master] 

However, you can get git rev-list to automatically generate the list of revisions of interest, using

git rev-list --reverse --no-merges --first-parent <commit-ID-of-hack>..feature 

Edit: you also need the --first-parent flag to avoid collecting commits such as C1 and C2, and --reverse flag, so that commits get cherry-picked in the desired order.

You can pass the output of that command to git cherry-pick:

git checkout master git cherry-pick `git rev-list --reverse --no-merges --first-parent <commit-ID-of-hack>..feature` 

which would yield

  hack---F1---F2--- .... --- F68--M1---F67---...---F99 [feature]  /                               / C1-------------C2---------------C3---F1'---F2'---...---F99' [HEAD=master] 
like image 176
jub0bs Avatar answered Oct 05 '22 16:10

jub0bs


Looking at your original workflow, it seems like you want to ignore merges, the only problem is using -i for an interactive rebase, which preserves merges.

git checkout -b temp   git rebase --onto master hack temp    * Big drawback is gone! git checkout master   git merge temp   git branch -d temp 

Should work exactly how you want. This probably doesn't exactly solve your "general case," though.

like image 43
Schala Walls Avatar answered Oct 05 '22 15:10

Schala Walls