hgbook
annotate fr/ch05-daily.xml @ 964:6b680d569bb4
deleting a bunch of files not longer necessary to build the documentation.
Adding missing newly files needed to build the documentation
Adding missing newly files needed to build the documentation
author | Romain PELISSE <belaran@gmail.com> |
---|---|
date | Sun Aug 16 04:58:01 2009 +0200 (2009-08-16) |
parents | |
children | 6f8c48362758 |
rev | line source |
---|---|
belaran@964 | 1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> |
belaran@964 | 2 |
belaran@964 | 3 <chapter> |
belaran@964 | 4 <title>Mercurial in daily use</title> |
belaran@964 | 5 <para>\label{chap:daily}</para> |
belaran@964 | 6 |
belaran@964 | 7 <sect1> |
belaran@964 | 8 <title>Telling Mercurial which files to track</title> |
belaran@964 | 9 |
belaran@964 | 10 <para>Mercurial does not work with files in your repository unless you tell |
belaran@964 | 11 it to manage them. The <command role="hg-cmd">hg status</command> command will tell you which |
belaran@964 | 12 files Mercurial doesn't know about; it uses a <quote><literal>?</literal></quote> to |
belaran@964 | 13 display such files.</para> |
belaran@964 | 14 |
belaran@964 | 15 <para>To tell Mercurial to track a file, use the <command role="hg-cmd">hg add</command> command. Once |
belaran@964 | 16 you have added a file, the entry in the output of <command role="hg-cmd">hg status</command> for |
belaran@964 | 17 that file changes from <quote><literal>?</literal></quote> to <quote><literal>A</literal></quote>. |
belaran@964 | 18 <!-- &interaction.daily.files.add; --></para> |
belaran@964 | 19 |
belaran@964 | 20 <para>After you run a <command role="hg-cmd">hg commit</command>, the files that you added before the |
belaran@964 | 21 commit will no longer be listed in the output of <command role="hg-cmd">hg status</command>. The |
belaran@964 | 22 reason for this is that <command role="hg-cmd">hg status</command> only tells you about |
belaran@964 | 23 <quote>interesting</quote> files&emdash;those that you have modified or told Mercurial |
belaran@964 | 24 to do something with&emdash;by default. If you have a repository that |
belaran@964 | 25 contains thousands of files, you will rarely want to know about files |
belaran@964 | 26 that Mercurial is tracking, but that have not changed. (You can still |
belaran@964 | 27 get this information; we'll return to this later.)</para> |
belaran@964 | 28 |
belaran@964 | 29 <para>Once you add a file, Mercurial doesn't do anything with it |
belaran@964 | 30 immediately. Instead, it will take a snapshot of the file's state the |
belaran@964 | 31 next time you perform a commit. It will then continue to track the |
belaran@964 | 32 changes you make to the file every time you commit, until you remove |
belaran@964 | 33 the file.</para> |
belaran@964 | 34 |
belaran@964 | 35 <sect2> |
belaran@964 | 36 <title>Explicit versus implicit file naming</title> |
belaran@964 | 37 |
belaran@964 | 38 <para>A useful behaviour that Mercurial has is that if you pass the name of |
belaran@964 | 39 a directory to a command, every Mercurial command will treat this as |
belaran@964 | 40 <quote>I want to operate on every file in this directory and its |
belaran@964 | 41 subdirectories</quote>. |
belaran@964 | 42 <!-- &interaction.daily.files.add-dir; --> |
belaran@964 | 43 Notice in this example that Mercurial printed the names of the files |
belaran@964 | 44 it added, whereas it didn't do so when we added the file named |
belaran@964 | 45 <filename>a</filename> in the earlier example.</para> |
belaran@964 | 46 |
belaran@964 | 47 <para>What's going on is that in the former case, we explicitly named the |
belaran@964 | 48 file to add on the command line, so the assumption that Mercurial |
belaran@964 | 49 makes in such cases is that you know what you were doing, and it |
belaran@964 | 50 doesn't print any output.</para> |
belaran@964 | 51 |
belaran@964 | 52 <para>However, when we <emphasis>imply</emphasis> the names of files by giving the name of |
belaran@964 | 53 a directory, Mercurial takes the extra step of printing the name of |
belaran@964 | 54 each file that it does something with. This makes it more clear what |
belaran@964 | 55 is happening, and reduces the likelihood of a silent and nasty |
belaran@964 | 56 surprise. This behaviour is common to most Mercurial commands.</para> |
belaran@964 | 57 |
belaran@964 | 58 </sect2> |
belaran@964 | 59 <sect2> |
belaran@964 | 60 <title>Aside: Mercurial tracks files, not directories</title> |
belaran@964 | 61 |
belaran@964 | 62 <para>Mercurial does not track directory information. Instead, it tracks |
belaran@964 | 63 the path to a file. Before creating a file, it first creates any |
belaran@964 | 64 missing directory components of the path. After it deletes a file, it |
belaran@964 | 65 then deletes any empty directories that were in the deleted file's |
belaran@964 | 66 path. This sounds like a trivial distinction, but it has one minor |
belaran@964 | 67 practical consequence: it is not possible to represent a completely |
belaran@964 | 68 empty directory in Mercurial. |
belaran@964 | 69 </para> |
belaran@964 | 70 |
belaran@964 | 71 <para>Empty directories are rarely useful, and there are unintrusive |
belaran@964 | 72 workarounds that you can use to achieve an appropriate effect. The |
belaran@964 | 73 developers of Mercurial thus felt that the complexity that would be |
belaran@964 | 74 required to manage empty directories was not worth the limited benefit |
belaran@964 | 75 this feature would bring. |
belaran@964 | 76 </para> |
belaran@964 | 77 |
belaran@964 | 78 <para>If you need an empty directory in your repository, there are a few |
belaran@964 | 79 ways to achieve this. One is to create a directory, then <command role="hg-cmd">hg add</command> a |
belaran@964 | 80 <quote>hidden</quote> file to that directory. On Unix-like systems, any file |
belaran@964 | 81 name that begins with a period (<quote><literal>.</literal></quote>) is treated as hidden |
belaran@964 | 82 by most commands and GUI tools. This approach is illustrated in |
belaran@964 | 83 figure <xref linkend="ex:daily:hidden"/>. |
belaran@964 | 84 </para> |
belaran@964 | 85 |
belaran@964 | 86 <informalfigure> |
belaran@964 | 87 <para> <!-- &interaction.daily.files.hidden; --> |
belaran@964 | 88 <caption><para>Simulating an empty directory using a hidden file</para></caption> |
belaran@964 | 89 \label{ex:daily:hidden} |
belaran@964 | 90 </para> |
belaran@964 | 91 </informalfigure> |
belaran@964 | 92 |
belaran@964 | 93 <para>Another way to tackle a need for an empty directory is to simply |
belaran@964 | 94 create one in your automated build scripts before they will need it. |
belaran@964 | 95 </para> |
belaran@964 | 96 |
belaran@964 | 97 </sect2> |
belaran@964 | 98 </sect1> |
belaran@964 | 99 <sect1> |
belaran@964 | 100 <title>How to stop tracking a file</title> |
belaran@964 | 101 |
belaran@964 | 102 <para>Once you decide that a file no longer belongs in your repository, use |
belaran@964 | 103 the <command role="hg-cmd">hg remove</command> command; this deletes the file, and tells Mercurial |
belaran@964 | 104 to stop tracking it. A removed file is represented in the output of |
belaran@964 | 105 <command role="hg-cmd">hg status</command> with a <quote><literal>R</literal></quote>. |
belaran@964 | 106 <!-- &interaction.daily.files.remove; --> |
belaran@964 | 107 </para> |
belaran@964 | 108 |
belaran@964 | 109 <para>After you <command role="hg-cmd">hg remove</command> a file, Mercurial will no longer track |
belaran@964 | 110 changes to that file, even if you recreate a file with the same name |
belaran@964 | 111 in your working directory. If you do recreate a file with the same |
belaran@964 | 112 name and want Mercurial to track the new file, simply <command role="hg-cmd">hg add</command> it. |
belaran@964 | 113 Mercurial will know that the newly added file is not related to the |
belaran@964 | 114 old file of the same name. |
belaran@964 | 115 </para> |
belaran@964 | 116 |
belaran@964 | 117 <sect2> |
belaran@964 | 118 <title>Removing a file does not affect its history</title> |
belaran@964 | 119 |
belaran@964 | 120 <para>It is important to understand that removing a file has only two |
belaran@964 | 121 effects. |
belaran@964 | 122 </para> |
belaran@964 | 123 <itemizedlist> |
belaran@964 | 124 <listitem><para>It removes the current version of the file from the working |
belaran@964 | 125 directory. |
belaran@964 | 126 </para> |
belaran@964 | 127 </listitem> |
belaran@964 | 128 <listitem><para>It stops Mercurial from tracking changes to the file, from the |
belaran@964 | 129 time of the next commit. |
belaran@964 | 130 </para> |
belaran@964 | 131 </listitem></itemizedlist> |
belaran@964 | 132 <para>Removing a file <emphasis>does not</emphasis> in any way alter the <emphasis>history</emphasis> of |
belaran@964 | 133 the file. |
belaran@964 | 134 </para> |
belaran@964 | 135 |
belaran@964 | 136 <para>If you update the working directory to a changeset in which a file |
belaran@964 | 137 that you have removed was still tracked, it will reappear in the |
belaran@964 | 138 working directory, with the contents it had when you committed that |
belaran@964 | 139 changeset. If you then update the working directory to a later |
belaran@964 | 140 changeset, in which the file had been removed, Mercurial will once |
belaran@964 | 141 again remove the file from the working directory. |
belaran@964 | 142 </para> |
belaran@964 | 143 |
belaran@964 | 144 </sect2> |
belaran@964 | 145 <sect2> |
belaran@964 | 146 <title>Missing files</title> |
belaran@964 | 147 |
belaran@964 | 148 <para>Mercurial considers a file that you have deleted, but not used |
belaran@964 | 149 <command role="hg-cmd">hg remove</command> to delete, to be <emphasis>missing</emphasis>. A missing file is |
belaran@964 | 150 represented with <quote><literal>!</literal></quote> in the output of <command role="hg-cmd">hg status</command>. |
belaran@964 | 151 Mercurial commands will not generally do anything with missing files. |
belaran@964 | 152 <!-- &interaction.daily.files.missing; --> |
belaran@964 | 153 </para> |
belaran@964 | 154 |
belaran@964 | 155 <para>If your repository contains a file that <command role="hg-cmd">hg status</command> reports as |
belaran@964 | 156 missing, and you want the file to stay gone, you can run |
belaran@964 | 157 <command role="hg-cmd">hg remove <option role="hg-opt-remove">--after</option></command> at any time later on, to |
belaran@964 | 158 tell Mercurial that you really did mean to remove the file. |
belaran@964 | 159 <!-- &interaction.daily.files.remove-after; --> |
belaran@964 | 160 </para> |
belaran@964 | 161 |
belaran@964 | 162 <para>On the other hand, if you deleted the missing file by accident, use |
belaran@964 | 163 <command role="hg-cmd">hg revert <emphasis>filename</emphasis></command> to recover the file. It will |
belaran@964 | 164 reappear, in unmodified form. |
belaran@964 | 165 <!-- &interaction.daily.files.recover-missing; --> |
belaran@964 | 166 </para> |
belaran@964 | 167 |
belaran@964 | 168 <para>\subsection{Aside: why tell Mercurial explicitly to |
belaran@964 | 169 remove a file?} |
belaran@964 | 170 </para> |
belaran@964 | 171 |
belaran@964 | 172 <para>You might wonder why Mercurial requires you to explicitly tell it that |
belaran@964 | 173 you are deleting a file. Early during the development of Mercurial, |
belaran@964 | 174 it let you delete a file however you pleased; Mercurial would notice |
belaran@964 | 175 the absence of the file automatically when you next ran a |
belaran@964 | 176 <command role="hg-cmd">hg commit</command>, and stop tracking the file. In practice, this made it |
belaran@964 | 177 too easy to accidentally remove a file without noticing. |
belaran@964 | 178 </para> |
belaran@964 | 179 |
belaran@964 | 180 <para>\subsection{Useful shorthand&emdash;adding and removing files |
belaran@964 | 181 in one step} |
belaran@964 | 182 </para> |
belaran@964 | 183 |
belaran@964 | 184 <para>Mercurial offers a combination command, <command role="hg-cmd">hg addremove</command>, that adds |
belaran@964 | 185 untracked files and marks missing files as removed. |
belaran@964 | 186 <!-- &interaction.daily.files.addremove; --> |
belaran@964 | 187 The <command role="hg-cmd">hg commit</command> command also provides a <option role="hg-opt-commit">-A</option> option |
belaran@964 | 188 that performs this same add-and-remove, immediately followed by a |
belaran@964 | 189 commit. |
belaran@964 | 190 <!-- &interaction.daily.files.commit-addremove; --> |
belaran@964 | 191 </para> |
belaran@964 | 192 |
belaran@964 | 193 </sect2> |
belaran@964 | 194 </sect1> |
belaran@964 | 195 <sect1> |
belaran@964 | 196 <title>Copying files</title> |
belaran@964 | 197 |
belaran@964 | 198 <para>Mercurial provides a <command role="hg-cmd">hg copy</command> command that lets you make a new |
belaran@964 | 199 copy of a file. When you copy a file using this command, Mercurial |
belaran@964 | 200 makes a record of the fact that the new file is a copy of the original |
belaran@964 | 201 file. It treats these copied files specially when you merge your work |
belaran@964 | 202 with someone else's. |
belaran@964 | 203 </para> |
belaran@964 | 204 |
belaran@964 | 205 <sect2> |
belaran@964 | 206 <title>The results of copying during a merge</title> |
belaran@964 | 207 |
belaran@964 | 208 <para>What happens during a merge is that changes <quote>follow</quote> a copy. To |
belaran@964 | 209 best illustrate what this means, let's create an example. We'll start |
belaran@964 | 210 with the usual tiny repository that contains a single file. |
belaran@964 | 211 <!-- &interaction.daily.copy.init; --> |
belaran@964 | 212 We need to do some work in parallel, so that we'll have something to |
belaran@964 | 213 merge. So let's clone our repository. |
belaran@964 | 214 <!-- &interaction.daily.copy.clone; --> |
belaran@964 | 215 Back in our initial repository, let's use the <command role="hg-cmd">hg copy</command> command to |
belaran@964 | 216 make a copy of the first file we created. |
belaran@964 | 217 <!-- &interaction.daily.copy.copy; --> |
belaran@964 | 218 </para> |
belaran@964 | 219 |
belaran@964 | 220 <para>If we look at the output of the <command role="hg-cmd">hg status</command> command afterwards, the |
belaran@964 | 221 copied file looks just like a normal added file. |
belaran@964 | 222 <!-- &interaction.daily.copy.status; --> |
belaran@964 | 223 But if we pass the <option role="hg-opt-status">-C</option> option to <command role="hg-cmd">hg status</command>, it |
belaran@964 | 224 prints another line of output: this is the file that our newly-added |
belaran@964 | 225 file was copied <emphasis>from</emphasis>. |
belaran@964 | 226 <!-- &interaction.daily.copy.status-copy; --> |
belaran@964 | 227 </para> |
belaran@964 | 228 |
belaran@964 | 229 <para>Now, back in the repository we cloned, let's make a change in |
belaran@964 | 230 parallel. We'll add a line of content to the original file that we |
belaran@964 | 231 created. |
belaran@964 | 232 <!-- &interaction.daily.copy.other; --> |
belaran@964 | 233 Now we have a modified <filename>file</filename> in this repository. When we |
belaran@964 | 234 pull the changes from the first repository, and merge the two heads, |
belaran@964 | 235 Mercurial will propagate the changes that we made locally to |
belaran@964 | 236 <filename>file</filename> into its copy, <filename>new-file</filename>. |
belaran@964 | 237 <!-- &interaction.daily.copy.merge; --> |
belaran@964 | 238 </para> |
belaran@964 | 239 |
belaran@964 | 240 </sect2> |
belaran@964 | 241 <sect2> |
belaran@964 | 242 <title>Why should changes follow copies?</title> |
belaran@964 | 243 <para>\label{sec:daily:why-copy} |
belaran@964 | 244 </para> |
belaran@964 | 245 |
belaran@964 | 246 <para>This behaviour, of changes to a file propagating out to copies of the |
belaran@964 | 247 file, might seem esoteric, but in most cases it's highly desirable. |
belaran@964 | 248 </para> |
belaran@964 | 249 |
belaran@964 | 250 <para>First of all, remember that this propagation <emphasis>only</emphasis> happens when |
belaran@964 | 251 you merge. So if you <command role="hg-cmd">hg copy</command> a file, and subsequently modify the |
belaran@964 | 252 original file during the normal course of your work, nothing will |
belaran@964 | 253 happen. |
belaran@964 | 254 </para> |
belaran@964 | 255 |
belaran@964 | 256 <para>The second thing to know is that modifications will only propagate |
belaran@964 | 257 across a copy as long as the repository that you're pulling changes |
belaran@964 | 258 from <emphasis>doesn't know</emphasis> about the copy. |
belaran@964 | 259 </para> |
belaran@964 | 260 |
belaran@964 | 261 <para>The reason that Mercurial does this is as follows. Let's say I make |
belaran@964 | 262 an important bug fix in a source file, and commit my changes. |
belaran@964 | 263 Meanwhile, you've decided to <command role="hg-cmd">hg copy</command> the file in your repository, |
belaran@964 | 264 without knowing about the bug or having seen the fix, and you have |
belaran@964 | 265 started hacking on your copy of the file. |
belaran@964 | 266 </para> |
belaran@964 | 267 |
belaran@964 | 268 <para>If you pulled and merged my changes, and Mercurial <emphasis>didn't</emphasis> |
belaran@964 | 269 propagate changes across copies, your source file would now contain |
belaran@964 | 270 the bug, and unless you remembered to propagate the bug fix by hand, |
belaran@964 | 271 the bug would <emphasis>remain</emphasis> in your copy of the file. |
belaran@964 | 272 </para> |
belaran@964 | 273 |
belaran@964 | 274 <para>By automatically propagating the change that fixed the bug from the |
belaran@964 | 275 original file to the copy, Mercurial prevents this class of problem. |
belaran@964 | 276 To my knowledge, Mercurial is the <emphasis>only</emphasis> revision control system |
belaran@964 | 277 that propagates changes across copies like this. |
belaran@964 | 278 </para> |
belaran@964 | 279 |
belaran@964 | 280 <para>Once your change history has a record that the copy and subsequent |
belaran@964 | 281 merge occurred, there's usually no further need to propagate changes |
belaran@964 | 282 from the original file to the copied file, and that's why Mercurial |
belaran@964 | 283 only propagates changes across copies until this point, and no |
belaran@964 | 284 further. |
belaran@964 | 285 </para> |
belaran@964 | 286 |
belaran@964 | 287 </sect2> |
belaran@964 | 288 <sect2> |
belaran@964 | 289 <title>How to make changes <emphasis>not</emphasis> follow a copy</title> |
belaran@964 | 290 |
belaran@964 | 291 <para>If, for some reason, you decide that this business of automatically |
belaran@964 | 292 propagating changes across copies is not for you, simply use your |
belaran@964 | 293 system's normal file copy command (on Unix-like systems, that's |
belaran@964 | 294 <command>cp</command>) to make a copy of a file, then <command role="hg-cmd">hg add</command> the new copy |
belaran@964 | 295 by hand. Before you do so, though, please do reread |
belaran@964 | 296 section <xref linkend="sec:daily:why-copy"/>, and make an informed decision that |
belaran@964 | 297 this behaviour is not appropriate to your specific case. |
belaran@964 | 298 </para> |
belaran@964 | 299 |
belaran@964 | 300 </sect2> |
belaran@964 | 301 <sect2> |
belaran@964 | 302 <title>Behaviour of the <command role="hg-cmd">hg copy</command> command</title> |
belaran@964 | 303 |
belaran@964 | 304 <para>When you use the <command role="hg-cmd">hg copy</command> command, Mercurial makes a copy of each |
belaran@964 | 305 source file as it currently stands in the working directory. This |
belaran@964 | 306 means that if you make some modifications to a file, then <command role="hg-cmd">hg copy</command> |
belaran@964 | 307 it without first having committed those changes, the new copy will |
belaran@964 | 308 also contain the modifications you have made up until that point. (I |
belaran@964 | 309 find this behaviour a little counterintuitive, which is why I mention |
belaran@964 | 310 it here.) |
belaran@964 | 311 </para> |
belaran@964 | 312 |
belaran@964 | 313 <para>The <command role="hg-cmd">hg copy</command> command acts similarly to the Unix <command>cp</command> |
belaran@964 | 314 command (you can use the <command role="hg-cmd">hg cp</command> alias if you prefer). The last |
belaran@964 | 315 argument is the <emphasis>destination</emphasis>, and all prior arguments are |
belaran@964 | 316 <emphasis>sources</emphasis>. If you pass it a single file as the source, and the |
belaran@964 | 317 destination does not exist, it creates a new file with that name. |
belaran@964 | 318 <!-- &interaction.daily.copy.simple; --> |
belaran@964 | 319 If the destination is a directory, Mercurial copies its sources into |
belaran@964 | 320 that directory. |
belaran@964 | 321 <!-- &interaction.daily.copy.dir-dest; --> |
belaran@964 | 322 Copying a directory is recursive, and preserves the directory |
belaran@964 | 323 structure of the source. |
belaran@964 | 324 <!-- &interaction.daily.copy.dir-src; --> |
belaran@964 | 325 If the source and destination are both directories, the source tree is |
belaran@964 | 326 recreated in the destination directory. |
belaran@964 | 327 <!-- &interaction.daily.copy.dir-src-dest; --> |
belaran@964 | 328 </para> |
belaran@964 | 329 |
belaran@964 | 330 <para>As with the <command role="hg-cmd">hg rename</command> command, if you copy a file manually and |
belaran@964 | 331 then want Mercurial to know that you've copied the file, simply use |
belaran@964 | 332 the <option role="hg-opt-copy">--after</option> option to <command role="hg-cmd">hg copy</command>. |
belaran@964 | 333 <!-- &interaction.daily.copy.after; --> |
belaran@964 | 334 </para> |
belaran@964 | 335 |
belaran@964 | 336 </sect2> |
belaran@964 | 337 </sect1> |
belaran@964 | 338 <sect1> |
belaran@964 | 339 <title>Renaming files</title> |
belaran@964 | 340 |
belaran@964 | 341 <para>It's rather more common to need to rename a file than to make a copy |
belaran@964 | 342 of it. The reason I discussed the <command role="hg-cmd">hg copy</command> command before talking |
belaran@964 | 343 about renaming files is that Mercurial treats a rename in essentially |
belaran@964 | 344 the same way as a copy. Therefore, knowing what Mercurial does when |
belaran@964 | 345 you copy a file tells you what to expect when you rename a file. |
belaran@964 | 346 </para> |
belaran@964 | 347 |
belaran@964 | 348 <para>When you use the <command role="hg-cmd">hg rename</command> command, Mercurial makes a copy of |
belaran@964 | 349 each source file, then deletes it and marks the file as removed. |
belaran@964 | 350 <!-- &interaction.daily.rename.rename; --> |
belaran@964 | 351 The <command role="hg-cmd">hg status</command> command shows the newly copied file as added, and |
belaran@964 | 352 the copied-from file as removed. |
belaran@964 | 353 <!-- &interaction.daily.rename.status; --> |
belaran@964 | 354 As with the results of a <command role="hg-cmd">hg copy</command>, we must use the |
belaran@964 | 355 <option role="hg-opt-status">-C</option> option to <command role="hg-cmd">hg status</command> to see that the added file |
belaran@964 | 356 is really being tracked by Mercurial as a copy of the original, now |
belaran@964 | 357 removed, file. |
belaran@964 | 358 <!-- &interaction.daily.rename.status-copy; --> |
belaran@964 | 359 </para> |
belaran@964 | 360 |
belaran@964 | 361 <para>As with <command role="hg-cmd">hg remove</command> and <command role="hg-cmd">hg copy</command>, you can tell Mercurial about |
belaran@964 | 362 a rename after the fact using the <option role="hg-opt-rename">--after</option> option. In |
belaran@964 | 363 most other respects, the behaviour of the <command role="hg-cmd">hg rename</command> command, and |
belaran@964 | 364 the options it accepts, are similar to the <command role="hg-cmd">hg copy</command> command. |
belaran@964 | 365 </para> |
belaran@964 | 366 |
belaran@964 | 367 <sect2> |
belaran@964 | 368 <title>Renaming files and merging changes</title> |
belaran@964 | 369 |
belaran@964 | 370 <para>Since Mercurial's rename is implemented as copy-and-remove, the same |
belaran@964 | 371 propagation of changes happens when you merge after a rename as after |
belaran@964 | 372 a copy. |
belaran@964 | 373 </para> |
belaran@964 | 374 |
belaran@964 | 375 <para>If I modify a file, and you rename it to a new name, and then we merge |
belaran@964 | 376 our respective changes, my modifications to the file under its |
belaran@964 | 377 original name will be propagated into the file under its new name. |
belaran@964 | 378 (This is something you might expect to <quote>simply work,</quote> but not all |
belaran@964 | 379 revision control systems actually do this.) |
belaran@964 | 380 </para> |
belaran@964 | 381 |
belaran@964 | 382 <para>Whereas having changes follow a copy is a feature where you can |
belaran@964 | 383 perhaps nod and say <quote>yes, that might be useful,</quote> it should be clear |
belaran@964 | 384 that having them follow a rename is definitely important. Without |
belaran@964 | 385 this facility, it would simply be too easy for changes to become |
belaran@964 | 386 orphaned when files are renamed. |
belaran@964 | 387 </para> |
belaran@964 | 388 |
belaran@964 | 389 </sect2> |
belaran@964 | 390 <sect2> |
belaran@964 | 391 <title>Divergent renames and merging</title> |
belaran@964 | 392 |
belaran@964 | 393 <para>The case of diverging names occurs when two developers start with a |
belaran@964 | 394 file&emdash;let's call it <filename>foo</filename>&emdash;in their respective |
belaran@964 | 395 repositories. |
belaran@964 | 396 </para> |
belaran@964 | 397 |
belaran@964 | 398 <para><!-- &interaction.rename.divergent.clone; --> |
belaran@964 | 399 Anne renames the file to <filename>bar</filename>. |
belaran@964 | 400 <!-- &interaction.rename.divergent.rename.anne; --> |
belaran@964 | 401 Meanwhile, Bob renames it to <filename>quux</filename>. |
belaran@964 | 402 <!-- &interaction.rename.divergent.rename.bob; --> |
belaran@964 | 403 </para> |
belaran@964 | 404 |
belaran@964 | 405 <para>I like to think of this as a conflict because each developer has |
belaran@964 | 406 expressed different intentions about what the file ought to be named. |
belaran@964 | 407 </para> |
belaran@964 | 408 |
belaran@964 | 409 <para>What do you think should happen when they merge their work? |
belaran@964 | 410 Mercurial's actual behaviour is that it always preserves <emphasis>both</emphasis> |
belaran@964 | 411 names when it merges changesets that contain divergent renames. |
belaran@964 | 412 <!-- &interaction.rename.divergent.merge; --> |
belaran@964 | 413 </para> |
belaran@964 | 414 |
belaran@964 | 415 <para>Notice that Mercurial does warn about the divergent renames, but it |
belaran@964 | 416 leaves it up to you to do something about the divergence after the merge. |
belaran@964 | 417 </para> |
belaran@964 | 418 |
belaran@964 | 419 </sect2> |
belaran@964 | 420 <sect2> |
belaran@964 | 421 <title>Convergent renames and merging</title> |
belaran@964 | 422 |
belaran@964 | 423 <para>Another kind of rename conflict occurs when two people choose to |
belaran@964 | 424 rename different <emphasis>source</emphasis> files to the same <emphasis>destination</emphasis>. |
belaran@964 | 425 In this case, Mercurial runs its normal merge machinery, and lets you |
belaran@964 | 426 guide it to a suitable resolution. |
belaran@964 | 427 </para> |
belaran@964 | 428 |
belaran@964 | 429 </sect2> |
belaran@964 | 430 <sect2> |
belaran@964 | 431 <title>Other name-related corner cases</title> |
belaran@964 | 432 |
belaran@964 | 433 <para>Mercurial has a longstanding bug in which it fails to handle a merge |
belaran@964 | 434 where one side has a file with a given name, while another has a |
belaran@964 | 435 directory with the same name. This is documented as <ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue29">issue 29</ulink>. |
belaran@964 | 436 <!-- &interaction.issue29.go; --> |
belaran@964 | 437 </para> |
belaran@964 | 438 |
belaran@964 | 439 </sect2> |
belaran@964 | 440 </sect1> |
belaran@964 | 441 <sect1> |
belaran@964 | 442 <title>Recovering from mistakes</title> |
belaran@964 | 443 |
belaran@964 | 444 <para>Mercurial has some useful commands that will help you to recover from |
belaran@964 | 445 some common mistakes. |
belaran@964 | 446 </para> |
belaran@964 | 447 |
belaran@964 | 448 <para>The <command role="hg-cmd">hg revert</command> command lets you undo changes that you have made to |
belaran@964 | 449 your working directory. For example, if you <command role="hg-cmd">hg add</command> a file by |
belaran@964 | 450 accident, just run <command role="hg-cmd">hg revert</command> with the name of the file you added, |
belaran@964 | 451 and while the file won't be touched in any way, it won't be tracked |
belaran@964 | 452 for adding by Mercurial any longer, either. You can also use |
belaran@964 | 453 <command role="hg-cmd">hg revert</command> to get rid of erroneous changes to a file. |
belaran@964 | 454 </para> |
belaran@964 | 455 |
belaran@964 | 456 <para>It's useful to remember that the <command role="hg-cmd">hg revert</command> command is useful for |
belaran@964 | 457 changes that you have not yet committed. Once you've committed a |
belaran@964 | 458 change, if you decide it was a mistake, you can still do something |
belaran@964 | 459 about it, though your options may be more limited. |
belaran@964 | 460 </para> |
belaran@964 | 461 |
belaran@964 | 462 <para>For more information about the <command role="hg-cmd">hg revert</command> command, and details |
belaran@964 | 463 about how to deal with changes you have already committed, see |
belaran@964 | 464 chapter <xref linkend="chap:undo"/>. |
belaran@964 | 465 </para> |
belaran@964 | 466 |
belaran@964 | 467 </sect1> |
belaran@964 | 468 </chapter> |
belaran@964 | 469 |
belaran@964 | 470 <!-- |
belaran@964 | 471 local variables: |
belaran@964 | 472 sgml-parent-document: ("00book.xml" "book" "chapter") |
belaran@964 | 473 end: |
belaran@964 | 474 --> |