Git分支详细信息 Git确实保留了一些日志 refs/heads/master实际上在这里很奇怪

请问我如何确定Git分支的以下详细信息

  • 谁创建了分支
  • 创建分支时
  • 已创建新分支的分支
zbrabbit 回答:Git分支详细信息 Git确实保留了一些日志 refs/heads/master实际上在这里很奇怪

您对分支机构的想法过于信任。 Git不在乎分支; Git不在乎 commits 。但是为了这样说,我们必须首先停止并定义单词 branch 。在本段中,“分支”的意思是分支名称,例如masterdevelopfeature/tall。对于Git,这些名称仅具有一个功能:记录提交的原始哈希ID。

Git还有其他实体,人们可以并且确实将其称为“分支”。参见What exactly do we mean by "branch"?

无论如何,Git中的分支 name 会保存一次提交的哈希ID。这实际上非常有用:对于我们的人(对于他们来说,Git哈希ID看起来像是随机垃圾)以及对Git本身而言。但这就是他们自己拥有的所有。重要信息都存储在其他位置,大部分存储在提交本身中。

Git 真的在乎提交。提交存储着您要查找的大多数数据:谁来创建它们,何时创建以及从哪个其他早期提交中获得。

分支名称不存储您要查找的任何数据。他们没有创作者信息。他们也没有自己的历史(但是我们稍后会看到更多)。有一个重要原因。

与ClearCase不同,Git是分布式版本控制系统。在ClearCase中,有一个中央的托管存储位置:卷对象库或VOB。各个用户进入中央存储并从中获取内容,然后将其放回其中。为此,这些用户必须都共享VOB的名称。因此,如果VOB想要命名为Bruce,那么其他人也都可以将其命名为Bruce。

使用Git,每个存储库都是独立的。每个人都有自己的分支名称,而与其他人的分支名称无关。 Git中的 only 真正通用名称是哈希ID。 每个人都同意哈希ID:在每个 Git存储库中,哈希ID为08da6496b61341ec45eac36afcc8f94242763468的提交是08da6496b61341ec45eac36afcc8f94242763468。其他提交都不能具有ID 08da6496b61341ec45eac36afcc8f94242763468

如果您和我计划将我们的存储库连接在一起,我们可能会想要不时地协调我们的分支名称,而我们可以做到这一点。但是我的存储库有 my 分支名称,而您的拥有您的分支名称。 是分支名称的 all 的创建者。我实际上不能您的存储库中创建分支名称。我所能做的就是通过一个大的丑陋的哈希ID向您提交一个提交,然后询问您的Git创建或更新一些名称。 1

以另一种方式进行设置比较普遍:我授予您只读访问我的存储库的权限。您运行git fetch以使您的Git通过Internet调用我的Git。您的Git问我的Git:嘿,其他Git,您有哪些分支名称?这些分支名称附带哪些通用共享的哈希ID? My Git为您提供了名称和哈希ID列表,您的Git从那里开始工作:

  • Torek的Git说他的mastera123456...。我有a123456...,所以我很好。
  • Torek的Git说他的devb789abc...。嗯,我没有b789abc...。也许我应该通过其哈希ID来请求该提交。

此过程一直持续到您的Git在此通信阶段掌握Git交出的所有信息为止。然后,您的Git通过哈希ID询问它想要的任何提交。如果该提交的 parent 提交(存储在实际提交中的另一个哈希ID)表示您的Git没有的提交,则您的Git可以要求 哈希ID,等等。

最终,您的Git返回到您的Git已经具有的某个哈希ID –在这种情况下,您的Git具有提交并且根本不需要它–或我用尽了提交并说“这就是全部“。 2 然后,您的Git在您的Git存储库中创建我已提交的每个提交。

您的Git在此过程中要做的最后一件事是创建或更新您的远程跟踪名称。在这里,您的Git 更改了我的所有名称,而不再使用您的分支名称(这是您的,而不是我的!),而是以一种简单易用的方式进行更改。您的Git使用我的Git的昵称,而不是URL。您的Git昵称可能是origin-尽管您可以并且实际上必须为要调用的其他每个Git设置一个不同。名称origin只是您用来进行初始克隆的Git的默认名称。

