The epic git 💣

By Chen Hui Jing / @hj_chen

Some background


🎮 🏀 🚲 💻 👟

My name is Chen Hui Jing.

Self taught designer and developer.

Write blog posts from time to time.

Love HTML and CSS very much.

In case of fire

A little back-story

+ + =

The repo does not forget

5.94gb repo

Step 1: git filter-branch

git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch FOLDER_NAME' --prune-empty --tag-name-filter cat -- --all
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch FOLDER_NAME' --prune-empty --tag-name-filter cat -- --all

Hey, it's a pretty long line. ¯\_(ツ)_/¯

filter-branch --index-filter
  • The filter-branch command allows you to rewrite the Git history
  • Can apply filters to modify information about each commit
  • --index-filter rewrites the index
  • Possible to use --tree-filter but --index-filter is faster because it does not check out the tree
'git rm -rf --cached --ignore-unmatch FOLDER_NAME'
  • Used with --index-filter for optimal results
  • Removes file(s) recursively (rm) and forcefully(-rf)
  • --cached is used to unstage and remove paths from the index
  • --ignore-unmatch will prevent the command from failing if the file is absent from the tree of a commit
--prune-empty --tag-name-filter cat
  • --prune-empty allows the filter-branch command to ignore empty commits generated by the filters applied
  • -tag-name-filter cat will update the relevant tags by rewriting them
-- --all

Step 2: git prune

git prune

Step 3: remove old references

rm -rf .git/refs/original/
  • Removes any old references to the unwanted folder/file
  • Branches, remote-tracking branches, and tags are all references to commits
  • All references are named with a slash-separated path name starting with "refs"

Step 4: git reflog

git reflog expire --expire=now --all
  • To manage reference log information
  • expire is used to prune older reflog entries
  • --expire=now specifies how far behind these older entries should be, in this case, right now
  • Official documentation for git reflog

Step 5: git gc

git gc --prune=now
  • Cleans up unnecessary files and optimises the local repository
  • --prune=now prunes objects older than the date specified, in this case, right now
  • Official documentation for git gc

Step 6: clone to new repo

git clone --no-hardlinks file://PATH/TO/OLD-REPO NEW-REPO
  • Gives a "clean" repository with the history rewritten to remove target folder, with all other commits intact

Houston, we got a problem

  • Force pushing these changes up to remote didn't work 😭
  • Create a new remote repository and push the clean repo up there
  • Asked everyone to change their remote origin
  • Only works if nobody pulled from the time you screwed up and the time you fixed things

To find out more...