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