2

I would like to remove 7/8 commits from around two years ago from my GitHub repository. Only 2/3 of the commits touch any code, the rest were just adding and removing the config files.

Some previous developers uploaded and removed literally > 650 duplicate config files, and it is messing up our github stat page. Stat Graph

We've tried removing them with git rebase -i, but it took 6 hours and most parts of the code were gone.

How do we remove these ancient commits without messing up other commit history? We're currently recoding all code on the repository, so it is not a big deal if the changes from those individual commits aren't kept, but we'd like to keep all the statistics that went along with the old code besides this.

Petersnow2
  • 49
  • 5
  • Can you clarify the "took 6 hours and most parts of the code were gone"? How were you using `git rebase`, specifically? – Oliver Charlesworth Dec 11 '17 at 21:53
  • Commits "*can't*" be removed from *shared* history of a repo that has been cloned (or rather, if the commits or downstream commits have been pulled) because others have (and *depend on*) those commits to make up the DAG. The extreme fix is to create a new repository and cleanly import, but this is an extreme measure and has downstream impacts as it's a *new* repo with the same name. – user2864740 Dec 11 '17 at 22:08
  • We used `git rebase -i` and deleted the commits from the editor that popped up. We copy + pasted around 5000 "git rebase --skip" commands there's no way we could fix 5000 commits manually, and it wouldn't continue without us taking an action. @user2864740 Look at the screenshot I linked. You can't tell anything from that graph. – Petersnow2 Dec 11 '17 at 22:09
  • Possible duplicate of [Delete commits from a branch in Git](https://stackoverflow.com/questions/1338728/delete-commits-from-a-branch-in-git) – albert Dec 11 '17 at 22:32
  • 2
    To be honest, I'd be very worried if I saw a software engineer spending 6 hours copy+pasting the same command, 5000 times! – Tom Lord Dec 11 '17 at 22:35
  • @TomLord Haha, I just made a text document with that command a couple thousand lines long, and pasted that into the terminal once, and it took 6 hours from there. – Petersnow2 Dec 12 '17 at 23:33
  • @Kneesnap Haha, OK... That's a little more respectable ;) – Tom Lord Dec 13 '17 at 10:02

2 Answers2

1

Obligatory DANGER: Re-writing the project history is very risky! Make sure you have a backup before attempting this, and proceed with extreme caution!

To delete one specific commit in a project (e.g. from years ago), you can:

git rebase -p --onto SHA^ SHA

Where SHA is the commit you want to delete.

The documentation for these options is:

-p, --preserve-merges
  Recreate merge commits instead of flattening the history by replaying
  commits a merge commit introduces. Merge conflict resolutions or
  manual amendments to merge commits are not preserved.

--onto <newbase>
  Starting point at which to create the new commits. If the --onto
  option is not specified, the starting point is <upstream>. May
  be any valid commit, and not just an existing branch name.

After making this change, you'll need to:

git push --force origin master
#        ^^^^^^^
#          !!!
Tom Lord
  • 22,829
  • 4
  • 43
  • 67
0

Two steps are needed:

  1. Rewrite git history, with one of:
    • Rebase from the last good commit, discarding all messy commits:

git rebase --interactive good-commit-sha

  • or filter-branch

git filter-branch --tree-filter 'rm -f config-files' HEAD

  1. Force push to the master:

git push --force origin master

Note that push force is strongly discouraged, since it will make all current clones of your repo inconsistent. Any conflict will have to be fixed manually.

Gonzalo Matheu
  • 6,511
  • 4
  • 29
  • 49