如何撤消 'git fetch'

How to undo 'git fetch'

我刚刚在我的 repo B 中添加了额外的 remote A,然后 运行 git fetch A。我怎样才能撤消提取?如果我只是删除 remote A: git remote remove A1 它会撤消获取吗?

更新:

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

以上是我 运行 的命令,所以结果我将所有分支都提取到我的 repo B 但是我只需要 repo A 中的一个特定分支,我需要它进入repo B 上的特定文件夹,但那是另一回事 Merge code between two dfferent git repositories

很难1到"undo"一个git fetch,但从来没有2任何理由需要 撤消 git fetch

记住,git fetch 所做的是调用远程,获取分支名称到 SHA-1 映射的列表,带来提交和您需要的其他对象,以便将它们存储在您的存储库中,然后更新您的远程跟踪分支,以便它们指向远程的当前(截至您刚刚打电话时)分支提示。这对您的任何工作树文件都没有影响,如果您明天再次 运行 git fetch,那么明天可以跳过今天完成的任何工作。如果您 设法撤消了 fetch,明天 运行 将不得不重新做今天完成的工作,所以这是一个净损失:您只是花费了一些精力,所以您的 git 明天将不得不通过网络带来更多代码。

也就是说,脚注时间到了。 :-)


1如果您有远程引用日志(您可能有),并不困难:只需使用远程引用日志来查找远程- 跟踪在最近一次获取中更新的分支——同样的信息也可能在 FETCH_HEAD 文件中仍然可用——然后使用 git update-ref 将这些引用指向它们之前的 reflog 条目。但这仍然会将获取的对象留在您的存储库中,因此要真正清除它们,您还必须删除中间的 reflog 条目,然后 运行 git gc --prune=now,这需要非常小心并且会丢弃 所有 未引用的对象,而不仅仅是最近 fetch.

带来的对象

2我想有人会争辩说 "running low on disk space" 可能是这样做的一个原因,特别是如果一个大对象被意外推送到远程并将被删除来自下一个 fetch 的遥控器。不过,在 space 之外的文件系统中工作通常很棘手,而且我不确定除了将整个存储库移动到其他地方(没有磁盘的某个地方 space 个问题)。

您可以撤消 所有 从远程 A 的提取,只需删除此远程即可:

git remote remove A

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

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

我真的很喜欢 torek 的回答,但它没有为您提供 "update reflogs" 的命令,这正是我要找的。我在其他答案 reverse a git fetch 中找到了这个,所以我把它留在这里以简化对其他答案的搜索。


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

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

话虽如此,您可以 "undo" git fetch 通过执行以下操作:

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

这一切所做的就是将 origin/master 指针更改为先前的状态。也许您需要尝试 {n} 才能获得准确的状态,但总的来说它可能会有所帮助。

您可以使用以下命令删除您不小心获取但不想保留的任何分支:

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, etc],例如git remote set-branches origin master.

set-branches 的默认行为是始终替换列表。如果要追加,请使用 --add 选项:git remote set-branches --add origin another_branch

非常简单的解决方案:

git reset --keep HEAD@{1}

或第二个解决方案:

git reset --hard master@{"10 minutes ago"}