origin/main 和 origin/HEAD 在我的提交中意味着什么,为什么它们是红色的?

发布于 2025-01-11 14:50:39 字数 517 浏览 1 评论 0原文

我已经开始使用 Git,最近学会了使用它

git log --all --graph

来查看我的提交历史记录,我注意到一些令人担忧的细节。例如,左边的线是红色的,这表明有问题。此外,在提交名称之后有一些我无法解释的文本。我认为 HEAD -> main 表示 HEAD 指向 main。但是还有另外 2 个字符串(也是红色表示有问题),我认为它们是遥控器?

左边的线是否表明有问题,或者我读错了?提交编号旁边的文本是什么意思?这三个部分分别代表什么意思呢?有什么问题吗?如果有,我该如何修复?

这是我日志中的最上面一行。 origin/mainorigin/HEAD 是什么意思?为什么它们是红色的?

* commit 9bee2dac5bb71b843022409d33a46af52be217d4 (HEAD -> main, origin/main, origin/HEAD)

I've started using Git, and I've recently learned to use

git log --all --graph

to look at my commit history, and I noticed some details that I find worrying. For example, the line to the left is red, which indicates to me that something is wrong. Moreover just after the name of the commit there is some text which I have trouble interpreting. I think that HEAD -> main means that the HEAD is pointing to main. But then there are 2 more strings (also in red indicating something is wrong) which I think are remotes?

Is the line to the left indicating something is wrong, or am I reading it wrong? What does the text next to the commit number mean? What do the three parts mean? Is there something wrong, and if so how can I fix it?

This is the topmost line in my log. What does origin/main and origin/HEAD mean and why are they red?

* commit 9bee2dac5bb71b843022409d33a46af52be217d4 (HEAD -> main, origin/main, origin/HEAD)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱娆 2025-01-18 14:50:39

Git 实际上就是关于提交。提交具有哈希 ID:

<前><代码>* 提交 9bee2dac5bb71b843022409d33a46af52be217d4 (...)

那个 9bee...7d4 东西是您在 main 分支上最新提交的哈希 ID。随着您和其他人添加新的提交, 最新的提交会随着时间的推移而发生变化,但目前,9bee2da... 是最新的。

如果 Git 没有更简单的方法来命名提交,那么所有使用 Git 的人都会发疯。 (有人说 Git 无论如何都会这样做。)想象一下必须记住这些又大又难看的随机数 -寻找东西只是为了得到你的承诺!但您不必这样做:Git 会将每个分支的最新提交的哈希 ID 保存在分支名称中。

那么,存储库主要由两个数据库组成:一个(通常是最大的)保存提交并支持内部 Git 对象。这些都有哈希 ID;您将处理提交的哈希 ID。为了帮助您和 Git 本身找到提交和其他哈希 ID,存储库还存储了一堆名称:分支名称、标签名称、refs/ stash 代表 git stash,等等。这个大名称表中的每个名称都存储一个哈希 ID,这是存储库中的另一个数据库:一组。对。其中一些名称是分支名称,这些名称是存储库中的分支。

