DEV Community

loading...

Remove accidentally pushed file from a git repository history in 4 simple steps

moshe profile image Moshe Zada Updated on ・3 min read

Although git offers gitignore mechanism for ignoring files from being committed to git, you may find yourself stuck with a big file in your repo
Alt text
Simply deleting the file with rm is not enough, git records all the history of all of your branches forever in the .git directory at the root of your project.

Step #1: Backup your repo!

Simply copy the project directory
cp -r myproject backup

Step #2: Identify the commit that introduced the new file

The easiest way is to look at the output of git log command, assuming you want to delete a file called client/public/favicons/red/hugefile.ova run

$ git log client/public/favicons/red/hugefile.ova
Sat Aug 17 19:16:17 2019 +0300 7ff66fa Add favicons  [Moshe Zada]

As you can see, it seems like commit 7ff66fa introduced the big file, let's rewrite the history!

Step #3: Go back in time

Now that we find the commit that we want to return back to, run

git rebase --interactive 7ff66fa~1

Right after running this command, your editor will open up with the commit history from 7ff66fa to the last commit, for example:

pick 7ff66fa Add favicons
pick 48d9cc0 Readme (#84)
pick b9f23fd GitBook: [master] 17 pages modified
pick 1e0f4f1 move to docs
pick 23adabf GitBook: [master] 4 pages modified
pick 237c792 revert readme
pick 9418698 Continue reload if had exception
pick 3723c3c Add Copy option to index
pick 1ff0ec1 Add filter for manage aliases
pick 8a8770d Better null message
pick 4d8b64c Subscribe to input change
pick 9bc31b6 Save more data for node stats
pick 546e10b Small fixes

# Rebase 5058e82..eafa06e onto 5058e82 (193 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

go to the first line, the one that starts with your git commit and change the first word to the letter e - for edit (vimmiers: cwe<ESC>) and exit your editor (:wq)

Step #4: Rewrite the history and push your changes

Now git will start replaying the last commits and give you shell just before the bad commit
delete the file:
rm client/public/favicons/red/hugefile.ova
Add the change to git
git add client/public/favicons/red/hugefile.ova
Commit and continue the rebase
git commit --amend '-S' && git rebase --continue
Verify changes and push your changes

Thank Joe and Eugene for pointing git push --force should be used with caution
git push -f be carful with this. the -f stands for force. Be default git will complain if you try to re-write history, but you can force it to go anyway. If you are on a solo project this should be fine, but if you are working on a team make sure no one has pulled the branch and added commits on top of it You won't be doing them any favors.
Don't be afraid to use it. Just make sure you communicate with your team on what is being done.

git push --force

That's it 🙂

Found this post useful? Add a star⭐️ to my Github project🙂

GitHub logo moshe / elasticsearch-comrade

Elasticsearch admin panel built for ops and monitoring

Elasticsearch Comrade Twitter Follow python docker pulls CircleCI GitHub issues GitHub license

Elasticsearch Comrade is an open-source Elasticsearch admin and monitoring panel highly inspired by Cerebro. Elasticsearch Comrade built with python3, VueJS, Sanic, Vuetify2 and Cypress Alt text Alt text

Main Features

  • Elasticsearch version 5,6 and 7 support (tested against elasticsearch 7.7)
  • Multi cluster
  • Rest API with autocompletion, history, templates, and history
  • SQL editor (version 7 only)
  • Built for big clusters
  • Node statistics and monitoring
  • Manage aliases
  • Inspect running tasks
  • Manage index templates
  • Manage snapshots
  • And much more ...

Quickstart

Cluster dir definitaions

Comrade discovers clusters using the --clusters-dir param, docs are here, examples are here

Using docker (recommended)

docker run -v $PWD/clusters/:/app/comrade/clusters/ -it -p 8000:8000 mosheza/elasticsearch-comrade

Using the python package

pip install elasticsearch-comrade
comrade --clusters-dir clusters

Installation, configuration and next steps

Here

Roadmap

v1.1.0

  • Add python package
  • Reindex screen
  • Comrade dashboard

v1.2.0

  • Cluster settings screen
  • Evacuate node from shards
  • Add commrade version indicator to footer

v1.3.0

  • Beats screen
  • Threadpools screen

Screenshots

Alt text Alt text Alt text Alt text Alt text

Discussion (9)

pic
Editor guide
Collapse
leohajder profile image
Leo Hajder

Cool :)

If you use git rebase -i on a branch, you should specify where you want to push. The default origin is origin/master, so be careful and don't overwrite your main branch.

So, let's say you're on a branch called feature/new-stuff and you want to rewrite its history...
Do the steps above, just remember to push to the right origin in the end. In this case:
git push -f origin feature/new-stuff

Collapse
moshe profile image
Moshe Zada Author

Hi @leo ,
Looking at git-scm.com/docs/git-config it seems like the default push.default is simple.
simple - in centralized workflow, work like upstream with an added safety to refuse to push if the upstream branch’s name is different from the local one.
upstream - push the current branch back to the branch whose changes are usually integrated into the current branch (which is called @{upstream}). This mode only makes sense if you are pushing to the same repository you would normally pull from (i.e. central workflow).

So if the branch names differ the push will be refused.

Collapse
leohajder profile image
Leo Hajder

Oh... Ok, this is new to me. Thanks for the clarification.

Collapse
karataev profile image
Eugene Karataev

I agree with Joe, use git push -f with caution.

Warning: It is considered bad practice to rebase commits which you have already pushed to a remote repository. Doing so may invoke the wrath of the git gods.

Collapse
moshe profile image
Moshe Zada Author

Agree, I will add a warning thank you @joe and Eugene for the feedback

Collapse
joekaiser profile image
Joe • Edited

To all you devs coming from Google

git push -f be carful with this. the -f stands for force. Be default git will complain if you try to re-write history, but you can force it to go anyway. If you are on a solo project this should be fine, but if you are working on a team make sure no one has pulled the branch and added commits on top of it You won't be doing them any favors.

Don't be afraid to use it. Just make sure you communicate with your team on what is being done.

Collapse
adamukaapan profile image
Adam Krpan

Another note! If you're using GitHub and accidentally committed a secret (like I did, but that's a whole other story), GitHub has a few other steps they recommend you take. The main one is "Contact GitHub Support or GitHub Premium Support, asking them to remove cached views and references to the sensitive data in pull requests on GitHub." Source: help.github.com/en/github/authenti...

I'm not sure exactly how necessary this is, but I figured I'd note it in case some others are really paranoid.

Collapse
zerolab profile image
Dan Braghis

Nice how-to!

There is also rtyley.github.io/bfg-repo-cleaner/ which accomplishes the same in a hopefully simpler way for many. I did a write-up on how to use it a while ago - torchbox.com/blog/how-remove-unwan... . Leaving it here in case it helps someone

Collapse
jenc profile image
jen chan

This is a much more straightforward solution than the post I wrote!