{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Branches\n",
    "\n",
    "If using git is like a time machine, then branches are parallel universes. You can use branches to to try out experiments, to isolate development of features or topics and, as we'll see later, they are used to collaborate with other repositories.\n",
    "\n",
    "In some version control systems branching and (especially) merging are expensive operations. In git they are very easy and fast. In fact branching is just creating an alias to point to a particular commit.\n",
    "\n",
    "## git branch and git checkout\n",
    "\n",
    "We can use the ``git branch`` command to see what branches we have. Initially we just have the one branch, by default called \"master\"\n",
    "\n",
    "```\n",
    "$ git branch\n",
    "* master\n",
    "```\n",
    "\n",
    "We can create a new branch simply by appending the name\n",
    "\n",
    "```\n",
    "$ git branch crazy-idea\n",
    "```\n",
    "\n",
    "Now we have \n",
    "\n",
    "```\n",
    "$ git branch\n",
    "  crazy-idea\n",
    "* master\n",
    "```\n",
    "\n",
    "The asterisk indicates which branch we are currently on. To change the the new branch we use\n",
    "\n",
    "```\n",
    "git checkout crazy-idea\n",
    "```\n",
    "\n",
    "You could also do the last two steps in the one command \n",
    "\n",
    "```\n",
    "git checkout -b crazy-idea\n",
    "```\n",
    "\n",
    "If we add a new file, commit it, then change back to the master branch we see that the new file is no longer in the working directory.\n",
    "\n",
    "If we decide that the branch is not needed we can delete it. If there are commits on that branch git will warn us\n",
    "\n",
    "```\n",
    "$ git branch -d crazy-idea \n",
    "error: The branch 'crazy-idea' is not fully merged.\n",
    "If you are sure you want to delete it, run 'git branch -D crazy-idea'.\n",
    "$ git branch -D crazy-idea\n",
    "Deleted branch crazy-idea (was b85e41a).\n",
    "```\n",
    "\n",
    "## git merge\n",
    "\n",
    "Merging is the partner to branching. Suppose we have finished developemnt on a new feature in a branch and we want the code in the master branch, we do this using ``git merge``\n",
    "\n",
    "First make sure we are on the branch we want to merge in to\n",
    "\n",
    "```\n",
    "$ git checkout master\n",
    "```\n",
    "\n",
    "Then use git merge with the name of the branch we are merging in \n",
    "\n",
    "```\n",
    "$ git merge new-feature \n",
    "Updating f7a92c7..bf7762c\n",
    "Fast-forward\n",
    " new-feature.md | 0\n",
    " 1 file changed, 0 insertions(+), 0 deletions(-)\n",
    " create mode 100644 new-feature.md\n",
    "```\n",
    "\n",
    "We can go ahead and delete the feature branch now. Git won't complain since the changes have been merged.\n",
    "\n",
    "## Merge conflicts\n",
    "\n",
    "When git can automatically figure out how to merge it does, but it is sometimes the case that the same file has different edits in the same place. When this happens it is called a conflict and the output looks like this\n",
    "\n",
    "```\n",
    "$ git merge feature2\n",
    "Auto-merging new-feature.md\n",
    "CONFLICT (content): Merge conflict in new-feature.md\n",
    "Automatic merge failed; fix conflicts and then commit the result.\n",
    "```\n",
    "\n",
    "Git has edited the file mentioned and added markers to draw your attention to where the conflicts are. It looks like\n",
    "\n",
    "```\n",
    "$ cat new-feature.md \n",
    "# Implementing the new feature\n",
    "\n",
    "<<<<<<< HEAD\n",
    "Here's how it looks in master\n",
    "=======\n",
    "Here's how it looks in feature2\n",
    ">>>>>>> feature2\n",
    "```\n",
    "\n",
    "What we need to do now is use a text editor to change the file to the state we want then ``git add`` then ``git commit`` it.\n",
    "\n",
    "If you are doing a lot of merging, say you have become the maintainer or release manager  of a piece of software you should look in to the more sophisticated merge tools which can be configured with ``git mergetool``."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Excercises\n",
    "\n",
    "## Exercise 1\n",
    "\n",
    "Create and use a branch\n",
    "\n",
    "- examine what branches you have\n",
    "\n",
    "```\n",
    "git branch\n",
    "```\n",
    "\n",
    "- create a new branch called experiment1\n",
    "\n",
    "```\n",
    "git branch experiment1\n",
    "```\n",
    "\n",
    "- switch to your branch\n",
    "\n",
    "```\n",
    "git checkout experiment1\n",
    "```\n",
    "\n",
    "- add a new file and commit it  \n",
    "\n",
    "```\n",
    "nano new.md\n",
    "git add new.md\n",
    "git commit -m \"new file containing vital info\"\n",
    "```\n",
    "\n",
    "- switch back to the master branch\n",
    "\n",
    "```\n",
    "git checkout master\n",
    "```\n",
    "\n",
    "- delete the experiment1 branch\n",
    "\n",
    "```\n",
    "git branch -D experiment1\n",
    "```\n",
    "\n",
    "## Exercise 2\n",
    "\n",
    "Merge a feature\n",
    "\n",
    "- create a new branch called feature1 and check it out\n",
    "\n",
    "```\n",
    "git checkout -b feature1\n",
    "```\n",
    "\n",
    "- add a new file and commit it\n",
    "\n",
    "```\n",
    "nano new.md\n",
    "git add new.md\n",
    "git commit -m \"implement the new feature\"\n",
    "```\n",
    "\n",
    "- switch back to the master branch\n",
    "\n",
    "```\n",
    "git checkout master\n",
    "```\n",
    "\n",
    "- merge in your feature branch\n",
    "\n",
    "```\n",
    "git merge feature1\n",
    "```\n",
    "\n",
    "## Exercise 3\n",
    "\n",
    "Create and resolve a merge conflit\n",
    "\n",
    "- Edit the same line in the same file in both the master and feature branches and commit it in both\n",
    "\n",
    "```\n",
    "# on the master branch\n",
    "nano new.md\n",
    "git add new.md\n",
    "git commit -m \"feature work in master\"\n",
    "\n",
    "# on the feature1 branch\n",
    "git checkout feature1\n",
    "nano new.md\n",
    "git add new.md\n",
    "git commit -m \"more feature development\"\n",
    "```\n",
    "\n",
    "- Attempt to merge feature1 in to master\n",
    "\n",
    "```\n",
    "git checkout master\n",
    "git merge feature1\n",
    "```\n",
    "\n",
    "- Resolve the conflict \n",
    "\n",
    "```\n",
    "nano new.md\n",
    "git add new.md\n",
    "git commit -m \"resolved conflict\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
