Tom Thorne
Tom Thorne

Reputation: 214

How to rewrite history so that all changes made within a folder are removed?

This question is about rewriting git history. Six months ago I decided to make changes over an existing subfolder of my repository, and now I've changed my mind and want to undo that and all the associated history. Note, I want changes outside that subfolder should be left as is.

So, specifically, I am trying to remove the history of all the changes made within one of the subfolders of the repo, from a certain date onwards.

The end result I am hoping for should look like no edits/adds/deletes were ever made in the subfolder after that date.

Looking at the the answer to Remove file from git repository (history), and also http://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository, the closest I've got is this:

git filter-branch --index-filter 'git rm -r -f --cached --ignore-unmatch TheFolderToRemove' --prune-empty --all xxxxxx..HEAD 
git reset --hard
git remote rm origin
rm -r .git/refs/original/
git reflog expire --expire=now --all
git gc --aggressive
git prune

This removes all the files in the subfolder.

Can someone please show me how to modify this so that it just removes the changes applied within the folder? Many thanks

Upvotes: 3

Views: 401

Answers (2)

Marco
Marco

Reputation: 5109

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatched somefolder/somefolder' --prune-empty --tag-name-filter cat -- --all

The -rf parameter removes all files in that folder or subfolder recursively.

Upvotes: 0

vergenzt
vergenzt

Reputation: 10367

Running the filter-branch with git rm --cached tells git to remove the directory and stage that removal! It only did what you told it to do.

If you still have the original objects: (i.e. you didn't actually run gc and prune)

You want to use git reset to unstage changes to that directory from the index, not remove the directory itself:

$ git filter-branch --index-filter 'git reset -q xxxxxx TheFolderToRemove' \
>     --prune-empty -- --all xxxxxx..HEAD

where xxxxxx is the commit with state you want the folder to be in.

If you do not still have the original objects: (i.e. you pruned the old tree from your repository)

Checkout the commit in which the folder is shown as removed (I believe it should be the commit after xxxxxx), undo the removal, amend the commit, and rebase the rest of history on top:

$ git checkout -b temp <commit_after_xxxxxx>
$ git checkout HEAD^ <removed_folder>
$ git commit --amend
[temp abcdef1] <message>

Then, if master is your only branch:

$ git rebase --preserve-merges temp master

Upvotes: 4

Related Questions