1

EDIT:

It turned out that it was the editor VIM that is hard to use and not the commands. I am posting a link to, how to exit out of VIM editor for everybody's reference:

How do I exit the Vim editor?


I know this is a pretty newbie question but everywhere I have read tutorials, they just say open in interactive mode, pick this, squash that and then save and exit. I am unable to do any of these things. Can anyone explain in laymen terms, how to proceed about this?

BTW, I am talking in particular about the command, git rebase -i branch and mode looks like this:

enter image description here

Manish Kumar Sharma
  • 12,982
  • 9
  • 58
  • 105
  • *"I am unable to do any of these things."* -- Why not? – axiac Jul 27 '17 at 18:16
  • There is no "Git interactive mode". `git rebase -i` is not completely automatic as other Git commands. It is, in fact, a big recipe (use [`git help rebase`](https://git-scm.com/docs/git-rebase#_splitting_commits) to read it) that allows the user to guide Git during the process. – axiac Jul 27 '17 at 18:18
  • Really good article about it is in the git book (https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) – Qeek Jul 27 '17 at 18:18
  • Read [this answer](https://stackoverflow.com/a/27399649/4265352) that explains how to run interactive rebase using a GUI Git client (the question and the answer are about SourceTree but it works the same for any GUI Git client that offers the "Interactive Rebase" command). – axiac Jul 27 '17 at 18:20
  • @axiac : I tried typing the pick #commit and then squash # commit. But then what? – Manish Kumar Sharma Jul 27 '17 at 18:45
  • First step of the interactive rebase is to edit the plan. Using the command line client (`git rebase -i`) the plan is the text file that opens in your editor. You edit the plan (change the order of commits, mark commits for editing etc) then save the file and close the editor. Git then starts the rebasing according to the plan and stops either when it reaches a point where the plan says to stop (to amend a commit or to edit the commit message when commits are squashed) or when it encounters a conflict. – axiac Jul 27 '17 at 18:55
  • Interactive rebase is an advanced Git command that is not used every day. If you are a beginner you should start with the common operations. Also, reading the [Git book](https://git-scm.com/book/en/v2) could help you understand how it works internally. – axiac Jul 27 '17 at 18:57
  • @axiac : I figured it out. Posted an answer. – Manish Kumar Sharma Jul 27 '17 at 19:32

1 Answers1

1

To squash means combine. With the help of squash you can combine last X commits in your git repo.

Lets understand this through one simple example

  1. Create 4 files fileA, fileB, fileC, fileD in any useless git directory using

    touch fileA fileB fileC fileD

If you check git status you can see these files newly created.

  1. Now add files as follow

    git add fileA
    
    git commit -m "fileA added"
    
    git add fileB
    
    git commit -m "fileB added"
    
    git add fileC
    
    git commit -m "fileC added"
    
    git add fileD
    
    git commit -m "fileD added"
    

If you do git log, you can see commit messages similar to below :

last commit - fileD added

2nd last commit - fileC added

3rd last commit - fileB added

4th last commit - fileA added

Now To squash 2nd , 3rd and 4th last commit. You can do as follow:

git rebase -i HEAD~4

You can see something like this (observe that order reverse compare to git log output):

pick d16e7b5 fileA added

pick 221b175 fileB added

pick 8006a22 fileC added

pick 4fb6454 fileD added

4th last commit is shown at top, then 3rd last and so on.

Our goal is to squash 2nd , 3rd and 4th last commit. For that you can to word pick with squash as follow:

pick d16e7b5 fileA added

squash 221b175 fileB added

squash 8006a22 fileC added

pick 4fb6454 fileD added

Once you save this you can find 2nd, 3rd and 4th last commit will be combined(squashed). In above case you will never need to use squash for d16e7b5 because that is first commit in rebase there is no previous commit you have provided.

git log will show you :

last commit - fileD added

2ns last commit - " FileA added

                FileB added

                FileC added"

I suspect that you must be using squash at first commit that's why it's not working

Note : Following case always give you error if you try in this example.

squash d16e7b5 fileA added

pick 221b175 fileB added

pick 8006a22 fileC added

pick 4fb6454 fileD added

Punit Vara
  • 3,744
  • 1
  • 16
  • 30