在交互式 rebase 期间,X 和 Y 被替换为包含结果更改的全新提交 (Z)。如果原始提交没有链接到另一个提交、分支、标签或其他引用,它们就会变得悬空/无法访问。如您所知,它们仍然可以在您的本地存储库中访问,并且最终会被垃圾回收。
当您将分支推送到远程时,只会推送引用的提交。在这种情况下,Z 和更早的提交尚未在远程(如果有)上。 X 和 Y 不会被推送,除非它们是您稍后推送的另一个引用(例如分支)的一部分。
$ git clone <remote-repo> .
$ echo "SECRET" > file.txt
$ git commit -am "X"
$ echo "******" > file.txt
$ git commit -am "Y"
$ git log --oneline --graph --all
* 2e61b2a (HEAD -> master) Y
* fbeb59a X
* 3068e71 (origin/master, origin/HEAD) Initial commit
$ git rebase -i HEAD~2 # pick X, squash Y, new message: 'Z'
$ gittest % git log --oneline --graph --all
* bc58ac7 (HEAD -> master) Z
* 3068e71 (origin/master, origin/HEAD) Initial commit
新的提交 bc58ac7 替换了另外两个提交。 diff 不显示秘密值(在提交 X 中看到),而只显示两个提交的结果更改:
$ git diff 3068e71 bc58ac7
diff --git a/file.txt b/file.txt
index e69de29..0b13ec0 100644
--- a/file.txt
+++ b/file.txt
@@ -0,0 +1 @@
+******
推送后,我们看到origin/master 引用了新的提交:
$ git push
$ git log --oneline --graph --all
* bc58ac7 (HEAD -> master, origin/master, origin/HEAD) Z
* 3068e71 Initial commit
当我们打印远程存储库上的所有对象时,我们看到两个提交都不存在。 (此命令需要在远程仓库中执行,而不是在本地克隆中。)
$ git cat-file --batch-check --batch-all-objects
0b13ec01f786f69139940c06f3bc7f9645550cfa blob 7
3068e71e3ca27d864af7a1c5eb7dc90aee31de14 commit 229
76fd94cb5a10f70fe2fadc41af74e9eeeb8e35b5 tree 36
bc58ac7510f3e08d693029674a7ac545404e48cd commit 264
bdd68b0120ca91384c1606468b4ca81b8f67c728 tree 36
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 blob 0