git - 为什么 Git 使用类似 "origin foo"、 "remotes/origin/foo"和 "origin/foo"等易混淆的名称?

标签 git git-fork

我被要求使用 Fork Workflow,即我必须处理具有相同或相似名称的多个分支。我为什么要使用这些不同的变体?

以下是不同命名约定的一些示例:

  • 我的分支机构
  • 起源我的分支
  • 起源/我的分支机构
  • 远程/来源/mybranch
  • 上游 mybranch
  • 上游/mybranch

最佳答案

小心地背诵一系列记住的 Git 命令。 Git 有一个 simple but powerful object model .了解 git 命令在对象模型方面的工作方式,以及您想要执行的操作如何适合命令执行的操作。根据我的经验,运行内存的命令有时会导致多次重复调用相同的序列,这可能会以奇怪的方式混淆历史。疑惑的队友上门求助后,我坐下来,看看现在的状态,挠了挠头,问“你怎么会变成这个状态的?”

跟踪分支的命名方案(例如origin/mybranchremotes/origin/mybranch — 甚至refs/remotes/origin/mybranchupstream/mybranch 也是如此)泄露了分支命名空间的实现细节,即。refs , remotes,origin是解压存储时的物理目录。查看 git pack-refs documentation或在 .git/refs 下面的目录层次结构中探索.

为了方便用户,Git 接受分支的缩写名称,类似于用户无需输入完整的 40 个字符的 SHA1 对象名称。 git rev-parse documentation解释。

<refname>, e.g. master, heads/master, refs/heads/master
A symbolic ref name. E.g. master typically means the commit object referenced by refs/heads/master. If you happen to have both heads/master and tags/master, you can explicitly say heads/master to tell Git which one you mean. When ambiguous, a <refname> is disambiguated by taking the first match in the following rules:

  1. If $GIT_DIR/<refname> exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD);

  2. otherwise, refs/<refname> if it exists;

  3. otherwise, refs/tags/<refname> if it exists;

  4. otherwise, refs/heads/<refname> if it exists;

  5. otherwise, refs/remotes/<refname> if it exists;

  6. otherwise, refs/remotes/<refname>/HEAD if it exists.

Git 文档引用 refs/remotes/origin/foo作为符号全名完整引用名,它们对于通过名称指定精确引用很有用,不会产生歧义——例如在自动化程序中。

请注意 mybranch指的是您的本地 mybranch ,而不是它的跟踪分支(或远程跟踪分支)origin/mybranchupstream/mybranch .跟踪分支随着每次获取或 pull 而更新。把它们想象成你历史上的书签,或者你上次 pull 时 Remote 所在的路径上的路标。有可能——而且经常发生——mybranchorigin/mybranch引用不同的提交。

对比origin mybranch从不提及 origin/mybranchmybranch . Git 没有“/运算符(operator)。”这种想法使这两个独立的论点脱离了上下文。请记住,Git 是一套命令行工具,命令行工具接受参数作为位置参数,而 Unix 命令 shell 用空格分隔参数。在上下文中,命令

git push origin master

有一般形式

git push <remote> <branch>

也就是说,其中一个参数命名为远程,另一个命名为(通常是本地)分支。所以在英语中,它的意思是“在我的 <branch> 上推送提交” (在本例中名为 master)到远程(在本例中名为 origin)。”

关于git - 为什么 Git 使用类似 "origin foo"、 "remotes/origin/foo"和 "origin/foo"等易混淆的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57312560/

相关文章:

reactjs - gh-pages 脚本无法将 .nojekyll 提交到 GitHub

git - 避免忽略 git 中的文件夹

git - 查看对 Mercurial 中的特定文件进行更改的所有修订号

git - 如何找到已删除项目的 Github 分支?

git - 在裸存储库下 checkout 单个文件

git - 如何确保所有内容都已使用 git 推送?

git - 使用 git 删除不在本地存储库中的分支

Git - 如何删除上游存储库中的文件,但不删除我的分支中的文件

git - 用自己的 fork 交换 git 子模块

git - 如何将一个 Gitlab 项目复制到另一个 Gitlab 仓库?