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:
Git has chosen choice #3: Attempt to merge in the changes from the working directory into the files in the new branch.
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.
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:
$ 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.