Use git push -f to force update the remote branch, overwriting it using the local branch's changes. This operation is necessary anytime your local and remote repository diverge.
git fetch downloads the latest from remote without trying to merge or rebase anything. git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master .
One explanation would be that the latest commits have been done on another branch, as explained in "Git pull from my public repository not working". The other possibility is for you to be in a detached HEAD mode. That would make any git pull "up-to-date" since you are in any branch.
Just like git push --force allows overwriting remote branches, git fetch --force (or git pull --force ) allows overwriting local branches.
This should do the trick:
git reset --hard HEAD
git pull
git fetch
git checkout origin/name_of_branch # correct state but in 'head without a name'
git checkout -B name_of_branch # overwrite current tree onto name_of_branch
This checks out the remote tracking branch into a head without a name, then you can have a look and check you're happy. Whenever you want to (even after changes or commits) the second git checkout labels your current tree with 'name_of_branch', even if it has to delete the old name_of_branch to do so.
The syntax of git commands seems unintuitive. In fact it's the Git data model that is unintuitive. This isn't bad design, but because it works with files, branches, commits in ways that are much more flexible and powerful than other version control systems. Once you grok how these things work in Git, the command line will make a lot of sense and you will be able to accurately guess how to do complicated things.
git fetch
This fetches all the updates that have happened on the origin
server since the last time. Git separates fetching from the server from updating, merging, etc. any of your branches. All the branches called origin/XXX
are your most recent versions of what's on the server. They are not remote branches but remote tracking branches, local branches which track remote branches. When you do git fetch
, you update them, without touching any of your own branches. When you do git merge
, git rebase
, and so on, you use the fetched version, without grabbing a more recent copy from the server. This means you have control over when network requests are made (if you aren't always connected to the server), and you can 'fetch' a snapshot of the server, then merge at your leisure. If in doubt, do git fetch
first.
git checkout origin/name_of_branch
git checkout
does two things. It updates your files to that branch, and it sets your HEAD
to that branch. The files things is what you'd expect. The HEAD
things means that when you do commits, they will added to the end of the branch that HEAD
points to. IOW, checkout
does both output - write the right versions of the files, and prepares for input - gets ready to store the commits you are going to do in the right place. If you checkout a branch called foo
, your tree changes to the state saved in foo
, and the next commits you do will be added to foo
. In the case of origin\xyz
, you can't write your changes to an origin
branch - these track what is on the origin
server and can't be committed to directly. So the checkout updates the files, and sets HEAD
to nothing - an unnamed branch. This stops you accidentally committing your newly checked out stuff back onto the previous branch you were using, and in fact you will be heavily discouraged by git from committing at all until you have a destination branch.git checkout -B name_of_branch
As usual, when git does two different things with one command, both of them can be configured separately. So the second part of what checkout
does, setting HEAD
to the branch you want to commit to, can be to a new branch, instead of the branch you're checking out, if you use the -B
option. So git checkout -B new_stuff old_stuff
will set all your files to the state in old_stuff
, but get you ready to write your commits to the new branch new_stuff
. This is a common task, and saves you checking out a branch then forking it, in two steps. Now, almost all arguments to git commands can be omitted, and git will do the most obvious thing. In this case, that is making a new branch based on the one you are on, rather than one you want to checkout. So git takes the unnamed branch you are on, and makes a new branch called name_of_branch
, which you can start committing to.
Note that an uppper case letter "B" kind of means 'force'. If you used "-b" git would refuse to overwrite an already existing branch. With "-B" it will go ahead and do it without warning or confirming.The go-to, knee-jerk, solution is: git reset --hard origin/master
†
† or origin/main
or whatever the name of your origin's branch is.
It's the almighty solution for experts and beginners alike that swiftly gets the job done. Albeit while blowing away all uncommitted changes without warning.
The safer command is slightly more of a pain to type: git checkout -B master origin/master
git config --global alias.become '!git checkout -B "$(git symbolic-ref --short HEAD)"'
Henceforth, one can type: git become origin/master
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With