175

I'm working in a branch (i.e. design) and I've made a number of changes, but I need to discard them all and reset it to match the repository version. I thought git checkout design would do it, but it just tells me I'm already in branch design and that I have 3 modified files.

How would I discard those changes and get the branch as it stands now on the remote server?

nbro
  • 15,395
  • 32
  • 113
  • 196
Will
  • 5,370
  • 9
  • 35
  • 48
  • Here's a link to my answer on a related question: https://stackoverflow.com/questions/22620393/various-ways-to-remove-local-git-changes/65398480#65398480 – anupamkrishna Dec 21 '20 at 19:14

15 Answers15

296

Note: You CANNOT UNDO this.

Try git checkout -f this will discard any local changes which are not committed in ALL branches and master.

ismail
  • 46,010
  • 9
  • 86
  • 95
  • It worked! Thanks! I kept trying to check out but it won't let me. It kept saying I have to "commit" or "stash" but all I want to do is trash every change I made. And this worked! Thanks. – No One Apr 30 '21 at 01:11
121

git reset --hard can help you if you want to throw away everything since your last commit

Kyle Clegg
  • 38,547
  • 26
  • 130
  • 141
gor
  • 11,498
  • 5
  • 36
  • 42
36
git diff master > branch.diff
git apply --reverse branch.diff
Rubens Mariuzzo
  • 28,358
  • 27
  • 121
  • 148
Mike Kaganski
  • 701
  • 6
  • 18
  • These steps can be very useful, if your goal is set the state of a specific branch to be equal with the master branch. To do so, run this from within the specific branch, and then delete the [branch name].diff file when done using `git rm [branch name].diff` – karolus May 08 '20 at 12:37
  • 1
    Does not work here. I get `error: git diff header lacks filename information when removing 1 leading pathname component (line 5)` – guettli May 24 '22 at 12:24
21

If you don't want any changes in design and definitely want it to just match a remote's branch, you can also just delete the branch and recreate it:

# Switch to some branch other than design
$ git br -D design
$ git co -b design origin/design            # Will set up design to track origin's design branch
mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 9
    also: git checkout design; git reset --hard origin/design – Dan Sep 20 '11 at 13:34
  • I would also commit before deleting branch – Asarluhi Nov 17 '15 at 16:55
  • If you have commits in the local branch that are not on the remote, this is a recipe for getting into really confusing situations in my opinion. I would definitely *not* use this solution. – erewok Jul 28 '16 at 17:30
  • 1
    @erewok: Well, the question does specifically say that the asker wants to discard all changes. – mipadi Jul 28 '16 at 20:50
  • And I don't think this answer achieves that. – erewok Jul 28 '16 at 20:57
  • If you make commits to a local branch that where those commits are not on a remote, then you delete that branch, and then you pull from the remote and checkout your branch, you are liable to get back the branch you supposedly deleted. It's very hard to lose branches/commits with git. I've seen a lot of confusion about deleted branches or branches with subtly similar names (case-insensitive) to other branches. It's not a direction I would ever go in, having fought those battles before. – erewok Jul 28 '16 at 23:18
  • @erewok: How are you going to "get back the branch you supposedly deleted"? If you delete the branch (`git branch -D design`) and then recreate it based on the origin's (`git checkout -b design origin/design`), how would you end up with the old branch? You'd have to jump through a bunch of hoops (using the reflog or deliberating pulling those deleted commits) to do that. – mipadi Jul 28 '16 at 23:22
  • Exactly that has happened to me before. That's why I don't trust deleting branches and repulling. – erewok Jul 28 '16 at 23:39
  • 1
    @erewok: But if you get those commits after repulling, aren't you then "discarding commits to match the repository version"? In other words, if they're in the remote repo and you get them after pulling, then you're doing what this question *wants* to do. If you also want to remove them from the remote repo, then yes, you have to perform a few more commands—but that's not what this question is asking. It *wants* the local branch to match up with the remote's. – mipadi Jul 29 '16 at 00:19
11

When you want to discard changes in your local branch, you can stash these changes using git stash command.

git stash save "some_name"

Your changes will be saved and you can retrieve those later,if you want or you can delete it. After doing this, your branch will not have any uncommitted code and you can pull the latest code from your main branch using git pull.

user4948761
  • 129
  • 1
  • 5
7

In the source root: git reset ./ HEAD <--un-stage any staged changes git checkout ./ <--discard any unstaged changes

7

@Will, git immersion is a really nice and simple git tutorial. it will show you how to undo changes for the following cases: unstaged, staged and committed. labs 14-18

