Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Youtube

Github Stackoverflow Pinterest

Make it appear that you only made one edit before pushing to the team repo


Overview

This is a hands-on tutorial on how to use Git rebase from the command line.

First of all, there is a lot of misunderstanding about rebase.

Randy Fay comments (in 2011): The issue, of course, is “Does it help anybody in the future to see my topic branch and the various garbage commits on it.” The answer, much of the time, is “no”. That’s what serious rebasing is about. The “rebasing” discussed in this tiny article is just about making sure your local changes go on top of what’s already been committed, so you don’t end up with stupid, dangerous, useless merge commits that don’t help anything.

There are several ways to rebase away you extra commit messages into one commit with a cogent message before others see them:

  1. Interactively rebase to squash commits, on command-line, immediately below
  2. Rebasing on GitHub
  3. Rebase in IDEs (Microsoft’s ‘Visual Studio, etc.)

Man page

  1. To see Git’s documentation on the git rebase command:

    
    man git-rebase
    

It says a rebase reapplies commits on top of another base tip.

Interactive Rebase to squash commits

First, click on the video for a 2:29 minute prevew. Then follow the step-by-step instructions to become a pro at making comments a “first-class” citizen of what you put in GitHub.

(Thanks to Contato at RodolfoBandeira.com for the video. It would be a waste of time for me to duplicate the video he created Dec 2016. Thanks, Rodolfo!)

We start by doing a few prepatory steps not shown in the video:

  1. Create an empty folder (whatever name you choose) and cd into it.

    
    mkdir temp3
    cd temp3
    
  2. Initialize an empty Git repository for this exercise:

    
    git init
    
  3. Create an empty file using the touch command:

    
    touch 1.txt
    
  4. Add the file to Git Staging:

    
    git add .
    
  5. Commit:

    
    git commit -m 'add 1.txt'
    

    Your response would have a different commit id than 785d03b:

    [master (root-commit) 785d03b] add 1.txt
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 1.txt
    

    here’s what the video shows:

  6. List files:

    
    ls
    
  7. Create and switch to a new branch:

    
    git checkout -b feature/feature-1
    

    NOTE: A topical branch (or feature branch) is a private branch that you alone are using, and will not be exposed to the public repository.

    Begin steps to create a file in Git repo:

  8. Create an empty file using the touch command:

    
    touch 2.txt
    

    PROTIP: On a command-line terminal, press the cursor up key to retrive a prior command, then cursor left to edit it.

  9. Add the file to Git Staging:

    
    git add .
    
  10. Commit:

    
    git commit -m 'add 2.txt'
    
  11. Repeat the above 3 steps for 3.txt and 4.txt.

  12. See a list of commits made:

    
    git log
    

    If a colon appears at the bottom of the screen, press q to quit.

  13. Initiate Rebasing:

    
    git rebase -i master
    

    You should see a file displayed by your default editor. It should contain a list of commits made:

    pick 07e03c2 add 2.txt
    pick 5a71aa8 add 3.txt
    pick d693749 add 4.txt
     
    # Rebase 785d03b..d693749 onto 785d03b (3 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.
    #
    # Note that empty commits are commented out
    

    NOTE: Commit ids such as “07e03c2” are a stand-in for whatever commit id Git creates for each specific commit.

  14. In all lines under the first line, double-click the “pick” to select it, then type “s”.

    pick 07e03c2 add 2.txt
    s 5a71aa8 add 3.txt
    s d693749 add 4.txt
    

    The comment in the file says such action specifies a squash that melds (combine) content into the commit above it.

    CAUTION: Do not change the commit message text. You can do that in the next screen.

  15. Save the file using the keyboard action for the editor program you’re using.

    Git comes up with another file:

    # This is a combination of 3 commits.
    # This is the 1st commit message:
    add 2.txt
     
    # This is the commit message #2:
     
    add 3.txt
     
    # This is the commit message #3:
     
    add 4.txt
     
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Date:      Tue Apr 25 06:50:34 2017 -0400
    #
    # interactive rebase in progress; onto 785d03b
    # Last commands done (3 commands done):
    #    s 5a71aa8 add 3.txt
    #    s d693749 add 4.txt
    # No commands remaining.
    # You are currently editing a commit while rebasing branch 'feature/feature-1' on '785d03b'.
    #
    # Changes to be committed:
    #	new file:   2.txt
    #	new file:   3.txt
    #	new file:   4.txt
    #
    
  16. Type a comment character # in front of commit comments we don’t want to show to everyone: the “add 3.txt” and “add 4.txt”.

  17. Change the first commit’s message to reflect the combination of commits:

    
    add 2, 3, and 4.txt
    

    (Sorry, I can’t stand omission of the Oxford comma)

  18. Save and exit the file.

  19. See a list of commits to confirm:

    
    git log
    
  20. Retrieve files from master branch:

    
    git checkout master
    

    git rebase on top of …

  21. Initiate Rebasing:

    
    git rebase feature/feature-1
    

    The response should be:

    First, rewinding head to replay your work on top of it...
    Fast-forwarded master to feature/feature-1.   
    

    Delete branch

  22. Delete the feature branch marker that has been used up. This is not in the video, but a good habit.

    
    git branch -d feature/feature-1
    

    Verify with git reflog

  23. See the reference log:

    
    git reflog
    
    daa8535 HEAD@{0}: rebase finished: returning to refs/heads/master
    daa8535 HEAD@{1}: rebase: checkout feature/feature-1
    785d03b HEAD@{2}: checkout: moving from feature/feature-1 to master
    daa8535 HEAD@{3}: rebase -i (finish): returning to refs/heads/feature/feature-1
    daa8535 HEAD@{4}: rebase -i (squash): add 2, 3, and 4.txt
    d3b8645 HEAD@{5}: rebase -i (squash): # This is a combination of 2 commits.
    07e03c2 HEAD@{6}: rebase -i (start): checkout master
    d693749 HEAD@{7}: commit: add 4.txt
    5a71aa8 HEAD@{8}: commit: add 3.txt
    07e03c2 HEAD@{9}: commit: add 2.txt
    785d03b HEAD@{10}: checkout: moving from master to feature/feature-1
    785d03b HEAD@{11}: commit (initial): add 1.txt
    

