答案 0 :(得分:1)
您可能不是最新的或错误的分支。 直接尝试sha1
git log 8d69
git fetch --all
答案 1 :(得分:1)
运行git log
时,告诉它以哪个提交开始。如果您不告知,它将假定来自当前分支的当前提交。它从该起点查找它 可以找到的其余提交。您已经在存储库中提交了8d6995e4
,但是不在当前分支中。
您可以使用git log --all
来告诉它从记录的所有起始点(分支名称,标签名称,远程跟踪名称等等)开始,并且可能想要Get Help From A Dog或作为OznOg suggested使用视觉查看器。另请参见Pretty git branch graphs。
要了解这里发生的情况,您需要了解 commits (这是Git的raison d'être),以及Git如何找到它们(通常从分支名称开始)。这进入了图形中的 reachability 的想法,在Think Like (a) Git中以更长或更详尽的方式对此进行了解释。
每个提交都有自己的唯一哈希ID。那就是你在这里看到的那条丑陋的大字符串,8d6995e4
(尽管实际上更长— 40个字符,显然是随机的,实际上根本不是随机的)。哈希ID是提交的“真实名称”:这是Git在“所有提交”数据库中找到提交的方式(人们要做的主要工作是添加更多提交)。
每个提交还拥有一个 parent 提交哈希ID。也就是说,某个父提交的孩子会记住父哈希。父母不记得自己的孩子,因为一旦做出提交,里面的任何内容都不会改变。这种提交的冻结状态对git log
并不重要,但对许多其他Git命令也很重要
上面的内容有些夸张,因为至少一个提交(某人在一个新的空存储库中进行的第一个提交)没有 父项。 this 提交的父级是 this 提交之前的提交。第一次提交之前没有提交。而且,合并提交有多个父级,这就是它们使合并提交的原因。
这意味着提交形成了一个向后看的链。 git log
使用的是此向后链。这是一个只有三个提交的存储库的简单绘图,其中我只使用了一个大写字母,而不是笨拙的40个字符的哈希ID。显然,我们很快就会用完-存储库将在26次提交时已满-因此,这不是Git这样做的方式,但它确实可以很好地说明问题。我们的第一个提交是A
,其父 no 。然后我们将B
设为A
作为其父级,最后,将C
设为B
作为其父级。
A <-B <-C
由于提交中的任何内容都无法更改,因此我们可以将从子级到父级的反向连接绘制为双向连接,只要我们记得 Git 必须向后。在StackOverflow帖子中,这对我来说更方便,因为有时我还需要做对角线:
A--B--C
\
D
并且我没有方便的文本箭头适合所有人使用。
现在,要使git log
工作,您必须给它一个开始提交-哈希ID。实际上,要使Git中的许多功能正常工作,您必须给它们提供一个哈希ID。但是实际的哈希ID大而丑陋(8d6995e4
)且显然是随机的。它们绝对不是合理的顺序,人类没有办法记住它们。因此,我们要做的是选择一个分支名称,例如master
。我们让Git将 last 提交的哈希ID推入分支名称中,这意味着我们的绘图现在看起来像这样:
A--B--C <-- master
名称使Git可以找到 last 提交,在这种情况下为C
。 git log
从那里向后走 到B
,然后回到A
,然后由于A
没有父母,Git最终可以停止
要添加 new 提交,Git将打包您提交的内容-一个新的快照-并添加元数据,例如您的姓名和电子邮件地址,即当前时间,以及您的日志消息。 Git会自动将 current 提交的哈希ID添加到元数据中。 Git将所有内容都写到对象数据库中,并且编写它的操作会为此新提交分配其唯一的哈希ID。当然,这是其他一些丑陋的数字,但是我们将使用字母D
:
A--B--C <-- master
\
D
为了纪念D
是我们的最后一次提交,Git现在更新了我们的名字master
:
A--B--C
\
D <-- master
因此,git log
现在将从D
开始,然后显示C
,然后显示B
,然后显示A
。
重要的是 commits 。分支名称可以帮助我们找到它们。但是,当我们有多个分支名称时会发生什么?在我们进行了几次提交之后,让我们看一个稍微复杂一点的图:
...--C--D <-- master
\
E--F <-- develop
我们在上面说过,当我们进行新的提交时,Git会移动分支名称。但是Git如何知道哪个分支名称移动?如果我们有:
...--C--D <-- develop, master
-我们可能在某个时候做了-Git如何知道在进行提交E
时应该移动的是 develop 而不是master
? / p>
答案是我们使用git checkout
将特殊名称HEAD
附加到一个分支上。如果选择develop
,我们将得到:
...--C--D <-- develop (HEAD), master
然后,当我们添加提交E
时,Git将移动develop
:
...--C--D <-- master
\
E <-- develop (HEAD)
即使分支名称本身移动,名称HEAD
仍附加在分支名称上。 (对于那些好奇的人,此方法的实际实现是在.git
中有一个名为HEAD
的文件,该文件仅包含分支名称本身。因此,HEAD
的内容仅当您选择一个新分支时,更改该分支名称。分支名称的内容(用于master
和develop
的最新提交的哈希ID)存储在其他位置,或更多个不同的地方。)
顺便提一下,在这里的附图中,提交A-B-C-D
在两个分支上。提交E-F
仅在develop
上。但是由于可以移动分支名称,因此可以通过移动master
指向F
来更改它。这将使所有六个提交都在两个分支上。我们不必更改 commits 来执行此操作,这是必需的,因为我们不能这样做。 :-)
图可能变得更加复杂。与其显示一个非常复杂的视图(而不是像您实际可能看到的那样),而是显示了一个简单的视图,它显示了我们提交合并时发生的情况。这是之前图片:
I--J <-- release (HEAD)
/
...--G--H
\
K--L <-- develop
及其后的 :
I--J
/ \
...--G--H M <-- release (HEAD)
\ /
K--L <-- develop
新的合并提交M
仅在release
上。它有两个父母,J
和L
。提交J
仅在发布时,并且有一个父级I
。提交L
在两个分支上,并且有一个父级K
。 I
和K
都导致提交H
,这两个分支都位于该分支上,并且又导致返回G
,这两个分支都位于该分支上,依此类推。>
git log
进入的地方如果您在运行git log
时未给它一些开始提交,则Git会查看您的HEAD
来查找当前的提交。您当前的提交是您的分支名称指向的提交。您在注释中提到您在release
分支上,并且它指向合并提交。因此,您的图片可能看起来像我们刚刚绘制的内容。
git log
命令将从提交M
开始并将其显示给您。然后它将M
的父母的 all 全部添加到需要显示的提交列表中。现在,它必须尝试同时向您显示J
和L
。它不能,所以它从这两个中选择一个来显示。然后,它将显示的任何一个的父项添加到要显示的内容列表中。
如果仅显示J
,则git log
现在有两个提交可以同时显示给您,分别是L
和I
。它不能同时显示两个,因此选择一个。然后将其父母添加到列表中,依此类推。
默认情况下,git log
命令将混合来自合并两侧的提交。特别是,它会根据时间戳一次向他们展示一个,这样您就可以首先看到更新的了。如果J
比L
更新,则您会在J
之前看到L
,但是如果L
比J
更新,则会看到{ {1}}首先。 L
和I
也是如此(与K
和L
相比)。但是J
确实尊重图形的形状,因为它不管做什么,在完成显示git log
和{之前,它不会显示H
。 {1}}。
最终,它将能够显示I-J
,并且这样做时,其他要显示的提交列表将为空。它将显示K-L
,将H
的父项H
添加到列表中以显示(现在只有一个条目),然后显示H
并添加{{1} }的父母,依此类推。
但是G
不会显示提交无法通过从G
开始并向后工作来实现!
G
假设有一个 other 名称记住哈希ID git log
。这可能不是分支名称:也许是M
或 I--J
/ \
...--G--H M <-- release (HEAD)
\ /
K--L <-- develop
\
N--O--P <-- another-name
之类的名称,您的Git用来记住您在其他Git中看到的分支名称。>
运行P
不会显示提交origin/develop
。没有显示origin/master
,也不会退回到git log
。实际上,Git不能从P
到P
。它只能从O
到L
,向后。您需要选择一个起始提交哈希,该哈希从您关心的提交开始或超出您关心的提交,以查看您关心的提交。
请注意,此处的提交N
不在“ N
”上。我们使用“ on”一词来表示“承诺从尖端到达”。 L
的尖端是提交N-O-P
,无法通过从release
向后退来到达提交release
。
请注意,也不能通过从M
向后退来到达提交N
!两个提交可以有一个共同的祖先,而自己没有父母/子女或祖父母/孙子女的关系。他们有共同的祖先,这可能只会使他们成为兄弟姐妹或表兄弟。