首页 > 解决方案 > 是否仅获取本地存储库?

问题描述

有没有办法在仅限本地的存储库中进行提取?例如,如果我想在不进行合并的情况下将功能分支中的更改引入主分支?

换句话说,没有与此存储库连接的远程存储库。它只存在于我的机器上。除了好奇之外,我没有什么特别的原因。

标签: git

解决方案


git fetch有两项主要工作,一项是大(或大)和硬(-ish),另一项是小而容易。最困难的部分是以有效的方式从其他存储库获取实际提交和其他对象(所有这些都由哈希 ID 标记)。小而简单的工作是根据在完成大工作时学到的信息更新一些名称——通常是远程跟踪名称,如。origin/master

由于您的存储库已经包含了您的存储库的所有提交,因此指向git fetch您自己的存储库使大的困难工作变得微不足道,只剩下小而简单的工作。你可以这样做:

git fetch .

指示git fetch用作.URL 或远程名称。Git 将其视为一种file://URL,但没有 , //,因此它将当前目录命名为另一个存储库所在的本地文件。如果存储库位于当前目录中,则将您的 Git 存储库连接到自身。然后它会列出它拥有但没有的任何提交——当然是没有提交——因此没有要更新的提交。

在没有更新任何提交后,它继续进行较小的工作,即更新各种名称。要更新的名称是您通过refspecs提供的名称。通常,您会运行:

git fetch origin

并将remote.origin.fetch提供这些 refspec 参数。由于您没有使用origin,因此必须提供 refspecs。

refspec 的第二种最简单形式拼写为,其中和部分是refs。在这种第二简单的形式中,中间的冒号是必需的。1 源 ref 通常是一个分支名称,如- 或其完整拼写形式,- 而目标通常是一个远程跟踪名称,如.src:dstsrcdstmasterrefs/heads/masterrefs/remotes/origin/master

使用 时git fetch .,使用远程跟踪名称没有意义。不过,使用分支名称确实有意义。在这里,像这样的 refspec实际上是有意义的。master:develop

在这种第二简单的形式中,Git 从源 Git(即您自己)读取与源名称相关联的提交哈希 ID,并对目标 Git(这又是你自己)。如果允许更新,就会发生。如果没有,它不会。

--force即使检查失败,您也可以在 refspec 前面添加标志或前导加号以强制更新。所以这里git fetch . +master:developgit fetch --force . master:develop意思是一样的:从源 Git 读取并使用生成的哈希 ID在目标 Git 中master强制更新。develop这将清除您拥有的任何现有文件,develop并放入develop指向.master

换句话说,这与git branch -f develop master. 后者更明显,因此您应该使用该命令。(不过,对这里发生的事情的完整描述很有用。)

如果没有前导加号 or --force,这git fetch会导致使用更简单的 Git 命令更难表达的东西。Git 内置的唯一其他实现相同结果的东西是git push类似地使用:

git push . master:develop

具有与 完全相同的整体效果git fetch . master:develop。使用git push,您的 Git 会调用自己,自己提供它尚未拥有的任何提交(即没有),并要求自己温和而谨慎地更新,develop以匹配自己的- 与之后执行master的相同温和更新没有提交。git fetch . master:develop

所以,这两个命令都有这个效果。编号的步骤确定是接受还是拒绝温和/礼貌的更新:

  1. 测试分支名称是否develop存在。如果没有,继续:名称更新请求被接受。

  2. 测试是否develop是当前分支。如果是这样,请拒绝请求(但请参阅 的配置设置git push或 的-u标志git fetch)。

  3. 从当前分支设置中获取哈希 ID。测试新提议的提交 ID 是否具有当前提交哈希 ID 作为祖先。即测试本次更新是否为快进操作。如果是,请接受请求。

  4. 请求不是快进:拒绝请求。--force(此测试在或下被跳过/替换为“接受” +。)

如果请求被接受,该命令现在将用新建议的哈希 ID 替换存储在名称中的哈希 ID。因此,要么 要么git push . master:develop具有git fetch . master:develop快进我们的效果develop以匹配我们的master,前提是我们现在不在develop,并且快进是可能的。

要在没有git fetchorgit push的情况下执行此操作,直接的方法是:

git checkout develop
git merge --ff-only master

这实际上是我通常的做法——这种胡闹git push . master:develop实在是太棘手了。(我git push在极少数情况下确实想避免结帐时使用,以避免弄乱我当前的工作树。这些天,您可以使用git worktree add来避免弄乱这个工作树,但这比恶作剧git push .。)


1最简单的形式省略了冒号。当从其他Git获取提交时,此表单在某些情况下有一些用途,git push在您通常其他 Git 提交提交的更多用例中。但是如果你把你的 Git 指向它自己,这些用例永远不会适用,最简单的形式变得毫无用处。因此,这里所有的注意力都集中在第二简单的形式上。


推荐阅读