git commit和git commit-tree有什么区别

bprjcwpo  于 2023-04-28  发布在  Git
关注(0)|答案(2)|浏览(179)

我正在阅读有关git对象的内容:blob、tree、commit、tag。为了更好地理解git是如何工作的,我尝试了一些低级命令,如write-treecommit-tree

  1. mkdir test; cd test --〉git init
    1.我创建一个文件和git add file。我可以看到在.git/objects中生成了一个blob和树对象
  2. git write-tree打印当前树ID
  3. git commit-tree treeID -m "commit a tree"提交此树。在这个操作之后,生成了一个提交对象,我可以看到它确实包含了author,date等。但是,我不能使用git log检查我的提交,错误是:fatal: bad default revision 'HEAD'
    完成以上操作后,当我运行git status时,我看到文件仍然在索引中等待提交。commit-tree有什么用,commit-tree和commit有什么区别?
8ehkhllq

8ehkhllq1#

git-commit-记录对存储库的更改
在新提交中存储索引的当前内容沿着来自用户的描述更改的日志消息。
git commit“记录对仓库的更改”
git-commit的图示为here,位于SO
git-commit-tree-创建一个新的提交对象
基于提供的树对象创建一个新的提交对象,并在stdout上发出新的提交对象id。
这通常不是最终用户想要直接运行的。根据提供的树对象创建新的提交对象,并在stdout上发出新的提交对象id。除非给出-m-F选项,否则将从标准输入读取日志消息。

zaqlnxep

zaqlnxep2#

git-commit(1)是一个高级命令,你几乎总是要使用它。git-commit-tree(1)是一个较低级别的命令,它不是日常使用的命令。
git-commit(1)用于交互式提交新的更改。不过,我想我不必再细说了。
git-commit-tree(1)在以下情况下很有用:
1.想要显式地选择提交的父节点
1.你已经有了一个提交的 * 树 *
假设我想有效地将repo中的所有提交“压缩”为一个提交。但是“squash”是一个变基操作,因为它合并了更改,所以它是多余的,我不需要合并任何更改,因为我已经知道我想要的快照-当前的快照。因此:[1] [2]

$ git commit-tree -m Init HEAD^{tree}
1a875b50b508c70e44a4e6300fd80f580aed3d99

(That变成了无父提交,因为我没有用-p指定任何父提交。)
这就是提交的SHA1。我最好把它放在一个分支上,这样垃圾收集器几个月后就不会收集它了。

$ git branch new-start 1a875b50b508c70e44a4e6300fd80f580aed3d99

你可以做的另一件事是使用现有的提交和它们的树来创建任何你想要的历史。例如,我想创建一个Git仓库的历史记录,它只包含版本v1.0.0v2.0.0v2.40.0,并调用分支small-git

git clone https://github.com/git/git/ git-repo
cd git-repo
first=$(git commit-tree -m v1 v1.0.0^{tree})
second=$(git commit-tree -p $first -m v2 v2.0.0^{tree})
third=$(git commit-tree -p $second -m v2.40.0 v2.40.0^{tree})
git branch small-git $third

您可以使用以下命令进行验证(所有差异应为空):

$ # While on `small-git`
$ git diff v2.40.0
$ git diff @^ v2.0.0
$ git diff @^^ v1.0.0

注意事项

1.有关^{tree}语法,请参见man gitrevisions
1.这可以通过其他方式来实现,例如E。例如git checkout --orphan new-start && git commit -m Init。所以你并不需要这个命令。

相关问题