因此,假设您的Git叫我的Git origin。您的Git包含所有 my 分支及其对应的(单个)哈希ID的完整列表。因此,您的Git现在会创建或更新一个origin/*名称,该名称与我的Git名称相对应。我的Git告诉您的Git {em>我的 mastera123456...,因此您的Git创建或更新了origin/master以指向提交a123456...。您或者已经有了该提交,因此我的不必将其发送给您,或者没有,而是我要求Git发送它。我的Git告诉您的Git, my devb789abc...;您的Git现在有此提交;您的Git会创建或更新您的origin/dev,使其指向b789abc...

同样,重要的是 commits 。提交和哈希ID是Git的通用货币。别人的分支名称...好吧,那是别人要担心的。我们将其复制下来,并保存为远程跟踪名称,但它们不是分支名称。我的分支名称是我的;您的分支机构名称是您的。无论有人使用什么Git,他们的分支名称都是他们的 ,而不是其他人的。


1 对于您来说,记录更新请求是我本人可能是个好主意,但是Git本身并不愿意这样做。 Git本身没有任何形式的认证或授权。 Git依靠其他实体来执行任何所需的身份验证和/或授权。由于其他人正在这样做(如果确实正在做),Git也会将此类信息的任何记录留给另一个实体。

2 从技术上讲,我的Git只是移交了具有 no 父级(即,是 root提交)的提交。由于它没有父母,所以没有较早的提交要求。


Git确实保留了一些日志

考虑到以上几点(您的分支名称是 yours you 创建并更新它们的事实),我们应该提到Git实际上会保留您各种日志 refs 。这些日志也属于您,可以根据需要进行处理。但是,每次您的Git更新参考时,它会将参考的上一个值保存在“参考日志”中。

Git中的

A ref (或参考)是分支名称(如master),标签名称(如v2.1),远程跟踪名称(如origin/master),依此类推。每种名称仍然只存储一个哈希ID,但是名称的“种类”决定了您将如何使用它。

分支名称只是一个引用,其全名以refs/heads/开头。因此,您的master实际上只是名为refs/heads/master的引用。标记名称是ref,其全名以refs/tags/开头,因此v2.1refs/tags/v2.1的缩写。远程跟踪名称以refs/remotes/开头,并继续包含远程名称origin和另一个斜杠,因此origin的{​​{1 }}是master

每当您的Git更新任何这些名称时,它都会在该名称的引用日志中保留 old 值。它将 new 值放入该名称,并将当前日期和时间与旧值一起放入reflog。

这意味着,如果您想知道自己的refs/remotes/origin/master昨天有什么哈希ID,可以通过reflog为您的master来查找Git。如果它是今天早些时候更新的,则此reflog中将有一个条目,这表明昨天它具有其昨天实际拥有的任何哈希ID。

这些reflog条目最终 expire 并被扔掉。这与 commits 完全不同,后者大多数情况下都是永久存在的。 3 同样重要的是要记住,您的引用日志是您的。你看不到我的。

在Git中,拼写为master的引用非常特殊(大写),通常存储分支的名称而不是原始哈希ID。它可以 存储原始哈希ID;在这种模式下,Git表示您有一个“分离的HEAD”。但大多数情况下,它会记住您所在的分支的名称-例如,如果HEADgit status,则意味着on branch master在内部拥有名称HEAD它。 HEAD有一个reflog,其中存储了通过名称跟随基础提交哈希找到的原始哈希ID。


3 从技术上讲,只要您可以找到,提交就可以存在。这使得可达性的概念极为重要。有关可达性的更多信息,请参见Think Like (a) Git


refs/heads/master实际上在这里很奇怪

我上面描述的提交流程是针对git push的。请注意,git fetch表示先运行git pull,然后再运行第二个Git命令。第二个Git命令仅在您的存储库中运行:您的git fetch获得对其他Git存储库的只读访问权限,从中获取提交(和其他数据),然后更新您的远程-跟踪名称。 second 命令是将新提交合并到分支中的命令。我喜欢延迟第二条命令-我通常想先查看fetch实际获取的内容,然后再决定是否进行新提交,因此我很少使用{{1 }}。

与此同时,与fetch相反的最接近的事物是git fetch。这使您的Git再次调用另一个Git(通常使用您自己的名字):git pull表示您希望Git通过您的Git以您的名字git push存储的URL调用Git。这样,您的Git便不会从源Git获取 的提交。相反,您的Git 发送向其提交(和其他对象)。

您的Git会说:我已经为您提交了git push origin,您有吗?如果没有,您的Git将把它发送过来。如果origin具有父项9876543...,则您的Git确保其Git也具有9876543...,依此类推。最终,您的Git到达了他们的Git已经拥有的提交,而不必发送它,或者到达了根提交(一个没有父提交的根提交),因此不再有要发送的提交。

现在,您的Git已将您拥有,不需要,需要的所有提交发送给他们的Git,您的Git向其Git发送了一个礼貌的请求:请,如果可以,请设置您的a123456...a123456...由他们的Git决定接受还是拒绝此请求。基本的Git与GitHub,Bitbucket和Gitlab等人提供的更高级的待售版本相对,在这里的规则非常简单(尽管您可以编写自己喜欢的规则)。虚拟主机提供商还提供用户身份验证和日志记录等功能,如果您是管理员,则由他们来提供更好的控制权。 Basic Git的内置检查仅是:如果我服从此请求,我是否仍然能够找到已经具有名称的分支提示提交?

该测试-如果我接受这个新的提交哈希ID ,我将能够找到当前的提交 –是一项测试,用于查看操作是否是快进。这又是关于reachability的所有内容:从master开始,一直反向移动到父哈希ID,我现在可以使用名称中的哈希ID吗?如果名称是 new ,则基本的Git仅接受请求,而礼貌的请求是删除名称,则基本的Git仅接受请求。

您可以将此有礼貌的请求修改为强制命令:将您的9876543...设置为9876543...他们仍然可以拒绝该请求,但是再次,基本的Git将遵循该命令。 “这是一个快进”测试就消失了。

更新标签和其他名称的规则更简单(但直到Git 1.8.2才被打散):标签名称根本无法在没有master的情况下进行更新,而大多数其他名称使用分支-名称规则(“快进”)。

任何人使用9876543...时,所有真实的身份验证,授权和日志记录都应在接收端进行。 Basic Git假设其他实体正在执行这些操作:如果您已经克服了传输(--forcegit push或其他任何一种)提供的任何机制,那么一切都很好!如果您使用的是托管服务提供商,则由他们决定提供

本文链接:https://www.f2er.com/3138589.html

大家都在问