Rebase on GitHub

github merge pull request menu

These do NOT appear if there are changes to the default checks in Settings:

github-settings-rebase 650x250

Squash in VisualStudio

Squash on SourceTree

Rebase workflow

Early on, in 2007, http://changelog.complete.org/archives/586-rebase-considered-harmful

  • https://randyfay.com/content/rebase-workflow-git

  • http://www.darwinweb.net/articles/the-case-for-git-rebase says:

Rebase is at its essence simply takes a series of commits as if they were individual patches, and applies them at a different point in history.

  • http://unethicalblogger.com/2010/04/02/a-rebase-based-workflow.html

  • http://www.gitready.com/intermediate/2009/01/31/intro-to-rebase.html

  • http://www.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html

  • Rebase vs merge by Mary

More on Git Rebase

* https://git-scm.com/docs/git-rebase is the official documenation

Within a Git QuickStart using GitHub series https://www.youtube.com/watch?v=fbHs-yWoILs Merge/Rebase branches in GIT using visual Studio 7 Feb 2017

More

This is one of a series on Git and GitHub:

  1. Git and GitHub videos

  2. Why Git? (file-based backups vs Git clone)
  3. Git HEAD (Commitish references)
  4. Git-client based workflows
  5. Git whoops (correct mistakes)
  6. Git rebase
  7. Git interactive merge (imerge)
  8. Git commits with a Tag and Signature

  9. Git custom commands
  10. Git utilities
  11. Git hooks

  12. GitHub data security

  13. TFS vs GitHub
  14. GitHub REST API
  15. GitHub GraphQL API
  16. GitHub PowerShell API Programming
  17. GitHub GraphQL PowerShell Module