4

I'm wondering if squashed commits in a rebase can be visible+accessible to other people. I'll illustrate a quick example. Assume this is all happening on my local machine in a local git repo.

  • I make a commit 'X' with env secrets (oh no!)
  • I make a commit 'Y' that removes the committed env secrets along with some other unrelated code changes
  • I then rebase by squashing the 2 commits (e.g. git rebase -i HEAD~2) so that my commit with the env secrets has been squashed

Question: If I then push my commit to a public repo, would another person (assume a bad actor) be able to somehow pull the changes and search for the squashed commit which contains the env secrets?

Note: I understand from here that reflog commits are still accessible locally, but I'm asking not from a local repo perspective, but rather from the perspective of someone on another machine pulling my new commits. Additionally, I don't mind if squashed commit messages (emphasis on message) are still visible such as in the case someone forgets to comment them out during the rebase, the question I have is concerned with the squashed commits themselves.

Thank you!!

Matthew Liu
  • 309
  • 1
  • 9
  • No, I don't think so. However, one thing to be careful about is if you had switched to another branch with the commit containing your secrets, and then unknowingly pushed (e.g. via `--all`) that branch up to your remote. Git also shouldn't be pushing loose objects either as far as I know. – miqh Jun 21 '21 at 05:21

2 Answers2

3

During the interactive rebase, X and Y get replaced by a completely new commit (Z) containing the resulting changes. If the original commits are not linked to another commit, branch, tag or other reference, they become dangling/unreachable. As you already know, they remain accessible in your local repository and will eventually get garbage-collected.

When you push your branch to a remote, only the referenced commits are pushed. In this case Z and earlier commits not yet on the remote (if any). X and Y do not get pushed unless they are part of another reference (e.g. branch) that you push later.


$ 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

The new commit bc58ac7 replaced the two other commits. The diff does not show the secret value (seen in commit X) but only the resulting changes of both commits:

$ 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 @@
+******

After a push, we see that origin/master references the new commit:

$ git push
$ git log --oneline --graph --all
* bc58ac7 (HEAD -> master, origin/master, origin/HEAD) Z
* 3068e71 Initial commit

When we print all objects on the remote repository, we see that the two commits are not there. (This command needs to be executed in the remote repository, not in the local clone.)

$ 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
Matt
  • 12,848
  • 2
  • 31
  • 53
2

I understand from here that reflog commits are still accessible locally, but I'm asking not from a local repo perspective, but rather from the perspective of someone on another machine pulling my new commits.

Then no: reflog being purely local, none of the dereferenced history that you see in reflog will be visible after a push/pull.

There would be visible only if you pushed the first commit, before merge squashing then force pushing: the interval between the first and second push could leave time from someone to get the problematic commit.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250