For those who find git difficult to use and don't know a ton about it, understanding its underlying data structure helped me a lot.
A git repo is a Wikipedia>merkle tree.*
Each commit is a node that builds on its predecessor and branches are, well, branches. When you check out a branch and run git log, you're seeing the linear history of that particular branch from the most recent node to the root of the tree, often your “initial commit”. HEAD
is a pointer to whatever node you're currently at; when you git checkout
an old commit, you're moving HEAD
so it points to that older node. When you checkout
main, you're moving HEAD
so it points to whatever node is furthest down that branch.
Removing secrets from a repo is not feasible for large projects because it requires finding the commit introducing that secret and changing it. Because all child commits contain a hash of its parent commit, changing a parent invalidates every single one of its children and grandchildren and great-grandchildren and so on. The parent has changed, so its hash changed, so its child needs to be updated to include the new hash of its parent. That cascades through the rest of the tree. You then have to force-push to your remote because your local tree has wildly diverged from the remote tree; you're telling the remote to throw whatever tree it has away (the one with your secrets) and just accept the tree you're sending it (the one without your secrets). Your local tree and your remote tree are now the same … but your other contributors might have pulled the commit with your secrets. Now their tree is wildly diverged from the remote tree and they have two options: save their work somewhere else, rm -rf
their local repo, and re-clone the new tree or do a git reset <commit preceding the one with secrets>
and git pull
.
git reset <commit>
discards all the nodes on your branch up to and not including <commit>
. It's like pruning a branch that's grown too long; you cut it back then let it re-grow differently.
*Technically, a git tree is a Wikipedia>Directed Acyclic Graph, but I find that more people are already familiar with merkle trees than DAGs, so that analogy is usually easier to follow. Merkle trees and DAGs are similar enough