我最近从这个远程存储库克隆。 https://github.com/dave-githubber/my-first-github-repository
就在我克隆它之后,我做到了:
(base) hakan@hakan-VirtualBox:~/CompleteGitGuide/temp/my-first-github-repository$ git show-ref
1fd2ddb6f29becd8d3f3148271e230490d424f85 refs/heads/main
1fd2ddb6f29becd8d3f3148271e230490d424f85 refs/remotes/origin/HEAD
a45b41988603994aac1292ff086ba913567276e2 refs/remotes/origin/feature-1
1a6fd0202b24acb790e52a9a4dba4a26cc94a39a refs/remotes/origin/feature-2
1fd2ddb6f29becd8d3f3148271e230490d424f85 refs/remotes/origin/main
1fd2ddb6f29becd8d3f3148271e230490d424f85 refs/remotes/origin/temp
注意只有一个跟踪主分支:
(base) hakan@hakan-VirtualBox:~/CompleteGitGuide/temp/my-first-github-repository$ git branch -vv
* main 1fd2ddb [origin/main] Create hello-github.txt
但是,当我执行 git remote show origin 时,它说 feature-1、feature-2 和 temp 分支也被跟踪:
(base) hakan@hakan-VirtualBox:~/CompleteGitGuide/temp/my-first-github-repository$ git remote show origin
* remote origin
Fetch URL: https://github.com/dave-githubber/my-first-github-repository.git
Push URL: https://github.com/dave-githubber/my-first-github-repository.git
HEAD branch: main
Remote branches:
feature-1 tracked <<< why?
feature-2 tracked <<< why?
main tracked
temp tracked <<< why?
Local branch configured for 'git pull':
main merges with remote main
Local ref configured for 'git push':
main pushes to main (up to date)
您能解释一下为什么 feature-1
、feature-2
和 temp
分支显示为在本地跟踪吗?
答案 0 :(得分:1)
这只是意味着您的 Git 已经并且正在更新 origin/feature-1
、origin/feature-2
和 origin/temp
。
(这也是 Git 如何严重重载各种术语的另一个例子,例如“远程”、“跟踪”和“分支”。将 未跟踪文件与跟踪分支进行比较< /em> 和 git branch --set-upstream-to
选项。在糟糕的过去,我们不会说 master
有 origin/master
作为其上游,而是说 master
“跟踪” origin/master
。同时,origin/master
是远程跟踪名称,或远程跟踪分支名称...与跟踪文件和未跟踪文件无关。)
git remote
命令是一个奇怪的命令。要了解原因,让我们先看看其他一些命令。
大多数 Git 命令纯粹在本地运行。最大的两个例外是 git fetch
,它从某个 other Git 存储库获取(部分或全部)提交,以及 git push
,它发送(部分或全部)提交到其他一些 Git 存储库。第三个例外 git ls-remote
包括运行 git fetch
的第一部分——调用另一个 Git 存储库——然后只打印出 git fetch
将从 获得的信息< /em> 那个存储库,例如显示他们的分支和标签名称。
git pull
命令只是先运行 git fetch
,然后使用第二个在本地运行的 Git 命令——通常是 git merge
,但你可以将其配置为使用 git rebase
—— 合并 git fetch
刚刚获取的提交。因此,虽然 pull
确实会联系其他一些 Git,但这样做只是因为它以 fetch
开头。
这三个肯定会联系其他 Git 的命令通常使用 remote 来实现,这是一个像 origin
这样的短名称。这个短名称用作键值对中键的一部分,以便您的 Git 可以获取正确的 URL 以调用其他 Git。
很容易将所有其他 Git 命令视为仅在本地运行。但是对于 git remote
命令,这只是对了一半:
git remote add
、git remote remove
和 git remote set-url
都是纯本地操作。请注意,这些添加或删除了远程(如 origin
),或 - set-url
- 更改存储的 URL。
git remote update
主要是拼写 git fetch
的有趣方式; git remote prune
是一种拼写 git fetch --prune
的有趣方式;并且 git remote set-head
可以(但并不总是)调用与 git ls-remote
相同的代码:当使用 git remote set-head --auto
时,您的 Git 必须弄清楚他们的 Git 有作为他们的 HEAD
,这意味着调用他们的 Git 并询问他们。
git remote show
如果您不使用 -n
选项,则联系遥控器。像其他人一样,它使用 git ls-remote
或 git remote set-head
在这里使用的相同代码来询问其他 Git 其各种分支名称。使用 -n
,它不会那样做,只会查看您的(本地)远程跟踪名称。
其中一些东西早于遥控器的发明。在 Git 有遥控器之前,比如 origin
,你每次都必须输入完整的 URL。这太可怕了。1所以人们尝试了几种方法来解决这个问题。其中只有一个工作得非常好,但今天的 Git 仍然支持其他几个;您会在 git fetch
和 git push
文档中看到这些内容。
当远程的概念被发明时——像 origin
这样的短名称可以包含 URL——Git 发展了远程跟踪名称的概念.2 这些让你的 Git 记住 他们的 Git 的 main
、develop
、feature-1
等等在。我们使用它们的方式简单而干净:我们的 Git 从它们的 origin/main
创建或更新我们的 main
,因为我们运行了 git fetch origin
。如果我们的 Git 看到他们当时拥有 feature-1
,我们的 Git 也会创建或更新我们的 origin/feature-1
。这里的精确细节随着时间的推移而改变,3 但在现代 Git 中,我们有这些远程跟踪名称。我们只需运行 git fetch
即可更新它们。4
但是,您可以选择不让您自己的 Git 存储库跟踪他们的所有 (origin
) 分支。如果你愿意,你可以建立一个所谓的单分支克隆。在这里,您在 origin
上选择一些您希望 Git 复制到 origin/whatever
的分支:
您可以使用 git clone
选项在 --single-branch
时间执行此操作。
或者,您可以使用 git remote add
选项在 -t
时间执行此操作。
您可以使用 git remote set-branches
将您拥有 Git 副本的分支更新为远程跟踪名称。这样,您可以将事情设置为“跟踪”(例如,为其创建远程跟踪名称)两个 分支,而不仅仅是一个。
git remote show
命令将读取它们的分支名称(没有 -n
:git remote show
在内部运行 git ls-remote
)或猜测它们的分支名称 (-n
) , 并且会告诉你他们的哪个分支名称你正在将你的 Git 副本复制到远程跟踪名称。这就是说 tracked
时的意思。
1要了解原因,请尝试每次都输入完整的 URL。它会变得很累,而且错别字的机会很大。
2Git 文档称这些远程跟踪分支名称。我发现这里的branch 这个词只是把它弄乱了。例如,它们不是您存储库中的分支名称,因为 git switch
不会切换到它们;你必须使用 git switch --detach
并且你最终会得到一个分离的 HEAD。这一切都很好,但表明该名称不是 branch 名称,因此也不要将其 称为。
3在 Git 1.8.4 版之前,某些类型的 git fetch
根本不需要更新任何远程跟踪名称。一些 Linux 发行版仍然附带这些古老版本的 Git。使用 git --version
找出您拥有的版本。
4这些远程跟踪名称有一个问题。假设 origin
有一个临时分支名称,如 temp
。您运行 git fetch origin
(或仅运行 git fetch
,它从 origin
获取)并在您的存储库中获得 origin/temp
。
然后——一分钟后,或下周,或其他——控制origin
删除他们的temp
分支的人。你再次运行git fetch
;您的 Git 调用 origin
并找到 main
分支,但没有找到 temp
分支。因此,您的 Git 会更新您的 origin/main
...但对您的 origin/temp
没有任何作用。他们没有,所以没有必要更新你的。
这会让您陈旧 origin/temp
。这只是剩下的垃圾。您可以手动删除它,也可以运行 git fetch --prune origin
或 git remote prune origin
。你的 Git 会调用他们的 Git,查看他们的分支名称,看到他们没有有一个 temp
,看到你确实有一个 {{ 1}},并清除剩余的垃圾。
或者,您可以在配置中将 origin/temp
设置为 fetch.prune
。我在我的每用户全局中这样做:
true
这使得每个 git config --global fetch.prune true
都像 git fetch
一样,自动清除死木远程跟踪名称。
这可能应该是 Git 的默认设置,但 Git 仍然主要与 Git 1.7 版兼容,而 Git 1.7 版没有做到这一点,所以现代 Git 仍然没有。