1. 72
  1.  

  2. 11

    Wow, this is something I’ve wanted constantly for years! I’ve yet to test, but I suppose this project could need some more github stars – for each thing it does better than git rebase -i.

    Killer features to me:

    • Splitting a commit.
    • Ability to rebase without committing the current state (i.e. take away the punishment for committing often).
    • Edit an old commit safely. It’s super easy to accidentally squash two commits, if you ended up not following the steps exactly as it says (committing when you’re not supposed to, or not committing when you’re supposed to, I don’t remember). I like to think I’m a proficient git user, but I’m scared of the edit command.

    I’ve also wished it was possible to rename all commits at once directly in git rebase -i (without rewording each commit separately).

    Lastly, trying to convince my colleagues to rebase their commits wouldn’t be so hard if it was easy.

    1. 5

      See also this (older) article on Auto-squashing Git Commits.

      1. 8

        Great ideas, but doomed to suffer forever living in an obscure github project far outside of the mainstream. I wish more people would consider contributing to upstream git - it’s open source!

        1. 2

          Super cool. When you work in the branch/squash/PR workflow, this sort of tool is invaluable. Awesome work!

          1. 2

            I mean the real problem is needing to rewrite history in the first place. That always felt antithetical to the purpose of a VCS to me. All this nonsense is there purely ‘cause what is useful to write isn’t what is easy to read, and so it adds overhead and mutation and, as the article points out, the chance of getting your repo wedged into a weird state. Maybe separate “commits” from “changes”, which are just logical groupings of one or more commits that belong together?

            1. 12

              Drafts are not history. You can rewrite drafts, even shared drafts. Once it goes into master or on a tagged release, or whatever other criterion you want, it becomes history.

              Rewrite drafts all you want. Don’t rewrite history.

              1. 5

                Then I’d say our tools need better support for drafting, ’cause my butt clenches a little every time I have to type git push --force.

                1. 5

                  Does using git push --force-with-lease alleviate the clench?

                  Last I checked, the version of Git my distro has gifted me with, doesn’t have an option to make it the default push behavior. I just spell it out, but it really ahould be the default, for whatever it helps.

                  1. 3

                    Yeah, Mercurial Evolve is one such better tool. I just wish more people knew about it.

              2. 1

                I like it! One my pet peeves when working with fixup! commits is that I usually have multiple fixups commits on the branch before a PR is approved for instance and now I need to keep in mind how many fixup commits I had on the branch so that I can skip them over with --fixup=HEAD^3. I made an alias for automating this, but I wonder if this tool could be improved to automatically find the most recent non-fixup commit on the branch:

                last-non-fixup = !"git log --format=\"%s %h\" | awk '/^fixup!/ { next; } { print $(NF); exit}'"                                                                                                                                     
                fixup = !"git commit -s --fixup=$(git last-non-fixup)"
                

                (Of course, this bugs out when I don’t have any fixups commits on the branch :) )

                1. 1

                  I solved this by assuming that every branch is off the base branch in the repo, and where it isn’t I set a config in my repo to tell my tooling what the base branch for that particular feature branch is.

                  When I want to rebase a feature branch on it’s original base branch I just run

                  git rebase $(git config --default refs/remotes/origin/HEAD --get "branch.$(git current-branch).base")
                  

                  And to override the base branch from origin/HEAD for a particular feature branch, I configure it with

                  git checkout feature-branch
                  git config --add "branch.$(git current-branch).base" "refs/heads/accidentally_long_lived_branch"
                  
                  1. 1

                    I almost always use git commit --fixup :/beginningofcommitmessage.

                    1. 1

                      Well, the problem with that is that I need to remember and type it. Not a big deal, indeed, but it’s nice to automate it away.

                  2. 1

                    It triggers rebuilds! Because rebase touches the file tree, some build systems (like gecko’s recursive-make backend) rebuild unnecessarially.

                    Oh that’s why the Firefox build has been doing that!!