Reputation: 893
I was working on a branch which was in the following state
A'--B'--C'--D'
/
A--B--C--D
some very bad things happened and I have to go back to B' both locally and remote so that the remote repository is the following
A'--B'
/
A--B--C--D
For the local repository I did
git reset --hard <sha>
but how can I do that for the remote repository?
I should be able to do something like
git push origin mybranch --reset
but it's not in the man page
I tried creating a commit which would cancel the previous ones but
git add .
reports that there are no changes (expected since I'm exactly after the previous push)
So how can I reset the remote repository?
Upvotes: 3
Views: 929
Reputation: 41383
To override a tracked remote branch with yours, do git push origin --force mybranch
. (Or use -f
instead of --force
, or prefix the branch name with +
: git push origin +mybranch
.)
Note that you should warn any collaborators that may have changed your branch that it has been changed remotely, so they will not override it back. Because git push
on their copies will do fast-forward for remote branch — unless you made at least one new commit to it, and git pull
will not update their local version of a branch. Collaborators should do:
git fetch origin
git checkout mybranch
git rebase origin/mybranch
Updated for completeness: As @CodeGnome suggests, to completely remove commits from existence, run git prune --expire now
on all Git repos that contained them. Be warned though, that this command will remove all dangling objects from Git, and will prevent recovery of any data that you 'lost' before you run it. It is usually OK, but you need to be warned anyway.
Update: as this page suggests, git prune --expire now
will not clean commit from reflogs. See the link for the solution. For a less-invasive solution, try git reflog expire --all mybranch
. You have to do this before you run git prune
.
Sometimes it is more preferable to explicitly generate an "undo" commit that removes the changes (so old version and the fact of its removal are visible in history). There is a git revert
command for it.
Upvotes: 4
Reputation: 84343
All you really need to do is be on the B' branch, and then go git push --force
to overwrite the current commit pointer for that branch. If you don't have your remotes set up as tracking branches, you may need to do git push --force origin <branchname>
instead.
C' and D' will remain in the reflog and as objects in the repository until they are eventually pruned, but shouldn't show up as part of any log history unless you start digging into the plumbing.
If you want C' and D' out of the repository altogether, you can call git prune --expire now
in both repositories. That should remove the dangling objects altogether.
Upvotes: 3