Git: best way to remove all changes from a given file for one branch

git discard changes to file
git discard staged changes
git reset file
git undo discard local changes
how to get local changes in git
git clean modified files
git ignore all local changes
how to save local changes in git

I have a bit of a messy branch with 20 or so commits, and I'm preparing for a merge back to master. I've rebased it off master, and looking closer, I realise that there are files being modified in ways that are totally irrelevant to this branch, and not ready to be committed. The changes to those files aren't confined to specific commits.

So basically, I don't want anything to do with those files to be included in this branch if possible. Is there a good way to go about this? My fall back position #1 is obviously to just copy over the latest copy of each of those files then commit. But then the history will still contain the changes, and the Git Gods will frown upon me.

Fall back position #2 is to do the same, then squash the whole branch history down to one commit.

Any improvements on these?

Say your history is

$ git lola
* 6473d7f (master) Update
| * 9bcfa7e (HEAD, topic) Munge a, b, and c
| * 99af942 Munge b and c
| * 8383e2c Munge a and b
|/
* d1363f4 Baseline

Note: lola is a non-standard but helpful alias.

The commits have modified three different files.

$ git log --decorate=short --pretty=oneline --name-status topic
9bcfa7e946a92c226ad50ce430a9e4ae55b32490 (HEAD, topic)
M       a
M       b
M       c
99af942dbb922effcad8a72e96bec9ee9afcc437 Munge b and c
M       b
M       c
8383e2c8d6092550fec13d3c888c037b3a68af15 Munge a and b
M       a
M       b
d1363f4fba67d94999b269b51bdb50a8a68ba27a Baseline
A       a
A       b
A       c

The changes to file b are the ones you want to keep, and you want to discard all changes to a and c. One way to do this is with git filter-branch.

$ git checkout -b tmp topic
Switched to a new branch 'tmp'

$ git merge-base topic master
d1363f4fba67d94999b269b51bdb50a8a68ba27a

$ git filter-branch --tree-filter 'git checkout d1363f -- a c' master..tmp
Rewrite 8383e2c8d6092550fec13d3c888c037b3a68af15 (1/3)
Rewrite 99af942dbb922effcad8a72e96bec9ee9afcc437 (2/3)
Rewrite 9bcfa7e946a92c226ad50ce430a9e4ae55b32490 (3/3)
Ref 'refs/heads/tmp' was rewritten

The tree filter above checks out the commits in the named range and restores files a and c to the content at the “merge base,” that is, the commit at which topic branched away from master.

Now tmp has all topic’s changes to b but no changes to any other file.

$ git log --decorate --pretty=oneline --name-status tmp
9ee7e2bd2f380cc338b0264686bcd6f071eb1087 (HEAD, tmp) Munge a, b, and c
M       b
226c22f150af1ddc1f9adc19f97fc4f220851ada Munge b and c
M       b
45e706f7b22c37ee2025ee0d04c651135e7b31cd Munge a and b
M       b
d1363f4fba67d94999b269b51bdb50a8a68ba27a Baseline
A       a
A       b
A       c

As a safety measure, git filter-branch stores a backup of your original ref. When you’re satisfied with your changes and want to delete the backup tmp, run

$ git update-ref -d refs/original/refs/heads/tmp

How to discard all changes made to a branch?, How do I remove changes from one file to another in git? If we add a line to a file in each commit in the chain, one way to get back to the version with only two lines is to reset to that commit, i.e., git reset HEAD~1. Another way to end up with the two-line version is to add a new commit that has the third line removed—effectively canceling out that change.

To checkout to a specific version you can do git checkout <sha1> <file> where sha1 is the unique sha1 hash of that version you want the file to be in.

Undo Changes, When using Git, it is common to make changes that you want to that you want to revert the changes made to one specific file… The git checkout command switches between branches or restores working tree files. is clean, because you would lose any working directory changes that aren't committed. Git – Undo All Uncommitted Changes Posted on Tuesday December 27th, 2016 Tuesday April 4th, 2017 by admin Lets say you have been working on a project that is tracked by Git and suddenly realized that you did something wrong.

