我是Git的新手,所以要问一些与之相关的基本问题。 之前我使用过clearcase和svn。
例如在Subversion中,当我们进行一些文件更改并签入/提交时,将创建相同链接的日志,如链接“ https://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-showlog.html”中所示。因此,Subversion会维护每次提交期间签入/提交的各种记录和文件的日志历史记录。
Git是否还会在分支中维护所有签到的历史记录,以及在每次签入期间更改/添加/删除文件的历史记录? 如何在Git扩展程序/浏览器中或通过命令查看此信息(各种检入/提交到分支以及在每次提交中生效的文件)?
换句话说:今天假设在任何分支的Git中,我都签入/提交了一些文件更改。然后几天后,我再次进行一些更改/添加/删除一些文件并签入它们。 现在过了几天,我想查看对分支的所有提交以及每次检入/提交期间更改/检入的所有文件。 如何在Git扩展程序/浏览器中或通过命令查看所有与签入相关的信息?
答案 0 :(得分:2)
GIT还会在分支中维护所有签入的历史记录,以及在每次签入期间更改/添加/删除文件的情况吗?
否:Git的模型完全不同。
换句话说:假设今天在任何分支的GIT中,我都签入/提交一些文件更改。
Git不存储更改。 Git存储 commits 。每个提交代表每个文件的完整快照,完整且完整无缺,并带有提交时每个此类文件的内容。
更确切地说,提交是一个对象-这是一个Git术语,但在这里我们也可以通用使用它-由唯一的哈希ID(例如5d826e972970a784bd7a7bdf587512510097b8c7
标识)(这是提交中的哈希ID Git的Git存储库):
额外的间接级别(提交包含树的哈希ID,树的哈希ID包含包含文件内容的blob的哈希ID)使Git可以在多个提交之间重用未修改的文件。每个Git对象都是100%只读的,因此一旦提交,所有文件的内容将一直保存(或者至少保存到删除提交本身为止,这非常棘手)。
Git将呈现作为更改提交给您,但要这样做,git log
从确定的最后提交开始通过其哈希ID(您必须以某种方式提供)。 (您可以通过原始哈希ID来完成此操作,但这很丑陋。我们稍后会再讨论。)这是 last 提交,因为Git现在可以向后退 了,使用存储在该提交中的先前哈希ID:
... <-F <-G <-H <-- start here at H
提交H
是所有文件的完整快照。 G
的前身H
也是如此。 Git提取两个提交,进行比较,并打印出它们之间的差异,以向您显示H
中发生的事情。
现在Git显示了H
,它可以移回到G
。为了显示G
中发生的情况,Git提取了其前身F
,提取了G
,将它们进行比较,并打印出差异。
git log
命令就是执行此后退操作的命令。它显示日志消息,并使用-p
进行提取和比较。
带有哈希ID的git show
命令将打印日志消息,并执行一个向后移动和渐进式比较,然后停止。
当然,这里的哈希ID太恐怖了,完全不适合正常人使用。与SVN版本号不同,任何两个背对背的提交哈希ID之间没有关系。您不应该记住它们。相反,Git为您提供了两种主要方法来让 Git 为您记住它们:
标记名称或多或少永久地存储哈希ID。鉴于提交是最终版本,您可能需要对其进行标记。没有人会更改发布v2.20.0
的提交,因此您可以将5d826e972970a784bd7a7bdf587512510097b8c7
标记为v2.20.0
,而不必再次记住大的丑陋哈希ID。
分支名称(尽管有些棘手,但我们可能想与分支区分开)也存储了哈希ID。不过,与标记的主要区别在于,当您在分支上进行 new 提交时,Git 会自动更新分支名称以存储新提交的新哈希ID。
让我们再次看一下先前的图形,并添加一个分支名称master
:
... <-F <-G <-H <-- master (HEAD)
名称master
附有单词HEAD
。这意味着这是我们的当前分支。
现在继续进行一次 new 提交(通常会修改文件和git add
等)。 Git收集我们的日志消息,永久冻结所有文件的内容,创建一个树对象以记住它们,并创建一个提交对象以存储元数据,例如提交H
的哈希ID,新树的哈希ID ,我们输入的日志消息等。这个新的提交对象获得了一些新的丑陋的哈希ID,我们将其称为I
,而不是猜测它。 I
的 parent 将是H
:
...--F--G--H <-- master (HEAD)
\
I
作为我们{{1}的 last 步骤,Git现在将git commit
的实际哈希ID写入名称I
,其中master
附件:
HEAD
因此,现在,如果我们要求Git向我们显示...--F--G--H
\
I <-- master (HEAD)
,Git将提取master
,显示I
的日志消息,提取I
,然后将其与提取了H
,并向我们展示了从I
到H
的差异-无需输入任何哈希ID。
请注意,如果在提交之前将 new 分支名称I
附加到develop
上,并使我们的H
,则新提交{{1} }转到新分支:
HEAD
提交的发生方式与完全相同。哈希ID甚至可能完全相同(尽管这要求我们在完全相同的秒进行提交,因为哈希ID对提交内的时间戳进行编码)。更改的是哪个分支名称Git将新的哈希ID写入了其中。
这就是Git分支的意义:它们是可移动的指针,指向提交。重要的是 commit 。分支名称是获取提交哈希ID的简单方法,这些ID在我们工作时会自动移动。
每个提交都是完整的快照,并且重要的是哈希ID。名称就在那里找到哈希ID。当您来自SVN或Clearcase时,Git其余大部分明显的怪异是由于这两个事实。 (其余大部分是由于Git的 index 引起的,在此不做介绍。)
答案 1 :(得分:1)
您在寻找吗 git log -p。向您显示更改文件的差异。 另外,还有git log的许多其他选项,可以帮助您缩小范围以找到所需的内容。这是参考文献https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History