epubjs
Version:
Render ePub documents in the browser, across many devices
109 lines (73 loc) • 12.5 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pro Git - professional version control</title>
<meta content="http://www.w3.org/1999/xhtml; charset=utf-8" http-equiv="Content-Type"/>
<link href="stylesheet.css" type="text/css" rel="stylesheet"/>
<style type="text/css">
@page { margin-bottom: 5.000000pt; margin-top: 5.000000pt; }</style>
</head>
<body class="calibre">
<h2 class="calibre4" id="calibre_pb_25">Remote Branches</h2>
<p class="calibre3">Remote branches are references to the state of branches on your remote repositories. They're local branches that you can't move; they're moved automatically whenever you do any network communication. Remote branches act as bookmarks to remind you where the branches on your remote repositories were the last time you connected to them.</p>
<p class="calibre3">They take the form <code class="calibre10">(remote)/(branch)</code>. For instance, if you wanted to see what the <code class="calibre10">master</code> branch on your <code class="calibre10">origin</code> remote looked like as of the last time you communicated with it, you would check the <code class="calibre10">origin/master</code> branch. If you were working on an issue with a partner and they pushed up an <code class="calibre10">iss53</code> branch, you might have your own local <code class="calibre10">iss53</code> branch; but the branch on the server would point to the commit at <code class="calibre10">origin/iss53</code>.</p>
<p class="calibre3">This may be a bit confusing, so let's look at an example. Let's say you have a Git server on your network at <code class="calibre10">git.ourcompany.com</code>. If you clone from this, Git automatically names it <code class="calibre10">origin</code> for you, pulls down all its data, creates a pointer to where its <code class="calibre10">master</code> branch is, and names it <code class="calibre10">origin/master</code> locally; and you can't move it. Git also gives you your own <code class="calibre10">master</code> branch starting at the same place as origin's <code class="calibre10">master</code> branch, so you have something to work from (see Figure 3-22).</p>
<p class="calibre3"><img src="18333fig0322-tn.png" alt="Figure 3-22. A Git clone gives you your own master branch and origin/master pointing to origin's master branch." title="Figure 3-22. A Git clone gives you your own master branch and origin/master pointing to origin's master branch." class="calibre6"/></p>
<p class="calibre3">If you do some work on your local master branch, and, in the meantime, someone else pushes to <code class="calibre10">git.ourcompany.com</code> and updates its master branch, then your histories move forward differently. Also, as long as you stay out of contact with your origin server, your <code class="calibre10">origin/master</code> pointer doesn't move (see Figure 3-23).</p>
<p class="calibre3"><img src="18333fig0323-tn.png" alt="Figure 3-23. Working locally and having someone push to your remote server makes each history move forward differently." title="Figure 3-23. Working locally and having someone push to your remote server makes each history move forward differently." class="calibre6"/></p>
<p class="calibre3">To synchronize your work, you run a <code class="calibre10">git fetch origin</code> command. This command looks up which server origin is (in this case, it's <code class="calibre10">git.ourcompany.com</code>), fetches any data from it that you don't yet have, and updates your local database, moving your <code class="calibre10">origin/master</code> pointer to its new, more up-to-date position (see Figure 3-24).</p>
<p class="calibre3"><img src="18333fig0324-tn.png" alt="Figure 3-24. The git fetch command updates your remote references." title="Figure 3-24. The git fetch command updates your remote references." class="calibre6"/></p>
<p class="calibre3">To demonstrate having multiple remote servers and what remote branches for those remote projects look like, let's assume you have another internal Git server that is used only for development by one of your sprint teams. This server is at <code class="calibre10">git.team1.ourcompany.com</code>. You can add it as a new remote reference to the project you're currently working on by running the <code class="calibre10">git remote add</code> command as we covered in Chapter 2. Name this remote <code class="calibre10">teamone</code>, which will be your shortname for that whole URL (see Figure 3-25).</p>
<p class="calibre3"><img src="18333fig0325-tn.png" alt="Figure 3-25. Adding another server as a remote." title="Figure 3-25. Adding another server as a remote." class="calibre6"/></p>
<p class="calibre3">Now, you can run <code class="calibre10">git fetch teamone</code> to fetch everything server has that you don't have yet. Because that server is a subset of the data your <code class="calibre10">origin</code> server has right now, Git fetches no data but sets a remote branch called <code class="calibre10">teamone/master</code> to point to the commit that <code class="calibre10">teamone</code> has as its <code class="calibre10">master</code> branch (see Figure 3-26).</p>
<p class="calibre3"><img src="18333fig0326-tn.png" alt="Figure 3-26. You get a reference to teamone's master branch position locally." title="Figure 3-26. You get a reference to teamone's master branch position locally." class="calibre6"/></p>
<h3 class="calibre5">Pushing</h3>
<p class="calibre3">When you want to share a branch with the world, you need to push it up to a remote that you have write access to. Your local branches aren't automatically synchronized to the remotes you write to - you have to explicitly push the branches you want to share. That way, you can use private branches for work you don't want to share, and push up only the topic branches you want to collaborate on.</p>
<p class="calibre3">If you have a branch named <code class="calibre10">serverfix</code> that you want to work on with others, you can push it up the same way you pushed your first branch. Run <code class="calibre10">git push (remote) (branch)</code>:</p>
<pre class="calibre9"><code class="calibre10">$ git push origin serverfix
Counting objects: 20, done.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 1.74 KiB, done.
Total 15 (delta 5), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new branch] serverfix -> serverfix
</code></pre>
<p class="calibre3">This is a bit of a shortcut. Git automatically expands the <code class="calibre10">serverfix</code> branchname out to <code class="calibre10">refs/heads/serverfix:refs/heads/serverfix</code>, which means, "Take my serverfix local branch and push it to update the remote's serverfix branch." We'll go over the <code class="calibre10">refs/heads/</code> part in detail in Chapter 9, but you can generally leave it off. You can also do <code class="calibre10">git push origin serverfix:serverfix</code>, which does the same thing - it says, "Take my serverfix and make it the remote's serverfix." You can use this format to push a local branch into a remote branch that is named differently. If you didn't want it to be called <code class="calibre10">serverfix</code> on the remote, you could instead run <code class="calibre10">git push origin serverfix:awesomebranch</code> to push your local <code class="calibre10">serverfix</code> branch to the <code class="calibre10">awesomebranch</code> branch on the remote project.</p>
<p class="calibre3">The next time one of your collaborators fetches from the server, they will get a reference to where the server's version of <code class="calibre10">serverfix</code> is under the remote branch <code class="calibre10">origin/serverfix</code>:</p>
<pre class="calibre9"><code class="calibre10">$ git fetch origin
remote: Counting objects: 20, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (15/15), done.
From git@github.com:schacon/simplegit
* [new branch] serverfix -> origin/serverfix
</code></pre>
<p class="calibre3">It's important to note that when you do a fetch that brings down new remote branches, you don't automatically have local, editable copies of them. In other words, in this case, you don't have a new <code class="calibre10">serverfix</code> branch - you only have an <code class="calibre10">origin/serverfix</code> pointer that you can't modify.</p>
<p class="calibre3">To merge this work into your current working branch, you can run <code class="calibre10">git merge origin/serverfix</code>. If you want your own <code class="calibre10">serverfix</code> branch that you can work on, you can base it off your remote branch:</p>
<pre class="calibre9"><code class="calibre10">$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"
</code></pre>
<p class="calibre3">This gives you a local branch that you can work on that starts where <code class="calibre10">origin/serverfix</code> is.</p>
<h3 class="calibre5">Tracking Branches</h3>
<p class="calibre3">Checking out a local branch from a remote branch automatically creates what is called a <em class="calibre12">tracking branch</em>. Tracking branches are local branches that have a direct relationship to a remote branch. If you're on a tracking branch and type git push, Git automatically knows which server and branch to push to. Also, running <code class="calibre10">git pull</code> while on one of these branches fetches all the remote references and then automatically merges in the corresponding remote branch.</p>
<p class="calibre3">When you clone a repository, it generally automatically creates a <code class="calibre10">master</code> branch that tracks <code class="calibre10">origin/master</code>. That's why <code class="calibre10">git push</code> and <code class="calibre10">git pull</code> work out of the box with no other arguments. However, you can set up other tracking branches if you wish - ones that don't track branches on <code class="calibre10">origin</code> and don't track the <code class="calibre10">master</code> branch. The simple case is the example you just saw, running <code class="calibre10">git checkout -b [branch] [remotename]/[branch]</code>. If you have Git version 1.6.2 or later, you can also use the <code class="calibre10">--track</code> shorthand:</p>
<pre class="calibre9"><code class="calibre10">$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"
</code></pre>
<p class="calibre3">To set up a local branch with a different name than the remote branch, you can easily use the first version with a different local branch name:</p>
<pre class="calibre9"><code class="calibre10">$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "sf"
</code></pre>
<p class="calibre3">Now, your local branch sf will automatically push to and pull from origin/serverfix.</p>
<h3 class="calibre5">Deleting Remote Branches</h3>
<p class="calibre3">Suppose you're done with a remote branch - say, you and your collaborators are finished with a feature and have merged it into your remote's <code class="calibre10">master</code> branch (or whatever branch your stable codeline is in). You can delete a remote branch using the rather obtuse syntax <code class="calibre10">git push [remotename] :[branch]</code>. If you want to delete your <code class="calibre10">serverfix</code> branch from the server, you run the following:</p>
<pre class="calibre9"><code class="calibre10">$ git push origin :serverfix
To git@github.com:schacon/simplegit.git
- [deleted] serverfix
</code></pre>
<p class="calibre3">Boom. No more branch on your server. You may want to dog-ear this page, because you'll need that command, and you'll likely forget the syntax. A way to remember this command is by recalling the <code class="calibre10">git push [remotename] [localbranch]:[remotebranch]</code> syntax that we went over a bit earlier. If you leave off the <code class="calibre10">[localbranch]</code> portion, then you're basically saying, "Take nothing on my side and make it be <code class="calibre10">[remotebranch]</code>."</p>
</body>
</html>