I ran into a couple of problems as Windows user:

  1. Use Double Quotes for --tree-filter command.
  2. Use forward slashes for filepath.
  3. Dont start filepath with forward slash.

Here is how my command ended up looking:

git filter-branch -f --tree-filter "git checkout a59f75 -- source/_posts/blog1.md source/_posts/blog2.md" master..tmp

Introduction to undoing things in git, git stash save is not going away any time soon, so don't worry about it suddenly disappearing. git status Changes to be committed: (use "git reset HEAD <file>. git status # On branch master nothing to commit, working directory clean You can reapply the one you just stashed by using the command shown in the help  The easiest way to unstage files on Git is to use the “git reset” command and specify the file you want to unstage. git reset <commit> -- <path> By default, the commit parameter is optional : if you don’t specify it, it will be referring to HEAD .

You could make your changes to remove functionality as a new commit, then create a patch from it. Do your rebasing/squashing or whatever you need to to prepare to merge back to master, then when you want to add the new functionality back in, you can apply the patch in reverse mode with

git apply -R

Note I've never done this... but it should work in theory I think. :-)

Numerous undo possibilities in Git, At any stage, you may want to undo something. One of the common undos takes place when you commit too early and possibly forget to git add * $ git status On branch master Changes to be committed: (use "git reset HEAD <file>. go over stashing and branching in Git Branching; these are generally better ways to go. $ git ls-files <file1> <file2> Remove File From Commit using Git Restore. Since Git 2.23, there is a new way to remove files from commit, but you will have to make sure that you are using a Git version greater or equal than 2.23. $ git --version git version 2.24.1. Note : Git 2.23 was released in August 2019 and you may not have this version

How to Discard Unstaged Changes in Git - Guide, Using git add -p to add/commit only some changes to make multiple commits is Those can be deleted with git clean -nd git clean -ndX respectively, or git On branch master # Changes to be committed: # (use "git reset HEAD <file>. file as a new commit; Either way, I want to move a commit from one branch to another  To remove a file from Git, you have to remove it from your tracked files (more accurately, remove it from your staging area) and then commit. The git rm command does that, and also removes the file from your working directory so you don’t see it as an untracked file the next time around.

Stashing and Cleaning, Git is one of these things that you learn progressively. To keep your stash list clean you can also execute git stash pop instead. Use case: Out of habit, you staged all modifications using git add . , but want to unstage certain files to commit git checkout is used to change branches, but if you check out a  There is a shortcut in case you want to discard all changes made on this branch since you have last pushed or in any event, to make your local branch identical to "upstream". Upstream, for local tracking branches, is the place you get history from when you git pull: typically for master it might be origin/master.

Undoing Things, How do I remove all uncommitted changes to my working directory? How do I rollback a file to a certain commit in history? Just use the Contact button at the top right to get in touch! One possible action to take in Git is to undo changes you made replant the master branch onto the corrected merge. At this point there are 3 options to undo the local changes you have: Discard all local changes, but save them for possible re-use later: git stash. Discarding local changes (permanently) to a file: git checkout -- <file>. Discard all local changes to all files permanently: git reset --hard.

Comments
  • +1 Excellent answer. Using filter-branch is such an amazing tool once you wrap your head around it.
  • Lots of great stuff in here I'm still digesting. 'log --name-status <branch>' is cool.
  • Buh. I followed all the steps of this excellent answer, and everything went swimmingly until the end of the filter-branch. "WARNING: Ref 'refs/heads/tmp' is unchanged". Checking the history, the file modifications are still there, and none of the commit ids have changed (as far as I can tell), even though git reported "rewriting" them all. Hmm.
  • Ah. Weirdly the argument to "git checkout" was treated as case-sensitive (even though I'm on Windows). It's now worked. Running that "git log" command is now strange in two ways: it still lists the file as modified (even though there are no changes to it in the diff), and the old commit id is retained (but shown in yellow now). Scary command!
  • Err, next question: how does one restore from that backup, that I see in refs/original/heads/...