<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" /> <title></title> <meta name="author" content="James Blackwell <jblack@gnuarch.org>" /> <style type="text/css"> /* :Author: David Goodger (goodger@python.org) :Id: $Id: html4css1.css 5196 2007-06-03 20:25:28Z wiemann $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to customize this style sheet. */ /* used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { border: 0 } table.borderless td, table.borderless th { /* Override padding for "table.docutils td" with "! important". The right padding separates the table cells. */ padding: 0 0.5em 0 0 ! important } .first { /* Override more specific margin styles with "! important". */ margin-top: 0 ! important } .last, .with-subtitle { margin-bottom: 0 ! important } .hidden { display: none } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } /* Uncomment (and remove this text!) to get bold-faced definition list terms dl.docutils dt { font-weight: bold } */ div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title { color: red ; font-weight: bold ; font-family: sans-serif } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } */ div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em ; margin-right: 2em } div.footer, div.header { clear: both; font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin: 0 0 0.5em 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { margin-top: 0.4em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } img.align-left { clear: left } img.align-right { clear: right } ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font-family: serif ; font-size: 100% } pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em } span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.pre { white-space: pre } span.problematic { color: red } span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { border-left: solid 1px gray; margin-left: 1px } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid 1px black; margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; white-space: nowrap ; padding-left: 0 } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } ul.auto-toc { list-style-type: none } </style> </head> <body> <div class="document"> <table class="docinfo" frame="void" rules="none"> <col class="docinfo-name" /> <col class="docinfo-content" /> <tbody valign="top"> <tr class="field"><th class="docinfo-name">title:</th><td class="field-body">Using Arch From an Informal Perspective</td> </tr> <tr class="field"><th class="docinfo-name">license:</th><td class="field-body">General Public License, V2</td> </tr> <tr class="field"><th class="docinfo-name">copyright:</th><td class="field-body"><ol class="first upperalpha simple" start="3"> <li>2004, 2005 Canonical Ltd.</li> </ol> <div class="last system-message"> <p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">../../bazaar-docs/src/FollowingTux.rst</tt>, line 3)</p> Cannot extract compound bibliographic field "copyright".</div> </td> </tr> <tr><th class="docinfo-name">Author:</th> <td>James Blackwell <<a class="reference external" href="mailto:jblack@gnuarch.org">jblack@gnuarch.org</a>></td></tr> <tr class="field"><th class="docinfo-name">contributors:</th><td class="field-body">Bob Finney</td> </tr> <tr class="field"><th class="docinfo-name" colspan="2">original-location:</th></tr> <tr><td> </td><td class="field-body"><a class="reference external" href="mailto:jblack@gnuarch.org--2004/bazaar-docs--initial--1.1">jblack@gnuarch.org--2004/bazaar-docs--initial--1.1</a></td> </tr> </tbody> </table> <p>If you are interested in a project that is already using arch, then consider yourself lucky! You are about to embark on some of the easiest revision control you have ever seen in your life.</p> <p>Before we get started, I am going to define some roles and definitions. We are going to call you, the reader, "jdoe", while we are going to call the developer of the project that you are interested in "Tux". Tux is running a free software project called "fishfarm", which you have recently become interested in. On Tux's website, he has told you the following:</p> <blockquote> <ul class="simple"> <li>He keeps the fishfarm sources in an arch archive</li> <li>The archive's location is at: <a class="reference external" href="http://tux.nd/tux@hackingpenguin.nd--2004">http://tux.nd/tux@hackingpenguin.nd--2004</a></li> <li>He may or may not have told you his archive's name is <a class="reference external" href="mailto:tux@hackingpenguin.nd--2004">tux@hackingpenguin.nd--2004</a></li> <li>That he keeps a configuration file called "fishfarm" in his dists--tux package.</li> </ul> </blockquote> <p>Tux has recently changed his development model. Once upon a time, he released early and frequently. These days, he's only releasing two or three times a year. He's told his users that if they're interested in following development, then they should use arch as well.</p> <p>Ok then. So lets use arch. Before we can use arch, we have to tell arch who we are. Don't worry about getting spammed. This only gets saved locally.</p> <pre class="literal-block"> $ baz my-id "Joe Blow <jblow@isp.com>" </pre> <p>I'm sure that arch is glad to meet you. :) Like many other revision control systems, because you can use an archive, you have to tell arch where to find the archive. We perform this with the register-archive command:</p> <pre class="literal-block"> $ baz register-archive http://tux.nd/tux@hackingpenguin.nd--2004 Registered archive tux@hackingpenguin.nd--2004 </pre> <p>Good job. Now, we have a choice. Now, we could either go ahead and get fishfarm, or we can be nosy and poke around in Tux's archive and see what else he has there. I'll assume you're as nosy as me. :</p> <pre class="literal-block"> $ baz rbrowse tux@hackingpenguin.nd--2004/ tux@hackingpenguin.nd--2004 dists dists--tux dists--tux--1 base-0 .. patch-12 fishfarm fishfarm--dev fishfarm--dev--1.0 base-0 .. patch-221 fishfarm--dev--1.2 base-0 .. patch-34 </pre> <p>Don't be scared of it. What you're seeing here is all the various versions of packages that Tux has. We can see that he has a "dists--tux", and a "fishfarm--dev". In fact, he has two fishfarms; the 1.0 series of fishfarm, and the 1.2 series of fishfarm.</p> <p>That's interesting and all, but how do we see what sort of work he's actually done? That's easy as well. Lets pick a package and a version (what's called a "qualified version"), tack it on to the end of the archive (called the "fully qualified version" and tell rbrowse to show it to us (the -s says to show us the descrption of the patches):</p> <pre class="literal-block"> $ baz rbrowse -s tux@hackingpenguin.nd--2004/fishfarm--dev--1.2 | head -10 tux@hackingpenguin.nd--2004 fishfarm fishfarm--dev fishfarm--dev--1.2 base-0 Initial import patch-1 Taught fishfarm to breed even more herring! patch-2 Reduced the chance for a polar bear attack </pre> <p>Thats kind of neat, but not really anything special. There are, however, neater things we can do with rbrowse. For example, we could have added --patch-regex "snow", and we would have seen all the patches in which Tux talks about snow.</p> <p>I digress. Rather than showing you how to browse archives, I should be showing you how to actually get fishfarm. Well, in this case, its pretty easy, because Tux has set up a "config" branch, which we can use to build a system made out of a bunch of packages (though in this case, he has just one package). First, lets get his package:</p> <pre class="literal-block"> $ baz get tux@hackingpenguin.nd--2004/dists--tux fishfarm [lots of baz output] $ cd fishfarm $ ls configs/ {arch} $ ls configs fishfarm-dev $ baz buildcfg configs/fishfarm-dev [lots of baz output] $ ls configs fishfarm fishfarm-dev $ cd fishfarm </pre> <p>And there you are! You now have a copy of fishfarm for your use and abuse. You can do all the things you're normally accustomed to in a source tree.</p> <p>In the next chapter, we'll cover how to maintain local changes. While you grab some coffee, I'm going to get a smoke. See you in a few.</p> <ol class="arabic simple" start="2"> <li>Maintaining Local changes</li> </ol> <p>Welcome back. When we last met, we covered how to get a working copy of Tux's work. We covered setting up your id, registering Tux's archive, and using buildcfg to grab his code. Today, we'll cover how to track Tux's project with local changes.</p> <p>The first thing that you'll have to do is setup an archive. Setting up an archive requires knowing two things: What the name of the archive is, and where you're going to keep it. An archive name has two parts, the "email component" and the "naming component". In your case, your email address is <a class="reference external" href="mailto:jblow@isp.com">jblow@isp.com</a>, so that will be the email component. For the naming component, we're going to use "fishfarm-2004". Now, we add them together for the whole archive name: <a class="reference external" href="mailto:jblow@isp.com--fishfarm-2004">jblow@isp.com--fishfarm-2004</a>.</p> <p>But where ever shall we save the archives? That depends upon your preference. Traditionally, people will make a ~/{archives} dir, but if you really hate using braces, then ~/archives will do fine.</p> <pre class="literal-block"> $ baz mkdir ~/.archives $ baz make-archive jblow@isp.com--farm-2004 \ /home/jblow/.archives/jblow@isp.com--farm-2004 $ baz my-default-archive jblow@isp.com--farm-2004 </pre> <p>The more observant among you probably noticed that I added an extra command, my-default-archive. This command does exactly what you would think; if we tell arch to get something like "fishfarm--dev", then by default it will go to <a class="reference external" href="mailto:jblow@isp.com--farm-2004">jblow@isp.com--farm-2004</a> to get it first.</p> <p>Congratulations. You now have your own, albeit empty, archive. Don't worry about it being empty; in the very near future we're going to add some new packages, some versions for those packages, and some revisions for that version.</p> <p>In fact, lets create a package now. As I mentioned before, we'd like to localize Tux's packages so that we can hack on them locally. Lets go ahead and do so now:</p> <pre class="literal-block"> $ baz branch tux@hackingpenguin.nd--2004/fishfarm--dev--1.2 \ jblow@isp.com--farm-2004/fishfarm--jblow--1.2 $ echo If you see this then you are paying attention $ baz branch tux@hackingpenguin.nd--2004/dists--tux--1 \ jblow@isp.com--farm-2004/dists--jblow--1 </pre> <p>So, what is a branch? Well, you can almost (but not quite) think of a tag as a sym-link from the last revision of his version (at the time that we do the tag) to the start of our version. From that point on, we can build on that. For example, lets say that tux has 3 revisions in dists--tux--1</p> <pre class="literal-block"> $ baz rbrowse tux@hackingpenguin.nd--2004/dists--tux--1 tux@hackingpenguin.nd--2004 dists dists--tux dists--tux--1 base-0 .. patch-3 </pre> <p>And if you look at your archive, you would see something that looked like this:</p> <pre class="literal-block"> $ baz rbrowse -s jblow@isp.com--farm-2004 dists dists--jblow dists--jblow--1 base-0 tag of tux@hackingpenguin.nd--2004/dists--tux--1--patch-3 fishfarm fishfarm--jblow fishfarm--jblow--1.2 base-0 tag of tux@hackingpenguin.nd--2004/fishfarm--jblow--1.2--patch-34 </pre> <p>So, now that we've tagged off of Tux, how do we hack on it? For example, we'll have to hack the config file to point at our versions rather than his versions:</p> <pre class="literal-block"> $ baz get dists--jblow--1 mydists [lots of baz output] $ cd mydists $ vi configs/fishfarm-dev [change the config to change the config to point to yours instead from: tux@hackingpenguin.nd--2004/fishfarm--dev--1.2 to: jblow@isp.com--farm-2004/fishfarm--jblow--1.2 ] </pre> <p>Now that you've made this change, you still have to commit it to the archive so that it will be there the next time you get. You perform commits with the "baz commit" command. You can get tricky with commit messages by typing something like vi <cite>baz make-log</cite>, but the easiest way to store you changes is with the following:</p> <pre class="literal-block"> $ baz commit -s"Changing the fishfarm config to point to mine instead" [bunches of baz output] </pre> <p>Sure enough, baz figures out the changes since the last time you committed, and stores them in the archive. You can verify it by either getting another copy of the work tree in a different directory, or by running the "baz logs" command:</p> <pre class="literal-block"> $ baz logs -s base-0 tag of tag of tux@hackingpenguin.nd--2004/dists--tux--1--patch-3 patch-1 Changing the fishfarm config to point to mine instead </pre> <p>By now you're probably starting to think "Hey! I could probably have a whole bunch of working trees, but what happens when I commit to one? Won't the rest of them go out of date?" That is absolutely correct. Whenever a working tree gets out of date, you can catch it up by simply typing "baz update". This will cause baz to undo all of the current changes in the working tree, apply all of the missing changesets one by one, and them reapply the missing changesets.</p> <p>This is a pretty powerful thing we've done. Even though Tux doesn't know that we exist, we were able to make a localized fork of his code without giving up on having a revision control system at _our_ beck and call. In the next chapter, things start to get more interesting.</p> <ol class="arabic simple" start="3"> <li>Merging Tux's work back into you</li> </ol> <p>Of course, while you're doing this work, Tux has been busy as well. He's continued to work on his project and add new patches to his archive by committing them. However, your archive doesn't know about them yet, because you haven't merged his changes.</p> <p>There are two main ways that you can catch yourself up to Tux. You can either "baz replay" or "baz merge" with his code. There is a simple rule of thumb that you can use when you're trying to decide whether or not to use replay or merge: If you and Tux have both been working in different areas of the code and if Tux hasn't merged from you, then you can use replay. Otherwise, you'll need to use merge. The differences between replay and merge are too deep and significant to cover here; suffice it to say that while "merge" is a much smarter command, "replay" is capable of providing one with a finer granularity of control.</p> <p>Since Tux has no idea that we even exist at this point, we can safely use replay. The first thing that we have to do is get a clean working copy of our version. As always, we'll perform this step with the "baz get" command. Then, we'll tell baz to try and merge in Tux's latest changes.</p> <pre class="literal-block"> $ baz get dists--jblow--1 mydists $ cd mydists $ baz replay tux@hackingpenguin.nd--2004/dists--tux--1 [ lots of tla output as tla applies Tux's changesets to our code ] </pre> <p>I should mention an important point again: Make sure that when you are merging somebody else's code, that you do so into a <em>clean</em> working copy. Merging local changes and remote changes is a bad idea. Trust me. What will happen is that down the road, the guy that you merged from is going to try to merge from you, and he's going to get a lot of conflicts. The reason for that is that when you sneak your changes into his changeset, when he merges you, he's not going to have any of that local code you snuck in. So just say "No".</p> <p>So where were we? Oh yeah. You had just updated your tree to have Tux's new changes. If you're as flighty as I am, you've probably forgotten how the tree has changed. You can always check the status of how a tree has changed by running the following:</p> <pre class="literal-block"> $ baz status [baz lists what files were added/deleted/modified, etc] </pre> <p>If you want to see how the code actually changed, then a even more useful command is:</p> <blockquote> $ baz diff | less [less pops up, and you're shown a diff between the last commit this working tree knows about and how the working tree actually looks]</blockquote> <p>Once you're happy that the replay is really doing what its supposed to do, including resolving any conflicts that happened during merge, then you can go ahead and commit with something like:</p> <pre class="literal-block"> $ baz commit -L"Merged changes from Tux" </pre> <p>You can do this however often you like. You can not merge him for weeks at a time, or you can do it on a daily basis. Its really up to you.</p> <p>If you're used to the second generation revision control systems, by this point you're probably saying "WOW! I can do that with arch??" Yes, you can, even on a daily basis. But in the next chapter, we're going to hit on some stuff that should knock your socks off... well, maybe not your socks, but at least your shoes.</p> <ol class="arabic simple" start="4"> <li>Sharing your work with others</li> </ol> <p>Ok. Now I'm going to set the way-back machine way-forward.... say six months or so, which works out to about 20 years in Internet time. During this time, You've been working on fishfarm. Tux has been working on fishfarm, and you've been merging him. But something inside of you snaps. You're tired of maintaining your local changes, and you decide its time to sluff off your maintenance work on Tux. I'm sorry. Not sluff... "donate". Yeah. You decide to DONATE your code to Tux. :)</p> <p>The first thing that you have to do in order to donate your work to Tux is to make your archive publicly available. If you're like me, you probably do your work on a laptop. Or perhaps your main work machine is sitting behind NAT of some sort. Maybe you've got some cruddy ISP that only gives you dynamic addresses. If you're particularly unlucky, perhaps all three of them are true. That's fine, because arch can perform a little bit of magic we call mirroring.</p> <p>The idea behind mirroring is that you can take an archive in one place, and make a copy of it elsewhere. You can also update the mirror whenever it suits you. In order to mirror an archive you own remotely, you need to know two pieces of information: 1. The archive name you want to mirror and 2. Where you want to mirror it. You have a few different ways you can mirror and archive: the local filesystem (no good here, because we've already established that you're machine isn't available to the public), ftp (not such a hot idea, because that means your password is going over the 'net in plaintext), WebDAV (provided you A) have a version of arch that can handle SSL and B) can find a place that allows you to upload via WebDAV), and the old favorite standby, sftp (which is a fancy of way of saying "ssh"). In case you can't tell, I heartily recommend ssh.</p> <p>For the sake of describing this easily, I'm going to assume that you have setup password-less ssh on some machine out on the 'net. Who knows; you may have setup an account at sourcecontrol.net so that you could push your archive!</p> <p>The first thing you need to do is to make sure that you can ssh to the machine without having to enter a password. Ok. That's not _really_ required, but if you don't, I don't make any guarantees as to your long term sanity. Usually, the way that you setup ssh for password-less logins goes along the following:</p> <pre class="literal-block"> 1. $ ssh-keygen -t rsa 2. [follow the prompts, hit enter when it asks for the new password] 3. copy ~/.ssh/id_rsa.pub into .ssh/authorized_keys on the server you're trying to ssh to. 4. Make sure that the permissions on .ssh and authorized_keys are very limited. If memory serves, you have to make sure that you have the equivalent of chmod 600 .ssh .ssh/authorized_keys 5. Test to make sure you can ssh in without a password. If not, play with the permissions some more. Generally speaking, if you can't log in without a password, the problem is that either "group" or "other" can either read or write some of your files in .ssh </pre> <p>Now that you have ssh working, I'm going to make the assumption that any file that you put at isp.com/home/jblow/public_html/filename is available via http at <a class="reference external" href="http://isp.com/~jblow/filename">http://isp.com/~jblow/filename</a>. If that's not the case for you, that's fine. Just adjust the instructions accordingly. Notice how I use environment variables to store the various information I need. One useful thing that many archers do is they'll set some useful environment variables in their loginfile (For example, I use $WORKARCH for <a class="reference external" href="mailto:james.blackwell@canonical.com--2004">james.blackwell@canonical.com--2004</a>, and $BOSSWORK for <a class="reference external" href="mailto:robert.collins@canonical.com">robert.collins@canonical.com</a>) ::</p> <pre class="literal-block"> $ export MYARCH=jblow@isp.com--fishfarm-2004 $ export SERVER=sftp://jblow@user.isp.com $ export ARCHDIR=home/jblow/public_html/archives $ baz make-archive -l -m $MYARCH $SERVER/$ARCHDIR/$MYARCH $ baz archive-mirror $MYARCH </pre> <p>And that's it. Your archive should now be publicly available. Whenever you want to update the mirror, just run "baz archive-mirror <a class="reference external" href="mailto:jblow@isp.com--fishfarm-2004">jblow@isp.com--fishfarm-2004</a>".</p> <p>When you tell other people about your public archive, all that you have to tell them is where it is. In your case, you would just tell them "My archive is at <a class="reference external" href="http://user.isp.com/~jblow/archives/jblow@isp.com--fishfarm-2004">http://user.isp.com/~jblow/archives/jblow@isp.com--fishfarm-2004</a>." Arch will be able to figure out the name on its own.</p> <p>Probably now is another time for you to take a short break, because we're going to start diving into stuff thats a little more difficult. So why don't you go grab a snack, kiss the spouse, and come right back, ready to go.</p> <ol class="arabic simple" start="5"> <li>More Advanced Merging</li> </ol> <p>In the last chapter, we covered how to make your archive publicly available. In this chapter, we're actually going to do something useful with that information. Its time for us to come clean and tell Tux that we've been maintaining a localized version of his software. So, we shoot him an email, and in that email, we tell him something along the lines of:</p> <pre class="literal-block"> To: Tux From: jblow Hey Tux, just wanted to let you know that your code r0x0rs! Well, it mostly rocks, cause I had to make a whole bunch of changes. Anyways, I put my archive up at http://user.isp.com/~jblow/archives /jblow@isp.com--fishfarm-2004. You can find my hacks in the fishfarm--jblow--1.2 branch. Keep up the fight, Joe Blow </pre> <p>Tux is going to do one of two things. He's either going to blow you off for six months (You are, after all, Joe 'Blow'), or he's going to dive into your software with both feet so that he can look productive to his users. After all, you've already done lots of hard work for him! Lets assume in this case that it's the latter, so that we don't have to wait six months for you to read the next part of the tutorial.</p> <p>Tux is going to do several things. He's going to register your archive, he's going to merge your work into one of his working copies and, if you're lucky, he's going to commit your work. This would look like this:</p> <pre class="literal-block"> $ baz register-archive http://user.isp.com/~jblow/archives/ Registered archive: jblow@isp.com--fishfarm-2004 $ baz get fishfarm--devo--1.2 replayingjoe [tla output] $ cd replaying $ baz replay jblow@isp.com--fishfarm-2004/fishfarm--jblow--1.2 [lots of tla output] $ baz status [what files changed, etc] $ baz diffs | less $ make && make test [no problems] $ baz commit -s"Now you can have more than one fishfarm (Joe Blow)" </pre> <p>Congratulations! You've just taken your first steps to being a fishfarm developer. Get used to the idea of people yelling at you to work harder, faster, and longer for nothing. :)</p> <p>However, things aren't quite as simple as they were before. Have you ever tried to apply the same patch twice, and gotten conflicts? Well, the same thing will happen with baz replay, because its not quite smart enough to not apply your own patches. It just so happens that there is a --skip-present option to replay, but that's usually not what we want.</p> <p>"Why?" I'm Glad you asked. Its possible that when the other guy made a mistake when he merged you by, not just commiting your patches, but his own chan ges as well. If he does that, then your archive is going to think your patch means one thing, but his archive is going to think that your patch means something different. So when you run "baz replay --skip-present", it won't just skip your patch, but it'll skip his local changes as well. Eventually, you're likely to have a conflict, because the your tree looks slightly different to each one of you.</p> <p>So what should we do? Well, in the next chapters, we're going to cover the merge tool. This tool is a bit smarter, and will let you do things with arch that you just plain can't do with most revision control systems.</p> <ol class="arabic simple" start="6"> <li>No muss, No Fuss, Merge away</li> </ol> <p>In the previous chapter, we realized that replay has some limitations that can really cramp the style of developers, particilarly lazy ones that have a habit of comitting local changes along with merges at the same time.</p> <p>Using the merge tool is essentially as easy as using replay. Tux would do the following:</p> <pre class="literal-block"> $ baz register-archive http://user.isp.com/~jblow/archives/ Registered archive: jblow@isp.com--fishfarm-2004 $ baz get fishfarm--devo--1.2 mergingjoe [tla output] $ cd mergingjoe $ baz merge jblow@isp.com--fishfarm-2004/fishfarm--jblow--1.2 [lots of tla output] $ baz status [what files changed, etc] $ baz diffs | less $ make && make test [no problems] $ baz commit -s"Now you can have more than one fishfarm (Joe Blow)" </pre> <p>So, how does merge work? A quick overly simple explanation is that merge does the following:</p> <pre class="literal-block"> 1. baz figures out the last time Tux merged you 2. baz builds a list of changes between when he last merged you and what's current in your archive 3. baz applies those changes to his working tree 4. Tux fixes any rejected code 5. Tux commits the merge </pre> <p>And that's really all there is to it!</p> </div> </body> </html>