You better get it right, or otherwise you get to nuke the whole repository.
You better get it right, or otherwise you get to nuke the whole repository.
`git reflog` contains a full history of all refs you’ve been on in chronological order. Unless you explicitly delete them, dangling refs are not cleaned up immediately. If you rewrite history and realise you made a mistake, you can likely recover by simply resetting the mutated branch to something from the reflog, even days or weeks afterwards (the default reflog retention is 30 days).
The `tmp` command creates a commit of all changes, branches it, then rolls back the commit.
[1] https://github.com/flurdy/dotfiles/blob/master/.config/fish/...
Start another branch at the point where you want to rewrite history; don't switch to it: `git branch original-history-branch`.
Now `git rebase` your branch to your heart's content. This branch will have the new, rewritten history.
The original-history-branch still has your old history, refers to your old commits and prevents them from being garbage-collected, just in case you'd like to reset your target branch to that state.
That is to say - sure, it can work, but automated history tracking is far superior.
Though, git does at least have reflog, so if you accidentally delete or overwrite a branch, you should be able to get it back. That’s far better than the equivalent situation with files on a filesystem. But it’s still not real history tracking.
Git keeps a version for you while you are doing a rebase, so you can say `git rebase --abort` and get back to the preserved state. But it does not keep a log of these, and, more importantly, does not ask you whether you are glad with the end result: you cannot --abort right after a rebase completed without conflicts. One would say that you should explicitly do something like `git rebase commit` (or `git merge commit`) after you have reviewed the result.
Another approach (which might not be git anymore, but close enough to talk about in git nomenclature) might be some kind of facade layer for the history where you fix wrong comments, bundle up old commits to linear groups and so on. A commit hash would still reference a code state, but the repository state (code and its revised history presentation) would be something like "g123abc as seen by g345fed", usually "g123abc as seen by branch/HEAD", perhaps width some clever defaults like "head of whatever branch has the most recent commit on top of g123abc"
If you do a big force push on a remote repository you could keep the old stuff in a tag or a branch.
IMO "easy to break but easy to fix" is better than "hard to break but impossible to fix", and there ain't no such thing as "hard to break" after enough time passes.
You can find the "old" commits using "git reflog".
I've fixed a lot of botched rebases with that :)
It takes so much of the guess-work out of build tools, CI, etc.
I say stuff it!