hgbook
diff en/ch05-daily.xml @ 1000:0fba9db5e75c
Added tag french-xdoc-build-fixed for changeset a6b81cd31cfd
author | Romain PELISSE <belaran@gmail.com> |
---|---|
date | Sat Sep 12 20:53:56 2009 +0200 (2009-09-12) |
parents | 477d6a3e5023 |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/en/ch05-daily.xml Sat Sep 12 20:53:56 2009 +0200 1.3 @@ -0,0 +1,840 @@ 1.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 1.5 + 1.6 +<chapter id="chap:daily"> 1.7 + <?dbhtml filename="mercurial-in-daily-use.html"?> 1.8 + <title>Mercurial in daily use</title> 1.9 + 1.10 + <sect1> 1.11 + <title>Telling Mercurial which files to track</title> 1.12 + 1.13 + <para id="x_1a3">Mercurial does not work with files in your repository unless 1.14 + you tell it to manage them. The <command role="hg-cmd">hg 1.15 + status</command> command will tell you which files Mercurial 1.16 + doesn't know about; it uses a 1.17 + <quote><literal>?</literal></quote> to display such 1.18 + files.</para> 1.19 + 1.20 + <para id="x_1a4">To tell Mercurial to track a file, use the <command 1.21 + role="hg-cmd">hg add</command> command. Once you have added a 1.22 + file, the entry in the output of <command role="hg-cmd">hg 1.23 + status</command> for that file changes from 1.24 + <quote><literal>?</literal></quote> to 1.25 + <quote><literal>A</literal></quote>.</para> 1.26 + 1.27 + &interaction.daily.files.add; 1.28 + 1.29 + <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>, 1.30 + the files that you added before the commit will no longer be 1.31 + listed in the output of <command role="hg-cmd">hg 1.32 + status</command>. The reason for this is that by default, <command 1.33 + role="hg-cmd">hg status</command> only tells you about 1.34 + <quote>interesting</quote> files&emdash;those that you have (for 1.35 + example) modified, removed, or renamed. If you have a repository 1.36 + that contains thousands of files, you will rarely want to know 1.37 + about files that Mercurial is tracking, but that have not 1.38 + changed. (You can still get this information; we'll return to 1.39 + this later.)</para> 1.40 + 1.41 + <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it 1.42 + immediately. Instead, it will take a snapshot of the file's 1.43 + state the next time you perform a commit. It will then continue 1.44 + to track the changes you make to the file every time you commit, 1.45 + until you remove the file.</para> 1.46 + 1.47 + <sect2> 1.48 + <title>Explicit versus implicit file naming</title> 1.49 + 1.50 + <para id="x_1a7">A useful behavior that Mercurial has is that if you pass 1.51 + the name of a directory to a command, every Mercurial command 1.52 + will treat this as <quote>I want to operate on every file in 1.53 + this directory and its subdirectories</quote>.</para> 1.54 + 1.55 + &interaction.daily.files.add-dir; 1.56 + 1.57 + <para id="x_1a8">Notice in this example that Mercurial printed 1.58 + the names of the files it added, whereas it didn't do so when 1.59 + we added the file named <filename>myfile.txt</filename> in the 1.60 + earlier example.</para> 1.61 + 1.62 + <para id="x_1a9">What's going on is that in the former case, we explicitly 1.63 + named the file to add on the command line. The assumption 1.64 + that Mercurial makes in such cases is that we know what we 1.65 + are doing, and it doesn't print any output.</para> 1.66 + 1.67 + <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of 1.68 + files by giving the name of a directory, Mercurial takes the 1.69 + extra step of printing the name of each file that it does 1.70 + something with. This makes it more clear what is happening, 1.71 + and reduces the likelihood of a silent and nasty surprise. 1.72 + This behavior is common to most Mercurial commands.</para> 1.73 + </sect2> 1.74 + 1.75 + <sect2> 1.76 + <title>Mercurial tracks files, not directories</title> 1.77 + 1.78 + <para id="x_1ab">Mercurial does not track directory information. Instead, 1.79 + it tracks the path to a file. Before creating a file, it 1.80 + first creates any missing directory components of the path. 1.81 + After it deletes a file, it then deletes any empty directories 1.82 + that were in the deleted file's path. This sounds like a 1.83 + trivial distinction, but it has one minor practical 1.84 + consequence: it is not possible to represent a completely 1.85 + empty directory in Mercurial.</para> 1.86 + 1.87 + <para id="x_1ac">Empty directories are rarely useful, and there are 1.88 + unintrusive workarounds that you can use to achieve an 1.89 + appropriate effect. The developers of Mercurial thus felt 1.90 + that the complexity that would be required to manage empty 1.91 + directories was not worth the limited benefit this feature 1.92 + would bring.</para> 1.93 + 1.94 + <para id="x_1ad">If you need an empty directory in your repository, there 1.95 + are a few ways to achieve this. One is to create a directory, 1.96 + then <command role="hg-cmd">hg add</command> a 1.97 + <quote>hidden</quote> file to that directory. On Unix-like 1.98 + systems, any file name that begins with a period 1.99 + (<quote><literal>.</literal></quote>) is treated as hidden by 1.100 + most commands and GUI tools. This approach is illustrated 1.101 + below.</para> 1.102 + 1.103 +&interaction.daily.files.hidden; 1.104 + 1.105 + <para id="x_1ae">Another way to tackle a need for an empty directory is to 1.106 + simply create one in your automated build scripts before they 1.107 + will need it.</para> 1.108 + </sect2> 1.109 + </sect1> 1.110 + 1.111 + <sect1> 1.112 + <title>How to stop tracking a file</title> 1.113 + 1.114 + <para id="x_1af">Once you decide that a file no longer belongs in 1.115 + your repository, use the <command role="hg-cmd">hg 1.116 + remove</command> command. This deletes the file, and tells 1.117 + Mercurial to stop tracking it (which will occur at the next 1.118 + commit). A removed file is represented in the output of 1.119 + <command role="hg-cmd">hg status</command> with a 1.120 + <quote><literal>R</literal></quote>.</para> 1.121 + 1.122 + &interaction.daily.files.remove; 1.123 + 1.124 + <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file, 1.125 + Mercurial will no longer track changes to that file, even if you 1.126 + recreate a file with the same name in your working directory. 1.127 + If you do recreate a file with the same name and want Mercurial 1.128 + to track the new file, simply <command role="hg-cmd">hg 1.129 + add</command> it. Mercurial will know that the newly added 1.130 + file is not related to the old file of the same name.</para> 1.131 + 1.132 + <sect2> 1.133 + <title>Removing a file does not affect its history</title> 1.134 + 1.135 + <para id="x_1b1">It is important to understand that removing a file has 1.136 + only two effects.</para> 1.137 + <itemizedlist> 1.138 + <listitem><para id="x_1b2">It removes the current version of the file 1.139 + from the working directory.</para> 1.140 + </listitem> 1.141 + <listitem><para id="x_1b3">It stops Mercurial from tracking changes to 1.142 + the file, from the time of the next commit.</para> 1.143 + </listitem></itemizedlist> 1.144 + <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way 1.145 + alter the <emphasis>history</emphasis> of the file.</para> 1.146 + 1.147 + <para id="x_1b5">If you update the working directory to a 1.148 + changeset that was committed when it was still tracking a file 1.149 + that you later removed, the file will reappear in the working 1.150 + directory, with the contents it had when you committed that 1.151 + changeset. If you then update the working directory to a 1.152 + later changeset, in which the file had been removed, Mercurial 1.153 + will once again remove the file from the working 1.154 + directory.</para> 1.155 + </sect2> 1.156 + 1.157 + <sect2> 1.158 + <title>Missing files</title> 1.159 + 1.160 + <para id="x_1b6">Mercurial considers a file that you have deleted, but not 1.161 + used <command role="hg-cmd">hg remove</command> to delete, to 1.162 + be <emphasis>missing</emphasis>. A missing file is 1.163 + represented with <quote><literal>!</literal></quote> in the 1.164 + output of <command role="hg-cmd">hg status</command>. 1.165 + Mercurial commands will not generally do anything with missing 1.166 + files.</para> 1.167 + 1.168 + &interaction.daily.files.missing; 1.169 + 1.170 + <para id="x_1b7">If your repository contains a file that <command 1.171 + role="hg-cmd">hg status</command> reports as missing, and 1.172 + you want the file to stay gone, you can run <command 1.173 + role="hg-cmd">hg remove <option 1.174 + role="hg-opt-remove">--after</option></command> at any 1.175 + time later on, to tell Mercurial that you really did mean to 1.176 + remove the file.</para> 1.177 + 1.178 + &interaction.daily.files.remove-after; 1.179 + 1.180 + <para id="x_1b8">On the other hand, if you deleted the missing file by 1.181 + accident, give <command role="hg-cmd">hg revert</command> the 1.182 + name of the file to recover. It will reappear, in unmodified 1.183 + form.</para> 1.184 + 1.185 + &interaction.daily.files.recover-missing; 1.186 + </sect2> 1.187 + 1.188 + <sect2> 1.189 + <title>Aside: why tell Mercurial explicitly to remove a 1.190 + file?</title> 1.191 + 1.192 + <para id="x_1b9">You might wonder why Mercurial requires you to explicitly 1.193 + tell it that you are deleting a file. Early during the 1.194 + development of Mercurial, it let you delete a file however you 1.195 + pleased; Mercurial would notice the absence of the file 1.196 + automatically when you next ran a <command role="hg-cmd">hg 1.197 + commit</command>, and stop tracking the file. In practice, 1.198 + this made it too easy to accidentally remove a file without 1.199 + noticing.</para> 1.200 + </sect2> 1.201 + 1.202 + <sect2> 1.203 + <title>Useful shorthand&emdash;adding and removing files in one 1.204 + step</title> 1.205 + 1.206 + <para id="x_1ba">Mercurial offers a combination command, <command 1.207 + role="hg-cmd">hg addremove</command>, that adds untracked 1.208 + files and marks missing files as removed.</para> 1.209 + 1.210 + &interaction.daily.files.addremove; 1.211 + 1.212 + <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command 1.213 + also provides a <option role="hg-opt-commit">-A</option> 1.214 + option that performs this same add-and-remove, immediately 1.215 + followed by a commit.</para> 1.216 + 1.217 + &interaction.daily.files.commit-addremove; 1.218 + </sect2> 1.219 + </sect1> 1.220 + 1.221 + <sect1 id="chap:daily.copy"> 1.222 + <title>Copying files</title> 1.223 + 1.224 + <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg 1.225 + copy</command> command that lets you make a new copy of a 1.226 + file. When you copy a file using this command, Mercurial makes 1.227 + a record of the fact that the new file is a copy of the original 1.228 + file. It treats these copied files specially when you merge 1.229 + your work with someone else's.</para> 1.230 + 1.231 + <sect2> 1.232 + <title>The results of copying during a merge</title> 1.233 + 1.234 + <para id="x_1bd">What happens during a merge is that changes 1.235 + <quote>follow</quote> a copy. To best illustrate what this 1.236 + means, let's create an example. We'll start with the usual 1.237 + tiny repository that contains a single file.</para> 1.238 + 1.239 + &interaction.daily.copy.init; 1.240 + 1.241 + <para id="x_1be">We need to do some work in 1.242 + parallel, so that we'll have something to merge. So let's 1.243 + clone our repository.</para> 1.244 + 1.245 + &interaction.daily.copy.clone; 1.246 + 1.247 + <para id="x_1bf">Back in our initial repository, let's use the <command 1.248 + role="hg-cmd">hg copy</command> command to make a copy of 1.249 + the first file we created.</para> 1.250 + 1.251 + &interaction.daily.copy.copy; 1.252 + 1.253 + <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg 1.254 + status</command> command afterwards, the copied file looks 1.255 + just like a normal added file.</para> 1.256 + 1.257 + &interaction.daily.copy.status; 1.258 + 1.259 + <para id="x_1c1">But if we pass the <option 1.260 + role="hg-opt-status">-C</option> option to <command 1.261 + role="hg-cmd">hg status</command>, it prints another line of 1.262 + output: this is the file that our newly-added file was copied 1.263 + <emphasis>from</emphasis>.</para> 1.264 + 1.265 + &interaction.daily.copy.status-copy; 1.266 + 1.267 + <para id="x_1c2">Now, back in the repository we cloned, let's make a change 1.268 + in parallel. We'll add a line of content to the original file 1.269 + that we created.</para> 1.270 + 1.271 + &interaction.daily.copy.other; 1.272 + 1.273 + <para id="x_1c3">Now we have a modified <filename>file</filename> in this 1.274 + repository. When we pull the changes from the first 1.275 + repository, and merge the two heads, Mercurial will propagate 1.276 + the changes that we made locally to <filename>file</filename> 1.277 + into its copy, <filename>new-file</filename>.</para> 1.278 + 1.279 + &interaction.daily.copy.merge; 1.280 + </sect2> 1.281 + 1.282 + <sect2 id="sec:daily:why-copy"> 1.283 + <title>Why should changes follow copies?</title> 1.284 + 1.285 + <para id="x_1c4">This behavior&emdash;of changes to a file 1.286 + propagating out to copies of the file&emdash;might seem 1.287 + esoteric, but in most cases it's highly desirable.</para> 1.288 + 1.289 + <para id="x_1c5">First of all, remember that this propagation 1.290 + <emphasis>only</emphasis> happens when you merge. So if you 1.291 + <command role="hg-cmd">hg copy</command> a file, and 1.292 + subsequently modify the original file during the normal course 1.293 + of your work, nothing will happen.</para> 1.294 + 1.295 + <para id="x_1c6">The second thing to know is that modifications will only 1.296 + propagate across a copy as long as the changeset that you're 1.297 + merging changes from <emphasis>hasn't yet seen</emphasis> 1.298 + the copy.</para> 1.299 + 1.300 + <para id="x_1c7">The reason that Mercurial does this is as follows. Let's 1.301 + say I make an important bug fix in a source file, and commit 1.302 + my changes. Meanwhile, you've decided to <command 1.303 + role="hg-cmd">hg copy</command> the file in your repository, 1.304 + without knowing about the bug or having seen the fix, and you 1.305 + have started hacking on your copy of the file.</para> 1.306 + 1.307 + <para id="x_1c8">If you pulled and merged my changes, and Mercurial 1.308 + <emphasis>didn't</emphasis> propagate changes across copies, 1.309 + your new source file would now contain the bug, and unless you 1.310 + knew to propagate the bug fix by hand, the bug would 1.311 + <emphasis>remain</emphasis> in your copy of the file.</para> 1.312 + 1.313 + <para id="x_1c9">By automatically propagating the change that fixed the bug 1.314 + from the original file to the copy, Mercurial prevents this 1.315 + class of problem. To my knowledge, Mercurial is the 1.316 + <emphasis>only</emphasis> revision control system that 1.317 + propagates changes across copies like this.</para> 1.318 + 1.319 + <para id="x_1ca">Once your change history has a record that the copy and 1.320 + subsequent merge occurred, there's usually no further need to 1.321 + propagate changes from the original file to the copied file, 1.322 + and that's why Mercurial only propagates changes across copies 1.323 + at the first merge, and not afterwards.</para> 1.324 + </sect2> 1.325 + 1.326 + <sect2> 1.327 + <title>How to make changes <emphasis>not</emphasis> follow a 1.328 + copy</title> 1.329 + 1.330 + <para id="x_1cb">If, for some reason, you decide that this business of 1.331 + automatically propagating changes across copies is not for 1.332 + you, simply use your system's normal file copy command (on 1.333 + Unix-like systems, that's <command>cp</command>) to make a 1.334 + copy of a file, then <command role="hg-cmd">hg add</command> 1.335 + the new copy by hand. Before you do so, though, please do 1.336 + reread <xref linkend="sec:daily:why-copy"/>, and make 1.337 + an informed 1.338 + decision that this behavior is not appropriate to your 1.339 + specific case.</para> 1.340 + 1.341 + </sect2> 1.342 + <sect2> 1.343 + <title>Behavior of the <command role="hg-cmd">hg copy</command> 1.344 + command</title> 1.345 + 1.346 + <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command> 1.347 + command, Mercurial makes a copy of each source file as it 1.348 + currently stands in the working directory. This means that if 1.349 + you make some modifications to a file, then <command 1.350 + role="hg-cmd">hg copy</command> it without first having 1.351 + committed those changes, the new copy will also contain the 1.352 + modifications you have made up until that point. (I find this 1.353 + behavior a little counterintuitive, which is why I mention it 1.354 + here.)</para> 1.355 + 1.356 + <para id="x_1cd">The <command role="hg-cmd">hg copy</command> 1.357 + command acts similarly to the Unix <command>cp</command> 1.358 + command (you can use the <command role="hg-cmd">hg 1.359 + cp</command> alias if you prefer). We must supply two or 1.360 + more arguments, of which the last is treated as the 1.361 + <emphasis>destination</emphasis>, and all others are 1.362 + <emphasis>sources</emphasis>.</para> 1.363 + 1.364 + <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a 1.365 + single file as the source, and the destination does not exist, 1.366 + it creates a new file with that name.</para> 1.367 + 1.368 + &interaction.daily.copy.simple; 1.369 + 1.370 + <para id="x_1ce">If the destination is a directory, Mercurial copies its 1.371 + sources into that directory.</para> 1.372 + 1.373 + &interaction.daily.copy.dir-dest; 1.374 + 1.375 + <para id="x_1cf">Copying a directory is 1.376 + recursive, and preserves the directory structure of the 1.377 + source.</para> 1.378 + 1.379 + &interaction.daily.copy.dir-src; 1.380 + 1.381 + <para id="x_1d0">If the source and destination are both directories, the 1.382 + source tree is recreated in the destination directory.</para> 1.383 + 1.384 + &interaction.daily.copy.dir-src-dest; 1.385 + 1.386 + <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command> 1.387 + command, if you copy a file manually and then want Mercurial 1.388 + to know that you've copied the file, simply use the <option 1.389 + role="hg-opt-copy">--after</option> option to <command 1.390 + role="hg-cmd">hg copy</command>.</para> 1.391 + 1.392 + &interaction.daily.copy.after; 1.393 + </sect2> 1.394 + </sect1> 1.395 + 1.396 + <sect1> 1.397 + <title>Renaming files</title> 1.398 + 1.399 + <para id="x_1d2">It's rather more common to need to rename a file than to 1.400 + make a copy of it. The reason I discussed the <command 1.401 + role="hg-cmd">hg copy</command> command before talking about 1.402 + renaming files is that Mercurial treats a rename in essentially 1.403 + the same way as a copy. Therefore, knowing what Mercurial does 1.404 + when you copy a file tells you what to expect when you rename a 1.405 + file.</para> 1.406 + 1.407 + <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command> 1.408 + command, Mercurial makes a copy of each source file, then 1.409 + deletes it and marks the file as removed.</para> 1.410 + 1.411 + &interaction.daily.rename.rename; 1.412 + 1.413 + <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows 1.414 + the newly copied file as added, and the copied-from file as 1.415 + removed.</para> 1.416 + 1.417 + &interaction.daily.rename.status; 1.418 + 1.419 + <para id="x_1d5">As with the results of a <command role="hg-cmd">hg 1.420 + copy</command>, we must use the <option 1.421 + role="hg-opt-status">-C</option> option to <command 1.422 + role="hg-cmd">hg status</command> to see that the added file 1.423 + is really being tracked by Mercurial as a copy of the original, 1.424 + now removed, file.</para> 1.425 + 1.426 + &interaction.daily.rename.status-copy; 1.427 + 1.428 + <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and 1.429 + <command role="hg-cmd">hg copy</command>, you can tell Mercurial 1.430 + about a rename after the fact using the <option 1.431 + role="hg-opt-rename">--after</option> option. In most other 1.432 + respects, the behavior of the <command role="hg-cmd">hg 1.433 + rename</command> command, and the options it accepts, are 1.434 + similar to the <command role="hg-cmd">hg copy</command> 1.435 + command.</para> 1.436 + 1.437 + <para id="x_686">If you're familiar with the Unix command line, you'll be 1.438 + glad to know that <command role="hg-cmd">hg rename</command> 1.439 + command can be invoked as <command role="hg-cmd">hg 1.440 + mv</command>.</para> 1.441 + 1.442 + <sect2> 1.443 + <title>Renaming files and merging changes</title> 1.444 + 1.445 + <para id="x_1d7">Since Mercurial's rename is implemented as 1.446 + copy-and-remove, the same propagation of changes happens when 1.447 + you merge after a rename as after a copy.</para> 1.448 + 1.449 + <para id="x_1d8">If I modify a file, and you rename it to a new name, and 1.450 + then we merge our respective changes, my modifications to the 1.451 + file under its original name will be propagated into the file 1.452 + under its new name. (This is something you might expect to 1.453 + <quote>simply work,</quote> but not all revision control 1.454 + systems actually do this.)</para> 1.455 + 1.456 + <para id="x_1d9">Whereas having changes follow a copy is a feature where 1.457 + you can perhaps nod and say <quote>yes, that might be 1.458 + useful,</quote> it should be clear that having them follow a 1.459 + rename is definitely important. Without this facility, it 1.460 + would simply be too easy for changes to become orphaned when 1.461 + files are renamed.</para> 1.462 + </sect2> 1.463 + 1.464 + <sect2> 1.465 + <title>Divergent renames and merging</title> 1.466 + 1.467 + <para id="x_1da">The case of diverging names occurs when two developers 1.468 + start with a file&emdash;let's call it 1.469 + <filename>foo</filename>&emdash;in their respective 1.470 + repositories.</para> 1.471 + 1.472 + &interaction.rename.divergent.clone; 1.473 + 1.474 + <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para> 1.475 + 1.476 + &interaction.rename.divergent.rename.anne; 1.477 + 1.478 + <para id="x_1dc">Meanwhile, Bob renames it to 1.479 + <filename>quux</filename>. (Remember that <command 1.480 + role="hg-cmd">hg mv</command> is an alias for <command 1.481 + role="hg-cmd">hg rename</command>.)</para> 1.482 + 1.483 + &interaction.rename.divergent.rename.bob; 1.484 + 1.485 + <para id="x_1dd">I like to think of this as a conflict because each 1.486 + developer has expressed different intentions about what the 1.487 + file ought to be named.</para> 1.488 + 1.489 + <para id="x_1de">What do you think should happen when they merge their 1.490 + work? Mercurial's actual behavior is that it always preserves 1.491 + <emphasis>both</emphasis> names when it merges changesets that 1.492 + contain divergent renames.</para> 1.493 + 1.494 + &interaction.rename.divergent.merge; 1.495 + 1.496 + <para id="x_1df">Notice that while Mercurial warns about the divergent 1.497 + renames, it leaves it up to you to do something about the 1.498 + divergence after the merge.</para> 1.499 + </sect2> 1.500 + 1.501 + <sect2> 1.502 + <title>Convergent renames and merging</title> 1.503 + 1.504 + <para id="x_1e0">Another kind of rename conflict occurs when two people 1.505 + choose to rename different <emphasis>source</emphasis> files 1.506 + to the same <emphasis>destination</emphasis>. In this case, 1.507 + Mercurial runs its normal merge machinery, and lets you guide 1.508 + it to a suitable resolution.</para> 1.509 + </sect2> 1.510 + 1.511 + <sect2> 1.512 + <title>Other name-related corner cases</title> 1.513 + 1.514 + <para id="x_1e1">Mercurial has a longstanding bug in which it fails to 1.515 + handle a merge where one side has a file with a given name, 1.516 + while another has a directory with the same name. This is 1.517 + documented as <ulink role="hg-bug" 1.518 + url="http://www.selenic.com/mercurial/bts/issue29">issue 1.519 + 29</ulink>.</para> 1.520 + 1.521 + &interaction.issue29.go; 1.522 + 1.523 + </sect2> 1.524 + </sect1> 1.525 + 1.526 + <sect1> 1.527 + <title>Recovering from mistakes</title> 1.528 + 1.529 + <para id="x_1e2">Mercurial has some useful commands that will help you to 1.530 + recover from some common mistakes.</para> 1.531 + 1.532 + <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets 1.533 + you undo changes that you have made to your working directory. 1.534 + For example, if you <command role="hg-cmd">hg add</command> a 1.535 + file by accident, just run <command role="hg-cmd">hg 1.536 + revert</command> with the name of the file you added, and 1.537 + while the file won't be touched in any way, it won't be tracked 1.538 + for adding by Mercurial any longer, either. You can also use 1.539 + <command role="hg-cmd">hg revert</command> to get rid of 1.540 + erroneous changes to a file.</para> 1.541 + 1.542 + <para id="x_1e4">It is helpful to remember that the <command 1.543 + role="hg-cmd">hg revert</command> command is useful for 1.544 + changes that you have not yet committed. Once you've committed 1.545 + a change, if you decide it was a mistake, you can still do 1.546 + something about it, though your options may be more 1.547 + limited.</para> 1.548 + 1.549 + <para id="x_1e5">For more information about the <command 1.550 + role="hg-cmd">hg revert</command> command, and details about 1.551 + how to deal with changes you have already committed, see <xref 1.552 + linkend="chap:undo"/>.</para> 1.553 + </sect1> 1.554 + 1.555 + <sect1> 1.556 + <title>Dealing with tricky merges</title> 1.557 + 1.558 + <para id="x_687">In a complicated or large project, it's not unusual for a 1.559 + merge of two changesets to result in some headaches. Suppose 1.560 + there's a big source file that's been extensively edited by each 1.561 + side of a merge: this is almost inevitably going to result in 1.562 + conflicts, some of which can take a few tries to sort 1.563 + out.</para> 1.564 + 1.565 + <para id="x_688">Let's develop a simple case of this and see how to deal with 1.566 + it. We'll start off with a repository containing one file, and 1.567 + clone it twice.</para> 1.568 + 1.569 + &interaction.ch04-resolve.init; 1.570 + 1.571 + <para id="x_689">In one clone, we'll modify the file in one way.</para> 1.572 + 1.573 + &interaction.ch04-resolve.left; 1.574 + 1.575 + <para id="x_68a">In another, we'll modify the file differently.</para> 1.576 + 1.577 + &interaction.ch04-resolve.right; 1.578 + 1.579 + <para id="x_68b">Next, we'll pull each set of changes into our original 1.580 + repo.</para> 1.581 + 1.582 + &interaction.ch04-resolve.pull; 1.583 + 1.584 + <para id="x_68c">We expect our repository to now contain two heads.</para> 1.585 + 1.586 + &interaction.ch04-resolve.heads; 1.587 + 1.588 + <para id="x_68d">Normally, if we run <command role="hg-cmd">hg 1.589 + merge</command> at this point, it will drop us into a GUI that 1.590 + will let us manually resolve the conflicting edits to 1.591 + <filename>myfile.txt</filename>. However, to simplify things 1.592 + for presentation here, we'd like the merge to fail immediately 1.593 + instead. Here's one way we can do so.</para> 1.594 + 1.595 + &interaction.ch04-resolve.export; 1.596 + 1.597 + <para id="x_68e">We've told Mercurial's merge machinery to run the command 1.598 + <command>false</command> (which, as we desire, fails 1.599 + immediately) if it detects a merge that it can't sort out 1.600 + automatically.</para> 1.601 + 1.602 + <para id="x_68f">If we now fire up <command role="hg-cmd">hg 1.603 + merge</command>, it should grind to a halt and report a 1.604 + failure.</para> 1.605 + 1.606 + &interaction.ch04-resolve.merge; 1.607 + 1.608 + <para id="x_690">Even if we don't notice that the merge failed, Mercurial 1.609 + will prevent us from accidentally committing the result of a 1.610 + failed merge.</para> 1.611 + 1.612 + &interaction.ch04-resolve.cifail; 1.613 + 1.614 + <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in 1.615 + this case, it suggests that we use the unfamiliar <command 1.616 + role="hg-cmd">hg resolve</command> command. As usual, 1.617 + <command role="hg-cmd">hg help resolve</command> will print a 1.618 + helpful synopsis.</para> 1.619 + 1.620 + <sect2> 1.621 + <title>File resolution states</title> 1.622 + 1.623 + <para id="x_692">When a merge occurs, most files will usually remain 1.624 + unmodified. For each file where Mercurial has to do 1.625 + something, it tracks the state of the file.</para> 1.626 + 1.627 + <itemizedlist> 1.628 + <listitem> 1.629 + <para id="x_693">A <emphasis>resolved</emphasis> file has been 1.630 + successfully merged, either automatically by Mercurial or 1.631 + manually with human intervention.</para> 1.632 + </listitem> 1.633 + <listitem> 1.634 + <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged 1.635 + successfully, and needs more attention.</para> 1.636 + </listitem> 1.637 + </itemizedlist> 1.638 + 1.639 + <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the 1.640 + unresolved state after a merge, it considers the merge to have 1.641 + failed. Fortunately, we do not need to restart the entire 1.642 + merge from scratch.</para> 1.643 + 1.644 + <para id="x_696">The <option role="hg-opt-resolve">--list</option> or 1.645 + <option role="hg-opt-resolve">-l</option> option to <command 1.646 + role="hg-cmd">hg resolve</command> prints out the state of 1.647 + each merged file.</para> 1.648 + 1.649 + &interaction.ch04-resolve.list; 1.650 + 1.651 + <para id="x_697">In the output from <command role="hg-cmd">hg 1.652 + resolve</command>, a resolved file is marked with 1.653 + <literal>R</literal>, while an unresolved file is marked with 1.654 + <literal>U</literal>. If any files are listed with 1.655 + <literal>U</literal>, we know that an attempt to commit the 1.656 + results of the merge will fail.</para> 1.657 + </sect2> 1.658 + 1.659 + <sect2> 1.660 + <title>Resolving a file merge</title> 1.661 + 1.662 + <para id="x_698">We have several options to move a file from the unresolved 1.663 + into the resolved state. By far the most common is to rerun 1.664 + <command role="hg-cmd">hg resolve</command>. If we pass the 1.665 + names of individual files or directories, it will retry the 1.666 + merges of any unresolved files present in those locations. We 1.667 + can also pass the <option role="hg-opt-resolve">--all</option> 1.668 + or <option role="hg-opt-resolve">-a</option> option, which 1.669 + will retry the merges of <emphasis>all</emphasis> unresolved 1.670 + files.</para> 1.671 + 1.672 + <para id="x_699">Mercurial also lets us modify the resolution state of a 1.673 + file directly. We can manually mark a file as resolved using 1.674 + the <option role="hg-opt-resolve">--mark</option> option, or 1.675 + as unresolved using the <option 1.676 + role="hg-opt-resolve">--unmark</option> option. This allows 1.677 + us to clean up a particularly messy merge by hand, and to keep 1.678 + track of our progress with each file as we go.</para> 1.679 + </sect2> 1.680 + </sect1> 1.681 + 1.682 + <sect1> 1.683 + <title>More useful diffs</title> 1.684 + 1.685 + <para id="x_6c7">The default output of the <command role="hg-cmd">hg 1.686 + diff</command> command is backwards compatible with the 1.687 + regular <command>diff</command> command, but this has some 1.688 + drawbacks.</para> 1.689 + 1.690 + <para id="x_6c8">Consider the case where we use <command role="hg-cmd">hg 1.691 + rename</command> to rename a file.</para> 1.692 + 1.693 + &interaction.ch04-diff.rename.basic; 1.694 + 1.695 + <para id="x_6c9">The output of <command role="hg-cmd">hg diff</command> above 1.696 + obscures the fact that we simply renamed a file. The <command 1.697 + role="hg-cmd">hg diff</command> command accepts an option, 1.698 + <option>--git</option> or <option>-g</option>, to use a newer 1.699 + diff format that displays such information in a more readable 1.700 + form.</para> 1.701 + 1.702 + &interaction.ch04-diff.rename.git; 1.703 + 1.704 + <para id="x_6ca">This option also helps with a case that can otherwise be 1.705 + confusing: a file that appears to be modified according to 1.706 + <command role="hg-cmd">hg status</command>, but for which 1.707 + <command role="hg-cmd">hg diff</command> prints nothing. This 1.708 + situation can arise if we change the file's execute 1.709 + permissions.</para> 1.710 + 1.711 + &interaction.ch04-diff.chmod; 1.712 + 1.713 + <para id="x_6cb">The normal <command>diff</command> command pays no attention 1.714 + to file permissions, which is why <command role="hg-cmd">hg 1.715 + diff</command> prints nothing by default. If we supply it 1.716 + with the <option>-g</option> option, it tells us what really 1.717 + happened.</para> 1.718 + 1.719 + &interaction.ch04-diff.chmod.git; 1.720 + </sect1> 1.721 + 1.722 + <sect1> 1.723 + <title>Which files to manage, and which to avoid</title> 1.724 + 1.725 + <para id="x_6cc">Revision control systems are generally best at managing text 1.726 + files that are written by humans, such as source code, where the 1.727 + files do not change much from one revision to the next. Some 1.728 + centralized revision control systems can also deal tolerably 1.729 + well with binary files, such as bitmap images.</para> 1.730 + 1.731 + <para id="x_6cd">For instance, a game development team will typically manage 1.732 + both its source code and all of its binary assets (e.g. geometry 1.733 + data, textures, map layouts) in a revision control 1.734 + system.</para> 1.735 + 1.736 + <para id="x_6ce">Because it is usually impossible to merge two conflicting 1.737 + modifications to a binary file, centralized systems often 1.738 + provide a file locking mechanism that allow a user to say 1.739 + <quote>I am the only person who can edit this 1.740 + file</quote>.</para> 1.741 + 1.742 + <para id="x_6cf">Compared to a centralized system, a distributed revision 1.743 + control system changes some of the factors that guide decisions 1.744 + over which files to manage and how.</para> 1.745 + 1.746 + <para id="x_6d0">For instance, a distributed revision control system cannot, 1.747 + by its nature, offer a file locking facility. There is thus no 1.748 + built-in mechanism to prevent two people from making conflicting 1.749 + changes to a binary file. If you have a team where several 1.750 + people may be editing binary files frequently, it may not be a 1.751 + good idea to use Mercurial&emdash;or any other distributed 1.752 + revision control system&emdash;to manage those files.</para> 1.753 + 1.754 + <para id="x_6d1">When storing modifications to a file, Mercurial usually 1.755 + saves only the differences between the previous and current 1.756 + versions of the file. For most text files, this is extremely 1.757 + efficient. However, some files (particularly binary files) are 1.758 + laid out in such a way that even a small change to a file's 1.759 + logical content results in many or most of the bytes inside the 1.760 + file changing. For instance, compressed files are particularly 1.761 + susceptible to this. If the differences between each successive 1.762 + version of a file are always large, Mercurial will not be able 1.763 + to store the file's revision history very efficiently. This can 1.764 + affect both local storage needs and the amount of time it takes 1.765 + to clone a repository.</para> 1.766 + 1.767 + <para id="x_6d2">To get an idea of how this could affect you in practice, 1.768 + suppose you want to use Mercurial to manage an OpenOffice 1.769 + document. OpenOffice stores documents on disk as compressed zip 1.770 + files. Edit even a single letter of your document in OpenOffice, 1.771 + and almost every byte in the entire file will change when you 1.772 + save it. Now suppose that file is 2MB in size. Because most of 1.773 + the file changes every time you save, Mercurial will have to 1.774 + store all 2MB of the file every time you commit, even though 1.775 + from your perspective, perhaps only a few words are changing 1.776 + each time. A single frequently-edited file that is not friendly 1.777 + to Mercurial's storage assumptions can easily have an outsized 1.778 + effect on the size of the repository.</para> 1.779 + 1.780 + <para id="x_6d3">Even worse, if both you and someone else edit the OpenOffice 1.781 + document you're working on, there is no useful way to merge your 1.782 + work. In fact, there isn't even a good way to tell what the 1.783 + differences are between your respective changes.</para> 1.784 + 1.785 + <para id="x_6d4">There are thus a few clear recommendations about specific 1.786 + kinds of files to be very careful with.</para> 1.787 + 1.788 + <itemizedlist> 1.789 + <listitem> 1.790 + <para id="x_6d5">Files that are very large and incompressible, e.g. ISO 1.791 + CD-ROM images, will by virtue of sheer size make clones over 1.792 + a network very slow.</para> 1.793 + </listitem> 1.794 + <listitem> 1.795 + <para id="x_6d6">Files that change a lot from one revision to the next 1.796 + may be expensive to store if you edit them frequently, and 1.797 + conflicts due to concurrent edits may be difficult to 1.798 + resolve.</para> 1.799 + </listitem> 1.800 + </itemizedlist> 1.801 + </sect1> 1.802 + 1.803 + <sect1> 1.804 + <title>Backups and mirroring</title> 1.805 + 1.806 + <para id="x_6d7">Since Mercurial maintains a complete copy of history in each 1.807 + clone, everyone who uses Mercurial to collaborate on a project 1.808 + can potentially act as a source of backups in the event of a 1.809 + catastrophe. If a central repository becomes unavailable, you 1.810 + can construct a replacement simply by cloning a copy of the 1.811 + repository from one contributor, and pulling any changes they 1.812 + may not have seen from others.</para> 1.813 + 1.814 + <para id="x_6d8">It is simple to use Mercurial to perform off-site backups 1.815 + and remote mirrors. Set up a periodic job (e.g. via the 1.816 + <command>cron</command> command) on a remote server to pull 1.817 + changes from your master repositories every hour. This will 1.818 + only be tricky in the unlikely case that the number of master 1.819 + repositories you maintain changes frequently, in which case 1.820 + you'll need to do a little scripting to refresh the list of 1.821 + repositories to back up.</para> 1.822 + 1.823 + <para id="x_6d9">If you perform traditional backups of your master 1.824 + repositories to tape or disk, and you want to back up a 1.825 + repository named <filename>myrepo</filename>, use <command>hg 1.826 + clone -U myrepo myrepo.bak</command> to create a 1.827 + clone of <filename>myrepo</filename> before you start your 1.828 + backups. The <option>-U</option> option doesn't check out a 1.829 + working directory after the clone completes, since that would be 1.830 + superfluous and make the backup take longer.</para> 1.831 + 1.832 + <para id="x_6da">If you then back up <filename>myrepo.bak</filename> instead 1.833 + of <filename>myrepo</filename>, you will be guaranteed to have a 1.834 + consistent snapshot of your repository that won't be pushed to 1.835 + by an insomniac developer in mid-backup.</para> 1.836 + </sect1> 1.837 +</chapter> 1.838 + 1.839 +<!-- 1.840 +local variables: 1.841 +sgml-parent-document: ("00book.xml" "book" "chapter") 1.842 +end: 1.843 +-->