1175

I have two branches:

  1. local branch (the one which I work with)
  2. remote branch (public, only well-tested commits go there)

Recently I seriously messed up my local branch.

How would I replace the local branch entirely with the remote one, so I can continue my work from where the remote branch is now?

I have already searched SO and checking out to the remote branch locally does not have any effect.

Dale K
  • 25,246
  • 15
  • 42
  • 71
YemSalat
  • 19,986
  • 13
  • 44
  • 51
  • 31
    I know the accepted answer has 1280 up-votes, but you should really consider changing the accepted answer to the one by @TTT. – Jamie May 22 '20 at 18:20

17 Answers17

1875
  1. Make sure you've checked out the branch you're replacing (from Zoltán's comment).
  2. Assuming that master is the local branch you're replacing, and that "origin/master" is the remote branch you want to reset to:

    git reset --hard origin/master
    

This updates your local HEAD branch to be the same revision as origin/master, and --hard will sync this change into the index and workspace as well.

Mathieu K.
  • 283
  • 3
  • 14
araqnid
  • 127,052
  • 24
  • 157
  • 134
  • 8
    Thanks for your suggestion, I am just so 'scared' of using --hard and --force already, so I just picked the solution which does not use those. – YemSalat Feb 09 '12 at 12:36
  • 18
    @KonstantinLevin: ah yes, the naming of those options is rather irritating. `git reset` by default will repoint your current branch and sync the index. `--soft` will skip updating the index, `--hard` will also sync the workspace. My own experience is using `--hard` most of the time, except when I want to undo the last commit (which is just `git reset HEAD^`) – araqnid Feb 09 '12 at 13:08
  • @KonstantinLevin, hard or force is scary but not "branch -d" (delete)? I like this solution, simple and straight to the point. – km1 Dec 10 '13 at 14:32
  • 11
    After having more experience with git I'm convinced this is a better solution, thanks. – YemSalat Dec 11 '13 at 03:37
  • 31
    probably you will need to fetch first: `git fetch origin remote_branch` – b1r3k Jul 30 '14 at 12:16
  • 1
    Probably because I have not done what @b1r3k have suggested, I was rolled back to the second last commit.... I did: `git commit`, `git push`, `than some crap`, `git reset --hard origin/master` and my local master branch was rolled back to commit before the last one... – b.b3rn4rd Nov 13 '14 at 23:38
  • This answer will NOT work if local files are corrupted. In that case you should use http://stackoverflow.com/questions/11706215/how-to-fix-git-error-object-file-is-empty/16421187#16421187 – Marco Faustinelli Dec 03 '14 at 09:08
  • Tried that just stuck in a never ending hell of mergetool fails that don't roll the changes back or forward, just make it worse and worse. Can't find any documentation on it. Git is just a complete and total nightmare. – Owl Jul 12 '16 at 14:27
  • 88
    You should note that this will replace **whichever branch** your currently on with the **contents of master**. So if you're on e.g. a feature-branch, it will replace all its commits with `master`, so make sure you've checked out the branch you're replacing first. – Zoltán Jul 15 '16 at 08:29
  • If you want to save any uncommitted changes, you'll want to stash them first, as this will discard them. – jpmc26 Mar 28 '17 at 20:38
  • git checkout master git fetch origin master git reset --hard origin/master git submodule update – Eugene Kaurov Aug 17 '17 at 09:05
  • git checkout master git fetch origin master git reset --hard origin/master git pull git submodule foreach git submodule update git status – Eugene Kaurov Aug 18 '17 at 12:54
  • What if the branch I want to replace isn't `master`? – Jon Schneider Dec 05 '17 at 21:05
  • 1
    It looks like this should actually be git reset --hard remote/origin/master for more current versions of git. – Wedge Jan 05 '18 at 23:33
386

I'm kind of surprised no one mentioned this yet; I use it nearly every day:

git reset --hard @{u}

Basically, @{u} is just shorthand for the upstream branch that your current branch is tracking. For example, this typically equates to origin/[my-current-branch-name]. It's nice because it's branch agnostic.

Make sure to git fetch first to get the latest copy of the remote branch.

Side Note: In most shells the command will work as written, but if you're using Git in PowerShell or csh you'll need to escape the special characters first, though I've also confirmed it works as a string in both, so for example:

git reset --hard '@{u}'
TTT
  • 22,611
  • 8
  • 63
  • 69
  • 1
    This looks like the most modern approach, the previous approach of `git reset --hard origin/master` is rejected on my 2.29.2 git executables which print out `# fatal: Cannot do hard reset with paths.` – jxramos Nov 07 '20 at 04:31
  • 2
    Surprised no one has mentioned that using it every day seems like an anti-pattern - what local changes are you clobbering constantly? This should be an rare occurrence or your usage of VCS needs to be reworked. – Kevin Lee May 20 '21 at 08:30
  • 7
    @KevinLee LOL. That's harsh! When I wrote that I was on the DevOps team and did a lot of throwaway testing of builds and merges, daily. As a developer I still do that sometimes but admittedly it's no longer "every day". Nowadays it's usually when I catch minor things while doing code reviews, and I fix them up and amend or rebase other dev's branches for them. When I'm done I instruct them to do this command on their own local branch so they can grab my changes before addressing the other suggestions in their PR. That's probably weekly, at least. ;) – TTT May 20 '21 at 15:37
  • 1
    @KevinLee I just thought you'd be happy to know in the last couple of weeks I'm still finding myself doing this almost every day. I tend to do a lot of throwaway commits regularly, for various reasons (answering SO questions or learning new Git commands, teaching my co-workers about Git and demoing commands to them, and while coding, testing merges), and it's slightly faster for me to to type `@{u}` than it is to figure out how many commits I need to reset back with `@~X`. – TTT Jun 08 '21 at 14:54
  • @TTT fair, those are good use cases - and makes a lot of sense for DevOps as well. I suppose its more of a design problem with git's API, `reset --hard` is named like it should be done infrequently and by people who know what they're doing. Or maybe the "right" thing to do is make a new branch for your mucking around and clobber the branch when you're done. – Kevin Lee Aug 15 '21 at 22:00
  • 1
    Downvoted for PowerShill details. Bash and csh (or at least csh) also require escaping/"strings" and are much more widely used. – user234461 Oct 10 '22 at 10:23
  • @user234461 Actually, I've tested this in bash, zsh, ksh, dash, and windows command line, and none of them need to be escaped. Only PowerShell and (now I know csh too) need to be escaped. I've updated the Side Note to include csh as well. – TTT Oct 10 '22 at 16:23
  • "no upstream configured for branch 'master' " – clockw0rk Feb 16 '23 at 00:17
  • 1
    @clockw0rk This answer's shorthand assumes your local branch is tracking a remote branch. If it isn't, then either you can use `git reset --hard origin/master`, or you can first set the upstream: `git branch -u origin/master` and from then on you can use this answer's shorthand. – TTT Feb 16 '23 at 03:24
  • Beers on me, this is a god-send answer. Worked great with modern git config circa mid 2023 – Llama D'Attore Jun 15 '23 at 03:08
