[git] Make the current commit the only (initial) commit in a Git repository?

I currently have a local Git repository, which I push to a Github repository.

The local repository has ~10 commits, and the Github repository is a synchronised duplicate of this.

What I'd like to do is remove ALL the version history from the local Git repository, so the current contents of the repository appear as the only commit (and therefore older versions of files within the repository are not stored).

I'd then like to push these changes to Github.

I have investigated Git rebase, but this appears to be more suited to removing specific versions. Another potential solution is to delete the local repo, and create a new one - though this would probably create a lot of work!

ETA: There are specific directories / files that are untracked - if possible I would like to maintain the untracking of these files.

This question is related to git github git-commit

The answer is


This deletes the history on the master branch (you might want to make a backup before running the commands):

git branch tmp_branch $(echo "commit message" | git commit-tree HEAD^{tree})
git checkout tmp_branch
git branch -D master
git branch -m master
git push -f --set-upstream origin master

This is based on the answer from @dan_waterworth.


This is my favoured approach:

git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})

This will create a new branch with one commit that adds everything in HEAD. It doesn't alter anything else, so it's completely safe.


For that use Shallow Clone command git clone --depth 1 URL - It will clones only the current HEAD of the repository


The only solution that works for me (and keeps submodules working) is

git checkout --orphan newBranch
git add -A  # Add all files and commit them
git commit
git branch -D master  # Deletes the master branch
git branch -m master  # Rename the current branch to master
git push -f origin master  # Force push master branch to github
git gc --aggressive --prune=all     # remove the old files

Deleting .git/ always causes huge issues when I have submodules. Using git rebase --root would somehow cause conflicts for me (and take long since I had a lot of history).


Variant of larsmans's proposed method:

Save your untrackfiles list:

git ls-files --others --exclude-standard > /tmp/my_untracked_files

Save your git configuration:

mv .git/config /tmp/

Then perform larsmans's first steps:

rm -rf .git
git init
git add .

Restore your config:

mv /tmp/config .git/

Untrack you untracked files:

cat /tmp/my_untracked_files | xargs -0 git rm --cached

Then commit:

git commit -m "Initial commit"

And finally push to your repository:

git push -u --force origin master

git filter-branch is the major-surgery tool.

git filter-branch --parent-filter true -- @^!

--parent-filter gets the parents on stdin and should print the rewritten parents on stdout; unix true exits successfully and prints nothing, so: no parents. @^! is Git shorthand for "the head commit but not any of its parents". Then delete all the other refs and push at leisure.


The other option, which could turn out to be a lot of work if you have a lot of commits, is an interactive rebase (assuming your git version is >=1.7.12):git rebase --root -i

When presented with a list of commits in your editor:

  • Change "pick" to "reword" for the first commit
  • Change "pick" to "fixup" every other commit

Save and close. Git will start rebasing.

At the end you would have a new root commit that is a combination of all the ones that came after it.

The advantage is that you don't have to delete your repository and if you have second thoughts you always have a fallback.

If you really do want to nuke your history, reset master to this commit and delete all other branches.


Below is a script adapted from @Zeelot 's answer. It should remove the history from all branches, not just the master branch:

for BR in $(git branch); do   
  git checkout $BR
  git checkout --orphan ${BR}_temp
  git commit -m "Initial commit"
  git branch -D $BR
  git branch -m $BR
done;
git gc --aggressive --prune=all

It worked for my purposes (I am not using submodules).


Deleting the .git folder may cause problems in your git repository. If you want to delete all your commit history but keep the code in its current state, it is very safe to do it as in the following:

  1. Checkout

    git checkout --orphan latest_branch

  2. Add all the files

    git add -A

  3. Commit the changes

    git commit -am "commit message"

  4. Delete the branch

    git branch -D master

  5. Rename the current branch to master

    git branch -m master

  6. Finally, force update your repository

    git push -f origin master

PS: this will not keep your old commit history around


To remove the last commit from git, you can simply run

git reset --hard HEAD^ 

If you are removing multiple commits from the top, you can run

git reset --hard HEAD~2 

to remove the last two commits. You can increase the number to remove even more commits.

More info here.

Git tutoturial here provides help on how to purge repository:

you want to remove the file from history and add it to the .gitignore to ensure it is not accidentally re-committed. For our examples, we're going to remove Rakefile from the GitHub gem repository.

