git-history
实验性:重写历史
概要
git history fixup <commit> [--dry-run] [--update-refs=(branches|head)] [--reedit-message] [--empty=(drop|keep|abort)]
git history reword <commit> [--dry-run] [--update-refs=(branches|head)]
git history split <commit> [--dry-run] [--update-refs=(branches|head)] [--] [<pathspec>...]描述
通过重新排列或修改历史中的特定提交来重写历史。
此命令是实验性的。行为可能会更改。
此命令与 git-rebase(1) 相关,因为两个命令都可用于重写历史。但有几个主要区别:
- git-history(1) 的大多数子命令可以在裸仓库中工作,因为它们不需要触及索引或工作树。
fixup子命令是一个例外,因为它从索引读取暂存的更改。 - git-history(1) 目前不执行任何 githooks(5)。这将来可能会改变。
- git-history(1) 默认更新原始提交的所有后代分支以指向重写的提交。
总体而言,git-history(1) 旨在提供一种更固执的方式来修改提交历史,与 git-rebase(1) 相比通常更易于使用。
如果您想将一系列提交重新应用到不同的基础,请使用 git-rebase(1);如果想一次编辑一系列提交,请使用交互式变基。
限制
此命令(尚)不能处理包含合并的历史。您应该改用带有 --rebase-merges 标志的 git-rebase(1)。
此外,该命令不支持可能导致合并冲突的操作。此限制是设计使然,因为历史重写不打算成为有状态的操作。一旦 Git 了解一等冲突,此限制就可以解除。
使用带有 --empty=drop 的 fixup 时,尚不支持删除根提交。
命令
fixup <commit>- 将当前暂存的更改应用到指定的提交。这本质上类似于git commit --fixup=<commit>后跟git rebase --autosquash <commit>~。通过在 HEAD 提交、目标提交和从暂存更改生成的树之间执行三向合并,将更改应用到目标提交。 默认情况下,目标提交的提交消息和作者身份会被保留,除非您指定--reedit-message。 如果应用暂存的更改会导致冲突,命令将中止并报错。原始提交的所有后代分支都会更新以指向重写的历史。reword <commit>- 重写指定提交的提交消息。此提交的所有其他详细信息保持不变。此命令将启动带有该提交当前消息的编辑器。split <commit> [--] [<pathspec>...]- 通过选择将移入新的拆分提交的块,交互式地将 <commit> 拆分为两个提交。这些块将被写入成为先前提交父提交的新提交。原始提交保持不变,只是其父提交将是新拆分的提交。 拆分提交的提交消息将通过启动配置的编辑器来询问。提交的作者身份将与原始提交相同。
选项
--dry-run- 不更新任何引用,而是以 git-update-ref(1) 可以消费的格式打印任何引用更新。--reedit-message- 打开编辑器以修改目标提交的消息。--empty=(drop|keep|abort)- 控制提交因修复变为空时发生的情况。这可能在两种情况下发生:- 修复目标本身变空,因为暂存的更改恰好抵消了该提交引入的所有更改。
- 后代提交在重放期间变空,因为它引入了刚刚修复到祖先中的相同更改。 使用
drop(默认)时,空提交从重写的历史中删除。 使用keep时,空提交按原样保留在重写的历史中。 使用abort时,如果任何提交将变空,命令将停止并报错。
--update-refs=(branches|head)- 控制命令将更新哪些引用(如果有)。使用branches时,指向原始提交后代提交的所有本地分支将被重写。使用head时,仅当前HEAD引用将被重写。默认为branches。
示例
修复提交
$ git log --oneline --stat
abc1234 (HEAD -> main) third
third.txt | 1 +
def5678 second
second.txt | 1 +
ghi9012 first
first.txt | 1 +
$ echo "change" >>unrelated.txt
$ git add unrelated.txt
$ git history fixup ghi9012
$ git log --oneline --stat
jkl3456 (HEAD -> main) third
third.txt | 1 +
mno7890 second
second.txt | 1 +
pqr1234 first
first.txt | 1 +
unrelated.txt | 1 +暂存的 unrelated.txt 添加已被合并到 first 提交中。所有后代提交都已在重写的历史之上重放。
拆分提交
$ git log --stat --oneline
3f81232 (HEAD -> main) original
bar | 1 +
foo | 1 +
2 files changed, 2 insertions(+)
$ git history split HEAD
diff --git a/bar b/bar
new file mode 100644
index 0000000..5716ca5
--- /dev/null
+++ b/bar
@@ -0,0 +1 @@
+bar
(1/1) Stage addition [y,n,q,a,d,p,?]? y
diff --git a/foo b/foo
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo
(1/1) Stage addition [y,n,q,a,d,p,?]? n
$ git log --stat --oneline
7cebe64 (HEAD -> main) original
foo | 1 +
1 file changed, 1 insertion(+)
d1582f3 split-out commit
bar | 1 +
1 file changed, 1 insertion(+)Git
git(1) 套件的一部分
