【问题标题】:How to undo 'git fetch'如何撤消“git fetch”
【发布时间】:2016-06-06 03:17:12
【问题描述】:

我刚刚在我的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.

【问题讨论】:

  • 为什么要撤消提取?
  • 另外,如果有疑问,您可以尝试一下。移除遥控器不会破坏任何东西。
  • @mipadi 只想清理被带到我的仓库的任何东西
  • @bodovix 我想​​有很多方法可以剥那只猫的皮。在我们的例子中,在合并提交与引用故事编号的提交消息之间,甚至从 PR 工具中存储的历史记录中,我们总是可以重新创建我们想要的任何功能分支,而无需保存它们中的任何一个。但是,如果您不使用合并提交或带有历史记录的 PR 工具,那么您将需要另一种方法,并且将分支保留在 repo 中肯定是一种方法。
  • @TTT 好吧,这就是为什么我认为我们会保留我们的产品很长时间,但谁知道呢。可能只是因为这就是它一直以来的做法。我可能会进一步询问;) - 但不管 greps 对我来说,这个问题几乎都无效

标签: git git-remote git-fetch


【解决方案1】:

很难1“撤消”git fetch,但从来没有2任何理由需要撤消 @ 987654323@.

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

也就是说,是时候添加脚注了。 :-)


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

2我认为有人可能会争辩说“磁盘空间不足”可能是这样做的一个原因,特别是如果一个大对象被意外推送到远程并且将从远程删除由下一个fetch。不过,在空间不足的文件系统中工作通常很棘手,我不确定除了将整个存储库移到其他地方(没有磁盘空间问题的地方)之外,我还想在这里做很多事情。

【讨论】:

  • 其他贡献者可能已经提交了导致问题的更改。可以通过重置 HEAD 暂时删除违规提交,但指向“master”的日志指针不会重新出现。这会使重新设置功能分支变得更具挑战性,这也是我过去希望撤消 fetch 的原因。
  • @FelixLechner:这些提交只能通过 remote-tracking 名称(例如 origin/master)或标签名称访问。如果您采取一些措施(例如运行 git mergegit rebase)来更改您自己的分支名称,它们将只能通过您自己的分支名称访问。您自己的分支始终不受git fetch 的影响。当你想要rebase或者merge时,你可以通过commit hash ID而不是分支名来实现。
  • 我有一个非常很好的理由撤消git fetch。我已经获取了几个月的 Chromium 存储库提交,并希望收回我的 100GB 磁盘空间。我已经使用git fetch --depth=100000 获取,以便仅获取最后几个月,现在我想将其全部删除,仅获取最后 100 次左右的提交。
  • @Jespertheend:您可以使用git fetch --depth=100 来进一步解决问题,但我不确定git gc 是否会收拾这里的烂摊子。但我会注意到 100 GB 是about US$5。 (我知道,没那么简单。我需要升级自己的系统,我也有同样的痛苦:-))
  • @torek 我最终只是删除了整个存储库并再次获取它。幸运的是,设置构建管道并不太复杂。购买额外的硬盘驱动器不是问题。我有几个可以使用的硬盘驱动器。但是将外部设备连接到笔记本电脑并不理想,而且 MacBook 也不容易升级。
【解决方案2】:

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

git remote remove A

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

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

【讨论】:

【解决方案3】:

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


假设你有你的origin 远程和你的本地develop 分支基于master,但是你本地的masterorigin/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' 会去下载来自远程存储库的文件..我面临的问题是奇怪的错误“错误:膨胀:数据流错误(未知压缩方法)致命:读取对象失败”,还有一条警告消息,我的 git 比一个用于远程..所以我想证明或反驳它是否只是存储库损坏,或者实际上有新的压缩方法,我的本地 git 无法处理。
【解决方案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, etc],例如git remote set-branches origin master.

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

【讨论】:

    【解决方案5】:

    非常简单的解决方案:

    git reset --keep HEAD@{1}
    

    或第二种解决方案:

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

    【讨论】:

      猜你喜欢
      • 2019-08-23
      • 2015-06-05
      • 2014-11-03
      • 2011-08-14
      • 1970-01-01
      • 2021-11-03
      相关资源
      最近更新 更多