又是黎明,又是另一天,试图学习令人震惊的违反直觉,受术语困扰的Git。在本地开发服务器上运行命令git log
时,得到以下输出:
$ git log
commit 07cfffea573a70a59b2be7a6ff8d7dee3e831e (HEAD -> master, live/master)
Author: My Name <example@hotmail.com>
Date: Mon Jul 6 17:02:16 2020 +0000
manual changes to functions.php permissions
commit 3f507d8211be744b1c5a997c81d13b77d968be (central/master)
Author: My Name <example@hotmail.com>
Date: Thu Mar 12 00:14:22 2020 +0000
Contact Form 7 update
commit 41c64ed4fbde1924557e7886901ab8078d088a
Author: My Name <example@hotmail.com>
Date: Wed Mar 11 19:11:53 2020 +0000
Added PHP error log for Contact Form 7
简单来说,那里的那些遥控器到底意味着什么?我发现的任何问题似乎都无法回答,man git log
一看就知道它不是为Git初学者编写的。
对我来说,输出似乎表明这些远程控制器当前卡在了它们各自出现的提交上,但是我知道情况并非如此,因为我已经从{{1 }}直接转到live
(并在Github上确认已进行了更改),但是central
仍显示在旧提交的旁边。
这里的遥控器到底是什么意思?
答案 0 :(得分:1)
TL; DR:您的评论问题的答案:
这是否意味着即使两个遥控器的内容相同(由于将一个遥控器的更改推向另一个遥控器),我也必须从两个遥控器中获取/拉取以保持本地存储库为最新状态?
是“是的,您必须对每个远程计算机运行git fetch
”。您可能想定义一个遥控器的组和/或运行git remote update
,它对所有遥控器都运行git fetch
。或者,git fetch --all
也从所有远程更新。 (组中的内容可为您提供更大的控制权;您可以使用git remote update group
更新特定的远程组。)
要理解这些内容,您需要意识到:
一个Git存储库将提交(和其他Git对象)存储在一个数据库(通常是大型数据库)中,并在第二个数据库中存储了一组名称,例如分支名称,标记名称和远程跟踪名称。通常要小得多)。
提交使用其哈希ID唯一编号,但是具有相同提交的所有Git(即所有Git存储库)对于这两个Git中100%相同的所有提交始终使用相同的哈希ID。
分支名称(但没有任何其他名称)具有特殊的属性:根据定义,它们始终包含该分支的一部分 last 提交的原始哈希ID。 / p>
要使上述所有工作正常进行,当您“进入”分支然后提交 new 提交时,Git会自动将分支名称中存储的哈希ID替换为哈希新创建的提交的ID(其哈希ID以前从未出现在您自己的Git存储库中,也不会出现在任何 other Git存储库中,而是以后将获得的每个Git表示同意的是那个提交的 the 哈希ID)。
通常-有一些例外,但我们暂时将它们放在一旁-我们只会将 add 新提交提交到存储库。这样可以更轻松地考虑各种情况,因此非常有用。
然后,在其中添加:
每个Git存储库通常独立于任何其他Git存储库。
不过,有时您会将一个Git连接到另一个Git。当您这样做时,一个Git会将其部分或全部名称显示给另一个Git。这些是fetch
和push
操作。一个Git会向另一个Git提供一些提交,这两个提交之一还没有完成:
对于git fetch
,另一个Git列出了它的名称和哈希ID,而您的Git 得到表示它还没有但想要/需要。
对于git push
,您的Git列出了哈希ID,而另一个Git则在需要时使用它们。然后,您的Git礼貌地(定期推送)或命令(强制推动)另一个Git,以将某些 名称设置为某些哈希ID。通常,这些是分支名称:对于分支master
或分支develop
或其他名称,我们有一个新的提交,或者可能是 n 个新提交,所以我们将它们发送过来,然后询问他们可以更新他们的 master
或develop
或其他任何东西。
远程跟踪名称(例如origin/master
,central/master
,live/master
等)是您对Git的记忆。一些 other Git的 branch 名称。只有当您的Git与他们的Git联系时,才能更新这些记忆。由于内部原因,当您git push
时,您的Git仅更新git push
的特定名称;但是git fetch
默认会更新所有内容,除非您告诉它应该更新的一组特定名称。
如果您仅接触过一个其他Git,并且除您的命令外,他们从未更新过其名称,则您的Git始终具有正确的信息。例如,这是针对您自己的个人存储库的私有GitHub存储库的常见情况:没有其他人添加。它只会从您获得 new 提交。因此,您的git fetch
从未真正要做任何工作:它们的分支名称始终是您的早期git push
的结果。
但是,如果其他人可以更新其他Git(或Git,复数形式),则您需要运行git fetch
与其他Git联系,并找出已在其Git中添加了哪些新提交。自上次与您的特定Git进行联系以来的分支。您的git fetch remote
将从其他Git获取具有新的提交及其唯一但通用的哈希ID的哈希ID,然后根据需要更新您的remote/branchname
远程跟踪分支。
如果您有遥控器alice
和barney
并运行git fetch alice
,则将获得所有新提交,然后更新所有alice/*
名称。随后的git fetch barney
可能实际上并没有获得任何新的提交(例如您可能已经从alice
获得了它们),但是随后将更新您所有的barney/*
名称。
请注意,您可以使用git branch -f
或git reset
从分支中删除提交。也就是说,给定类似以下内容:
... <-F <-G <-H <-- master
其中名称master
标识哈希为H
的提交,而提交H
导致返回到G
,依此类推,我们可以git checkout master; git reset --hard HEAD~1
推开H
:
H [abandoned]
/
... <-F <-G <-- master
提交H
会在此存储库中保留至少一小段时间-多长时间,取决于我们不会在此处讨论的许多其他因素-但是现在master
标识提交{{1} }而不是提交G
。
如果此 Git存储库位于其他人的远程位置(例如,如果我们目前H
,并且您已经从alice
获得了H
这样您的alice
名称会提交alice/master
,然后在您运行时:
H
您会看到您的git fetch alice
已强制更新。这告诉您爱丽丝做了一些摆脱提交的事情。在您的存储库中,您仍有一段时间会提交alice/master
。您可能会或可能无法以某种方式轻松找到它;但是您的H
也被 撤消了一次提交,也可以确定提交alice/master
。
Git中的标签名称 应该永远不会移动。这是我们对并非总是服从的人类的约束。 Git何时以及是否更新Git记住的标签名称有些棘手。标签与分支在两个方面有所不同:首先,它们不应该移动,与分支名称不同。其次,您的Git通常只会将其他一些Git的标签名称复制到您的Git中,而无需询问,也不需要这种精美的远程跟踪内容。没有G
,只有标签alice/v1.2
。
如果标签从未被删除且从未移动过,则您将不必担心其中的任何一个:您要么拥有一个标签,它是正确的,要么就没有标签,您可以从中获取它。任何其他Git。
答案 1 :(得分:0)
简单来说,那些遥控器到底代表什么?
git log
输出中的提交旁边的注释始终与您的本地“引用”(即分支或标签)相对应。在这里,live/master
和central/master
是远程跟踪分支;您可以使用git branch --remote
(或简称为-r
)列出这些信息。
远程跟踪分支是本地引用,在您执行以下操作时会更新它们:
git push central master
应该将当前已签出的分支上的新更改推送到master
远程服务器上的central
分支上,并且更新refs/remotes/central/master
指向当前分支的头git fetch central master
将在master
远程上获取central
分支并更新refs/remotes/central/master
。类似地,git fetch central
将获取central
遥控器上的所有分支。而且由于git pull
在引擎盖下做了git fetch
,因此在拉动时也会更新远程跟踪分支。关于Git手册页:确实,对于初学者来说有些内容不容易阅读。我建议您从以下资源开始:
官方文档中的某些页面: