let's assume that the Mummy
(Dracula and Wolfman's boss)
has already put some notes in a version control repository
- whose URL is <code>https://universal.software-carpentry.org/monsters</code>.
+ whose URL is <code>https://universal.software-carpentry.org/explore</code>.
Every repository has an address like this that uniquely identifies the location of the master copy.
</p>
</p>
<pre>
-$ <span class="in">svn checkout https://universal.software-carpentry.org/monsters</span>
+$ <span class="in">svn checkout https://universal.software-carpentry.org/explore</span>
</pre>
<p class="continue">
- This creates a new directory called <code>monsters</code>
+ This creates a new directory called <code>explore</code>
and fills it with a copy of the repository's contents
(<a href="#f:example_repo">Figure 6</a>).
</p>
<pre>
-<span class="out">A monsters/jupiter
-A monsters/mars
-A monsters/mars/mons-olympus.txt
-A monsters/mars/cydonia.txt
-A monsters/earth
-A monsters/earth/himalayas.txt
-A monsters/earth/antarctica.txt
-A monsters/earth/carlsbad.txt
+<span class="out">A explore/jupiter
+A explore/mars
+A explore/mars/mons-olympus.txt
+A explore/mars/cydonia.txt
+A explore/earth
+A explore/earth/himalayas.txt
+A explore/earth/antarctica.txt
+A explore/earth/carlsbad.txt
Checked out revision 6.</span>
</pre>
</p>
<pre>
-$ <span class="in">cd monsters</span>
+$ <span class="in">cd explore</span>
$ <span class="in">ls</span>
<span class="out">earth jupiter mars</span>
$ <span class="in">ls *</span>
<pre>
$ <span class="in">pwd</span>
-<span class="out">/home/vlad/monsters</span>
+<span class="out">/home/vlad/explore</span>
$ <span class="in">ls -a</span>
<span class="out">. .. .svn earth jupiter mars</span>
$ <span class="in">ls -F .svn</span>
the date the change was made,
and whatever comment the user provided when the change was submitted.
As we can see,
- the <code>monsters</code> project is currently at revision 6,
+ the <code>explore</code> project is currently at revision 6,
and all changes so far have been made by the Mummy.
</p>
</section>
- <section id="s:merge">
+<section id="s:merge">
+ <h2>Merging Conflicts</h2>
- <h2>Merging Conflicts</h2>
-
- <div class="understand" id="u:merge">
- <h3>Understand:</h3>
- <ul>
- <li>What a conflict in an update is.</li>
- <li>How to resolve conflicts when updating.</li>
- </ul>
- </div>
+ <div class="understand">
+ <h3>Learning Objectives:</h3>
+ <ul>
+ <li>Explain what causes conflicts to occur and how to tell when one has occurred.</li>
+ <li>Resolve a conflict.</li>
+ <li>Identify the auxiliary files created when a conflict occurs.</li>
+ </ul>
+ </div>
- <p>
- Dracula and Wolfman have both synchronized their working copies of <code>monsters</code>
- with version 8 of the repository.
- Dracula now edits his copy to change Amalthea's radius
- from a single number to a triple to reflect its irregular shape:
- </p>
+ <p>
+ Dracula and Wolfman have both synchronized their working copies of <code>explore</code>
+ with version 8 of the repository.
+ Dracula now edits his copy to change Amalthea's radius
+ from a single number to a triple to reflect its irregular shape:
+ </p>
<pre src="svn/moons_dracula_triple.txt">
Name Orbital Radius Orbital Period Mass Radius
Callisto 1882.7 16.689018 1075.9 2410.3
</pre>
- <p class="continue">
- He then commits his work,
- creating revision 9 of the repository
- (<a href="#f:after_dracula_commits">Figure XXX</a>).
- </p>
+ <p class="continue">
+ He then commits his work,
+ creating revision 9 of the repository
+ (<a href="#f:after_dracula_commits">Figure 9</a>).
+ </p>
- <figure id="f:after_dracula_commits">
- <img src="svn/after_dracula_commits.png" alt="After Dracula Commits" />
- </figure>
+ <figure id="f:after_dracula_commits">
+ <img src="svn/after_dracula_commits.png" alt="After Dracula Commits" />
+ <figcaption>Figure 9: After Dracula Commits</figcaption>
+ </figure>
- <p>
- But while he is doing this,
- Wolfman is editing <em>his</em> copy
- to add information about two other minor moons,
- Himalia and Elara:
- </p>
+ <p>
+ But while he is doing this,
+ Wolfman is editing <em>his</em> copy
+ to add information about two other minor moons,
+ Himalia and Elara:
+ </p>
<pre src="svn/moons_wolfman_extras.txt">
Name Orbital Radius Orbital Period Mass Radius
Elara 11740 259.6528 0.008 40.0</span>
</pre>
- <p>
- When Wolfman tries to commit his changes to the repository,
- Subversion won't let him:
- </p>
+ <p>
+ When Wolfman tries to commit his changes to the repository,
+ Subversion won't let him:
+ </p>
<pre>
$ <span class="in">svn commit -m "Added data for Himalia, Elara"</span>
svn: resource out of date; try updating</span>
</pre>
- <p class="continue">
- The reason is that
- Wolfman's changes were based on revision 8,
- but the repository is now at revision 9,
- and the file that Wolfman is trying to overwrite
- is different in the later revision.
- (Remember,
- one of version control's main jobs is to make sure that
- people don't trample on each other's work.)
- Wolfman has to update his working copy to get Dracula's changes before he can commit.
- Luckily,
- Dracula edited a line that Wolfman didn't change,
- so Subversion can merge the differences automatically.
- </p>
+ <p class="continue">
+ The reason is that
+ Wolfman's changes were based on revision 8,
+ but the repository is now at revision 9,
+ and the file that Wolfman is trying to overwrite
+ is different in the later revision.
+ (Remember,
+ one of version control's main jobs is to make sure that
+ people don't trample on each other's work.)
+ Wolfman has to update his working copy to get Dracula's changes before he can commit.
+ Luckily,
+ Dracula edited a line that Wolfman didn't change,
+ so Subversion can merge the differences automatically.
+ </p>
- <p>
- This does <em>not</em> mean that Wolfman's changes have been committed to the repository:
- Subversion only does that when it's ordered to.
- Wolfman's changes are still in his working copy,
- and <em>only</em> in his working copy.
- But since Wolfman's version of the file now includes
- the lines that Dracula added,
- Wolfman can go ahead and commit them as usual to create revision 10.
- </p>
+ <p>
+ This does <em>not</em> mean that Wolfman's changes have been committed to the repository:
+ Subversion only does that when it's ordered to.
+ Wolfman's changes are still in his working copy,
+ and <em>only</em> in his working copy.
+ But since Wolfman's version of the file now includes
+ the lines that Dracula added,
+ Wolfman can go ahead and commit them as usual to create revision 10.
+ </p>
- <p>
- Wolfman's working copy is now in sync with the master,
- but Dracula's is one behind at revision 9.
- At this point,
- they independently decide to add measurement units
- to the columns in <code>moons.txt</code>.
- Wolfman is quicker off the mark this time;
- he adds a line to the file:
- </p>
+ <p>
+ Wolfman's working copy is now in sync with the master,
+ but Dracula's is one behind at revision 9.
+ At this point,
+ they independently decide to add measurement units
+ to the columns in <code>moons.txt</code>.
+ Wolfman is quicker off the mark this time;
+ he adds a line to the file:
+ </p>
<pre src="svn/moons_wolfman_units.txt">
Name Orbital Radius Orbital Period Mass Radius
Elara 11740 259.6528 0.008 40.0
</pre>
- <p class="continue">
- and commits it to create revision 11.
- While he is doing this,
- though,
- Dracula inserts a different line at the top of the file:
- </p>
+ <p class="continue">
+ and commits it to create revision 11.
+ While he is doing this,
+ though,
+ Dracula inserts a different line at the top of the file:
+ </p>
<pre src="svn/moons_dracula_units.txt">
Name Orbital Radius Orbital Period Mass Radius
Elara 11740 259.6528 0.008 40.0
</pre>
- <p>
- Once again,
- when Dracula tries to commit,
- Subversion tells him he can't.
- But this time,
- when Dracula does updates his working copy,
- he doesn't just get the line Wolfman added to create revision 11.
- There is an actual conflict in the file,
- so Subversion asks Dracula what he wants to do:
- </p>
+ <p>
+ Once again,
+ when Dracula tries to commit,
+ Subversion tells him he can't.
+ But this time,
+ when Dracula does updates his working copy,
+ he doesn't just get the line Wolfman added to create revision 11.
+ There is an actual conflict in the file,
+ so Subversion asks Dracula what he wants to do:
+ </p>
<pre src="svn/moons_dracula_conflict.txt">
$ <span class="in">svn update</span>
(s) show all options:</span>
</pre>
- <p>
- Dracula choose <code>p</code> for "postpone",
- which tells Subversion that he'll deal with the problem later.
- Once the update is finished,
- he opens <code>moons.txt</code> in his editor and sees:
- </p>
+ <p>
+ Dracula choose <code>p</code> for "postpone",
+ which tells Subversion that he'll deal with the problem later.
+ Once the update is finished,
+ he opens <code>moons.txt</code> in his editor and sees:
+ </p>
<pre>
Name Orbital Radius Orbital Period Mass
Callisto 1882.7 16.689018 1075.9
</pre>
- <p class="continue">
- As we can see,
- Subversion has inserted
- <a href="glossary.html#conflict-marker">conflict markers</a>
- in <code>moons.txt</code>
- wherever there is a conflict.
- The line <code><<<<<<< .mine</code> shows the start of the conflict,
- and is followed by the lines from the local copy of the file.
- The separator <code>=======</code> is then
- followed by the lines from the repository's file that are in conflict with that section,
- while <code>>>>>>>> .r11</code> marks the end of the conflict.
- </p>
+ <p class="continue">
+ As we can see,
+ Subversion has inserted
+ <a href="glossary.html#conflict-marker">conflict markers</a>
+ in <code>moons.txt</code>
+ wherever there is a conflict.
+ The line <code><<<<<<< .mine</code> shows the start of the conflict,
+ and is followed by the lines from the local copy of the file.
+ The separator <code>=======</code> is then
+ followed by the lines from the repository's file that are in conflict with that section,
+ while <code>>>>>>>> .r11</code> marks the end of the conflict.
+ </p>
- <p>
- Before he can commit,
- Dracula has to edit his copy of the file to get rid of those markers.
- He changes it to:
- </p>
+ <p>
+ Before he can commit,
+ Dracula has to edit his copy of the file to get rid of those markers.
+ He changes it to:
+ </p>
<pre src="svn/moons_dracula_resolved.txt">
Name Orbital Radius Orbital Period Mass Radius
Elara 11740 259.6528 0.008 40.0
</pre>
- <p class="continue">
- then uses the <code>svn resolved</code> command to tell Subversion that
- he has fixed the problem.
- Subversion will now let him commit to create revision 12.
- </p>
+ <p class="continue">
+ then uses the <code>svn resolved</code> command to tell Subversion that
+ he has fixed the problem.
+ Subversion will now let him commit to create revision 12.
+ </p>
- <div class="box">
+ <div class="box">
+ <h3>Auxiliary Files</h3>
- <h3>Auxiliary Files</h3>
+ <p>
+ When Dracula did his update and Subversion detected the conflict in <code>moons.txt</code>,
+ it created three temporary files to help Dracula resolve it.
+ The first is called <code>moons.txt.r9</code>;
+ it is the file as it was in Dracula's local copy
+ before he started making changes,
+ i.e., the common ancestor for his work
+ and whatever he is in conflict with.
+ </p>
- <p>
- When Dracula did his update and Subversion detected the conflict in <code>moons.txt</code>,
- it created three temporary files to help Dracula resolve it.
- The first is called <code>moons.txt.r9</code>;
- it is the file as it was in Dracula's local copy
- before he started making changes,
- i.e., the common ancestor for his work
- and whatever he is in conflict with.
- </p>
+ <p>
+ The second file is <code>moons.txt.r11</code>.
+ This is the most up-to-date revision from the repository—the
+ file as it is including Wolfman's changes.
+ The third temporary file, <code>moons.txt.mine</code>,
+ is the file as it was in Dracula's working copy before he did the Subversion update.
+ </p>
- <p>
- The second file is <code>moons.txt.r11</code>.
- This is the most up-to-date revision from the repository—the
- file as it is including Wolfman's changes.
- The third temporary file, <code>moons.txt.mine</code>,
- is the file as it was in Dracula's working copy before he did the Subversion update.
- </p>
+ <p>
+ Subversion creates these auxiliary files primarily
+ to help people merge conflicts in binary files.
+ It wouldn't make sense to insert <code><<<<<<<</code>
+ and <code>>>>>>>></code> characters into an image file
+ (it would almost certainly result in a corrupted image).
+ The <code>svn resolved</code> command deletes these three extra files
+ as well as telling Subversion that the conflict has been taken care of.
+ </p>
- <p>
- Subversion creates these auxiliary files primarily
- to help people merge conflicts in binary files.
- It wouldn't make sense to insert <code><<<<<<<</code>
- and <code>>>>>>>></code> characters into an image file
- (it would almost certainly result in a corrupted image).
- The <code>svn resolved</code> command deletes these three extra files
- as well as telling Subversion that the conflict has been taken care of.
- </p>
+ </div>
- </div>
+ <p>
+ Some power users prefer to work with interpolated conflict markers directly,
+ but for the rest of us,
+ there are several tools for displaying differences and helping to merge them,
+ including <a href="http://diffuse.sourceforge.net/">Diffuse</a> and <a href="http://winmerge.org/">WinMerge</a>.
+ If Dracula launches Diffuse,
+ it displays his file,
+ the common base that he and Wolfman were working from,
+ and Wolfman's file in a three-pane view
+ (<a href="#f:diff_viewer">Figure 10</a>):
+ </p>
- <p>
- Some power users prefer to work with interpolated conflict markers directly,
- but for the rest of us,
- there are several tools for displaying differences and helping to merge them,
- including <a href="http://diffuse.sourceforge.net/">Diffuse</a> and <a href="http://winmerge.org/">WinMerge</a>.
- If Dracula launches Diffuse,
- it displays his file,
- the common base that he and Wolfman were working from,
- and Wolfman's file in a three-pane view
- (<a href="#f:diff_viewer">Figure XXX</a>):
- </p>
+ <figure id="f:diff_viewer">
+ <img src="svn/diff_viewer.png" alt="A Difference Viewer" />
+ <figcaption>Figure 10: A Difference Viewer</figcaption>
+ </figure>
- <figure id="f:diff_viewer">
- <img src="svn/diff_viewer.png" alt="A Difference Viewer" />
- </figure>
+ <p class="continue">
+ Dracula can use the buttons to merge changes from either of the edited versions
+ into the common ancestor,
+ or edit the central pane directly.
+ Again,
+ once he is done,
+ he uses <code>svn resolved</code> and <code>svn commit</code>
+ to create revision 12 of the repository.
+ </p>
- <p class="continue">
- Dracula can use the buttons to merge changes from either of the edited versions
- into the common ancestor,
- or edit the central pane directly.
- Again,
- once he is done,
- he uses <code>svn resolved</code> and <code>svn commit</code>
- to create revision 12 of the repository.
- </p>
+ <p>
+ In this case, the conflict was small and easy to fix.
+ However, if two or more people on a team are repeatedly creating conflicts for one another,
+ it's usually a signal of deeper communication problems:
+ either they aren't talking as often as they should, or their responsibilities overlap.
+ If used properly,
+ the version control system can help the team find and fix these issues
+ so that it will be more productive in future.
+ </p>
- <p>
- In this case, the conflict was small and easy to fix.
- However, if two or more people on a team are repeatedly creating conflicts for one another,
- it's usually a signal of deeper communication problems:
- either they aren't talking as often as they should, or their responsibilities overlap.
- If used properly,
- the version control system can help the team find and fix these issues
- so that it will be more productive in future.
- </p>
+ <div class="box">
+ <h3>Working With Multiple Files</h3>
- <div class="box">
+ <p>
+ As mentioned <a href="#a:transaction">earlier</a>,
+ every logical change to a project should result in a single commit,
+ and every commit should represent one logical change.
+ This is especially true when resolving conflicts:
+ the work done to reconcile one person's changes with another are often complicated,
+ so it should be a single entry in the project's history,
+ with other, later, changes coming after it.
+ </p>
- <h3>Working With Multiple Files</h3>
+ </div>
- <p>
- As mentioned <a href="#a:transaction">earlier</a>,
- every logical change to a project should result in a single commit,
- and every commit should represent one logical change.
- This is especially true when resolving conflicts:
- the work done to reconcile one person's changes with another are often complicated,
- so it should be a single entry in the project's history,
- with other, later, changes coming after it.
- </p>
+ <div class="keypoints">
+ <h3>Summary</h3>
+ <ul>
+ <li>Conflicts must be resolved before a commit can be completed.</li>
+ <li>Subversion puts markers in text files to show regions of conflict.</li>
+ <li>For each conflicted file, Subversion creates auxiliary files containing the common parent, the master version, and the local version.</li>
+ <li><code>svn resolve <em>files</em></code> tells Subversion that conflicts have been resolved.</li>
+ </ul>
+ </div>
- </div>
+ <div class="challenges">
+ <h3>Challenges</h3>
- <div class="keypoints" id="k:merge">
- <h3>Summary</h3>
- <ul>
- <li>Conflicts must be resolved before a commit can be completed.</li>
- <li>Subversion puts markers in text files to show regions of conflict.</li>
- <li>For each conflicted file, Subversion creates auxiliary files containing the common parent, the master version, and the local version.</li>
- <li><code>svn resolve <em>files</em></code> tells Subversion that conflicts have been resolved.</li>
- </ul>
- </div>
+ <p>
+ If you are working in a group,
+ partner with someone who has also wrote a biography for themselves
+ for the previous section's challenges.
+ </p>
- </section>
+ <ol>
+ <li>
+ Both partners use <code>svn update</code>
+ to make sure their working copies are up to date
+ and that there are no local changes.
+ </li>
+ <li>
+ The first partner edits her biography and commits the changes.
+ </li>
+ <li>
+ The second partner edits her copy of the file
+ (<em>without</em> having updated to get the first partner's changes),
+ then tries to <code>svn commit</code>.
+ </li>
+ <li>
+ Once the second partner has resolved the conflict,
+ she commits her changes.
+ </li>
+ <li>
+ Repeat these four steps with roles reversed.
+ </li>
+ </ol>
- <section id="s:rollback">
+ <p>
+ If you are working on your own,
+ you can simulate the steps above
+ by checking out a second copy of the project into a new directory.
+ (Remember,
+ this cannot overlap any existing checked-out copies.)
+ Edit your biography in one copy and commit those changes,
+ then switch to the other copy and edit the same file
+ before updating.
+ <a href="#f:challenge_conflict">Figure 11</a> shows
+ the differences between these two challenges.
+ </p>
- <h2>Recovering Old Versions</h2>
+ <figure id="f:challenge_conflict">
+ <img src="svn/challenge_conflict.png" alt="Practicing Conflict Resolution" />
+ <figcaption>Figure 11: Practicing Conflict Resolution</figcaption>
+ </figure>
+ </div>
- <div class="understand" id="u:rollback">
- <h3>Understand:</h3>
- <ul>
- <li>How to undo changes to a working copy.</li>
- <li>How to recover old versions of files.</li>
- <li>What a branch is.</li>
- </ul>
- </div>
+</section>
- <p>
- Now that we have seen how to merge files and resolve conflicts,
- we can look at how to use version control as an "infinite undo".
- Suppose that when Wolfman starts work late one night,
- his copy of <code>monsters</code> is in sync with the head at revision 12.
- He decides to edit the file <code>moons.txt</code>;
- unfortunately, he forgot that there was a full moon,
- so his changes don't make a lot of sense:
- </p>
+<section id="s:rollback">
+ <h2>Recovering Old Versions</h2>
+
+ <div class="understand">
+ <h3>Learning Objectives:</h3>
+ <ul>
+ <li>Discard changes made to a working copy.</li>
+ <li>Recover an old version of a file.</li>
+ <li>Explain what branches are and when they are used.</li>
+ </ul>
+ </div>
+
+ <p>
+ Now that we have seen how to merge files and resolve conflicts,
+ we can look at how to use version control as an "infinite undo".
+ Suppose that when Wolfman starts work late one night,
+ his copy of <code>explore</code> is in sync with the head at revision 12.
+ He decides to edit the file <code>moons.txt</code>;
+ unfortunately, he forgot that there was a full moon,
+ so his changes don't make a lot of sense:
+ </p>
<pre src="svn/poetry.txt">
Just one moon can make me growl
...
</pre>
- <p>
- When he's back in human form the next day,
- he wants to undo his changes.
- Without version control, his choices would be grim:
- he could try to edit them back into their original state by hand
- (which for some reason hardly ever seems to work),
- or ask his colleagues to send him their copies of the files
- (which is almost as embarrassing as chasing the neighbor's cat when in wolf form).
- </p>
+ <p>
+ When he's back in human form the next day,
+ he wants to undo his changes.
+ Without version control, his choices would be grim:
+ he could try to edit them back into their original state by hand
+ (which for some reason hardly ever seems to work),
+ or ask his colleagues to send him their copies of the files
+ (which is almost as embarrassing as chasing the neighbor's cat when in wolf form).
+ </p>
- <p>
- Since he's using Subversion, though,
- and hasn't committed his work to the repository,
- all he has to do is <a href="glossary.html#revert">revert</a> his local changes.
- <code>svn revert</code> simply throws away local changes to files
- and puts things back the way they were before those changes were made.
- This is a purely local operation:
- since Subversion stores the history of the project inside every working copy,
- Wolfman doesn't need to be connected to the network to do this.
- </p>
+ <p>
+ Since he's using Subversion, though,
+ and hasn't committed his work to the repository,
+ all he has to do is <a href="glossary.html#revert">revert</a> his local changes.
+ <code>svn revert</code> simply throws away local changes to files
+ and puts things back the way they were before those changes were made.
+ This is a purely local operation:
+ since Subversion stores the history of the project inside every working copy,
+ Wolfman doesn't need to be connected to the network to do this.
+ </p>
- <p>
- To start,
- Wolfman uses <code>svn diff</code> <em>without</em> the <code>-r HEAD</code> flag
- to take a look at the differences between his file
- and the master copy in the repository.
- Since he doesn't want to keep his changes,
- his next command is <code>svn revert moons.txt</code>.
- </p>
+ <p>
+ To start,
+ Wolfman uses <code>svn diff</code> <em>without</em> the <code>-r HEAD</code> flag
+ to take a look at the differences between his file
+ and the master copy in the repository.
+ Since he doesn't want to keep his changes,
+ his next command is <code>svn revert moons.txt</code>.
+ </p>
<pre>
$ <span class="in">cd jupiter</span>
<span class="out">Reverted moons.txt</span>
</pre>
- <p>
- What if someone <em>has</em> committed their changes,
- but still wants to undo them?
- For example,
- suppose Dracula decides that the numbers in <code>moons.txt</code> would look better with commas.
- He edits the file to put them in:
- </p>
+ <p>
+ What if someone <em>has</em> committed their changes,
+ but still wants to undo them?
+ For example,
+ suppose Dracula decides that the numbers in <code>moons.txt</code> would look better with commas.
+ He edits the file to put them in:
+ </p>
<pre src="svn/moons_commas.txt">
Name Orbital Radius Orbital Period Mass Radius
Elara 11<span class="highlight">,</span>740 259.6528 0.008 40.0
</pre>
- <p class="continue">
- then commits his changes to create revision 13.
- A little while later,
- the Mummy sees the change and orders Dracula to put things back the way they were.
- What should Dracula do?
- </p>
+ <p class="continue">
+ then commits his changes to create revision 13.
+ A little while later,
+ the Mummy sees the change and orders Dracula to put things back the way they were.
+ What should Dracula do?
+ </p>
- <p>
- We can draw the sequence of events leading up to revision 13
- as shown in <a href="#f:before_undoing">Fixture XXX</a>:
- </p>
+ <p>
+ We can draw the sequence of events leading up to revision 13
+ as shown in <a href="#f:before_undoing">Fixture 12</a>:
+ </p>
- <figure id="f:before_undoing">
- <img src="svn/before_undoing.png" alt="Before Undoing" />
- </figure>
+ <figure id="f:before_undoing">
+ <img src="svn/before_undoing.png" alt="Before Undoing" />
+ <figcaption>Figure 12: Before Undoing</figcaption>
+ </figure>
- <p class="continue">
- Dracula wants to erase revision 13 from the repository,
- but he can't actually do that:
- once a change is in the repository,
- it's there forever.
- What he can do instead is merge the old revision with the current revision
- to create a new revision
- (<a href="#f:merging_history">Fixture XXX</a>).
- </p>
+ <p class="continue">
+ Dracula wants to erase revision 13 from the repository,
+ but he can't actually do that:
+ once a change is in the repository,
+ it's there forever.
+ What he can do instead is merge the old revision with the current revision
+ to create a new revision
+ (<a href="#f:merging_history">Fixture 13</a>).
+ </p>
- <figure id="f:merging_history">
- <img src="svn/merging_history.png" alt="Merging History" />
- </figure>
+ <figure id="f:merging_history">
+ <img src="svn/merging_history.png" alt="Merging History" />
+ <figcaption>Figure 13: Merging History</figcaption>
+ </figure>
- <p class="continue">
- This is exactly like merging changes made by two different people;
- the only difference is that the "other person" is his past self.
- </p>
+ <p class="continue">
+ This is exactly like merging changes made by two different people;
+ the only difference is that the "other person" is his past self.
+ </p>
- <p>
- To undo his commas,
- Dracula must merge revision 12 (the one before his change)
- with revision 13 (the current head revision)
- using <code>svn merge</code>:
- </p>
+ <p>
+ To undo his commas,
+ Dracula must merge revision 12 (the one before his change)
+ with revision 13 (the current head revision)
+ using <code>svn merge</code>:
+ </p>
<pre>
$ <span class="in">svn merge -r HEAD:12 moons.txt</span>
U moons.txt</span>
</pre>
- <p class="continue">
- The <code>-r</code> flag specifies the range of revisions to merge:
- to undo the changes from revision 12 to revision 13,
- he uses either <code>13:12</code> or <code>HEAD:12</code>
- (since he is going backward in time from the most recent revision to revision 12).
- This is called a <a href="glossary.html#reverse-merge">reverse</a> merge
- because he's going backward in time.
- </p>
+ <p class="continue">
+ The <code>-r</code> flag specifies the range of revisions to merge:
+ to undo the changes from revision 12 to revision 13,
+ he uses either <code>13:12</code> or <code>HEAD:12</code>
+ (since he is going backward in time from the most recent revision to revision 12).
+ This is called a <a href="glossary.html#reverse-merge">reverse</a> merge
+ because he's going backward in time.
+ </p>
- <p>
- After he runs this command,
- he must run <code>svn commit</code> to save the changes to the repository.
- This creates a new revision, number 14,
- rather than erasing revision 13.
- That way,
- the changes he made to create revision 13 are still there
- if he can ever convince the Mummy that numbers should have commas.
- </p>
+ <p>
+ After he runs this command,
+ he must run <code>svn commit</code> to save the changes to the repository.
+ This creates a new revision, number 14,
+ rather than erasing revision 13.
+ That way,
+ the changes he made to create revision 13 are still there
+ if he can ever convince the Mummy that numbers should have commas.
+ </p>
- <p>
- Merging can be used to recover older revisions of files,
- not just the most recent,
- and to recover many files or directories at a time.
- The most frequent use, though,
- is to manage parallel streams of development in large projects.
- This is outside the scope of this chapter,
- but the basic idea is simple.
- </p>
+ <p>
+ Merging can be used to recover older revisions of files,
+ not just the most recent,
+ and to recover many files or directories at a time.
+ The most frequent use, though,
+ is to manage parallel streams of development in large projects.
+ This is outside the scope of this chapter,
+ but the basic idea is simple.
+ </p>
- <p>
- Suppose that Universal Monsters has just released a new program for designing secret lairs.
- Dracula and Wolfman are supposed to start adding a few features
- that had to be left out of the first release because time ran short.
- At the same time,
- Frankenstein and the Mummy are doing technical support:
- their job is to fix any bugs that users find.
- All sorts of things could go wrong if both teams tried to work on the same code at the same time.
- For example,
- if Frankenstein fixed a bug and sent a new copy of the program to a user in Greenland,
- it would be all too easy for him to accidentally include
- the half-completed shark tank control feature that Wolfman was working on.
- </p>
+ <p>
+ Suppose that Universal Missions has just released a new program
+ for designing interplanetary voyages.
+ Dracula and Wolfman are supposed to add some features
+ that were left out of the first release because time ran short.
+ At the same time,
+ Frankenstein and the Mummy are doing technical support:
+ their job is to fix any bugs that users find.
+ </p>
- <p>
- The usual way to handle this situation is
- to create a <a href="glossary.html#branch">branch</a>
- in the repository for each major sub-project
- (<a href="#f:branch_merge">Figure XXX</a>).
- While Wolfman and Dracula work on
- the <a href="glossary.html#main-line">main line</a>,
- Frankenstein and the Mummy create a branch,
- which is just another copy of the repository's files and directories
- that is also under version control.
- They can work in their branch without disturbing Wolfman and Dracula and vice versa:
- </p>
+ <p>
+ All sorts of things could go wrong
+ if both teams tried to work on the same code at the same time.
+ In particular,
+ Dracula and Wolfman might want to make large changes
+ to the structure of the code
+ in order to make it easier to add new features,
+ while Frankenstein and the Mummy want to make as few changes as possible
+ so as not to introduce new bugs while fixing old ones.
+ </p>
- <figure id="f:branch_merge">
- <img src="svn/branch_merge.png" alt="Branching and Merging" />
- </figure>
+ <p>
+ The usual way to handle this situation is
+ to create a <a href="glossary.html#branch">branch</a>
+ in the repository for each major sub-project
+ (<a href="#f:branch_merge">Figure 14</a>).
+ While Wolfman and Dracula work on
+ the <a href="glossary.html#main-line">main line</a>,
+ Frankenstein and the Mummy create a branch,
+ which is just another copy of the repository's files and directories
+ that is also under version control.
+ They can work in their branch without disturbing Wolfman and Dracula and vice versa:
+ </p>
- <p>
- Branches in version control repositories are often described as "parallel universes".
- Each branch starts off as a clone of the project at some moment in time
- (typically each time the software is released,
- or whenever work starts on a major new feature).
- Changes made to a branch only affect that branch,
- just as changes made to the files in one directory don't affect files in other directories.
- However,
- the branch and the main line are both stored in the same repository,
- so their revision numbers are always in step.
- </p>
+ <figure id="f:branch_merge">
+ <img src="svn/branch_merge.png" alt="Branching and Merging" />
+ <figcaption>Figure 14: Branching and Merging</figcaption>
+ </figure>
- <p>
- If someone decides that a bug fix in one branch should also be made in another,
- all they have to do is merge the files in question.
- This is exactly like merging an old version of a file with the current one,
- but instead of going backward in time,
- the change is brought sideways from one branch to another.
- </p>
+ <p>
+ Branches in version control repositories are often described as "parallel universes".
+ Each branch starts off as a clone of the project at some moment in time
+ (typically each time the software is released,
+ or whenever work starts on a major new feature).
+ Changes made to a branch only affect that branch,
+ just as changes made to the files in one directory don't affect files in other directories.
+ However,
+ the branch and the main line are both stored in the same repository,
+ so their revision numbers are always in step.
+ </p>
- <p>
- Branching helps projects scale up by letting sub-teams work independently,
- but too many branches can cause as many problems as they solve.
- Karl Fogel's excellent book
- <a href="bib.html#fogel-producing-oss"><cite>Producing Open Source Software</cite></a>,
- and Laura Wingerd and Christopher Seiwald's paper
- "<a href="bib.html#wingerd-seiwald-scm">High-level Best Practices in Software Configuration Management</a>",
- talk about branches in much more detail.
- Projects usually don't need to do this until they have a dozen or more developers,
- or until several versions of their software are in simultaneous use,
- but using branches is a key part of switching from software carpentry to software engineering.
- </p>
+ <p>
+ If someone decides that a bug fix in one branch should also be made in another,
+ all they have to do is merge the files in question.
+ This is exactly like merging an old version of a file with the current one,
+ but instead of going backward in time,
+ the change is brought sideways from one branch to another.
+ </p>
- <div class="keypoints" id="k:rollback">
- <h3>Summary</h3>
- <ul>
- <li>Old versions of files can be recovered by merging their old state with their current state.</li>
- <li>Recovering an old version of a file does not erase the intervening changes.</li>
- <li>Use branches to support parallel independent development.</li>
- <li><code>svn merge</code> merges two revisions of a file.</li>
- <li><code>svn revert</code> undoes local changes to files.</li>
- </ul>
- </div>
+ <p>
+ Branching helps projects scale up by letting sub-teams work independently,
+ but too many branches can cause as many problems as they solve.
+ Karl Fogel's excellent book
+ <a href="bib.html#fogel-producing-oss"><cite>Producing Open Source Software</cite></a>,
+ and Laura Wingerd and Christopher Seiwald's paper
+ "<a href="bib.html#wingerd-seiwald-scm">High-level Best Practices in Software Configuration Management</a>",
+ talk about branches in much more detail.
+ Projects usually don't need to do this until they have a dozen or more developers,
+ or until several versions of their software are in simultaneous use,
+ but using branches is a key part of switching from software carpentry to software engineering.
+ </p>
- </section>
+ <div class="keypoints">
+ <h3>Summary</h3>
+ <ul>
+ <li>Old versions of files can be recovered by merging their old state with their current state.</li>
+ <li>Recovering an old version of a file does not erase the intervening changes.</li>
+ <li>Use branches to support parallel independent development.</li>
+ <li><code>svn merge</code> merges two revisions of a file.</li>
+ <li><code>svn revert</code> undoes local changes to files.</li>
+ </ul>
+ </div>
+
+ <div class="challenges">
+ <h3>Challenges</h3>
+
+ <p class="fixme">write some</p>
+ </div>
+
+</section>
<section id="s:setup">