41

I'm learning how to use git these days and I had to do many hit-and-misses. Thus I needed to delete and create anew my remote and local repos. Is there a way to roll back to the first commit of the repo and delete all history after that? Basically a clean slate to experiment on.

Aleksandar Savkov
  • 2,894
  • 3
  • 24
  • 30
  • 6
    Yet another simple task made difficult by Git. The Git devs should use Stack Overflow as feedback in their SDLC loop. 18K people should indicate something is seriously wrong with Git's workflow. They need to hire a UX expert because they clearly cannot git it right on their own. – jww Nov 28 '17 at 04:40
  • Lol. It's 64k now – Eskay Amadeus Jan 04 '23 at 17:34

7 Answers7

56

I don't know of any way to do exactly what you're asking (one can roll back to first commit, but not delete all history, since the history will at least contain that initial commit.)

If I were you I'd just delete the remote repo and the .git directory of the local repo, and start over with git init.

The closest that I can get to what you're asking for would be to rollback all but the first commit. To do that, you'd first find the SHA1 of the first commit, for example:

% git rev-list --max-parents=0 --abbrev-commit HEAD
aa8119f

...and then run either

% git reset aa8119f

...or

% git reset --hard aa8119f

...depending on whether you want to preserve or discard all the changes made since that initial commit. (The above assumes that you have only one branch. If not, you'll also have to delete any other branches you have with git branch -d <BRANCHNAME>.)

Finally, you'd run

% git push -f

(I hope that you realize that git push -f is a no-no whenever you're pushing to a repo that is shared with others.)

Unfortunately, as already explained, this approach does not delete all the history.

If this is something you'll want to do often, I'd recommend that, immediately after git init, you run something like

% git commit --allow-empty --allow-empty-message -m ''
% git tag -a -m '' ROOT

This will put an empty commit at the root of your history, and tag it with a tag named ROOT. Then you can do something like

% git reset ROOT

or

% git reset --hard ROOT

to bring you back to that first empty commit.

To get a good handle on what git reset does, I recommend reading this.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
kjo
  • 33,683
  • 52
  • 148
  • 265
  • 2
    re: "this approach does not delete all the history" It's true that you cannot get rid of the initial commit, but after resetting to the first commit you can finalize with `git rm *` to clean up files (careful if you have modified files) and then `git commit --amend --allow-empty --reset-author --date= -m "Erased history"` to clean the first commit's information. – TWiStErRob Feb 28 '16 at 15:51
  • 1
    Yet another simple task made difficult by Git. The Git devs should use Stack Overflow as feedback in their SDLC loop. 18K people should indicate something is seriously wrong with Git's workflow. They need to hire a UX expert because they clearly cannot git it right on their own. – jww Nov 28 '17 at 04:40
  • This helped me: https://stackoverflow.com/a/6637891/7741897 If you need to delete all the history - run `git reset --hard` after performing the step from the answer through the link – Eduard Aug 01 '18 at 14:18
14

You could reset to the first commit:

"How to show first commit by 'git log'?" describes how to find the first commit:

git log --pretty=format:%H | tail -1

(works only if there is no multiple root branches)

git reset --hard yourFirstCommitSHA1

Note that after the reset, to really get a clean slate, you could simply git init a new repo and copy the content of your first commit you just reset to (and add and commit in that new repo)

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Out of curiosity: how does one get multiple root branches? – kjo Feb 29 '16 at 14:41
  • That's great to know. Thanks!!! (I would have never found it, since I expected such functionality to be provided by--and documented under--`git branch`, rather than `git checkout`; I find it somewhat perverse that one is *required* to check out such a branch in order to create it.) – kjo Feb 29 '16 at 17:38
  • 1
    Yet another simple task made difficult by Git. The Git devs should use Stack Overflow as feedback in their SDLC loop. 18K people should indicate something is seriously wrong with Git's workflow. They need to hire a UX expert because they clearly cannot git it right on their own. – jww Nov 28 '17 at 04:41
12

Just blow away the .git directory once you've got your first commit checked out. As such:

git checkout <first-commit-sha>
rm -rf .git
git init
git add -A
git commit -m 'Initial Commit'
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • Much better than mine. Maybe give the command to find the master root commit's sha? – jthill May 12 '13 at 01:29
  • Bearing in mind that this 1) deletes your configuration (`.git/config`) and 2) also completely wipes out submodules (their commits, and config). So make sure you back up your config file settings that you care about, and make sure you don't have any unpushed commits in submodules. There are probably other gotchas, so in general I do not agree with this solution. – void.pointer Feb 14 '19 at 17:26
5

Checkout to master:

$ git checkout master

Show log:

$ git log

Reset to first commit:

$ git reset --hard <you first commit number>

Then, push changes to remote:

$ git push --force origin
Alexey Slusar
  • 51
  • 1
  • 1
4

To do a clean reset you want to eliminate the logs and any config changes and everything, I'd do this by fetching just the master root into a new repo:

git tag master-root $(git rev-list --topo-order master|sed '$!d')
git init ../reset-my-repo
cd ../reset-my-repo
git fetch $OLDPWD master-root
git checkout -B master FETCH_HEAD

(i.e. pretty much what VonC said)

(added --topo-order to protect against bad timestamps)

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
jthill
  • 55,082
  • 5
  • 77
  • 137
  • This seems a more detailed version of my answer below, so +1 – VonC May 11 '13 at 20:11
  • @VonC I see that now, I paid attention only to the effect of the commands. I'm still pretty new, didn't mean to step on yours, would my answer have been better as an edit to yours? – jthill May 11 '13 at 20:38
  • not at all. I find your answer more detailed, and if it is working for the op, it deserves the green tick :) – VonC May 12 '13 at 09:16
1

You can certainly remove all history in current branch using:

git reset --hard <commit_id>

where commit_id is sha1 of some historic commit.

However, it is rarely needed if you are learning and want to experiment.

Instead, you can simply create new branch for your experiments, like:

git branch experiment <commit_id>
git checkout experiment
...

This would be identical for most intents and purposes to first variant, but you can switch back if you want.

You can can also rename branches, such that your experiments have original branch names, like:

git branch -m master backup
git branch master
git checkout master

If you want to nuke backup branch, simply do:

git branch -D backup
mvp
  • 111,019
  • 13
  • 122
  • 148
0

Or by shell script :)

#!/bin/bash

variable=`git rev-list --max-parents=0 --abbrev-commit HEAD`

git reset --hard $variable
git push -f

If you send this to someone else don't forget to add

echo "Ja pie***** cos Ty odje***..."
Deadjim
  • 27
  • 6