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