+local repo has two branches ``v1`` and ``v2``. For most examples the
+currently checked out branch is ``v2``. That is, it's assumed you have
+done something like that::
+
+ $ git clone -b v2 http://git.python.org/python.git
+ $ cd python
+ $ git branch v1 origin/v1
+
+The first command clones remote repository into local directory
+`python``, creates a new local branch v2, sets remotes/origin/v2 as
+its upstream remote-tracking branch and checks it out into the working
+directory.
+
+The last command creates a new local branch v1 and sets
+remotes/origin/v1 as its upstream remote-tracking branch.
+
+The same result can be achieved with commands::
+
+ $ git clone -b v1 http://git.python.org/python.git
+ $ cd python
+ $ git checkout --track origin/v2
+
+The last command creates a new local branch v2, sets remotes/origin/v2
+as its upstream remote-tracking branch and checks it out into the
+working directory.
+
+
+Branches and branches
+=====================
+
+Git terminology can be a bit misleading. Take, for example, the term
+"branch". In git it has two meanings. A branch is a directed line of
+commits (possibly with merges). And a branch is a label or a pointer
+assigned to a line of commits. It is important to distinguish when you
+talk about commits and when about their labels. Lines of commits are
+by itself unnamed and are usually only lengthening and merging.
+Labels, on the other hand, can be created, moved, renamed and deleted
+freely.
+
+
+Remote repositories and remote branches
+=======================================
+
+Remote-tracking branches are branches (pointers to commits) in your
+local repository. They are there for you to remember what branches and
+commits have been pulled from and pushed to what remote repos (you can
+pull from and push to many remotes). Remote-tracking branches live
+under ``remotes/$REMOTE`` namespaces, e.g. ``remotes/origin/v2``.
+
+To see the status of remote-tracking branches run::
+
+ $ git branch -rv
+
+To see local and remote-tracking branches (and tags) pointing to
+commits::
+
+ $ git log --decorate
+
+You never do your own development on remote-tracking branches. You
+create a local branch that has a remote branch as upstream and do
+development on that local branch. On push git pushes commits to the
+remote repo and updates remote-tracking branches, on pull git fetches
+commits from the remote repo, updates remote-tracking branches and
+fast-forwards, merges or rebases local branches.
+
+When you do an initial clone like this::
+
+ $ git clone -b v1 http://git.python.org/python.git
+
+git clones remote repository ``http://git.python.org/python.git`` to
+directory ``python``, creates remote-tracking branches, creates a
+local branch ``v1``, configure it to track upstream remotes/origin/v1
+branch and checks out ``v1`` into the working directory.
+
+Updating local and remote-tracking branches
+-------------------------------------------
+
+There is a major difference between
+
+::
+
+ $ git fetch $REMOTE $BRANCH
+
+and
+
+::
+
+ $ git fetch $REMOTE $BRANCH:$BRANCH
+
+The first command fetches commits from the named $BRANCH in the
+$REMOTE repository that are not in your repository and leaves the id
+(the hash) of the head commit in file .git/FETCH_HEAD and updates
+remote-tracking branch.
+
+The second command fetches commits from the named $BRANCH in the
+$REMOTE repository that are not in your repository and updates both
+the local branch $BRANCH and its upstream remote-tracking branch. But
+it refuses to update branches in case of non-fast-forward. And it
+refuses to update the current branch.
+
+The first command is used internally by ``git pull``.
+
+::
+
+ $ git pull $REMOTE $BRANCH
+
+is equivalent to
+
+::
+
+ $ git fetch $REMOTE $BRANCH
+ $ git merge FETCH_HEAD
+
+Certainly, $BRANCH in that case should be your current branch. If you
+want to merge a different branch into your current branch first update
+that non-current branch and then merge::
+
+ $ git fetch origin v1:v1 # Update v1
+ $ git pull --rebase origin v2 # Update the current branch v2 using
+ # rebase instead of merge
+ $ git merge v1
+
+If you have not yet pushed commits on ``v1``, though, the scenario has
+to become a bit more complex. Git refuses to update
+non-fast-forwardable branch, and you don't want to do force-pull
+because that would remove your non-pushed commits and you would need
+to recover. So you want to rebase ``v1`` but you cannot rebase
+non-current branch. Hence, checkout ``v1`` and rebase it before
+merging::
+
+ $ git checkout v1
+ $ git pull --rebase origin v1
+ $ git checkout v2
+ $ git pull --rebase origin v2
+ $ git merge v1
+
+It is possible to configure git to make it fetch/pull a few branches
+or all branches at once, so you can simply run
+
+::
+
+ $ git pull origin
+
+or even
+
+::
+
+ $ git pull
+
+Default remote repository for fetching/pulling is origin. Default set
+of references to fetch is calculated using matching algorithm: git
+fetches all branches having the same name on both ends.
+
+Push
+''''
+
+Pushing is a bit simpler. There is only one command ``push``. When you
+run
+
+::
+
+ $ git push origin v1 v2
+
+git pushes local v1 to remote v1 and local v2 to remote v2. The same
+as::
+
+ $ git push origin v1:v1 v2:v2
+
+Git pushes commits to the remote repo and updates remote-tracking
+branches. Git refuses to push commits that aren't fast-forwardable.
+You can force-push anyway, but please remember - you can force-push to
+your own repositories but don't force-push to public or shared repos.
+If you find git refuses to push commits that aren't fast-forwardable,
+better fetch and merge commits from the remote repo (or rebase your
+commits on top of the fetched commits), then push. Only force-push if
+you know what you do and why you do it. See the section `Commit
+editing and caveats`_ below.
+
+It is possible to configure git to make it push a few branches or all
+branches at once, so you can simply run
+
+::
+
+ $ git push origin
+
+or even
+
+::
+
+ $ git push
+
+Default remote repository for pushing is origin. Default set
+of references to push in git before 2.0 is calculated using matching
+algorithm: git pushes all branches having the same name on both ends.
+Default set of references to push in git 2.0+ is calculated using
+simple algorithm: git pushes the current branch back to its
+@{upstream}.
+
+To configure git before 2.0 to the new behaviour run::
+
+$ git config push.default simple
+
+To configure git 2.0+ to the old behaviour run::
+
+$ git config push.default matching
+
+Git refuses to push a branch if it's the current branch in the remote
+non-bare repository: git refuses to update remote working directory.
+You really should push only to bare repositories. For non-bare
+repositories git prefers pull-based workflow.
+
+When you want to deploy code on a remote host and can only use push
+(because your workstation is behind a firewall and you cannot pull
+from it) you do that in two steps using two repositories: you push
+from the workstation to a bare repo on the remote host, ssh to the
+remote host and pull from the bare repo to a non-bare deployment repo.
+
+Tags
+''''
+
+Git automatically fetches tags that point to commits being fetched
+during fetch/pull. To fetch all tags (and commits they point to) run
+``git fetch --tags origin``. To fetch some specific tags fetch them
+explicitly::
+
+ $ git fetch origin tag $TAG1 tag $TAG2...
+
+For example::
+
+ $ git fetch origin tag 1.4.2 tag 2.1.7
+
+Git doesn't automatically pushes tags. That allows you to have private
+tags (lightweight tags are also private for a repo, they cannot be
+pushed). To push tags list them explicitly::
+
+ $ git push origin tag 1.4.2
+ $ git push origin v1 v2 tag 2.1.7
+
+Don't move tags with ``git tag -f`` or remove tags with ``git tag -d``
+after they have been published.