Git rebase -I is not that scary

(cachebag.sh)

67 points | by vinhnx 9 hours ago

26 comments

  • flyingcircus3 7 hours ago
    After more than a decade of using git, I know that my comfort with rebase, and confidence that I wont make an error I can't undo, comes from knowing that I can always abort. And assuming it wasn't garbage collected, I can always get back to orphaned commits, or the commit before I rebased, as long as I keep their hashes. I can definitely look back on my less confident days as times when I wrongly assumed I was walking a tightrope where screwing up was painful and expensive, and easy to take the wrong path, and abort is the universal solvent to all of that.

    I do still find myself tripping up on whether the next appropriate step is to make a commit or continue the rebase, as that is dependent on if you're in a merge conflict or just editing a commit. But even when I get that wrong, and collapse two commits together, abort saves the day.

    • hetman 5 hours ago
      You don't need to keep their hashes because git keeps them for you. If you realise too late that things went terribly wrong, you can get the pre-rebase hashes with "git reflog". (It can take a little getting used to knowing how to identify them quickly after a rebase but they're there.)
    • janpeuker 1 hour ago
      > as long as I keep their hashes

      that means my hashes or their hashes or them keeping my hashes, I am never sure

      • selckin 1 hour ago
        you can just make a backup copy of .git or your entire project dir. When you get lost, just delete your .git, copy from the backup and try again
        • herywort 18 minutes ago
          Is this a joke? git's whole purpose is to save the history of your project and return to earlier versions when needed
        • delusional 26 minutes ago
          You never need to do that. git-reflog(1) is the most general solution if you will ever need.
  • LunicLynx 53 minutes ago
    One additional thing I would mention ist that: When resolving conflicts never try to solve them for the final result. Consider each conflict without considering how the code will change in a later commit. I’ve seen people die a painful rebase death because of this.
    • chrysoprace 26 minutes ago
      Yeah like the other commenter below mentioned, `rerere` takes a lot of the pain out of layering rebased changes. It's important (IMO) to make sure each commit still contains a logical change and a working system, even with an incremental rebase.
    • formerly_proven 50 minutes ago
      rerere
      • inigyou 19 minutes ago
        this is not a cat on a keyboard. it is the name of a git command that does this.
  • pajko 5 hours ago
    Why isn't the 'edit' command mentioned? It's one of the most useful features. It can be used for splitting commits, for example. Mark the commit you want to split to be edited. The commit replay is going to stop after that commit. Now:

      git reset HEAD^1 (NO --hard!)
      git commit --patch ...
      git rebase --continue
    
    You want to add some pending changes to the previous commit? No problem:

      git commit --patch --amend ...
    
    You want to move the pending changes to future commits?

      git stash
      git rebase --continue
      git stash pop
  • nixpulvis 7 hours ago
    I feel like if you're scared of rebasing, you don't actually understand git.
    • Glyptodon 7 hours ago
      My fear has never been rebasing itself, but that I make some kind of mistake with a random change conflict and don't notice it because it's not tested for directly. But I'm also not sure if that's categorically a git fear. (Edit: related to this, I think this sort of minor "itchy worry" is grounded in how sometimes conceptually simple diffs look messy during conflict resolution.)
      • hetman 5 hours ago
        If all I'm doing with git rebase is reorganising my commits, and I have to deal with conflicts, after I'm done, I always git diff my pre-rebase head with post rebase head commit hash. I can quickly see I've messed something up if the diff isn't empty. For more complex tasks it's best to leave the rearranging until last, but where not possible, the diff is still pretty useful to double check my work.
        • seba_dos1 1 hour ago
          range-diff can be useful for that too.
      • seba_dos1 2 hours ago
        Setting:

            merge.conflictStyle = zdiff3
        
        made most of my fears regarding conflict resolution go away, as it right away gives me the stuff that I used to look for manually to understand the context of the conflict, which was probably the most error prone part of the process.
    • jerf 6 hours ago
      Reflog is, as the article says, the permission to do all kinds of crazy things, including rebasing. Once you realize any committed state is recoverable for a good period of time it really frees you.

      Plus you can always take a note of the commit hash before you do anything crazy. But reflog means you don't have to.

      Git really does have all the features you need. I wouldn't argue with anyone complaining about the UI to get there. But it's all in there somewhere.

    • LAC-Tech 5 hours ago
      Correct on both counts.
    • irishcoffee 7 hours ago
      The part where git needs to be “understood” is the entire problem. “Do one thing and do it well” was the whole mantra, which was completely ignored with the disaster that is git. It’s objectively awful.
      • rcxdude 1 hour ago
        Absolutely everything in computing needs to be 'understood' to be used.
      • seba_dos1 2 hours ago
        What's objectively awful is your incredibly intellectually lazy take and how widespread it is. It's always worth taking a few hours to understand powerful tools that you're going to spend years/decades with, and Git isn't even that hard to grasp when you actually want to learn rather than make excuses for your unwillingness to spend a bit of effort on it.

        Over time I'm becoming more and more convinced that the only major Git's sin (and the reason for its popularity at the same time) is being so easy to use that it can be used for basic things with no understanding whatsoever, so people just cargocult it and call it a day. Then once they accidentally get off the beaten path they are absolutely hopeless against the most trivial issues they're being presented with.

        Git is a tool for manipulating a data structure that is the repository. Using it without understanding that structure is like trying to use a word processor without knowing how to write - and apparently half of the industry is content with only knowing how to put clipart onto the printed page.

      • teaearlgraycold 5 hours ago
        It could be so much better. At the same time, it’s one of the core tools for a developer. You’ll learn it eventually. You’re going to be using version control for decades. I’ve met devs many years into their careers who don’t understand rebase. It’s like going to a metal shop and they’re complaining about the learning curve on their welder and half the tradesmen are still at a novice level.
        • LAC-Tech 4 hours ago
          I still don't know it very well, and it's been well over a decade. I think it's a combination of a few things:

          - I find it uninteresting. My version control needs are very simple.

          - Most teams I have been in use a small subset of it.

          - It's confusing terms and inconsistent cli are huge warning signs to not go down that rabbithole. Today instead of learning Git I read some Tony Hoare, much better.

          I've been at once place where they rebased, and it was awful. Complete waste of time. (great place otherwise though)

          • Hendrikto 1 hour ago
            Give it an hour or two. It is really not that complicated. A little bit of investment will pay huge dividends. Do yourself the favor.
            • LAC-Tech 14 minutes ago
              I could say the same for reading Tony Hoare.
        • rdevilla 4 hours ago
          [dead]
      • LAC-Tech 5 hours ago
        yeah I would really love to see a subset of git with a sane cli. would switch in a heartbeat.
    • avaer 48 minutes ago
      When I interview someone and they are scared of `git rebase -i` it's a huge red flag.

      Git rebase has such foundational data structures and concepts that you couldn't pass a serious college programming course without grokking it.

      The only reason someone would be scared of git rebase is:

        a) they don't know the basics of programming/software engineering
        b) they are not intellectually curious enough to look into how tf the software they use every day works
      
      You probably shouldn't have engineers like that on your team.
      • chrysoprace 19 minutes ago
        I wonder if it's because it opens in the default visual editor (typically vi/vim) and while I'm primarily a (neo)vim user now, it is certainly not the most intuitive editor to get started with without guidance.
      • dtheodor 31 minutes ago
        An interviewer asking me about git rebase is the huge red flag
        • Valodim 16 minutes ago
          Genuine question, why? It seems like a reasonable knowledge check that can be answered in a few sentences.
      • pipes 33 minutes ago
        I'm genuinely unsure why rebase interactive is more scary than rebase
        • bonzini 21 minutes ago
          Yeah I never use non-interactive rebase. Even if I don't need to edit the todo list, reading it gives me a confirmation of what git will do.
  • eviks 16 minutes ago
    > it is very hard to actually lose work here, for three reasons.

    The opposite is true, of course, for example: you move commits arround, start to resolve conflicts, and after a few steps you realize you can't, so when you

    > you can bail out at any time. as aforementioned with git rebase --abort

    Yep, except for all the work you've done resolving the conflict, that's "aborted"

    > the old commits still exist in git’s object database, unreferenced but intact,

    The best UI there is - some hidded data store you're, of course, intimately familiar with, so won't have any trouble getting data out of. Oh, wait, you didn't even know it existed? Tough luck, git gud to avoid data loss!

    > botched rebase is a few minutes of you perusing through the reflog.

    Unless, of course, your not that sharp to remember all the commits from their names and would also like to see the diff contents to connect to your code work. But that's just more minutes extra, not that big of a loss.

    > there’s of course, the low-tech insurance policy: git branch backup-before-rebase

    Finally some sensible advice, one that should be the default backup plan to save userst he trouble of wasting "few minutes" perusing the logs

  • mikemcquaid 2 hours ago
    I’ve used Git for 20 years now and wrote a book about it.

    The biggest mistake most sources make when teaching about history rewriting is omitting these two lessons first:

    - it’s easy to lose uncommitted data in Git and hard to lose committed data

    - given this, learn how to use ‘git reflog’ to see what you’ve done and how to undo/redo it (as this post recommends but, even then, a little too late)

    If you just get in the habit of constant committing and checking reflog: you’ll never lose data.

    (Related lesson from my 10 years employed by GitHub: they almost never do the git gc you’d expect to remove commits so once you push a commit: it’s likely there forever and identifiable by that same hash from anywhere in the fork network. This can be bad/scary so be aware).

  • occz 1 hour ago
    Adopting interactive rebasing along with curating my commits for the benefit of the reviewer has been the best upgrade I've made to my git usage in probably the last five years.
  • koolba 7 hours ago
    That “-I” really needs to be lowercase.
    • zahrevsky 6 hours ago
      Someone should collect all the cases when header capitalization on HN affected meaning
    • Normal_gaussian 7 hours ago
      Yeah I got quite excited that there was somehow a better -i; its almost perfect clickbait
      • dietr1ch 5 hours ago
        I was hoping for a rebase that recalled what your previous base commit of your branch.

        I'm really not fond of having to `git rebase --interactive` just to drop all commits that are "already in master", especially when I forget this silly step and get a borked rebase.

  • maxloh 6 hours ago
    I found the VS Code GitLens extension to be a good abstraction for interactive rebase. It provides a drag-and-drop UI with a dropdown to select actions applied to each commit. That is much easier than editing a text file.

    Here's a GIF I found with Google: https://yogwang.site/2025/cursor-vscode-gitlens-rebase-edito...

  • beebix 1 hour ago
    A young dev who's still ambitious, gotta love it.
  • vorticalbox 1 hour ago
    I used to always have deep dread when having to use git but then I found [0]

    [0] https://ohshitgit.com/

  • TazeTSchnitzel 7 hours ago
    I wish there were a shorthand for

      x git commit --amend --reset-author --no-edit
    
    I use that one very frequently (after a fixup, of course) because I want the author date on amended commits to reflect the last time I edited them, not the first time I committed them.
    • throw-the-towel 7 hours ago
      But you can make your own alias?

        > git config --global alias.whatever_you_want 'commit --amend --reset-author --no-edit'
      
      https://git-scm.com/book/ms/v2/Git-Basics-Git-Aliases
    • whateveracct 5 hours ago
      i edit my commit dates constantly for various reasons

      get ahead at work? split into commits and make it look like multiple days of work

      work on your own IP during work hours? edit the timestamp to be outside work hours (i even have a script for this)

  • conradludgate 4 hours ago
    I should publish it at some point (it's just a simple bash script), but I made a convenient alias `git bisect-rebase` which helps catch up very old branches.

    It isn't particularly fast, but it uses bisect to find the first commit on the target branch that conflicts with your branch, then let's you rebase to that commit. You then repeat the process until you are caught up.

    The idea is that solving one conflict many times is usually quite easy, especially if you know the conflicting commit messages, but solving many conflicts in one go is not so easy. This was inspired by me rebasing a 6 month old branch which refactored a file that happened to have many edits in between.

    • auscompgeek 3 hours ago
      That somewhat sounds like the sort of thing git imerge does.
  • bob1029 5 hours ago
    Rebase is scary if you are conflicting on many items.

    I have a simple rule where if the rebase cannot be solved within a few commit rewrites that I will restart the branch from latest master.

    If you are suffering from really difficult rebase scenarios, it's likely that the senior developers are more at fault than the junior developers. The way you organize work over the codebase has the biggest impact on how things would conflict. If nothing ever does, rebasing is a trivial operation.

    • seba_dos1 1 hour ago
      There's nothing scary about conflicts on cherry-picked commits. It's just sometimes tedious to resolve them one-by-one, and sometimes may just not be worth the effort if it can be done in a better way.
  • KoleSeise1277 6 hours ago
    I still make a throwaway branch before a complicated rebase. It costs nothing and turns the whole operation into a low-stakes edit instead of a leap of faith.
    • russdill 6 hours ago
      Yes, and you can diff the two branches when you are done!
  • jordanboxer 6 hours ago

      git commit —fixup=<commit-id> 
      git rebase -i —autosquash
    
    
    
    This is my best friend
  • BobbyTables2 7 hours ago
    I also thought rebase was scary long ago. It is scary in the sense if one messes something up without realizing and then pushes to master…

    Besides interactive rebase, my other favorite command is “git log —-oneline origin/master..HEAD”

    It shows me exactly where I am…

  • vivzkestrel 5 hours ago
    - i often go back like 5 commits and make changes like this

    - git rebase -i <commit-hash>^

    - select edit

    - git reset --soft HEAD~

    - make some changes

    - git add . && git commit -m "changes"

    - git rebase --continue

    - Am I using git rebase wrong?

    • noam_k 4 hours ago
      I wouldn't say it's wrong.

      My preference, however, is creating a fixup commit and using rebase to squash it into the old one.

      Edit: A sibling comment mentioned "git history fixup" which I'll have to try out.

  • trescenzi 7 hours ago
    Another git command I love using is `git add -p`. I always want to commit in chunks as I go but sometimes I wait to long or realize later I could have broken it up. Being able to select only pieces of a file to add to a specific commit is so great. Editing the chunks manually can be a bit intimidating but since it only stages the change you can always restore the file and try again if the diff doesn't look right after the add.
    • nicoburns 6 hours ago
      That "git add -p" works from the command line is cool, but this is the one git task that I feel is significantly easier using a GUI tool (I use one specifically for this (and viewing diffs) while otherwise mostly using the command line).
      • sodapopcan 6 hours ago
        I used to feel the same, and I still use a TUI tool, but after working with people who always used the CLI for this (who oddly otherwise were big into IDEs) it's actually an oddly really nice experience and not really any faster or slower. In fact, seeing a hunk at a time has this "focusing" affect on thinking about each change.

        Again, though, I still use a visual tool.

      • seba_dos1 1 hour ago
        Yeah, that's what I use the built-in `git gui` for.
  • code_lettuce 7 hours ago
    Big rebase fan here. I find myself using squash the most.
    • Normal_gaussian 7 hours ago

          pick a1b2c3d Add user model
          s e4f5g6h Fix typo in user model
          pick i7j8k9l Add login endpoint
          s m0n1o2p WIP debugging login endpoint
          s feedbee fixed login endpoint
          s deadbee fixed login endpoint
          s adebade fixed login endpoint
          s abcdefg actually fixed login endpoint
      
      Of course, I get reminded about f/fixup every now and then - think "golly, that will save a second or two" and promptly forget.
  • newsicanuse 7 hours ago
    I use rebase so much but it only feels comfortable because I follow a workflow while rebasing.
  • fleventynine 5 hours ago
    I typically work with commit chains of at least 5 commits in various states of code review, so I spend at least 60% of my development time editing an old commit in the middle of a rebase -i.
    • nopurpose 1 hour ago
      You might find `jj` to help you there: all changesets have stable identifier and their content can be updated at any moment in-place.

      TLDR; `jj edit <what_to_edit>; $EDITOR` will update a commit in the middle of the branch

  • dionian 6 hours ago
    sometimes i wish mercurial won, if nothing else for the fact that i found its ux to be more enjoyable. I respect and use git, but never got comfortable with merging. im thankful AI can automate it for me now
  • cmrdporcupine 7 hours ago
    I really love the emacs interactive rebase mode, which comes up by default when you have EDITOR=emacs and do rebase -i.

    I know you can do this from within magit as well but I've never gotten into that workflow.

    • skydhash 7 hours ago
      The nice thing with magit is how easy it is to manipulate hunks and line, truly editing commits with a surgical precision, all with an handful of keybindings.
      • ks6g10 6 hours ago
        Even just rebase fixup a commit that is a few commits below HEAD is just a few chords away. Use it many times a week when working.
  • jauntywundrkind 7 hours ago
    rebase interactive is so great, such a powerful tool.

    it's the one clear tool that i used all the time. moving to jj, it has lots of amazing tools starting with `jj edit` to go change the past safely & conveniently, with much less pain. but i miss the direct powerful data-driven experience of seeing the timeline in a text file, and picking what to do with it. sometimes.

    imo every dev should work to get some competency with git rebase! it's an amazing tool. there's few other systems that give such direct control. it's top layer is, perhaps, the excel of version control?

  • ed_mercer 6 hours ago
    I cannot recall the last time I committed manually, let alone rebase manually. An agent can do it for you faster and without making mistakes.