##// END OF EJS Templates
copies: distinguish between merged and touched files during upgrade...
marmoute -
r47571:433cef8f default
parent child Browse files
Show More
@@ -1,958 +1,966 b''
1 # coding: utf-8
1 # coding: utf-8
2 # metadata.py -- code related to various metadata computation and access.
2 # metadata.py -- code related to various metadata computation and access.
3 #
3 #
4 # Copyright 2019 Google, Inc <martinvonz@google.com>
4 # Copyright 2019 Google, Inc <martinvonz@google.com>
5 # Copyright 2020 Pierre-Yves David <pierre-yves.david@octobus.net>
5 # Copyright 2020 Pierre-Yves David <pierre-yves.david@octobus.net>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9 from __future__ import absolute_import, print_function
9 from __future__ import absolute_import, print_function
10
10
11 import multiprocessing
11 import multiprocessing
12 import struct
12 import struct
13
13
14 from .node import (
14 from .node import (
15 nullid,
15 nullid,
16 nullrev,
16 nullrev,
17 )
17 )
18 from . import (
18 from . import (
19 error,
19 error,
20 pycompat,
20 pycompat,
21 requirements as requirementsmod,
21 requirements as requirementsmod,
22 util,
22 util,
23 )
23 )
24
24
25 from .revlogutils import (
25 from .revlogutils import (
26 flagutil as sidedataflag,
26 flagutil as sidedataflag,
27 sidedata as sidedatamod,
27 sidedata as sidedatamod,
28 )
28 )
29
29
30
30
31 class ChangingFiles(object):
31 class ChangingFiles(object):
32 """A class recording the changes made to files by a changeset
32 """A class recording the changes made to files by a changeset
33
33
34 Actions performed on files are gathered into 3 sets:
34 Actions performed on files are gathered into 3 sets:
35
35
36 - added: files actively added in the changeset.
36 - added: files actively added in the changeset.
37 - merged: files whose history got merged
37 - merged: files whose history got merged
38 - removed: files removed in the revision
38 - removed: files removed in the revision
39 - salvaged: files that might have been deleted by a merge but were not
39 - salvaged: files that might have been deleted by a merge but were not
40 - touched: files affected by the merge
40 - touched: files affected by the merge
41
41
42 and copies information is held by 2 mappings
42 and copies information is held by 2 mappings
43
43
44 - copied_from_p1: {"<new-name>": "<source-name-in-p1>"} mapping for copies
44 - copied_from_p1: {"<new-name>": "<source-name-in-p1>"} mapping for copies
45 - copied_from_p2: {"<new-name>": "<source-name-in-p2>"} mapping for copies
45 - copied_from_p2: {"<new-name>": "<source-name-in-p2>"} mapping for copies
46
46
47 See their inline help for details.
47 See their inline help for details.
48 """
48 """
49
49
50 def __init__(
50 def __init__(
51 self,
51 self,
52 touched=None,
52 touched=None,
53 added=None,
53 added=None,
54 removed=None,
54 removed=None,
55 merged=None,
55 merged=None,
56 salvaged=None,
56 salvaged=None,
57 p1_copies=None,
57 p1_copies=None,
58 p2_copies=None,
58 p2_copies=None,
59 ):
59 ):
60 self._added = set(() if added is None else added)
60 self._added = set(() if added is None else added)
61 self._merged = set(() if merged is None else merged)
61 self._merged = set(() if merged is None else merged)
62 self._removed = set(() if removed is None else removed)
62 self._removed = set(() if removed is None else removed)
63 self._touched = set(() if touched is None else touched)
63 self._touched = set(() if touched is None else touched)
64 self._salvaged = set(() if salvaged is None else salvaged)
64 self._salvaged = set(() if salvaged is None else salvaged)
65 self._touched.update(self._added)
65 self._touched.update(self._added)
66 self._touched.update(self._merged)
66 self._touched.update(self._merged)
67 self._touched.update(self._removed)
67 self._touched.update(self._removed)
68 self._p1_copies = dict(() if p1_copies is None else p1_copies)
68 self._p1_copies = dict(() if p1_copies is None else p1_copies)
69 self._p2_copies = dict(() if p2_copies is None else p2_copies)
69 self._p2_copies = dict(() if p2_copies is None else p2_copies)
70
70
71 def __eq__(self, other):
71 def __eq__(self, other):
72 return (
72 return (
73 self.added == other.added
73 self.added == other.added
74 and self.merged == other.merged
74 and self.merged == other.merged
75 and self.removed == other.removed
75 and self.removed == other.removed
76 and self.salvaged == other.salvaged
76 and self.salvaged == other.salvaged
77 and self.touched == other.touched
77 and self.touched == other.touched
78 and self.copied_from_p1 == other.copied_from_p1
78 and self.copied_from_p1 == other.copied_from_p1
79 and self.copied_from_p2 == other.copied_from_p2
79 and self.copied_from_p2 == other.copied_from_p2
80 )
80 )
81
81
82 @property
82 @property
83 def has_copies_info(self):
83 def has_copies_info(self):
84 return bool(
84 return bool(
85 self.removed
85 self.removed
86 or self.merged
86 or self.merged
87 or self.salvaged
87 or self.salvaged
88 or self.copied_from_p1
88 or self.copied_from_p1
89 or self.copied_from_p2
89 or self.copied_from_p2
90 )
90 )
91
91
92 @util.propertycache
92 @util.propertycache
93 def added(self):
93 def added(self):
94 """files actively added in the changeset
94 """files actively added in the changeset
95
95
96 Any file present in that revision that was absent in all the changeset's
96 Any file present in that revision that was absent in all the changeset's
97 parents.
97 parents.
98
98
99 In case of merge, this means a file absent in one of the parents but
99 In case of merge, this means a file absent in one of the parents but
100 existing in the other will *not* be contained in this set. (They were
100 existing in the other will *not* be contained in this set. (They were
101 added by an ancestor)
101 added by an ancestor)
102 """
102 """
103 return frozenset(self._added)
103 return frozenset(self._added)
104
104
105 def mark_added(self, filename):
105 def mark_added(self, filename):
106 if 'added' in vars(self):
106 if 'added' in vars(self):
107 del self.added
107 del self.added
108 self._added.add(filename)
108 self._added.add(filename)
109 self.mark_touched(filename)
109 self.mark_touched(filename)
110
110
111 def update_added(self, filenames):
111 def update_added(self, filenames):
112 for f in filenames:
112 for f in filenames:
113 self.mark_added(f)
113 self.mark_added(f)
114
114
115 @util.propertycache
115 @util.propertycache
116 def merged(self):
116 def merged(self):
117 """files actively merged during a merge
117 """files actively merged during a merge
118
118
119 Any modified files which had modification on both size that needed merging.
119 Any modified files which had modification on both size that needed merging.
120
120
121 In this case a new filenode was created and it has two parents.
121 In this case a new filenode was created and it has two parents.
122 """
122 """
123 return frozenset(self._merged)
123 return frozenset(self._merged)
124
124
125 def mark_merged(self, filename):
125 def mark_merged(self, filename):
126 if 'merged' in vars(self):
126 if 'merged' in vars(self):
127 del self.merged
127 del self.merged
128 self._merged.add(filename)
128 self._merged.add(filename)
129 self.mark_touched(filename)
129 self.mark_touched(filename)
130
130
131 def update_merged(self, filenames):
131 def update_merged(self, filenames):
132 for f in filenames:
132 for f in filenames:
133 self.mark_merged(f)
133 self.mark_merged(f)
134
134
135 @util.propertycache
135 @util.propertycache
136 def removed(self):
136 def removed(self):
137 """files actively removed by the changeset
137 """files actively removed by the changeset
138
138
139 In case of merge this will only contain the set of files removing "new"
139 In case of merge this will only contain the set of files removing "new"
140 content. For any file absent in the current changeset:
140 content. For any file absent in the current changeset:
141
141
142 a) If the file exists in both parents, it is clearly "actively" removed
142 a) If the file exists in both parents, it is clearly "actively" removed
143 by this changeset.
143 by this changeset.
144
144
145 b) If a file exists in only one parent and in none of the common
145 b) If a file exists in only one parent and in none of the common
146 ancestors, then the file was newly added in one of the merged branches
146 ancestors, then the file was newly added in one of the merged branches
147 and then got "actively" removed.
147 and then got "actively" removed.
148
148
149 c) If a file exists in only one parent and at least one of the common
149 c) If a file exists in only one parent and at least one of the common
150 ancestors using the same filenode, then the file was unchanged on one
150 ancestors using the same filenode, then the file was unchanged on one
151 side and deleted on the other side. The merge "passively" propagated
151 side and deleted on the other side. The merge "passively" propagated
152 that deletion, but didn't "actively" remove the file. In this case the
152 that deletion, but didn't "actively" remove the file. In this case the
153 file is *not* included in the `removed` set.
153 file is *not* included in the `removed` set.
154
154
155 d) If a file exists in only one parent and at least one of the common
155 d) If a file exists in only one parent and at least one of the common
156 ancestors using a different filenode, then the file was changed on one
156 ancestors using a different filenode, then the file was changed on one
157 side and removed on the other side. The merge process "actively"
157 side and removed on the other side. The merge process "actively"
158 decided to drop the new change and delete the file. Unlike in the
158 decided to drop the new change and delete the file. Unlike in the
159 previous case, (c), the file included in the `removed` set.
159 previous case, (c), the file included in the `removed` set.
160
160
161 Summary table for merge:
161 Summary table for merge:
162
162
163 case | exists in parents | exists in gca || removed
163 case | exists in parents | exists in gca || removed
164 (a) | both | * || yes
164 (a) | both | * || yes
165 (b) | one | none || yes
165 (b) | one | none || yes
166 (c) | one | same filenode || no
166 (c) | one | same filenode || no
167 (d) | one | new filenode || yes
167 (d) | one | new filenode || yes
168 """
168 """
169 return frozenset(self._removed)
169 return frozenset(self._removed)
170
170
171 def mark_removed(self, filename):
171 def mark_removed(self, filename):
172 if 'removed' in vars(self):
172 if 'removed' in vars(self):
173 del self.removed
173 del self.removed
174 self._removed.add(filename)
174 self._removed.add(filename)
175 self.mark_touched(filename)
175 self.mark_touched(filename)
176
176
177 def update_removed(self, filenames):
177 def update_removed(self, filenames):
178 for f in filenames:
178 for f in filenames:
179 self.mark_removed(f)
179 self.mark_removed(f)
180
180
181 @util.propertycache
181 @util.propertycache
182 def salvaged(self):
182 def salvaged(self):
183 """files that might have been deleted by a merge, but still exists.
183 """files that might have been deleted by a merge, but still exists.
184
184
185 During a merge, the manifest merging might select some files for
185 During a merge, the manifest merging might select some files for
186 removal, or for a removed/changed conflict. If at commit time the file
186 removal, or for a removed/changed conflict. If at commit time the file
187 still exists, its removal was "reverted" and the file is "salvaged"
187 still exists, its removal was "reverted" and the file is "salvaged"
188 """
188 """
189 return frozenset(self._salvaged)
189 return frozenset(self._salvaged)
190
190
191 def mark_salvaged(self, filename):
191 def mark_salvaged(self, filename):
192 if "salvaged" in vars(self):
192 if "salvaged" in vars(self):
193 del self.salvaged
193 del self.salvaged
194 self._salvaged.add(filename)
194 self._salvaged.add(filename)
195 self.mark_touched(filename)
195 self.mark_touched(filename)
196
196
197 def update_salvaged(self, filenames):
197 def update_salvaged(self, filenames):
198 for f in filenames:
198 for f in filenames:
199 self.mark_salvaged(f)
199 self.mark_salvaged(f)
200
200
201 @util.propertycache
201 @util.propertycache
202 def touched(self):
202 def touched(self):
203 """files either actively modified, added or removed"""
203 """files either actively modified, added or removed"""
204 return frozenset(self._touched)
204 return frozenset(self._touched)
205
205
206 def mark_touched(self, filename):
206 def mark_touched(self, filename):
207 if 'touched' in vars(self):
207 if 'touched' in vars(self):
208 del self.touched
208 del self.touched
209 self._touched.add(filename)
209 self._touched.add(filename)
210
210
211 def update_touched(self, filenames):
211 def update_touched(self, filenames):
212 for f in filenames:
212 for f in filenames:
213 self.mark_touched(f)
213 self.mark_touched(f)
214
214
215 @util.propertycache
215 @util.propertycache
216 def copied_from_p1(self):
216 def copied_from_p1(self):
217 return self._p1_copies.copy()
217 return self._p1_copies.copy()
218
218
219 def mark_copied_from_p1(self, source, dest):
219 def mark_copied_from_p1(self, source, dest):
220 if 'copied_from_p1' in vars(self):
220 if 'copied_from_p1' in vars(self):
221 del self.copied_from_p1
221 del self.copied_from_p1
222 self._p1_copies[dest] = source
222 self._p1_copies[dest] = source
223
223
224 def update_copies_from_p1(self, copies):
224 def update_copies_from_p1(self, copies):
225 for dest, source in copies.items():
225 for dest, source in copies.items():
226 self.mark_copied_from_p1(source, dest)
226 self.mark_copied_from_p1(source, dest)
227
227
228 @util.propertycache
228 @util.propertycache
229 def copied_from_p2(self):
229 def copied_from_p2(self):
230 return self._p2_copies.copy()
230 return self._p2_copies.copy()
231
231
232 def mark_copied_from_p2(self, source, dest):
232 def mark_copied_from_p2(self, source, dest):
233 if 'copied_from_p2' in vars(self):
233 if 'copied_from_p2' in vars(self):
234 del self.copied_from_p2
234 del self.copied_from_p2
235 self._p2_copies[dest] = source
235 self._p2_copies[dest] = source
236
236
237 def update_copies_from_p2(self, copies):
237 def update_copies_from_p2(self, copies):
238 for dest, source in copies.items():
238 for dest, source in copies.items():
239 self.mark_copied_from_p2(source, dest)
239 self.mark_copied_from_p2(source, dest)
240
240
241
241
242 def compute_all_files_changes(ctx):
242 def compute_all_files_changes(ctx):
243 """compute the files changed by a revision"""
243 """compute the files changed by a revision"""
244 p1 = ctx.p1()
244 p1 = ctx.p1()
245 p2 = ctx.p2()
245 p2 = ctx.p2()
246 if p1.rev() == nullrev and p2.rev() == nullrev:
246 if p1.rev() == nullrev and p2.rev() == nullrev:
247 return _process_root(ctx)
247 return _process_root(ctx)
248 elif p1.rev() != nullrev and p2.rev() == nullrev:
248 elif p1.rev() != nullrev and p2.rev() == nullrev:
249 return _process_linear(p1, ctx)
249 return _process_linear(p1, ctx)
250 elif p1.rev() == nullrev and p2.rev() != nullrev:
250 elif p1.rev() == nullrev and p2.rev() != nullrev:
251 # In the wild, one can encounter changeset where p1 is null but p2 is not
251 # In the wild, one can encounter changeset where p1 is null but p2 is not
252 return _process_linear(p1, ctx, parent=2)
252 return _process_linear(p1, ctx, parent=2)
253 elif p1.rev() == p2.rev():
253 elif p1.rev() == p2.rev():
254 # In the wild, one can encounter such "non-merge"
254 # In the wild, one can encounter such "non-merge"
255 return _process_linear(p1, ctx)
255 return _process_linear(p1, ctx)
256 else:
256 else:
257 return _process_merge(p1, p2, ctx)
257 return _process_merge(p1, p2, ctx)
258
258
259
259
260 def _process_root(ctx):
260 def _process_root(ctx):
261 """compute the appropriate changed files for a changeset with no parents"""
261 """compute the appropriate changed files for a changeset with no parents"""
262 # Simple, there was nothing before it, so everything is added.
262 # Simple, there was nothing before it, so everything is added.
263 md = ChangingFiles()
263 md = ChangingFiles()
264 manifest = ctx.manifest()
264 manifest = ctx.manifest()
265 for filename in manifest:
265 for filename in manifest:
266 md.mark_added(filename)
266 md.mark_added(filename)
267 return md
267 return md
268
268
269
269
270 def _process_linear(parent_ctx, children_ctx, parent=1):
270 def _process_linear(parent_ctx, children_ctx, parent=1):
271 """compute the appropriate changed files for a changeset with a single parent"""
271 """compute the appropriate changed files for a changeset with a single parent"""
272 md = ChangingFiles()
272 md = ChangingFiles()
273 parent_manifest = parent_ctx.manifest()
273 parent_manifest = parent_ctx.manifest()
274 children_manifest = children_ctx.manifest()
274 children_manifest = children_ctx.manifest()
275
275
276 copies_candidate = []
276 copies_candidate = []
277
277
278 for filename, d in parent_manifest.diff(children_manifest).items():
278 for filename, d in parent_manifest.diff(children_manifest).items():
279 if d[1][0] is None:
279 if d[1][0] is None:
280 # no filenode for the "new" value, file is absent
280 # no filenode for the "new" value, file is absent
281 md.mark_removed(filename)
281 md.mark_removed(filename)
282 else:
282 else:
283 copies_candidate.append(filename)
283 copies_candidate.append(filename)
284 if d[0][0] is None:
284 if d[0][0] is None:
285 # not filenode for the "old" value file was absent
285 # not filenode for the "old" value file was absent
286 md.mark_added(filename)
286 md.mark_added(filename)
287 else:
287 else:
288 # filenode for both "old" and "new"
288 # filenode for both "old" and "new"
289 md.mark_touched(filename)
289 md.mark_touched(filename)
290
290
291 if parent == 1:
291 if parent == 1:
292 copied = md.mark_copied_from_p1
292 copied = md.mark_copied_from_p1
293 elif parent == 2:
293 elif parent == 2:
294 copied = md.mark_copied_from_p2
294 copied = md.mark_copied_from_p2
295 else:
295 else:
296 assert False, "bad parent value %d" % parent
296 assert False, "bad parent value %d" % parent
297
297
298 for filename in copies_candidate:
298 for filename in copies_candidate:
299 copy_info = children_ctx[filename].renamed()
299 copy_info = children_ctx[filename].renamed()
300 if copy_info:
300 if copy_info:
301 source, srcnode = copy_info
301 source, srcnode = copy_info
302 copied(source, filename)
302 copied(source, filename)
303
303
304 return md
304 return md
305
305
306
306
307 def _process_merge(p1_ctx, p2_ctx, ctx):
307 def _process_merge(p1_ctx, p2_ctx, ctx):
308 """compute the appropriate changed files for a changeset with two parents
308 """compute the appropriate changed files for a changeset with two parents
309
309
310 This is a more advance case. The information we need to record is summarise
310 This is a more advance case. The information we need to record is summarise
311 in the following table:
311 in the following table:
312
312
313 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
313 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
314 β”‚ diff β•² diff β”‚ ΓΈ β”‚ (Some, None) β”‚ (None, Some) β”‚ (Some, Some) β”‚
314 β”‚ diff β•² diff β”‚ ΓΈ β”‚ (Some, None) β”‚ (None, Some) β”‚ (Some, Some) β”‚
315 β”‚ p2 β•² p1 β”‚ β”‚ β”‚ β”‚ β”‚
315 β”‚ p2 β•² p1 β”‚ β”‚ β”‚ β”‚ β”‚
316 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
316 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
317 β”‚ β”‚ β”‚πŸ„± No Changes β”‚πŸ„³ No Changes β”‚ β”‚
317 β”‚ β”‚ β”‚πŸ„± No Changes β”‚πŸ„³ No Changes β”‚ β”‚
318 β”‚ ΓΈ β”‚πŸ„° No Changes β”‚ OR β”‚ OR β”‚πŸ„΅ No Changes β”‚
318 β”‚ ΓΈ β”‚πŸ„° No Changes β”‚ OR β”‚ OR β”‚πŸ„΅ No Changes β”‚
319 β”‚ β”‚ β”‚πŸ„² Deleted[1] β”‚πŸ„΄ Salvaged[2]β”‚ [3] β”‚
319 β”‚ β”‚ β”‚πŸ„² Deleted[1] β”‚πŸ„΄ Salvaged[2]β”‚ [3] β”‚
320 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
320 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
321 β”‚ β”‚πŸ„Ά No Changes β”‚ β”‚ β”‚ β”‚
321 β”‚ β”‚πŸ„Ά No Changes β”‚ β”‚ β”‚ β”‚
322 β”‚ (Some, None) β”‚ OR β”‚πŸ„» Deleted β”‚ ΓΈ β”‚ ΓΈ β”‚
322 β”‚ (Some, None) β”‚ OR β”‚πŸ„» Deleted β”‚ ΓΈ β”‚ ΓΈ β”‚
323 β”‚ β”‚πŸ„· Deleted[1] β”‚ β”‚ β”‚ β”‚
323 β”‚ β”‚πŸ„· Deleted[1] β”‚ β”‚ β”‚ β”‚
324 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
324 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
325 β”‚ β”‚πŸ„Έ No Changes β”‚ β”‚ β”‚ πŸ„½ Touched β”‚
325 β”‚ β”‚πŸ„Έ No Changes β”‚ β”‚ β”‚ πŸ„½ Touched β”‚
326 β”‚ (None, Some) β”‚ OR β”‚ ΓΈ β”‚πŸ„Ό Added β”‚OR πŸ…€ Salvaged β”‚
326 β”‚ (None, Some) β”‚ OR β”‚ ΓΈ β”‚πŸ„Ό Added β”‚OR πŸ…€ Salvaged β”‚
327 β”‚ β”‚πŸ„Ή Salvaged[2]β”‚ β”‚ (copied?) β”‚ (copied?) β”‚
327 β”‚ β”‚πŸ„Ή Salvaged[2]β”‚ β”‚ (copied?) β”‚ (copied?) β”‚
328 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
328 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
329 β”‚ β”‚ β”‚ β”‚ πŸ„Ύ Touched β”‚ β”‚
329 β”‚ β”‚ β”‚ β”‚ πŸ„Ύ Touched β”‚ πŸ„Ώ Merged β”‚
330 β”‚ (Some, Some) β”‚πŸ„Ί No Changes β”‚ ΓΈ β”‚OR πŸ… Salvaged β”‚πŸ„Ώ Merged β”‚
330 β”‚ (Some, Some) β”‚πŸ„Ί No Changes β”‚ ΓΈ β”‚OR πŸ… Salvaged β”‚OR πŸ…‚ Touched β”‚
331 β”‚ β”‚ [3] β”‚ β”‚ (copied?) β”‚ (copied?) β”‚
331 β”‚ β”‚ [3] β”‚ β”‚ (copied?) β”‚ (copied?) β”‚
332 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
332 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
333
333
334 Special case [1]:
334 Special case [1]:
335
335
336 The situation is:
336 The situation is:
337 - parent-A: file exists,
337 - parent-A: file exists,
338 - parent-B: no file,
338 - parent-B: no file,
339 - working-copy: no file.
339 - working-copy: no file.
340
340
341 Detecting a "deletion" will depend on the presence of actual change on
341 Detecting a "deletion" will depend on the presence of actual change on
342 the "parent-A" branch:
342 the "parent-A" branch:
343
343
344 Subcase πŸ„± or πŸ„Ά : if the state of the file in "parent-A" is unchanged
344 Subcase πŸ„± or πŸ„Ά : if the state of the file in "parent-A" is unchanged
345 compared to the merge ancestors, then parent-A branch left the file
345 compared to the merge ancestors, then parent-A branch left the file
346 untouched while parent-B deleted it. We simply apply the change from
346 untouched while parent-B deleted it. We simply apply the change from
347 "parent-B" branch the file was automatically dropped.
347 "parent-B" branch the file was automatically dropped.
348 The result is:
348 The result is:
349 - file is not recorded as touched by the merge.
349 - file is not recorded as touched by the merge.
350
350
351 Subcase πŸ„² or πŸ„· : otherwise, the change from parent-A branch were explicitly dropped and
351 Subcase πŸ„² or πŸ„· : otherwise, the change from parent-A branch were explicitly dropped and
352 the file was "deleted again". From a user perspective, the message
352 the file was "deleted again". From a user perspective, the message
353 about "locally changed" while "remotely deleted" (or the other way
353 about "locally changed" while "remotely deleted" (or the other way
354 around) was issued and the user chose to deleted the file.
354 around) was issued and the user chose to deleted the file.
355 The result:
355 The result:
356 - file is recorded as touched by the merge.
356 - file is recorded as touched by the merge.
357
357
358
358
359 Special case [2]:
359 Special case [2]:
360
360
361 The situation is:
361 The situation is:
362 - parent-A: no file,
362 - parent-A: no file,
363 - parent-B: file,
363 - parent-B: file,
364 - working-copy: file (same content as parent-B).
364 - working-copy: file (same content as parent-B).
365
365
366 There are three subcases depending on the ancestors contents:
366 There are three subcases depending on the ancestors contents:
367
367
368 - A) the file is missing in all ancestors,
368 - A) the file is missing in all ancestors,
369 - B) at least one ancestor has the file with filenode β‰  from parent-B,
369 - B) at least one ancestor has the file with filenode β‰  from parent-B,
370 - C) all ancestors use the same filenode as parent-B,
370 - C) all ancestors use the same filenode as parent-B,
371
371
372 Subcase (A) is the simpler, nothing happend on parent-A side while
372 Subcase (A) is the simpler, nothing happend on parent-A side while
373 parent-B added it.
373 parent-B added it.
374
374
375 The result:
375 The result:
376 - the file is not marked as touched by the merge.
376 - the file is not marked as touched by the merge.
377
377
378 Subcase (B) is the counter part of "Special case [1]", the file was
378 Subcase (B) is the counter part of "Special case [1]", the file was
379 modified on parent-B side, while parent-A side deleted it. However this
379 modified on parent-B side, while parent-A side deleted it. However this
380 time, the conflict was solved by keeping the file (and its
380 time, the conflict was solved by keeping the file (and its
381 modification). We consider the file as "salvaged".
381 modification). We consider the file as "salvaged".
382
382
383 The result:
383 The result:
384 - the file is marked as "salvaged" by the merge.
384 - the file is marked as "salvaged" by the merge.
385
385
386 Subcase (C) is subtle variation of the case above. In this case, the
386 Subcase (C) is subtle variation of the case above. In this case, the
387 file in unchanged on the parent-B side and actively removed on the
387 file in unchanged on the parent-B side and actively removed on the
388 parent-A side. So the merge machinery correctly decide it should be
388 parent-A side. So the merge machinery correctly decide it should be
389 removed. However, the file was explicitly restored to its parent-B
389 removed. However, the file was explicitly restored to its parent-B
390 content before the merge was commited. The file is be marked
390 content before the merge was commited. The file is be marked
391 as salvaged too. From the merge result perspective, this is similar to
391 as salvaged too. From the merge result perspective, this is similar to
392 Subcase (B), however from the merge resolution perspective they differ
392 Subcase (B), however from the merge resolution perspective they differ
393 since in (C), there was some conflict not obvious solution to the
393 since in (C), there was some conflict not obvious solution to the
394 merge (That got reversed)
394 merge (That got reversed)
395
395
396 Special case [3]:
396 Special case [3]:
397
397
398 The situation is:
398 The situation is:
399 - parent-A: file,
399 - parent-A: file,
400 - parent-B: file (different filenode as parent-A),
400 - parent-B: file (different filenode as parent-A),
401 - working-copy: file (same filenode as parent-B).
401 - working-copy: file (same filenode as parent-B).
402
402
403 This case is in theory much simple, for this to happens, this mean the
403 This case is in theory much simple, for this to happens, this mean the
404 filenode in parent-A is purely replacing the one in parent-B (either a
404 filenode in parent-A is purely replacing the one in parent-B (either a
405 descendant, or a full new file history, see changeset). So the merge
405 descendant, or a full new file history, see changeset). So the merge
406 introduce no changes, and the file is not affected by the merge...
406 introduce no changes, and the file is not affected by the merge...
407
407
408 However, in the wild it is possible to find commit with the above is not
408 However, in the wild it is possible to find commit with the above is not
409 True. For example repository have some commit where the *new* node is an
409 True. For example repository have some commit where the *new* node is an
410 ancestor of the node in parent-A, or where parent-A and parent-B are two
410 ancestor of the node in parent-A, or where parent-A and parent-B are two
411 branches of the same file history, yet not merge-filenode were created
411 branches of the same file history, yet not merge-filenode were created
412 (while the "merge" should have led to a "modification").
412 (while the "merge" should have led to a "modification").
413
413
414 Detecting such cases (and not recording the file as modified) would be a
414 Detecting such cases (and not recording the file as modified) would be a
415 nice bonus. However do not any of this yet.
415 nice bonus. However do not any of this yet.
416 """
416 """
417
417
418 repo = ctx.repo()
418 md = ChangingFiles()
419 md = ChangingFiles()
419
420
420 m = ctx.manifest()
421 m = ctx.manifest()
421 p1m = p1_ctx.manifest()
422 p1m = p1_ctx.manifest()
422 p2m = p2_ctx.manifest()
423 p2m = p2_ctx.manifest()
423 diff_p1 = p1m.diff(m)
424 diff_p1 = p1m.diff(m)
424 diff_p2 = p2m.diff(m)
425 diff_p2 = p2m.diff(m)
425
426
426 cahs = ctx.repo().changelog.commonancestorsheads(
427 cahs = ctx.repo().changelog.commonancestorsheads(
427 p1_ctx.node(), p2_ctx.node()
428 p1_ctx.node(), p2_ctx.node()
428 )
429 )
429 if not cahs:
430 if not cahs:
430 cahs = [nullrev]
431 cahs = [nullrev]
431 mas = [ctx.repo()[r].manifest() for r in cahs]
432 mas = [ctx.repo()[r].manifest() for r in cahs]
432
433
433 copy_candidates = []
434 copy_candidates = []
434
435
435 # Dealing with case πŸ„° happens automatically. Since there are no entry in
436 # Dealing with case πŸ„° happens automatically. Since there are no entry in
436 # d1 nor d2, we won't iterate on it ever.
437 # d1 nor d2, we won't iterate on it ever.
437
438
438 # Iteration over d1 content will deal with all cases, but the one in the
439 # Iteration over d1 content will deal with all cases, but the one in the
439 # first column of the table.
440 # first column of the table.
440 for filename, d1 in diff_p1.items():
441 for filename, d1 in diff_p1.items():
441
442
442 d2 = diff_p2.pop(filename, None)
443 d2 = diff_p2.pop(filename, None)
443
444
444 if d2 is None:
445 if d2 is None:
445 # this deal with the first line of the table.
446 # this deal with the first line of the table.
446 _process_other_unchanged(md, mas, filename, d1)
447 _process_other_unchanged(md, mas, filename, d1)
447 else:
448 else:
448
449
449 if d1[0][0] is None and d2[0][0] is None:
450 if d1[0][0] is None and d2[0][0] is None:
450 # case πŸ„Ό β€” both deleted the file.
451 # case πŸ„Ό β€” both deleted the file.
451 md.mark_added(filename)
452 md.mark_added(filename)
452 copy_candidates.append(filename)
453 copy_candidates.append(filename)
453 elif d1[1][0] is None and d2[1][0] is None:
454 elif d1[1][0] is None and d2[1][0] is None:
454 # case πŸ„» β€” both deleted the file.
455 # case πŸ„» β€” both deleted the file.
455 md.mark_removed(filename)
456 md.mark_removed(filename)
456 elif d1[1][0] is not None and d2[1][0] is not None:
457 elif d1[1][0] is not None and d2[1][0] is not None:
457 if d1[0][0] is None or d2[0][0] is None:
458 if d1[0][0] is None or d2[0][0] is None:
458 if any(_find(ma, filename) is not None for ma in mas):
459 if any(_find(ma, filename) is not None for ma in mas):
459 # case πŸ…€ or πŸ…
460 # case πŸ…€ or πŸ…
460 md.mark_salvaged(filename)
461 md.mark_salvaged(filename)
461 else:
462 else:
462 # case πŸ„½ πŸ„Ύ : touched
463 # case πŸ„½ πŸ„Ύ : touched
463 md.mark_touched(filename)
464 md.mark_touched(filename)
464 else:
465 else:
465 # case πŸ„Ώ : merged
466 fctx = repo.filectx(filename, fileid=d1[1][0])
466 md.mark_merged(filename)
467 if fctx.p2().rev() == nullrev:
468 # case πŸ…‚
469 # lets assume we can trust the file history. If the
470 # filenode is not a merge, the file was not merged.
471 md.mark_touched(filename)
472 else:
473 # case πŸ„Ώ
474 md.mark_merged(filename)
467 copy_candidates.append(filename)
475 copy_candidates.append(filename)
468 else:
476 else:
469 # Impossible case, the post-merge file status cannot be None on
477 # Impossible case, the post-merge file status cannot be None on
470 # one side and Something on the other side.
478 # one side and Something on the other side.
471 assert False, "unreachable"
479 assert False, "unreachable"
472
480
473 # Iteration over remaining d2 content deal with the first column of the
481 # Iteration over remaining d2 content deal with the first column of the
474 # table.
482 # table.
475 for filename, d2 in diff_p2.items():
483 for filename, d2 in diff_p2.items():
476 _process_other_unchanged(md, mas, filename, d2)
484 _process_other_unchanged(md, mas, filename, d2)
477
485
478 for filename in copy_candidates:
486 for filename in copy_candidates:
479 copy_info = ctx[filename].renamed()
487 copy_info = ctx[filename].renamed()
480 if copy_info:
488 if copy_info:
481 source, srcnode = copy_info
489 source, srcnode = copy_info
482 if source in p1_ctx and p1_ctx[source].filenode() == srcnode:
490 if source in p1_ctx and p1_ctx[source].filenode() == srcnode:
483 md.mark_copied_from_p1(source, filename)
491 md.mark_copied_from_p1(source, filename)
484 elif source in p2_ctx and p2_ctx[source].filenode() == srcnode:
492 elif source in p2_ctx and p2_ctx[source].filenode() == srcnode:
485 md.mark_copied_from_p2(source, filename)
493 md.mark_copied_from_p2(source, filename)
486 return md
494 return md
487
495
488
496
489 def _find(manifest, filename):
497 def _find(manifest, filename):
490 """return the associate filenode or None"""
498 """return the associate filenode or None"""
491 if filename not in manifest:
499 if filename not in manifest:
492 return None
500 return None
493 return manifest.find(filename)[0]
501 return manifest.find(filename)[0]
494
502
495
503
496 def _process_other_unchanged(md, mas, filename, diff):
504 def _process_other_unchanged(md, mas, filename, diff):
497 source_node = diff[0][0]
505 source_node = diff[0][0]
498 target_node = diff[1][0]
506 target_node = diff[1][0]
499
507
500 if source_node is not None and target_node is None:
508 if source_node is not None and target_node is None:
501 if any(not _find(ma, filename) == source_node for ma in mas):
509 if any(not _find(ma, filename) == source_node for ma in mas):
502 # case πŸ„² of πŸ„·
510 # case πŸ„² of πŸ„·
503 md.mark_removed(filename)
511 md.mark_removed(filename)
504 # else, we have case πŸ„± or πŸ„Ά : no change need to be recorded
512 # else, we have case πŸ„± or πŸ„Ά : no change need to be recorded
505 elif source_node is None and target_node is not None:
513 elif source_node is None and target_node is not None:
506 if any(_find(ma, filename) is not None for ma in mas):
514 if any(_find(ma, filename) is not None for ma in mas):
507 # case πŸ„΄ or πŸ„Ή
515 # case πŸ„΄ or πŸ„Ή
508 md.mark_salvaged(filename)
516 md.mark_salvaged(filename)
509 # else, we have case πŸ„³ or πŸ„Έ : simple merge without intervention
517 # else, we have case πŸ„³ or πŸ„Έ : simple merge without intervention
510 elif source_node is not None and target_node is not None:
518 elif source_node is not None and target_node is not None:
511 # case πŸ„΅ or πŸ„Ί : simple merge without intervention
519 # case πŸ„΅ or πŸ„Ί : simple merge without intervention
512 #
520 #
513 # In buggy case where source_node is not an ancestors of target_node.
521 # In buggy case where source_node is not an ancestors of target_node.
514 # There should have a been a new filenode created, recording this as
522 # There should have a been a new filenode created, recording this as
515 # "modified". We do not deal with them yet.
523 # "modified". We do not deal with them yet.
516 pass
524 pass
517 else:
525 else:
518 # An impossible case, the diff algorithm should not return entry if the
526 # An impossible case, the diff algorithm should not return entry if the
519 # file is missing on both side.
527 # file is missing on both side.
520 assert False, "unreachable"
528 assert False, "unreachable"
521
529
522
530
523 def _missing_from_all_ancestors(mas, filename):
531 def _missing_from_all_ancestors(mas, filename):
524 return all(_find(ma, filename) is None for ma in mas)
532 return all(_find(ma, filename) is None for ma in mas)
525
533
526
534
527 def computechangesetfilesadded(ctx):
535 def computechangesetfilesadded(ctx):
528 """return the list of files added in a changeset"""
536 """return the list of files added in a changeset"""
529 added = []
537 added = []
530 for f in ctx.files():
538 for f in ctx.files():
531 if not any(f in p for p in ctx.parents()):
539 if not any(f in p for p in ctx.parents()):
532 added.append(f)
540 added.append(f)
533 return added
541 return added
534
542
535
543
536 def get_removal_filter(ctx, x=None):
544 def get_removal_filter(ctx, x=None):
537 """return a function to detect files "wrongly" detected as `removed`
545 """return a function to detect files "wrongly" detected as `removed`
538
546
539 When a file is removed relative to p1 in a merge, this
547 When a file is removed relative to p1 in a merge, this
540 function determines whether the absence is due to a
548 function determines whether the absence is due to a
541 deletion from a parent, or whether the merge commit
549 deletion from a parent, or whether the merge commit
542 itself deletes the file. We decide this by doing a
550 itself deletes the file. We decide this by doing a
543 simplified three way merge of the manifest entry for
551 simplified three way merge of the manifest entry for
544 the file. There are two ways we decide the merge
552 the file. There are two ways we decide the merge
545 itself didn't delete a file:
553 itself didn't delete a file:
546 - neither parent (nor the merge) contain the file
554 - neither parent (nor the merge) contain the file
547 - exactly one parent contains the file, and that
555 - exactly one parent contains the file, and that
548 parent has the same filelog entry as the merge
556 parent has the same filelog entry as the merge
549 ancestor (or all of them if there two). In other
557 ancestor (or all of them if there two). In other
550 words, that parent left the file unchanged while the
558 words, that parent left the file unchanged while the
551 other one deleted it.
559 other one deleted it.
552 One way to think about this is that deleting a file is
560 One way to think about this is that deleting a file is
553 similar to emptying it, so the list of changed files
561 similar to emptying it, so the list of changed files
554 should be similar either way. The computation
562 should be similar either way. The computation
555 described above is not done directly in _filecommit
563 described above is not done directly in _filecommit
556 when creating the list of changed files, however
564 when creating the list of changed files, however
557 it does something very similar by comparing filelog
565 it does something very similar by comparing filelog
558 nodes.
566 nodes.
559 """
567 """
560
568
561 if x is not None:
569 if x is not None:
562 p1, p2, m1, m2 = x
570 p1, p2, m1, m2 = x
563 else:
571 else:
564 p1 = ctx.p1()
572 p1 = ctx.p1()
565 p2 = ctx.p2()
573 p2 = ctx.p2()
566 m1 = p1.manifest()
574 m1 = p1.manifest()
567 m2 = p2.manifest()
575 m2 = p2.manifest()
568
576
569 @util.cachefunc
577 @util.cachefunc
570 def mas():
578 def mas():
571 p1n = p1.node()
579 p1n = p1.node()
572 p2n = p2.node()
580 p2n = p2.node()
573 cahs = ctx.repo().changelog.commonancestorsheads(p1n, p2n)
581 cahs = ctx.repo().changelog.commonancestorsheads(p1n, p2n)
574 if not cahs:
582 if not cahs:
575 cahs = [nullrev]
583 cahs = [nullrev]
576 return [ctx.repo()[r].manifest() for r in cahs]
584 return [ctx.repo()[r].manifest() for r in cahs]
577
585
578 def deletionfromparent(f):
586 def deletionfromparent(f):
579 if f in m1:
587 if f in m1:
580 return f not in m2 and all(
588 return f not in m2 and all(
581 f in ma and ma.find(f) == m1.find(f) for ma in mas()
589 f in ma and ma.find(f) == m1.find(f) for ma in mas()
582 )
590 )
583 elif f in m2:
591 elif f in m2:
584 return all(f in ma and ma.find(f) == m2.find(f) for ma in mas())
592 return all(f in ma and ma.find(f) == m2.find(f) for ma in mas())
585 else:
593 else:
586 return True
594 return True
587
595
588 return deletionfromparent
596 return deletionfromparent
589
597
590
598
591 def computechangesetfilesremoved(ctx):
599 def computechangesetfilesremoved(ctx):
592 """return the list of files removed in a changeset"""
600 """return the list of files removed in a changeset"""
593 removed = []
601 removed = []
594 for f in ctx.files():
602 for f in ctx.files():
595 if f not in ctx:
603 if f not in ctx:
596 removed.append(f)
604 removed.append(f)
597 if removed:
605 if removed:
598 rf = get_removal_filter(ctx)
606 rf = get_removal_filter(ctx)
599 removed = [r for r in removed if not rf(r)]
607 removed = [r for r in removed if not rf(r)]
600 return removed
608 return removed
601
609
602
610
603 def computechangesetfilesmerged(ctx):
611 def computechangesetfilesmerged(ctx):
604 """return the list of files merged in a changeset"""
612 """return the list of files merged in a changeset"""
605 merged = []
613 merged = []
606 if len(ctx.parents()) < 2:
614 if len(ctx.parents()) < 2:
607 return merged
615 return merged
608 for f in ctx.files():
616 for f in ctx.files():
609 if f in ctx:
617 if f in ctx:
610 fctx = ctx[f]
618 fctx = ctx[f]
611 parents = fctx._filelog.parents(fctx._filenode)
619 parents = fctx._filelog.parents(fctx._filenode)
612 if parents[1] != nullid:
620 if parents[1] != nullid:
613 merged.append(f)
621 merged.append(f)
614 return merged
622 return merged
615
623
616
624
617 def computechangesetcopies(ctx):
625 def computechangesetcopies(ctx):
618 """return the copies data for a changeset
626 """return the copies data for a changeset
619
627
620 The copies data are returned as a pair of dictionnary (p1copies, p2copies).
628 The copies data are returned as a pair of dictionnary (p1copies, p2copies).
621
629
622 Each dictionnary are in the form: `{newname: oldname}`
630 Each dictionnary are in the form: `{newname: oldname}`
623 """
631 """
624 p1copies = {}
632 p1copies = {}
625 p2copies = {}
633 p2copies = {}
626 p1 = ctx.p1()
634 p1 = ctx.p1()
627 p2 = ctx.p2()
635 p2 = ctx.p2()
628 narrowmatch = ctx._repo.narrowmatch()
636 narrowmatch = ctx._repo.narrowmatch()
629 for dst in ctx.files():
637 for dst in ctx.files():
630 if not narrowmatch(dst) or dst not in ctx:
638 if not narrowmatch(dst) or dst not in ctx:
631 continue
639 continue
632 copied = ctx[dst].renamed()
640 copied = ctx[dst].renamed()
633 if not copied:
641 if not copied:
634 continue
642 continue
635 src, srcnode = copied
643 src, srcnode = copied
636 if src in p1 and p1[src].filenode() == srcnode:
644 if src in p1 and p1[src].filenode() == srcnode:
637 p1copies[dst] = src
645 p1copies[dst] = src
638 elif src in p2 and p2[src].filenode() == srcnode:
646 elif src in p2 and p2[src].filenode() == srcnode:
639 p2copies[dst] = src
647 p2copies[dst] = src
640 return p1copies, p2copies
648 return p1copies, p2copies
641
649
642
650
643 def encodecopies(files, copies):
651 def encodecopies(files, copies):
644 items = []
652 items = []
645 for i, dst in enumerate(files):
653 for i, dst in enumerate(files):
646 if dst in copies:
654 if dst in copies:
647 items.append(b'%d\0%s' % (i, copies[dst]))
655 items.append(b'%d\0%s' % (i, copies[dst]))
648 if len(items) != len(copies):
656 if len(items) != len(copies):
649 raise error.ProgrammingError(
657 raise error.ProgrammingError(
650 b'some copy targets missing from file list'
658 b'some copy targets missing from file list'
651 )
659 )
652 return b"\n".join(items)
660 return b"\n".join(items)
653
661
654
662
655 def decodecopies(files, data):
663 def decodecopies(files, data):
656 try:
664 try:
657 copies = {}
665 copies = {}
658 if not data:
666 if not data:
659 return copies
667 return copies
660 for l in data.split(b'\n'):
668 for l in data.split(b'\n'):
661 strindex, src = l.split(b'\0')
669 strindex, src = l.split(b'\0')
662 i = int(strindex)
670 i = int(strindex)
663 dst = files[i]
671 dst = files[i]
664 copies[dst] = src
672 copies[dst] = src
665 return copies
673 return copies
666 except (ValueError, IndexError):
674 except (ValueError, IndexError):
667 # Perhaps someone had chosen the same key name (e.g. "p1copies") and
675 # Perhaps someone had chosen the same key name (e.g. "p1copies") and
668 # used different syntax for the value.
676 # used different syntax for the value.
669 return None
677 return None
670
678
671
679
672 def encodefileindices(files, subset):
680 def encodefileindices(files, subset):
673 subset = set(subset)
681 subset = set(subset)
674 indices = []
682 indices = []
675 for i, f in enumerate(files):
683 for i, f in enumerate(files):
676 if f in subset:
684 if f in subset:
677 indices.append(b'%d' % i)
685 indices.append(b'%d' % i)
678 return b'\n'.join(indices)
686 return b'\n'.join(indices)
679
687
680
688
681 def decodefileindices(files, data):
689 def decodefileindices(files, data):
682 try:
690 try:
683 subset = []
691 subset = []
684 if not data:
692 if not data:
685 return subset
693 return subset
686 for strindex in data.split(b'\n'):
694 for strindex in data.split(b'\n'):
687 i = int(strindex)
695 i = int(strindex)
688 if i < 0 or i >= len(files):
696 if i < 0 or i >= len(files):
689 return None
697 return None
690 subset.append(files[i])
698 subset.append(files[i])
691 return subset
699 return subset
692 except (ValueError, IndexError):
700 except (ValueError, IndexError):
693 # Perhaps someone had chosen the same key name (e.g. "added") and
701 # Perhaps someone had chosen the same key name (e.g. "added") and
694 # used different syntax for the value.
702 # used different syntax for the value.
695 return None
703 return None
696
704
697
705
698 # see mercurial/helptext/internals/revlogs.txt for details about the format
706 # see mercurial/helptext/internals/revlogs.txt for details about the format
699
707
700 ACTION_MASK = int("111" "00", 2)
708 ACTION_MASK = int("111" "00", 2)
701 # note: untouched file used as copy source will as `000` for this mask.
709 # note: untouched file used as copy source will as `000` for this mask.
702 ADDED_FLAG = int("001" "00", 2)
710 ADDED_FLAG = int("001" "00", 2)
703 MERGED_FLAG = int("010" "00", 2)
711 MERGED_FLAG = int("010" "00", 2)
704 REMOVED_FLAG = int("011" "00", 2)
712 REMOVED_FLAG = int("011" "00", 2)
705 SALVAGED_FLAG = int("100" "00", 2)
713 SALVAGED_FLAG = int("100" "00", 2)
706 TOUCHED_FLAG = int("101" "00", 2)
714 TOUCHED_FLAG = int("101" "00", 2)
707
715
708 COPIED_MASK = int("11", 2)
716 COPIED_MASK = int("11", 2)
709 COPIED_FROM_P1_FLAG = int("10", 2)
717 COPIED_FROM_P1_FLAG = int("10", 2)
710 COPIED_FROM_P2_FLAG = int("11", 2)
718 COPIED_FROM_P2_FLAG = int("11", 2)
711
719
712 # structure is <flag><filename-end><copy-source>
720 # structure is <flag><filename-end><copy-source>
713 INDEX_HEADER = struct.Struct(">L")
721 INDEX_HEADER = struct.Struct(">L")
714 INDEX_ENTRY = struct.Struct(">bLL")
722 INDEX_ENTRY = struct.Struct(">bLL")
715
723
716
724
717 def encode_files_sidedata(files):
725 def encode_files_sidedata(files):
718 all_files = set(files.touched)
726 all_files = set(files.touched)
719 all_files.update(files.copied_from_p1.values())
727 all_files.update(files.copied_from_p1.values())
720 all_files.update(files.copied_from_p2.values())
728 all_files.update(files.copied_from_p2.values())
721 all_files = sorted(all_files)
729 all_files = sorted(all_files)
722 file_idx = {f: i for (i, f) in enumerate(all_files)}
730 file_idx = {f: i for (i, f) in enumerate(all_files)}
723 file_idx[None] = 0
731 file_idx[None] = 0
724
732
725 chunks = [INDEX_HEADER.pack(len(all_files))]
733 chunks = [INDEX_HEADER.pack(len(all_files))]
726
734
727 filename_length = 0
735 filename_length = 0
728 for f in all_files:
736 for f in all_files:
729 filename_size = len(f)
737 filename_size = len(f)
730 filename_length += filename_size
738 filename_length += filename_size
731 flag = 0
739 flag = 0
732 if f in files.added:
740 if f in files.added:
733 flag |= ADDED_FLAG
741 flag |= ADDED_FLAG
734 elif f in files.merged:
742 elif f in files.merged:
735 flag |= MERGED_FLAG
743 flag |= MERGED_FLAG
736 elif f in files.removed:
744 elif f in files.removed:
737 flag |= REMOVED_FLAG
745 flag |= REMOVED_FLAG
738 elif f in files.salvaged:
746 elif f in files.salvaged:
739 flag |= SALVAGED_FLAG
747 flag |= SALVAGED_FLAG
740 elif f in files.touched:
748 elif f in files.touched:
741 flag |= TOUCHED_FLAG
749 flag |= TOUCHED_FLAG
742
750
743 copy = None
751 copy = None
744 if f in files.copied_from_p1:
752 if f in files.copied_from_p1:
745 flag |= COPIED_FROM_P1_FLAG
753 flag |= COPIED_FROM_P1_FLAG
746 copy = files.copied_from_p1.get(f)
754 copy = files.copied_from_p1.get(f)
747 elif f in files.copied_from_p2:
755 elif f in files.copied_from_p2:
748 copy = files.copied_from_p2.get(f)
756 copy = files.copied_from_p2.get(f)
749 flag |= COPIED_FROM_P2_FLAG
757 flag |= COPIED_FROM_P2_FLAG
750 copy_idx = file_idx[copy]
758 copy_idx = file_idx[copy]
751 chunks.append(INDEX_ENTRY.pack(flag, filename_length, copy_idx))
759 chunks.append(INDEX_ENTRY.pack(flag, filename_length, copy_idx))
752 chunks.extend(all_files)
760 chunks.extend(all_files)
753 return {sidedatamod.SD_FILES: b''.join(chunks)}
761 return {sidedatamod.SD_FILES: b''.join(chunks)}
754
762
755
763
756 def decode_files_sidedata(sidedata):
764 def decode_files_sidedata(sidedata):
757 md = ChangingFiles()
765 md = ChangingFiles()
758 raw = sidedata.get(sidedatamod.SD_FILES)
766 raw = sidedata.get(sidedatamod.SD_FILES)
759
767
760 if raw is None:
768 if raw is None:
761 return md
769 return md
762
770
763 copies = []
771 copies = []
764 all_files = []
772 all_files = []
765
773
766 assert len(raw) >= INDEX_HEADER.size
774 assert len(raw) >= INDEX_HEADER.size
767 total_files = INDEX_HEADER.unpack_from(raw, 0)[0]
775 total_files = INDEX_HEADER.unpack_from(raw, 0)[0]
768
776
769 offset = INDEX_HEADER.size
777 offset = INDEX_HEADER.size
770 file_offset_base = offset + (INDEX_ENTRY.size * total_files)
778 file_offset_base = offset + (INDEX_ENTRY.size * total_files)
771 file_offset_last = file_offset_base
779 file_offset_last = file_offset_base
772
780
773 assert len(raw) >= file_offset_base
781 assert len(raw) >= file_offset_base
774
782
775 for idx in range(total_files):
783 for idx in range(total_files):
776 flag, file_end, copy_idx = INDEX_ENTRY.unpack_from(raw, offset)
784 flag, file_end, copy_idx = INDEX_ENTRY.unpack_from(raw, offset)
777 file_end += file_offset_base
785 file_end += file_offset_base
778 filename = raw[file_offset_last:file_end]
786 filename = raw[file_offset_last:file_end]
779 filesize = file_end - file_offset_last
787 filesize = file_end - file_offset_last
780 assert len(filename) == filesize
788 assert len(filename) == filesize
781 offset += INDEX_ENTRY.size
789 offset += INDEX_ENTRY.size
782 file_offset_last = file_end
790 file_offset_last = file_end
783 all_files.append(filename)
791 all_files.append(filename)
784 if flag & ACTION_MASK == ADDED_FLAG:
792 if flag & ACTION_MASK == ADDED_FLAG:
785 md.mark_added(filename)
793 md.mark_added(filename)
786 elif flag & ACTION_MASK == MERGED_FLAG:
794 elif flag & ACTION_MASK == MERGED_FLAG:
787 md.mark_merged(filename)
795 md.mark_merged(filename)
788 elif flag & ACTION_MASK == REMOVED_FLAG:
796 elif flag & ACTION_MASK == REMOVED_FLAG:
789 md.mark_removed(filename)
797 md.mark_removed(filename)
790 elif flag & ACTION_MASK == SALVAGED_FLAG:
798 elif flag & ACTION_MASK == SALVAGED_FLAG:
791 md.mark_salvaged(filename)
799 md.mark_salvaged(filename)
792 elif flag & ACTION_MASK == TOUCHED_FLAG:
800 elif flag & ACTION_MASK == TOUCHED_FLAG:
793 md.mark_touched(filename)
801 md.mark_touched(filename)
794
802
795 copied = None
803 copied = None
796 if flag & COPIED_MASK == COPIED_FROM_P1_FLAG:
804 if flag & COPIED_MASK == COPIED_FROM_P1_FLAG:
797 copied = md.mark_copied_from_p1
805 copied = md.mark_copied_from_p1
798 elif flag & COPIED_MASK == COPIED_FROM_P2_FLAG:
806 elif flag & COPIED_MASK == COPIED_FROM_P2_FLAG:
799 copied = md.mark_copied_from_p2
807 copied = md.mark_copied_from_p2
800
808
801 if copied is not None:
809 if copied is not None:
802 copies.append((copied, filename, copy_idx))
810 copies.append((copied, filename, copy_idx))
803
811
804 for copied, filename, copy_idx in copies:
812 for copied, filename, copy_idx in copies:
805 copied(all_files[copy_idx], filename)
813 copied(all_files[copy_idx], filename)
806
814
807 return md
815 return md
808
816
809
817
810 def _getsidedata(srcrepo, rev):
818 def _getsidedata(srcrepo, rev):
811 ctx = srcrepo[rev]
819 ctx = srcrepo[rev]
812 files = compute_all_files_changes(ctx)
820 files = compute_all_files_changes(ctx)
813 return encode_files_sidedata(files), files.has_copies_info
821 return encode_files_sidedata(files), files.has_copies_info
814
822
815
823
816 def copies_sidedata_computer(repo, revlog, rev, existing_sidedata):
824 def copies_sidedata_computer(repo, revlog, rev, existing_sidedata):
817 return _getsidedata(repo, rev)[0]
825 return _getsidedata(repo, rev)[0]
818
826
819
827
820 def set_sidedata_spec_for_repo(repo):
828 def set_sidedata_spec_for_repo(repo):
821 if requirementsmod.COPIESSDC_REQUIREMENT in repo.requirements:
829 if requirementsmod.COPIESSDC_REQUIREMENT in repo.requirements:
822 repo.register_wanted_sidedata(sidedatamod.SD_FILES)
830 repo.register_wanted_sidedata(sidedatamod.SD_FILES)
823 repo.register_sidedata_computer(
831 repo.register_sidedata_computer(
824 b"changelog",
832 b"changelog",
825 sidedatamod.SD_FILES,
833 sidedatamod.SD_FILES,
826 (sidedatamod.SD_FILES,),
834 (sidedatamod.SD_FILES,),
827 copies_sidedata_computer,
835 copies_sidedata_computer,
828 )
836 )
829
837
830
838
831 def getsidedataadder(srcrepo, destrepo):
839 def getsidedataadder(srcrepo, destrepo):
832 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
840 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
833 if pycompat.iswindows or not use_w:
841 if pycompat.iswindows or not use_w:
834 return _get_simple_sidedata_adder(srcrepo, destrepo)
842 return _get_simple_sidedata_adder(srcrepo, destrepo)
835 else:
843 else:
836 return _get_worker_sidedata_adder(srcrepo, destrepo)
844 return _get_worker_sidedata_adder(srcrepo, destrepo)
837
845
838
846
839 def _sidedata_worker(srcrepo, revs_queue, sidedata_queue, tokens):
847 def _sidedata_worker(srcrepo, revs_queue, sidedata_queue, tokens):
840 """The function used by worker precomputing sidedata
848 """The function used by worker precomputing sidedata
841
849
842 It read an input queue containing revision numbers
850 It read an input queue containing revision numbers
843 It write in an output queue containing (rev, <sidedata-map>)
851 It write in an output queue containing (rev, <sidedata-map>)
844
852
845 The `None` input value is used as a stop signal.
853 The `None` input value is used as a stop signal.
846
854
847 The `tokens` semaphore is user to avoid having too many unprocessed
855 The `tokens` semaphore is user to avoid having too many unprocessed
848 entries. The workers needs to acquire one token before fetching a task.
856 entries. The workers needs to acquire one token before fetching a task.
849 They will be released by the consumer of the produced data.
857 They will be released by the consumer of the produced data.
850 """
858 """
851 tokens.acquire()
859 tokens.acquire()
852 rev = revs_queue.get()
860 rev = revs_queue.get()
853 while rev is not None:
861 while rev is not None:
854 data = _getsidedata(srcrepo, rev)
862 data = _getsidedata(srcrepo, rev)
855 sidedata_queue.put((rev, data))
863 sidedata_queue.put((rev, data))
856 tokens.acquire()
864 tokens.acquire()
857 rev = revs_queue.get()
865 rev = revs_queue.get()
858 # processing of `None` is completed, release the token.
866 # processing of `None` is completed, release the token.
859 tokens.release()
867 tokens.release()
860
868
861
869
862 BUFF_PER_WORKER = 50
870 BUFF_PER_WORKER = 50
863
871
864
872
865 def _get_worker_sidedata_adder(srcrepo, destrepo):
873 def _get_worker_sidedata_adder(srcrepo, destrepo):
866 """The parallel version of the sidedata computation
874 """The parallel version of the sidedata computation
867
875
868 This code spawn a pool of worker that precompute a buffer of sidedata
876 This code spawn a pool of worker that precompute a buffer of sidedata
869 before we actually need them"""
877 before we actually need them"""
870 # avoid circular import copies -> scmutil -> worker -> copies
878 # avoid circular import copies -> scmutil -> worker -> copies
871 from . import worker
879 from . import worker
872
880
873 nbworkers = worker._numworkers(srcrepo.ui)
881 nbworkers = worker._numworkers(srcrepo.ui)
874
882
875 tokens = multiprocessing.BoundedSemaphore(nbworkers * BUFF_PER_WORKER)
883 tokens = multiprocessing.BoundedSemaphore(nbworkers * BUFF_PER_WORKER)
876 revsq = multiprocessing.Queue()
884 revsq = multiprocessing.Queue()
877 sidedataq = multiprocessing.Queue()
885 sidedataq = multiprocessing.Queue()
878
886
879 assert srcrepo.filtername is None
887 assert srcrepo.filtername is None
880 # queue all tasks beforehand, revision numbers are small and it make
888 # queue all tasks beforehand, revision numbers are small and it make
881 # synchronisation simpler
889 # synchronisation simpler
882 #
890 #
883 # Since the computation for each node can be quite expensive, the overhead
891 # Since the computation for each node can be quite expensive, the overhead
884 # of using a single queue is not revelant. In practice, most computation
892 # of using a single queue is not revelant. In practice, most computation
885 # are fast but some are very expensive and dominate all the other smaller
893 # are fast but some are very expensive and dominate all the other smaller
886 # cost.
894 # cost.
887 for r in srcrepo.changelog.revs():
895 for r in srcrepo.changelog.revs():
888 revsq.put(r)
896 revsq.put(r)
889 # queue the "no more tasks" markers
897 # queue the "no more tasks" markers
890 for i in range(nbworkers):
898 for i in range(nbworkers):
891 revsq.put(None)
899 revsq.put(None)
892
900
893 allworkers = []
901 allworkers = []
894 for i in range(nbworkers):
902 for i in range(nbworkers):
895 args = (srcrepo, revsq, sidedataq, tokens)
903 args = (srcrepo, revsq, sidedataq, tokens)
896 w = multiprocessing.Process(target=_sidedata_worker, args=args)
904 w = multiprocessing.Process(target=_sidedata_worker, args=args)
897 allworkers.append(w)
905 allworkers.append(w)
898 w.start()
906 w.start()
899
907
900 # dictionnary to store results for revision higher than we one we are
908 # dictionnary to store results for revision higher than we one we are
901 # looking for. For example, if we need the sidedatamap for 42, and 43 is
909 # looking for. For example, if we need the sidedatamap for 42, and 43 is
902 # received, when shelve 43 for later use.
910 # received, when shelve 43 for later use.
903 staging = {}
911 staging = {}
904
912
905 def sidedata_companion(revlog, rev):
913 def sidedata_companion(revlog, rev):
906 data = {}, False
914 data = {}, False
907 if util.safehasattr(revlog, b'filteredrevs'): # this is a changelog
915 if util.safehasattr(revlog, b'filteredrevs'): # this is a changelog
908 # Is the data previously shelved ?
916 # Is the data previously shelved ?
909 data = staging.pop(rev, None)
917 data = staging.pop(rev, None)
910 if data is None:
918 if data is None:
911 # look at the queued result until we find the one we are lookig
919 # look at the queued result until we find the one we are lookig
912 # for (shelve the other ones)
920 # for (shelve the other ones)
913 r, data = sidedataq.get()
921 r, data = sidedataq.get()
914 while r != rev:
922 while r != rev:
915 staging[r] = data
923 staging[r] = data
916 r, data = sidedataq.get()
924 r, data = sidedataq.get()
917 tokens.release()
925 tokens.release()
918 sidedata, has_copies_info = data
926 sidedata, has_copies_info = data
919 new_flag = 0
927 new_flag = 0
920 if has_copies_info:
928 if has_copies_info:
921 new_flag = sidedataflag.REVIDX_HASCOPIESINFO
929 new_flag = sidedataflag.REVIDX_HASCOPIESINFO
922 return False, (), sidedata, new_flag, 0
930 return False, (), sidedata, new_flag, 0
923
931
924 return sidedata_companion
932 return sidedata_companion
925
933
926
934
927 def _get_simple_sidedata_adder(srcrepo, destrepo):
935 def _get_simple_sidedata_adder(srcrepo, destrepo):
928 """The simple version of the sidedata computation
936 """The simple version of the sidedata computation
929
937
930 It just compute it in the same thread on request"""
938 It just compute it in the same thread on request"""
931
939
932 def sidedatacompanion(revlog, rev):
940 def sidedatacompanion(revlog, rev):
933 sidedata, has_copies_info = {}, False
941 sidedata, has_copies_info = {}, False
934 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
942 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
935 sidedata, has_copies_info = _getsidedata(srcrepo, rev)
943 sidedata, has_copies_info = _getsidedata(srcrepo, rev)
936 new_flag = 0
944 new_flag = 0
937 if has_copies_info:
945 if has_copies_info:
938 new_flag = sidedataflag.REVIDX_HASCOPIESINFO
946 new_flag = sidedataflag.REVIDX_HASCOPIESINFO
939
947
940 return False, (), sidedata, new_flag, 0
948 return False, (), sidedata, new_flag, 0
941
949
942 return sidedatacompanion
950 return sidedatacompanion
943
951
944
952
945 def getsidedataremover(srcrepo, destrepo):
953 def getsidedataremover(srcrepo, destrepo):
946 def sidedatacompanion(revlog, rev):
954 def sidedatacompanion(revlog, rev):
947 f = ()
955 f = ()
948 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
956 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
949 if revlog.flags(rev) & sidedataflag.REVIDX_SIDEDATA:
957 if revlog.flags(rev) & sidedataflag.REVIDX_SIDEDATA:
950 f = (
958 f = (
951 sidedatamod.SD_P1COPIES,
959 sidedatamod.SD_P1COPIES,
952 sidedatamod.SD_P2COPIES,
960 sidedatamod.SD_P2COPIES,
953 sidedatamod.SD_FILESADDED,
961 sidedatamod.SD_FILESADDED,
954 sidedatamod.SD_FILESREMOVED,
962 sidedatamod.SD_FILESREMOVED,
955 )
963 )
956 return False, f, {}, 0, sidedataflag.REVIDX_HASCOPIESINFO
964 return False, f, {}, 0, sidedataflag.REVIDX_HASCOPIESINFO
957
965
958 return sidedatacompanion
966 return sidedatacompanion
@@ -1,3833 +1,3819 b''
1 #testcases filelog compatibility changeset sidedata upgraded upgraded-parallel
1 #testcases filelog compatibility changeset sidedata upgraded upgraded-parallel
2
2
3 =====================================================
3 =====================================================
4 Test Copy tracing for chain of copies involving merge
4 Test Copy tracing for chain of copies involving merge
5 =====================================================
5 =====================================================
6
6
7 This test files covers copies/rename case for a chains of commit where merges
7 This test files covers copies/rename case for a chains of commit where merges
8 are involved. It cheks we do not have unwanted update of behavior and that the
8 are involved. It cheks we do not have unwanted update of behavior and that the
9 different options to retrieve copies behave correctly.
9 different options to retrieve copies behave correctly.
10
10
11
11
12 Setup
12 Setup
13 =====
13 =====
14
14
15 use git diff to see rename
15 use git diff to see rename
16
16
17 $ cat << EOF >> ./no-linkrev
17 $ cat << EOF >> ./no-linkrev
18 > #!$PYTHON
18 > #!$PYTHON
19 > # filter out linkrev part of the debugindex command
19 > # filter out linkrev part of the debugindex command
20 > import sys
20 > import sys
21 > for line in sys.stdin:
21 > for line in sys.stdin:
22 > if " linkrev " in line:
22 > if " linkrev " in line:
23 > print(line.rstrip())
23 > print(line.rstrip())
24 > else:
24 > else:
25 > l = "%s *%s" % (line[:6], line[14:].rstrip())
25 > l = "%s *%s" % (line[:6], line[14:].rstrip())
26 > print(l)
26 > print(l)
27 > EOF
27 > EOF
28 $ chmod +x no-linkrev
28 $ chmod +x no-linkrev
29
29
30 $ cat << EOF >> $HGRCPATH
30 $ cat << EOF >> $HGRCPATH
31 > [diff]
31 > [diff]
32 > git=yes
32 > git=yes
33 > [command-templates]
33 > [command-templates]
34 > log={desc}\n
34 > log={desc}\n
35 > EOF
35 > EOF
36
36
37 #if compatibility
37 #if compatibility
38 $ cat >> $HGRCPATH << EOF
38 $ cat >> $HGRCPATH << EOF
39 > [experimental]
39 > [experimental]
40 > copies.read-from = compatibility
40 > copies.read-from = compatibility
41 > EOF
41 > EOF
42 #endif
42 #endif
43
43
44 #if changeset
44 #if changeset
45 $ cat >> $HGRCPATH << EOF
45 $ cat >> $HGRCPATH << EOF
46 > [experimental]
46 > [experimental]
47 > copies.read-from = changeset-only
47 > copies.read-from = changeset-only
48 > copies.write-to = changeset-only
48 > copies.write-to = changeset-only
49 > EOF
49 > EOF
50 #endif
50 #endif
51
51
52 #if sidedata
52 #if sidedata
53 $ cat >> $HGRCPATH << EOF
53 $ cat >> $HGRCPATH << EOF
54 > [format]
54 > [format]
55 > exp-use-side-data = yes
55 > exp-use-side-data = yes
56 > exp-use-copies-side-data-changeset = yes
56 > exp-use-copies-side-data-changeset = yes
57 > EOF
57 > EOF
58 #endif
58 #endif
59
59
60
60
61 $ cat > same-content.txt << EOF
61 $ cat > same-content.txt << EOF
62 > Here is some content that will be the same accros multiple file.
62 > Here is some content that will be the same accros multiple file.
63 >
63 >
64 > This is done on purpose so that we end up in some merge situation, were the
64 > This is done on purpose so that we end up in some merge situation, were the
65 > resulting content is the same as in the parent(s), but a new filenodes still
65 > resulting content is the same as in the parent(s), but a new filenodes still
66 > need to be created to record some file history information (especially
66 > need to be created to record some file history information (especially
67 > about copies).
67 > about copies).
68 > EOF
68 > EOF
69
69
70 $ hg init repo-chain
70 $ hg init repo-chain
71 $ cd repo-chain
71 $ cd repo-chain
72
72
73 Add some linear rename initialy
73 Add some linear rename initialy
74
74
75 $ cp ../same-content.txt a
75 $ cp ../same-content.txt a
76 $ cp ../same-content.txt b
76 $ cp ../same-content.txt b
77 $ cp ../same-content.txt h
77 $ cp ../same-content.txt h
78 $ echo "original content for P" > p
78 $ echo "original content for P" > p
79 $ echo "original content for Q" > q
79 $ echo "original content for Q" > q
80 $ echo "original content for R" > r
80 $ echo "original content for R" > r
81 $ hg ci -Am 'i-0 initial commit: a b h p q r'
81 $ hg ci -Am 'i-0 initial commit: a b h p q r'
82 adding a
82 adding a
83 adding b
83 adding b
84 adding h
84 adding h
85 adding p
85 adding p
86 adding q
86 adding q
87 adding r
87 adding r
88 $ hg mv a c
88 $ hg mv a c
89 $ hg mv p s
89 $ hg mv p s
90 $ hg ci -Am 'i-1: a -move-> c, p -move-> s'
90 $ hg ci -Am 'i-1: a -move-> c, p -move-> s'
91 $ hg mv c d
91 $ hg mv c d
92 $ hg mv s t
92 $ hg mv s t
93 $ hg ci -Am 'i-2: c -move-> d, s -move-> t'
93 $ hg ci -Am 'i-2: c -move-> d, s -move-> t'
94 $ hg log -G
94 $ hg log -G
95 @ i-2: c -move-> d, s -move-> t
95 @ i-2: c -move-> d, s -move-> t
96 |
96 |
97 o i-1: a -move-> c, p -move-> s
97 o i-1: a -move-> c, p -move-> s
98 |
98 |
99 o i-0 initial commit: a b h p q r
99 o i-0 initial commit: a b h p q r
100
100
101
101
102 And having another branch with renames on the other side
102 And having another branch with renames on the other side
103
103
104 $ hg mv d e
104 $ hg mv d e
105 $ hg ci -Am 'a-1: d -move-> e'
105 $ hg ci -Am 'a-1: d -move-> e'
106 $ hg mv e f
106 $ hg mv e f
107 $ hg ci -Am 'a-2: e -move-> f'
107 $ hg ci -Am 'a-2: e -move-> f'
108 $ hg log -G --rev '::.'
108 $ hg log -G --rev '::.'
109 @ a-2: e -move-> f
109 @ a-2: e -move-> f
110 |
110 |
111 o a-1: d -move-> e
111 o a-1: d -move-> e
112 |
112 |
113 o i-2: c -move-> d, s -move-> t
113 o i-2: c -move-> d, s -move-> t
114 |
114 |
115 o i-1: a -move-> c, p -move-> s
115 o i-1: a -move-> c, p -move-> s
116 |
116 |
117 o i-0 initial commit: a b h p q r
117 o i-0 initial commit: a b h p q r
118
118
119
119
120 Have a branching with nothing on one side
120 Have a branching with nothing on one side
121
121
122 $ hg up 'desc("i-2")'
122 $ hg up 'desc("i-2")'
123 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
123 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
124 $ echo foo > b
124 $ echo foo > b
125 $ hg ci -m 'b-1: b update'
125 $ hg ci -m 'b-1: b update'
126 created new head
126 created new head
127 $ hg log -G --rev '::.'
127 $ hg log -G --rev '::.'
128 @ b-1: b update
128 @ b-1: b update
129 |
129 |
130 o i-2: c -move-> d, s -move-> t
130 o i-2: c -move-> d, s -move-> t
131 |
131 |
132 o i-1: a -move-> c, p -move-> s
132 o i-1: a -move-> c, p -move-> s
133 |
133 |
134 o i-0 initial commit: a b h p q r
134 o i-0 initial commit: a b h p q r
135
135
136
136
137 Create a branch that delete a file previous renamed
137 Create a branch that delete a file previous renamed
138
138
139 $ hg up 'desc("i-2")'
139 $ hg up 'desc("i-2")'
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg rm d
141 $ hg rm d
142 $ hg ci -m 'c-1 delete d'
142 $ hg ci -m 'c-1 delete d'
143 created new head
143 created new head
144 $ hg log -G --rev '::.'
144 $ hg log -G --rev '::.'
145 @ c-1 delete d
145 @ c-1 delete d
146 |
146 |
147 o i-2: c -move-> d, s -move-> t
147 o i-2: c -move-> d, s -move-> t
148 |
148 |
149 o i-1: a -move-> c, p -move-> s
149 o i-1: a -move-> c, p -move-> s
150 |
150 |
151 o i-0 initial commit: a b h p q r
151 o i-0 initial commit: a b h p q r
152
152
153
153
154 Create a branch that delete a file previous renamed and recreate it
154 Create a branch that delete a file previous renamed and recreate it
155
155
156 $ hg up 'desc("i-2")'
156 $ hg up 'desc("i-2")'
157 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
157 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
158 $ hg rm d
158 $ hg rm d
159 $ hg ci -m 'd-1 delete d'
159 $ hg ci -m 'd-1 delete d'
160 created new head
160 created new head
161 $ echo bar > d
161 $ echo bar > d
162 $ hg add d
162 $ hg add d
163 $ hg ci -m 'd-2 re-add d'
163 $ hg ci -m 'd-2 re-add d'
164 $ hg log -G --rev '::.'
164 $ hg log -G --rev '::.'
165 @ d-2 re-add d
165 @ d-2 re-add d
166 |
166 |
167 o d-1 delete d
167 o d-1 delete d
168 |
168 |
169 o i-2: c -move-> d, s -move-> t
169 o i-2: c -move-> d, s -move-> t
170 |
170 |
171 o i-1: a -move-> c, p -move-> s
171 o i-1: a -move-> c, p -move-> s
172 |
172 |
173 o i-0 initial commit: a b h p q r
173 o i-0 initial commit: a b h p q r
174
174
175
175
176 Having another branch renaming a different file to the same filename as another
176 Having another branch renaming a different file to the same filename as another
177
177
178 $ hg up 'desc("i-2")'
178 $ hg up 'desc("i-2")'
179 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 $ hg mv b g
180 $ hg mv b g
181 $ hg ci -m 'e-1 b -move-> g'
181 $ hg ci -m 'e-1 b -move-> g'
182 created new head
182 created new head
183 $ hg mv g f
183 $ hg mv g f
184 $ hg ci -m 'e-2 g -move-> f'
184 $ hg ci -m 'e-2 g -move-> f'
185 $ hg log -G --rev '::.'
185 $ hg log -G --rev '::.'
186 @ e-2 g -move-> f
186 @ e-2 g -move-> f
187 |
187 |
188 o e-1 b -move-> g
188 o e-1 b -move-> g
189 |
189 |
190 o i-2: c -move-> d, s -move-> t
190 o i-2: c -move-> d, s -move-> t
191 |
191 |
192 o i-1: a -move-> c, p -move-> s
192 o i-1: a -move-> c, p -move-> s
193 |
193 |
194 o i-0 initial commit: a b h p q r
194 o i-0 initial commit: a b h p q r
195
195
196 $ hg up -q null
196 $ hg up -q null
197
197
198 Having a branch similar to the 'a' one, but moving the 'p' file around.
198 Having a branch similar to the 'a' one, but moving the 'p' file around.
199
199
200 $ hg up 'desc("i-2")'
200 $ hg up 'desc("i-2")'
201 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
202 $ hg mv t u
202 $ hg mv t u
203 $ hg ci -Am 'p-1: t -move-> u'
203 $ hg ci -Am 'p-1: t -move-> u'
204 created new head
204 created new head
205 $ hg mv u v
205 $ hg mv u v
206 $ hg ci -Am 'p-2: u -move-> v'
206 $ hg ci -Am 'p-2: u -move-> v'
207 $ hg log -G --rev '::.'
207 $ hg log -G --rev '::.'
208 @ p-2: u -move-> v
208 @ p-2: u -move-> v
209 |
209 |
210 o p-1: t -move-> u
210 o p-1: t -move-> u
211 |
211 |
212 o i-2: c -move-> d, s -move-> t
212 o i-2: c -move-> d, s -move-> t
213 |
213 |
214 o i-1: a -move-> c, p -move-> s
214 o i-1: a -move-> c, p -move-> s
215 |
215 |
216 o i-0 initial commit: a b h p q r
216 o i-0 initial commit: a b h p q r
217
217
218 $ hg up -q null
218 $ hg up -q null
219
219
220 Having another branch renaming a different file to the same filename as another
220 Having another branch renaming a different file to the same filename as another
221
221
222 $ hg up 'desc("i-2")'
222 $ hg up 'desc("i-2")'
223 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 $ hg mv r w
224 $ hg mv r w
225 $ hg ci -m 'q-1 r -move-> w'
225 $ hg ci -m 'q-1 r -move-> w'
226 created new head
226 created new head
227 $ hg mv w v
227 $ hg mv w v
228 $ hg ci -m 'q-2 w -move-> v'
228 $ hg ci -m 'q-2 w -move-> v'
229 $ hg log -G --rev '::.'
229 $ hg log -G --rev '::.'
230 @ q-2 w -move-> v
230 @ q-2 w -move-> v
231 |
231 |
232 o q-1 r -move-> w
232 o q-1 r -move-> w
233 |
233 |
234 o i-2: c -move-> d, s -move-> t
234 o i-2: c -move-> d, s -move-> t
235 |
235 |
236 o i-1: a -move-> c, p -move-> s
236 o i-1: a -move-> c, p -move-> s
237 |
237 |
238 o i-0 initial commit: a b h p q r
238 o i-0 initial commit: a b h p q r
239
239
240 $ hg up -q null
240 $ hg up -q null
241
241
242 Setup all merge
242 Setup all merge
243 ===============
243 ===============
244
244
245 This is done beforehand to validate that the upgrade process creates valid copy
245 This is done beforehand to validate that the upgrade process creates valid copy
246 information.
246 information.
247
247
248 merging with unrelated change does not interfere with the renames
248 merging with unrelated change does not interfere with the renames
249 ---------------------------------------------------------------
249 ---------------------------------------------------------------
250
250
251 - rename on one side
251 - rename on one side
252 - unrelated change on the other side
252 - unrelated change on the other side
253
253
254 $ case_desc="simple merge - A side: multiple renames, B side: unrelated update"
254 $ case_desc="simple merge - A side: multiple renames, B side: unrelated update"
255
255
256 $ hg up 'desc("b-1")'
256 $ hg up 'desc("b-1")'
257 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 $ hg merge 'desc("a-2")'
258 $ hg merge 'desc("a-2")'
259 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
259 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
260 (branch merge, don't forget to commit)
260 (branch merge, don't forget to commit)
261 $ hg ci -m "mBAm-0 $case_desc - one way"
261 $ hg ci -m "mBAm-0 $case_desc - one way"
262 $ hg up 'desc("a-2")'
262 $ hg up 'desc("a-2")'
263 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 $ hg merge 'desc("b-1")'
264 $ hg merge 'desc("b-1")'
265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 (branch merge, don't forget to commit)
266 (branch merge, don't forget to commit)
267 $ hg ci -m "mABm-0 $case_desc - the other way"
267 $ hg ci -m "mABm-0 $case_desc - the other way"
268 created new head
268 created new head
269 $ hg log -G --rev '::(desc("mABm")+desc("mBAm"))'
269 $ hg log -G --rev '::(desc("mABm")+desc("mBAm"))'
270 @ mABm-0 simple merge - A side: multiple renames, B side: unrelated update - the other way
270 @ mABm-0 simple merge - A side: multiple renames, B side: unrelated update - the other way
271 |\
271 |\
272 +---o mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way
272 +---o mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way
273 | |/
273 | |/
274 | o b-1: b update
274 | o b-1: b update
275 | |
275 | |
276 o | a-2: e -move-> f
276 o | a-2: e -move-> f
277 | |
277 | |
278 o | a-1: d -move-> e
278 o | a-1: d -move-> e
279 |/
279 |/
280 o i-2: c -move-> d, s -move-> t
280 o i-2: c -move-> d, s -move-> t
281 |
281 |
282 o i-1: a -move-> c, p -move-> s
282 o i-1: a -move-> c, p -move-> s
283 |
283 |
284 o i-0 initial commit: a b h p q r
284 o i-0 initial commit: a b h p q r
285
285
286
286
287
287
288 merging with the side having a delete
288 merging with the side having a delete
289 -------------------------------------
289 -------------------------------------
290
290
291 case summary:
291 case summary:
292 - one with change to an unrelated file
292 - one with change to an unrelated file
293 - one deleting the change
293 - one deleting the change
294 and recreate an unrelated file after the merge
294 and recreate an unrelated file after the merge
295
295
296 $ case_desc="simple merge - C side: delete a file with copies history , B side: unrelated update"
296 $ case_desc="simple merge - C side: delete a file with copies history , B side: unrelated update"
297
297
298 $ hg up 'desc("b-1")'
298 $ hg up 'desc("b-1")'
299 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
299 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
300 $ hg merge 'desc("c-1")'
300 $ hg merge 'desc("c-1")'
301 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
301 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
302 (branch merge, don't forget to commit)
302 (branch merge, don't forget to commit)
303 $ hg ci -m "mBCm-0 $case_desc - one way"
303 $ hg ci -m "mBCm-0 $case_desc - one way"
304 $ echo bar > d
304 $ echo bar > d
305 $ hg add d
305 $ hg add d
306 $ hg ci -m 'mBCm-1 re-add d'
306 $ hg ci -m 'mBCm-1 re-add d'
307 $ hg up 'desc("c-1")'
307 $ hg up 'desc("c-1")'
308 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
308 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
309 $ hg merge 'desc("b-1")'
309 $ hg merge 'desc("b-1")'
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 (branch merge, don't forget to commit)
311 (branch merge, don't forget to commit)
312 $ hg ci -m "mCBm-0 $case_desc - the other way"
312 $ hg ci -m "mCBm-0 $case_desc - the other way"
313 created new head
313 created new head
314 $ echo bar > d
314 $ echo bar > d
315 $ hg add d
315 $ hg add d
316 $ hg ci -m 'mCBm-1 re-add d'
316 $ hg ci -m 'mCBm-1 re-add d'
317 $ hg log -G --rev '::(desc("mCBm")+desc("mBCm"))'
317 $ hg log -G --rev '::(desc("mCBm")+desc("mBCm"))'
318 @ mCBm-1 re-add d
318 @ mCBm-1 re-add d
319 |
319 |
320 o mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way
320 o mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way
321 |\
321 |\
322 | | o mBCm-1 re-add d
322 | | o mBCm-1 re-add d
323 | | |
323 | | |
324 +---o mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way
324 +---o mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way
325 | |/
325 | |/
326 | o c-1 delete d
326 | o c-1 delete d
327 | |
327 | |
328 o | b-1: b update
328 o | b-1: b update
329 |/
329 |/
330 o i-2: c -move-> d, s -move-> t
330 o i-2: c -move-> d, s -move-> t
331 |
331 |
332 o i-1: a -move-> c, p -move-> s
332 o i-1: a -move-> c, p -move-> s
333 |
333 |
334 o i-0 initial commit: a b h p q r
334 o i-0 initial commit: a b h p q r
335
335
336
336
337 Comparing with a merge re-adding the file afterward
337 Comparing with a merge re-adding the file afterward
338 ---------------------------------------------------
338 ---------------------------------------------------
339
339
340 Merge:
340 Merge:
341 - one with change to an unrelated file
341 - one with change to an unrelated file
342 - one deleting and recreating the change
342 - one deleting and recreating the change
343
343
344 $ case_desc="simple merge - B side: unrelated update, D side: delete and recreate a file (with different content)"
344 $ case_desc="simple merge - B side: unrelated update, D side: delete and recreate a file (with different content)"
345
345
346 $ hg up 'desc("b-1")'
346 $ hg up 'desc("b-1")'
347 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
347 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
348 $ hg merge 'desc("d-2")'
348 $ hg merge 'desc("d-2")'
349 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
350 (branch merge, don't forget to commit)
350 (branch merge, don't forget to commit)
351 $ hg ci -m "mBDm-0 $case_desc - one way"
351 $ hg ci -m "mBDm-0 $case_desc - one way"
352 $ hg up 'desc("d-2")'
352 $ hg up 'desc("d-2")'
353 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
353 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
354 $ hg merge 'desc("b-1")'
354 $ hg merge 'desc("b-1")'
355 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
355 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
356 (branch merge, don't forget to commit)
356 (branch merge, don't forget to commit)
357 $ hg ci -m "mDBm-0 $case_desc - the other way"
357 $ hg ci -m "mDBm-0 $case_desc - the other way"
358 created new head
358 created new head
359 $ hg log -G --rev '::(desc("mDBm")+desc("mBDm"))'
359 $ hg log -G --rev '::(desc("mDBm")+desc("mBDm"))'
360 @ mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way
360 @ mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way
361 |\
361 |\
362 +---o mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way
362 +---o mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way
363 | |/
363 | |/
364 | o d-2 re-add d
364 | o d-2 re-add d
365 | |
365 | |
366 | o d-1 delete d
366 | o d-1 delete d
367 | |
367 | |
368 o | b-1: b update
368 o | b-1: b update
369 |/
369 |/
370 o i-2: c -move-> d, s -move-> t
370 o i-2: c -move-> d, s -move-> t
371 |
371 |
372 o i-1: a -move-> c, p -move-> s
372 o i-1: a -move-> c, p -move-> s
373 |
373 |
374 o i-0 initial commit: a b h p q r
374 o i-0 initial commit: a b h p q r
375
375
376
376
377
377
378 Comparing with a merge with colliding rename
378 Comparing with a merge with colliding rename
379 --------------------------------------------
379 --------------------------------------------
380
380
381 Subcase: new copy information on both side
381 Subcase: new copy information on both side
382 ``````````````````````````````````````````
382 ``````````````````````````````````````````
383
383
384 - the "e-" branch renaming b to f (through 'g')
384 - the "e-" branch renaming b to f (through 'g')
385 - the "a-" branch renaming d to f (through e)
385 - the "a-" branch renaming d to f (through e)
386
386
387 $ case_desc="merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f)"
387 $ case_desc="merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f)"
388
388
389 $ hg up 'desc("a-2")'
389 $ hg up 'desc("a-2")'
390 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
390 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
391 $ hg merge 'desc("e-2")'
391 $ hg merge 'desc("e-2")'
392 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
392 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
393 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
393 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
394 (branch merge, don't forget to commit)
394 (branch merge, don't forget to commit)
395 $ hg ci -m "mAEm-0 $case_desc - one way"
395 $ hg ci -m "mAEm-0 $case_desc - one way"
396 $ hg up 'desc("e-2")'
396 $ hg up 'desc("e-2")'
397 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
397 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
399 $ hg merge 'desc("a-2")'
399 $ hg merge 'desc("a-2")'
400 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
400 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
401 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
401 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
402 (branch merge, don't forget to commit)
402 (branch merge, don't forget to commit)
403 $ hg ci -m "mEAm-0 $case_desc - the other way"
403 $ hg ci -m "mEAm-0 $case_desc - the other way"
404 created new head
404 created new head
405 $ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
405 $ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
406 @ mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
406 @ mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
407 |\
407 |\
408 +---o mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
408 +---o mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
409 | |/
409 | |/
410 | o e-2 g -move-> f
410 | o e-2 g -move-> f
411 | |
411 | |
412 | o e-1 b -move-> g
412 | o e-1 b -move-> g
413 | |
413 | |
414 o | a-2: e -move-> f
414 o | a-2: e -move-> f
415 | |
415 | |
416 o | a-1: d -move-> e
416 o | a-1: d -move-> e
417 |/
417 |/
418 o i-2: c -move-> d, s -move-> t
418 o i-2: c -move-> d, s -move-> t
419 |
419 |
420 o i-1: a -move-> c, p -move-> s
420 o i-1: a -move-> c, p -move-> s
421 |
421 |
422 o i-0 initial commit: a b h p q r
422 o i-0 initial commit: a b h p q r
423
423
424
424
425 Subcase: new copy information on both side with an actual merge happening
425 Subcase: new copy information on both side with an actual merge happening
426 `````````````````````````````````````````````````````````````````````````
426 `````````````````````````````````````````````````````````````````````````
427
427
428 - the "p-" branch renaming 't' to 'v' (through 'u')
428 - the "p-" branch renaming 't' to 'v' (through 'u')
429 - the "q-" branch renaming 'r' to 'v' (through 'w')
429 - the "q-" branch renaming 'r' to 'v' (through 'w')
430
430
431 $ case_desc="merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content)"
431 $ case_desc="merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content)"
432
432
433 $ hg up 'desc("p-2")'
433 $ hg up 'desc("p-2")'
434 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
434 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
435 $ hg merge 'desc("q-2")' --tool ':union'
435 $ hg merge 'desc("q-2")' --tool ':union'
436 merging v
436 merging v
437 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
437 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
438 (branch merge, don't forget to commit)
438 (branch merge, don't forget to commit)
439 $ hg ci -m "mPQm-0 $case_desc - one way"
439 $ hg ci -m "mPQm-0 $case_desc - one way"
440 $ hg up 'desc("q-2")'
440 $ hg up 'desc("q-2")'
441 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
441 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 $ hg merge 'desc("p-2")' --tool ':union'
442 $ hg merge 'desc("p-2")' --tool ':union'
443 merging v
443 merging v
444 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
444 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
445 (branch merge, don't forget to commit)
445 (branch merge, don't forget to commit)
446 $ hg ci -m "mQPm-0 $case_desc - the other way"
446 $ hg ci -m "mQPm-0 $case_desc - the other way"
447 created new head
447 created new head
448 $ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
448 $ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
449 o mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
449 o mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
450 |\
450 |\
451 +---o mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
451 +---o mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
452 | |/
452 | |/
453 | o e-2 g -move-> f
453 | o e-2 g -move-> f
454 | |
454 | |
455 | o e-1 b -move-> g
455 | o e-1 b -move-> g
456 | |
456 | |
457 o | a-2: e -move-> f
457 o | a-2: e -move-> f
458 | |
458 | |
459 o | a-1: d -move-> e
459 o | a-1: d -move-> e
460 |/
460 |/
461 o i-2: c -move-> d, s -move-> t
461 o i-2: c -move-> d, s -move-> t
462 |
462 |
463 o i-1: a -move-> c, p -move-> s
463 o i-1: a -move-> c, p -move-> s
464 |
464 |
465 o i-0 initial commit: a b h p q r
465 o i-0 initial commit: a b h p q r
466
466
467
467
468 Subcase: existing copy information overwritten on one branch
468 Subcase: existing copy information overwritten on one branch
469 ````````````````````````````````````````````````````````````
469 ````````````````````````````````````````````````````````````
470
470
471 Merge:
471 Merge:
472 - one with change to an unrelated file (b)
472 - one with change to an unrelated file (b)
473 - one overwriting a file (d) with a rename (from h to i to d)
473 - one overwriting a file (d) with a rename (from h to i to d)
474
474
475 $ case_desc="simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d)"
475 $ case_desc="simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d)"
476
476
477 $ hg up 'desc("i-2")'
477 $ hg up 'desc("i-2")'
478 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
478 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
479 $ hg mv h i
479 $ hg mv h i
480 $ hg commit -m "f-1: rename h -> i"
480 $ hg commit -m "f-1: rename h -> i"
481 created new head
481 created new head
482 $ hg mv --force i d
482 $ hg mv --force i d
483 $ hg commit -m "f-2: rename i -> d"
483 $ hg commit -m "f-2: rename i -> d"
484 $ hg debugindex d | ../no-linkrev
484 $ hg debugindex d | ../no-linkrev
485 rev linkrev nodeid p1 p2
485 rev linkrev nodeid p1 p2
486 0 * d8252ab2e760 000000000000 000000000000 (no-changeset !)
486 0 * d8252ab2e760 000000000000 000000000000 (no-changeset !)
487 0 * ae258f702dfe 000000000000 000000000000 (changeset !)
487 0 * ae258f702dfe 000000000000 000000000000 (changeset !)
488 1 * b004912a8510 000000000000 000000000000
488 1 * b004912a8510 000000000000 000000000000
489 2 * 7b79e2fe0c89 000000000000 000000000000 (no-changeset !)
489 2 * 7b79e2fe0c89 000000000000 000000000000 (no-changeset !)
490 $ hg up 'desc("b-1")'
490 $ hg up 'desc("b-1")'
491 3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
491 3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
492 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
492 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
493 $ hg merge 'desc("f-2")'
493 $ hg merge 'desc("f-2")'
494 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
494 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
495 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
495 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
496 (branch merge, don't forget to commit)
496 (branch merge, don't forget to commit)
497 $ hg ci -m "mBFm-0 $case_desc - one way"
497 $ hg ci -m "mBFm-0 $case_desc - one way"
498 $ hg up 'desc("f-2")'
498 $ hg up 'desc("f-2")'
499 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
500 $ hg merge 'desc("b-1")'
500 $ hg merge 'desc("b-1")'
501 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
502 (branch merge, don't forget to commit)
502 (branch merge, don't forget to commit)
503 $ hg ci -m "mFBm-0 $case_desc - the other way"
503 $ hg ci -m "mFBm-0 $case_desc - the other way"
504 created new head
504 created new head
505 $ hg up null --quiet
505 $ hg up null --quiet
506 $ hg log -G --rev '::(desc("mBFm")+desc("mFBm"))'
506 $ hg log -G --rev '::(desc("mBFm")+desc("mFBm"))'
507 o mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
507 o mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
508 |\
508 |\
509 +---o mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
509 +---o mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
510 | |/
510 | |/
511 | o f-2: rename i -> d
511 | o f-2: rename i -> d
512 | |
512 | |
513 | o f-1: rename h -> i
513 | o f-1: rename h -> i
514 | |
514 | |
515 o | b-1: b update
515 o | b-1: b update
516 |/
516 |/
517 o i-2: c -move-> d, s -move-> t
517 o i-2: c -move-> d, s -move-> t
518 |
518 |
519 o i-1: a -move-> c, p -move-> s
519 o i-1: a -move-> c, p -move-> s
520 |
520 |
521 o i-0 initial commit: a b h p q r
521 o i-0 initial commit: a b h p q r
522
522
523
523
524 Subcase: existing copy information overwritten on one branch, with different content)
524 Subcase: existing copy information overwritten on one branch, with different content)
525 `````````````````````````````````````````````````````````````````````````````````````
525 `````````````````````````````````````````````````````````````````````````````````````
526
526
527 Merge:
527 Merge:
528 - one with change to an unrelated file (b)
528 - one with change to an unrelated file (b)
529 - one overwriting a file (t) with a rename (from r to x to t), v content is not the same as on the other branch
529 - one overwriting a file (t) with a rename (from r to x to t), v content is not the same as on the other branch
530
530
531 $ case_desc="simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content"
531 $ case_desc="simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content"
532
532
533 $ hg up 'desc("i-2")'
533 $ hg up 'desc("i-2")'
534 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
534 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
535 $ hg mv r x
535 $ hg mv r x
536 $ hg commit -m "r-1: rename r -> x"
536 $ hg commit -m "r-1: rename r -> x"
537 created new head
537 created new head
538 $ hg mv --force x t
538 $ hg mv --force x t
539 $ hg commit -m "r-2: rename t -> x"
539 $ hg commit -m "r-2: rename t -> x"
540 $ hg debugindex t | ../no-linkrev
540 $ hg debugindex t | ../no-linkrev
541 rev linkrev nodeid p1 p2
541 rev linkrev nodeid p1 p2
542 0 * d74efbf65309 000000000000 000000000000 (no-changeset !)
542 0 * d74efbf65309 000000000000 000000000000 (no-changeset !)
543 1 * 02a930b9d7ad 000000000000 000000000000 (no-changeset !)
543 1 * 02a930b9d7ad 000000000000 000000000000 (no-changeset !)
544 0 * 5aed6a8dbff0 000000000000 000000000000 (changeset !)
544 0 * 5aed6a8dbff0 000000000000 000000000000 (changeset !)
545 1 * a38b2fa17021 000000000000 000000000000 (changeset !)
545 1 * a38b2fa17021 000000000000 000000000000 (changeset !)
546 $ hg up 'desc("b-1")'
546 $ hg up 'desc("b-1")'
547 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
547 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
548 $ hg merge 'desc("r-2")'
548 $ hg merge 'desc("r-2")'
549 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
549 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
550 (branch merge, don't forget to commit)
550 (branch merge, don't forget to commit)
551 $ hg ci -m "mBRm-0 $case_desc - one way"
551 $ hg ci -m "mBRm-0 $case_desc - one way"
552 $ hg up 'desc("r-2")'
552 $ hg up 'desc("r-2")'
553 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
553 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
554 $ hg merge 'desc("b-1")'
554 $ hg merge 'desc("b-1")'
555 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
555 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 (branch merge, don't forget to commit)
556 (branch merge, don't forget to commit)
557 $ hg ci -m "mRBm-0 $case_desc - the other way"
557 $ hg ci -m "mRBm-0 $case_desc - the other way"
558 created new head
558 created new head
559 $ hg up null --quiet
559 $ hg up null --quiet
560 $ hg log -G --rev '::(desc("mBRm")+desc("mRBm"))'
560 $ hg log -G --rev '::(desc("mBRm")+desc("mRBm"))'
561 o mRBm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - the other way
561 o mRBm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - the other way
562 |\
562 |\
563 +---o mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way
563 +---o mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way
564 | |/
564 | |/
565 | o r-2: rename t -> x
565 | o r-2: rename t -> x
566 | |
566 | |
567 | o r-1: rename r -> x
567 | o r-1: rename r -> x
568 | |
568 | |
569 o | b-1: b update
569 o | b-1: b update
570 |/
570 |/
571 o i-2: c -move-> d, s -move-> t
571 o i-2: c -move-> d, s -move-> t
572 |
572 |
573 o i-1: a -move-> c, p -move-> s
573 o i-1: a -move-> c, p -move-> s
574 |
574 |
575 o i-0 initial commit: a b h p q r
575 o i-0 initial commit: a b h p q r
576
576
577
577
578
578
579 Subcase: reset of the copy history on one side
579 Subcase: reset of the copy history on one side
580 ``````````````````````````````````````````````
580 ``````````````````````````````````````````````
581
581
582 Merge:
582 Merge:
583 - one with change to a file
583 - one with change to a file
584 - one deleting and recreating the file
584 - one deleting and recreating the file
585
585
586 Unlike in the 'BD/DB' cases, an actual merge happened here. So we should
586 Unlike in the 'BD/DB' cases, an actual merge happened here. So we should
587 consider history and rename on both branch of the merge.
587 consider history and rename on both branch of the merge.
588
588
589 $ case_desc="actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content"
589 $ case_desc="actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content"
590
590
591 $ hg up 'desc("i-2")'
591 $ hg up 'desc("i-2")'
592 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
592 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
593 $ echo "some update" >> d
593 $ echo "some update" >> d
594 $ hg commit -m "g-1: update d"
594 $ hg commit -m "g-1: update d"
595 created new head
595 created new head
596 $ hg up 'desc("d-2")'
596 $ hg up 'desc("d-2")'
597 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
597 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
598 $ hg merge 'desc("g-1")' --tool :union
598 $ hg merge 'desc("g-1")' --tool :union
599 merging d
599 merging d
600 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
600 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
601 (branch merge, don't forget to commit)
601 (branch merge, don't forget to commit)
602 $ hg ci -m "mDGm-0 $case_desc - one way"
602 $ hg ci -m "mDGm-0 $case_desc - one way"
603 $ hg up 'desc("g-1")'
603 $ hg up 'desc("g-1")'
604 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
604 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
605 $ hg merge 'desc("d-2")' --tool :union
605 $ hg merge 'desc("d-2")' --tool :union
606 merging d
606 merging d
607 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
607 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
608 (branch merge, don't forget to commit)
608 (branch merge, don't forget to commit)
609 $ hg ci -m "mGDm-0 $case_desc - the other way"
609 $ hg ci -m "mGDm-0 $case_desc - the other way"
610 created new head
610 created new head
611 $ hg log -G --rev '::(desc("mDGm")+desc("mGDm"))'
611 $ hg log -G --rev '::(desc("mDGm")+desc("mGDm"))'
612 @ mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way
612 @ mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way
613 |\
613 |\
614 +---o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
614 +---o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
615 | |/
615 | |/
616 | o g-1: update d
616 | o g-1: update d
617 | |
617 | |
618 o | d-2 re-add d
618 o | d-2 re-add d
619 | |
619 | |
620 o | d-1 delete d
620 o | d-1 delete d
621 |/
621 |/
622 o i-2: c -move-> d, s -move-> t
622 o i-2: c -move-> d, s -move-> t
623 |
623 |
624 o i-1: a -move-> c, p -move-> s
624 o i-1: a -move-> c, p -move-> s
625 |
625 |
626 o i-0 initial commit: a b h p q r
626 o i-0 initial commit: a b h p q r
627
627
628
628
629 Subcase: merging a change to a file with a "copy overwrite" to that file from another branch
629 Subcase: merging a change to a file with a "copy overwrite" to that file from another branch
630 ````````````````````````````````````````````````````````````````````````````````````````````
630 ````````````````````````````````````````````````````````````````````````````````````````````
631
631
632 Merge:
632 Merge:
633 - one with change to a file (d)
633 - one with change to a file (d)
634 - one overwriting that file with a rename (from h to i, to d)
634 - one overwriting that file with a rename (from h to i, to d)
635
635
636 This case is similar to BF/FB, but an actual merge happens, so both side of the
636 This case is similar to BF/FB, but an actual merge happens, so both side of the
637 history are relevant.
637 history are relevant.
638
638
639 Note:
639 Note:
640 | In this case, the merge get conflicting information since on one side we have
640 | In this case, the merge get conflicting information since on one side we have
641 | "a -> c -> d". and one the other one we have "h -> i -> d".
641 | "a -> c -> d". and one the other one we have "h -> i -> d".
642 |
642 |
643 | The current code arbitrarily pick one side
643 | The current code arbitrarily pick one side
644
644
645 $ case_desc="merge - G side: content change, F side: copy overwrite, no content change"
645 $ case_desc="merge - G side: content change, F side: copy overwrite, no content change"
646
646
647 $ hg up 'desc("f-2")'
647 $ hg up 'desc("f-2")'
648 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
648 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
649 $ hg merge 'desc("g-1")' --tool :union
649 $ hg merge 'desc("g-1")' --tool :union
650 merging d (no-changeset !)
650 merging d (no-changeset !)
651 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (no-changeset !)
651 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (no-changeset !)
652 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
652 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
653 (branch merge, don't forget to commit)
653 (branch merge, don't forget to commit)
654 $ hg ci -m "mFGm-0 $case_desc - one way"
654 $ hg ci -m "mFGm-0 $case_desc - one way"
655 created new head
655 created new head
656 $ hg up 'desc("g-1")'
656 $ hg up 'desc("g-1")'
657 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
657 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
658 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
658 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
659 $ hg merge 'desc("f-2")' --tool :union
659 $ hg merge 'desc("f-2")' --tool :union
660 merging d (no-changeset !)
660 merging d (no-changeset !)
661 0 files updated, 1 files merged, 1 files removed, 0 files unresolved (no-changeset !)
661 0 files updated, 1 files merged, 1 files removed, 0 files unresolved (no-changeset !)
662 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
662 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
663 (branch merge, don't forget to commit)
663 (branch merge, don't forget to commit)
664 $ hg ci -m "mGFm-0 $case_desc - the other way"
664 $ hg ci -m "mGFm-0 $case_desc - the other way"
665 created new head
665 created new head
666 $ hg log -G --rev '::(desc("mGFm")+desc("mFGm"))'
666 $ hg log -G --rev '::(desc("mGFm")+desc("mFGm"))'
667 @ mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
667 @ mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
668 |\
668 |\
669 +---o mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
669 +---o mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
670 | |/
670 | |/
671 | o g-1: update d
671 | o g-1: update d
672 | |
672 | |
673 o | f-2: rename i -> d
673 o | f-2: rename i -> d
674 | |
674 | |
675 o | f-1: rename h -> i
675 o | f-1: rename h -> i
676 |/
676 |/
677 o i-2: c -move-> d, s -move-> t
677 o i-2: c -move-> d, s -move-> t
678 |
678 |
679 o i-1: a -move-> c, p -move-> s
679 o i-1: a -move-> c, p -move-> s
680 |
680 |
681 o i-0 initial commit: a b h p q r
681 o i-0 initial commit: a b h p q r
682
682
683
683
684
684
685 Comparing with merging with a deletion (and keeping the file)
685 Comparing with merging with a deletion (and keeping the file)
686 -------------------------------------------------------------
686 -------------------------------------------------------------
687
687
688 Merge:
688 Merge:
689 - one removing a file (d)
689 - one removing a file (d)
690 - one updating that file
690 - one updating that file
691 - the merge keep the modified version of the file (canceling the delete)
691 - the merge keep the modified version of the file (canceling the delete)
692
692
693 In this case, the file keep on living after the merge. So we should not drop its
693 In this case, the file keep on living after the merge. So we should not drop its
694 copy tracing chain.
694 copy tracing chain.
695
695
696 $ case_desc="merge updated/deleted - revive the file (updated content)"
696 $ case_desc="merge updated/deleted - revive the file (updated content)"
697
697
698 $ hg up 'desc("c-1")'
698 $ hg up 'desc("c-1")'
699 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
699 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
700 $ hg merge 'desc("g-1")'
700 $ hg merge 'desc("g-1")'
701 file 'd' was deleted in local [working copy] but was modified in other [merge rev].
701 file 'd' was deleted in local [working copy] but was modified in other [merge rev].
702 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
702 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
703 What do you want to do? u
703 What do you want to do? u
704 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
704 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
705 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
705 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
706 [1]
706 [1]
707 $ hg resolve -t :other d
707 $ hg resolve -t :other d
708 (no more unresolved files)
708 (no more unresolved files)
709 $ hg ci -m "mCGm-0 $case_desc - one way"
709 $ hg ci -m "mCGm-0 $case_desc - one way"
710 created new head
710 created new head
711
711
712 $ hg up 'desc("g-1")'
712 $ hg up 'desc("g-1")'
713 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
713 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
714 $ hg merge 'desc("c-1")'
714 $ hg merge 'desc("c-1")'
715 file 'd' was deleted in other [merge rev] but was modified in local [working copy].
715 file 'd' was deleted in other [merge rev] but was modified in local [working copy].
716 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
716 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
717 What do you want to do? u
717 What do you want to do? u
718 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
718 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
719 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
719 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
720 [1]
720 [1]
721 $ hg resolve -t :local d
721 $ hg resolve -t :local d
722 (no more unresolved files)
722 (no more unresolved files)
723 $ hg ci -m "mGCm-0 $case_desc - the other way"
723 $ hg ci -m "mGCm-0 $case_desc - the other way"
724 created new head
724 created new head
725
725
726 $ hg log -G --rev '::(desc("mCGm")+desc("mGCm"))'
726 $ hg log -G --rev '::(desc("mCGm")+desc("mGCm"))'
727 @ mGCm-0 merge updated/deleted - revive the file (updated content) - the other way
727 @ mGCm-0 merge updated/deleted - revive the file (updated content) - the other way
728 |\
728 |\
729 +---o mCGm-0 merge updated/deleted - revive the file (updated content) - one way
729 +---o mCGm-0 merge updated/deleted - revive the file (updated content) - one way
730 | |/
730 | |/
731 | o g-1: update d
731 | o g-1: update d
732 | |
732 | |
733 o | c-1 delete d
733 o | c-1 delete d
734 |/
734 |/
735 o i-2: c -move-> d, s -move-> t
735 o i-2: c -move-> d, s -move-> t
736 |
736 |
737 o i-1: a -move-> c, p -move-> s
737 o i-1: a -move-> c, p -move-> s
738 |
738 |
739 o i-0 initial commit: a b h p q r
739 o i-0 initial commit: a b h p q r
740
740
741
741
742
742
743
743
744 Comparing with merge restoring an untouched deleted file
744 Comparing with merge restoring an untouched deleted file
745 --------------------------------------------------------
745 --------------------------------------------------------
746
746
747 Merge:
747 Merge:
748 - one removing a file (d)
748 - one removing a file (d)
749 - one leaving the file untouched
749 - one leaving the file untouched
750 - the merge actively restore the file to the same content.
750 - the merge actively restore the file to the same content.
751
751
752 In this case, the file keep on living after the merge. So we should not drop its
752 In this case, the file keep on living after the merge. So we should not drop its
753 copy tracing chain.
753 copy tracing chain.
754
754
755 $ case_desc="merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge)"
755 $ case_desc="merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge)"
756
756
757 $ hg up 'desc("c-1")'
757 $ hg up 'desc("c-1")'
758 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
758 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
759 $ hg merge 'desc("b-1")'
759 $ hg merge 'desc("b-1")'
760 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
760 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
761 (branch merge, don't forget to commit)
761 (branch merge, don't forget to commit)
762 $ hg revert --rev 'desc("b-1")' d
762 $ hg revert --rev 'desc("b-1")' d
763 $ hg ci -m "mCB-revert-m-0 $case_desc - one way"
763 $ hg ci -m "mCB-revert-m-0 $case_desc - one way"
764 created new head
764 created new head
765
765
766 $ hg up 'desc("b-1")'
766 $ hg up 'desc("b-1")'
767 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
767 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
768 $ hg merge 'desc("c-1")'
768 $ hg merge 'desc("c-1")'
769 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
769 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
770 (branch merge, don't forget to commit)
770 (branch merge, don't forget to commit)
771 $ hg revert --rev 'desc("b-1")' d
771 $ hg revert --rev 'desc("b-1")' d
772 $ hg ci -m "mBC-revert-m-0 $case_desc - the other way"
772 $ hg ci -m "mBC-revert-m-0 $case_desc - the other way"
773 created new head
773 created new head
774
774
775 $ hg log -G --rev '::(desc("mCB-revert-m")+desc("mBC-revert-m"))'
775 $ hg log -G --rev '::(desc("mCB-revert-m")+desc("mBC-revert-m"))'
776 @ mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
776 @ mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
777 |\
777 |\
778 +---o mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
778 +---o mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
779 | |/
779 | |/
780 | o c-1 delete d
780 | o c-1 delete d
781 | |
781 | |
782 o | b-1: b update
782 o | b-1: b update
783 |/
783 |/
784 o i-2: c -move-> d, s -move-> t
784 o i-2: c -move-> d, s -move-> t
785 |
785 |
786 o i-1: a -move-> c, p -move-> s
786 o i-1: a -move-> c, p -move-> s
787 |
787 |
788 o i-0 initial commit: a b h p q r
788 o i-0 initial commit: a b h p q r
789
789
790
790
791
791
792 $ hg up null --quiet
792 $ hg up null --quiet
793
793
794 Merging a branch where a rename was deleted with a branch where the same file was renamed
794 Merging a branch where a rename was deleted with a branch where the same file was renamed
795 ------------------------------------------------------------------------------------------
795 ------------------------------------------------------------------------------------------
796
796
797 Create a "conflicting" merge where `d` get removed on one branch before its
797 Create a "conflicting" merge where `d` get removed on one branch before its
798 rename information actually conflict with the other branch.
798 rename information actually conflict with the other branch.
799
799
800 (the copy information from the branch that was not deleted should win).
800 (the copy information from the branch that was not deleted should win).
801
801
802 $ case_desc="simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch)"
802 $ case_desc="simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch)"
803
803
804 $ hg up 'desc("i-0")'
804 $ hg up 'desc("i-0")'
805 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
805 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
806 $ hg mv b d
806 $ hg mv b d
807 $ hg ci -m "h-1: b -(move)-> d"
807 $ hg ci -m "h-1: b -(move)-> d"
808 created new head
808 created new head
809
809
810 $ hg up 'desc("c-1")'
810 $ hg up 'desc("c-1")'
811 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
811 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
812 $ hg merge 'desc("h-1")'
812 $ hg merge 'desc("h-1")'
813 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
813 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
814 (branch merge, don't forget to commit)
814 (branch merge, don't forget to commit)
815 $ hg ci -m "mCH-delete-before-conflict-m-0 $case_desc - one way"
815 $ hg ci -m "mCH-delete-before-conflict-m-0 $case_desc - one way"
816
816
817 $ hg up 'desc("h-1")'
817 $ hg up 'desc("h-1")'
818 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
818 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
819 $ hg merge 'desc("c-1")'
819 $ hg merge 'desc("c-1")'
820 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
820 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
821 (branch merge, don't forget to commit)
821 (branch merge, don't forget to commit)
822 $ hg ci -m "mHC-delete-before-conflict-m-0 $case_desc - the other way"
822 $ hg ci -m "mHC-delete-before-conflict-m-0 $case_desc - the other way"
823 created new head
823 created new head
824 $ hg log -G --rev '::(desc("mCH-delete-before-conflict-m")+desc("mHC-delete-before-conflict-m"))'
824 $ hg log -G --rev '::(desc("mCH-delete-before-conflict-m")+desc("mHC-delete-before-conflict-m"))'
825 @ mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way
825 @ mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way
826 |\
826 |\
827 +---o mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way
827 +---o mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way
828 | |/
828 | |/
829 | o h-1: b -(move)-> d
829 | o h-1: b -(move)-> d
830 | |
830 | |
831 o | c-1 delete d
831 o | c-1 delete d
832 | |
832 | |
833 o | i-2: c -move-> d, s -move-> t
833 o | i-2: c -move-> d, s -move-> t
834 | |
834 | |
835 o | i-1: a -move-> c, p -move-> s
835 o | i-1: a -move-> c, p -move-> s
836 |/
836 |/
837 o i-0 initial commit: a b h p q r
837 o i-0 initial commit: a b h p q r
838
838
839
839
840 Variant of previous with extra changes introduced by the merge
840 Variant of previous with extra changes introduced by the merge
841 --------------------------------------------------------------
841 --------------------------------------------------------------
842
842
843 Multiple cases above explicitely test cases where content are the same on both side during merge. In this section we will introduce variants for theses cases where new change are introduced to these file content during the merges.
843 Multiple cases above explicitely test cases where content are the same on both side during merge. In this section we will introduce variants for theses cases where new change are introduced to these file content during the merges.
844
844
845
845
846 Subcase: merge has same initial content on both side, but merge introduced a change
846 Subcase: merge has same initial content on both side, but merge introduced a change
847 ```````````````````````````````````````````````````````````````````````````````````
847 ```````````````````````````````````````````````````````````````````````````````````
848
848
849 Same as `mAEm` and `mEAm` but with extra change to the file before commiting
849 Same as `mAEm` and `mEAm` but with extra change to the file before commiting
850
850
851 - the "e-" branch renaming b to f (through 'g')
851 - the "e-" branch renaming b to f (through 'g')
852 - the "a-" branch renaming d to f (through e)
852 - the "a-" branch renaming d to f (through e)
853
853
854 $ case_desc="merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent)"
854 $ case_desc="merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent)"
855
855
856 $ hg up 'desc("a-2")'
856 $ hg up 'desc("a-2")'
857 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
857 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
858 $ hg merge 'desc("e-2")'
858 $ hg merge 'desc("e-2")'
859 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
859 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
860 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
860 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
861 (branch merge, don't forget to commit)
861 (branch merge, don't forget to commit)
862 $ echo "content change for mAE-change-m" > f
862 $ echo "content change for mAE-change-m" > f
863 $ hg ci -m "mAE-change-m-0 $case_desc - one way"
863 $ hg ci -m "mAE-change-m-0 $case_desc - one way"
864 created new head
864 created new head
865 $ hg up 'desc("e-2")'
865 $ hg up 'desc("e-2")'
866 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
866 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
867 $ hg merge 'desc("a-2")'
867 $ hg merge 'desc("a-2")'
868 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
868 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
869 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
869 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
870 (branch merge, don't forget to commit)
870 (branch merge, don't forget to commit)
871 $ echo "content change for mEA-change-m" > f
871 $ echo "content change for mEA-change-m" > f
872 $ hg ci -m "mEA-change-m-0 $case_desc - the other way"
872 $ hg ci -m "mEA-change-m-0 $case_desc - the other way"
873 created new head
873 created new head
874 $ hg log -G --rev '::(desc("mAE-change-m")+desc("mEA-change-m"))'
874 $ hg log -G --rev '::(desc("mAE-change-m")+desc("mEA-change-m"))'
875 @ mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
875 @ mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
876 |\
876 |\
877 +---o mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
877 +---o mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
878 | |/
878 | |/
879 | o e-2 g -move-> f
879 | o e-2 g -move-> f
880 | |
880 | |
881 | o e-1 b -move-> g
881 | o e-1 b -move-> g
882 | |
882 | |
883 o | a-2: e -move-> f
883 o | a-2: e -move-> f
884 | |
884 | |
885 o | a-1: d -move-> e
885 o | a-1: d -move-> e
886 |/
886 |/
887 o i-2: c -move-> d, s -move-> t
887 o i-2: c -move-> d, s -move-> t
888 |
888 |
889 o i-1: a -move-> c, p -move-> s
889 o i-1: a -move-> c, p -move-> s
890 |
890 |
891 o i-0 initial commit: a b h p q r
891 o i-0 initial commit: a b h p q r
892
892
893
893
894 Subcase: merge overwrite common copy information, but with extra change during the merge
894 Subcase: merge overwrite common copy information, but with extra change during the merge
895 ````````````````````````````````````````````````````````````````````````````````````````
895 ````````````````````````````````````````````````````````````````````````````````````````
896
896
897 Merge:
897 Merge:
898 - one with change to an unrelated file (b)
898 - one with change to an unrelated file (b)
899 - one overwriting a file (d) with a rename (from h to i to d)
899 - one overwriting a file (d) with a rename (from h to i to d)
900 - the merge update f content
900 - the merge update f content
901
901
902 $ case_desc="merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d)"
902 $ case_desc="merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d)"
903
903
904 $ hg up 'desc("f-2")'
904 $ hg up 'desc("f-2")'
905 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
905 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
906 #if no-changeset
906 #if no-changeset
907 $ hg debugindex d | ../no-linkrev
907 $ hg debugindex d | ../no-linkrev
908 rev linkrev nodeid p1 p2
908 rev linkrev nodeid p1 p2
909 0 * d8252ab2e760 000000000000 000000000000
909 0 * d8252ab2e760 000000000000 000000000000
910 1 * b004912a8510 000000000000 000000000000
910 1 * b004912a8510 000000000000 000000000000
911 2 * 7b79e2fe0c89 000000000000 000000000000
911 2 * 7b79e2fe0c89 000000000000 000000000000
912 3 * 17ec97e60577 d8252ab2e760 000000000000
912 3 * 17ec97e60577 d8252ab2e760 000000000000
913 4 * 06dabf50734c b004912a8510 17ec97e60577
913 4 * 06dabf50734c b004912a8510 17ec97e60577
914 5 * 19c0e3924691 17ec97e60577 b004912a8510
914 5 * 19c0e3924691 17ec97e60577 b004912a8510
915 6 * 89c873a01d97 7b79e2fe0c89 17ec97e60577
915 6 * 89c873a01d97 7b79e2fe0c89 17ec97e60577
916 7 * d55cb4e9ef57 000000000000 000000000000
916 7 * d55cb4e9ef57 000000000000 000000000000
917 #else
917 #else
918 $ hg debugindex d | ../no-linkrev
918 $ hg debugindex d | ../no-linkrev
919 rev linkrev nodeid p1 p2
919 rev linkrev nodeid p1 p2
920 0 * ae258f702dfe 000000000000 000000000000
920 0 * ae258f702dfe 000000000000 000000000000
921 1 * b004912a8510 000000000000 000000000000
921 1 * b004912a8510 000000000000 000000000000
922 2 * 5cce88bf349f ae258f702dfe 000000000000
922 2 * 5cce88bf349f ae258f702dfe 000000000000
923 3 * cc269dd788c8 b004912a8510 5cce88bf349f
923 3 * cc269dd788c8 b004912a8510 5cce88bf349f
924 4 * 51c91a115080 5cce88bf349f b004912a8510
924 4 * 51c91a115080 5cce88bf349f b004912a8510
925 #endif
925 #endif
926 $ hg up 'desc("b-1")'
926 $ hg up 'desc("b-1")'
927 3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
927 3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
928 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
928 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
929 $ hg merge 'desc("f-2")'
929 $ hg merge 'desc("f-2")'
930 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
930 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
931 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
931 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
932 (branch merge, don't forget to commit)
932 (branch merge, don't forget to commit)
933 $ echo "extra-change to (formelly h) during the merge" > d
933 $ echo "extra-change to (formelly h) during the merge" > d
934 $ hg ci -m "mBF-change-m-0 $case_desc - one way"
934 $ hg ci -m "mBF-change-m-0 $case_desc - one way"
935 created new head
935 created new head
936 $ hg manifest --rev . --debug | grep " d"
936 $ hg manifest --rev . --debug | grep " d"
937 1c334238bd42ec85c6a0d83fd1b2a898a6a3215d 644 d (no-changeset !)
937 1c334238bd42ec85c6a0d83fd1b2a898a6a3215d 644 d (no-changeset !)
938 cea2d99c0fde64672ef61953786fdff34f16e230 644 d (changeset !)
938 cea2d99c0fde64672ef61953786fdff34f16e230 644 d (changeset !)
939
939
940 $ hg up 'desc("f-2")'
940 $ hg up 'desc("f-2")'
941 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
941 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
942 $ hg merge 'desc("b-1")'
942 $ hg merge 'desc("b-1")'
943 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
943 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
944 (branch merge, don't forget to commit)
944 (branch merge, don't forget to commit)
945 $ echo "extra-change to (formelly h) during the merge" > d
945 $ echo "extra-change to (formelly h) during the merge" > d
946 $ hg ci -m "mFB-change-m-0 $case_desc - the other way"
946 $ hg ci -m "mFB-change-m-0 $case_desc - the other way"
947 created new head
947 created new head
948 $ hg manifest --rev . --debug | grep " d"
948 $ hg manifest --rev . --debug | grep " d"
949 1c334238bd42ec85c6a0d83fd1b2a898a6a3215d 644 d (no-changeset !)
949 1c334238bd42ec85c6a0d83fd1b2a898a6a3215d 644 d (no-changeset !)
950 cea2d99c0fde64672ef61953786fdff34f16e230 644 d (changeset !)
950 cea2d99c0fde64672ef61953786fdff34f16e230 644 d (changeset !)
951 #if no-changeset
951 #if no-changeset
952 $ hg debugindex d | ../no-linkrev
952 $ hg debugindex d | ../no-linkrev
953 rev linkrev nodeid p1 p2
953 rev linkrev nodeid p1 p2
954 0 * d8252ab2e760 000000000000 000000000000
954 0 * d8252ab2e760 000000000000 000000000000
955 1 * b004912a8510 000000000000 000000000000
955 1 * b004912a8510 000000000000 000000000000
956 2 * 7b79e2fe0c89 000000000000 000000000000
956 2 * 7b79e2fe0c89 000000000000 000000000000
957 3 * 17ec97e60577 d8252ab2e760 000000000000
957 3 * 17ec97e60577 d8252ab2e760 000000000000
958 4 * 06dabf50734c b004912a8510 17ec97e60577
958 4 * 06dabf50734c b004912a8510 17ec97e60577
959 5 * 19c0e3924691 17ec97e60577 b004912a8510
959 5 * 19c0e3924691 17ec97e60577 b004912a8510
960 6 * 89c873a01d97 7b79e2fe0c89 17ec97e60577
960 6 * 89c873a01d97 7b79e2fe0c89 17ec97e60577
961 7 * d55cb4e9ef57 000000000000 000000000000
961 7 * d55cb4e9ef57 000000000000 000000000000
962 8 * 1c334238bd42 7b79e2fe0c89 000000000000
962 8 * 1c334238bd42 7b79e2fe0c89 000000000000
963 #else
963 #else
964 $ hg debugindex d | ../no-linkrev
964 $ hg debugindex d | ../no-linkrev
965 rev linkrev nodeid p1 p2
965 rev linkrev nodeid p1 p2
966 0 * ae258f702dfe 000000000000 000000000000
966 0 * ae258f702dfe 000000000000 000000000000
967 1 * b004912a8510 000000000000 000000000000
967 1 * b004912a8510 000000000000 000000000000
968 2 * 5cce88bf349f ae258f702dfe 000000000000
968 2 * 5cce88bf349f ae258f702dfe 000000000000
969 3 * cc269dd788c8 b004912a8510 5cce88bf349f
969 3 * cc269dd788c8 b004912a8510 5cce88bf349f
970 4 * 51c91a115080 5cce88bf349f b004912a8510
970 4 * 51c91a115080 5cce88bf349f b004912a8510
971 5 * cea2d99c0fde ae258f702dfe 000000000000
971 5 * cea2d99c0fde ae258f702dfe 000000000000
972 #endif
972 #endif
973 $ hg log -G --rev '::(desc("mBF-change-m")+desc("mFB-change-m"))'
973 $ hg log -G --rev '::(desc("mBF-change-m")+desc("mFB-change-m"))'
974 @ mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
974 @ mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
975 |\
975 |\
976 +---o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
976 +---o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
977 | |/
977 | |/
978 | o f-2: rename i -> d
978 | o f-2: rename i -> d
979 | |
979 | |
980 | o f-1: rename h -> i
980 | o f-1: rename h -> i
981 | |
981 | |
982 o | b-1: b update
982 o | b-1: b update
983 |/
983 |/
984 o i-2: c -move-> d, s -move-> t
984 o i-2: c -move-> d, s -move-> t
985 |
985 |
986 o i-1: a -move-> c, p -move-> s
986 o i-1: a -move-> c, p -move-> s
987 |
987 |
988 o i-0 initial commit: a b h p q r
988 o i-0 initial commit: a b h p q r
989
989
990
990
991 Subcase: restoring and untouched deleted file, while touching it
991 Subcase: restoring and untouched deleted file, while touching it
992 ````````````````````````````````````````````````````````````````
992 ````````````````````````````````````````````````````````````````
993
993
994 Merge:
994 Merge:
995 - one removing a file (d)
995 - one removing a file (d)
996 - one leaving the file untouched
996 - one leaving the file untouched
997 - the merge actively restore the file to the same content.
997 - the merge actively restore the file to the same content.
998
998
999 In this case, the file keep on living after the merge. So we should not drop its
999 In this case, the file keep on living after the merge. So we should not drop its
1000 copy tracing chain.
1000 copy tracing chain.
1001
1001
1002 $ case_desc="merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge)"
1002 $ case_desc="merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge)"
1003
1003
1004 $ hg up 'desc("c-1")'
1004 $ hg up 'desc("c-1")'
1005 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1005 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1006 $ hg merge 'desc("b-1")'
1006 $ hg merge 'desc("b-1")'
1007 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1007 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1008 (branch merge, don't forget to commit)
1008 (branch merge, don't forget to commit)
1009 $ hg revert --rev 'desc("b-1")' d
1009 $ hg revert --rev 'desc("b-1")' d
1010 $ echo "new content for d after the revert" > d
1010 $ echo "new content for d after the revert" > d
1011 $ hg ci -m "mCB-change-m-0 $case_desc - one way"
1011 $ hg ci -m "mCB-change-m-0 $case_desc - one way"
1012 created new head
1012 created new head
1013 $ hg manifest --rev . --debug | grep " d"
1013 $ hg manifest --rev . --debug | grep " d"
1014 e333780c17752a3b0dd15e3ad48aa4e5c745f621 644 d (no-changeset !)
1014 e333780c17752a3b0dd15e3ad48aa4e5c745f621 644 d (no-changeset !)
1015 4b540a18ad699234b2b2aa18cb69555ac9c4b1df 644 d (changeset !)
1015 4b540a18ad699234b2b2aa18cb69555ac9c4b1df 644 d (changeset !)
1016
1016
1017 $ hg up 'desc("b-1")'
1017 $ hg up 'desc("b-1")'
1018 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1018 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1019 $ hg merge 'desc("c-1")'
1019 $ hg merge 'desc("c-1")'
1020 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1020 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1021 (branch merge, don't forget to commit)
1021 (branch merge, don't forget to commit)
1022 $ hg revert --rev 'desc("b-1")' d
1022 $ hg revert --rev 'desc("b-1")' d
1023 $ echo "new content for d after the revert" > d
1023 $ echo "new content for d after the revert" > d
1024 $ hg ci -m "mBC-change-m-0 $case_desc - the other way"
1024 $ hg ci -m "mBC-change-m-0 $case_desc - the other way"
1025 created new head
1025 created new head
1026 $ hg manifest --rev . --debug | grep " d"
1026 $ hg manifest --rev . --debug | grep " d"
1027 e333780c17752a3b0dd15e3ad48aa4e5c745f621 644 d (no-changeset !)
1027 e333780c17752a3b0dd15e3ad48aa4e5c745f621 644 d (no-changeset !)
1028 4b540a18ad699234b2b2aa18cb69555ac9c4b1df 644 d (changeset !)
1028 4b540a18ad699234b2b2aa18cb69555ac9c4b1df 644 d (changeset !)
1029
1029
1030
1030
1031 $ hg up null --quiet
1031 $ hg up null --quiet
1032 $ hg log -G --rev '::(desc("mCB-change-m")+desc("mBC-change-m"))'
1032 $ hg log -G --rev '::(desc("mCB-change-m")+desc("mBC-change-m"))'
1033 o mBC-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1033 o mBC-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1034 |\
1034 |\
1035 +---o mCB-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1035 +---o mCB-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1036 | |/
1036 | |/
1037 | o c-1 delete d
1037 | o c-1 delete d
1038 | |
1038 | |
1039 o | b-1: b update
1039 o | b-1: b update
1040 |/
1040 |/
1041 o i-2: c -move-> d, s -move-> t
1041 o i-2: c -move-> d, s -move-> t
1042 |
1042 |
1043 o i-1: a -move-> c, p -move-> s
1043 o i-1: a -move-> c, p -move-> s
1044 |
1044 |
1045 o i-0 initial commit: a b h p q r
1045 o i-0 initial commit: a b h p q r
1046
1046
1047
1047
1048 Decision from previous merge are properly chained with later merge
1048 Decision from previous merge are properly chained with later merge
1049 ------------------------------------------------------------------
1049 ------------------------------------------------------------------
1050
1050
1051 Subcase: chaining conflicting rename resolution
1051 Subcase: chaining conflicting rename resolution
1052 ```````````````````````````````````````````````
1052 ```````````````````````````````````````````````
1053
1053
1054 The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We
1054 The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We
1055 add more change on the respective branch and merge again. These second merge
1055 add more change on the respective branch and merge again. These second merge
1056 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
1056 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
1057 about that file should stay unchanged.
1057 about that file should stay unchanged.
1058
1058
1059 We also touch J during some of the merge to check for unrelated change to new file during merge.
1059 We also touch J during some of the merge to check for unrelated change to new file during merge.
1060
1060
1061 $ case_desc="chained merges (conflict -> simple) - same content everywhere"
1061 $ case_desc="chained merges (conflict -> simple) - same content everywhere"
1062
1062
1063 (extra unrelated changes)
1063 (extra unrelated changes)
1064
1064
1065 $ hg up 'desc("a-2")'
1065 $ hg up 'desc("a-2")'
1066 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1066 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1067 $ echo j > unrelated-j
1067 $ echo j > unrelated-j
1068 $ hg add unrelated-j
1068 $ hg add unrelated-j
1069 $ hg ci -m 'j-1: unrelated changes (based on the "a" series of changes)'
1069 $ hg ci -m 'j-1: unrelated changes (based on the "a" series of changes)'
1070 created new head
1070 created new head
1071
1071
1072 $ hg up 'desc("e-2")'
1072 $ hg up 'desc("e-2")'
1073 2 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1073 2 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1074 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1074 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1075 $ echo k > unrelated-k
1075 $ echo k > unrelated-k
1076 $ hg add unrelated-k
1076 $ hg add unrelated-k
1077 $ hg ci -m 'k-1: unrelated changes (based on "e" changes)'
1077 $ hg ci -m 'k-1: unrelated changes (based on "e" changes)'
1078 created new head
1078 created new head
1079
1079
1080 (merge variant 1)
1080 (merge variant 1)
1081
1081
1082 $ hg up 'desc("mAEm")'
1082 $ hg up 'desc("mAEm")'
1083 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1083 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1084 0 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1084 0 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1085 $ hg merge 'desc("k-1")'
1085 $ hg merge 'desc("k-1")'
1086 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1086 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1087 (branch merge, don't forget to commit)
1087 (branch merge, don't forget to commit)
1088 $ hg ci -m "mAE,Km: $case_desc"
1088 $ hg ci -m "mAE,Km: $case_desc"
1089
1089
1090 (merge variant 2)
1090 (merge variant 2)
1091
1091
1092 $ hg up 'desc("k-1")'
1092 $ hg up 'desc("k-1")'
1093 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
1093 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
1094 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
1094 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
1095
1095
1096 $ hg merge 'desc("mAEm")'
1096 $ hg merge 'desc("mAEm")'
1097 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
1097 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
1098 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
1098 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
1099 (branch merge, don't forget to commit)
1099 (branch merge, don't forget to commit)
1100 $ hg ci -m "mK,AEm: $case_desc"
1100 $ hg ci -m "mK,AEm: $case_desc"
1101 created new head
1101 created new head
1102
1102
1103 (merge variant 3)
1103 (merge variant 3)
1104
1104
1105 $ hg up 'desc("mEAm")'
1105 $ hg up 'desc("mEAm")'
1106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1107 $ hg merge 'desc("j-1")'
1107 $ hg merge 'desc("j-1")'
1108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1109 (branch merge, don't forget to commit)
1109 (branch merge, don't forget to commit)
1110 $ echo jj > unrelated-j
1110 $ echo jj > unrelated-j
1111 $ hg ci -m "mEA,Jm: $case_desc"
1111 $ hg ci -m "mEA,Jm: $case_desc"
1112
1112
1113 (merge variant 4)
1113 (merge variant 4)
1114
1114
1115 $ hg up 'desc("j-1")'
1115 $ hg up 'desc("j-1")'
1116 3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
1116 3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
1117 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
1117 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
1118 $ hg merge 'desc("mEAm")'
1118 $ hg merge 'desc("mEAm")'
1119 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
1119 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
1120 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
1120 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
1121 (branch merge, don't forget to commit)
1121 (branch merge, don't forget to commit)
1122 $ echo jj > unrelated-j
1122 $ echo jj > unrelated-j
1123 $ hg ci -m "mJ,EAm: $case_desc"
1123 $ hg ci -m "mJ,EAm: $case_desc"
1124 created new head
1124 created new head
1125
1125
1126
1126
1127 $ hg log -G --rev '::(desc("mAE,Km") + desc("mK,AEm") + desc("mEA,Jm") + desc("mJ,EAm"))'
1127 $ hg log -G --rev '::(desc("mAE,Km") + desc("mK,AEm") + desc("mEA,Jm") + desc("mJ,EAm"))'
1128 @ mJ,EAm: chained merges (conflict -> simple) - same content everywhere
1128 @ mJ,EAm: chained merges (conflict -> simple) - same content everywhere
1129 |\
1129 |\
1130 +---o mEA,Jm: chained merges (conflict -> simple) - same content everywhere
1130 +---o mEA,Jm: chained merges (conflict -> simple) - same content everywhere
1131 | |/
1131 | |/
1132 | | o mK,AEm: chained merges (conflict -> simple) - same content everywhere
1132 | | o mK,AEm: chained merges (conflict -> simple) - same content everywhere
1133 | | |\
1133 | | |\
1134 | | +---o mAE,Km: chained merges (conflict -> simple) - same content everywhere
1134 | | +---o mAE,Km: chained merges (conflict -> simple) - same content everywhere
1135 | | | |/
1135 | | | |/
1136 | | | o k-1: unrelated changes (based on "e" changes)
1136 | | | o k-1: unrelated changes (based on "e" changes)
1137 | | | |
1137 | | | |
1138 | o | | j-1: unrelated changes (based on the "a" series of changes)
1138 | o | | j-1: unrelated changes (based on the "a" series of changes)
1139 | | | |
1139 | | | |
1140 o-----+ mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
1140 o-----+ mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
1141 |/ / /
1141 |/ / /
1142 | o / mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
1142 | o / mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
1143 |/|/
1143 |/|/
1144 | o e-2 g -move-> f
1144 | o e-2 g -move-> f
1145 | |
1145 | |
1146 | o e-1 b -move-> g
1146 | o e-1 b -move-> g
1147 | |
1147 | |
1148 o | a-2: e -move-> f
1148 o | a-2: e -move-> f
1149 | |
1149 | |
1150 o | a-1: d -move-> e
1150 o | a-1: d -move-> e
1151 |/
1151 |/
1152 o i-2: c -move-> d, s -move-> t
1152 o i-2: c -move-> d, s -move-> t
1153 |
1153 |
1154 o i-1: a -move-> c, p -move-> s
1154 o i-1: a -move-> c, p -move-> s
1155 |
1155 |
1156 o i-0 initial commit: a b h p q r
1156 o i-0 initial commit: a b h p q r
1157
1157
1158
1158
1159 Subcase: chaining conflicting rename resolution, with actual merging happening
1159 Subcase: chaining conflicting rename resolution, with actual merging happening
1160 ``````````````````````````````````````````````````````````````````````````````
1160 ``````````````````````````````````````````````````````````````````````````````
1161
1161
1162 The "mPQm" and "mQPm" case create a rename tracking conflict on file 't'. We
1162 The "mPQm" and "mQPm" case create a rename tracking conflict on file 't'. We
1163 add more change on the respective branch and merge again. These second merge
1163 add more change on the respective branch and merge again. These second merge
1164 does not involve the file 't' and the arbitration done within "mPQm" and "mQP"
1164 does not involve the file 't' and the arbitration done within "mPQm" and "mQP"
1165 about that file should stay unchanged.
1165 about that file should stay unchanged.
1166
1166
1167 $ case_desc="chained merges (conflict -> simple) - different content"
1167 $ case_desc="chained merges (conflict -> simple) - different content"
1168
1168
1169 (extra unrelated changes)
1169 (extra unrelated changes)
1170
1170
1171 $ hg up 'desc("p-2")'
1171 $ hg up 'desc("p-2")'
1172 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
1172 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
1173 $ echo s > unrelated-s
1173 $ echo s > unrelated-s
1174 $ hg add unrelated-s
1174 $ hg add unrelated-s
1175 $ hg ci -m 's-1: unrelated changes (based on the "p" series of changes)'
1175 $ hg ci -m 's-1: unrelated changes (based on the "p" series of changes)'
1176 created new head
1176 created new head
1177
1177
1178 $ hg up 'desc("q-2")'
1178 $ hg up 'desc("q-2")'
1179 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
1179 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
1180 $ echo t > unrelated-t
1180 $ echo t > unrelated-t
1181 $ hg add unrelated-t
1181 $ hg add unrelated-t
1182 $ hg ci -m 't-1: unrelated changes (based on "q" changes)'
1182 $ hg ci -m 't-1: unrelated changes (based on "q" changes)'
1183 created new head
1183 created new head
1184
1184
1185 (merge variant 1)
1185 (merge variant 1)
1186
1186
1187 $ hg up 'desc("mPQm")'
1187 $ hg up 'desc("mPQm")'
1188 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1188 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1189 $ hg merge 'desc("t-1")'
1189 $ hg merge 'desc("t-1")'
1190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1191 (branch merge, don't forget to commit)
1191 (branch merge, don't forget to commit)
1192 $ hg ci -m "mPQ,Tm: $case_desc"
1192 $ hg ci -m "mPQ,Tm: $case_desc"
1193
1193
1194 (merge variant 2)
1194 (merge variant 2)
1195
1195
1196 $ hg up 'desc("t-1")'
1196 $ hg up 'desc("t-1")'
1197 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1197 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1198
1198
1199 $ hg merge 'desc("mPQm")'
1199 $ hg merge 'desc("mPQm")'
1200 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1200 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1201 (branch merge, don't forget to commit)
1201 (branch merge, don't forget to commit)
1202 $ hg ci -m "mT,PQm: $case_desc"
1202 $ hg ci -m "mT,PQm: $case_desc"
1203 created new head
1203 created new head
1204
1204
1205 (merge variant 3)
1205 (merge variant 3)
1206
1206
1207 $ hg up 'desc("mQPm")'
1207 $ hg up 'desc("mQPm")'
1208 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1208 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1209 $ hg merge 'desc("s-1")'
1209 $ hg merge 'desc("s-1")'
1210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1211 (branch merge, don't forget to commit)
1211 (branch merge, don't forget to commit)
1212 $ hg ci -m "mQP,Sm: $case_desc"
1212 $ hg ci -m "mQP,Sm: $case_desc"
1213
1213
1214 (merge variant 4)
1214 (merge variant 4)
1215
1215
1216 $ hg up 'desc("s-1")'
1216 $ hg up 'desc("s-1")'
1217 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1217 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1218 $ hg merge 'desc("mQPm")'
1218 $ hg merge 'desc("mQPm")'
1219 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1219 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1220 (branch merge, don't forget to commit)
1220 (branch merge, don't forget to commit)
1221 $ hg ci -m "mS,QPm: $case_desc"
1221 $ hg ci -m "mS,QPm: $case_desc"
1222 created new head
1222 created new head
1223 $ hg up null --quiet
1223 $ hg up null --quiet
1224
1224
1225
1225
1226 $ hg log -G --rev '::(desc("mPQ,Tm") + desc("mT,PQm") + desc("mQP,Sm") + desc("mS,QPm"))'
1226 $ hg log -G --rev '::(desc("mPQ,Tm") + desc("mT,PQm") + desc("mQP,Sm") + desc("mS,QPm"))'
1227 o mS,QPm: chained merges (conflict -> simple) - different content
1227 o mS,QPm: chained merges (conflict -> simple) - different content
1228 |\
1228 |\
1229 +---o mQP,Sm: chained merges (conflict -> simple) - different content
1229 +---o mQP,Sm: chained merges (conflict -> simple) - different content
1230 | |/
1230 | |/
1231 | | o mT,PQm: chained merges (conflict -> simple) - different content
1231 | | o mT,PQm: chained merges (conflict -> simple) - different content
1232 | | |\
1232 | | |\
1233 | | +---o mPQ,Tm: chained merges (conflict -> simple) - different content
1233 | | +---o mPQ,Tm: chained merges (conflict -> simple) - different content
1234 | | | |/
1234 | | | |/
1235 | | | o t-1: unrelated changes (based on "q" changes)
1235 | | | o t-1: unrelated changes (based on "q" changes)
1236 | | | |
1236 | | | |
1237 | o | | s-1: unrelated changes (based on the "p" series of changes)
1237 | o | | s-1: unrelated changes (based on the "p" series of changes)
1238 | | | |
1238 | | | |
1239 o-----+ mQPm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - the other way
1239 o-----+ mQPm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - the other way
1240 |/ / /
1240 |/ / /
1241 | o / mPQm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - one way
1241 | o / mPQm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - one way
1242 |/|/
1242 |/|/
1243 | o q-2 w -move-> v
1243 | o q-2 w -move-> v
1244 | |
1244 | |
1245 | o q-1 r -move-> w
1245 | o q-1 r -move-> w
1246 | |
1246 | |
1247 o | p-2: u -move-> v
1247 o | p-2: u -move-> v
1248 | |
1248 | |
1249 o | p-1: t -move-> u
1249 o | p-1: t -move-> u
1250 |/
1250 |/
1251 o i-2: c -move-> d, s -move-> t
1251 o i-2: c -move-> d, s -move-> t
1252 |
1252 |
1253 o i-1: a -move-> c, p -move-> s
1253 o i-1: a -move-> c, p -move-> s
1254 |
1254 |
1255 o i-0 initial commit: a b h p q r
1255 o i-0 initial commit: a b h p q r
1256
1256
1257
1257
1258 Subcase: chaining salvage information during a merge
1258 Subcase: chaining salvage information during a merge
1259 ````````````````````````````````````````````````````
1259 ````````````````````````````````````````````````````
1260
1260
1261 We add more change on the branch were the file was deleted. merging again
1261 We add more change on the branch were the file was deleted. merging again
1262 should preserve the fact eh file was salvaged.
1262 should preserve the fact eh file was salvaged.
1263
1263
1264 $ case_desc="chained merges (salvaged -> simple) - same content (when the file exists)"
1264 $ case_desc="chained merges (salvaged -> simple) - same content (when the file exists)"
1265
1265
1266 (creating the change)
1266 (creating the change)
1267
1267
1268 $ hg up 'desc("c-1")'
1268 $ hg up 'desc("c-1")'
1269 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1269 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1270 $ echo l > unrelated-l
1270 $ echo l > unrelated-l
1271 $ hg add unrelated-l
1271 $ hg add unrelated-l
1272 $ hg ci -m 'l-1: unrelated changes (based on "c" changes)'
1272 $ hg ci -m 'l-1: unrelated changes (based on "c" changes)'
1273 created new head
1273 created new head
1274
1274
1275 (Merge variant 1)
1275 (Merge variant 1)
1276
1276
1277 $ hg up 'desc("mBC-revert-m")'
1277 $ hg up 'desc("mBC-revert-m")'
1278 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1278 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1279 $ hg merge 'desc("l-1")'
1279 $ hg merge 'desc("l-1")'
1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1281 (branch merge, don't forget to commit)
1281 (branch merge, don't forget to commit)
1282 $ hg ci -m "mBC+revert,Lm: $case_desc"
1282 $ hg ci -m "mBC+revert,Lm: $case_desc"
1283
1283
1284 (Merge variant 2)
1284 (Merge variant 2)
1285
1285
1286 $ hg up 'desc("mCB-revert-m")'
1286 $ hg up 'desc("mCB-revert-m")'
1287 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1287 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1288 $ hg merge 'desc("l-1")'
1288 $ hg merge 'desc("l-1")'
1289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1290 (branch merge, don't forget to commit)
1290 (branch merge, don't forget to commit)
1291 $ hg ci -m "mCB+revert,Lm: $case_desc"
1291 $ hg ci -m "mCB+revert,Lm: $case_desc"
1292
1292
1293 (Merge variant 3)
1293 (Merge variant 3)
1294
1294
1295 $ hg up 'desc("l-1")'
1295 $ hg up 'desc("l-1")'
1296 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1296 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1297
1297
1298 $ hg merge 'desc("mBC-revert-m")'
1298 $ hg merge 'desc("mBC-revert-m")'
1299 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1299 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1300 (branch merge, don't forget to commit)
1300 (branch merge, don't forget to commit)
1301 $ hg ci -m "mL,BC+revertm: $case_desc"
1301 $ hg ci -m "mL,BC+revertm: $case_desc"
1302 created new head
1302 created new head
1303
1303
1304 (Merge variant 4)
1304 (Merge variant 4)
1305
1305
1306 $ hg up 'desc("l-1")'
1306 $ hg up 'desc("l-1")'
1307 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1307 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1308
1308
1309 $ hg merge 'desc("mCB-revert-m")'
1309 $ hg merge 'desc("mCB-revert-m")'
1310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1311 (branch merge, don't forget to commit)
1311 (branch merge, don't forget to commit)
1312 $ hg ci -m "mL,CB+revertm: $case_desc"
1312 $ hg ci -m "mL,CB+revertm: $case_desc"
1313 created new head
1313 created new head
1314
1314
1315 $ hg log -G --rev '::(desc("mBC+revert,Lm") + desc("mCB+revert,Lm") + desc("mL,BC+revertm") + desc("mL,CB+revertm"))'
1315 $ hg log -G --rev '::(desc("mBC+revert,Lm") + desc("mCB+revert,Lm") + desc("mL,BC+revertm") + desc("mL,CB+revertm"))'
1316 @ mL,CB+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1316 @ mL,CB+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1317 |\
1317 |\
1318 | | o mL,BC+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1318 | | o mL,BC+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1319 | |/|
1319 | |/|
1320 +-+---o mCB+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1320 +-+---o mCB+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1321 | | |
1321 | | |
1322 | +---o mBC+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1322 | +---o mBC+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1323 | | |/
1323 | | |/
1324 | o | l-1: unrelated changes (based on "c" changes)
1324 | o | l-1: unrelated changes (based on "c" changes)
1325 | | |
1325 | | |
1326 | | o mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1326 | | o mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1327 | |/|
1327 | |/|
1328 o---+ mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1328 o---+ mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1329 |/ /
1329 |/ /
1330 o | c-1 delete d
1330 o | c-1 delete d
1331 | |
1331 | |
1332 | o b-1: b update
1332 | o b-1: b update
1333 |/
1333 |/
1334 o i-2: c -move-> d, s -move-> t
1334 o i-2: c -move-> d, s -move-> t
1335 |
1335 |
1336 o i-1: a -move-> c, p -move-> s
1336 o i-1: a -move-> c, p -move-> s
1337 |
1337 |
1338 o i-0 initial commit: a b h p q r
1338 o i-0 initial commit: a b h p q r
1339
1339
1340
1340
1341
1341
1342 Subcase: chaining "merged" information during a merge
1342 Subcase: chaining "merged" information during a merge
1343 ``````````````````````````````````````````````````````
1343 ``````````````````````````````````````````````````````
1344
1344
1345 When a non-rename change are merged with a copy overwrite, the merge pick the copy source from (p1) as the reference. We should preserve this information in subsequent merges.
1345 When a non-rename change are merged with a copy overwrite, the merge pick the copy source from (p1) as the reference. We should preserve this information in subsequent merges.
1346
1346
1347 $ case_desc="chained merges (copy-overwrite -> simple) - same content"
1347 $ case_desc="chained merges (copy-overwrite -> simple) - same content"
1348
1348
1349 (extra unrelated changes)
1349 (extra unrelated changes)
1350
1350
1351 $ hg up 'desc("f-2")'
1351 $ hg up 'desc("f-2")'
1352 2 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1352 2 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1353 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1353 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1354 $ echo n > unrelated-n
1354 $ echo n > unrelated-n
1355 $ hg add unrelated-n
1355 $ hg add unrelated-n
1356 $ hg ci -m 'n-1: unrelated changes (based on the "f" series of changes)'
1356 $ hg ci -m 'n-1: unrelated changes (based on the "f" series of changes)'
1357 created new head
1357 created new head
1358
1358
1359 $ hg up 'desc("g-1")'
1359 $ hg up 'desc("g-1")'
1360 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1360 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1361 $ echo o > unrelated-o
1361 $ echo o > unrelated-o
1362 $ hg add unrelated-o
1362 $ hg add unrelated-o
1363 $ hg ci -m 'o-1: unrelated changes (based on "g" changes)'
1363 $ hg ci -m 'o-1: unrelated changes (based on "g" changes)'
1364 created new head
1364 created new head
1365
1365
1366 (merge variant 1)
1366 (merge variant 1)
1367
1367
1368 $ hg up 'desc("mFGm")'
1368 $ hg up 'desc("mFGm")'
1369 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1369 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !)
1370 0 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1370 0 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !)
1371 $ hg merge 'desc("o-1")'
1371 $ hg merge 'desc("o-1")'
1372 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1372 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1373 (branch merge, don't forget to commit)
1373 (branch merge, don't forget to commit)
1374 $ hg ci -m "mFG,Om: $case_desc"
1374 $ hg ci -m "mFG,Om: $case_desc"
1375
1375
1376 (merge variant 2)
1376 (merge variant 2)
1377
1377
1378 $ hg up 'desc("o-1")'
1378 $ hg up 'desc("o-1")'
1379 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
1379 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !)
1380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
1380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !)
1381 $ hg merge 'desc("FGm")'
1381 $ hg merge 'desc("FGm")'
1382 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
1382 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !)
1383 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
1383 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !)
1384 (branch merge, don't forget to commit)
1384 (branch merge, don't forget to commit)
1385 $ hg ci -m "mO,FGm: $case_desc"
1385 $ hg ci -m "mO,FGm: $case_desc"
1386 created new head
1386 created new head
1387
1387
1388 (merge variant 3)
1388 (merge variant 3)
1389
1389
1390 $ hg up 'desc("mGFm")'
1390 $ hg up 'desc("mGFm")'
1391 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1391 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1392 $ hg merge 'desc("n-1")'
1392 $ hg merge 'desc("n-1")'
1393 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1393 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1394 (branch merge, don't forget to commit)
1394 (branch merge, don't forget to commit)
1395 $ hg ci -m "mGF,Nm: $case_desc"
1395 $ hg ci -m "mGF,Nm: $case_desc"
1396
1396
1397 (merge variant 4)
1397 (merge variant 4)
1398
1398
1399 $ hg up 'desc("n-1")'
1399 $ hg up 'desc("n-1")'
1400 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1400 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1401 $ hg merge 'desc("mGFm")'
1401 $ hg merge 'desc("mGFm")'
1402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1403 (branch merge, don't forget to commit)
1403 (branch merge, don't forget to commit)
1404 $ hg ci -m "mN,GFm: $case_desc"
1404 $ hg ci -m "mN,GFm: $case_desc"
1405 created new head
1405 created new head
1406
1406
1407 $ hg log -G --rev '::(desc("mFG,Om") + desc("mO,FGm") + desc("mGF,Nm") + desc("mN,GFm"))'
1407 $ hg log -G --rev '::(desc("mFG,Om") + desc("mO,FGm") + desc("mGF,Nm") + desc("mN,GFm"))'
1408 @ mN,GFm: chained merges (copy-overwrite -> simple) - same content
1408 @ mN,GFm: chained merges (copy-overwrite -> simple) - same content
1409 |\
1409 |\
1410 +---o mGF,Nm: chained merges (copy-overwrite -> simple) - same content
1410 +---o mGF,Nm: chained merges (copy-overwrite -> simple) - same content
1411 | |/
1411 | |/
1412 | | o mO,FGm: chained merges (copy-overwrite -> simple) - same content
1412 | | o mO,FGm: chained merges (copy-overwrite -> simple) - same content
1413 | | |\
1413 | | |\
1414 | | +---o mFG,Om: chained merges (copy-overwrite -> simple) - same content
1414 | | +---o mFG,Om: chained merges (copy-overwrite -> simple) - same content
1415 | | | |/
1415 | | | |/
1416 | | | o o-1: unrelated changes (based on "g" changes)
1416 | | | o o-1: unrelated changes (based on "g" changes)
1417 | | | |
1417 | | | |
1418 | o | | n-1: unrelated changes (based on the "f" series of changes)
1418 | o | | n-1: unrelated changes (based on the "f" series of changes)
1419 | | | |
1419 | | | |
1420 o-----+ mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
1420 o-----+ mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
1421 |/ / /
1421 |/ / /
1422 | o / mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
1422 | o / mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
1423 |/|/
1423 |/|/
1424 | o g-1: update d
1424 | o g-1: update d
1425 | |
1425 | |
1426 o | f-2: rename i -> d
1426 o | f-2: rename i -> d
1427 | |
1427 | |
1428 o | f-1: rename h -> i
1428 o | f-1: rename h -> i
1429 |/
1429 |/
1430 o i-2: c -move-> d, s -move-> t
1430 o i-2: c -move-> d, s -move-> t
1431 |
1431 |
1432 o i-1: a -move-> c, p -move-> s
1432 o i-1: a -move-> c, p -move-> s
1433 |
1433 |
1434 o i-0 initial commit: a b h p q r
1434 o i-0 initial commit: a b h p q r
1435
1435
1436
1436
1437 Subcase: chaining conflicting rename resolution, with extra change during the merge
1437 Subcase: chaining conflicting rename resolution, with extra change during the merge
1438 ```````````````````````````````````````````````````````````````````````````````````
1438 ```````````````````````````````````````````````````````````````````````````````````
1439
1439
1440 The "mEA-change-m-0" and "mAE-change-m-0" case create a rename tracking conflict on file 'f'. We
1440 The "mEA-change-m-0" and "mAE-change-m-0" case create a rename tracking conflict on file 'f'. We
1441 add more change on the respective branch and merge again. These second merge
1441 add more change on the respective branch and merge again. These second merge
1442 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
1442 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
1443 about that file should stay unchanged.
1443 about that file should stay unchanged.
1444
1444
1445 $ case_desc="chained merges (conflict+change -> simple) - same content on both branch in the initial merge"
1445 $ case_desc="chained merges (conflict+change -> simple) - same content on both branch in the initial merge"
1446
1446
1447
1447
1448 (merge variant 1)
1448 (merge variant 1)
1449
1449
1450 $ hg up 'desc("mAE-change-m")'
1450 $ hg up 'desc("mAE-change-m")'
1451 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
1451 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
1452 $ hg merge 'desc("k-1")'
1452 $ hg merge 'desc("k-1")'
1453 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1453 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1454 (branch merge, don't forget to commit)
1454 (branch merge, don't forget to commit)
1455 $ hg ci -m "mAE-change,Km: $case_desc"
1455 $ hg ci -m "mAE-change,Km: $case_desc"
1456
1456
1457 (merge variant 2)
1457 (merge variant 2)
1458
1458
1459 $ hg up 'desc("k-1")'
1459 $ hg up 'desc("k-1")'
1460 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1460 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1461
1461
1462 $ hg merge 'desc("mAE-change-m")'
1462 $ hg merge 'desc("mAE-change-m")'
1463 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1463 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1464 (branch merge, don't forget to commit)
1464 (branch merge, don't forget to commit)
1465 $ hg ci -m "mK,AE-change-m: $case_desc"
1465 $ hg ci -m "mK,AE-change-m: $case_desc"
1466 created new head
1466 created new head
1467
1467
1468 (merge variant 3)
1468 (merge variant 3)
1469
1469
1470 $ hg up 'desc("mEA-change-m")'
1470 $ hg up 'desc("mEA-change-m")'
1471 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1471 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1472 $ hg merge 'desc("j-1")'
1472 $ hg merge 'desc("j-1")'
1473 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1473 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1474 (branch merge, don't forget to commit)
1474 (branch merge, don't forget to commit)
1475 $ hg ci -m "mEA-change,Jm: $case_desc"
1475 $ hg ci -m "mEA-change,Jm: $case_desc"
1476
1476
1477 (merge variant 4)
1477 (merge variant 4)
1478
1478
1479 $ hg up 'desc("j-1")'
1479 $ hg up 'desc("j-1")'
1480 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1480 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1481 $ hg merge 'desc("mEA-change-m")'
1481 $ hg merge 'desc("mEA-change-m")'
1482 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1482 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1483 (branch merge, don't forget to commit)
1483 (branch merge, don't forget to commit)
1484 $ hg ci -m "mJ,EA-change-m: $case_desc"
1484 $ hg ci -m "mJ,EA-change-m: $case_desc"
1485 created new head
1485 created new head
1486
1486
1487
1487
1488 $ hg log -G --rev '::(desc("mAE-change,Km") + desc("mK,AE-change-m") + desc("mEA-change,Jm") + desc("mJ,EA-change-m"))'
1488 $ hg log -G --rev '::(desc("mAE-change,Km") + desc("mK,AE-change-m") + desc("mEA-change,Jm") + desc("mJ,EA-change-m"))'
1489 @ mJ,EA-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1489 @ mJ,EA-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1490 |\
1490 |\
1491 +---o mEA-change,Jm: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1491 +---o mEA-change,Jm: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1492 | |/
1492 | |/
1493 | | o mK,AE-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1493 | | o mK,AE-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1494 | | |\
1494 | | |\
1495 | | +---o mAE-change,Km: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1495 | | +---o mAE-change,Km: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1496 | | | |/
1496 | | | |/
1497 | | | o k-1: unrelated changes (based on "e" changes)
1497 | | | o k-1: unrelated changes (based on "e" changes)
1498 | | | |
1498 | | | |
1499 | o | | j-1: unrelated changes (based on the "a" series of changes)
1499 | o | | j-1: unrelated changes (based on the "a" series of changes)
1500 | | | |
1500 | | | |
1501 o-----+ mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
1501 o-----+ mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
1502 |/ / /
1502 |/ / /
1503 | o / mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
1503 | o / mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
1504 |/|/
1504 |/|/
1505 | o e-2 g -move-> f
1505 | o e-2 g -move-> f
1506 | |
1506 | |
1507 | o e-1 b -move-> g
1507 | o e-1 b -move-> g
1508 | |
1508 | |
1509 o | a-2: e -move-> f
1509 o | a-2: e -move-> f
1510 | |
1510 | |
1511 o | a-1: d -move-> e
1511 o | a-1: d -move-> e
1512 |/
1512 |/
1513 o i-2: c -move-> d, s -move-> t
1513 o i-2: c -move-> d, s -move-> t
1514 |
1514 |
1515 o i-1: a -move-> c, p -move-> s
1515 o i-1: a -move-> c, p -move-> s
1516 |
1516 |
1517 o i-0 initial commit: a b h p q r
1517 o i-0 initial commit: a b h p q r
1518
1518
1519
1519
1520 Summary of all created cases
1520 Summary of all created cases
1521 ----------------------------
1521 ----------------------------
1522
1522
1523 $ hg up --quiet null
1523 $ hg up --quiet null
1524
1524
1525 (This exists to help keeping a compact list of the various cases we have built)
1525 (This exists to help keeping a compact list of the various cases we have built)
1526
1526
1527 $ hg log -T '{desc|firstline}\n'| sort
1527 $ hg log -T '{desc|firstline}\n'| sort
1528 a-1: d -move-> e
1528 a-1: d -move-> e
1529 a-2: e -move-> f
1529 a-2: e -move-> f
1530 b-1: b update
1530 b-1: b update
1531 c-1 delete d
1531 c-1 delete d
1532 d-1 delete d
1532 d-1 delete d
1533 d-2 re-add d
1533 d-2 re-add d
1534 e-1 b -move-> g
1534 e-1 b -move-> g
1535 e-2 g -move-> f
1535 e-2 g -move-> f
1536 f-1: rename h -> i
1536 f-1: rename h -> i
1537 f-2: rename i -> d
1537 f-2: rename i -> d
1538 g-1: update d
1538 g-1: update d
1539 h-1: b -(move)-> d
1539 h-1: b -(move)-> d
1540 i-0 initial commit: a b h p q r
1540 i-0 initial commit: a b h p q r
1541 i-1: a -move-> c, p -move-> s
1541 i-1: a -move-> c, p -move-> s
1542 i-2: c -move-> d, s -move-> t
1542 i-2: c -move-> d, s -move-> t
1543 j-1: unrelated changes (based on the "a" series of changes)
1543 j-1: unrelated changes (based on the "a" series of changes)
1544 k-1: unrelated changes (based on "e" changes)
1544 k-1: unrelated changes (based on "e" changes)
1545 l-1: unrelated changes (based on "c" changes)
1545 l-1: unrelated changes (based on "c" changes)
1546 mABm-0 simple merge - A side: multiple renames, B side: unrelated update - the other way
1546 mABm-0 simple merge - A side: multiple renames, B side: unrelated update - the other way
1547 mAE,Km: chained merges (conflict -> simple) - same content everywhere
1547 mAE,Km: chained merges (conflict -> simple) - same content everywhere
1548 mAE-change,Km: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1548 mAE-change,Km: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1549 mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
1549 mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
1550 mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
1550 mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
1551 mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way
1551 mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way
1552 mBC+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1552 mBC+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1553 mBC-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1553 mBC-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1554 mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1554 mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
1555 mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way
1555 mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way
1556 mBCm-1 re-add d
1556 mBCm-1 re-add d
1557 mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way
1557 mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way
1558 mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
1558 mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
1559 mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
1559 mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
1560 mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way
1560 mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way
1561 mCB+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1561 mCB+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists)
1562 mCB-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1562 mCB-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1563 mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1563 mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
1564 mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way
1564 mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way
1565 mCBm-1 re-add d
1565 mCBm-1 re-add d
1566 mCGm-0 merge updated/deleted - revive the file (updated content) - one way
1566 mCGm-0 merge updated/deleted - revive the file (updated content) - one way
1567 mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way
1567 mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way
1568 mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way
1568 mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way
1569 mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
1569 mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
1570 mEA,Jm: chained merges (conflict -> simple) - same content everywhere
1570 mEA,Jm: chained merges (conflict -> simple) - same content everywhere
1571 mEA-change,Jm: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1571 mEA-change,Jm: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1572 mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
1572 mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
1573 mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
1573 mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
1574 mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
1574 mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
1575 mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
1575 mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
1576 mFG,Om: chained merges (copy-overwrite -> simple) - same content
1576 mFG,Om: chained merges (copy-overwrite -> simple) - same content
1577 mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
1577 mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
1578 mGCm-0 merge updated/deleted - revive the file (updated content) - the other way
1578 mGCm-0 merge updated/deleted - revive the file (updated content) - the other way
1579 mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way
1579 mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way
1580 mGF,Nm: chained merges (copy-overwrite -> simple) - same content
1580 mGF,Nm: chained merges (copy-overwrite -> simple) - same content
1581 mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
1581 mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
1582 mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way
1582 mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way
1583 mJ,EA-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1583 mJ,EA-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1584 mJ,EAm: chained merges (conflict -> simple) - same content everywhere
1584 mJ,EAm: chained merges (conflict -> simple) - same content everywhere
1585 mK,AE-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1585 mK,AE-change-m: chained merges (conflict+change -> simple) - same content on both branch in the initial merge
1586 mK,AEm: chained merges (conflict -> simple) - same content everywhere
1586 mK,AEm: chained merges (conflict -> simple) - same content everywhere
1587 mL,BC+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1587 mL,BC+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1588 mL,CB+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1588 mL,CB+revertm: chained merges (salvaged -> simple) - same content (when the file exists)
1589 mN,GFm: chained merges (copy-overwrite -> simple) - same content
1589 mN,GFm: chained merges (copy-overwrite -> simple) - same content
1590 mO,FGm: chained merges (copy-overwrite -> simple) - same content
1590 mO,FGm: chained merges (copy-overwrite -> simple) - same content
1591 mPQ,Tm: chained merges (conflict -> simple) - different content
1591 mPQ,Tm: chained merges (conflict -> simple) - different content
1592 mPQm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - one way
1592 mPQm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - one way
1593 mQP,Sm: chained merges (conflict -> simple) - different content
1593 mQP,Sm: chained merges (conflict -> simple) - different content
1594 mQPm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - the other way
1594 mQPm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - the other way
1595 mRBm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - the other way
1595 mRBm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - the other way
1596 mS,QPm: chained merges (conflict -> simple) - different content
1596 mS,QPm: chained merges (conflict -> simple) - different content
1597 mT,PQm: chained merges (conflict -> simple) - different content
1597 mT,PQm: chained merges (conflict -> simple) - different content
1598 n-1: unrelated changes (based on the "f" series of changes)
1598 n-1: unrelated changes (based on the "f" series of changes)
1599 o-1: unrelated changes (based on "g" changes)
1599 o-1: unrelated changes (based on "g" changes)
1600 p-1: t -move-> u
1600 p-1: t -move-> u
1601 p-2: u -move-> v
1601 p-2: u -move-> v
1602 q-1 r -move-> w
1602 q-1 r -move-> w
1603 q-2 w -move-> v
1603 q-2 w -move-> v
1604 r-1: rename r -> x
1604 r-1: rename r -> x
1605 r-2: rename t -> x
1605 r-2: rename t -> x
1606 s-1: unrelated changes (based on the "p" series of changes)
1606 s-1: unrelated changes (based on the "p" series of changes)
1607 t-1: unrelated changes (based on "q" changes)
1607 t-1: unrelated changes (based on "q" changes)
1608
1608
1609
1609
1610 Test that sidedata computations during upgrades are correct
1610 Test that sidedata computations during upgrades are correct
1611 ===========================================================
1611 ===========================================================
1612
1612
1613 We upgrade a repository that is not using sidedata (the filelog case) and
1613 We upgrade a repository that is not using sidedata (the filelog case) and
1614 check that the same side data have been generated as if they were computed at
1614 check that the same side data have been generated as if they were computed at
1615 commit time.
1615 commit time.
1616
1616
1617
1617
1618 #if upgraded
1618 #if upgraded
1619 $ cat >> $HGRCPATH << EOF
1619 $ cat >> $HGRCPATH << EOF
1620 > [format]
1620 > [format]
1621 > exp-use-side-data = yes
1621 > exp-use-side-data = yes
1622 > exp-use-copies-side-data-changeset = yes
1622 > exp-use-copies-side-data-changeset = yes
1623 > EOF
1623 > EOF
1624 $ hg debugformat -v
1624 $ hg debugformat -v
1625 format-variant repo config default
1625 format-variant repo config default
1626 fncache: yes yes yes
1626 fncache: yes yes yes
1627 dotencode: yes yes yes
1627 dotencode: yes yes yes
1628 generaldelta: yes yes yes
1628 generaldelta: yes yes yes
1629 share-safe: no no no
1629 share-safe: no no no
1630 sparserevlog: yes yes yes
1630 sparserevlog: yes yes yes
1631 persistent-nodemap: no no no
1631 persistent-nodemap: no no no
1632 copies-sdc: no yes no
1632 copies-sdc: no yes no
1633 revlog-v2: no yes no
1633 revlog-v2: no yes no
1634 plain-cl-delta: yes yes yes
1634 plain-cl-delta: yes yes yes
1635 compression: * (glob)
1635 compression: * (glob)
1636 compression-level: default default default
1636 compression-level: default default default
1637 $ hg debugupgraderepo --run --quiet
1637 $ hg debugupgraderepo --run --quiet
1638 upgrade will perform the following actions:
1638 upgrade will perform the following actions:
1639
1639
1640 requirements
1640 requirements
1641 preserved: * (glob)
1641 preserved: * (glob)
1642 removed: revlogv1
1642 removed: revlogv1
1643 added: exp-copies-sidedata-changeset, exp-revlogv2.2, exp-sidedata-flag
1643 added: exp-copies-sidedata-changeset, exp-revlogv2.2, exp-sidedata-flag
1644
1644
1645 processed revlogs:
1645 processed revlogs:
1646 - all-filelogs
1646 - all-filelogs
1647 - changelog
1647 - changelog
1648 - manifest
1648 - manifest
1649
1649
1650 #endif
1650 #endif
1651
1651
1652 #if upgraded-parallel
1652 #if upgraded-parallel
1653 $ cat >> $HGRCPATH << EOF
1653 $ cat >> $HGRCPATH << EOF
1654 > [format]
1654 > [format]
1655 > exp-use-side-data = yes
1655 > exp-use-side-data = yes
1656 > exp-use-copies-side-data-changeset = yes
1656 > exp-use-copies-side-data-changeset = yes
1657 > [experimental]
1657 > [experimental]
1658 > worker.repository-upgrade=yes
1658 > worker.repository-upgrade=yes
1659 > [worker]
1659 > [worker]
1660 > enabled=yes
1660 > enabled=yes
1661 > numcpus=8
1661 > numcpus=8
1662 > EOF
1662 > EOF
1663 $ hg debugformat -v
1663 $ hg debugformat -v
1664 format-variant repo config default
1664 format-variant repo config default
1665 fncache: yes yes yes
1665 fncache: yes yes yes
1666 dotencode: yes yes yes
1666 dotencode: yes yes yes
1667 generaldelta: yes yes yes
1667 generaldelta: yes yes yes
1668 share-safe: no no no
1668 share-safe: no no no
1669 sparserevlog: yes yes yes
1669 sparserevlog: yes yes yes
1670 persistent-nodemap: no no no
1670 persistent-nodemap: no no no
1671 copies-sdc: no yes no
1671 copies-sdc: no yes no
1672 revlog-v2: no yes no
1672 revlog-v2: no yes no
1673 plain-cl-delta: yes yes yes
1673 plain-cl-delta: yes yes yes
1674 compression: * (glob)
1674 compression: * (glob)
1675 compression-level: default default default
1675 compression-level: default default default
1676 $ hg debugupgraderepo --run --quiet
1676 $ hg debugupgraderepo --run --quiet
1677 upgrade will perform the following actions:
1677 upgrade will perform the following actions:
1678
1678
1679 requirements
1679 requirements
1680 preserved: * (glob)
1680 preserved: * (glob)
1681 removed: revlogv1
1681 removed: revlogv1
1682 added: exp-copies-sidedata-changeset, exp-revlogv2.2, exp-sidedata-flag
1682 added: exp-copies-sidedata-changeset, exp-revlogv2.2, exp-sidedata-flag
1683
1683
1684 processed revlogs:
1684 processed revlogs:
1685 - all-filelogs
1685 - all-filelogs
1686 - changelog
1686 - changelog
1687 - manifest
1687 - manifest
1688
1688
1689 #endif
1689 #endif
1690
1690
1691
1691
1692 #if no-compatibility no-filelog no-changeset
1692 #if no-compatibility no-filelog no-changeset
1693
1693
1694 $ hg debugchangedfiles --compute 0
1694 $ hg debugchangedfiles --compute 0
1695 added : a, ;
1695 added : a, ;
1696 added : b, ;
1696 added : b, ;
1697 added : h, ;
1697 added : h, ;
1698 added : p, ;
1698 added : p, ;
1699 added : q, ;
1699 added : q, ;
1700 added : r, ;
1700 added : r, ;
1701
1701
1702 $ for rev in `hg log --rev 'all()' -T '{rev}\n'`; do
1702 $ for rev in `hg log --rev 'all()' -T '{rev}\n'`; do
1703 > case_id=`hg log -r $rev -T '{word(0, desc, ":")}\n'`
1703 > case_id=`hg log -r $rev -T '{word(0, desc, ":")}\n'`
1704 > echo "##### revision \"$case_id\" #####"
1704 > echo "##### revision \"$case_id\" #####"
1705 > hg debugsidedata -c -v -- $rev
1705 > hg debugsidedata -c -v -- $rev
1706 > hg debugchangedfiles $rev
1706 > hg debugchangedfiles $rev
1707 > done
1707 > done
1708 ##### revision "i-0 initial commit" #####
1708 ##### revision "i-0 initial commit" #####
1709 1 sidedata entries
1709 1 sidedata entries
1710 entry-0014 size 64
1710 entry-0014 size 64
1711 '\x00\x00\x00\x06\x04\x00\x00\x00\x01\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00abhpqr'
1711 '\x00\x00\x00\x06\x04\x00\x00\x00\x01\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00abhpqr'
1712 added : a, ;
1712 added : a, ;
1713 added : b, ;
1713 added : b, ;
1714 added : h, ;
1714 added : h, ;
1715 added : p, ;
1715 added : p, ;
1716 added : q, ;
1716 added : q, ;
1717 added : r, ;
1717 added : r, ;
1718 ##### revision "i-1" #####
1718 ##### revision "i-1" #####
1719 1 sidedata entries
1719 1 sidedata entries
1720 entry-0014 size 44
1720 entry-0014 size 44
1721 '\x00\x00\x00\x04\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x02acps'
1721 '\x00\x00\x00\x04\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x02acps'
1722 removed : a, ;
1722 removed : a, ;
1723 added p1: c, a;
1723 added p1: c, a;
1724 removed : p, ;
1724 removed : p, ;
1725 added p1: s, p;
1725 added p1: s, p;
1726 ##### revision "i-2" #####
1726 ##### revision "i-2" #####
1727 1 sidedata entries
1727 1 sidedata entries
1728 entry-0014 size 44
1728 entry-0014 size 44
1729 '\x00\x00\x00\x04\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x02cdst'
1729 '\x00\x00\x00\x04\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x02cdst'
1730 removed : c, ;
1730 removed : c, ;
1731 added p1: d, c;
1731 added p1: d, c;
1732 removed : s, ;
1732 removed : s, ;
1733 added p1: t, s;
1733 added p1: t, s;
1734 ##### revision "a-1" #####
1734 ##### revision "a-1" #####
1735 1 sidedata entries
1735 1 sidedata entries
1736 entry-0014 size 24
1736 entry-0014 size 24
1737 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00de'
1737 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00de'
1738 removed : d, ;
1738 removed : d, ;
1739 added p1: e, d;
1739 added p1: e, d;
1740 ##### revision "a-2" #####
1740 ##### revision "a-2" #####
1741 1 sidedata entries
1741 1 sidedata entries
1742 entry-0014 size 24
1742 entry-0014 size 24
1743 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00ef'
1743 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00ef'
1744 removed : e, ;
1744 removed : e, ;
1745 added p1: f, e;
1745 added p1: f, e;
1746 ##### revision "b-1" #####
1746 ##### revision "b-1" #####
1747 1 sidedata entries
1747 1 sidedata entries
1748 entry-0014 size 14
1748 entry-0014 size 14
1749 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00b'
1749 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00b'
1750 touched : b, ;
1750 touched : b, ;
1751 ##### revision "c-1 delete d" #####
1751 ##### revision "c-1 delete d" #####
1752 1 sidedata entries
1752 1 sidedata entries
1753 entry-0014 size 14
1753 entry-0014 size 14
1754 '\x00\x00\x00\x01\x0c\x00\x00\x00\x01\x00\x00\x00\x00d'
1754 '\x00\x00\x00\x01\x0c\x00\x00\x00\x01\x00\x00\x00\x00d'
1755 removed : d, ;
1755 removed : d, ;
1756 ##### revision "d-1 delete d" #####
1756 ##### revision "d-1 delete d" #####
1757 1 sidedata entries
1757 1 sidedata entries
1758 entry-0014 size 14
1758 entry-0014 size 14
1759 '\x00\x00\x00\x01\x0c\x00\x00\x00\x01\x00\x00\x00\x00d'
1759 '\x00\x00\x00\x01\x0c\x00\x00\x00\x01\x00\x00\x00\x00d'
1760 removed : d, ;
1760 removed : d, ;
1761 ##### revision "d-2 re-add d" #####
1761 ##### revision "d-2 re-add d" #####
1762 1 sidedata entries
1762 1 sidedata entries
1763 entry-0014 size 14
1763 entry-0014 size 14
1764 '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00d'
1764 '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00d'
1765 added : d, ;
1765 added : d, ;
1766 ##### revision "e-1 b -move-> g" #####
1766 ##### revision "e-1 b -move-> g" #####
1767 1 sidedata entries
1767 1 sidedata entries
1768 entry-0014 size 24
1768 entry-0014 size 24
1769 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00bg'
1769 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00bg'
1770 removed : b, ;
1770 removed : b, ;
1771 added p1: g, b;
1771 added p1: g, b;
1772 ##### revision "e-2 g -move-> f" #####
1772 ##### revision "e-2 g -move-> f" #####
1773 1 sidedata entries
1773 1 sidedata entries
1774 entry-0014 size 24
1774 entry-0014 size 24
1775 '\x00\x00\x00\x02\x06\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00fg'
1775 '\x00\x00\x00\x02\x06\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00fg'
1776 added p1: f, g;
1776 added p1: f, g;
1777 removed : g, ;
1777 removed : g, ;
1778 ##### revision "p-1" #####
1778 ##### revision "p-1" #####
1779 1 sidedata entries
1779 1 sidedata entries
1780 entry-0014 size 24
1780 entry-0014 size 24
1781 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00tu'
1781 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00tu'
1782 removed : t, ;
1782 removed : t, ;
1783 added p1: u, t;
1783 added p1: u, t;
1784 ##### revision "p-2" #####
1784 ##### revision "p-2" #####
1785 1 sidedata entries
1785 1 sidedata entries
1786 entry-0014 size 24
1786 entry-0014 size 24
1787 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00uv'
1787 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00uv'
1788 removed : u, ;
1788 removed : u, ;
1789 added p1: v, u;
1789 added p1: v, u;
1790 ##### revision "q-1 r -move-> w" #####
1790 ##### revision "q-1 r -move-> w" #####
1791 1 sidedata entries
1791 1 sidedata entries
1792 entry-0014 size 24
1792 entry-0014 size 24
1793 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00rw'
1793 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00rw'
1794 removed : r, ;
1794 removed : r, ;
1795 added p1: w, r;
1795 added p1: w, r;
1796 ##### revision "q-2 w -move-> v" #####
1796 ##### revision "q-2 w -move-> v" #####
1797 1 sidedata entries
1797 1 sidedata entries
1798 entry-0014 size 24
1798 entry-0014 size 24
1799 '\x00\x00\x00\x02\x06\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00vw'
1799 '\x00\x00\x00\x02\x06\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00vw'
1800 added p1: v, w;
1800 added p1: v, w;
1801 removed : w, ;
1801 removed : w, ;
1802 ##### revision "mBAm-0 simple merge - A side" #####
1802 ##### revision "mBAm-0 simple merge - A side" #####
1803 1 sidedata entries
1803 1 sidedata entries
1804 entry-0014 size 4
1804 entry-0014 size 4
1805 '\x00\x00\x00\x00'
1805 '\x00\x00\x00\x00'
1806 ##### revision "mABm-0 simple merge - A side" #####
1806 ##### revision "mABm-0 simple merge - A side" #####
1807 1 sidedata entries
1807 1 sidedata entries
1808 entry-0014 size 4
1808 entry-0014 size 4
1809 '\x00\x00\x00\x00'
1809 '\x00\x00\x00\x00'
1810 ##### revision "mBCm-0 simple merge - C side" #####
1810 ##### revision "mBCm-0 simple merge - C side" #####
1811 1 sidedata entries
1811 1 sidedata entries
1812 entry-0014 size 4
1812 entry-0014 size 4
1813 '\x00\x00\x00\x00'
1813 '\x00\x00\x00\x00'
1814 ##### revision "mBCm-1 re-add d" #####
1814 ##### revision "mBCm-1 re-add d" #####
1815 1 sidedata entries
1815 1 sidedata entries
1816 entry-0014 size 14
1816 entry-0014 size 14
1817 '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00d'
1817 '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00d'
1818 added : d, ;
1818 added : d, ;
1819 ##### revision "mCBm-0 simple merge - C side" #####
1819 ##### revision "mCBm-0 simple merge - C side" #####
1820 1 sidedata entries
1820 1 sidedata entries
1821 entry-0014 size 4
1821 entry-0014 size 4
1822 '\x00\x00\x00\x00'
1822 '\x00\x00\x00\x00'
1823 ##### revision "mCBm-1 re-add d" #####
1823 ##### revision "mCBm-1 re-add d" #####
1824 1 sidedata entries
1824 1 sidedata entries
1825 entry-0014 size 14
1825 entry-0014 size 14
1826 '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00d'
1826 '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00d'
1827 added : d, ;
1827 added : d, ;
1828 ##### revision "mBDm-0 simple merge - B side" #####
1828 ##### revision "mBDm-0 simple merge - B side" #####
1829 1 sidedata entries
1829 1 sidedata entries
1830 entry-0014 size 4
1830 entry-0014 size 4
1831 '\x00\x00\x00\x00'
1831 '\x00\x00\x00\x00'
1832 ##### revision "mDBm-0 simple merge - B side" #####
1832 ##### revision "mDBm-0 simple merge - B side" #####
1833 1 sidedata entries
1833 1 sidedata entries
1834 entry-0014 size 4
1834 entry-0014 size 4
1835 '\x00\x00\x00\x00'
1835 '\x00\x00\x00\x00'
1836 ##### revision "mAEm-0 merge with copies info on both side - A side" #####
1836 ##### revision "mAEm-0 merge with copies info on both side - A side" #####
1837 1 sidedata entries
1837 1 sidedata entries
1838 entry-0014 size 14
1838 entry-0014 size 14
1839 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1839 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1840 merged : f, ;
1840 merged : f, ;
1841 ##### revision "mEAm-0 merge with copies info on both side - A side" #####
1841 ##### revision "mEAm-0 merge with copies info on both side - A side" #####
1842 1 sidedata entries
1842 1 sidedata entries
1843 entry-0014 size 14
1843 entry-0014 size 14
1844 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1844 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1845 merged : f, ;
1845 merged : f, ;
1846 ##### revision "mPQm-0 merge with copies info on both side - P side" #####
1846 ##### revision "mPQm-0 merge with copies info on both side - P side" #####
1847 1 sidedata entries
1847 1 sidedata entries
1848 entry-0014 size 14
1848 entry-0014 size 14
1849 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00v'
1849 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00v'
1850 merged : v, ;
1850 merged : v, ;
1851 ##### revision "mQPm-0 merge with copies info on both side - P side" #####
1851 ##### revision "mQPm-0 merge with copies info on both side - P side" #####
1852 1 sidedata entries
1852 1 sidedata entries
1853 entry-0014 size 14
1853 entry-0014 size 14
1854 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00v'
1854 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00v'
1855 merged : v, ;
1855 merged : v, ;
1856 ##### revision "f-1" #####
1856 ##### revision "f-1" #####
1857 1 sidedata entries
1857 1 sidedata entries
1858 entry-0014 size 24
1858 entry-0014 size 24
1859 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00hi'
1859 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00hi'
1860 removed : h, ;
1860 removed : h, ;
1861 added p1: i, h;
1861 added p1: i, h;
1862 ##### revision "f-2" #####
1862 ##### revision "f-2" #####
1863 1 sidedata entries
1863 1 sidedata entries
1864 entry-0014 size 24
1864 entry-0014 size 24
1865 '\x00\x00\x00\x02\x16\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00di'
1865 '\x00\x00\x00\x02\x16\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00di'
1866 touched p1: d, i;
1866 touched p1: d, i;
1867 removed : i, ;
1867 removed : i, ;
1868 ##### revision "mBFm-0 simple merge - B side" #####
1868 ##### revision "mBFm-0 simple merge - B side" #####
1869 1 sidedata entries
1869 1 sidedata entries
1870 entry-0014 size 4
1870 entry-0014 size 4
1871 '\x00\x00\x00\x00'
1871 '\x00\x00\x00\x00'
1872 ##### revision "mFBm-0 simple merge - B side" #####
1872 ##### revision "mFBm-0 simple merge - B side" #####
1873 1 sidedata entries
1873 1 sidedata entries
1874 entry-0014 size 4
1874 entry-0014 size 4
1875 '\x00\x00\x00\x00'
1875 '\x00\x00\x00\x00'
1876 ##### revision "r-1" #####
1876 ##### revision "r-1" #####
1877 1 sidedata entries
1877 1 sidedata entries
1878 entry-0014 size 24
1878 entry-0014 size 24
1879 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00rx'
1879 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00rx'
1880 removed : r, ;
1880 removed : r, ;
1881 added p1: x, r;
1881 added p1: x, r;
1882 ##### revision "r-2" #####
1882 ##### revision "r-2" #####
1883 1 sidedata entries
1883 1 sidedata entries
1884 entry-0014 size 24
1884 entry-0014 size 24
1885 '\x00\x00\x00\x02\x16\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00tx'
1885 '\x00\x00\x00\x02\x16\x00\x00\x00\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x02\x00\x00\x00\x00tx'
1886 touched p1: t, x;
1886 touched p1: t, x;
1887 removed : x, ;
1887 removed : x, ;
1888 ##### revision "mBRm-0 simple merge - B side" #####
1888 ##### revision "mBRm-0 simple merge - B side" #####
1889 1 sidedata entries
1889 1 sidedata entries
1890 entry-0014 size 4
1890 entry-0014 size 4
1891 '\x00\x00\x00\x00'
1891 '\x00\x00\x00\x00'
1892 ##### revision "mRBm-0 simple merge - B side" #####
1892 ##### revision "mRBm-0 simple merge - B side" #####
1893 1 sidedata entries
1893 1 sidedata entries
1894 entry-0014 size 4
1894 entry-0014 size 4
1895 '\x00\x00\x00\x00'
1895 '\x00\x00\x00\x00'
1896 ##### revision "g-1" #####
1896 ##### revision "g-1" #####
1897 1 sidedata entries
1897 1 sidedata entries
1898 entry-0014 size 14
1898 entry-0014 size 14
1899 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d'
1899 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d'
1900 touched : d, ;
1900 touched : d, ;
1901 ##### revision "mDGm-0 actual content merge, copies on one side - D side" #####
1901 ##### revision "mDGm-0 actual content merge, copies on one side - D side" #####
1902 1 sidedata entries
1902 1 sidedata entries
1903 entry-0014 size 14
1903 entry-0014 size 14
1904 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1904 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1905 merged : d, ;
1905 merged : d, ;
1906 ##### revision "mGDm-0 actual content merge, copies on one side - D side" #####
1906 ##### revision "mGDm-0 actual content merge, copies on one side - D side" #####
1907 1 sidedata entries
1907 1 sidedata entries
1908 entry-0014 size 14
1908 entry-0014 size 14
1909 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1909 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1910 merged : d, ;
1910 merged : d, ;
1911 ##### revision "mFGm-0 merge - G side" #####
1911 ##### revision "mFGm-0 merge - G side" #####
1912 1 sidedata entries
1912 1 sidedata entries
1913 entry-0014 size 14
1913 entry-0014 size 14
1914 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1914 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1915 merged : d, ;
1915 merged : d, ;
1916 ##### revision "mGFm-0 merge - G side" #####
1916 ##### revision "mGFm-0 merge - G side" #####
1917 1 sidedata entries
1917 1 sidedata entries
1918 entry-0014 size 14
1918 entry-0014 size 14
1919 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1919 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d'
1920 merged : d, ;
1920 merged : d, ;
1921 ##### revision "mCGm-0 merge updated/deleted - revive the file (updated content) - one way" #####
1921 ##### revision "mCGm-0 merge updated/deleted - revive the file (updated content) - one way" #####
1922 1 sidedata entries
1922 1 sidedata entries
1923 entry-0014 size 14
1923 entry-0014 size 14
1924 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1924 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1925 salvaged : d, ;
1925 salvaged : d, ;
1926 ##### revision "mGCm-0 merge updated/deleted - revive the file (updated content) - the other way" #####
1926 ##### revision "mGCm-0 merge updated/deleted - revive the file (updated content) - the other way" #####
1927 1 sidedata entries
1927 1 sidedata entries
1928 entry-0014 size 14
1928 entry-0014 size 14
1929 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1929 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1930 salvaged : d, ;
1930 salvaged : d, ;
1931 ##### revision "mCB-revert-m-0 merge explicitely revive deleted file - B side" #####
1931 ##### revision "mCB-revert-m-0 merge explicitely revive deleted file - B side" #####
1932 1 sidedata entries
1932 1 sidedata entries
1933 entry-0014 size 14
1933 entry-0014 size 14
1934 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1934 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1935 salvaged : d, ;
1935 salvaged : d, ;
1936 ##### revision "mBC-revert-m-0 merge explicitely revive deleted file - B side" #####
1936 ##### revision "mBC-revert-m-0 merge explicitely revive deleted file - B side" #####
1937 1 sidedata entries
1937 1 sidedata entries
1938 entry-0014 size 14
1938 entry-0014 size 14
1939 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1939 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1940 salvaged : d, ;
1940 salvaged : d, ;
1941 ##### revision "h-1" #####
1941 ##### revision "h-1" #####
1942 1 sidedata entries
1942 1 sidedata entries
1943 entry-0014 size 24
1943 entry-0014 size 24
1944 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00bd'
1944 '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00bd'
1945 removed : b, ;
1945 removed : b, ;
1946 added p1: d, b;
1946 added p1: d, b;
1947 ##### revision "mCH-delete-before-conflict-m-0 simple merge - C side" #####
1947 ##### revision "mCH-delete-before-conflict-m-0 simple merge - C side" #####
1948 1 sidedata entries
1948 1 sidedata entries
1949 entry-0014 size 4
1949 entry-0014 size 4
1950 '\x00\x00\x00\x00'
1950 '\x00\x00\x00\x00'
1951 ##### revision "mHC-delete-before-conflict-m-0 simple merge - C side" #####
1951 ##### revision "mHC-delete-before-conflict-m-0 simple merge - C side" #####
1952 1 sidedata entries
1952 1 sidedata entries
1953 entry-0014 size 4
1953 entry-0014 size 4
1954 '\x00\x00\x00\x00'
1954 '\x00\x00\x00\x00'
1955 ##### revision "mAE-change-m-0 merge with file update and copies info on both side - A side" #####
1955 ##### revision "mAE-change-m-0 merge with file update and copies info on both side - A side" #####
1956 1 sidedata entries
1956 1 sidedata entries
1957 entry-0014 size 14
1957 entry-0014 size 14
1958 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1958 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1959 merged : f, ;
1959 merged : f, ;
1960 ##### revision "mEA-change-m-0 merge with file update and copies info on both side - A side" #####
1960 ##### revision "mEA-change-m-0 merge with file update and copies info on both side - A side" #####
1961 1 sidedata entries
1961 1 sidedata entries
1962 entry-0014 size 14
1962 entry-0014 size 14
1963 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1963 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f'
1964 merged : f, ;
1964 merged : f, ;
1965 ##### revision "mBF-change-m-0 merge with extra change - B side" #####
1965 ##### revision "mBF-change-m-0 merge with extra change - B side" #####
1966 1 sidedata entries
1966 1 sidedata entries
1967 entry-0014 size 14
1967 entry-0014 size 14
1968 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (no-upgraded no-upgraded-parallel !)
1968 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d'
1969 touched : d, ; (no-upgraded no-upgraded-parallel !)
1969 touched : d, ;
1970 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded missing-correct-output !)
1971 touched : d, ; (upgraded missing-correct-output !)
1972 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded known-bad-output !)
1973 merged : d, ; (upgraded known-bad-output !)
1974 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded-parallel missing-correct-output !)
1975 touched : d, ; (upgraded-parallel missing-correct-output !)
1976 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded-parallel known-bad-output !)
1977 merged : d, ; (upgraded-parallel known-bad-output !)
1978 ##### revision "mFB-change-m-0 merge with extra change - B side" #####
1970 ##### revision "mFB-change-m-0 merge with extra change - B side" #####
1979 1 sidedata entries
1971 1 sidedata entries
1980 entry-0014 size 14
1972 entry-0014 size 14
1981 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (no-upgraded no-upgraded-parallel !)
1973 '\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d'
1982 touched : d, ; (no-upgraded no-upgraded-parallel !)
1974 touched : d, ;
1983 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded-parallel known-bad-output !)
1984 merged : d, ; (upgraded-parallel known-bad-output !)
1985 '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded known-bad-output !)
1986 merged : d, ; (upgraded known-bad-output !)
1987 ##### revision "mCB-change-m-0 merge explicitely revive deleted file - B side" #####
1975 ##### revision "mCB-change-m-0 merge explicitely revive deleted file - B side" #####
1988 1 sidedata entries
1976 1 sidedata entries
1989 entry-0014 size 14
1977 entry-0014 size 14
1990 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1978 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1991 salvaged : d, ;
1979 salvaged : d, ;
1992 ##### revision "mBC-change-m-0 merge explicitely revive deleted file - B side" #####
1980 ##### revision "mBC-change-m-0 merge explicitely revive deleted file - B side" #####
1993 1 sidedata entries
1981 1 sidedata entries
1994 entry-0014 size 14
1982 entry-0014 size 14
1995 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1983 '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
1996 salvaged : d, ;
1984 salvaged : d, ;
1997 ##### revision "j-1" #####
1985 ##### revision "j-1" #####
1998 1 sidedata entries
1986 1 sidedata entries
1999 entry-0014 size 24
1987 entry-0014 size 24
2000 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j'
1988 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j'
2001 added : unrelated-j, ;
1989 added : unrelated-j, ;
2002 ##### revision "k-1" #####
1990 ##### revision "k-1" #####
2003 1 sidedata entries
1991 1 sidedata entries
2004 entry-0014 size 24
1992 entry-0014 size 24
2005 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-k'
1993 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-k'
2006 added : unrelated-k, ;
1994 added : unrelated-k, ;
2007 ##### revision "mAE,Km" #####
1995 ##### revision "mAE,Km" #####
2008 1 sidedata entries
1996 1 sidedata entries
2009 entry-0014 size 4
1997 entry-0014 size 4
2010 '\x00\x00\x00\x00'
1998 '\x00\x00\x00\x00'
2011 ##### revision "mK,AEm" #####
1999 ##### revision "mK,AEm" #####
2012 1 sidedata entries
2000 1 sidedata entries
2013 entry-0014 size 4
2001 entry-0014 size 4
2014 '\x00\x00\x00\x00'
2002 '\x00\x00\x00\x00'
2015 ##### revision "mEA,Jm" #####
2003 ##### revision "mEA,Jm" #####
2016 1 sidedata entries
2004 1 sidedata entries
2017 entry-0014 size 24
2005 entry-0014 size 24
2018 '\x00\x00\x00\x01\x14\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j'
2006 '\x00\x00\x00\x01\x14\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j'
2019 touched : unrelated-j, ;
2007 touched : unrelated-j, ;
2020 ##### revision "mJ,EAm" #####
2008 ##### revision "mJ,EAm" #####
2021 1 sidedata entries
2009 1 sidedata entries
2022 entry-0014 size 24
2010 entry-0014 size 24
2023 '\x00\x00\x00\x01\x14\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j'
2011 '\x00\x00\x00\x01\x14\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j'
2024 touched : unrelated-j, ;
2012 touched : unrelated-j, ;
2025 ##### revision "s-1" #####
2013 ##### revision "s-1" #####
2026 1 sidedata entries
2014 1 sidedata entries
2027 entry-0014 size 24
2015 entry-0014 size 24
2028 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-s'
2016 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-s'
2029 added : unrelated-s, ;
2017 added : unrelated-s, ;
2030 ##### revision "t-1" #####
2018 ##### revision "t-1" #####
2031 1 sidedata entries
2019 1 sidedata entries
2032 entry-0014 size 24
2020 entry-0014 size 24
2033 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-t'
2021 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-t'
2034 added : unrelated-t, ;
2022 added : unrelated-t, ;
2035 ##### revision "mPQ,Tm" #####
2023 ##### revision "mPQ,Tm" #####
2036 1 sidedata entries
2024 1 sidedata entries
2037 entry-0014 size 4
2025 entry-0014 size 4
2038 '\x00\x00\x00\x00'
2026 '\x00\x00\x00\x00'
2039 ##### revision "mT,PQm" #####
2027 ##### revision "mT,PQm" #####
2040 1 sidedata entries
2028 1 sidedata entries
2041 entry-0014 size 4
2029 entry-0014 size 4
2042 '\x00\x00\x00\x00'
2030 '\x00\x00\x00\x00'
2043 ##### revision "mQP,Sm" #####
2031 ##### revision "mQP,Sm" #####
2044 1 sidedata entries
2032 1 sidedata entries
2045 entry-0014 size 4
2033 entry-0014 size 4
2046 '\x00\x00\x00\x00'
2034 '\x00\x00\x00\x00'
2047 ##### revision "mS,QPm" #####
2035 ##### revision "mS,QPm" #####
2048 1 sidedata entries
2036 1 sidedata entries
2049 entry-0014 size 4
2037 entry-0014 size 4
2050 '\x00\x00\x00\x00'
2038 '\x00\x00\x00\x00'
2051 ##### revision "l-1" #####
2039 ##### revision "l-1" #####
2052 1 sidedata entries
2040 1 sidedata entries
2053 entry-0014 size 24
2041 entry-0014 size 24
2054 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-l'
2042 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-l'
2055 added : unrelated-l, ;
2043 added : unrelated-l, ;
2056 ##### revision "mBC+revert,Lm" #####
2044 ##### revision "mBC+revert,Lm" #####
2057 1 sidedata entries
2045 1 sidedata entries
2058 entry-0014 size 4
2046 entry-0014 size 4
2059 '\x00\x00\x00\x00'
2047 '\x00\x00\x00\x00'
2060 ##### revision "mCB+revert,Lm" #####
2048 ##### revision "mCB+revert,Lm" #####
2061 1 sidedata entries
2049 1 sidedata entries
2062 entry-0014 size 4
2050 entry-0014 size 4
2063 '\x00\x00\x00\x00'
2051 '\x00\x00\x00\x00'
2064 ##### revision "mL,BC+revertm" #####
2052 ##### revision "mL,BC+revertm" #####
2065 1 sidedata entries
2053 1 sidedata entries
2066 entry-0014 size 4
2054 entry-0014 size 4
2067 '\x00\x00\x00\x00'
2055 '\x00\x00\x00\x00'
2068 ##### revision "mL,CB+revertm" #####
2056 ##### revision "mL,CB+revertm" #####
2069 1 sidedata entries
2057 1 sidedata entries
2070 entry-0014 size 4
2058 entry-0014 size 4
2071 '\x00\x00\x00\x00'
2059 '\x00\x00\x00\x00'
2072 ##### revision "n-1" #####
2060 ##### revision "n-1" #####
2073 1 sidedata entries
2061 1 sidedata entries
2074 entry-0014 size 24
2062 entry-0014 size 24
2075 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-n'
2063 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-n'
2076 added : unrelated-n, ;
2064 added : unrelated-n, ;
2077 ##### revision "o-1" #####
2065 ##### revision "o-1" #####
2078 1 sidedata entries
2066 1 sidedata entries
2079 entry-0014 size 24
2067 entry-0014 size 24
2080 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-o'
2068 '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-o'
2081 added : unrelated-o, ;
2069 added : unrelated-o, ;
2082 ##### revision "mFG,Om" #####
2070 ##### revision "mFG,Om" #####
2083 1 sidedata entries
2071 1 sidedata entries
2084 entry-0014 size 4
2072 entry-0014 size 4
2085 '\x00\x00\x00\x00'
2073 '\x00\x00\x00\x00'
2086 ##### revision "mO,FGm" #####
2074 ##### revision "mO,FGm" #####
2087 1 sidedata entries
2075 1 sidedata entries
2088 entry-0014 size 4
2076 entry-0014 size 4
2089 '\x00\x00\x00\x00'
2077 '\x00\x00\x00\x00'
2090 ##### revision "mGF,Nm" #####
2078 ##### revision "mGF,Nm" #####
2091 1 sidedata entries
2079 1 sidedata entries
2092 entry-0014 size 4
2080 entry-0014 size 4
2093 '\x00\x00\x00\x00'
2081 '\x00\x00\x00\x00'
2094 ##### revision "mN,GFm" #####
2082 ##### revision "mN,GFm" #####
2095 1 sidedata entries
2083 1 sidedata entries
2096 entry-0014 size 4
2084 entry-0014 size 4
2097 '\x00\x00\x00\x00'
2085 '\x00\x00\x00\x00'
2098 ##### revision "mAE-change,Km" #####
2086 ##### revision "mAE-change,Km" #####
2099 1 sidedata entries
2087 1 sidedata entries
2100 entry-0014 size 4
2088 entry-0014 size 4
2101 '\x00\x00\x00\x00'
2089 '\x00\x00\x00\x00'
2102 ##### revision "mK,AE-change-m" #####
2090 ##### revision "mK,AE-change-m" #####
2103 1 sidedata entries
2091 1 sidedata entries
2104 entry-0014 size 4
2092 entry-0014 size 4
2105 '\x00\x00\x00\x00'
2093 '\x00\x00\x00\x00'
2106 ##### revision "mEA-change,Jm" #####
2094 ##### revision "mEA-change,Jm" #####
2107 1 sidedata entries
2095 1 sidedata entries
2108 entry-0014 size 4
2096 entry-0014 size 4
2109 '\x00\x00\x00\x00'
2097 '\x00\x00\x00\x00'
2110 ##### revision "mJ,EA-change-m" #####
2098 ##### revision "mJ,EA-change-m" #####
2111 1 sidedata entries
2099 1 sidedata entries
2112 entry-0014 size 4
2100 entry-0014 size 4
2113 '\x00\x00\x00\x00'
2101 '\x00\x00\x00\x00'
2114
2102
2115 #endif
2103 #endif
2116
2104
2117
2105
2118 Test copy information chaining
2106 Test copy information chaining
2119 ==============================
2107 ==============================
2120
2108
2121 Check that matching only affect the destination and not intermediate path
2109 Check that matching only affect the destination and not intermediate path
2122 -------------------------------------------------------------------------
2110 -------------------------------------------------------------------------
2123
2111
2124 The two status call should give the same value for f
2112 The two status call should give the same value for f
2125
2113
2126 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("a-2")'
2114 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("a-2")'
2127 A f
2115 A f
2128 a
2116 a
2129 A t
2117 A t
2130 p
2118 p
2131 R a
2119 R a
2132 R p
2120 R p
2133 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("a-2")' f
2121 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("a-2")' f
2134 A f
2122 A f
2135 a (no-changeset no-compatibility !)
2123 a (no-changeset no-compatibility !)
2136
2124
2137 merging with unrelated change does not interfere with the renames
2125 merging with unrelated change does not interfere with the renames
2138 ---------------------------------------------------------------
2126 ---------------------------------------------------------------
2139
2127
2140 - rename on one side
2128 - rename on one side
2141 - unrelated change on the other side
2129 - unrelated change on the other side
2142
2130
2143 $ hg log -G --rev '::(desc("mABm")+desc("mBAm"))'
2131 $ hg log -G --rev '::(desc("mABm")+desc("mBAm"))'
2144 o mABm-0 simple merge - A side: multiple renames, B side: unrelated update - the other way
2132 o mABm-0 simple merge - A side: multiple renames, B side: unrelated update - the other way
2145 |\
2133 |\
2146 +---o mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way
2134 +---o mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way
2147 | |/
2135 | |/
2148 | o b-1: b update
2136 | o b-1: b update
2149 | |
2137 | |
2150 o | a-2: e -move-> f
2138 o | a-2: e -move-> f
2151 | |
2139 | |
2152 o | a-1: d -move-> e
2140 o | a-1: d -move-> e
2153 |/
2141 |/
2154 o i-2: c -move-> d, s -move-> t
2142 o i-2: c -move-> d, s -move-> t
2155 |
2143 |
2156 o i-1: a -move-> c, p -move-> s
2144 o i-1: a -move-> c, p -move-> s
2157 |
2145 |
2158 o i-0 initial commit: a b h p q r
2146 o i-0 initial commit: a b h p q r
2159
2147
2160
2148
2161 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mABm")'
2149 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mABm")'
2162 A f
2150 A f
2163 d
2151 d
2164 R d
2152 R d
2165 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBAm")'
2153 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBAm")'
2166 A f
2154 A f
2167 d
2155 d
2168 R d
2156 R d
2169 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mABm")'
2157 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mABm")'
2170 M b
2158 M b
2171 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mBAm")'
2159 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mBAm")'
2172 M b
2160 M b
2173 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mABm")'
2161 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mABm")'
2174 M b
2162 M b
2175 A f
2163 A f
2176 d
2164 d
2177 R d
2165 R d
2178 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBAm")'
2166 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBAm")'
2179 M b
2167 M b
2180 A f
2168 A f
2181 d
2169 d
2182 R d
2170 R d
2183 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mABm")'
2171 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mABm")'
2184 M b
2172 M b
2185 A f
2173 A f
2186 a
2174 a
2187 A t
2175 A t
2188 p
2176 p
2189 R a
2177 R a
2190 R p
2178 R p
2191 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBAm")'
2179 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBAm")'
2192 M b
2180 M b
2193 A f
2181 A f
2194 a
2182 a
2195 A t
2183 A t
2196 p
2184 p
2197 R a
2185 R a
2198 R p
2186 R p
2199
2187
2200 merging with the side having a delete
2188 merging with the side having a delete
2201 -------------------------------------
2189 -------------------------------------
2202
2190
2203 case summary:
2191 case summary:
2204 - one with change to an unrelated file
2192 - one with change to an unrelated file
2205 - one deleting the change
2193 - one deleting the change
2206 and recreate an unrelated file after the merge
2194 and recreate an unrelated file after the merge
2207
2195
2208 $ hg log -G --rev '::(desc("mCBm")+desc("mBCm"))'
2196 $ hg log -G --rev '::(desc("mCBm")+desc("mBCm"))'
2209 o mCBm-1 re-add d
2197 o mCBm-1 re-add d
2210 |
2198 |
2211 o mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way
2199 o mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way
2212 |\
2200 |\
2213 | | o mBCm-1 re-add d
2201 | | o mBCm-1 re-add d
2214 | | |
2202 | | |
2215 +---o mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way
2203 +---o mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way
2216 | |/
2204 | |/
2217 | o c-1 delete d
2205 | o c-1 delete d
2218 | |
2206 | |
2219 o | b-1: b update
2207 o | b-1: b update
2220 |/
2208 |/
2221 o i-2: c -move-> d, s -move-> t
2209 o i-2: c -move-> d, s -move-> t
2222 |
2210 |
2223 o i-1: a -move-> c, p -move-> s
2211 o i-1: a -move-> c, p -move-> s
2224 |
2212 |
2225 o i-0 initial commit: a b h p q r
2213 o i-0 initial commit: a b h p q r
2226
2214
2227 - comparing from the merge
2215 - comparing from the merge
2228
2216
2229 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBCm-0")'
2217 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBCm-0")'
2230 R d
2218 R d
2231 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCBm-0")'
2219 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCBm-0")'
2232 R d
2220 R d
2233 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBCm-0")'
2221 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBCm-0")'
2234 M b
2222 M b
2235 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCBm-0")'
2223 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCBm-0")'
2236 M b
2224 M b
2237 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBCm-0")'
2225 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBCm-0")'
2238 M b
2226 M b
2239 R d
2227 R d
2240 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mCBm-0")'
2228 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mCBm-0")'
2241 M b
2229 M b
2242 R d
2230 R d
2243 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBCm-0")'
2231 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBCm-0")'
2244 M b
2232 M b
2245 A t
2233 A t
2246 p
2234 p
2247 R a
2235 R a
2248 R p
2236 R p
2249 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCBm-0")'
2237 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCBm-0")'
2250 M b
2238 M b
2251 A t
2239 A t
2252 p
2240 p
2253 R a
2241 R a
2254 R p
2242 R p
2255
2243
2256 - comparing with the merge children re-adding the file
2244 - comparing with the merge children re-adding the file
2257
2245
2258 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBCm-1")'
2246 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBCm-1")'
2259 M d
2247 M d
2260 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCBm-1")'
2248 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCBm-1")'
2261 M d
2249 M d
2262 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBCm-1")'
2250 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBCm-1")'
2263 M b
2251 M b
2264 A d
2252 A d
2265 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCBm-1")'
2253 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCBm-1")'
2266 M b
2254 M b
2267 A d
2255 A d
2268 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBCm-1")'
2256 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBCm-1")'
2269 M b
2257 M b
2270 M d
2258 M d
2271 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mCBm-1")'
2259 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mCBm-1")'
2272 M b
2260 M b
2273 M d
2261 M d
2274 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBCm-1")'
2262 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBCm-1")'
2275 M b
2263 M b
2276 A d
2264 A d
2277 A t
2265 A t
2278 p
2266 p
2279 R a
2267 R a
2280 R p
2268 R p
2281 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCBm-1")'
2269 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCBm-1")'
2282 M b
2270 M b
2283 A d
2271 A d
2284 A t
2272 A t
2285 p
2273 p
2286 R a
2274 R a
2287 R p
2275 R p
2288
2276
2289 Comparing with a merge re-adding the file afterward
2277 Comparing with a merge re-adding the file afterward
2290 ---------------------------------------------------
2278 ---------------------------------------------------
2291
2279
2292 Merge:
2280 Merge:
2293 - one with change to an unrelated file
2281 - one with change to an unrelated file
2294 - one deleting and recreating the change
2282 - one deleting and recreating the change
2295
2283
2296 $ hg log -G --rev '::(desc("mDBm")+desc("mBDm"))'
2284 $ hg log -G --rev '::(desc("mDBm")+desc("mBDm"))'
2297 o mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way
2285 o mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way
2298 |\
2286 |\
2299 +---o mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way
2287 +---o mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way
2300 | |/
2288 | |/
2301 | o d-2 re-add d
2289 | o d-2 re-add d
2302 | |
2290 | |
2303 | o d-1 delete d
2291 | o d-1 delete d
2304 | |
2292 | |
2305 o | b-1: b update
2293 o | b-1: b update
2306 |/
2294 |/
2307 o i-2: c -move-> d, s -move-> t
2295 o i-2: c -move-> d, s -move-> t
2308 |
2296 |
2309 o i-1: a -move-> c, p -move-> s
2297 o i-1: a -move-> c, p -move-> s
2310 |
2298 |
2311 o i-0 initial commit: a b h p q r
2299 o i-0 initial commit: a b h p q r
2312
2300
2313 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBDm-0")'
2301 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBDm-0")'
2314 M d
2302 M d
2315 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mDBm-0")'
2303 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mDBm-0")'
2316 M d
2304 M d
2317 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mBDm-0")'
2305 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mBDm-0")'
2318 M b
2306 M b
2319 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDBm-0")'
2307 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDBm-0")'
2320 M b
2308 M b
2321 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBDm-0")'
2309 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBDm-0")'
2322 M b
2310 M b
2323 M d
2311 M d
2324 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mDBm-0")'
2312 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mDBm-0")'
2325 M b
2313 M b
2326 M d
2314 M d
2327
2315
2328 The bugs makes recorded copy is different depending of where we started the merge from since
2316 The bugs makes recorded copy is different depending of where we started the merge from since
2329
2317
2330 $ hg manifest --debug --rev 'desc("mBDm-0")' | grep '644 d'
2318 $ hg manifest --debug --rev 'desc("mBDm-0")' | grep '644 d'
2331 b004912a8510032a0350a74daa2803dadfb00e12 644 d
2319 b004912a8510032a0350a74daa2803dadfb00e12 644 d
2332 $ hg manifest --debug --rev 'desc("mDBm-0")' | grep '644 d'
2320 $ hg manifest --debug --rev 'desc("mDBm-0")' | grep '644 d'
2333 b004912a8510032a0350a74daa2803dadfb00e12 644 d
2321 b004912a8510032a0350a74daa2803dadfb00e12 644 d
2334
2322
2335 $ hg manifest --debug --rev 'desc("d-2")' | grep '644 d'
2323 $ hg manifest --debug --rev 'desc("d-2")' | grep '644 d'
2336 b004912a8510032a0350a74daa2803dadfb00e12 644 d
2324 b004912a8510032a0350a74daa2803dadfb00e12 644 d
2337 $ hg manifest --debug --rev 'desc("b-1")' | grep '644 d'
2325 $ hg manifest --debug --rev 'desc("b-1")' | grep '644 d'
2338 d8252ab2e760b0d4e5288fd44cbd15a0fa567e16 644 d (no-changeset !)
2326 d8252ab2e760b0d4e5288fd44cbd15a0fa567e16 644 d (no-changeset !)
2339 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 d (changeset !)
2327 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 d (changeset !)
2340 $ hg debugindex d | head -n 4 | ../no-linkrev
2328 $ hg debugindex d | head -n 4 | ../no-linkrev
2341 rev linkrev nodeid p1 p2
2329 rev linkrev nodeid p1 p2
2342 0 * d8252ab2e760 000000000000 000000000000 (no-changeset !)
2330 0 * d8252ab2e760 000000000000 000000000000 (no-changeset !)
2343 0 * ae258f702dfe 000000000000 000000000000 (changeset !)
2331 0 * ae258f702dfe 000000000000 000000000000 (changeset !)
2344 1 * b004912a8510 000000000000 000000000000
2332 1 * b004912a8510 000000000000 000000000000
2345 2 * 7b79e2fe0c89 000000000000 000000000000 (no-changeset !)
2333 2 * 7b79e2fe0c89 000000000000 000000000000 (no-changeset !)
2346 2 * 5cce88bf349f ae258f702dfe 000000000000 (changeset !)
2334 2 * 5cce88bf349f ae258f702dfe 000000000000 (changeset !)
2347
2335
2348 Log output should not include a merge commit as it did not happen
2336 Log output should not include a merge commit as it did not happen
2349
2337
2350 $ hg log -Gfr 'desc("mBDm-0")' d
2338 $ hg log -Gfr 'desc("mBDm-0")' d
2351 o d-2 re-add d
2339 o d-2 re-add d
2352 |
2340 |
2353 ~
2341 ~
2354
2342
2355 $ hg log -Gfr 'desc("mDBm-0")' d
2343 $ hg log -Gfr 'desc("mDBm-0")' d
2356 o d-2 re-add d
2344 o d-2 re-add d
2357 |
2345 |
2358 ~
2346 ~
2359
2347
2360 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")'
2348 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")'
2361 M b
2349 M b
2362 A d
2350 A d
2363 A t
2351 A t
2364 p
2352 p
2365 R a
2353 R a
2366 R p
2354 R p
2367 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDBm-0")'
2355 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDBm-0")'
2368 M b
2356 M b
2369 A d
2357 A d
2370 A t
2358 A t
2371 p
2359 p
2372 R a
2360 R a
2373 R p
2361 R p
2374
2362
2375
2363
2376 Comparing with a merge with colliding rename
2364 Comparing with a merge with colliding rename
2377 --------------------------------------------
2365 --------------------------------------------
2378
2366
2379 Subcase: new copy information on both side
2367 Subcase: new copy information on both side
2380 ``````````````````````````````````````````
2368 ``````````````````````````````````````````
2381
2369
2382 - the "e-" branch renaming b to f (through 'g')
2370 - the "e-" branch renaming b to f (through 'g')
2383 - the "a-" branch renaming d to f (through e)
2371 - the "a-" branch renaming d to f (through e)
2384
2372
2385 $ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
2373 $ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
2386 o mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
2374 o mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way
2387 |\
2375 |\
2388 +---o mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
2376 +---o mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way
2389 | |/
2377 | |/
2390 | o e-2 g -move-> f
2378 | o e-2 g -move-> f
2391 | |
2379 | |
2392 | o e-1 b -move-> g
2380 | o e-1 b -move-> g
2393 | |
2381 | |
2394 o | a-2: e -move-> f
2382 o | a-2: e -move-> f
2395 | |
2383 | |
2396 o | a-1: d -move-> e
2384 o | a-1: d -move-> e
2397 |/
2385 |/
2398 o i-2: c -move-> d, s -move-> t
2386 o i-2: c -move-> d, s -move-> t
2399 |
2387 |
2400 o i-1: a -move-> c, p -move-> s
2388 o i-1: a -move-> c, p -move-> s
2401 |
2389 |
2402 o i-0 initial commit: a b h p q r
2390 o i-0 initial commit: a b h p q r
2403
2391
2404 #if no-changeset
2392 #if no-changeset
2405 $ hg manifest --debug --rev 'desc("mAEm-0")' | grep '644 f'
2393 $ hg manifest --debug --rev 'desc("mAEm-0")' | grep '644 f'
2406 2ff93c643948464ee1f871867910ae43a45b0bea 644 f
2394 2ff93c643948464ee1f871867910ae43a45b0bea 644 f
2407 $ hg manifest --debug --rev 'desc("mEAm-0")' | grep '644 f'
2395 $ hg manifest --debug --rev 'desc("mEAm-0")' | grep '644 f'
2408 2ff93c643948464ee1f871867910ae43a45b0bea 644 f
2396 2ff93c643948464ee1f871867910ae43a45b0bea 644 f
2409 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
2397 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
2410 b76eb76580df486c3d51d63c5c210d4dd43a8ac7 644 f
2398 b76eb76580df486c3d51d63c5c210d4dd43a8ac7 644 f
2411 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
2399 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
2412 e8825b386367b29fec957283a80bb47b47483fe1 644 f
2400 e8825b386367b29fec957283a80bb47b47483fe1 644 f
2413 $ hg debugindex f | ../no-linkrev
2401 $ hg debugindex f | ../no-linkrev
2414 rev linkrev nodeid p1 p2
2402 rev linkrev nodeid p1 p2
2415 0 * b76eb76580df 000000000000 000000000000
2403 0 * b76eb76580df 000000000000 000000000000
2416 1 * e8825b386367 000000000000 000000000000
2404 1 * e8825b386367 000000000000 000000000000
2417 2 * 2ff93c643948 b76eb76580df e8825b386367
2405 2 * 2ff93c643948 b76eb76580df e8825b386367
2418 3 * 2f649fba7eb2 b76eb76580df e8825b386367
2406 3 * 2f649fba7eb2 b76eb76580df e8825b386367
2419 4 * 774e7c1637d5 e8825b386367 b76eb76580df
2407 4 * 774e7c1637d5 e8825b386367 b76eb76580df
2420 #else
2408 #else
2421 $ hg manifest --debug --rev 'desc("mAEm-0")' | grep '644 f'
2409 $ hg manifest --debug --rev 'desc("mAEm-0")' | grep '644 f'
2422 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2410 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2423 $ hg manifest --debug --rev 'desc("mEAm-0")' | grep '644 f'
2411 $ hg manifest --debug --rev 'desc("mEAm-0")' | grep '644 f'
2424 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2412 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2425 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
2413 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
2426 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2414 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2427 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
2415 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
2428 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2416 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
2429 $ hg debugindex f | ../no-linkrev
2417 $ hg debugindex f | ../no-linkrev
2430 rev linkrev nodeid p1 p2
2418 rev linkrev nodeid p1 p2
2431 0 * ae258f702dfe 000000000000 000000000000
2419 0 * ae258f702dfe 000000000000 000000000000
2432 1 * d3613c1ec831 ae258f702dfe 000000000000
2420 1 * d3613c1ec831 ae258f702dfe 000000000000
2433 2 * 05e03c868bbc ae258f702dfe 000000000000
2421 2 * 05e03c868bbc ae258f702dfe 000000000000
2434 #endif
2422 #endif
2435
2423
2436 # Here the filelog based implementation is not looking at the rename
2424 # Here the filelog based implementation is not looking at the rename
2437 # information (because the file exist on both side). However the changelog
2425 # information (because the file exist on both side). However the changelog
2438 # based on works fine. We have different output.
2426 # based on works fine. We have different output.
2439
2427
2440 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mAEm-0")'
2428 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mAEm-0")'
2441 M f (no-changeset !)
2429 M f (no-changeset !)
2442 b (no-filelog no-changeset !)
2430 b (no-filelog no-changeset !)
2443 R b
2431 R b
2444 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mEAm-0")'
2432 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mEAm-0")'
2445 M f (no-changeset !)
2433 M f (no-changeset !)
2446 b (no-filelog no-changeset !)
2434 b (no-filelog no-changeset !)
2447 R b
2435 R b
2448 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mAEm-0")'
2436 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mAEm-0")'
2449 M f (no-changeset !)
2437 M f (no-changeset !)
2450 d (no-filelog no-changeset !)
2438 d (no-filelog no-changeset !)
2451 R d
2439 R d
2452 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mEAm-0")'
2440 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mEAm-0")'
2453 M f (no-changeset !)
2441 M f (no-changeset !)
2454 d (no-filelog no-changeset !)
2442 d (no-filelog no-changeset !)
2455 R d
2443 R d
2456 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("a-2")'
2444 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("a-2")'
2457 A f
2445 A f
2458 d
2446 d
2459 R d
2447 R d
2460 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("e-2")'
2448 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("e-2")'
2461 A f
2449 A f
2462 b
2450 b
2463 R b
2451 R b
2464
2452
2465 # From here, we run status against revision where both source file exists.
2453 # From here, we run status against revision where both source file exists.
2466 #
2454 #
2467 # The filelog based implementation picks an arbitrary side based on revision
2455 # The filelog based implementation picks an arbitrary side based on revision
2468 # numbers. So the same side "wins" whatever the parents order is. This is
2456 # numbers. So the same side "wins" whatever the parents order is. This is
2469 # sub-optimal because depending on revision numbers means the result can be
2457 # sub-optimal because depending on revision numbers means the result can be
2470 # different from one repository to the next.
2458 # different from one repository to the next.
2471 #
2459 #
2472 # The changeset based algorithm use the parent order to break tie on conflicting
2460 # The changeset based algorithm use the parent order to break tie on conflicting
2473 # information and will have a different order depending on who is p1 and p2.
2461 # information and will have a different order depending on who is p1 and p2.
2474 # That order is stable accross repositories. (data from p1 prevails)
2462 # That order is stable accross repositories. (data from p1 prevails)
2475
2463
2476 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mAEm-0")'
2464 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mAEm-0")'
2477 A f
2465 A f
2478 d
2466 d
2479 R b
2467 R b
2480 R d
2468 R d
2481 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mEAm-0")'
2469 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mEAm-0")'
2482 A f
2470 A f
2483 d (filelog !)
2471 d (filelog !)
2484 b (no-filelog !)
2472 b (no-filelog !)
2485 R b
2473 R b
2486 R d
2474 R d
2487 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAEm-0")'
2475 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAEm-0")'
2488 A f
2476 A f
2489 a
2477 a
2490 A t
2478 A t
2491 p
2479 p
2492 R a
2480 R a
2493 R b
2481 R b
2494 R p
2482 R p
2495 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEAm-0")'
2483 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEAm-0")'
2496 A f
2484 A f
2497 a (filelog !)
2485 a (filelog !)
2498 b (no-filelog !)
2486 b (no-filelog !)
2499 A t
2487 A t
2500 p
2488 p
2501 R a
2489 R a
2502 R b
2490 R b
2503 R p
2491 R p
2504
2492
2505
2493
2506 Subcase: existing copy information overwritten on one branch
2494 Subcase: existing copy information overwritten on one branch
2507 ````````````````````````````````````````````````````````````
2495 ````````````````````````````````````````````````````````````
2508
2496
2509 Note:
2497 Note:
2510 | In this case, one of the merge wrongly record a merge while there is none.
2498 | In this case, one of the merge wrongly record a merge while there is none.
2511 | This lead to bad copy tracing information to be dug up.
2499 | This lead to bad copy tracing information to be dug up.
2512
2500
2513
2501
2514 Merge:
2502 Merge:
2515 - one with change to an unrelated file (b)
2503 - one with change to an unrelated file (b)
2516 - one overwriting a file (d) with a rename (from h to i to d)
2504 - one overwriting a file (d) with a rename (from h to i to d)
2517
2505
2518 $ hg log -G --rev '::(desc("mBFm")+desc("mFBm"))'
2506 $ hg log -G --rev '::(desc("mBFm")+desc("mFBm"))'
2519 o mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
2507 o mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
2520 |\
2508 |\
2521 +---o mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
2509 +---o mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
2522 | |/
2510 | |/
2523 | o f-2: rename i -> d
2511 | o f-2: rename i -> d
2524 | |
2512 | |
2525 | o f-1: rename h -> i
2513 | o f-1: rename h -> i
2526 | |
2514 | |
2527 o | b-1: b update
2515 o | b-1: b update
2528 |/
2516 |/
2529 o i-2: c -move-> d, s -move-> t
2517 o i-2: c -move-> d, s -move-> t
2530 |
2518 |
2531 o i-1: a -move-> c, p -move-> s
2519 o i-1: a -move-> c, p -move-> s
2532 |
2520 |
2533 o i-0 initial commit: a b h p q r
2521 o i-0 initial commit: a b h p q r
2534
2522
2535 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBFm-0")'
2523 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBFm-0")'
2536 M b
2524 M b
2537 A d
2525 A d
2538 h
2526 h
2539 A t
2527 A t
2540 p
2528 p
2541 R a
2529 R a
2542 R h
2530 R h
2543 R p
2531 R p
2544 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFBm-0")'
2532 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFBm-0")'
2545 M b
2533 M b
2546 A d
2534 A d
2547 h
2535 h
2548 A t
2536 A t
2549 p
2537 p
2550 R a
2538 R a
2551 R h
2539 R h
2552 R p
2540 R p
2553 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBFm-0")'
2541 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBFm-0")'
2554 M d (no-changeset !)
2542 M d (no-changeset !)
2555 h (no-filelog no-changeset !)
2543 h (no-filelog no-changeset !)
2556 R h
2544 R h
2557 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBFm-0")'
2545 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBFm-0")'
2558 M b
2546 M b
2559 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBFm-0")'
2547 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBFm-0")'
2560 M b
2548 M b
2561 M d (no-changeset !)
2549 M d (no-changeset !)
2562 i (no-filelog no-changeset !)
2550 i (no-filelog no-changeset !)
2563 R i
2551 R i
2564 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mFBm-0")'
2552 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mFBm-0")'
2565 M d (no-changeset !)
2553 M d (no-changeset !)
2566 h (no-filelog no-changeset !)
2554 h (no-filelog no-changeset !)
2567 R h
2555 R h
2568 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFBm-0")'
2556 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFBm-0")'
2569 M b
2557 M b
2570 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFBm-0")'
2558 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFBm-0")'
2571 M b
2559 M b
2572 M d (no-changeset !)
2560 M d (no-changeset !)
2573 i (no-filelog no-changeset !)
2561 i (no-filelog no-changeset !)
2574 R i
2562 R i
2575
2563
2576 #if no-changeset
2564 #if no-changeset
2577 $ hg log -Gfr 'desc("mBFm-0")' d
2565 $ hg log -Gfr 'desc("mBFm-0")' d
2578 o f-2: rename i -> d
2566 o f-2: rename i -> d
2579 |
2567 |
2580 o f-1: rename h -> i
2568 o f-1: rename h -> i
2581 :
2569 :
2582 o i-0 initial commit: a b h p q r
2570 o i-0 initial commit: a b h p q r
2583
2571
2584 #else
2572 #else
2585 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2573 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2586 $ hg log -Gfr 'desc("mBFm-0")' d
2574 $ hg log -Gfr 'desc("mBFm-0")' d
2587 o i-2: c -move-> d, s -move-> t
2575 o i-2: c -move-> d, s -move-> t
2588 |
2576 |
2589 ~
2577 ~
2590 #endif
2578 #endif
2591
2579
2592 #if no-changeset
2580 #if no-changeset
2593 $ hg log -Gfr 'desc("mFBm-0")' d
2581 $ hg log -Gfr 'desc("mFBm-0")' d
2594 o f-2: rename i -> d
2582 o f-2: rename i -> d
2595 |
2583 |
2596 o f-1: rename h -> i
2584 o f-1: rename h -> i
2597 :
2585 :
2598 o i-0 initial commit: a b h p q r
2586 o i-0 initial commit: a b h p q r
2599
2587
2600 #else
2588 #else
2601 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2589 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2602 $ hg log -Gfr 'desc("mFBm-0")' d
2590 $ hg log -Gfr 'desc("mFBm-0")' d
2603 o i-2: c -move-> d, s -move-> t
2591 o i-2: c -move-> d, s -move-> t
2604 |
2592 |
2605 ~
2593 ~
2606 #endif
2594 #endif
2607
2595
2608
2596
2609 Subcase: existing copy information overwritten on one branch, with different content)
2597 Subcase: existing copy information overwritten on one branch, with different content)
2610 `````````````````````````````````````````````````````````````````````````````````````
2598 `````````````````````````````````````````````````````````````````````````````````````
2611
2599
2612 Merge:
2600 Merge:
2613 - one with change to an unrelated file (b)
2601 - one with change to an unrelated file (b)
2614 - one overwriting a file (t) with a rename (from r to x to t), v content is not the same as on the other branch
2602 - one overwriting a file (t) with a rename (from r to x to t), v content is not the same as on the other branch
2615
2603
2616 $ hg log -G --rev '::(desc("mBRm")+desc("mRBm"))'
2604 $ hg log -G --rev '::(desc("mBRm")+desc("mRBm"))'
2617 o mRBm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - the other way
2605 o mRBm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - the other way
2618 |\
2606 |\
2619 +---o mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way
2607 +---o mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way
2620 | |/
2608 | |/
2621 | o r-2: rename t -> x
2609 | o r-2: rename t -> x
2622 | |
2610 | |
2623 | o r-1: rename r -> x
2611 | o r-1: rename r -> x
2624 | |
2612 | |
2625 o | b-1: b update
2613 o | b-1: b update
2626 |/
2614 |/
2627 o i-2: c -move-> d, s -move-> t
2615 o i-2: c -move-> d, s -move-> t
2628 |
2616 |
2629 o i-1: a -move-> c, p -move-> s
2617 o i-1: a -move-> c, p -move-> s
2630 |
2618 |
2631 o i-0 initial commit: a b h p q r
2619 o i-0 initial commit: a b h p q r
2632
2620
2633 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBRm-0")'
2621 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBRm-0")'
2634 M b
2622 M b
2635 A d
2623 A d
2636 a
2624 a
2637 A t
2625 A t
2638 r
2626 r
2639 R a
2627 R a
2640 R p
2628 R p
2641 R r
2629 R r
2642 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mRBm-0")'
2630 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mRBm-0")'
2643 M b
2631 M b
2644 A d
2632 A d
2645 a
2633 a
2646 A t
2634 A t
2647 r
2635 r
2648 R a
2636 R a
2649 R p
2637 R p
2650 R r
2638 R r
2651 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBRm-0")'
2639 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBRm-0")'
2652 M t
2640 M t
2653 r (no-filelog !)
2641 r (no-filelog !)
2654 R r
2642 R r
2655 $ hg status --copies --rev 'desc("r-2")' --rev 'desc("mBRm-0")'
2643 $ hg status --copies --rev 'desc("r-2")' --rev 'desc("mBRm-0")'
2656 M b
2644 M b
2657 $ hg status --copies --rev 'desc("r-1")' --rev 'desc("mBRm-0")'
2645 $ hg status --copies --rev 'desc("r-1")' --rev 'desc("mBRm-0")'
2658 M b
2646 M b
2659 M t
2647 M t
2660 x (no-filelog !)
2648 x (no-filelog !)
2661 R x
2649 R x
2662 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mRBm-0")'
2650 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mRBm-0")'
2663 M t
2651 M t
2664 r (no-filelog !)
2652 r (no-filelog !)
2665 R r
2653 R r
2666 $ hg status --copies --rev 'desc("r-2")' --rev 'desc("mRBm-0")'
2654 $ hg status --copies --rev 'desc("r-2")' --rev 'desc("mRBm-0")'
2667 M b
2655 M b
2668 $ hg status --copies --rev 'desc("r-1")' --rev 'desc("mRBm-0")'
2656 $ hg status --copies --rev 'desc("r-1")' --rev 'desc("mRBm-0")'
2669 M b
2657 M b
2670 M t
2658 M t
2671 x (no-filelog !)
2659 x (no-filelog !)
2672 R x
2660 R x
2673
2661
2674 #if no-changeset
2662 #if no-changeset
2675 $ hg log -Gfr 'desc("mBRm-0")' d
2663 $ hg log -Gfr 'desc("mBRm-0")' d
2676 o i-2: c -move-> d, s -move-> t
2664 o i-2: c -move-> d, s -move-> t
2677 |
2665 |
2678 o i-1: a -move-> c, p -move-> s
2666 o i-1: a -move-> c, p -move-> s
2679 |
2667 |
2680 o i-0 initial commit: a b h p q r
2668 o i-0 initial commit: a b h p q r
2681
2669
2682 #else
2670 #else
2683 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2671 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2684 $ hg log -Gfr 'desc("mBRm-0")' d
2672 $ hg log -Gfr 'desc("mBRm-0")' d
2685 o i-2: c -move-> d, s -move-> t
2673 o i-2: c -move-> d, s -move-> t
2686 |
2674 |
2687 ~
2675 ~
2688 #endif
2676 #endif
2689
2677
2690 #if no-changeset
2678 #if no-changeset
2691 $ hg log -Gfr 'desc("mRBm-0")' d
2679 $ hg log -Gfr 'desc("mRBm-0")' d
2692 o i-2: c -move-> d, s -move-> t
2680 o i-2: c -move-> d, s -move-> t
2693 |
2681 |
2694 o i-1: a -move-> c, p -move-> s
2682 o i-1: a -move-> c, p -move-> s
2695 |
2683 |
2696 o i-0 initial commit: a b h p q r
2684 o i-0 initial commit: a b h p q r
2697
2685
2698 #else
2686 #else
2699 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2687 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2700 $ hg log -Gfr 'desc("mRBm-0")' d
2688 $ hg log -Gfr 'desc("mRBm-0")' d
2701 o i-2: c -move-> d, s -move-> t
2689 o i-2: c -move-> d, s -move-> t
2702 |
2690 |
2703 ~
2691 ~
2704 #endif
2692 #endif
2705
2693
2706 Subcase: reset of the copy history on one side
2694 Subcase: reset of the copy history on one side
2707 ``````````````````````````````````````````````
2695 ``````````````````````````````````````````````
2708
2696
2709 Merge:
2697 Merge:
2710 - one with change to a file
2698 - one with change to a file
2711 - one deleting and recreating the file
2699 - one deleting and recreating the file
2712
2700
2713 Unlike in the 'BD/DB' cases, an actual merge happened here. So we should
2701 Unlike in the 'BD/DB' cases, an actual merge happened here. So we should
2714 consider history and rename on both branch of the merge.
2702 consider history and rename on both branch of the merge.
2715
2703
2716 $ hg log -G --rev '::(desc("mDGm")+desc("mGDm"))'
2704 $ hg log -G --rev '::(desc("mDGm")+desc("mGDm"))'
2717 o mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way
2705 o mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way
2718 |\
2706 |\
2719 +---o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2707 +---o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2720 | |/
2708 | |/
2721 | o g-1: update d
2709 | o g-1: update d
2722 | |
2710 | |
2723 o | d-2 re-add d
2711 o | d-2 re-add d
2724 | |
2712 | |
2725 o | d-1 delete d
2713 o | d-1 delete d
2726 |/
2714 |/
2727 o i-2: c -move-> d, s -move-> t
2715 o i-2: c -move-> d, s -move-> t
2728 |
2716 |
2729 o i-1: a -move-> c, p -move-> s
2717 o i-1: a -move-> c, p -move-> s
2730 |
2718 |
2731 o i-0 initial commit: a b h p q r
2719 o i-0 initial commit: a b h p q r
2732
2720
2733 One side of the merge have a long history with rename. The other side of the
2721 One side of the merge have a long history with rename. The other side of the
2734 merge point to a new file with a smaller history. Each side is "valid".
2722 merge point to a new file with a smaller history. Each side is "valid".
2735
2723
2736 (and again the filelog based algorithm only explore one, with a pick based on
2724 (and again the filelog based algorithm only explore one, with a pick based on
2737 revision numbers)
2725 revision numbers)
2738
2726
2739 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDGm-0")'
2727 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDGm-0")'
2740 A d
2728 A d
2741 a (filelog !)
2729 a (filelog !)
2742 A t
2730 A t
2743 p
2731 p
2744 R a
2732 R a
2745 R p
2733 R p
2746 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGDm-0")'
2734 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGDm-0")'
2747 A d
2735 A d
2748 a
2736 a
2749 A t
2737 A t
2750 p
2738 p
2751 R a
2739 R a
2752 R p
2740 R p
2753 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDGm-0")'
2741 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDGm-0")'
2754 M d
2742 M d
2755 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mGDm-0")'
2743 $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mGDm-0")'
2756 M d
2744 M d
2757 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mDGm-0")'
2745 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mDGm-0")'
2758 M d
2746 M d
2759 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGDm-0")'
2747 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGDm-0")'
2760 M d
2748 M d
2761
2749
2762 #if no-changeset
2750 #if no-changeset
2763 $ hg log -Gfr 'desc("mDGm-0")' d
2751 $ hg log -Gfr 'desc("mDGm-0")' d
2764 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2752 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2765 |\
2753 |\
2766 | o g-1: update d
2754 | o g-1: update d
2767 | |
2755 | |
2768 o | d-2 re-add d
2756 o | d-2 re-add d
2769 |/
2757 |/
2770 o i-2: c -move-> d, s -move-> t
2758 o i-2: c -move-> d, s -move-> t
2771 |
2759 |
2772 o i-1: a -move-> c, p -move-> s
2760 o i-1: a -move-> c, p -move-> s
2773 |
2761 |
2774 o i-0 initial commit: a b h p q r
2762 o i-0 initial commit: a b h p q r
2775
2763
2776 #else
2764 #else
2777 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2765 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2778 $ hg log -Gfr 'desc("mDGm-0")' d
2766 $ hg log -Gfr 'desc("mDGm-0")' d
2779 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2767 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2780 |\
2768 |\
2781 | o g-1: update d
2769 | o g-1: update d
2782 | |
2770 | |
2783 o | d-2 re-add d
2771 o | d-2 re-add d
2784 |/
2772 |/
2785 o i-2: c -move-> d, s -move-> t
2773 o i-2: c -move-> d, s -move-> t
2786 |
2774 |
2787 ~
2775 ~
2788 #endif
2776 #endif
2789
2777
2790
2778
2791 #if no-changeset
2779 #if no-changeset
2792 $ hg log -Gfr 'desc("mDGm-0")' d
2780 $ hg log -Gfr 'desc("mDGm-0")' d
2793 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2781 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2794 |\
2782 |\
2795 | o g-1: update d
2783 | o g-1: update d
2796 | |
2784 | |
2797 o | d-2 re-add d
2785 o | d-2 re-add d
2798 |/
2786 |/
2799 o i-2: c -move-> d, s -move-> t
2787 o i-2: c -move-> d, s -move-> t
2800 |
2788 |
2801 o i-1: a -move-> c, p -move-> s
2789 o i-1: a -move-> c, p -move-> s
2802 |
2790 |
2803 o i-0 initial commit: a b h p q r
2791 o i-0 initial commit: a b h p q r
2804
2792
2805 #else
2793 #else
2806 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2794 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2807 $ hg log -Gfr 'desc("mDGm-0")' d
2795 $ hg log -Gfr 'desc("mDGm-0")' d
2808 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2796 o mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way
2809 |\
2797 |\
2810 | o g-1: update d
2798 | o g-1: update d
2811 | |
2799 | |
2812 o | d-2 re-add d
2800 o | d-2 re-add d
2813 |/
2801 |/
2814 o i-2: c -move-> d, s -move-> t
2802 o i-2: c -move-> d, s -move-> t
2815 |
2803 |
2816 ~
2804 ~
2817 #endif
2805 #endif
2818
2806
2819 Subcase: merging a change to a file with a "copy overwrite" to that file from another branch
2807 Subcase: merging a change to a file with a "copy overwrite" to that file from another branch
2820 ````````````````````````````````````````````````````````````````````````````````````````````
2808 ````````````````````````````````````````````````````````````````````````````````````````````
2821
2809
2822 Merge:
2810 Merge:
2823 - one with change to a file (d)
2811 - one with change to a file (d)
2824 - one overwriting that file with a rename (from h to i, to d)
2812 - one overwriting that file with a rename (from h to i, to d)
2825
2813
2826 This case is similar to BF/FB, but an actual merge happens, so both side of the
2814 This case is similar to BF/FB, but an actual merge happens, so both side of the
2827 history are relevant.
2815 history are relevant.
2828
2816
2829
2817
2830 $ hg log -G --rev '::(desc("mGFm")+desc("mFGm"))'
2818 $ hg log -G --rev '::(desc("mGFm")+desc("mFGm"))'
2831 o mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
2819 o mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
2832 |\
2820 |\
2833 +---o mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
2821 +---o mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
2834 | |/
2822 | |/
2835 | o g-1: update d
2823 | o g-1: update d
2836 | |
2824 | |
2837 o | f-2: rename i -> d
2825 o | f-2: rename i -> d
2838 | |
2826 | |
2839 o | f-1: rename h -> i
2827 o | f-1: rename h -> i
2840 |/
2828 |/
2841 o i-2: c -move-> d, s -move-> t
2829 o i-2: c -move-> d, s -move-> t
2842 |
2830 |
2843 o i-1: a -move-> c, p -move-> s
2831 o i-1: a -move-> c, p -move-> s
2844 |
2832 |
2845 o i-0 initial commit: a b h p q r
2833 o i-0 initial commit: a b h p q r
2846
2834
2847
2835
2848 Note:
2836 Note:
2849 | In this case, the merge get conflicting information since on one side we have
2837 | In this case, the merge get conflicting information since on one side we have
2850 | "a -> c -> d". and one the other one we have "h -> i -> d".
2838 | "a -> c -> d". and one the other one we have "h -> i -> d".
2851 |
2839 |
2852 | The current code arbitrarily pick one side depending the ordering of the merged hash:
2840 | The current code arbitrarily pick one side depending the ordering of the merged hash:
2853
2841
2854 In this case, the file hash from "f-2" is lower, so it will be `p1` of the resulting filenode its copy tracing information will win (and trace back to "h"):
2842 In this case, the file hash from "f-2" is lower, so it will be `p1` of the resulting filenode its copy tracing information will win (and trace back to "h"):
2855
2843
2856 Details on this hash ordering pick:
2844 Details on this hash ordering pick:
2857
2845
2858 $ hg manifest --debug 'desc("g-1")' | egrep 'd$'
2846 $ hg manifest --debug 'desc("g-1")' | egrep 'd$'
2859 17ec97e605773eb44a117d1136b3849bcdc1924f 644 d (no-changeset !)
2847 17ec97e605773eb44a117d1136b3849bcdc1924f 644 d (no-changeset !)
2860 5cce88bf349f7c742bb440f2c53f81db9c294279 644 d (changeset !)
2848 5cce88bf349f7c742bb440f2c53f81db9c294279 644 d (changeset !)
2861 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("g-1")' d
2849 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("g-1")' d
2862 A d
2850 A d
2863 a (no-changeset no-compatibility !)
2851 a (no-changeset no-compatibility !)
2864
2852
2865 $ hg manifest --debug 'desc("f-2")' | egrep 'd$'
2853 $ hg manifest --debug 'desc("f-2")' | egrep 'd$'
2866 7b79e2fe0c8924e0e598a82f048a7b024afa4d96 644 d (no-changeset !)
2854 7b79e2fe0c8924e0e598a82f048a7b024afa4d96 644 d (no-changeset !)
2867 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 d (changeset !)
2855 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 d (changeset !)
2868 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("f-2")' d
2856 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("f-2")' d
2869 A d
2857 A d
2870 h (no-changeset no-compatibility !)
2858 h (no-changeset no-compatibility !)
2871
2859
2872 Copy tracing data on the resulting merge:
2860 Copy tracing data on the resulting merge:
2873
2861
2874 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFGm-0")'
2862 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFGm-0")'
2875 A d
2863 A d
2876 h (no-filelog !)
2864 h (no-filelog !)
2877 a (filelog !)
2865 a (filelog !)
2878 A t
2866 A t
2879 p
2867 p
2880 R a
2868 R a
2881 R h
2869 R h
2882 R p
2870 R p
2883 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGFm-0")'
2871 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGFm-0")'
2884 A d
2872 A d
2885 a (no-changeset !)
2873 a (no-changeset !)
2886 h (changeset !)
2874 h (changeset !)
2887 A t
2875 A t
2888 p
2876 p
2889 R a
2877 R a
2890 R h
2878 R h
2891 R p
2879 R p
2892 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFGm-0")'
2880 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFGm-0")'
2893 M d
2881 M d
2894 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mGFm-0")'
2882 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mGFm-0")'
2895 M d
2883 M d
2896 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFGm-0")'
2884 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFGm-0")'
2897 M d
2885 M d
2898 i (no-filelog !)
2886 i (no-filelog !)
2899 R i
2887 R i
2900 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mGFm-0")'
2888 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mGFm-0")'
2901 M d
2889 M d
2902 i (no-filelog !)
2890 i (no-filelog !)
2903 R i
2891 R i
2904 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mFGm-0")'
2892 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mFGm-0")'
2905 M d (no-changeset !)
2893 M d (no-changeset !)
2906 h (no-filelog no-changeset !)
2894 h (no-filelog no-changeset !)
2907 R h
2895 R h
2908 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGFm-0")'
2896 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGFm-0")'
2909 M d (no-changeset !)
2897 M d (no-changeset !)
2910 h (no-filelog no-changeset !)
2898 h (no-filelog no-changeset !)
2911 R h
2899 R h
2912
2900
2913 #if no-changeset
2901 #if no-changeset
2914 $ hg log -Gfr 'desc("mFGm-0")' d
2902 $ hg log -Gfr 'desc("mFGm-0")' d
2915 o mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
2903 o mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way
2916 |\
2904 |\
2917 | o g-1: update d
2905 | o g-1: update d
2918 | |
2906 | |
2919 o | f-2: rename i -> d
2907 o | f-2: rename i -> d
2920 | |
2908 | |
2921 o | f-1: rename h -> i
2909 o | f-1: rename h -> i
2922 |/
2910 |/
2923 o i-2: c -move-> d, s -move-> t
2911 o i-2: c -move-> d, s -move-> t
2924 |
2912 |
2925 o i-1: a -move-> c, p -move-> s
2913 o i-1: a -move-> c, p -move-> s
2926 |
2914 |
2927 o i-0 initial commit: a b h p q r
2915 o i-0 initial commit: a b h p q r
2928
2916
2929 #else
2917 #else
2930 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2918 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2931 $ hg log -Gfr 'desc("mFGm-0")' d
2919 $ hg log -Gfr 'desc("mFGm-0")' d
2932 o g-1: update d
2920 o g-1: update d
2933 |
2921 |
2934 o i-2: c -move-> d, s -move-> t
2922 o i-2: c -move-> d, s -move-> t
2935 |
2923 |
2936 ~
2924 ~
2937 #endif
2925 #endif
2938
2926
2939 #if no-changeset
2927 #if no-changeset
2940 $ hg log -Gfr 'desc("mGFm-0")' d
2928 $ hg log -Gfr 'desc("mGFm-0")' d
2941 o mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
2929 o mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way
2942 |\
2930 |\
2943 | o g-1: update d
2931 | o g-1: update d
2944 | |
2932 | |
2945 o | f-2: rename i -> d
2933 o | f-2: rename i -> d
2946 | |
2934 | |
2947 o | f-1: rename h -> i
2935 o | f-1: rename h -> i
2948 |/
2936 |/
2949 o i-2: c -move-> d, s -move-> t
2937 o i-2: c -move-> d, s -move-> t
2950 |
2938 |
2951 o i-1: a -move-> c, p -move-> s
2939 o i-1: a -move-> c, p -move-> s
2952 |
2940 |
2953 o i-0 initial commit: a b h p q r
2941 o i-0 initial commit: a b h p q r
2954
2942
2955 #else
2943 #else
2956 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2944 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
2957 $ hg log -Gfr 'desc("mGFm-0")' d
2945 $ hg log -Gfr 'desc("mGFm-0")' d
2958 o g-1: update d
2946 o g-1: update d
2959 |
2947 |
2960 o i-2: c -move-> d, s -move-> t
2948 o i-2: c -move-> d, s -move-> t
2961 |
2949 |
2962 ~
2950 ~
2963 #endif
2951 #endif
2964
2952
2965 Subcase: new copy information on both side with an actual merge happening
2953 Subcase: new copy information on both side with an actual merge happening
2966 `````````````````````````````````````````````````````````````````````````
2954 `````````````````````````````````````````````````````````````````````````
2967
2955
2968 - the "p-" branch renaming 't' to 'v' (through 'u')
2956 - the "p-" branch renaming 't' to 'v' (through 'u')
2969 - the "q-" branch renaming 'r' to 'v' (through 'w')
2957 - the "q-" branch renaming 'r' to 'v' (through 'w')
2970
2958
2971
2959
2972 $ hg log -G --rev '::(desc("mPQm")+desc("mQPm"))'
2960 $ hg log -G --rev '::(desc("mPQm")+desc("mQPm"))'
2973 o mQPm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - the other way
2961 o mQPm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - the other way
2974 |\
2962 |\
2975 +---o mPQm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - one way
2963 +---o mPQm-0 merge with copies info on both side - P side: rename t to v, Q side: r to v, (different content) - one way
2976 | |/
2964 | |/
2977 | o q-2 w -move-> v
2965 | o q-2 w -move-> v
2978 | |
2966 | |
2979 | o q-1 r -move-> w
2967 | o q-1 r -move-> w
2980 | |
2968 | |
2981 o | p-2: u -move-> v
2969 o | p-2: u -move-> v
2982 | |
2970 | |
2983 o | p-1: t -move-> u
2971 o | p-1: t -move-> u
2984 |/
2972 |/
2985 o i-2: c -move-> d, s -move-> t
2973 o i-2: c -move-> d, s -move-> t
2986 |
2974 |
2987 o i-1: a -move-> c, p -move-> s
2975 o i-1: a -move-> c, p -move-> s
2988 |
2976 |
2989 o i-0 initial commit: a b h p q r
2977 o i-0 initial commit: a b h p q r
2990
2978
2991
2979
2992 #if no-changeset
2980 #if no-changeset
2993 $ hg manifest --debug --rev 'desc("mPQm-0")' | grep '644 v'
2981 $ hg manifest --debug --rev 'desc("mPQm-0")' | grep '644 v'
2994 0946c662ef16e4e67397fd717389eb6693d41749 644 v
2982 0946c662ef16e4e67397fd717389eb6693d41749 644 v
2995 $ hg manifest --debug --rev 'desc("mQPm-0")' | grep '644 v'
2983 $ hg manifest --debug --rev 'desc("mQPm-0")' | grep '644 v'
2996 0db3aad7fcc1ec27fab57060e327b9e864ea0cc9 644 v
2984 0db3aad7fcc1ec27fab57060e327b9e864ea0cc9 644 v
2997 $ hg manifest --debug --rev 'desc("p-2")' | grep '644 v'
2985 $ hg manifest --debug --rev 'desc("p-2")' | grep '644 v'
2998 3f91841cd75cadc9a1f1b4e7c1aa6d411f76032e 644 v
2986 3f91841cd75cadc9a1f1b4e7c1aa6d411f76032e 644 v
2999 $ hg manifest --debug --rev 'desc("q-2")' | grep '644 v'
2987 $ hg manifest --debug --rev 'desc("q-2")' | grep '644 v'
3000 c43c088b811fd27983c0a9aadf44f3343cd4cd7e 644 v
2988 c43c088b811fd27983c0a9aadf44f3343cd4cd7e 644 v
3001 $ hg debugindex v | ../no-linkrev
2989 $ hg debugindex v | ../no-linkrev
3002 rev linkrev nodeid p1 p2
2990 rev linkrev nodeid p1 p2
3003 0 * 3f91841cd75c 000000000000 000000000000
2991 0 * 3f91841cd75c 000000000000 000000000000
3004 1 * c43c088b811f 000000000000 000000000000
2992 1 * c43c088b811f 000000000000 000000000000
3005 2 * 0946c662ef16 3f91841cd75c c43c088b811f
2993 2 * 0946c662ef16 3f91841cd75c c43c088b811f
3006 3 * 0db3aad7fcc1 c43c088b811f 3f91841cd75c
2994 3 * 0db3aad7fcc1 c43c088b811f 3f91841cd75c
3007 #else
2995 #else
3008 $ hg manifest --debug --rev 'desc("mPQm-0")' | grep '644 v'
2996 $ hg manifest --debug --rev 'desc("mPQm-0")' | grep '644 v'
3009 65fde9f6e4d4da23b3f610e07b53673ea9541d75 644 v
2997 65fde9f6e4d4da23b3f610e07b53673ea9541d75 644 v
3010 $ hg manifest --debug --rev 'desc("mQPm-0")' | grep '644 v'
2998 $ hg manifest --debug --rev 'desc("mQPm-0")' | grep '644 v'
3011 a098dda6413aecf154eefc976afc38b295acb7e5 644 v
2999 a098dda6413aecf154eefc976afc38b295acb7e5 644 v
3012 $ hg manifest --debug --rev 'desc("p-2")' | grep '644 v'
3000 $ hg manifest --debug --rev 'desc("p-2")' | grep '644 v'
3013 5aed6a8dbff0301328c08360d24354d3d064cf0d 644 v
3001 5aed6a8dbff0301328c08360d24354d3d064cf0d 644 v
3014 $ hg manifest --debug --rev 'desc("q-2")' | grep '644 v'
3002 $ hg manifest --debug --rev 'desc("q-2")' | grep '644 v'
3015 a38b2fa170219750dac9bc7d19df831f213ba708 644 v
3003 a38b2fa170219750dac9bc7d19df831f213ba708 644 v
3016 $ hg debugindex v | ../no-linkrev
3004 $ hg debugindex v | ../no-linkrev
3017 rev linkrev nodeid p1 p2
3005 rev linkrev nodeid p1 p2
3018 0 * 5aed6a8dbff0 000000000000 000000000000
3006 0 * 5aed6a8dbff0 000000000000 000000000000
3019 1 * a38b2fa17021 000000000000 000000000000
3007 1 * a38b2fa17021 000000000000 000000000000
3020 2 * 65fde9f6e4d4 5aed6a8dbff0 a38b2fa17021
3008 2 * 65fde9f6e4d4 5aed6a8dbff0 a38b2fa17021
3021 3 * a098dda6413a a38b2fa17021 5aed6a8dbff0
3009 3 * a098dda6413a a38b2fa17021 5aed6a8dbff0
3022 #endif
3010 #endif
3023
3011
3024 # Here the filelog based implementation is not looking at the rename
3012 # Here the filelog based implementation is not looking at the rename
3025 # information (because the file exist on both side). However the changelog
3013 # information (because the file exist on both side). However the changelog
3026 # based on works fine. We have different output.
3014 # based on works fine. We have different output.
3027
3015
3028 $ hg status --copies --rev 'desc("p-2")' --rev 'desc("mPQm-0")'
3016 $ hg status --copies --rev 'desc("p-2")' --rev 'desc("mPQm-0")'
3029 M v
3017 M v
3030 r (no-filelog !)
3018 r (no-filelog !)
3031 R r
3019 R r
3032 $ hg status --copies --rev 'desc("p-2")' --rev 'desc("mQPm-0")'
3020 $ hg status --copies --rev 'desc("p-2")' --rev 'desc("mQPm-0")'
3033 M v
3021 M v
3034 r (no-filelog !)
3022 r (no-filelog !)
3035 R r
3023 R r
3036 $ hg status --copies --rev 'desc("q-2")' --rev 'desc("mPQm-0")'
3024 $ hg status --copies --rev 'desc("q-2")' --rev 'desc("mPQm-0")'
3037 M v
3025 M v
3038 t (no-filelog !)
3026 t (no-filelog !)
3039 R t
3027 R t
3040 $ hg status --copies --rev 'desc("q-2")' --rev 'desc("mQPm-0")'
3028 $ hg status --copies --rev 'desc("q-2")' --rev 'desc("mQPm-0")'
3041 M v
3029 M v
3042 t (no-filelog !)
3030 t (no-filelog !)
3043 R t
3031 R t
3044 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("p-2")'
3032 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("p-2")'
3045 A v
3033 A v
3046 t
3034 t
3047 R t
3035 R t
3048 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("q-2")'
3036 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("q-2")'
3049 A v
3037 A v
3050 r
3038 r
3051 R r
3039 R r
3052
3040
3053 # From here, we run status against revision where both source file exists.
3041 # From here, we run status against revision where both source file exists.
3054 #
3042 #
3055 # The filelog based implementation picks an arbitrary side based on revision
3043 # The filelog based implementation picks an arbitrary side based on revision
3056 # numbers. So the same side "wins" whatever the parents order is. This is
3044 # numbers. So the same side "wins" whatever the parents order is. This is
3057 # sub-optimal because depending on revision numbers means the result can be
3045 # sub-optimal because depending on revision numbers means the result can be
3058 # different from one repository to the next.
3046 # different from one repository to the next.
3059 #
3047 #
3060 # The changeset based algorithm use the parent order to break tie on conflicting
3048 # The changeset based algorithm use the parent order to break tie on conflicting
3061 # information and will have a different order depending on who is p1 and p2.
3049 # information and will have a different order depending on who is p1 and p2.
3062 # That order is stable accross repositories. (data from p1 prevails)
3050 # That order is stable accross repositories. (data from p1 prevails)
3063
3051
3064 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mPQm-0")'
3052 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mPQm-0")'
3065 A v
3053 A v
3066 t
3054 t
3067 R r
3055 R r
3068 R t
3056 R t
3069 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mQPm-0")'
3057 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mQPm-0")'
3070 A v
3058 A v
3071 t (filelog !)
3059 t (filelog !)
3072 r (no-filelog !)
3060 r (no-filelog !)
3073 R r
3061 R r
3074 R t
3062 R t
3075 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mPQm-0")'
3063 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mPQm-0")'
3076 A d
3064 A d
3077 a
3065 a
3078 A v
3066 A v
3079 r (filelog !)
3067 r (filelog !)
3080 p (no-filelog !)
3068 p (no-filelog !)
3081 R a
3069 R a
3082 R p
3070 R p
3083 R r
3071 R r
3084 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mQPm-0")'
3072 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mQPm-0")'
3085 A d
3073 A d
3086 a
3074 a
3087 A v
3075 A v
3088 r
3076 r
3089 R a
3077 R a
3090 R p
3078 R p
3091 R r
3079 R r
3092
3080
3093
3081
3094 Comparing with merging with a deletion (and keeping the file)
3082 Comparing with merging with a deletion (and keeping the file)
3095 -------------------------------------------------------------
3083 -------------------------------------------------------------
3096
3084
3097 Merge:
3085 Merge:
3098 - one removing a file (d)
3086 - one removing a file (d)
3099 - one updating that file
3087 - one updating that file
3100 - the merge keep the modified version of the file (canceling the delete)
3088 - the merge keep the modified version of the file (canceling the delete)
3101
3089
3102 In this case, the file keep on living after the merge. So we should not drop its
3090 In this case, the file keep on living after the merge. So we should not drop its
3103 copy tracing chain.
3091 copy tracing chain.
3104
3092
3105 $ hg log -G --rev '::(desc("mCGm")+desc("mGCm"))'
3093 $ hg log -G --rev '::(desc("mCGm")+desc("mGCm"))'
3106 o mGCm-0 merge updated/deleted - revive the file (updated content) - the other way
3094 o mGCm-0 merge updated/deleted - revive the file (updated content) - the other way
3107 |\
3095 |\
3108 +---o mCGm-0 merge updated/deleted - revive the file (updated content) - one way
3096 +---o mCGm-0 merge updated/deleted - revive the file (updated content) - one way
3109 | |/
3097 | |/
3110 | o g-1: update d
3098 | o g-1: update d
3111 | |
3099 | |
3112 o | c-1 delete d
3100 o | c-1 delete d
3113 |/
3101 |/
3114 o i-2: c -move-> d, s -move-> t
3102 o i-2: c -move-> d, s -move-> t
3115 |
3103 |
3116 o i-1: a -move-> c, p -move-> s
3104 o i-1: a -move-> c, p -move-> s
3117 |
3105 |
3118 o i-0 initial commit: a b h p q r
3106 o i-0 initial commit: a b h p q r
3119
3107
3120
3108
3121 'a' is the copy source of 'd'
3109 'a' is the copy source of 'd'
3122
3110
3123 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCGm-0")'
3111 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCGm-0")'
3124 A d
3112 A d
3125 a (no-compatibility no-changeset !)
3113 a (no-compatibility no-changeset !)
3126 A t
3114 A t
3127 p
3115 p
3128 R a
3116 R a
3129 R p
3117 R p
3130 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGCm-0")'
3118 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGCm-0")'
3131 A d
3119 A d
3132 a (no-compatibility no-changeset !)
3120 a (no-compatibility no-changeset !)
3133 A t
3121 A t
3134 p
3122 p
3135 R a
3123 R a
3136 R p
3124 R p
3137 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCGm-0")'
3125 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCGm-0")'
3138 A d
3126 A d
3139 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mGCm-0")'
3127 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mGCm-0")'
3140 A d
3128 A d
3141 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mCGm-0")'
3129 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mCGm-0")'
3142 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGCm-0")'
3130 $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGCm-0")'
3143
3131
3144
3132
3145 Comparing with merge restoring an untouched deleted file
3133 Comparing with merge restoring an untouched deleted file
3146 --------------------------------------------------------
3134 --------------------------------------------------------
3147
3135
3148 Merge:
3136 Merge:
3149 - one removing a file (d)
3137 - one removing a file (d)
3150 - one leaving the file untouched
3138 - one leaving the file untouched
3151 - the merge actively restore the file to the same content.
3139 - the merge actively restore the file to the same content.
3152
3140
3153 In this case, the file keep on living after the merge. So we should not drop its
3141 In this case, the file keep on living after the merge. So we should not drop its
3154 copy tracing chain.
3142 copy tracing chain.
3155
3143
3156 $ hg log -G --rev '::(desc("mCB-revert-m")+desc("mBC-revert-m"))'
3144 $ hg log -G --rev '::(desc("mCB-revert-m")+desc("mBC-revert-m"))'
3157 o mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
3145 o mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
3158 |\
3146 |\
3159 +---o mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
3147 +---o mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
3160 | |/
3148 | |/
3161 | o c-1 delete d
3149 | o c-1 delete d
3162 | |
3150 | |
3163 o | b-1: b update
3151 o | b-1: b update
3164 |/
3152 |/
3165 o i-2: c -move-> d, s -move-> t
3153 o i-2: c -move-> d, s -move-> t
3166 |
3154 |
3167 o i-1: a -move-> c, p -move-> s
3155 o i-1: a -move-> c, p -move-> s
3168 |
3156 |
3169 o i-0 initial commit: a b h p q r
3157 o i-0 initial commit: a b h p q r
3170
3158
3171
3159
3172 'a' is the the copy source of 'd'
3160 'a' is the the copy source of 'd'
3173
3161
3174 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-revert-m-0")'
3162 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-revert-m-0")'
3175 M b
3163 M b
3176 A d
3164 A d
3177 a (no-compatibility no-changeset !)
3165 a (no-compatibility no-changeset !)
3178 A t
3166 A t
3179 p
3167 p
3180 R a
3168 R a
3181 R p
3169 R p
3182 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-revert-m-0")'
3170 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-revert-m-0")'
3183 M b
3171 M b
3184 A d
3172 A d
3185 a (no-compatibility no-changeset !)
3173 a (no-compatibility no-changeset !)
3186 A t
3174 A t
3187 p
3175 p
3188 R a
3176 R a
3189 R p
3177 R p
3190 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCB-revert-m-0")'
3178 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCB-revert-m-0")'
3191 M b
3179 M b
3192 A d
3180 A d
3193 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBC-revert-m-0")'
3181 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBC-revert-m-0")'
3194 M b
3182 M b
3195 A d
3183 A d
3196 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCB-revert-m-0")'
3184 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCB-revert-m-0")'
3197 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBC-revert-m-0")'
3185 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBC-revert-m-0")'
3198
3186
3199
3187
3200 Merging a branch where a rename was deleted with a branch where the same file was renamed
3188 Merging a branch where a rename was deleted with a branch where the same file was renamed
3201 ------------------------------------------------------------------------------------------
3189 ------------------------------------------------------------------------------------------
3202
3190
3203 Create a "conflicting" merge where `d` get removed on one branch before its
3191 Create a "conflicting" merge where `d` get removed on one branch before its
3204 rename information actually conflict with the other branch.
3192 rename information actually conflict with the other branch.
3205
3193
3206 (the copy information from the branch that was not deleted should win).
3194 (the copy information from the branch that was not deleted should win).
3207
3195
3208 $ hg log -G --rev '::(desc("mCH-delete-before-conflict-m")+desc("mHC-delete-before-conflict-m"))'
3196 $ hg log -G --rev '::(desc("mCH-delete-before-conflict-m")+desc("mHC-delete-before-conflict-m"))'
3209 o mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way
3197 o mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way
3210 |\
3198 |\
3211 +---o mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way
3199 +---o mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way
3212 | |/
3200 | |/
3213 | o h-1: b -(move)-> d
3201 | o h-1: b -(move)-> d
3214 | |
3202 | |
3215 o | c-1 delete d
3203 o | c-1 delete d
3216 | |
3204 | |
3217 o | i-2: c -move-> d, s -move-> t
3205 o | i-2: c -move-> d, s -move-> t
3218 | |
3206 | |
3219 o | i-1: a -move-> c, p -move-> s
3207 o | i-1: a -move-> c, p -move-> s
3220 |/
3208 |/
3221 o i-0 initial commit: a b h p q r
3209 o i-0 initial commit: a b h p q r
3222
3210
3223
3211
3224 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCH-delete-before-conflict-m")'
3212 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCH-delete-before-conflict-m")'
3225 A d
3213 A d
3226 b (no-compatibility no-changeset !)
3214 b (no-compatibility no-changeset !)
3227 A t
3215 A t
3228 p
3216 p
3229 R a
3217 R a
3230 R b
3218 R b
3231 R p
3219 R p
3232 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mHC-delete-before-conflict-m")'
3220 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mHC-delete-before-conflict-m")'
3233 A d
3221 A d
3234 b
3222 b
3235 A t
3223 A t
3236 p
3224 p
3237 R a
3225 R a
3238 R b
3226 R b
3239 R p
3227 R p
3240 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCH-delete-before-conflict-m")'
3228 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCH-delete-before-conflict-m")'
3241 A d
3229 A d
3242 b
3230 b
3243 R b
3231 R b
3244 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mHC-delete-before-conflict-m")'
3232 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mHC-delete-before-conflict-m")'
3245 A d
3233 A d
3246 b
3234 b
3247 R b
3235 R b
3248 $ hg status --copies --rev 'desc("h-1")' --rev 'desc("mCH-delete-before-conflict-m")'
3236 $ hg status --copies --rev 'desc("h-1")' --rev 'desc("mCH-delete-before-conflict-m")'
3249 A t
3237 A t
3250 p
3238 p
3251 R a
3239 R a
3252 R p
3240 R p
3253 $ hg status --copies --rev 'desc("h-1")' --rev 'desc("mHC-delete-before-conflict-m")'
3241 $ hg status --copies --rev 'desc("h-1")' --rev 'desc("mHC-delete-before-conflict-m")'
3254 A t
3242 A t
3255 p
3243 p
3256 R a
3244 R a
3257 R p
3245 R p
3258
3246
3259 Variant of previous with extra changes introduced by the merge
3247 Variant of previous with extra changes introduced by the merge
3260 --------------------------------------------------------------
3248 --------------------------------------------------------------
3261
3249
3262 (see case declaration for details)
3250 (see case declaration for details)
3263
3251
3264 Subcase: merge has same initial content on both side, but merge introduced a change
3252 Subcase: merge has same initial content on both side, but merge introduced a change
3265 ```````````````````````````````````````````````````````````````````````````````````
3253 ```````````````````````````````````````````````````````````````````````````````````
3266
3254
3267 - the "e-" branch renaming b to f (through 'g')
3255 - the "e-" branch renaming b to f (through 'g')
3268 - the "a-" branch renaming d to f (through e)
3256 - the "a-" branch renaming d to f (through e)
3269 - the merge add new change to b
3257 - the merge add new change to b
3270
3258
3271 $ hg log -G --rev '::(desc("mAE-change-m")+desc("mEA-change-m"))'
3259 $ hg log -G --rev '::(desc("mAE-change-m")+desc("mEA-change-m"))'
3272 o mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
3260 o mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way
3273 |\
3261 |\
3274 +---o mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
3262 +---o mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way
3275 | |/
3263 | |/
3276 | o e-2 g -move-> f
3264 | o e-2 g -move-> f
3277 | |
3265 | |
3278 | o e-1 b -move-> g
3266 | o e-1 b -move-> g
3279 | |
3267 | |
3280 o | a-2: e -move-> f
3268 o | a-2: e -move-> f
3281 | |
3269 | |
3282 o | a-1: d -move-> e
3270 o | a-1: d -move-> e
3283 |/
3271 |/
3284 o i-2: c -move-> d, s -move-> t
3272 o i-2: c -move-> d, s -move-> t
3285 |
3273 |
3286 o i-1: a -move-> c, p -move-> s
3274 o i-1: a -move-> c, p -move-> s
3287 |
3275 |
3288 o i-0 initial commit: a b h p q r
3276 o i-0 initial commit: a b h p q r
3289
3277
3290 #if no-changeset
3278 #if no-changeset
3291 $ hg manifest --debug --rev 'desc("mAE-change-m-0")' | grep '644 f'
3279 $ hg manifest --debug --rev 'desc("mAE-change-m-0")' | grep '644 f'
3292 2f649fba7eb284e720d02b61f0546fcef694c045 644 f
3280 2f649fba7eb284e720d02b61f0546fcef694c045 644 f
3293 $ hg manifest --debug --rev 'desc("mEA-change-m-0")' | grep '644 f'
3281 $ hg manifest --debug --rev 'desc("mEA-change-m-0")' | grep '644 f'
3294 774e7c1637d536b99e2d8ef16fd731f87a82bd09 644 f
3282 774e7c1637d536b99e2d8ef16fd731f87a82bd09 644 f
3295 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
3283 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
3296 b76eb76580df486c3d51d63c5c210d4dd43a8ac7 644 f
3284 b76eb76580df486c3d51d63c5c210d4dd43a8ac7 644 f
3297 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
3285 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
3298 e8825b386367b29fec957283a80bb47b47483fe1 644 f
3286 e8825b386367b29fec957283a80bb47b47483fe1 644 f
3299 $ hg debugindex f | ../no-linkrev
3287 $ hg debugindex f | ../no-linkrev
3300 rev linkrev nodeid p1 p2
3288 rev linkrev nodeid p1 p2
3301 0 * b76eb76580df 000000000000 000000000000
3289 0 * b76eb76580df 000000000000 000000000000
3302 1 * e8825b386367 000000000000 000000000000
3290 1 * e8825b386367 000000000000 000000000000
3303 2 * 2ff93c643948 b76eb76580df e8825b386367
3291 2 * 2ff93c643948 b76eb76580df e8825b386367
3304 3 * 2f649fba7eb2 b76eb76580df e8825b386367
3292 3 * 2f649fba7eb2 b76eb76580df e8825b386367
3305 4 * 774e7c1637d5 e8825b386367 b76eb76580df
3293 4 * 774e7c1637d5 e8825b386367 b76eb76580df
3306 #else
3294 #else
3307 $ hg manifest --debug --rev 'desc("mAE-change-m-0")' | grep '644 f'
3295 $ hg manifest --debug --rev 'desc("mAE-change-m-0")' | grep '644 f'
3308 d3613c1ec8310a812ac4268fd853ac576b6caea5 644 f
3296 d3613c1ec8310a812ac4268fd853ac576b6caea5 644 f
3309 $ hg manifest --debug --rev 'desc("mEA-change-m-0")' | grep '644 f'
3297 $ hg manifest --debug --rev 'desc("mEA-change-m-0")' | grep '644 f'
3310 05e03c868bbcab4a649cb33a238d7aa07398a469 644 f
3298 05e03c868bbcab4a649cb33a238d7aa07398a469 644 f
3311 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
3299 $ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
3312 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
3300 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
3313 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
3301 $ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
3314 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
3302 ae258f702dfeca05bf9b6a22a97a4b5645570f11 644 f
3315 $ hg debugindex f | ../no-linkrev
3303 $ hg debugindex f | ../no-linkrev
3316 rev linkrev nodeid p1 p2
3304 rev linkrev nodeid p1 p2
3317 0 * ae258f702dfe 000000000000 000000000000
3305 0 * ae258f702dfe 000000000000 000000000000
3318 1 * d3613c1ec831 ae258f702dfe 000000000000
3306 1 * d3613c1ec831 ae258f702dfe 000000000000
3319 2 * 05e03c868bbc ae258f702dfe 000000000000
3307 2 * 05e03c868bbc ae258f702dfe 000000000000
3320 #endif
3308 #endif
3321
3309
3322 # Here the filelog based implementation is not looking at the rename
3310 # Here the filelog based implementation is not looking at the rename
3323 # information (because the file exist on both side). However the changelog
3311 # information (because the file exist on both side). However the changelog
3324 # based on works fine. We have different output.
3312 # based on works fine. We have different output.
3325
3313
3326 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mAE-change-m-0")'
3314 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mAE-change-m-0")'
3327 M f
3315 M f
3328 b (no-filelog !)
3316 b (no-filelog !)
3329 R b
3317 R b
3330 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mEA-change-m-0")'
3318 $ hg status --copies --rev 'desc("a-2")' --rev 'desc("mEA-change-m-0")'
3331 M f
3319 M f
3332 b (no-filelog !)
3320 b (no-filelog !)
3333 R b
3321 R b
3334 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mAE-change-m-0")'
3322 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mAE-change-m-0")'
3335 M f
3323 M f
3336 d (no-filelog !)
3324 d (no-filelog !)
3337 R d
3325 R d
3338 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mEA-change-m-0")'
3326 $ hg status --copies --rev 'desc("e-2")' --rev 'desc("mEA-change-m-0")'
3339 M f
3327 M f
3340 d (no-filelog !)
3328 d (no-filelog !)
3341 R d
3329 R d
3342 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("a-2")'
3330 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("a-2")'
3343 A f
3331 A f
3344 d
3332 d
3345 R d
3333 R d
3346 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("e-2")'
3334 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("e-2")'
3347 A f
3335 A f
3348 b
3336 b
3349 R b
3337 R b
3350
3338
3351 # From here, we run status against revision where both source file exists.
3339 # From here, we run status against revision where both source file exists.
3352 #
3340 #
3353 # The filelog based implementation picks an arbitrary side based on revision
3341 # The filelog based implementation picks an arbitrary side based on revision
3354 # numbers. So the same side "wins" whatever the parents order is. This is
3342 # numbers. So the same side "wins" whatever the parents order is. This is
3355 # sub-optimal because depending on revision numbers means the result can be
3343 # sub-optimal because depending on revision numbers means the result can be
3356 # different from one repository to the next.
3344 # different from one repository to the next.
3357 #
3345 #
3358 # The changeset based algorithm use the parent order to break tie on conflicting
3346 # The changeset based algorithm use the parent order to break tie on conflicting
3359 # information and will have a different order depending on who is p1 and p2.
3347 # information and will have a different order depending on who is p1 and p2.
3360 # That order is stable accross repositories. (data from p1 prevails)
3348 # That order is stable accross repositories. (data from p1 prevails)
3361
3349
3362 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mAE-change-m-0")'
3350 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mAE-change-m-0")'
3363 A f
3351 A f
3364 d
3352 d
3365 R b
3353 R b
3366 R d
3354 R d
3367 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mEA-change-m-0")'
3355 $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mEA-change-m-0")'
3368 A f
3356 A f
3369 d (filelog !)
3357 d (filelog !)
3370 b (no-filelog !)
3358 b (no-filelog !)
3371 R b
3359 R b
3372 R d
3360 R d
3373 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE-change-m-0")'
3361 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE-change-m-0")'
3374 A f
3362 A f
3375 a
3363 a
3376 A t
3364 A t
3377 p
3365 p
3378 R a
3366 R a
3379 R b
3367 R b
3380 R p
3368 R p
3381 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA-change-m-0")'
3369 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA-change-m-0")'
3382 A f
3370 A f
3383 a (filelog !)
3371 a (filelog !)
3384 b (no-filelog !)
3372 b (no-filelog !)
3385 A t
3373 A t
3386 p
3374 p
3387 R a
3375 R a
3388 R b
3376 R b
3389 R p
3377 R p
3390
3378
3391
3379
3392 Subcase: merge overwrite common copy information, but with extra change during the merge
3380 Subcase: merge overwrite common copy information, but with extra change during the merge
3393 ```````````````````````````````````````````````````````````````````````````````````
3381 ```````````````````````````````````````````````````````````````````````````````````
3394
3382
3395 Merge:
3383 Merge:
3396 - one with change to an unrelated file (b)
3384 - one with change to an unrelated file (b)
3397 - one overwriting a file (d) with a rename (from h to i to d)
3385 - one overwriting a file (d) with a rename (from h to i to d)
3398
3386
3399 $ hg log -G --rev '::(desc("mBF-change-m")+desc("mFB-change-m"))'
3387 $ hg log -G --rev '::(desc("mBF-change-m")+desc("mFB-change-m"))'
3400 o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
3388 o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
3401 |\
3389 |\
3402 +---o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
3390 +---o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
3403 | |/
3391 | |/
3404 | o f-2: rename i -> d
3392 | o f-2: rename i -> d
3405 | |
3393 | |
3406 | o f-1: rename h -> i
3394 | o f-1: rename h -> i
3407 | |
3395 | |
3408 o | b-1: b update
3396 o | b-1: b update
3409 |/
3397 |/
3410 o i-2: c -move-> d, s -move-> t
3398 o i-2: c -move-> d, s -move-> t
3411 |
3399 |
3412 o i-1: a -move-> c, p -move-> s
3400 o i-1: a -move-> c, p -move-> s
3413 |
3401 |
3414 o i-0 initial commit: a b h p q r
3402 o i-0 initial commit: a b h p q r
3415
3403
3416 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBF-change-m-0")'
3404 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBF-change-m-0")'
3417 M b
3405 M b
3418 A d
3406 A d
3419 h (filelog !)
3407 h (filelog !)
3420 h (sidedata !)
3408 h (sidedata !)
3421 a (upgraded known-bad-output !)
3409 h (upgraded !)
3422 h (upgraded missing-correct-output !)
3410 h (upgraded-parallel !)
3423 a (upgraded-parallel known-bad-output !)
3424 h (upgraded-parallel missing-correct-output !)
3425 h (changeset !)
3411 h (changeset !)
3426 h (compatibility !)
3412 h (compatibility !)
3427 A t
3413 A t
3428 p
3414 p
3429 R a
3415 R a
3430 R h
3416 R h
3431 R p
3417 R p
3432 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFB-change-m-0")'
3418 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFB-change-m-0")'
3433 M b
3419 M b
3434 A d
3420 A d
3435 h
3421 h
3436 A t
3422 A t
3437 p
3423 p
3438 R a
3424 R a
3439 R h
3425 R h
3440 R p
3426 R p
3441 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBF-change-m-0")'
3427 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBF-change-m-0")'
3442 M d
3428 M d
3443 h (no-filelog !)
3429 h (no-filelog !)
3444 R h
3430 R h
3445 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBF-change-m-0")'
3431 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBF-change-m-0")'
3446 M b
3432 M b
3447 M d
3433 M d
3448 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBF-change-m-0")'
3434 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBF-change-m-0")'
3449 M b
3435 M b
3450 M d
3436 M d
3451 i (no-filelog !)
3437 i (no-filelog !)
3452 R i
3438 R i
3453 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mFB-change-m-0")'
3439 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mFB-change-m-0")'
3454 M d
3440 M d
3455 h (no-filelog !)
3441 h (no-filelog !)
3456 R h
3442 R h
3457 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFB-change-m-0")'
3443 $ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFB-change-m-0")'
3458 M b
3444 M b
3459 M d
3445 M d
3460 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFB-change-m-0")'
3446 $ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFB-change-m-0")'
3461 M b
3447 M b
3462 M d
3448 M d
3463 i (no-filelog !)
3449 i (no-filelog !)
3464 R i
3450 R i
3465
3451
3466 #if no-changeset
3452 #if no-changeset
3467 $ hg log -Gfr 'desc("mBF-change-m-0")' d
3453 $ hg log -Gfr 'desc("mBF-change-m-0")' d
3468 o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
3454 o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
3469 |\
3455 |\
3470 o : f-2: rename i -> d
3456 o : f-2: rename i -> d
3471 | :
3457 | :
3472 o : f-1: rename h -> i
3458 o : f-1: rename h -> i
3473 :/
3459 :/
3474 o i-0 initial commit: a b h p q r
3460 o i-0 initial commit: a b h p q r
3475
3461
3476 #else
3462 #else
3477 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
3463 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
3478 $ hg log -Gfr 'desc("mBF-change-m-0")' d
3464 $ hg log -Gfr 'desc("mBF-change-m-0")' d
3479 o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
3465 o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way
3480 :
3466 :
3481 o i-2: c -move-> d, s -move-> t
3467 o i-2: c -move-> d, s -move-> t
3482 |
3468 |
3483 ~
3469 ~
3484 #endif
3470 #endif
3485
3471
3486 #if no-changeset
3472 #if no-changeset
3487 $ hg log -Gfr 'desc("mFB-change-m-0")' d
3473 $ hg log -Gfr 'desc("mFB-change-m-0")' d
3488 o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
3474 o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
3489 |\
3475 |\
3490 o : f-2: rename i -> d
3476 o : f-2: rename i -> d
3491 | :
3477 | :
3492 o : f-1: rename h -> i
3478 o : f-1: rename h -> i
3493 :/
3479 :/
3494 o i-0 initial commit: a b h p q r
3480 o i-0 initial commit: a b h p q r
3495
3481
3496 #else
3482 #else
3497 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
3483 BROKEN: `hg log --follow <file>` relies on filelog metadata to work
3498 $ hg log -Gfr 'desc("mFB-change-m-0")' d
3484 $ hg log -Gfr 'desc("mFB-change-m-0")' d
3499 o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
3485 o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way
3500 :
3486 :
3501 o i-2: c -move-> d, s -move-> t
3487 o i-2: c -move-> d, s -move-> t
3502 |
3488 |
3503 ~
3489 ~
3504 #endif
3490 #endif
3505
3491
3506
3492
3507 Subcase: restoring and untouched deleted file, while touching it
3493 Subcase: restoring and untouched deleted file, while touching it
3508 ````````````````````````````````````````````````````````````````
3494 ````````````````````````````````````````````````````````````````
3509
3495
3510 Merge:
3496 Merge:
3511 - one removing a file (d)
3497 - one removing a file (d)
3512 - one leaving the file untouched
3498 - one leaving the file untouched
3513 - the merge actively restore the file to the same content.
3499 - the merge actively restore the file to the same content.
3514
3500
3515 In this case, the file keep on living after the merge. So we should not drop its
3501 In this case, the file keep on living after the merge. So we should not drop its
3516 copy tracing chain.
3502 copy tracing chain.
3517
3503
3518 $ hg log -G --rev '::(desc("mCB-change-m")+desc("mBC-change-m"))'
3504 $ hg log -G --rev '::(desc("mCB-change-m")+desc("mBC-change-m"))'
3519 o mBC-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
3505 o mBC-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way
3520 |\
3506 |\
3521 +---o mCB-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
3507 +---o mCB-change-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way
3522 | |/
3508 | |/
3523 | o c-1 delete d
3509 | o c-1 delete d
3524 | |
3510 | |
3525 o | b-1: b update
3511 o | b-1: b update
3526 |/
3512 |/
3527 o i-2: c -move-> d, s -move-> t
3513 o i-2: c -move-> d, s -move-> t
3528 |
3514 |
3529 o i-1: a -move-> c, p -move-> s
3515 o i-1: a -move-> c, p -move-> s
3530 |
3516 |
3531 o i-0 initial commit: a b h p q r
3517 o i-0 initial commit: a b h p q r
3532
3518
3533
3519
3534 'a' is the the copy source of 'd'
3520 'a' is the the copy source of 'd'
3535
3521
3536 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-change-m-0")'
3522 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-change-m-0")'
3537 M b
3523 M b
3538 A d
3524 A d
3539 a (no-compatibility no-changeset !)
3525 a (no-compatibility no-changeset !)
3540 A t
3526 A t
3541 p
3527 p
3542 R a
3528 R a
3543 R p
3529 R p
3544 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-change-m-0")'
3530 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-change-m-0")'
3545 M b
3531 M b
3546 A d
3532 A d
3547 a (no-compatibility no-changeset !)
3533 a (no-compatibility no-changeset !)
3548 A t
3534 A t
3549 p
3535 p
3550 R a
3536 R a
3551 R p
3537 R p
3552 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCB-change-m-0")'
3538 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCB-change-m-0")'
3553 M b
3539 M b
3554 A d
3540 A d
3555 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBC-change-m-0")'
3541 $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBC-change-m-0")'
3556 M b
3542 M b
3557 A d
3543 A d
3558 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCB-change-m-0")'
3544 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCB-change-m-0")'
3559 M d
3545 M d
3560 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBC-change-m-0")'
3546 $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBC-change-m-0")'
3561 M d
3547 M d
3562
3548
3563
3549
3564 Decision from previous merge are properly chained with later merge
3550 Decision from previous merge are properly chained with later merge
3565 ------------------------------------------------------------------
3551 ------------------------------------------------------------------
3566
3552
3567
3553
3568 Subcase: chaining conflicting rename resolution
3554 Subcase: chaining conflicting rename resolution
3569 ```````````````````````````````````````````````
3555 ```````````````````````````````````````````````
3570
3556
3571 The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We
3557 The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We
3572 add more change on the respective branch and merge again. These second merge
3558 add more change on the respective branch and merge again. These second merge
3573 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
3559 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
3574 about that file should stay unchanged.
3560 about that file should stay unchanged.
3575
3561
3576 The result from mAEm is the same for the subsequent merge:
3562 The result from mAEm is the same for the subsequent merge:
3577
3563
3578 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAEm")' f
3564 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAEm")' f
3579 A f
3565 A f
3580 a (filelog !)
3566 a (filelog !)
3581 a (sidedata !)
3567 a (sidedata !)
3582 a (upgraded !)
3568 a (upgraded !)
3583 a (upgraded-parallel !)
3569 a (upgraded-parallel !)
3584
3570
3585 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE,Km")' f
3571 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE,Km")' f
3586 A f
3572 A f
3587 a (filelog !)
3573 a (filelog !)
3588 a (sidedata !)
3574 a (sidedata !)
3589 a (upgraded !)
3575 a (upgraded !)
3590 a (upgraded-parallel !)
3576 a (upgraded-parallel !)
3591
3577
3592 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mK,AEm")' f
3578 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mK,AEm")' f
3593 A f
3579 A f
3594 a (filelog !)
3580 a (filelog !)
3595 a (sidedata !)
3581 a (sidedata !)
3596 a (upgraded !)
3582 a (upgraded !)
3597 a (upgraded-parallel !)
3583 a (upgraded-parallel !)
3598
3584
3599
3585
3600 The result from mEAm is the same for the subsequent merge:
3586 The result from mEAm is the same for the subsequent merge:
3601
3587
3602 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEAm")' f
3588 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEAm")' f
3603 A f
3589 A f
3604 a (filelog !)
3590 a (filelog !)
3605 b (sidedata !)
3591 b (sidedata !)
3606 b (upgraded !)
3592 b (upgraded !)
3607 b (upgraded-parallel !)
3593 b (upgraded-parallel !)
3608
3594
3609 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA,Jm")' f
3595 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA,Jm")' f
3610 A f
3596 A f
3611 a (filelog !)
3597 a (filelog !)
3612 b (sidedata !)
3598 b (sidedata !)
3613 b (upgraded !)
3599 b (upgraded !)
3614 b (upgraded-parallel !)
3600 b (upgraded-parallel !)
3615
3601
3616 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mJ,EAm")' f
3602 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mJ,EAm")' f
3617 A f
3603 A f
3618 a (filelog !)
3604 a (filelog !)
3619 b (sidedata !)
3605 b (sidedata !)
3620 b (upgraded !)
3606 b (upgraded !)
3621 b (upgraded-parallel !)
3607 b (upgraded-parallel !)
3622
3608
3623 Subcase: chaining conflicting rename resolution
3609 Subcase: chaining conflicting rename resolution
3624 ```````````````````````````````````````````````
3610 ```````````````````````````````````````````````
3625
3611
3626 The "mPQm" and "mQPm" case create a rename tracking conflict on file 'v'. We
3612 The "mPQm" and "mQPm" case create a rename tracking conflict on file 'v'. We
3627 add more change on the respective branch and merge again. These second merge
3613 add more change on the respective branch and merge again. These second merge
3628 does not involve the file 'v' and the arbitration done within "mPQm" and "mQP"
3614 does not involve the file 'v' and the arbitration done within "mPQm" and "mQP"
3629 about that file should stay unchanged.
3615 about that file should stay unchanged.
3630
3616
3631 The result from mPQm is the same for the subsequent merge:
3617 The result from mPQm is the same for the subsequent merge:
3632
3618
3633 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mPQm")' v
3619 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mPQm")' v
3634 A v
3620 A v
3635 r (filelog !)
3621 r (filelog !)
3636 p (sidedata !)
3622 p (sidedata !)
3637 p (upgraded !)
3623 p (upgraded !)
3638 p (upgraded-parallel !)
3624 p (upgraded-parallel !)
3639
3625
3640 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mPQ,Tm")' v
3626 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mPQ,Tm")' v
3641 A v
3627 A v
3642 r (filelog !)
3628 r (filelog !)
3643 p (sidedata !)
3629 p (sidedata !)
3644 p (upgraded !)
3630 p (upgraded !)
3645 p (upgraded-parallel !)
3631 p (upgraded-parallel !)
3646
3632
3647 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mT,PQm")' v
3633 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mT,PQm")' v
3648 A v
3634 A v
3649 r (filelog !)
3635 r (filelog !)
3650 p (sidedata !)
3636 p (sidedata !)
3651 p (upgraded !)
3637 p (upgraded !)
3652 p (upgraded-parallel !)
3638 p (upgraded-parallel !)
3653
3639
3654
3640
3655 The result from mQPm is the same for the subsequent merge:
3641 The result from mQPm is the same for the subsequent merge:
3656
3642
3657 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mQPm")' v
3643 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mQPm")' v
3658 A v
3644 A v
3659 r (no-changeset no-compatibility !)
3645 r (no-changeset no-compatibility !)
3660
3646
3661 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mQP,Sm")' v
3647 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mQP,Sm")' v
3662 A v
3648 A v
3663 r (no-changeset no-compatibility !)
3649 r (no-changeset no-compatibility !)
3664
3650
3665 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mS,QPm")' v
3651 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mS,QPm")' v
3666 A v
3652 A v
3667 r (filelog !)
3653 r (filelog !)
3668 r (sidedata !)
3654 r (sidedata !)
3669 r (upgraded !)
3655 r (upgraded !)
3670 r (upgraded-parallel !)
3656 r (upgraded-parallel !)
3671
3657
3672
3658
3673 Subcase: chaining salvage information during a merge
3659 Subcase: chaining salvage information during a merge
3674 ````````````````````````````````````````````````````
3660 ````````````````````````````````````````````````````
3675
3661
3676 We add more change on the branch were the file was deleted. merging again
3662 We add more change on the branch were the file was deleted. merging again
3677 should preserve the fact eh file was salvaged.
3663 should preserve the fact eh file was salvaged.
3678
3664
3679 reference output:
3665 reference output:
3680
3666
3681 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-revert-m-0")'
3667 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-revert-m-0")'
3682 M b
3668 M b
3683 A d
3669 A d
3684 a (no-changeset no-compatibility !)
3670 a (no-changeset no-compatibility !)
3685 A t
3671 A t
3686 p
3672 p
3687 R a
3673 R a
3688 R p
3674 R p
3689 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-revert-m-0")'
3675 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-revert-m-0")'
3690 M b
3676 M b
3691 A d
3677 A d
3692 a (no-changeset no-compatibility !)
3678 a (no-changeset no-compatibility !)
3693 A t
3679 A t
3694 p
3680 p
3695 R a
3681 R a
3696 R p
3682 R p
3697
3683
3698 chained output
3684 chained output
3699 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC+revert,Lm")'
3685 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC+revert,Lm")'
3700 M b
3686 M b
3701 A d
3687 A d
3702 a (no-changeset no-compatibility !)
3688 a (no-changeset no-compatibility !)
3703 A t
3689 A t
3704 p
3690 p
3705 A unrelated-l
3691 A unrelated-l
3706 R a
3692 R a
3707 R p
3693 R p
3708 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB+revert,Lm")'
3694 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB+revert,Lm")'
3709 M b
3695 M b
3710 A d
3696 A d
3711 a (no-changeset no-compatibility !)
3697 a (no-changeset no-compatibility !)
3712 A t
3698 A t
3713 p
3699 p
3714 A unrelated-l
3700 A unrelated-l
3715 R a
3701 R a
3716 R p
3702 R p
3717 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mL,BC+revertm")'
3703 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mL,BC+revertm")'
3718 M b
3704 M b
3719 A d
3705 A d
3720 a (no-changeset no-compatibility !)
3706 a (no-changeset no-compatibility !)
3721 A t
3707 A t
3722 p
3708 p
3723 A unrelated-l
3709 A unrelated-l
3724 R a
3710 R a
3725 R p
3711 R p
3726 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mL,CB+revertm")'
3712 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mL,CB+revertm")'
3727 M b
3713 M b
3728 A d
3714 A d
3729 a (no-changeset no-compatibility !)
3715 a (no-changeset no-compatibility !)
3730 A t
3716 A t
3731 p
3717 p
3732 A unrelated-l
3718 A unrelated-l
3733 R a
3719 R a
3734 R p
3720 R p
3735
3721
3736 Subcase: chaining "merged" information during a merge
3722 Subcase: chaining "merged" information during a merge
3737 ``````````````````````````````````````````````````````
3723 ``````````````````````````````````````````````````````
3738
3724
3739 When a non-rename change are merged with a copy overwrite, the merge pick the copy source from (p1) as the reference. We should preserve this information in subsequent merges.
3725 When a non-rename change are merged with a copy overwrite, the merge pick the copy source from (p1) as the reference. We should preserve this information in subsequent merges.
3740
3726
3741
3727
3742 reference output:
3728 reference output:
3743
3729
3744 (for details about the filelog pick, check the mFGm/mGFm case)
3730 (for details about the filelog pick, check the mFGm/mGFm case)
3745
3731
3746 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFGm")' d
3732 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFGm")' d
3747 A d
3733 A d
3748 a (filelog !)
3734 a (filelog !)
3749 h (sidedata !)
3735 h (sidedata !)
3750 h (upgraded !)
3736 h (upgraded !)
3751 h (upgraded-parallel !)
3737 h (upgraded-parallel !)
3752 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGFm")' d
3738 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGFm")' d
3753 A d
3739 A d
3754 a (filelog !)
3740 a (filelog !)
3755 a (sidedata !)
3741 a (sidedata !)
3756 a (upgraded !)
3742 a (upgraded !)
3757 a (upgraded-parallel !)
3743 a (upgraded-parallel !)
3758
3744
3759 Chained output
3745 Chained output
3760
3746
3761 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mO,FGm")' d
3747 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mO,FGm")' d
3762 A d
3748 A d
3763 a (filelog !)
3749 a (filelog !)
3764 h (sidedata !)
3750 h (sidedata !)
3765 h (upgraded !)
3751 h (upgraded !)
3766 h (upgraded-parallel !)
3752 h (upgraded-parallel !)
3767 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFG,Om")' d
3753 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFG,Om")' d
3768 A d
3754 A d
3769 a (filelog !)
3755 a (filelog !)
3770 h (sidedata !)
3756 h (sidedata !)
3771 h (upgraded !)
3757 h (upgraded !)
3772 h (upgraded-parallel !)
3758 h (upgraded-parallel !)
3773
3759
3774
3760
3775 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGF,Nm")' d
3761 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGF,Nm")' d
3776 A d
3762 A d
3777 a (no-changeset no-compatibility !)
3763 a (no-changeset no-compatibility !)
3778 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mN,GFm")' d
3764 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mN,GFm")' d
3779 A d
3765 A d
3780 a (no-changeset no-compatibility !)
3766 a (no-changeset no-compatibility !)
3781
3767
3782
3768
3783 Subcase: chaining conflicting rename resolution, with extra change during the merge
3769 Subcase: chaining conflicting rename resolution, with extra change during the merge
3784 ```````````````````````````````````````````````````````````````````````````````````
3770 ```````````````````````````````````````````````````````````````````````````````````
3785
3771
3786 The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We
3772 The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We
3787 add more change on the respective branch and merge again. These second merge
3773 add more change on the respective branch and merge again. These second merge
3788 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
3774 does not involve the file 'f' and the arbitration done within "mAEm" and "mEA"
3789 about that file should stay unchanged.
3775 about that file should stay unchanged.
3790
3776
3791 The result from mAEm is the same for the subsequent merge:
3777 The result from mAEm is the same for the subsequent merge:
3792
3778
3793 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE-change-m")' f
3779 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE-change-m")' f
3794 A f
3780 A f
3795 a (filelog !)
3781 a (filelog !)
3796 a (sidedata !)
3782 a (sidedata !)
3797 a (upgraded !)
3783 a (upgraded !)
3798 a (upgraded-parallel !)
3784 a (upgraded-parallel !)
3799
3785
3800 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE-change,Km")' f
3786 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAE-change,Km")' f
3801 A f
3787 A f
3802 a (filelog !)
3788 a (filelog !)
3803 a (sidedata !)
3789 a (sidedata !)
3804 a (upgraded !)
3790 a (upgraded !)
3805 a (upgraded-parallel !)
3791 a (upgraded-parallel !)
3806
3792
3807 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mK,AE-change-m")' f
3793 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mK,AE-change-m")' f
3808 A f
3794 A f
3809 a (no-changeset no-compatibility !)
3795 a (no-changeset no-compatibility !)
3810
3796
3811
3797
3812 The result from mEAm is the same for the subsequent merge:
3798 The result from mEAm is the same for the subsequent merge:
3813
3799
3814 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA-change-m")' f
3800 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA-change-m")' f
3815 A f
3801 A f
3816 a (filelog !)
3802 a (filelog !)
3817 b (sidedata !)
3803 b (sidedata !)
3818 b (upgraded !)
3804 b (upgraded !)
3819 b (upgraded-parallel !)
3805 b (upgraded-parallel !)
3820
3806
3821 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA-change,Jm")' f
3807 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEA-change,Jm")' f
3822 A f
3808 A f
3823 a (filelog !)
3809 a (filelog !)
3824 b (sidedata !)
3810 b (sidedata !)
3825 b (upgraded !)
3811 b (upgraded !)
3826 b (upgraded-parallel !)
3812 b (upgraded-parallel !)
3827
3813
3828 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mJ,EA-change-m")' f
3814 $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mJ,EA-change-m")' f
3829 A f
3815 A f
3830 a (filelog !)
3816 a (filelog !)
3831 b (sidedata !)
3817 b (sidedata !)
3832 b (upgraded !)
3818 b (upgraded !)
3833 b (upgraded-parallel !)
3819 b (upgraded-parallel !)
General Comments 0
You need to be logged in to leave comments. Login now