Reset local repository branch to be just like remote repository HEAD
Asked Answered
H

27

5712

How do I reset my local branch to be just like the branch on the remote repository?

I tried:

git reset --hard HEAD

But git status claims I have modified files:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
      modified:   java/com/mycompany/TestContacts.java
      modified:   java/com/mycompany/TestParser.java
Hydropathy answered 27/10, 2009 at 0:27 Comment(6)
According to the output of git status your second command git reset --hard HEAD failed. You didn’t paste it’s output, though. → Incomplete question.Selfconfessed
You are mixing two issues here: 1) how to reset a local branch to the point where the remote is and 2) how to clear your staging area (and possibly the working directory), so that git status says nothing to commit, working directory clean. – Please specify!Selfconfessed
Does this answer your question? How do I force "git pull" to overwrite local files?Est
Obviously not an answer if the repo is large, but for small repos you can hit it with a hammer and avoid git entirely: rm -fr ./repo; git clone repo. best way i've foundHibernate
I hit the same; I was trying git reset --hard origin/master when it should have been git reset --hard origin/main.Lexine
git reset --hard FETCH_HEAD worked for me. I hadn't pushed after rebase.Dabney
G
9793

Setting your branch to exactly match the remote branch can be done in two steps:

git fetch origin
git reset --hard origin/master

If you want to save your current branch's state before doing this (just in case), you can do:

git commit -a -m "Saving my work, just in case"
git branch my-saved-work

Now your work is saved on the branch "my-saved-work" in case you decide you want it back (or want to look at it later or diff it against your updated branch).

Note that the first example assumes that the remote repo's name is "origin" and that the branch named "master" in the remote repo matches the currently checked-out branch in your local repo.

BTW, this situation that you're in looks an awful lot like a common case where a push has been done into the currently checked out branch of a non-bare repository. Did you recently push into your local repo? If not, then no worries -- something else must have caused these files to unexpectedly end up modified. Otherwise, you should be aware that it's not recommended to push into a non-bare repository (and not into the currently checked-out branch, in particular).

