Squash my last X commits together using Git

前端 未结 30 3378
醉酒成梦
醉酒成梦 2020-11-21 05:17

How can I squash my last X commits together into one commit using Git?

相关标签:
30条回答
  • 2020-11-21 05:48

    I recommend avoiding git reset when possible -- especially for Git-novices. Unless you really need to automate a process based on a number of commits, there is a less exotic way...

    1. Put the to-be-squashed commits on a working branch (if they aren't already) -- use gitk for this
    2. Check out the target branch (e.g. 'master')
    3. git merge --squash (working branch name)
    4. git commit

    The commit message will be prepopulated based on the squash.

    0 讨论(0)
  • 2020-11-21 05:49

    Based on this article I found this method easier for my usecase.

    My 'dev' branch was ahead of 'origin/dev' by 96 commits (so these commits were not pushed to the remote yet).

    I wanted to squash these commits into one before pushing the change. I prefere to reset the branch to the state of 'origin/dev' (this will leave all changes from the 96 commits unstaged) and then commit the changes at once:

    git reset origin/dev
    git add --all
    git commit -m 'my commit message'
    
    0 讨论(0)
  • 2020-11-21 05:50

    2020 Simple solution without rebase :

    git reset --soft HEAD~2

    git commit -m "new commit message"

    git push -f

    2 means the last two commits will be squashed. You can replace it by any number

    0 讨论(0)
  • 2020-11-21 05:50

    In the branch you would like to combine the commits on, run:

    git rebase -i HEAD~(n number of commits back to review)
    

    example:

    git rebase -i HEAD~1
    

    This will open the text editor and you must switch the 'pick' in front of each commit with 'squash' if you would like these commits to be merged together. From documentation:

    p, pick = use commit

    s, squash = use commit, but meld into previous commit

    For example, if you are looking to merge all the commits into one, the 'pick' is the first commit you made and all future ones (placed below the first) should be set to 'squash'. If using vim, use :x in insert mode to save and exit the editor.

    Then to continue the rebase:

    git rebase --continue
    

    For more on this and other ways to rewrite your commit history see this helpful post

    0 讨论(0)
  • 2020-11-21 05:51

    If you don't care about the commit messages of the in-between commits, you can use

    git reset --mixed <commit-hash-into-which-you-want-to-squash>
    git commit -a --amend
    
    0 讨论(0)
  • 2020-11-21 05:51

    In addition to other excellent answers, I'd like to add how git rebase -i always confuses me with the commit order - older to newer one or vice versa? So this is my workflow:

    1. git rebase -i HEAD~[N] , where N is the number of commits I want to join, starting from the most recent one. So git rebase -i HEAD~5 would mean "squash the last 5 commits into a new one";
    2. the editor pops up, showing the list of commits I want to merge. Now they are displayed in reverse order: the older commit is on top. Mark as "squash" or "s" all the commits in there except the first/older one: it will be used as a starting point. Save and close the editor;
    3. the editor pops up again with a default message for the new commit: change it to your needs, save and close. Squash completed!

    Sources & additional reads: #1, #2.

    0 讨论(0)
提交回复
热议问题