如何撤销 'git fetch'

39

我刚刚向我的repo B添加了额外的remote A,然后运行了git fetch A。我如何撤销此操作?如果我只是移除remote Agit remote remove A1,这会撤销fetch吗?

更新:

$ git remote add A path/to/A
$ git fetch A

以上是我运行的命令,结果我将所有分支都获取到了我的repo B,但我只需要从repo A获取一个特定的分支,并将其放入repo B的特定文件夹中,但这是另一回事。详情请参考合并两个不同Git存储库之间的代码


2
你为什么想要撤销这个获取操作? - mipadi
@TheGeorgeous 但在我的情况下,这是自定义远程,我不需要从中汇集所有分支。然而,fetch从repo A带来了所有分支,但我只需要一个单独的分支。因此,fetch带来了我根本不需要的东西,也永远不会需要。 - Sergino
如果您只想删除特定的远程分支,请使用 git branch -r -d 命令。这样做将保留对象的常规保留期(默认为14天)。但是,您可能需要调整配置,以便将来从同一远程获取仅选择所需的特定分支。 - torek
1
@bodovix 我猜有很多种方法可以解决这个问题。在我们的情况下,通过使用带有引用故事编号的提交消息的合并提交,或者甚至从存储在PR工具中的历史记录中,我们总是可以重新创建任何想要的功能分支,而无需保存任何分支。但是,如果您不使用合并提交或具有历史记录的PR工具,则需要另一种方法,并且将分支保留在repo中肯定是一种方法。 - TTT
1
@TTT 嗯,这就是为什么我认为我们要保留我们的东西很长时间,但谁知道呢。可能只是因为一直以来都是这样做的。我可能会进一步询问;)- 但无论如何,grep 对我来说几乎消除了这个问题。 - bodovix
显示剩余7条评论
6个回答

43
您可以通过删除此远程来撤销对远程 A 的所有提取操作:
git remote remove A

现在只需再次添加它,并仅获取单个分支:

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

检查一下这个可能会有帮助 https://dev59.com/K2kw5IYBdhLWcg3wJXQh - Maytham Fahmi

21

撤销1一个 git fetch 是比较困难的,但是通常没有任何理由需要撤销一个 git fetch
记住,git fetch 的作用是调用远程库,获取分支名称与 SHA-1 映射列表,将您需要存储在本地仓库中的提交和其他对象带到本地,然后更新您的远程跟踪分支,使它们指向远程库当前(在您刚刚调用它的时间)的分支提示。 这对你的工作树文件没有任何影响,如果明天再次运行 git fetch,则今天的任何工作都可以被忽略掉。 如果你真的设法撤销了 fetch,那么明天运行的 fetch 将不得不重新执行今天完成的工作,因此这是一种净损失:你刚刚花费了一些努力,以便你的 git 明天必须通过网络带来更多的代码。

话虽如此,现在是注释的时间。 :-)


1如果您有远程引用日志(您可能会有),那么情况并不是太难:只需使用远程引用日志找到最近一次 fetch 更新的远程跟踪分支 - 这些相同的信息可能仍然可用于 FETCH_HEAD 文件中,然后使用 git update-ref 将这些引用指向其先前的 reflog 条目。 但是这仍将使获取的对象保留在您的本地仓库中,因此要真正清除它们,您还必须删除中间的 reflog 条目,然后运行 git gc --prune=now,这需要非常小心,并将丢弃所有未引用的对象,而不仅仅是最近一个 fetch 带来的对象。

2我认为可以有理由这样做是因为“磁盘空间不足”,特别是如果一个大对象被意外地推送到远程并将在下一次fetch之前从远程删除。然而,在一个没有足够空间的文件系统中工作总体上是很棘手的,我不确定除了将整个仓库移动到其他地方(没有磁盘空间问题的地方)外,我是否还想在这里做更多事情。


我有一个非常好的理由来撤销“git fetch”。我已经获取了几个月的Chromium存储库的提交,并希望恢复我的100GB磁盘空间。我使用“git fetch --depth = 100000”进行提取,以便仅获取最近几个月的提交,现在我想删除所有内容,仅获取最后的100个提交左右。 - Jespertheend
@Jespertheend:你可以使用git fetch --depth=100更深入地浅出一些东西,但我不确定git gc是否会清理这里的混乱。但我要注意到100 GB大约是5美元。(我知道,事实并非如此简单。我需要升级自己的系统,我感到同样的痛苦 :-)) - torek
@torek 我最终只是删除了整个代码库并重新获取了它。幸运的是,设置构建流水线并不太复杂。购买额外的硬盘不是问题。我有几个闲置的硬盘可以使用。但是连接外部设备到笔记本电脑并不理想,而且 MacBook 也不容易升级。 - Jespertheend
想要撤销一个 git fetch 的另一个原因是,如果你在实际情况中遇到了 Git 的 bug 并希望重现它 ;) - philb
@philb:如果你已经达到了那个水平(调试Git),那么你应该知道引用和引用规范是如何工作的 :-) - torek
显示剩余5条评论

9

我很喜欢torek的回答,但它没有提供“更新reflogs”的命令,这正是我在寻找的。我在其他回答reverse a git fetch中找到了这个命令,所以我把它留在这里,以便为其他人简化搜索。


假设您有一个origin远程,您的本地develop分支基于master,但您的本地master落后于origin/master但您还没有看到它,因为您还没有获取origin)。

因此,执行git fetch将向您的本地存储库添加来自origin/master和标签的新提交。在某些情况下,您根本不想看到这些新提交,因为它们会降低历史记录的可读性。

说了这么多,您可以通过执行以下操作“撤消”git fetch

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

这只是将origin/master指针更改为先前的状态。也许你需要稍微尝试一下{n}来获取精确的状态,但通常可以帮助解决问题。


在我的情况下,update-ref只是故事的一半。我想要将本地存储库实际还原到fetch之前的状态,以确保下一个'git fetch'会去下载来自远程存储库的文件..我面临的问题是奇怪的错误“error: inflate: data stream error (unknown compression method) fatal: failed to read object”,还有一个警告消息说我的git比远程使用的旧..所以我想证明或证明它只是存储库损坏,或者实际上有新的压缩方法,我的本地git无法处理。 - Igor Stasenko

6

非常简单的解决方案:

git reset --keep HEAD@{1}

或者第二种解决方案:
git reset --hard master@{"10 minutes ago"}

4
您可以使用以下命令删除您不想保留的错误获取的分支: git update-ref -d refs/remotes/YOUR_REMOTE_NAME/BRANCH_NAME_TO_DELETE 为了防止它们再次被获取,请将您的git远程设置为只获取指定的分支:git remote set-branches YOUR_REMOTE_NAME desired_branch1 [desired_branch2, desired_branch3, 等等],例如:git remote set-branches origin master
set-branches 的默认行为是始终替换列表。如果您想要附加,请使用 --add 选项:git remote set-branches --add origin another_branch

这是我个人认为的问题的真正答案。关于是否真的应该这样做的各种争论是有道理的,但并没有回答问题。 - bryant

0
如果我没记错的话,你实际上想要删除从远程仓库获取的分支 A
这个命令用于在本地删除从远程获取的分支:
git branch -r -d <branch-name>

你可以使用git branch -a命令来查看分支的名称,如果它的名称是remotes/origin/A,那么你应该使用git branch -rd origin/A命令来删除它。
如果你想撤销这个操作,可以再次进行fetch操作。
git fetch origin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接