Cesar A. Rivas
  • 1,355
  • 1
  • 10
  • 13
  • 2
    I'd just like to say I've now done git immersion .. over a year later. OI! I should have done this so much sooner ... – Will May 15 '12 at 20:21
  • 1
    This needs `Ruby` to be installed..which doesn't seem always a choice – Vishnu Jun 08 '18 at 07:53
  • please add the relevant information in this post, so that the answeer dont die the day the link rots. – LudvigH Jun 10 '21 at 15:40
6

REVERSIBLE Method to Discard All Changes:

I found this question after making a merge and forgetting to checkout develop immediately afterwards. You guessed it: I started modifying a few files directly on master. D'Oh! As my situation is hardly unique (we've all done it, haven't we ;->), I'll offer a reversible way I used to discard all changes to get master looking like develop again.

After doing a git diff to see what files were modified and assess the scope of my error, I executed:

git stash
git stash clear

After first stashing all the changes, they were next cleared. All the changes made to the files in error to master were gone and parity restored.

Let's say I now wanted to restore those changes. I can do this. First step is to find the hash of the stash I just cleared/dropped:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

After learning the hash, I successfully restored the uncommitted changes with:

git stash apply hash-of-cleared-stash

I didn't really want to restore those changes, just wanted to validate I could get them back, so I cleared them again.

Another option is to apply the stash to a different branch, rather than wipe the changes. So in terms of clearing changes made from working on the wrong branch, stash gives you a lot of flexibility to recover from your boo-boo.

Anyhoo, if you want a reversible means of clearing changes to a branch, the foregoing is a less dangerous way in this use-case.

F1Linux
  • 3,580
  • 3
  • 25
  • 24
3

For others, if you want to just revert changes on a single file:

git restore <fileName>
Brendan Boyle
  • 173
  • 1
  • 1
  • 7
3

List to work on this

git checkout -f

git reset --hard

git reset --hard HEAD^

To remove a newly added file do the following command:-

git reset HEAD < file >

This will work for both modified file and newly added file.

2

git checkout -f

This is suffice for your question. Only thing is, once its done, its done. There is no undo.

thestar
  • 4,959
  • 2
  • 28
  • 22
1

So, there's a number of legacy answers here. I'm going to show you how I start over on a branch in 2021:

When you have made dozens of commits and dozens of files changed and you need to reset

git checkout master
git pull origin master
git checkout -b feat-foo-v2 # make a second version of feat-foo branch

now you have a fresh branch. But you likely still did a bunch of work that is still good, you just need to pull in those files. While in your root git directory:

git checkout feat-foo -- path/to/file/to/be/used.java

Now you have a copy of the individual file from the old branch. Do this a few more times, and the old branch will be obsolete. Now you can feel free to delete that branch, and rename feat-foo-v2 to feat-foo.

Let's say you have a file with some changes, and you only want to pull in some of those changes. I suggest getting familiar with the --patch option on git checkout:

git checkout -p feat-foo -- path/to/file.java

will open up a dialog that allows you to select the parts of the changes to the file you want to keep.

When you can't just make a new branch For some reason, you're just enamored with your feature branch and you're unwilling or unable to give it up. You know you need to reset a few files, but you shouldn't need to reset the whole thing. Creating a whole new branch was actually just an un-necessary step. We can pull the fresh files from master:

git checkout master -- path/to/file.java

and now a file is reset! And if you just want to reset part of a file, --patch should work the same way.

Zach Folwick
  • 893
  • 10
  • 18
1

To make the branch exactly like the remote...

git fetch --all
git reset --hard origin/<BRANCH_NAME>
git clean -fdx # STAY ALERT! Untracked (.gitignore) directories and files will be gone!

Have fun!

Eduardo Lucio
  • 1,771
  • 2
  • 25
  • 43
0

If you want to redo/re-do all the changes on your branch:

git pull origin master --rebase # or, denote the latest "base" or "master" commit on your branch
git push
git reset --soft origin/<current branch name>
# re-evaluate all your changes, tweaking them at will
git reset --soft origin/master
# commit your tweaks, push
Devin Rhode
  • 23,026
  • 8
  • 58
  • 72
-3

How about rm -rf <working dir> followed by git clone <repo>.git

After reading all these suggestions, its exactly what I ended up doing and it worked perfectly!

Sean DiZazzo
  • 679
  • 8
  • 13
  • 1
    resetting the entire project from scratch just to undo the changes in a file is not a solution. Please use `git restore` or `git stash` – Abhinay Aug 25 '21 at 05:17