git clone https://github.com/defunkt/github-gem.git

cd github-gem

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch Rakefile' \
  --prune-empty --tag-name-filter cat -- --all

Now that we've erased the file from history, let's ensure that we don't accidentally commit it again.

echo "Rakefile" >> .gitignore

git add .gitignore

git commit -m "Add Rakefile to .gitignore"

If you're happy with the state of the repository, you need to force-push the changes to overwrite the remote repository.

git push origin master --force

I solved a similar issue by just deleting the .git folder from my project and reintegrating with version control through IntelliJ. Note: The .git folder is hidden. You can view it in the terminal with ls -a , and then remove it using rm -rf .git .


Here you go:

#!/bin/bash
#
# By Zibri (2019)
#
# Usage: gitclean username password giturl
#
gitclean () 
{ 
    odir=$PWD;
    if [ "$#" -ne 3 ]; then
        echo "Usage: gitclean username password giturl";
        return 1;
    fi;
    temp=$(mktemp -d 2>/dev/null /dev/shm/git.XXX || mktemp -d 2>/dev/null /tmp/git.XXX);
    cd "$temp";
    url=$(echo "$3" |sed -e "s/[^/]*\/\/\([^@]*@\)\?\.*/\1/");
    git clone "https://$1:$2@$url" && { 
        cd *;
        for BR in "$(git branch|tr " " "\n"|grep -v '*')";
        do
            echo working on branch $BR;
            git checkout $BR;
            git checkout --orphan $(basename "$temp"|tr -d .);
            git add -A;
            git commit -m "Initial Commit" && { 
                git branch -D $BR;
                git branch -m $BR;
                git push -f origin $BR;
                git gc --aggressive --prune=all
            };
        done
    };
    cd $odir;
    rm -rf "$temp"
}

Also hosted here: https://gist.github.com/Zibri/76614988478a076bbe105545a16ee743


What I'd like to do is remove ALL the version history from the local Git repository, so the current contents of the repository appear as the only commit (and therefore older versions of files within the repository are not stored).

A more conceptual answer:

git automatically garbage collects old commits if no tags/branches/refs point to them. So you simply have to remove all tags/branches and create a new orphan commit, associated with any branch - by convention you would let the branch master point to that commit.

The old, unreachable commits will then never again be seen by anyone unless they go digging with low-level git commands. If that is enough for you, I would just stop there and let the automatic GC do it's job whenever it wishes to. If you want to get rid of them right away, you can use git gc (possibly with --aggressive --prune=all). For the remote git repository, there's no way for you to force that though, unless you have shell access to their file system.


Just delete the Github repo and create a new one. By far the fastest, easiest and safest approach. After all, what do you have to gain carrying out all those commands in the accepted solution when all you want is the master branch with a single commit?


You could use shallow clones (git > 1.9):

git clone --depth depth remote-url

Further reading: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/


The method below is exactly reproducible, so there's no need to run clone again if both sides were consistent, just run the script on the other side too.

git log -n1 --format=%H >.git/info/grafts
git filter-branch -f
rm .git/info/grafts

If you then want to clean it up, try this script:

http://sam.nipl.net/b/git-gc-all-ferocious

I wrote a script which "kills history" for each branch in the repository:

http://sam.nipl.net/b/git-kill-history

see also: http://sam.nipl.net/b/confirm


Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to github

Does the target directory for a git clone have to match the repo name? Issue in installing php7.2-mcrypt How can I switch to another branch in git? How to draw checkbox or tick mark in GitHub Markdown table? How to add a new project to Github using VS Code git clone error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 How to add empty spaces into MD markdown readme on GitHub? key_load_public: invalid format git - remote add origin vs remote set-url origin Cloning specific branch

Examples related to git-commit

How to undo the last commit in git git status (nothing to commit, working directory clean), however with changes commited Fix GitLab error: "you are not allowed to push code to protected branches on this project"? How to rollback everything to previous commit Troubleshooting misplaced .git directory (nothing to commit) Pushing empty commits to remote Please enter a commit message to explain why this merge is necessary, especially if it merges an updated upstream into a topic branch How do I commit case-sensitive only filename changes in Git? How to save a git commit message from windows cmd? Remove files from Git commit