checkout
rebase
那么,什么是Git commit呢?
deyfvvtc1#
虽然可以解释为两者兼而有之,但GitHub工程团队很清楚(12月12日)。2020年):
Derrick Stolee开始于
关于Git对象,最重要的一点是Git通过对象ID(简称OID)引用每个对象,为对象提供唯一的名称。我们将使用git rev-parse <ref>命令来发现这些OID。每个对象本质上都是一个纯文本文件,我们可以使用git cat-file -p <oid>命令检查其内容。
git rev-parse <ref>
git cat-file -p <oid>
要查找当前修订版文件的OID,请运行git rev-parse HEAD:<path>。然后,使用git cat-file -p <oid>查找其内容。
git rev-parse HEAD:<path>
请注意,blob包含文件内容,但不包含文件 * 名称 *!这些名称来自Git的目录表示:树木树是路径条目的有序列表,与该路径上的对象类型、文件模式和对象的OID配对。子目录也被表示为树,所以树可以指向其他树!最后:
提交是时间快照。每个提交都包含一个指向其根目录树的指针,表示当时工作目录的状态。
提交具有对应于先前快照的父提交的列表。没有父提交是根提交,而有多个父提交是合并提交。提交还包含描述快照的元数据,例如作者和提交者(包括姓名、电子邮件地址和日期)以及提交消息。提交消息是提交作者相对于父提交描述该提交的目的的机会。x1c 0d1x的数据即使提交是快照,我们也经常在历史视图或GitHub上将提交视为差异。事实上,提交消息经常引用这个差异。通过比较提交和其父提交的根树,从快照数据动态生成差异。Git可以在时间上比较任意两个快照,而不仅仅是相邻的提交。计算差异是启用git cherry-pick或git rebase的原因。由于提交不是diff...Git不跟踪重命名。Git内部没有数据结构来存储在提交和其父提交之间发生的重命名记录。相反,Git尝试在动态比较计算期间检测重命名。此重命名检测有两个阶段:精确重命名和编辑重命名。在第一次计算diff后,Git检查diff的内部模型,以发现哪些路径被添加或删除。自然,从一个位置移动到另一个位置的文件将显示为从第一个位置删除,而在第二个位置添加。Git尝试匹配这些添加和删除以创建一组推断的重命名。
git cherry-pick
git rebase
flvtvl502#
提交是快照状态。当执行git diff时,它计算与父类的差异。这就是为什么可以有多个父代(当存在合并时的情况)。在内部,有增量压缩,但版本模型不是基于补丁的。Git中的一个核心概念是 index。这是一个包含被跟踪对象树的大对象。当更改从工作副本传播到索引时,将暂存更改;这将索引置于修改状态。提交操作将该状态转换为新的提交。
git diff
bkhjykvo3#
这里的答案太长了。
cherry-pick
uajslkp64#
事实上只有当你把提交看作是工作树的快照时,一些命令才有意义。这在checkout中最为明显,但在stash中也是如此,在fetch和reset中至少有一半是如此。对于其他命令,当您试图以这种方式考虑提交时,可能会导致疯狂。对于那些其他命令,提交明确被视为更改,
stash
fetch
reset
show
diff
apply
pull
merge
二元性1有一个副作用,可能会让习惯于其他版本系统的Git新手感到震惊。事实上,Git似乎甚至不提交自己的提交。什么?假设你已经创建了一个分支X,其中包含你喜欢认为是你的提交A和B的内容。但是master已经进步了一点,所以你rebase X到master。当你把A和B看作变化,而把master看作快照 (嘿,粒子和波在一个实验中!),这不是问题:只需将更改A和B应用到快照master。这种想法是如此自然,以至于你几乎不会注意到Git已经重写了你的提交A和B:它们现在具有不同的快照内容,因此具有不同的SHA-1 ID。在Git中,作为开发人员,概念上的提交并不是一成不变的,而是在使用仓库时发生变化的动态对象。相比之下,如果你把这三个(A、B和master)都看作是快照,或者把这三个都看作是变化,你的大脑会受到伤害,你将一事无成。
A
B
master
以上是非常简化的描述。在Git现实中
不要被Pro Git这本书对Git的第一个描述(在“Git Basics”一节)是 “快照,而不是差异” 这一事实所迷惑。Git is complicated after all.
4条答案
按热度按时间deyfvvtc1#
虽然可以解释为两者兼而有之,但GitHub工程团队很清楚(12月12日)。2020年):
Commits are snapshots, not diffs
Derrick Stolee开始于
对象ID
关于Git对象,最重要的一点是Git通过对象ID(简称OID)引用每个对象,为对象提供唯一的名称。
我们将使用
git rev-parse <ref>
命令来发现这些OID。每个对象本质上都是一个纯文本文件,我们可以使用
git cat-file -p <oid>
命令检查其内容。Blob(文件内容)
要查找当前修订版文件的OID,请运行
git rev-parse HEAD:<path>
。然后,使用
git cat-file -p <oid>
查找其内容。Trees(目录列表)
请注意,blob包含文件内容,但不包含文件 * 名称 *!
这些名称来自Git的目录表示:树木
树是路径条目的有序列表,与该路径上的对象类型、文件模式和对象的OID配对。
子目录也被表示为树,所以树可以指向其他树!
最后:
commit:快照时间
提交是时间快照。每个提交都包含一个指向其根目录树的指针,表示当时工作目录的状态。
提交具有对应于先前快照的父提交的列表。
没有父提交是根提交,而有多个父提交是合并提交。
提交还包含描述快照的元数据,例如作者和提交者(包括姓名、电子邮件地址和日期)以及提交消息。
提交消息是提交作者相对于父提交描述该提交的目的的机会。
x1c 0d1x的数据
即使提交是快照,我们也经常在历史视图或GitHub上将提交视为差异。事实上,提交消息经常引用这个差异。
通过比较提交和其父提交的根树,从快照数据动态生成差异。Git可以在时间上比较任意两个快照,而不仅仅是相邻的提交。
计算差异是启用
git cherry-pick
或git rebase
的原因。由于提交不是diff...
Git不跟踪重命名。Git内部没有数据结构来存储在提交和其父提交之间发生的重命名记录。
相反,Git尝试在动态比较计算期间检测重命名。此重命名检测有两个阶段:精确重命名和编辑重命名。
在第一次计算diff后,Git检查diff的内部模型,以发现哪些路径被添加或删除。
自然,从一个位置移动到另一个位置的文件将显示为从第一个位置删除,而在第二个位置添加。Git尝试匹配这些添加和删除以创建一组推断的重命名。
flvtvl502#
提交是快照状态。当执行
git diff
时,它计算与父类的差异。这就是为什么可以有多个父代(当存在合并时的情况)。在内部,有增量压缩,但版本模型不是基于补丁的。Git中的一个核心概念是 index。这是一个包含被跟踪对象树的大对象。当更改从工作副本传播到索引时,将暂存更改;这将索引置于修改状态。提交操作将该状态转换为新的提交。
bkhjykvo3#
这里的答案太长了。
1.某些命令,如
cherry-pick
、compute 快照之间的差异。uajslkp64#
理解Git粒子波二象性
在内部,Git将使用两种表示,这取决于(概念上)它认为哪一种在给定提交的存储空间和执行时间方面更有效。快照表示是主要表示。
从用户的Angular 看,但这取决于你做了什么:
对偶1:作为快照提交与作为变更提交
事实上只有当你把提交看作是工作树的快照时,一些命令才有意义。这在
checkout
中最为明显,但在stash
中也是如此,在fetch
和reset
中至少有一半是如此。对于其他命令,当您试图以这种方式考虑提交时,可能会导致疯狂。对于那些其他命令,提交明确被视为更改,
show
、diff
)apply
、cherry-pick
、pull
)rebase
)merge
、cherry-pick
)对偶二:作为一个固定的事情提交与像流动的东西一样承诺
二元性1有一个副作用,可能会让习惯于其他版本系统的Git新手感到震惊。事实上,Git似乎甚至不提交自己的提交。
什么?
假设你已经创建了一个分支X,其中包含你喜欢认为是你的提交
A
和B
的内容。但是master
已经进步了一点,所以你rebase
X到master
。当你把
A
和B
看作变化,而把master
看作快照 (嘿,粒子和波在一个实验中!),这不是问题:只需将更改A
和B
应用到快照master
。这种想法是如此自然,以至于你几乎不会注意到Git已经重写了你的提交
A
和B
:它们现在具有不同的快照内容,因此具有不同的SHA-1 ID。在Git中,作为开发人员,概念上的提交并不是一成不变的,而是在使用仓库时发生变化的动态对象。相比之下,如果你把这三个(
A
、B
和master
)都看作是快照,或者把这三个都看作是变化,你的大脑会受到伤害,你将一事无成。免责声明
以上是非常简化的描述。在Git现实中
不要被Pro Git这本书对Git的第一个描述(在“Git Basics”一节)是 “快照,而不是差异” 这一事实所迷惑。
Git is complicated after all.