I was uncomfortable with git until I read (the first 3 chapters of) the pro git book ( free here : https://git-scm.com/book/en/v2 ). It provides a great mental model of how git works under the hood. The UI of git - for better or worse - directly reflects its internals. And when I understood them, everything clicked into place.
bad_username
> scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze
`git rebase --abort` exists. One can also set a tag or something before doing the rebase, do whatever, then `git reset --hard $set_tag` to go back. Nothing to be scared of. Not like the prior state is lost.
jolmg
I don’t consider myself a coder or programmer, but learning git was like an organizational superpower for my particular brain wiring. I use it for websites, design projects, electronics engineering, music composition, personal knowledge bases, remote administration scripts, config management, snippets, so many applications and so many features for one system. It’s not always perfect, but I tell everyone I work with they should learn it.
nativeit
I've been theoretically a big fan of these commands; I use the `jj` equivalents all the time. The roadblock I've run into is that I as far as I can tell (from the man pages and the git source code) there's no way to get `git history` commands to sign commits they modify:
$ git log --oneline --show-signature # look ma, I signed my commits!
3a1dd8f gpg: Signature made Mon 13 Jul 2026 10:45:50 PM CDT
gpg: using RSA key FBF32CDBCC134B44FD29B66FA851D929D52FB93F
gpg: issuer "chandler@chandlerswift.com"
gpg: Good signature from "Chandler Swift <chandler@chandlerswift.com>" [ultimate]
Second commit
03c3f6e gpg: Signature made Mon 13 Jul 2026 10:45:16 PM CDT
gpg: using RSA key FBF32CDBCC134B44FD29B66FA851D929D52FB93F
gpg: issuer "chandler@chandlerswift.com"
gpg: Good signature from "Chandler Swift <chandler@chandlerswift.com>" [ultimate]
Initial commit
$ git history reword HEAD~
$ git log --oneline --show-signature # oops! where'd they go?
5662b2c (HEAD -> main) Second commit
6bf6830 Initial commit amended
This has pushed me back to the time-honored `git rebase -i` since I do want to keep my commits signed.
chandlerswift
I've been doing regular significant re-writes to my local Git commit history with relative ease for over a decade even without this new Git command.
I'm convinced that a big part of people often finding Git and rebase difficult is a user interface issue, having to know all the correct command line options and having to make your own mental model of what's happening and what you want to do, all makes it difficult to get a firm grasp on things.
I can't comment on what equivalent alternatives (especially on macOS/Linux as I'm a Windows user), but in terms of a UI for Git which exposes enormous power in an easy-to-use way I've found TortoiseGit to be spectacular and I especially like its rebase dialog:
Which you kick off from a context menu option from the commit line on the commit log you want to rebase onto with a simply named "Rebase <current reference> onto this" option:
It's super easy to re-order, split, combine, edit commits from here and it's obvious that will happen. If for whatever reason you decide you want to back out midway, you just abort and you're back to where you were.
I will concede there are aspects of a TortoiseGit I find a bit annoying, particularly that I feel I have to click around too much, instead of a shell extension I would prefer an app you launch with tabs or something, but I think this is a fundamental design principle of TortoiseGit, which followed the same principle as TortoiseSVN.
There is Git Extensions for Windows which seems nice at a glance, I tried it briefly, but I think I didn't stick with it either due to being unable to find an option I regularly used or I was just so used to TortoiseGit already.
jonathanlydall
In short, newer versions of git implemented three really frequent use cases of `git rebase --interactive` as separate lower-friction commands. Apparently they only work when there are no conflicts.
nine_k
I don't get all the effort people spend in perfectly curating git history. No one is ever going back and reading individual commits. Just squash everything before merging and call it a day.
paxys
> `git history fixup` fixes an old commit that has something wrong in it, then autorebases all your branches to match.
Simplifying `git rebase -i` is a great idea, but unfortunately, that does not match my workflow.
I always keep an history of my branches. For example, when I develop a feature, the first version of the branch is `myfeature.1`, then `myfeature.2`, and so on. This is useful because I can retrieve an old version when something behaves differently in a newer one. (And no, `git reflog` will not help)
This has saved me multiple times. For example, I can determine that a problem was introduced between `myfeature.58` and `myfeature.59`. If the "feature" contains 15 commits, I do:
This lets me see the changes between the 2 versions, commit by commit (even if they don't have the same base).
I don't want all the branches containing a commit to be rebased automatically (I already try using tags for old versions instead, but this does not quite fit).
rom1v
> That last part goes further than git rebase --update-refs, which only moves refs sitting inside the range you’re actively rebasing. git history instead finds and rewrites every local branch descended from the commit (while also having an option to limit it to only the current branch).
I'm reading that to mean that when I use `git rebase --update-refs` in this situation, where I've currently checked out `D` and update `B` to `B'`:
A ──► B ──► C ──► D
│
└───► E
I'll end up with this state, where `E` remains untouched?
A ──► B' ─► C' ─► D'
│
└───► B ──► E
(EDIT: Originally I had `E` point to `B'`, which doesn't make sense)
If I use `git history fixup`, it would also update `E` and end up with this?
A ──► B' ─► C' ─► D'
│
└───► E'
If that's the case, is there a way to get `git rebase` to have the same behavior? I've got decades of `git rebase` burned into my fingers at this point.
shepmaster
`git history split` is really going to help me help juniors break up their large PRs into smaller more concise changes. If only it had the option to split an entire branch in two easily.
comments (10)
bad_username
`git rebase --abort` exists. One can also set a tag or something before doing the rebase, do whatever, then `git reset --hard $set_tag` to go back. Nothing to be scared of. Not like the prior state is lost.
jolmg
nativeit
chandlerswift
I'm convinced that a big part of people often finding Git and rebase difficult is a user interface issue, having to know all the correct command line options and having to make your own mental model of what's happening and what you want to do, all makes it difficult to get a firm grasp on things.
I can't comment on what equivalent alternatives (especially on macOS/Linux as I'm a Windows user), but in terms of a UI for Git which exposes enormous power in an easy-to-use way I've found TortoiseGit to be spectacular and I especially like its rebase dialog:
https://tortoisegit.org/docs/tortoisegit/tgit-dug-rebase.htm...
Which you kick off from a context menu option from the commit line on the commit log you want to rebase onto with a simply named "Rebase <current reference> onto this" option:
https://tortoisegit.org/docs/tortoisegit/tgit-dug-showlog.ht...
It's super easy to re-order, split, combine, edit commits from here and it's obvious that will happen. If for whatever reason you decide you want to back out midway, you just abort and you're back to where you were.
I will concede there are aspects of a TortoiseGit I find a bit annoying, particularly that I feel I have to click around too much, instead of a shell extension I would prefer an app you launch with tabs or something, but I think this is a fundamental design principle of TortoiseGit, which followed the same principle as TortoiseSVN.
There is Git Extensions for Windows which seems nice at a glance, I tried it briefly, but I think I didn't stick with it either due to being unable to find an option I regularly used or I was just so used to TortoiseGit already.
jonathanlydall
nine_k
paxys
Simplifying `git rebase -i` is a great idea, but unfortunately, that does not match my workflow.
I always keep an history of my branches. For example, when I develop a feature, the first version of the branch is `myfeature.1`, then `myfeature.2`, and so on. This is useful because I can retrieve an old version when something behaves differently in a newer one. (And no, `git reflog` will not help)
This has saved me multiple times. For example, I can determine that a problem was introduced between `myfeature.58` and `myfeature.59`. If the "feature" contains 15 commits, I do:
This lets me see the changes between the 2 versions, commit by commit (even if they don't have the same base).I don't want all the branches containing a commit to be rebased automatically (I already try using tags for old versions instead, but this does not quite fit).
rom1v
I'm reading that to mean that when I use `git rebase --update-refs` in this situation, where I've currently checked out `D` and update `B` to `B'`:
I'll end up with this state, where `E` remains untouched? (EDIT: Originally I had `E` point to `B'`, which doesn't make sense)If I use `git history fixup`, it would also update `E` and end up with this?
If that's the case, is there a way to get `git rebase` to have the same behavior? I've got decades of `git rebase` burned into my fingers at this point.shepmaster
paularmstrong