Switching Branches Without Committing

Commands discussed in this section:

  • git checkout

Switching Branches: Without Committing

Typically you’d want to first switch to the right branch and then start modifying files in the working directory, right?

But, what if you have been working on some uncommitted changes in your working directory and then decide the uncommitted changes you’ve been working on actually belong on a different branch? If you switch branches with git checkout to a branch with different contents than the working directory, what should git do? Some choices git has:

  1. Ignore the uncommitted working directory changes, and set the working directory to the files in the new branch.
  2. Ignore the state of the files in the new branch, and use the working directory files.
  3. Attempt to merge in the changes from the working directory into the files in the new branch.

Git has chosen choice #3: Attempt to merge in the changes from the working directory into the files in the new branch.

Git Checkout Without Committing: WITHOUT A Conflict

Here is an example: let’s start with a new repository with one file, in the default master branch:

$ git init
Initialized empty Git repository ...
$ echo This is the README file. > README
$ git add .
$ git commit -m'Initial commit.'
[master (root-commit) 832b426] initial commit.
 create mode 100644 README

Next we’ll create a new branch, named test. The -b flag will cause the git to set the current branch to test after it is created:

$ git checkout -b test
$ ls
README

As you can see above, the README file has been carried along the working directory in the new test branch. While we are in the test branch, we’ll append a line to the README file:

$ echo This line was added in the working directory while in the test branch. >> README
$ cat README
This is the README file.
This line was added in the working directory while in the test branch.

When we switch to the master branch, the working directory is considered “dirty” since the README file has not been added to the index and committed. As a result, git will attempt to merge the contents of README from the test branch into the README file in the master branch:

$ git checkout master
M   README
Switched to branch 'master'
$ cat README
This is the README file.
This line was added in the working directory while in the test branch.

The M in the “M README” line above is telling you that the README file has been Merged into the master branch.

Git checkout without committing: WITH a conflict

The previous example showed the merge of a file that was uncommitted in an old branch before switching to a new branch where the merge did not have a conflict. It gets a little more exciting when there is a conflict.

Let’s start over with a new example that begins the same as the previous example. However, this time there will be a twist and a conflict.

$ git init
Initialized empty Git repository ...
$ echo This is the README file. > README
$ git add .
$ git commit -m'Initial commit.'
[master (root-commit) 832b426] initial commit.
 create mode 100644 README

Now we divert from the previous example as we:

  • Create the test branch.
  • The test branch will have the current version of the README file with the 1 line.
  • While still on the master branch, we add another line to README and commit that to the master branch.
$ git branch test

          [We're still on the master branch]

$ echo Second line added from the master branch. >> README
$ git commit -a -m'Line 2 added'
[master 52360ef] line 2 added
 1 files changed, 1 insertions(+), 0 deletions(-)

Now let’s switch to the test branch and verify the contents of the README file is still from the point where the test branch was created:

$ git checkout test
$ ls
README
$ cat README
This is the README file.

Now we add a different (and conflicting) line to the README file on the test branch:

$ echo A conflicted line added while on the test branch. >> README
$ git checkout master
error: You have local changes to 'README'; cannot switch branches.

This time we will use the -m option to git checkout, which tells git to merge in any conflicts, before switching branches:

$ git checkout -m master
M   README
Switched to branch 'master'
$ cat README
This is the README file.
<<<<<<< master
Second line added from the 'master' branch.
=======
A conflicted line added on the test branch.
>>>>>>> local
$ git branch
* master
  test

At this point you can edit the README file, decide what its contents should be, then commit the change.

Next: Merging Branches: Without A Conflict
Previous: Temporarily Stashing Your Work

Related:

Translation