337

That's as easy as three steps:

  1. Delete your local branch: git branch -d local_branch

  2. Fetch the latest remote branch: git fetch origin remote_branch

  3. Rebuild the local branch based on the remote one:

    git checkout -b local_branch origin/remote_branch

scharfmn
  • 3,561
  • 7
  • 38
  • 53
adamsmith
  • 5,759
  • 4
  • 27
  • 39
  • 8
    Actually what @araqnid said is right and more concise. I've tested it and you may try it too. – adamsmith Feb 09 '12 at 12:58
  • Wow, the git checkout -b local_branch origin/remote_branch is great! I always did this in two seperate commands. thanks! – kendepelchin Feb 15 '13 at 13:47
  • 26
    You might need to do `git branch -D local_branch` in the first step if your branch is not merged. – szeryf Jul 04 '13 at 09:44
  • thanks, I had a hard time when using gitflow, after publishing a branch and then finishing it, i wanted to go to the deleted branch, and your solution was the only one that worked, pull does not seem to work.. or I mave have not use it well -- – Decebal Mar 03 '14 at 12:25
  • 3
    we should ensure that the current branch is not the one which is to be to deleted. – a_secenthusiast Dec 30 '16 at 03:44
  • What's the difference between this and just doing `git checkout remote_branch` as the second step? – xr280xr Apr 19 '22 at 21:09
