hgbook
diff en/appA-svn.xml @ 686:e9154b3daa94
Repurpose appendix A.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Sun Apr 26 23:16:56 2009 -0700 (2009-04-26) |
parents | en/appA-cmdref.xml@b338f5490029 |
children | 0ffae4ee4c47 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/en/appA-svn.xml Sun Apr 26 23:16:56 2009 -0700 1.3 @@ -0,0 +1,441 @@ 1.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 1.5 + 1.6 +<appendix id="svn"> 1.7 + <?dbhtml filename="mercurial-for-subversion-users.html"?> 1.8 +<title>Migrating to Mercurial</title> 1.9 + 1.10 + <para>A common way to test the waters with a new revision control 1.11 + tool is to experiment with switching an existing project, rather 1.12 + than starting a new project from scratch.</para> 1.13 + 1.14 + <para>In this appendix, we discuss how to import a project's history 1.15 + into Mercurial, and what to look out for if you are used to a 1.16 + different revision control system.</para> 1.17 + 1.18 + <sect1> 1.19 + <title>Importing history from another system</title> 1.20 + 1.21 + <para>Mercurial ships with an extension named 1.22 + <literal>convert</literal>, which can import project history 1.23 + from most popular revision control systems. At the time this 1.24 + book was written, it could import history from the following 1.25 + systems:</para> 1.26 + <itemizedlist> 1.27 + <listitem> 1.28 + <para>Subversion</para> 1.29 + </listitem> 1.30 + <listitem> 1.31 + <para>CVS</para> 1.32 + </listitem> 1.33 + <listitem> 1.34 + <para>git</para> 1.35 + </listitem> 1.36 + <listitem> 1.37 + <para>Darcs</para> 1.38 + </listitem> 1.39 + <listitem> 1.40 + <para>Bazaar</para> 1.41 + </listitem> 1.42 + <listitem> 1.43 + <para>Monotone</para> 1.44 + </listitem> 1.45 + <listitem> 1.46 + <para>GNU Arch</para> 1.47 + </listitem> 1.48 + <listitem> 1.49 + <para>Mercurial</para> 1.50 + </listitem> 1.51 + </itemizedlist> 1.52 + 1.53 + <para>(To see why Mercurial itself is supported as a source, see 1.54 + <xref linkend="svn.filemap"/>.)</para> 1.55 + 1.56 + <para>You can enable the extension in the usual way, by editing 1.57 + your <filename>~/.hgrc</filename> file.</para> 1.58 + 1.59 + <programlisting>[extensions] 1.60 +convert =</programlisting> 1.61 + 1.62 + <para>This will make a <command>hg convert</command> command 1.63 + available. The command is easy to use. For instance, this 1.64 + command will import the Subversion history for the Nose unit 1.65 + testing framework into Mercurial.</para> 1.66 + 1.67 + <screen><prompt>$</prompt> <userinput>hg convert http://python-nose.googlecode.com/svn/trunk</userinput></screen> 1.68 + 1.69 + <para>The <literal>convert</literal> extension operates 1.70 + incrementally. In other words, after you have run <command>hg 1.71 + convert</command> once, running it again will import any new 1.72 + revisions committed after the first run began. Incremental 1.73 + conversion will only work if you run <command>hg 1.74 + convert</command> in the same Mercurial repository that you 1.75 + originally used, because the <literal>convert</literal> 1.76 + extension saves some private metadata in a 1.77 + non-revision-controlled file named 1.78 + <filename>.hg/shamap</filename> inside the target 1.79 + repository.</para> 1.80 + 1.81 + <sect2> 1.82 + <title>Mapping user names</title> 1.83 + 1.84 + <para>Some revision control tools save only short usernames with 1.85 + commits, and these can be difficult to interpret. The norm 1.86 + with Mercurial is to save a committer's name and email 1.87 + address, which is much more useful for talking to them after 1.88 + the fact.</para> 1.89 + 1.90 + <para>If you are converting a tree from a revision control 1.91 + system that uses short names, you can map those names to 1.92 + longer equivalents by passing a <option>--authors</option> 1.93 + option to <command>hg convert</command>. This option accepts 1.94 + a file name that should contain entries of the following 1.95 + form.</para> 1.96 + 1.97 + <programlisting>arist = Aristotle <aristotle@phil.example.gr> 1.98 +soc = Socrates <socrates@phil.example.gr></programlisting> 1.99 + 1.100 + <para>Whenever <literal>convert</literal> encounters a commit 1.101 + with the username <literal>arist</literal> in the source 1.102 + repository, it will use the name <literal>Aristotle 1.103 + <aristotle@phil.example.gr></literal> in the converted 1.104 + Mercurial revision. If no match is found for a name, it is 1.105 + used verbatim.</para> 1.106 + </sect2> 1.107 + 1.108 + <sect2 id="svn.filemap"> 1.109 + <title>Tidying up the tree</title> 1.110 + 1.111 + <para>Not all projects have pristine history. There may be a 1.112 + directory that should never have been checked in, a file that 1.113 + is too big, or a whole hierarchy that needs to be 1.114 + refactored.</para> 1.115 + 1.116 + <para>The <literal>convert</literal> extension supports the idea 1.117 + of a <quote>file map</quote> that can reorganize the files and 1.118 + directories in a project as it imports the project's history. 1.119 + This is useful not only when importing history from other 1.120 + revision control systems, but also to prune or refactor a 1.121 + Mercurial tree.</para> 1.122 + 1.123 + <para>To specify a file map, use the <option>--filemap</option> 1.124 + option and supply a file name. A file map contains lines of the 1.125 + following forms.</para> 1.126 + 1.127 + <programlisting># This is a comment. 1.128 +# Empty lines are ignored. 1.129 + 1.130 +include path/to/file 1.131 + 1.132 +exclude path/to/file 1.133 + 1.134 +rename from/some/path to/some/other/place 1.135 +</programlisting> 1.136 + 1.137 + <para>The <literal>include</literal> directive causes a file, or 1.138 + all files under a directory, to be included in the destination 1.139 + repository. This also excludes all other files and dirs not 1.140 + explicitely included. The <literal>exclude</literal> 1.141 + directive causes files or directories to be omitted, and 1.142 + others not explicitly mentioned to be included.</para> 1.143 + 1.144 + <para>To move a file or directory from one location to another, 1.145 + use the <literal>rename</literal> directive. If you need to 1.146 + move a file or directory from a subdirectory into the root of 1.147 + the repository, use <literal>.</literal> as the second 1.148 + argument to the <literal>rename</literal> directive.</para> 1.149 + </sect2> 1.150 + </sect1> 1.151 + 1.152 + <sect1> 1.153 + <title>Migrating from Subversion</title> 1.154 + 1.155 + <para>Subversion is currently the most popular open source 1.156 + revision control system. Although there are many differences 1.157 + between Mercurial and Subversion, making the transition from 1.158 + Subversion to Mercurial is not particularly difficult. The two 1.159 + have similar command sets and generally uniform 1.160 + interfaces.</para> 1.161 + 1.162 + <sect2> 1.163 + <title>Philosophical differences</title> 1.164 + 1.165 + <para>The fundamental difference between Subversion and 1.166 + Mercurial is of course that Subversion is centralized, while 1.167 + Mercurial is distributed. Since Mercurial stores all of a 1.168 + project's history on your local drive, it only needs to 1.169 + perform a network access when you want to explicitly 1.170 + communicate with another repository. In contrast, Subversion 1.171 + stores very little information locally, and the client must 1.172 + thus contact its server for many common operations.</para> 1.173 + 1.174 + <para>Subversion more or less gets away without a well-defined 1.175 + notion of a branch: which portion of a server's namespace 1.176 + qualifies as a branch is a matter of convention, with the 1.177 + software providing no enforcement. Mercurial treats a 1.178 + repository as the unit of branch management.</para> 1.179 + 1.180 + <sect3> 1.181 + <title>Scope of commands</title> 1.182 + 1.183 + <para>Since Subversion doesn't know what parts of its 1.184 + namespace are really branches, it treats most commands as 1.185 + requests to operate at and below whatever directory you are 1.186 + currently visiting. For instance, if you run <command>svn 1.187 + log</command>, you'll get the history of whatever part of 1.188 + the tree you're looking at, not the tree as a whole.</para> 1.189 + 1.190 + <para>Mercurial's commands behave differently, by defaulting 1.191 + to operating over an entire repository. Run <command>hg 1.192 + log</command> and it will tell you the history of the 1.193 + entire tree, no matter what part of the working directory 1.194 + you're visiting at the time. If you want the history of 1.195 + just a particular file or directory, simply supply it by 1.196 + name, e.g. <command>hg log src</command>.</para> 1.197 + 1.198 + <para>From my own experience, this difference in default 1.199 + behaviors is probably the most likely to trip you up if you 1.200 + have to switch back and forth frequently between the two 1.201 + tools.</para> 1.202 + </sect3> 1.203 + 1.204 + <sect3> 1.205 + <title>Multi-user operation and safety</title> 1.206 + 1.207 + <para>With Subversion, it is normal (though slightly frowned 1.208 + upon) for multiple people to collaborate in a single branch. 1.209 + If Alice and Bob are working together, and Alice commits 1.210 + some changes to their shared branch, Bob must update his 1.211 + client's view of the branch before he can commit. Since at 1.212 + this time he has no permanent record of the changes he has 1.213 + made, he can corrupt or lose his modifications during and 1.214 + after his update.</para> 1.215 + 1.216 + <para>Mercurial encourages a commit-then-merge model instead. 1.217 + Bob commits his changes locally before pulling changes from, 1.218 + or pushing them to, the server that he shares with Alice. 1.219 + If Alice pushed her changes before Bob tries to push his, he 1.220 + will not be able to push his changes until he pulls hers, 1.221 + merges with them, and commits the result of the merge. If 1.222 + he makes a mistake during the merge, he still has the option 1.223 + of reverting to the commit that recorded his changes.</para> 1.224 + 1.225 + <para>It is worth emphasizing that these are the common ways 1.226 + of working with these tools. Subversion supports a safer 1.227 + work-in-your-own-branch model, but it is cumbersome enough 1.228 + in practice to not be widely used. Mercurial can support 1.229 + the less safe mode of allowing changes to be pulled in and 1.230 + merged on top of uncommitted edits, but this is considered 1.231 + highly unusual.</para> 1.232 + </sect3> 1.233 + 1.234 + <sect3> 1.235 + <title>Published vs local changes</title> 1.236 + 1.237 + <para>A Subversion <command>svn commit</command> command 1.238 + immediately publishes changes to a server, where they can be 1.239 + seen by everyone who has read access.</para> 1.240 + 1.241 + <para>With Mercurial, commits are always local, and must be 1.242 + published via a <command>hg push</command> command 1.243 + afterwards.</para> 1.244 + 1.245 + <para>Each approach has its advantages and disadvantages. The 1.246 + Subversion model means that changes are published, and hence 1.247 + reviewable and usable, immediately. On the other hand, this 1.248 + means that a user must have commit access to a repository in 1.249 + order to use the software in a normal way, and commit access 1.250 + is not lightly given out by most open source 1.251 + projects.</para> 1.252 + 1.253 + <para>The Mercurial approach allows anyone who can clone a 1.254 + repository to commit changes without the need for someone 1.255 + else's permission, and they can then publish their changes 1.256 + and continue to participate however they see fit. The 1.257 + distinction between committing and pushing does open up the 1.258 + possibility of someone committing changes to their laptop 1.259 + and walking away for a few days having forgotten to push 1.260 + them, which in rare cases might leave collaborators 1.261 + temporarily stuck.</para> 1.262 + </sect3> 1.263 + </sect2> 1.264 + 1.265 + <sect2> 1.266 + <title>Quick reference</title> 1.267 + 1.268 + <table> 1.269 + <title>Subversion commands and Mercurial equivalents</title> 1.270 + <tgroup cols="3"> 1.271 + <thead> 1.272 + <row> 1.273 + <entry>Subversion</entry> 1.274 + <entry>Mercurial</entry> 1.275 + <entry>Notes</entry> 1.276 + </row> 1.277 + </thead> 1.278 + <tbody> 1.279 + <row> 1.280 + <entry><command>svn add</command></entry> 1.281 + <entry><command>hg add</command></entry> 1.282 + <entry></entry> 1.283 + </row> 1.284 + <row> 1.285 + <entry><command>svn blame</command></entry> 1.286 + <entry><command>hg annotate</command></entry> 1.287 + <entry></entry> 1.288 + </row> 1.289 + <row> 1.290 + <entry><command>svn cat</command></entry> 1.291 + <entry><command>hg cat</command></entry> 1.292 + <entry></entry> 1.293 + </row> 1.294 + <row> 1.295 + <entry><command>svn checkout</command></entry> 1.296 + <entry><command>hg clone</command></entry> 1.297 + <entry></entry> 1.298 + </row> 1.299 + <row> 1.300 + <entry><command>svn cleanup</command></entry> 1.301 + <entry>n/a</entry> 1.302 + <entry>No cleanup needed</entry> 1.303 + </row> 1.304 + <row> 1.305 + <entry><command>svn commit</command></entry> 1.306 + <entry><command>hg commit</command>; <command>hg 1.307 + push</command></entry> 1.308 + <entry><command>hg push</command> publishes after 1.309 + commit</entry> 1.310 + </row> 1.311 + <row> 1.312 + <entry><command>svn copy</command></entry> 1.313 + <entry><command>hg clone</command></entry> 1.314 + <entry>To create a new branch</entry> 1.315 + </row> 1.316 + <row> 1.317 + <entry><command>svn copy</command></entry> 1.318 + <entry><command>hg copy</command></entry> 1.319 + <entry>To copy files or directories</entry> 1.320 + </row> 1.321 + <row> 1.322 + <entry><command>svn delete</command> (<command>svn 1.323 + remove</command>)</entry> 1.324 + <entry><command>hg remove</command></entry> 1.325 + <entry></entry> 1.326 + </row> 1.327 + <row> 1.328 + <entry><command>svn diff</command></entry> 1.329 + <entry><command>hg diff</command></entry> 1.330 + <entry></entry> 1.331 + </row> 1.332 + <row> 1.333 + <entry><command>svn export</command></entry> 1.334 + <entry><command>hg archive</command></entry> 1.335 + <entry></entry> 1.336 + </row> 1.337 + <row> 1.338 + <entry><command>svn help</command></entry> 1.339 + <entry><command>hg help</command></entry> 1.340 + <entry></entry> 1.341 + </row> 1.342 + <row> 1.343 + <entry><command>svn import</command></entry> 1.344 + <entry><command>hg addremove</command>; <command>hg 1.345 + commit</command></entry> 1.346 + <entry></entry> 1.347 + </row> 1.348 + <row> 1.349 + <entry><command>svn info</command></entry> 1.350 + <entry><command>hg parents</command></entry> 1.351 + <entry>Shows what revision is checked out</entry> 1.352 + </row> 1.353 + <row> 1.354 + <entry><command>svn info</command></entry> 1.355 + <entry><command>hg showconfig 1.356 + paths.parent</command></entry> 1.357 + <entry>Shows what URL is checked out</entry> 1.358 + </row> 1.359 + <row> 1.360 + <entry><command>svn list</command></entry> 1.361 + <entry><command>hg manifest</command></entry> 1.362 + <entry></entry> 1.363 + </row> 1.364 + <row> 1.365 + <entry><command>svn log</command></entry> 1.366 + <entry><command>hg log</command></entry> 1.367 + <entry></entry> 1.368 + </row> 1.369 + <row> 1.370 + <entry><command>svn merge</command></entry> 1.371 + <entry><command>hg merge</command></entry> 1.372 + <entry></entry> 1.373 + </row> 1.374 + <row> 1.375 + <entry><command>svn mkdir</command></entry> 1.376 + <entry>n/a</entry> 1.377 + <entry>Mercurial does not track directories</entry> 1.378 + </row> 1.379 + <row> 1.380 + <entry><command>svn move</command> (<command>svn 1.381 + rename</command>)</entry> 1.382 + <entry><command>hg rename</command></entry> 1.383 + <entry></entry> 1.384 + </row> 1.385 + <row> 1.386 + <entry><command>svn resolved</command></entry> 1.387 + <entry><command>hg resolve -m</command></entry> 1.388 + <entry></entry> 1.389 + </row> 1.390 + <row> 1.391 + <entry><command>svn revert</command></entry> 1.392 + <entry><command>hg revert</command></entry> 1.393 + <entry></entry> 1.394 + </row> 1.395 + <row> 1.396 + <entry><command>svn status</command></entry> 1.397 + <entry><command>hg status</command></entry> 1.398 + <entry></entry> 1.399 + </row> 1.400 + <row> 1.401 + <entry><command>svn update</command></entry> 1.402 + <entry><command>hg pull -u</command></entry> 1.403 + <entry></entry> 1.404 + </row> 1.405 + </tbody> 1.406 + </tgroup> 1.407 + </table> 1.408 + </sect2> 1.409 + </sect1> 1.410 + 1.411 + <sect1> 1.412 + <title>Useful tips for newcomers</title> 1.413 + 1.414 + <para>Under some revision control systems, printing a diff for a 1.415 + single committed revision can be painful. For instance, with 1.416 + Subversion, to see what changed in revision 104654, you must 1.417 + type <command>svn diff -r104653:104654</command>. Mercurial 1.418 + eliminates the need to type the revision ID twice in this common 1.419 + case. For a plain diff, <command>hg export 104654</command>. For 1.420 + a log message followed by a diff, <command>hg log -r104654 1.421 + -p</command>.</para> 1.422 + 1.423 + <para>When you run <command>hg status</command> without any 1.424 + arguments, it prints the status of the entire tree, with paths 1.425 + relative to the root of the repository. This makes it tricky to 1.426 + copy a file name from the output of <command>hg status</command> 1.427 + into the command line. If you supply a file or directory name 1.428 + to <command>hg status</command>, it will print paths relative to 1.429 + your current location instead. So to get tree-wide status from 1.430 + <command>hg status</command>, with paths that are relative to 1.431 + your current directory and not the root of the repository, feed 1.432 + the output of <command>hg root</command> into <command>hg 1.433 + status</command>. You can easily do this as follows on a 1.434 + Unix-like system:</para> 1.435 + 1.436 + <screen><prompt>$</prompt> <userinput>hg status `hg root`</userinput></screen> 1.437 + </sect1> 1.438 +</appendix> 1.439 + 1.440 +<!-- 1.441 +local variables: 1.442 +sgml-parent-document: ("00book.xml" "book" "appendix") 1.443 +end: 1.444 +-->