Git commit-tree 与 Git commit的区别

本文深入探讨了Git中commit-tree指令的使用方法,通过实例演示如何基于一个tree的hashid创建commit对象,并将其放入仓库的过程。同时,文章还介绍了如何通过update-ref指令更新分支的head值,最终实现commit的生成。

'git commit-tree'指令基于一个tree的hash id创建了一个commit对象。

'git commit'则是将暂存区的内容放到仓库。暂存区的通常通常是一个commit对象。

所以,我们可以看到,要将这个commit-tree放入仓库中我们仍需要额外的操作。让我们再来模拟下这个过程。

[wlin@wlin local_version]$ git init
Initialized empty Git repository in /home/wlin/local_version/.git/
[wlin@wlin local_version]$ echo "version 1" > test.txt
[wlin@wlin local_version]$ git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30
[wlin@wlin local_version]$ git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
[wlin@wlin local_version]$ git write-tree
d8329fc1cc938780ffdd9f94e0d364e0ea74f579
[wlin@wlin local_version]$ echo "first commit" | git commit-tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
c51498ffa6d93bbe5661249a2e58d43ce0e45924
# 并没有commit生成
[wlin@wlin local_version]$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   test.txt
#
# 也没有log生成,显示的错误原因是HEAD没有指定有效的版本
[wlin@wlin local_version]$ git log
fatal: bad default revision 'HEAD'
# 更新master(如果你在其他分支上,则需要指定为其他分支)分支的head的值,指向我们的commit对象
[wlin@wlin local_version]$ git update-ref refs/heads/master b79cf1e3cdb481442f5e11d8bef81466b0f6305f
# 显示我们的commit
[wlin@wlin local_version]$ git log
commit c51498ffa6d93bbe5661249a2e58d43ce0e45924
Author: Cara Wang <wlin@redhat.com>
Date:   Wed Jan 23 16:53:05 2019 +0100

    first commit

 

`git commit --amend` 和 `git commit --amend --no-edit` 都是用来修改最新一次 commit 的命令,但它们在 **是否修改 commit message** 上有重要区别--- ## **1. `git commit --amend`(默认行为)** ### **作用** - **修改最新的 commit**(包括提交内容和 commit message)。 - 如果暂存区(Staged)有新的修改,会 **合并到上一个 commit**。 - **会打开默认编辑器**(如 Vim、Nano),让你修改 commit message。 ### **使用场景** - 想 **修改 commit message**(比如修正拼写错误、补充说明)。 - 想 **合并新的改动到上一个 commit**(比如漏掉了某个文件)。 ### **示例** ```bash git add new_file.txt # 添加漏掉的文件 git commit --amend # 修改 commit message 并合并 new_file.txt ``` **效果**: - Git 会打开编辑器,显示原 commit message,你可以修改它。 - 最终生成一个新的 commitCommit Hash 会变)。 --- ## **2. `git commit --amend --no-edit`** ### **作用** - **修改最新的 commit,但保持 commit message 不变**。 - 如果暂存区有新的修改,会 **合并到上一个 commit**,但 **不会修改 commit message**。 - **不会打开编辑器**,直接完成修改。 ### **使用场景** - 只想 **合并新的改动到上一个 commit**,但 **不想改 commit message**。 - 适用于: - 漏掉了某个文件(`git add` 后合并到上一个 commit)。 - 修复了代码但不想改 commit 描述。 ### **示例** ```bash git add fixed_code.py # 添加修复的代码 git commit --amend --no-edit # 合并到上一个 commit,不修改 message ``` **效果**: - 上一个 commit 会包含 `fixed_code.py`,但 commit message **完全不变**。 - Commit Hash 仍然会变(因为内容变了)。 --- ## **关键区别总结** | **行为** | `git commit --amend` | `git commit --amend --no-edit` | |-------------------------|----------------------|--------------------------------| | **是否修改 commit message** | ✅ 是(打开编辑器) | ❌ 否(保持原 message) | | **是否合并暂存区改动** | ✅ 是 | ✅ 是 | | **是否改变 Commit Hash** | ✅ 是 | ✅ 是 | | **适用场景** | 修改 message 或合并改动 | 仅合并改动,不改 message | --- ## **注意事项** 1. **`--amend` 会改变 Commit Hash** - 即使只是改 message,也会生成一个新的 commit,**影响 Git 历史**。 - 如果 commit 已经推送到远程,需要用 `git push --force-with-lease`(慎用!)。 2. **`--no-edit` 适合快速修复** - 如果你只是漏了文件或代码,且 commit message 已经足够清晰,用 `--no-edit` 更高效。 3. **编辑器行为** - 如果不加 `--no-edit`,Git 会打开默认编辑器(如 Vim),需要保存退出才能完成修改。 --- ## **示例对比** ### **场景 1:修改 commit message** ```bash git commit --amend # 修改 message ``` ### **场景 2:只合并新改动,不改 message** ```bash git add missing_file.js git commit --amend --no-edit # 合并文件,message 不变 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值