by zackmorris | 2025-06-22 18:51:02+00:00
This is great! And how did I not know about this? My favorite days are when I learn something new. Even better are when I learn that I was wrong and change my mind to improve my thinking. So meta!

Git notes would be ideal for annotating commits that contain commit hashes used as breadcrumbs to inform the developer (usually me months later) about context around previous work. These hashes might have changed due to a rebase or from using disk space optimization tools that rewrite history like these:

https://rtyley.github.io/bfg-repo-cleaner/

https://github.com/rtyley/bfg-repo-cleaner

https://github.com/newren/git-filter-repo

https://github.com/tiavision/GitRewrite

See also:

https://stackoverflow.com/questions/5613345/how-to-shrink-th...

https://stackoverflow.com/questions/1398919/make-git-consume...

https://stackoverflow.com/questions/2116778/reduce-git-repos...

https://stackoverflow.com/questions/3119850/is-there-a-way-t...

https://stackoverflow.com/questions/38789265/git-delete-some...

https://stackoverflow.com/questions/16057391/git-free-disk-s...

https://stackoverflow.com/questions/31423525/how-to-reduce-d...

https://stackoverflow.com/questions/16854425/compact-reposit...

https://stackoverflow.com/questions/13999191/trimming-huge-g...

https://stackoverflow.com/questions/4515580/how-do-i-remove-...

These methods are all uniquely terrible in various ways. Most likely user error on my part. I need this technique:

1. Choose a range of commit hashes (or hashes before a commit) and remove them. This can be useful when splitting repos, for example on projects that started as backend+frontend where the frontend is being forked off in a new repo and the older backend portion needs to be removed from it for security/privacy.

2. Rebase all branches (including those that crossed the deleted portion) to preserve their structure but start/end as recently as possible. Optionally discard branches that were created and merged entirely within the deleted ported, unless they're the trunk of other branches that merge after the deleted portion.

3. Search for old commit hashes in commit messages and update them to the new hashes while rebasing.

4. Bonus points for updating stashes (or other git features) having any commit hashes in their names. Also for importing/exporting a list of important commit hashes for use in project management, such as updating hashes in comments on kanban boards like Jira.

5. More bonus points for searching for large files (such as app.js or other build artifacts) so that they can be stripped from commits in branches, preferably not on a main trunk like master.

If you followed this far, I could also use a technique that rebases merged branches so that they form a series of D shapes instead of overlapping B shapes (this is useful during git bisect). Ideally this would happen automatically or be enforced via rules on sites like GitHub and GitLab. I always rebase my branches before merging, but others can't be bothered.

https://www.atlassian.com/git/tutorials/merging-vs-rebasing

Where I'm going with this: I git reset and git cherry-pick constantly in my own branches before merging, so that each branch has a clean work history like the trunk. I think of this as quantum committing, because I keep exploring the problem space until I find a solution that collapses (merges) into the history.

The problem is that git GUIs are inadequate for this work. I need to be able to cut/copy/paste commits, drag and drop them for reordering, etc. It should also derive the commit diff needed to make a commit match a branch (or folder) rather than throwing a conflict in my face, so that it operates more like Apple's Time Machine. If I had this app, I could simply select all commits that I wanted to delete, it would ask me "this rewrites history, are you sure?", and then delete them and do the right thing for affected branches. It would also have infinite undo powered by git reflog.

The idea being that commit hashes should not take priority - it's all about the information. We should never be trapped by the state of the repo, because that creates anxiety.

So we're missing a tool to orchestrate git the way that Kubernetes orchestrates Docker.