Genni answered 27/10, 2009 at 1:44 Comment(28)
Thank you for your answer. You said 'Note that the first example assumes that the remote repo's name is "origin" and that the branch named "master" in the remote repo matches the branch in your local repo.' How can I double check my remote repo's name and my branch name to be sure before I execute 'git reset --hard'? Thanks again.Hydropathy
If you didn't explicitly name the remote, then it's name is likely just "origin" (the default). You can use "git remote" to get a list of all remote names. You can then use "git remote <name>" to see which branches push/pull with each other (e.g. if your "master" branch was cloned from "master" in the remote named "origin", then you'll get a line that says "master merges with remote master").Genni
"it's not recommended to push into a non-bare repository (and not into the currently checked-out branch, in particular" Why is that?Elbrus
Just after fetching, I believe you can do git reset FETCH_HEAD --hard instead, as well, that's the same meaning.Alegre
@DanMoulding Is there a way to do this to a branch that isn't the current branch? Eg, I'm on branch ticket1066_super_new_feature and I want to reset uat_stable to origin/uat_stable without first doing git checkout uat_stable. If there is, would you consider adding this to the answer?Benzine
@Benzine I don't think there is a way to do that, at least not with git-reset. git-reset always operates on the current HEAD (i.e. the currently checked-out branch).Genni
@undashes What if I fetch into bare repository and cannot execute git reset FETCH_HEAD --hard because there's no work tree?Megaron
It did not remove files I have added.Latrell
In case you lost a commit because of the reset, you can use git reflog to find it and git cherry-pick $hash to restore it to the branch.Gesticulative
-1; I can't make any sense of the claim that the behaviour described by the OP looks like a consequence of pushing to the checked out branch of a non-bare repo. I've just tried pushing to the checked out branch of a non-bare repo; it simply updates the HEAD of the branch without updating the work tree. Yes, that can (and probably will) cause the branch to have a non-clean work tree. But it doesn't produce a situation in which a subsequence git reset --hard leaves file modifications in the work tree. I can't find any evidence that pushing to a non-bare repo could cause the behavior in the OP.Tailorbird
What if the branch I am working on is not master but some-new-feature? Is it git fetch origin` git reset --hard origin/some-new-feature ?Hufuf
@RazvanZamfir yes, exactly. I think this should be stated in the answer the first thing. A beginner might reset a local feature branch to master accidentally and be in more trouble that way.Jeanelle
When using a --bare repository you might need to make sure that remote tracking is enabled or you might get a fatal: ambiguous argument 'origin/master': unknown revision or path not in the working tree. See #38981970Maddy
@DanMoulding Why do you use git fetch origin ? origin being already set in git reset --hard origin/master, what would it change if I don't run git fetch origin ?Fowler
I had new files in my branch. So fetching and reset didn't delete them automatically. Otherwise all other changes were overwritten by the remote. Thank youHorsa
@SardarFaisal If you want to remove new/untracked files, you can run git clean first. Run git clean -n to see what would happen (i.e. which files would be removed), and git clean -f to actually remove them.Crossbench
@Fowler If you don't git fetch origin before you reset to the remote, then your local copy of the remote repository will not necessarily have all of the latest changes. Git doesn't automatically pull updates from remotes. I'll just add that if you don't specify a branch name it will reset the current branch to the tracking branch, i.e., git reset --hard origin will reset to origin/master if your current branch is tracking origin/master. The same is true for any other branch tracking a remote branch. Might be safer for new users.Keare
i did git fetch origin and git reset --hard origin/master and now i have 1200/26000 commits up/down and 92 local changes. how can that be?Planar
I did not have to use git fetch, but it still worked. Why why fetch included here?Libbielibbna
@EcksDee fetch makes sure you have the latest from the remote, otherwise you'll just reset to whatever commit you had locally, which may not be the actual latest commit if others have pushed commits to the remote.Microprint
If you want to save your current branch's state before doing this, you can also use git stash like the other answers mentioned below.Turgot
@Turgot git stash will not save the branch's state in a way that will survive a git reset. git stash will only save the uncommitted content in the working tree. Creating a copy of the branch will safely save the entire branch's state, such that it can be restored after the git reset, if needed.Genni
@DanMoulding, thanks for the explanation. Now I get your meaning: Use branching to save the commits in local repositories but not in the remote counterpart. But I think git stash will not lose the commits after a git reset as git stash list can show the commit's hash and you can use git reset --hard <commit's hash> to return and apply the stash.Turgot
You can also do a git clean to remove any untracked filesRiant
run git checkout master afterwards, too to prevent Get detached headPiccard
Typing the remote branch name is both inconvenient and error prone. Instead one may want to use either git reset --hard "@{u}" or git reset --hard ORIG_HEAD. Both do the same thing. The latter one is mentioned on the official git documentation git-scm.com/docs/git-reset#Documentation/…Null
@StanislavGerman-Evtushenko @{u} works consistently. ORIG_HEAD only works after the specific case of [fetch + merge/rebase]. It wouldn't work if you last moved @{u} via push or fetch, for instance. "ORIG_HEAD is created by commands that move your HEAD in a drastic way (git am, git merge, git rebase, git reset), to record the position of the HEAD before their operation, so that you can easily change the tip of the branch back to the state before you ran them." sourceMetaphrast
You are right. Thank you for this remark.Null
M
647

I needed to do (the solution in the accepted answer):

git fetch origin
git reset --hard origin/master

Followed by:

git clean -f

to remove local files

To see what files will be removed (without actually removing them):

git clean -n -f
Meteoroid answered 27/12, 2014 at 6:20 Comment(10)
also, git clean -d -f if there are untracked directories present.Raptor
also git clean -fdxInane
If you want exact copy of remote branch you have to follow by git clean -ffdx. Note that thare are two f.Latrell
The git clean -f was the essential piece I needed. Thanks!Wystand
I have the same problem, unfortunately, none of these commands worked for me. git status still reports a list of modified files.Spirillum
be careful using the clean command. it can delete ignored files from other branches.Selinaselinda
@PopeyGilbert, it will happend if .gitignore is different in two branches.Meteoroid
also git clean -nxdfCreeps
Do I need to do a git pull after this, per @Auk , or is doing so redundant?Pellet
git clean -fdx Stay alert! Untracked directories will be gone❗😉Penicillate
A
641

First, use git reset to reset to the previously fetched HEAD of the corresponding upstream branch:

git reset --hard @{u}

The advantage of specifying @{u} or its verbose form @{upstream} is that the name of the remote repo and branch don't have to be explicitly specified. On Windows or with PowerShell, specify "@{u}" (with double quotes).

Next, as needed, use git clean to remove untracked files, optionally also with -x:

git clean -df

Finally, as needed, get the latest changes:

git pull
Auk answered 10/2, 2015 at 20:27 Comment(10)
This seems like a better answer than the accepted one, because it dynamically resets to the current upstream branch rather than always a static one such as origin/masterLimpid
@Jonz spot on, the @{upstream} is very handy and can be used in aliases: alias resetthisbranch="git reset --hard @{upstream}"Santiagosantillan
why do we need add @{u} what difference it will make?Parshall
@GangadharJannu git reset --hard requires a commit, else it wouldn't know what to reset you to. @{u} points to a specific commit – the head of the tracked branch, from when you last did a git fetch.Endblown
@KristofferBakkejord Thanks for the explanation but even without commit hash we can do git reset --hard though it will not reset to remote branchParshall
@GangadharJannu I believe it won't even reset to the local branch then, but to the git index instead.Auk
For anyone else who almost opened a new question here, if you git from Powershell, use quotes (git reset --hard "@{u}"). Took me a while to figure that out.Acentric
This works when the the accepted answer doesn't and error you're getting is "warning: refname 'origin/master' is ambiguous." Thank you!Tomikotomkiel
@Acentric using the quotes also worked for me in git bash on Windows. CheersPreview
This should be the accepted answer. Reseting to origin/HEAD doesn't work everytimeCointon
G
215

git reset --hard HEAD actually only resets to the last committed state. In this case HEAD refers to the HEAD of your branch.

If you have several commits, this won't work..

What you probably want to do, is reset to the head of origin or whatever you remote repository is called. I'd probably just do something like

git reset --hard origin/HEAD

Be careful though. Hard resets cannot easily be undone. It is better to do as Dan suggests, and branch off a copy of your changes before resetting.

Globule answered 27/10, 2009 at 1:8 Comment(2)
There was an incorrect suggestion in my answer that Dan caught earlier. I edited it away, since I don't want to lead anyone astray. As to the origin/master or origin/HEAD stuff, I expect that depends on whether or not you actually do a fetch first. If you just cloned origin, and it had no other branches, which I find to be quite common, then it should reset it fine. But of course, Dan is right.Globule
This doesn't work as origin/HEAD is not necessarily the latest commit of your current branch in origin. Use instead : git reset --hard @{u}Cointon
A
103

All of the above suggests are right, but often to really reset your project, you also need to remove even files that are in your .gitignore.

To get the moral equivalent of erasing your project directory and re-cloning from the remote is:

git fetch
git reset --hard
git clean -x -d -f

Warning: git clean -x -d -f is irreversible and you may lose files and data (e.g. things you have ignored using .gitignore).

Athanasius answered 23/7, 2015 at 17:48 Comment(3)
Warning: "git clean -x -d -f" is irreversible and you may loose files and data in .gitignoreHomograft
A little shorter: git clean -xdf that is equal to git clean -x -d -f.Wretched
git clean -ffxd to remove everything not in the repoLatrell
H
70

Use the commands below. These commands will remove all untracked files from local git too

git fetch origin
git reset --hard origin/master
git clean -d -f
Habiliment answered 22/3, 2019 at 10:19 Comment(2)
This is a more complete response because without the git clean -d -f we'll still had some things of the old branch in local directory. Thanks man.Jungjungfrau
git clean -ffxd to truely remove everythingLatrell
S
50

The question mixes two issues here:

  1. how to reset a local branch to the point where the remote is
  2. how to clear your staging area (and possibly the working directory), so that git status says nothing to commit, working directory clean.

The one-stop-answer is:

  1. git fetch --prune (optional) Updates the local snapshot of the remote repo. Further commands are local only.
    git reset --hard @{upstream}Puts the local branch pointer to where the snapshot of the remote is, as well as set the index and the working directory to the files of that commit.
  2. git clean -d --force Removes untracked files and directories which hinder git to say “working directory clean”.
Selfconfessed answered 31/1, 2016 at 1:29 Comment(2)
The @{upstream} syntax requires upstream to be set which happens by default if you git checkout <branchname>. – Otherwise replace it with origin/<branchname>.Selfconfessed
Add -x to git clean to remove everything not in the commit (i.e. even files ignored with the .gitignore mechanism).Selfconfessed
M
36

Provided that the remote repository is origin, and that you're interested in branch_name:

git fetch origin
git reset --hard origin/<branch_name>

Also, you go for reset the current branch of origin to HEAD.

git fetch origin
git reset --hard origin/HEAD

How it works:

git fetch origin downloads the latest from remote without trying to merge or rebase anything.

Then the git reset resets the <branch_name> branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/branch_name.

Moraine answered 8/5, 2017 at 11:12 Comment(2)
I'm not sure I follow origin/HEAD here and I don't think it's correctAshelman
This is what I was looking for. All other answer reset with remote master branch, I wanted to know remote current branch. The answer if pretty straight-forward thoughHel
H
28

This is something I face regularly, & I've generalised the script Wolfgang provided above to work with any branch

I also added an "are you sure" prompt, & some feedback output

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# AT 2012-11-09
# see https://mcmap.net/q/11478/-reset-local-repository-branch-to-be-just-like-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
branchname=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`
read -p "Reset branch $branchname to origin (y/n)? "
[ "$REPLY" != "y" ] || 
echo "about to auto-commit any changes"
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  echo "Creating backup auto-save branch: auto-save-$branchname-at-$timestamp"
  git branch "auto-save-$branchname-at-$timestamp" 
fi
echo "now resetting to origin/$branchname"
git fetch origin
git reset --hard origin/$branchname
Hammett answered 9/11, 2012 at 13:1 Comment(2)
you might want to use "git remote" to get the name of the remote. In certain cases, it won't be "origin"Richmal
The logic in your script is not correct. The [ "$REPLY" != "y" ] || will only skip the next line echo "about to auto-commit any changes" and continue running the rest of the script. The line should read something like [[ "$REPLY" != "y" ]] && { echo "Exiting branch reset"; exit; }.Klopstock
A
28

You can fetch the origin and reset to solve the problem

 git fetch origin
 git reset --hard origin/main

You can save your changes before doing the reset like below,

git stash

And after resetting, if you want that changes back, you can simply run,

git stash apply
Afterheat answered 25/6, 2022 at 5:29 Comment(0)
D
22

I did:

git branch -D master
git checkout master

to totally reset branch


note, you should checkout to another branch to be able to delete required branch

Dedradedric answered 14/5, 2014 at 7:48 Comment(4)
You should read question once again, there is nothing on affecting remote, but setting to same as remote, so you shouldn't do anything with remote, and this helped in my case and non of above.Dedradedric
If you want to set it to the same as remote, you should at least do a fetch at some point don't you agree?Savonarola
you should at least try this or read docs: kernel.org/pub/software/scm/git/docs/git-checkout.htmlDedradedric
Way to go, I had a corrupt .pck file in the branch and the rest of options didn't work, thanks!!Nummular
H
19

Here is a script that automates what the most popular answer suggests ... See https://mcmap.net/q/11478/-reset-local-repository-branch-to-be-just-like-remote-repository-head for an improved version that supports branches

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see https://mcmap.net/q/11478/-reset-local-repository-branch-to-be-just-like-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  git branch "auto-save-at-$timestamp" 
fi
git fetch origin
git reset --hard origin/master
Hectogram answered 15/10, 2012 at 8:50 Comment(0)
T
18

The answer

git clean -d -f

was underrated (-d to remove directories). Thanks!

Tabernacle answered 25/1, 2020 at 0:29 Comment(1)
And for a full, 100% clean repo folder with no extra files, run git clean -xdf. This will delete any and all files that git is not aware of, and will make your folder match what is in git's object list exactly. Note that you can add -n (e.g. git clean -nxdf) to perform a "what-if" and it will tell you what it will delete without actually doing anything. (git clean)Pyknic
C
18

2023 simple solution :

git fetch
git reset --hard @{u}

Reseting to origin/HEAD won't always work as it's not necessarily the latest commit of your current branch.

Cointon answered 29/8, 2023 at 13:53 Comment(1)
That was easy. Worked perfectly for resetting my local branch against a rebased (and squashed) originInnutrition
P
16

If you had a problem as me, that you have already committed some changes, but now, for any reason you want to get rid of it, the quickest way is to use git reset like this:

git reset --hard HEAD~2

I had 2 not needed commits, hence the number 2. You can change it to your own number of commits to reset.

So answering your question - if you're 5 commits ahead of remote repository HEAD, you should run this command:

git reset --hard HEAD~5

Notice that you will lose the changes you've made, so be careful!

Phinney answered 16/6, 2014 at 3:35 Comment(0)
S
14

Previous answers assume that the branch to be reset is the current branch (checked out). In comments, OP hap497 clarified that the branch is indeed checked out, but this is not explicitly required by the original question. Since there is at least one "duplicate" question, Reset branch completely to repository state, which does not assume that the branch is checked out, here's an alternative:

If branch "mybranch" is not currently checked out, to reset it to remote branch "myremote/mybranch"'s head, you can use this low-level command:

git update-ref refs/heads/mybranch myremote/mybranch

This method leaves the checked out branch as it is, and the working tree untouched. It simply moves mybranch's head to another commit, whatever is given as the second argument. This is especially helpful if multiple branches need to be updated to new remote heads.

Use caution when doing this, though, and use gitk or a similar tool to double check source and destination. If you accidentally do this on the current branch (and git will not keep you from this), you may become confused, because the new branch content does not match the working tree, which did not change (to fix, update the branch again, to where it was before).

Sergent answered 25/6, 2016 at 17:13 Comment(0)
T
13

This is what I use often:

git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;

Note that it is good practice not to make changes to your local master/develop branch, but instead checkout to another branch for any change, with the branch name prepended by the type of change, e.g. feat/, chore/, fix/, etc. Thus you only need to pull changes, not push any changes from master. Same thing for other branches that others contribute to. So the above should only be used if you have happened to commit changes to a branch that others have committed to, and need to reset. Otherwise in future avoid pushing to a branch that others push to, instead checkout and push to the said branch via the checked out branch.

If you want to reset your local branch to the latest commit in the upstream branch, what works for me so far is:

Check your remotes, make sure your upstream and origin are what you expect, if not as expected then use git remote add upstream <insert URL>, e.g. of the original GitHub repo that you forked from, and/or git remote add origin <insert URL of the forked GitHub repo>.

git remote --verbose

git checkout develop;
git commit -m "Saving work.";
git branch saved-work;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force

On GitHub, you can also checkout the branch with the same name as the local one, in order to save the work there, although this isn't necessary if origin develop has the same changes as the local saved-work branch. I'm using the develop branch as an example, but it can be any existing branch name.

git add .
git commit -m "Reset to upstream/develop"
git push --force origin develop

Then if you need to merge these changes with another branch while where there are any conflicts, preserving the changes in develop, use:

git merge -s recursive -X theirs develop

While use

git merge -s recursive -X ours develop

to preserve branch_name's conflicting changes. Otherwise use a mergetool with git mergetool.

With all the changes together:

git commit -m "Saving work.";
git branch saved-work;
git checkout develop;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;
git add .;
git commit -m "Reset to upstream/develop";
git push --force origin develop;
git checkout branch_name;
git merge develop;

Note that instead of upstream/develop you could use a commit hash, other branch name, etc. Use a CLI tool such as Oh My Zsh to check that your branch is green indicating that there is nothing to commit and the working directory is clean (which is confirmed or also verifiable by git status). Note that this may actually add commits compared to upstream develop if there is anything automatically added by a commit, e.g. UML diagrams, license headers, etc., so in that case, you could then pull the changes on origin develop to upstream develop, if needed.

Torrance answered 26/4, 2018 at 1:30 Comment(0)
D
11

Only 3 commands will make it work

git fetch origin
git reset --hard origin/HEAD
git clean -f
Demark answered 16/12, 2019 at 19:4 Comment(0)
I
9

The top rated answer here did not reset my local code as expected.

  1. nowadays, master is usually main
  2. it doesn't do anything with untracked files you may have lying around

Instead:

  1. check the name of your default remote branch (this is not a git thing so check in GitHub) then replace main or master in step 4 below with this

  2. save current stuff git stash -u

  3. update from remote git fetch origin

  4. reset to remote default branch (but see step 1 above) git reset --hard origin/main

Ignore answered 27/6, 2022 at 10:52 Comment(0)
R
8

If you want to go back to the HEAD state for both the working directory and the index, then you should git reset --hard HEAD, rather than to HEAD^. (This may have been a typo, just like the single versus double dash for --hard.)

As for your specific question as to why those files appear in the status as modified, it looks like perhaps you did a soft reset instead of a hard reset. This will cause the files that were changed in the HEAD commit to appear as if they were staged, which is likely what you are seeing here.

Recess answered 27/10, 2009 at 2:10 Comment(0)
T
8

No amount of reset and cleaning seemed to have any effect on untracked and modified files in my local git repo (I tried all the options above). My only solution to this was to rm the local repo and re-clone it from the remote.

Fortunately I didn't have any other branches I cared about.

xkcd: Git

Tann answered 1/12, 2016 at 10:25 Comment(0)
A
7

First, check with git status if you have any local changes. If yes, stash them.

Then execute:

git fetch
git reset --hard @{push}

It will reset the current local branch to the same remote branch which would be used for git push. This is especially useful when git config push.default current is configured. For example, when your branch is abc and remote is origin, it will reset it to origin/abc.

Please see Git revisions for more details about @{push}

Amalberga answered 15/12, 2022 at 9:32 Comment(1)
This is really neat. I'm going to change/add a bunch of aliases with this @{push}Jockstrap
S
4

The only solution that works in all cases that I've seen is to delete and reclone. Maybe there's another way, but obviously this way leaves no chance of old state being left there, so I prefer it. Bash one-liner you can set as a macro if you often mess things up in git:

REPO_PATH=$(pwd) && GIT_URL=$(git config --get remote.origin.url) && cd .. && rm -rf $REPO_PATH && git clone --recursive $GIT_URL $REPO_PATH && cd $REPO_PATH

* assumes your .git files aren't corrupt

Sustentation answered 14/9, 2017 at 19:28 Comment(1)
you can also just reinstall your operating system if you want to be certain!Dustup
J
4

Have you forgotten to create a feature-branch and have committed directly on master by mistake?

You can create the feature branch now and set master back without affecting the worktree (local filesystem) to avoid triggering builds, tests and trouble with file-locks:

git checkout -b feature-branch
git branch -f master origin/master
Jaal answered 17/10, 2019 at 14:38 Comment(0)
L
1
  • Throwing error because it has uncomitted changes.
  1. So, You can use git stash
  • This saves uncomitted changes away for later use, and then reverts them from your working copy.
  • If you want these changes again, you can use git stash apply
  1. Then You can use git pull
  • This takes the recent code from remote repo.
Lanni answered 8/2, 2022 at 5:26 Comment(1)
Doesn't work if you have conflicting unpushed commits (error: "fatal: refusing to merge unrelated histories")Satiable
N
0
git fetch origin
git checkout main
git reset --hard origin/main
# Local `master` branch is now up to date with remote `main`
Nairobi answered 10/7, 2023 at 16:41 Comment(0)
I
-2

If you don't mind saving your local changes, yet still want to update your repository to match origin/HEAD, you can simply stash your local changes and then pull:

git stash
git pull
Ironstone answered 10/9, 2014 at 13:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.