51
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>
Sailesh
  • 25,517
  • 4
  • 34
  • 47
  • What does the --track part do? – Sentry.co Aug 11 '17 at 13:46
  • 4
    @GitSync, This is what `git help branch` says about `--track`. `When creating a new branch, set up branch..remote and branch..merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out.` I fixed this command in the answer. Thanks for raising the point. – Sailesh Aug 14 '17 at 16:57
  • 2
    You can say that it is just for convenience. If you do `git status`, it will report if your local branch is ahead or behind remote branch if you have them associated. Additionally, you can do `git pull` (or `push`) instead of full `git pull ` if you have already set your branch to track ``. – Sailesh Aug 15 '17 at 19:54
  • I did `git branch -m old/` instead of deleting, just in case. – Markus Graf Oct 14 '22 at 09:20
35

Replace everything with the remote branch; but, only from the same commit your local branch is on:

git reset --hard origin/some-branch

OR, get the latest from the remote branch and replace everything:

git fetch origin some-branch
git reset --hard FETCH_HEAD

As an aside, if needed, you can wipe out untracked files & directories that you haven't committed yet:

git clean -fd
Modular
  • 6,440
  • 2
  • 35
  • 38
  • 1
    The `git clean` command did it for me. `git reset hard origin/master` do not wipe out untracked files. Thanks! – Mornor Dec 10 '19 at 08:57
10

The safest and most complete way to replace the current local branch with the remote:

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

The stash line saves the changes that you have not committed. The branch line moves your branch to a different name, freeing up the original name. The fetch line retrieves the latest copy of the remote. The checkout line recreates the original branch as a tracking branch.

Or as a bash function:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

which renames the current branch to something like replaced_master_98d258f.

Joshua S
  • 301
  • 2
  • 6
7

It can be done multiple ways, continuing to edit this answer for spreading better knowledge perspective.

1) Reset hard

If you are working from remote develop branch, you can reset HEAD to the last commit on remote branch as below:

git reset --hard origin/develop

2) Delete current branch, and checkout again from the remote repository

Considering, you are working on develop branch in local repo, that syncs with remote/develop branch, you can do as below:

git branch -D develop
git checkout -b develop origin/develop

3) Abort Merge

If you are in-between a bad merge (mistakenly done with wrong branch), and wanted to avoid the merge to go back to the branch latest as below:

git merge --abort

4) Abort Rebase

If you are in-between a bad rebase, you can abort the rebase request as below:

git rebase --abort
Amit Kaneria
  • 5,466
  • 2
  • 35
  • 38
2

The selected answer is absolutely correct, however it did not leave me with the latest commit/pushes ...

So for me:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

Since I know I want to temporarily set my upstream branch for a few weeks to a specific branch ( same as the one i switched to / checked out earlier and did a hard reset on )

So AFTER reset

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 
Tom Stickel
  • 19,633
  • 6
  • 111
  • 113
2

You can do as @Hugo of @Laurent said, or you can use git rebase to delete the commits you want to get rid off, if you know which ones. I tend to use git rebase -i head~N (where N is a number, allowing you to manipulate the last N commits) for this kind of operations.

