+Let's assume we are happy with the changes and we want to include them
+into our master branch. To do this we simply run "git merge origin":
+
+ $ git merge origin
+ Updating a1a0e8b..3c54ac6
+ Fast forward
+ hello.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+Again, you'll see that this precisely matches the final portion of the
+output from "git pull". Using "git fetch" and "git merge" let us
+achieve exactly what "git pull" did, but we were able to stop in the
+middle to examine the situation, (and we could have decided to reject
+the changes and not merge them---leaving our master branch unchanged).
+
+##### On merges and "fast forward"
+
+You'll notice that we've been seeing the phrase "fast forward" several
+times. This is a special-case operation performed by "git merge" where
+a branch can be advanced along a linear sequence. This happens
+whenever you pull changes that build directly on top of the same
+commit you have as your most recent commit. In other words, there was
+never any divergence or simultaneous commits created in parallel in
+multiple repositories. If there had been parallel commits, then "git
+merge" would actually introduce a new merge commit to tie the two
+commits together.
+
+When a non-fast-forward merge occurs, there is always the possibility
+that a conflict occurs. In this case, "git merge" will leave conflict
+markers in the files and instruct you to resolve the conflicts. When
+you are finished, you would issue a "git commit -a" to create the
+merge commit.
+
+#### 2.8.3 Using "git remote" to pull changes other repositories
+
+We've already described how "git pull" will pull in changes from the
+repository which was the origin of the clone operation. Git also
+provides excellent support for pulling changes from any other
+repository as well, (distributed, rather than centralized
+development).
+
+If you have a situation where you want to pull a single time from some
+repository, then you can simply give the path or URL of the repository
+on the "git pull" command line. However, it's often the case that if
+you want to pull changes from a repository once, you'll want to pull
+changes from that same repository again in the future. This is where
+the "git remote" notion is extremely useful---it allows you to
+associate simple names, (and behaviors), with remote repository URLs
+
+We've already seen one instance of "git remote" which is the creation
+of the "origin" remote which happens automatically during "git
+clone". Let's now create another. Let's assume you are going to be
+working in the hello-remote repository and you'd like to pull changes
+from the hello-pull repository, where your friend "fred" has been
+making changes. Here's how to setup the new remote:
+
+ $ cd ../hello-remote
+ $ git remote add fred ../hello-pull
+
+So that's a "git remote add" command line followed by an arbitrary
+name you'd like for the new remote (fred) and the URL of the remote
+(../hello-pull). Obviously, the URL could be a git:// URL or any other
+git-supported URL in addition to a local path.
+
+The "git remote" command is really just a helper for adding some
+entries to the .git/config file. You might find it more convenient to
+edit that file directly once you get comfortable with things.
+
+At this point the name "fred" will work much like the name "origin"
+has worked in previous examples. For example, we can fetch the changes
+fred has made with "git fetch fred":
+
+ $ git fetch fred
+ remote: Generating pack...
+ Unpacking 3 objects...
+ remote: Done counting 5 objects.
+ Result has 3 objects.
+ Deltifying 3 objects...
+ 100% remote: (3/3) done
+ Total 3 (delta 1), reused 0 (delta 0)
+ 100% (3/3) done
+ * refs/remotes/fred/master: storing branch 'master' of ../hello-pull
+ commit: 3c54ac6
+
+Notice that this command-line only differs from the "git fetch" we did
+previously by explicitly naming which remote should be fetched. We
+could have explicitly said "git fetch origin" earlier.
+
+We can also list all known remote-tracking branches with "git branch
+-r":
+
+ $ git branch -r
+ fred/master
+ origin/HEAD
+ origin/master
+
+These remote-tracking branches make it very easy to collaborate with
+people as they are working on experimental features not yet ready for
+upstream inclusion. For example, if fred's latest code is still
+trashing filesystems then he might not want to push it out the the
+project's primary repository. But he may still want my help with
+it. So he can push it to a branch in his own repository for which I've
+got a remote. Then on my next "git fetch fred" I might notice a new
+branch called fred/trashes-filesystems and I can examine his code with
+a command such as "git log ..fred/trashed-filesystems".
+
+So lots of side collaboration can go on easily, and people working
+only with the primary repository never even have to see this dangerous
+code. It's distributed development at its finest.
+
+#### 2.8.4 Checking out previous revisions
+
+It's often useful to examine the working-tree state of some specific
+revision other than the tip of some branch. For example, maybe you
+would like to build a particular tagged version, or maybe you'd like
+to test the behavior of the code before a particular change was
+introduced. To do this, use "git checkout" and pass it the name of any
+revision, (with a branch name, a tag name, or any other commit
+identifier). For example, to examine our project before the original
+typo was introduced:
+
+ $ git checkout 0a633bf5
+ Note: moving to "0a633bf5" which isn't a local branch
+ If you want to create a new branch from this checkout, you may do so
+ (now or later) by using -b with the checkout command again. Example:
+ git checkout -b <new_branch_name>
+ HEAD is now at 0a633bf... Create a makefile
+
+The note that git gives us is to indicate that we are checking out a
+non-branch revision. This is perfectly fine if we are just exploring
+history, but if we actually wanted to use this revision as the basis
+for new commits, we would first have to create a new branch name as it
+describes.
+
+If we were to use "git checkout" with a branch name, then that would
+change the current branch, (meaning that any new commits would advance
+that branch pointer).
+
+For now, let's return back to the tip of the master branch by just
+checking it out again:
+
+ $ git checkout master
+ Previous HEAD position was 0a633bf... Create a makefile
+ Switched to branch "master"
+
+#### 2.8.5 Pushing changes to another repository
+
+As an unsurprising parallel to "git pull", git also provides "git
+push" for pushing changes to another repository. Now, generally the
+purpose of pushing to a repository is to have some "collaboration
+point" where potentially multiple people might be pushing or
+pulling. Because there might be multiple people pushing into the
+repository at any point, it wouldn't make sense to have a
+working-directory associated with this repository.
+
+For this, git has the notion of a "bare" repository, which is simply a
+repository with no working directory. Let's create a new bare
+repository and push some changes into it:
+
+ $ cd ..
+ $ mkdir hello-bare
+ $ cd hello-bare
+ $ git --bare init --shared
+
+The --shared option sets up the necessary group file permissions so
+that other users in my group will be able to push into this repository
+as well.
+
+Now lets return to our hello repository and push some changes to this
+new repository. Since this is our very first push into this repository
+we need to tell git which branches to push. The easiest way to do this
+is to use --all to indicate all branches:
+
+ $ cd ../hello
+ $ git push ../hello-bare --all
+ updating 'refs/heads/master'
+ from 0000000000000000000000000000000000000000
+ to 3c54ac672ec1130b36837f1b708054a7a1d402de
+ Generating pack...
+ Done counting 18 objects.
+ Deltifying 18 objects...
+ 100% (18/18) done
+ Writing 18 objects...
+ 100% (18/18) done
+ Total 18 (delta 3), reused 15 (delta 2)
+ Unpacking 18 objects...
+ 100% (18/18) done
+ refs/heads/master: 0000000000000000000000000000000000000000 -> 3c54ac672ec1130b36837f1b708054a7a1d402de
+
+For subsequent pushes we don't need to specify --all as "git push" by
+default pushes all branches that exist in both the local and remote
+repositories. Also, as with pull, instead of explicitly specifying a
+URL, you may also specify a remote to push to. And by default, after
+cloning a repository, "git push" with no other arguments will attempt
+to push back to the same origin repository. As this is often exactly
+what is wanted, you may find that "git push" alone is often exactly
+what you need.