Suppose I pull changes from a git repo. Then the author of the repo force pushes to the central repo. Now I can’t pull since the history is rewritten.
How can I pull the new commits (and abandon the old ones), assuming that the author force-pushed the correct version?
I know this is bad git workflow, but sometimes you can’t avoid this.
Throwing away your local changes
If you want to discard your work,
fetchandreset. For example, if you have a remote namedoriginand a branch namedmaster:Keeping your local changes
If you don’t want to throw away your work, you will have to do a
git rebase --onto. Suppose the oldoriginlooks like this:And you have this:
Now, the upstream changes change things:
You would have to run
git rebase --onto origin/master <C> master, where<C>is the SHA-1 of the oldorigin/masterbranch before upstream changes. This gives you this:Notice how B, C, X, Y, and Z are now “unreachable”. They will eventually be removed from your repository by Git. In the meantime (90 days), Git will keep a copy in the reflog in case it turns out you made a mistake.
Fixing mistakes
If you
git resetorgit rebasewrong and accidentally lose some local changes, you can find the changes in the reflog.In the comments, a user is suggesting
git reflog expirewith--expire=nowbut DO NOT RUN THIS COMMAND because this will DESTROY your safety net. The whole purpose of having a reflog is so that Git will sometimes save your neck when you run the wrong command.Basically, what this command will do is immediately destroy the B, C, X, Y, and Z commits in the examples above so you can’t get them back. There’s no real benefit to running this command, except it might save a little bit of disk space, but Git will already purge the data after 90 days so this benefit is short-lived.