git rebase

Title Text

Title Text

Title Text

GIT MERGE EXAMPLE

MERGE

  • adds an extra commit every time you merge origin/main into your branch
  • attempts to merge everything in one shot, merges can be overwhelming
  • keeps the commits in chronological order
  • history remains in tact

REBASE

  • takes all commits on your current branch and moves them all after the latest origin/master commit
  • does not add an extra commit
  •  
  • changes the history of your commits (timestamp and commit hash changes)

A different way of thinking about rebase

  • Imagine you branched off the main branch and applied all of your commits sequentially immediately afterward the last commit on main. You have now changed the history of your commit which is what rebasing is.
  • You can always abort/cancel a rebase
  • You can rebase as many times are you want

rebase example

rebase mode

  • git rebase --continue (you would run this after you have fixed a conflict staged and want to continue the rebasing process)

  • git rebase --abort (if all else fails, you can always abort)
  • git rebase --skip (will skip your commit)

* you can also recover after you have pushed the rebase using git reflog

INTERACTIVE REBASE

rewrite your history

INTERACTIVE REBASE

  • extremely helpful especially if your branch is polluted with a lot of merge and other unwanted commits.
  • say you made some quick eslint changes (for example), and you want it to be squashed into one commit
  • in this case, you want to do an interactive rebase on the last 2 commits.

INTERACTIVE REBASE

  • in this case, you want to do an interactive rebase on the LAST 2 commits.
  • will replay the last two commits locally and will bring up your default editor for git commit messages
git rebase -i HEAD~2

INTeractive TODO LIST

pick c164cd9 eslint fixes [Chester Rivas]
pick a4c0d8f finished refactoring the thing [Chester Rivas]

# Rebase c164cd9..a4c0d8f onto f0b1ed4 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

USE the FOrce

pick c164cd9 eslint fixes [Chester Rivas]
s a4c0d8f finished refactoring the thing [Chester Rivas]

# Rebase c164cd9..a4c0d8f onto f0b1ed4 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

interactive rebase complete

  • save and quit
  • force push - since you have rewritten the history of your branch you have to do a force push
  • force with lease - using --force will overwrite any changes made by someone else on the branch, to be safe use --force-with-lease

*ideally you want to squash your commits into milestones in your code or any logical order that makes sense to you.

don't rebase master

don't rebase master

  1. the main branch (and other shared branches) used for PRs should continue being merged
  2. shared branches have different authors and the history should be preserved because anyone can branch from a commit at any time
  3. if you rebase on master the commits will change and if someone else branches off, that commit no longer exists

other common mistakes

  1. make sure you have exited out of rebase mode before continuing to work
  2. don't rebase of your local main, always origin/main, that way you're guaranteed to be fetching the latest and origin/main
  3. when it doubt, accept "their" changes from server, you can always re-add your changes later
  4. be careful with dropping (d) commits, you might get rid of something you need
  5. if you have messed up your branch after you've finished rebasing and you want to rebase again, reset your branch to origin.
git reset --hard origin/ARC-0000

quick recap

  • rebase your branches only

  • squash commits to keep the history clear and concise

  • git rebase --abort to exit out of rebase mode

  • use tools like SourceTree to view the commit timeline

  • use WebStorm's merge conflict tools to resolve conflicts

git checkout ARC-000
git rebase origin/master

git push

#######################

# interactive and squashing commits

# last 5 commits locally

git rebase -i HEAD~5

# all commits from the time you branched off to your latest local commit

git rebase -i origin/master

# force push

git push -f

WORKFLOW EXAMPLE

.GITCONFIG

[rebase]
  instructionFormat = %s [%an]

*this will format each line when you run git interactive

Git Rebase

By Chester Rivas

Git Rebase

outlining the benefits of git rebase vs git merge

  • 736