How to undo 'git fetch'

北慕城南 提交于 2019-11-30 11:18:13

You can undo all fetches from remote A simply by removing this remote:

git remote remove A

Now just add it again and fetch only single branch:

git remote add A <path/to/repository>
git fetch A <name of branch>

It is difficult1 to "undo" a git fetch, but there is never2 any reason to need to undo a git fetch.

Remember, what git fetch does is call up the remote, get a list of branch-name to SHA-1 mappings, bring over commits and other objects you need in order to store those in your repository, and then update your remote-tracking branches so that they point to the remote's current (as of the time you just now phoned it up) branch tips. This has no effect on any of your work-tree files, and if you run git fetch again tomorrow, any work done today can be skipped tomorrow. If you do manage to undo the fetch, the one run tomorrow will have to re-do the work done today, so this is a net loss: you just spent some effort so that your git will have to bring more code over the network tomorrow.

That said, time for footnotes. :-)


1It's not that difficult if you have remote reflogs (which you probably do): just use the remote reflogs to find remote-tracking branches updated in the most recent fetch—this same information may also still be available in the FETCH_HEAD file—and then use git update-ref to point those references back to their previous reflog entries. But this will still leave the fetched objects in your repository, so to really clear them out, you must then also delete the intermediate reflog entries, and then run git gc --prune=now, which requires a lot of care and will discard all unreferenced objects, not just ones brought over by the most recent fetch.

2I think one could argue that "running low on disk space" might be a reason to do this, especially if a large object was accidentally pushed to the remote and will be removed from the remote by the next fetch. Working in a file system that is out of space is tricky in general, though, and I'm not sure I would want to do much here other than move the entire repository elsewhere (somewhere without the disk space issues).

I really liked answer from torek, but it doesn't provide you commands to "update reflogs", which is exactly what I was looking for. I found this in other answer reverse a git fetch, so I just leave it here to simplify searching for others.


Let's assume that you have your origin remote and your local develop branch is based on master, but your local master is behind origin/master (but you don't see it yet, because you haven't fetched origin yet).

So performing git fetch will add new commits from origin/master and tags to your local repo. In some cases you don't want to see those new commits at all and they will reduce readability of your history.

Having said that, you can "undo" git fetch by doing:

git update-ref refs/remotes/origin/master refs/remotes/origin/master@{1}

All this does is changes the origin/master pointer to the previous state. Maybe you'll have to play with {n} a bit to get the exact state, but in general it may help.

You can delete whatever branches you accidentally fetched that you don't want to keep with the following command:

git update-ref -d refs/remotes/YOUR_REMOTE_NAME/BRANCH_NAME_TO_DELETE

To prevent them from getting fetched again, set your git remote to only fetch specified branches: git remote set-branches YOUR_REMOTE_NAME desired_branch1 [desired_branch2, desired_branch3, etc], e.g. git remote set-branches origin master.

The default behaviour of set-branches is to always replace the list. If you want to append, use the --add option: git remote set-branches --add origin another_branch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!