2

I am currently converting a SVN repository to Git and during this process I want to make the history as linear as possible. The problem is that I have some feature branches in SVN which merges from the master branch during the process. This merging pattern makes rebaseing a pain and I cannot figure out how to do it properly.

My goal is to replace the merge of the feature branch with a squash commits: enter image description here

I have studied the answer to this question but none of the suggested answers seems to work for my case: git remove merge commit from history

How should I go about squashing my feature branch so that I can rebase it on master at the correct point in time?

Björn Blissing
  • 388
  • 1
  • 8
  • Why is this so desired? – evolutionxbox Mar 20 '19 at 00:12
  • I would say that the desire to do this is uncommon. In this case I was importing an old SVN repo and wanted to clean up the repo a bit before starting using it as a Git repo. This cleanup entailed squashing together related commits, fixing commit messages. To be able to do squashing with interactive rebase I needed to get rid of these merge commits. Please note that this Git repo was not active yet, so I was fine with re-writing history. – Björn Blissing Mar 21 '19 at 07:51

1 Answers1

2

Let's say that M is the topmost merge commit (the one between G and H):

git checkout -b cleaned-branch M
git reset --soft G
git commit -m "Get rid of merge"
git rebase M `git rev-parse master` --onto cleaned-branch
git checkout -B cleaned-branch

git reset --soft G will make git think that G is your current base commit, but it does that without touching your files (unlike checkout), so you'll be left with all the changes from the merge in the form of outstanding changes, and the subsequent commit will just have G as its parent. Then, we rebase the remaining commits and move cleaned-branch up to the resulting tip commit.

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • I have tried this proposed solution and there are two problems: 1. The commit will have todays time/date instead of the time/date from the history of merge M. 2. When I am done I have a new branch 'cleaned-branch' which is parallel to the master branch. I want to only have the master branch. – Björn Blissing Mar 18 '19 at 23:05
  • Ok.. I have figured out how to change the date/time of the new commit to match the old date/time. i.e. by using the flag --date='2014-05-05T10:08:00' in the commit command. – Björn Blissing Mar 18 '19 at 23:17
  • Just finish of with `git checkout -B master` on the last line instead, which will move `master` to the rebased tip commit. Note that the resulting `master` commit will have a different hash than the original one, but that's inherent in git and impossible to avoid: _any_ manipulation of old commits will change the hash of the modified commits and _all_ their descendant commits. – Aasmund Eldhuset Mar 18 '19 at 23:53
  • Ok.. I solved it by doing: `git checkout master` and then `git rebase --onto 'git rev-parse cleaned-branch' M 'git rev-parse master'` – Björn Blissing Mar 19 '19 at 00:03