Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prune empty merge commits from history in Git repository

I have cleaned up our Git repository quite a bit, we need to remove big parts from the history. I do this using:

git filter-branch --prune-empty --tree-filter 'rm -rf some_stuff' 

The --prune-empty flag will remove commits that are left empty after the process, except commits with multiple parents (merge commits). Even if the branch being merged in contains absolutely nothing, and the merge adds nothing to the tree.

How do I also prune these empty merge commits from the history?

like image 687
Bjarke Freund-Hansen Avatar asked Mar 21 '12 11:03

Bjarke Freund-Hansen


People also ask

How do I delete a merge commit in history?

You can use the Git reset command to undo a merge. Firstly, you need to check for the commit hash (or id) so you can use it to go back to the previous commit. To check for the hash, run git log or git reflog . git reflog is a better option because things are more readable with it.

How do I remove a merge commit in git?

Do git rebase -i <sha before the branches diverged> this will allow you to remove the merge commit and the log will be one single line as you wanted. You can also delete any commits that you do not want any more.

Does git merge keep history?

In the Conceptual Overview section, we saw how a feature branch can incorporate upstream changes from main using either git merge or git rebase . Merging is a safe option that preserves the entire history of your repository, while rebasing creates a linear history by moving your feature branch onto the tip of main .

Does rebase remove merge commits?

Rebase is powerful, but it comes with a price. One problem I face with rebase is, it removes merge commits. Suppose we have a common feature branch shared by multiple developers, we are merging commits to this branch first, and to keep atomic commits properly we are using no-fast-forward merge commits.


1 Answers

This is superior to the rebase solution because it preserves committer info, committer dates, and non-empty merges of the original history.

git filter-branch --prune-empty --parent-filter \     'sed "s/-p //g" | xargs -r git show-branch --independent | sed "s/\</-p /g"' 

This is inspired by the same thread on the kernel mailing list than Lucas' solution. However it does not require Ruby and is a one-liner. It does require GNU versions of xargs and sed though.

like image 164
raphinesse Avatar answered Sep 20 '22 21:09

raphinesse