(对象数据库中的对象是完全只读的:一旦提交,您就永远无法更改它名称中的名称数据库存储哈希 ID,但存储的哈希 ID 可以随时替换,甚至可以删除和/或创建新名称,因此名称会随着时间的推移而变化,以选择最新。 em> 提交。我们将跳过所有其余的细节。 不过,

Git 不仅仅是一个版本控制系统 (VCS):它是一个分布式 VCS。 Git 通过让我们复制存储库来实现这种分发技巧。我们使用 git clone 来做到这一点。当我们克隆其他人的 Git 存储库时,我们会获取他们的所有提交1,并且没有获得他们的任何分支。他们提交的哈希 ID 就是此时我们提交的哈希 ID:任何一个提交的哈希 ID 对于该特定提交都是完全唯一的 em>,以及每个具有 that 提交的 Git 存储库,都使用 that 哈希 ID。该哈希 ID 现在为该提交保留。 (这就是为什么它们又大又丑的原因:这样,总有一个新的 ID 可用于的所有新提交。)

记住它们的分支名称,我们的 Git 在我们的克隆中创建或更新我们自己的远程跟踪名称。我们的 Git 软件会记住我们用于制作克隆的 URL,使用更短的(比 URL)名称。这里有一个标准的名字,origin,每个人都使用它,2,因此他们的 Git 存储库的 URL 存储在名称 下起源。然后,Git 使用该相同名称粘贴在每个分支名称前面:它们的main成为我们的origin/main,他们的 develop (如果他们有的话)成为我们的 origin/develop,等等。

因此,您的 origin/* 名称只是反映了您克隆的存储库具有一些分支名称这一事实。他们的分支名称 = 您的远程跟踪名称,因为您的 Git 会看到它们的名称并更改它们,以便让您的存储库记住它们的分支。

因为您和他们共享提交——您的所有提交都来自他们——他们的origin/main会记住提交哈希 ID 9bee2da。 ..。一旦您的 git clone 操作复制了它们的提交并修改了它们的分支名称,您自己的 Git 软件就会在您的存储库中创建一个新分支。您的 Git 此处使用的名称是 main3 因此您的 Git 创建了您自己的 main 来匹配您的 origin/main > 你的 Git 用它来记住它们的 main

这意味着您拥有:

  • 分支名称 main:这是您的(目前)提交 9bee2da... 的名称;
  • 远程跟踪名称origin/main:这是他们分支名称的副本,上次您的Git与他们的Git软件对话和存储库,名为 commit 9bee2da...

因此,当您运行 git log 时,您的 Git:

  1. 使用名称 main 查找 9bee2da...
  2. 使用哈希 ID 9bee2da... 查找提交;
  3. 显示提交9bee2da...
  4. 在括号中添加您看到的装饰:有些是绿色的,有些是红色的。

(实际上,第 1 步之前还有一个步骤:您的 Git 使用 HEAD 来查找 main。但我们暂时不考虑该部分。)


1我们可以获得少于所有提交,但是“复制所有提交”至少是首先考虑这个问题的方法。

2如果您愿意,您可以使用其他东西。如果这样做,您的远程跟踪名称将会有所不同。但其他人都会期望看到起源,因此没有必要做额外的工作来使用不同的名称。

3您在 git clone 时告诉您的 Git,您希望 Git 复制哪个分支名称。例如,要选择他们的 develop,您可以运行 git clone -bdevelopment...。如果您不选择分支名称,您的 Git 会询问他们推荐的 Git 名称,通常是他们的 main 或 master 或其他名称。


绿色和红色,但没有什么问题

例如,左边的线是红色的,这表明有问题。

否:Git 默认只使用八种颜色,即 redgreenblueyellow青色洋红色黑色白色。这就是 20 年前常见的一切。这里允许使用一些额外的单词,如果您的终端支持,现代 Git 可以使用 24 位颜色(请参阅 Git 漂亮格式颜色< /a>)。对于画线部分(参见漂亮的 Git 分支图),Git 以红色开头(并且没有简单的方法来配置这)。

我认为 HEAD -> main 表示 HEAD 指向 main。

这是正确的:特殊名称 HEAD(实际上不是分支名称)通常包含某个分支的名称;当它发生时,我们说名称HEAD附加到,或指向该分支名称。

但是还有 2 个字符串(也是红色表示有问题),我认为它们是遥控器?

这些是我上面提到的远程跟踪名称。 git Branch -a 将显示分支名称(始终是本地的,因此“本地分支”是多余的,就像说“ATM 机”,但有时无论如何感觉都合适)和远程跟踪名称;它默认以绿色打印分支名称,默认以红色打印远程跟踪名称。我不确定这是否是一种助记设备(“红色=远程”),但如果您愿意,您可以将其用作助记设备。 (但是绿色等于什么?“Glocal”听起来太像“global”了。

Git is really all about commits. The commits have hash IDs:

* commit 9bee2dac5bb71b843022409d33a46af52be217d4 (...)

That 9bee...7d4 thing there is the hash ID for your latest commit on your main branch. The commit that is the latest will change over time, as you and others add new commits, but for now, 9bee2da... is the latest.

If Git didn't have easier ways to name commits, this would drive all the humans working with Git insane. (Some say that Git does that anyway.) Imagine having to memorize these big ugly random-looking things just to get your commits! But you don't have to do that: Git will save the hash ID of the latest commit of each of your branches, in a branch name.

Repositories, then, consist primarily of two databases: one—usually the biggest—holds the commits and supporting internal Git objects. These all have hash IDs; the commits' hash IDs are the ones you will deal with. To help you—and Git itself—find the commit and other hash IDs, the repository also stores a bunch of names: branch names, tag names, refs/stash for git stash, and so on. Each name in this big table of names stores one hash ID, and that's the other database in a repository: a set of <name, hash-ID> pairs. Some of these names are branch names, and those are the branches in the repository.

(The objects in the objects database are fully read-only: once you make a commit you can never change it. The names in the names database store hash IDs, but the stored hash IDs can be replaced at any time, or even deleted and/or new names created. So the names change over time, to select the latest commit. We'll skip all the rest of the details here, though they do matter.)

Git isn't just a version control system (VCS) though: it's a distributed VCS. Git does this distribution trick by letting us copy a repository. We use git clone to do that. When we clone someone else's Git repository, we get all their commits1 and none of their branches. The hash IDs of their commits are the hash IDs of our commits at this point: the hash ID of any one commit is totally unique to that particular commit, and every Git repository that has that commit, uses that hash ID for it. That hash ID is now reserved for that commit. (This is why they're so big and ugly: that way, that there's always a fresh new ID available for all of your new commits.)

To remember their branch names, our Git, in our clone, creates or updates our own remote-tracking names. Our Git software remembers the URL we used to make the clone, using a shorter (than a URL) name. There's a standard first name here, origin, which everybody uses,2 so the URL for their Git repository is stored under the name origin. Git then uses that same name to stick in front of each of their branch names: their main becomes our origin/main, their develop (if they have one) becomes our origin/develop, and so on.

So your origin/* names are simply a reflection of the fact that the repository you cloned has some branch names. Their branch names = your remote-tracking names, because your Git sees their names and changes them, to let your repository remember their branches.

Because you and they share the commits—you got all your commits from them—their origin/main remembers commit hash ID 9bee2da.... Once your git clone operation has copied their commits and modified their branch names, your own Git software creates one new branch in your repository. The name your Git used here was main.3 So your Git created your own main to match your origin/main that your Git uses to remember their main.

That means you have:

  • the branch name main: this is your name for (at the moment) commit 9bee2da...;
  • the remote-tracking name origin/main: this is your copy of their branch name that, the last time your Git talked with their Git software and repository, named commit 9bee2da....

So when you run git log, your Git:

  1. uses the name main to find 9bee2da...;
  2. uses the hash ID 9bee2da... to find the commit;
  3. shows the commit 9bee2da...;
  4. adds, in parentheses, the decorations you saw: some in green, some in red.

(There's actually a step before step 1: your Git uses HEAD to find main. But we're leaving that part out for now.)


1We can get less than all commits, but "copy all commits" is the way to think about this at first, at least.

2You can use something else if you want. If you do, your remote-tracking names will be a little different. But everyone else will expect to see origin, so there is no point to doing extra work to use a different name.

3You tell your Git, at git clone time, which of their branch names you want your Git to copy. To select their develop, for instance, you'd run git clone -b develop .... If you don't pick a branch name, your Git asks their Git which name they recommend, and usually that's their main or master or whatever.


Green and red, but nothing wrong

For example, the line to the left is red, which indicates to me that something is wrong.

No: Git just uses eight colors by default, namely red, green, blue, yellow, cyan, magenta, black, and white. This is all that was commonly available 20 years ago. There are some additional words allowed here, and modern Git can use 24-bit color if it's supported by your terminal (see Git pretty format colors). For the line-drawing part (see Pretty Git branch graphs), Git starts with red (and there's no easy way to configure this).

I think that HEAD -> main means that the HEAD is pointing to main.

That's correct: the special name HEAD—which is not actually a branch name—normally holds the name of some branch; when it does, we say that the name HEAD is attached to, or points to that branch name.

But then there are 2 more strings (also in red indicating something is wrong) which I think are remotes?

These are the remote-tracking names I mentioned above. git branch -a will show both branch names (which are always local, so "local branch" is redundant, like saying "ATM machine", but sometimes it feels appropriate anyway) and remote-tracking names; it prints the branch names in green by default, and the remote-tracking names in red by default. I'm not sure if this is meant as a mnemonic device ("red = remote"), but you can use it as one, if you like. (But then what does green equal? "Glocal" sounds way too much like "global". ????)

The second red name is origin/HEAD: this is your Git's copy of the other Git's HEAD, more or less. However, Git doesn't update it, the way it updates remote-tracking names.4 If you think their HEAD may have changed, you can run git remote set-head origin --auto to have your Git call up their Git and find where their HEAD is now. But there's very little use for origin/HEAD in my opinion, so I never bother.


4Every time you run git fetch origin, your Git calls up their Git again, using the URL Git saved under the name origin, and picks up any new commits they have, that you don't, and updates your remote-tracking names based on their branch names. In fact, git clone is really just shorthand for running git init + git remote add origin ... + git fetch origin + a few more steps: it's the git fetch step that creates all your remote-tracking names initially, and gets all their commits initially. Since git fetch defaults to get the commits they have that I don't, and initially you have no commits, it initially gets all their commits. Since it doesn't create or update any branch names—only remote-tracking names—that's why git clone copies all their commits and none of their branches.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文