ksol
  • 11,835
  • 5
  • 37
  • 64
  • Actually it was the 'git rebase' command that messed the whole thing up, then some forced merges and hard resets.. Anyway, what I was looking for is just some easy way of pulling the whole repo from remote server without merging. – YemSalat Feb 09 '12 at 12:17
1

If you want to update branch that is not currently checked out you can do:

git fetch -f origin rbranch:lbranch
Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
kqr
  • 406
  • 8
  • 12
1

git checkout .

i always use this command to replace my local changes with repository changes. git checkout space dot.

kamal
  • 21
  • 2
1

The way I did it was by deleting the local branch and making a git pull:

git branch -d local-branch-name
git pull
Felipe CS
  • 80
  • 10
0

As provided in chosen explanation, git reset is good. But nowadays we often use sub-modules: repositories inside repositories. For example, you if you use ZF3 and jQuery in your project you most probably want them to be cloned from their original repositories. In such case git reset is not enough. We need to update submodules to that exact version that are defined in our repository:

git checkout master
git fetch origin master
git reset --hard origin/master
git pull

git submodule foreach git submodule update

git status

it is the same as you will come (cd) recursively to the working directory of each sub-module and will run:

git submodule update

And it's very different from

git checkout master
git pull

because sub-modules point not to branch but to the commit.

In that cases when you manually checkout some branch for 1 or more submodules you can run

git submodule foreach git pull
Eugene Kaurov
  • 2,356
  • 28
  • 39
  • Please provide an explanation, especially when answering questions this old. Your answer is not helpful as-is. – Erik A Aug 18 '17 at 14:40
  • 1
    The accepted answer already proposes `git reset --hard`. This adds little value. – florisla Aug 18 '17 at 15:13
0
git reset --hard
git clean -fd

This worked for me - clean showed all the files it deleted too. If it tells you you'll lose changes, you need to stash.

Travis Heeter
  • 13,002
  • 13
  • 87
  • 129
0
  1. git fetch origin remote_branch
  2. git reset --hard FETCH_HEAD
0

Put the following command in your ~/.gitconfig file

[alias]
    override = "!f() { git fetch $1 && git reset --hard $1/$2 ; }; f"

Then assuming you have added a remote url called fork

git remote add fork git@github.com/xyz

you can completely override local <branch_name> with remote fork/<branch_name> like so:

git override fork <branch_name>
John Jiang
  • 827
  • 1
  • 9
  • 19
-4

The ugly but simpler way: delete your local folder, and clone the remote repository again.

Hugo
  • 2,569
  • 1
  • 19
  • 18
  • 12
    Or just delete the branch and check it out again. – laurent Feb 09 '12 at 12:08
  • Yep, I guess thats what I'm gonna do if I dont find how to do it in a less 'ugly' way – YemSalat Feb 09 '12 at 12:19
  • 3
    Ugly is sometimes useful to know. I do wish people wouldn't downvote things just because they're not the conventional way: there must be a more rational reason for downvoting... and it should be given. Git is a thing which achieves results. It is not some kind of sacred text. – mike rodent Nov 19 '17 at 11:22
  • 4
    I don't understand the downvotes :-( Yes, it is inelegant, etc. but it can work best in some cases... sorry @Hugo – silverdr May 10 '19 at 19:46
  • 1
    @Hugo, Agreed. Something mysterious and smelly happened to my local develop branch, and both the Team Lead and Engineering Manager suggested, among more elegant solutions, to just (zip, copy, and save my feature work, then) nuke the local repo and reclone. – AmitaiB May 22 '19 at 23:50
  • You should consder the amount of code developers have to deal with. Cloning cane take hours too. – Aakash Patel Apr 17 '20 at 08:21
  • ... a.k.a. ["The xkcd Git workflow"](https://xkcd.com/1597/) ... oft used, but an indication that you don't know your tooling. – 0xC0000022L Jun 06 '23 at 13:12