can';在4d58e4c关于ffserver.c文件之后是否无法获得git提交?

can';在4d58e4c关于ffserver.c文件之后是否无法获得git提交?,git,github,Git,Github,我想获得一个文件的完整修订历史记录,并使用git log--filepath命令。然而,结果并不完全 如上图所示,关于ffserver.c的最后一次提交是4d58e4c。但是从github文件历史来看,4d58e4c之后有很多提交。你可以去看看 另外,我使用图1命令来显示最新的提交(图1)。然而,由于github修订历史记录(图2),git命令结果(commit 4d58e4c)不是最新的提交,在该提交之后有许多提交,如图2中的094a496。我想知道为什么会发生这种情况,以及我如何在这次提交

我想获得一个文件的完整修订历史记录,并使用
git log--filepath
命令。然而,结果并不完全

如上图所示,关于ffserver.c的最后一次提交是4d58e4c。但是从github文件历史来看,4d58e4c之后有很多提交。你可以去看看

另外,我使用图1命令来显示最新的提交(图1)。然而,由于github修订历史记录(图2),git命令结果(commit 4d58e4c)不是最新的提交,在该提交之后有许多提交,如图2中的094a496。我想知道为什么会发生这种情况,以及我如何在这次提交后获得提交

那么,如何使用git命令或python代码获得这些提交,以及为什么我无法获得完整的修订历史记录

谢谢。

TL;博士 使用
git log 4d58e4c..HEAD
,或者使用
git log 4d58e4c^@..HEAD

长的 不过,在你开始使用这个食谱之前,花点时间来了解这意味着什么以及它是如何工作的是值得的。有许多关键项目需要学习:

  • 提交是有编号的,带有看起来随机的(虽然实际上不是随机的)散列ID

  • 提交保留快照和元数据:

    • 快照保存每个文件的完整副本,但采用特殊、只读、仅Git、压缩和消除重复的形式。因此,它们充当档案。这些文件在反归档(使用
      git checkout
      git switch
      )之前不可用。但它们可以在存档时短暂访问

    • 元数据最终将提交向后串在一起

  • 分支名称只是保存该分支上最新提交的哈希ID

  • Git反向工作

最后一点就是为什么前进如此困难。一旦找到commit
4d58e4c
,Git只能从它向后工作。所以诀窍是从“现在”(最近的提交)向后工作,直到到达“然后”(提交
4d58e4c
)。在时间倒转过程中,您访问的提交是
4d58e4c
之后的提交

犯罪的倒退性质 正如我们已经注意到的,每个提交都有一个看起来随机的散列ID号,表示为。Git使用此哈希ID来定位提交。实际提交存储在一个简单的文件中:散列ID是键,提交的元数据和快照是值。1

元数据是关于提交的信息:提交人、提交时间等。例如,在这里您可以找到作者和提交人的姓名,以及他们选择添加的任何日志消息。不过,其中一个元数据项是Git所称的提交的父项。这些是一些早期提交的原始哈希ID。大多数提交只存储一个父散列ID。主要的例外是合并提交,它定义为存储两个或多个散列ID的任何提交

一旦做出某种承诺,其中任何部分都无法更改。这是因为提交的哈希ID是内容(元数据,包括快照)的简单加密哈希。如果您将这些字节从键值数据库中取出,进行一些更改,然后将字节放回,您得到的不是对旧键下的值的更改,而是使用新的哈希ID键的新提交。现有提交仍保留在数据库中,仍然有效且可访问。您所做的只是添加一个新的提交

由于提交后,提交中的任何内容都无法更改,因此不可能将较新提交的哈希ID放入较旧的提交中。我们只能走另一条路。较新的提交可以包含较旧提交的哈希ID,我们知道这是因为较旧的提交已经存在

当一个提交包含另一个的散列ID时,我们说一个提交必然是一个较新的提交,正如我们刚才看到的指向较旧的提交。因此,如果每个提交中只有一个哈希ID,那么提交将形成一个序列,就像字符串上的珍珠一样,只是我们只能从较新的提交到较旧的提交:

只要我们有一些名字可以指向的提交,我们就可以有我们想要的任意多的名字。其中一些名称可能指向相同的提交:

如果我们运行
git checkout feature1
,我们会告诉git通过名称
feature1
选择commit
H
。签出的文件集未更改提交
H
仍为提交
H
-但
头的附件更改:

...--F   <-- main
      \
       G--H   <-- develop, feature1 (HEAD)
Git所做的是,
Git commit
命令在构建新提交时,将新提交的父级设置为当前提交,归档所有文件,2写出适当的元数据,获取新提交的哈希ID,然后,将新提交的哈希ID写入当前分支名称中,
HEAD
的附加将记住该名称。因此,现在分支名称
feature1
选择newcommit
I


2这种文件归档是偷偷的:Git使用Git索引中的副本,而不是工作树中的副本。在这个回答中,我们没有涉及Git的索引和您的工作树,但这种区别很重要


现在我们可以看到
git log
是如何工作的 通过忽略
git log
如何处理合并提交而简化,例如
git log
所做的是以您命名的某个提交开始,或者如果您没有命名提交,则以
HEAD
开始:

git log HEAD
以及:

两者都以通过名称
HEAD
找到的提交开始。由于
HEAD
通常附加到分支名称,3这将使用分支名称查找提交的哈希ID。
git log
命令随后显示提交的元数据。4

然后,在显示提交后,Git使用提交存储的父哈希ID向后移动一个
...--F   <-- main
      \
       G--H   <-- develop, feature1
...--F   <-- main
      \
       G--H   <-- develop (HEAD), feature1
...--F   <-- main
      \
       G--H   <-- develop, feature1 (HEAD)
...--F   <-- main
      \
       G--H   <-- develop
           \
            I   <-- feature1 (HEAD)
git log HEAD
git log
git log -- filepath
4d58e4c..HEAD