Reputation: 11885
Common recommendations to reset your working copy (master
branch) to the state of the upstream branch seem to be:
git checkout master
git fetch
git reset --hard origin/master
and
git checkout master
git reset --hard
git pull
Or with detaching the HEAD:
git checkout origin/master
git reset --hard
git pull origin master
The problem I have with these is that they are not fail-safe. The working copy could be in a state which results in a checkout error:
error: Your local changes to the following files would be overwritten by checkout:
...
Please commit your changes or stash them before you switch branches. Aborting
What seems to do the trick is the following:
git fetch
git checkout --force origin/master -B master
The checkout is forced, getting rid of local changes. The remote branch is checked out, overwriting a possibly existing local branch master
and not detaching the HEAD. origin/master
should refer to the latest remote HEAD because git fetch
is run before the checkout.
My question: are there additional Git corner cases which could prevent these commands from failing? Some weird working copy state, like in the middle of a merge, with untracked files becoming tracked or vice versa, ignored files being staged, submodule related things or something along these lines?
What commands would be equivalent to deleting the entire working copy and cloning the repository again? (I don't want to actually re-clone because the repository in question is huge.)
Upvotes: 0
Views: 931
Reputation: 3950
A force-checkout will overwrite untracked files in the working directory if they are tracked in the to-be checked-out branch, but it will not remove untracked files that are not part of the checkout.
Clean checkout the way I recommend it:
First clean up the working directory:
E.g. use one of these approaches:
git stash save -u 'some message'
.git stash apply stash{0}
git stash show -p stash@{0}
git show stash@{0}^3
.0
) may change if you save more stashes after this.git stash list
if in doubt which number to use.git status --ignored
and then using git stash save --all 'some message'
.git reset --hard HEAD; git clean -f -d
. Make sure you that you actually want to do this as you cannot undo this.git status --ignored
and then using git clean -f -d -x
. Make sure you that you actually want to do this as you cannot undo this. Usually this should not be necessary to avoid checkout collisions.After your cleanup of your working directory you should be able to checkout whichever branch you want without collisions.
(I don't want to actually re-clone because the repository in question is huge.)
Not sure if you're aware, so just in case that the bandwith is the problem here:
You can clone repositories locally. So instead of re-cloning e.g. from github, you could instead do a local git clone ./repo repo_new
and the adjust the origin in the new repo e.g. with git remote set-url https://mygitsvr/user/repo
.
Upvotes: 1