Embed Notice
HTML Code
Corresponding Notice
- Embed this notice
Amolith (amolith@nixnet.social)'s status on Saturday, 12-Aug-2023 00:53:23 JSTAmolith 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 merkle tree
https://en.wikipedia.org/wiki/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 containing 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 of 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.
I hope this helps :neofox_heart: