Show More
@@ -1421,17 +1421,23 b' def copy(ui, repo, pats, opts, rename=Fa' | |||||
1421 | forget = opts.get(b"forget") |
|
1421 | forget = opts.get(b"forget") | |
1422 | after = opts.get(b"after") |
|
1422 | after = opts.get(b"after") | |
1423 | dryrun = opts.get(b"dry_run") |
|
1423 | dryrun = opts.get(b"dry_run") | |
|
1424 | rev = opts.get(b'at_rev') | |||
|
1425 | if rev: | |||
|
1426 | if not forget and not after: | |||
|
1427 | # TODO: Remove this restriction and make it also create the copy | |||
|
1428 | # targets (and remove the rename source if rename==True). | |||
|
1429 | raise error.Abort(_(b'--at-rev requires --after')) | |||
|
1430 | ctx = scmutil.revsingle(repo, rev) | |||
|
1431 | if len(ctx.parents()) > 1: | |||
|
1432 | raise error.Abort(_(b'cannot mark/unmark copy in merge commit')) | |||
|
1433 | else: | |||
1424 | ctx = repo[None] |
|
1434 | ctx = repo[None] | |
|
1435 | ||||
1425 | pctx = ctx.p1() |
|
1436 | pctx = ctx.p1() | |
1426 |
|
1437 | |||
1427 | uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) |
|
1438 | uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) | |
1428 |
|
1439 | |||
1429 | if forget: |
|
1440 | if forget: | |
1430 | rev = opts[b'at_rev'] |
|
|||
1431 | if rev: |
|
|||
1432 | ctx = scmutil.revsingle(repo, rev) |
|
|||
1433 | else: |
|
|||
1434 | ctx = repo[None] |
|
|||
1435 | if ctx.rev() is None: |
|
1441 | if ctx.rev() is None: | |
1436 | new_ctx = ctx |
|
1442 | new_ctx = ctx | |
1437 | else: |
|
1443 | else: | |
@@ -1484,9 +1490,6 b' def copy(ui, repo, pats, opts, rename=Fa' | |||||
1484 | raise error.Abort(_(b'no destination specified')) |
|
1490 | raise error.Abort(_(b'no destination specified')) | |
1485 | dest = pats.pop() |
|
1491 | dest = pats.pop() | |
1486 |
|
1492 | |||
1487 | if opts.get(b'at_rev'): |
|
|||
1488 | raise error.Abort(_("--at-rev is only supported with --forget")) |
|
|||
1489 |
|
||||
1490 | def walkpat(pat): |
|
1493 | def walkpat(pat): | |
1491 | srcs = [] |
|
1494 | srcs = [] | |
1492 | m = scmutil.match(ctx, [pat], opts, globbed=True) |
|
1495 | m = scmutil.match(ctx, [pat], opts, globbed=True) | |
@@ -1517,6 +1520,55 b' def copy(ui, repo, pats, opts, rename=Fa' | |||||
1517 | srcs.append((abs, rel, exact)) |
|
1520 | srcs.append((abs, rel, exact)) | |
1518 | return srcs |
|
1521 | return srcs | |
1519 |
|
1522 | |||
|
1523 | if ctx.rev() is not None: | |||
|
1524 | rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') | |||
|
1525 | absdest = pathutil.canonpath(repo.root, cwd, dest) | |||
|
1526 | if ctx.hasdir(absdest): | |||
|
1527 | raise error.Abort( | |||
|
1528 | _(b'%s: --at-rev does not support a directory as destination') | |||
|
1529 | % uipathfn(absdest) | |||
|
1530 | ) | |||
|
1531 | if absdest not in ctx: | |||
|
1532 | raise error.Abort( | |||
|
1533 | _(b'%s: copy destination does not exist in %s') | |||
|
1534 | % (uipathfn(absdest), ctx) | |||
|
1535 | ) | |||
|
1536 | ||||
|
1537 | # avoid cycle context -> subrepo -> cmdutil | |||
|
1538 | from . import context | |||
|
1539 | ||||
|
1540 | copylist = [] | |||
|
1541 | for pat in pats: | |||
|
1542 | srcs = walkpat(pat) | |||
|
1543 | if not srcs: | |||
|
1544 | continue | |||
|
1545 | for abs, rel, exact in srcs: | |||
|
1546 | copylist.append(abs) | |||
|
1547 | ||||
|
1548 | # TODO: Add support for `hg cp --at-rev . foo bar dir` and | |||
|
1549 | # `hg cp --at-rev . dir1 dir2`, preferably unifying the code with the | |||
|
1550 | # existing functions below. | |||
|
1551 | if len(copylist) != 1: | |||
|
1552 | raise error.Abort(_(b'--at-rev requires a single source')) | |||
|
1553 | ||||
|
1554 | new_ctx = context.overlayworkingctx(repo) | |||
|
1555 | new_ctx.setbase(ctx.p1()) | |||
|
1556 | mergemod.graft(repo, ctx, wctx=new_ctx) | |||
|
1557 | ||||
|
1558 | new_ctx.markcopied(absdest, copylist[0]) | |||
|
1559 | ||||
|
1560 | with repo.lock(): | |||
|
1561 | mem_ctx = new_ctx.tomemctx_for_amend(ctx) | |||
|
1562 | new_node = mem_ctx.commit() | |||
|
1563 | ||||
|
1564 | if repo.dirstate.p1() == ctx.node(): | |||
|
1565 | with repo.dirstate.parentchange(): | |||
|
1566 | scmutil.movedirstate(repo, repo[new_node]) | |||
|
1567 | replacements = {ctx.node(): [new_node]} | |||
|
1568 | scmutil.cleanupnodes(repo, replacements, b'copy', fixphase=True) | |||
|
1569 | ||||
|
1570 | return | |||
|
1571 | ||||
1520 | # abssrc: hgsep |
|
1572 | # abssrc: hgsep | |
1521 | # relsrc: ossep |
|
1573 | # relsrc: ossep | |
1522 | # otarget: ossep |
|
1574 | # otarget: ossep |
@@ -2315,7 +2315,7 b' def continuecmd(ui, repo, **opts):' | |||||
2315 | b'', |
|
2315 | b'', | |
2316 | b'at-rev', |
|
2316 | b'at-rev', | |
2317 | b'', |
|
2317 | b'', | |
2318 | _(b'unmark copies in the given revision (EXPERIMENTAL)'), |
|
2318 | _(b'(un)mark copies in the given revision (EXPERIMENTAL)'), | |
2319 | _(b'REV'), |
|
2319 | _(b'REV'), | |
2320 | ), |
|
2320 | ), | |
2321 | ( |
|
2321 | ( | |
@@ -2345,7 +2345,7 b' def copy(ui, repo, *pats, **opts):' | |||||
2345 | all given (positional) arguments are unmarked as copies. The destination |
|
2345 | all given (positional) arguments are unmarked as copies. The destination | |
2346 | file(s) will be left in place (still tracked). |
|
2346 | file(s) will be left in place (still tracked). | |
2347 |
|
2347 | |||
2348 | This command takes effect with the next commit. |
|
2348 | This command takes effect with the next commit by default. | |
2349 |
|
2349 | |||
2350 | Returns 0 on success, 1 if errors are encountered. |
|
2350 | Returns 0 on success, 1 if errors are encountered. | |
2351 | """ |
|
2351 | """ |
@@ -14,8 +14,12 b'' | |||||
14 |
|
14 | |||
15 | * `hg copy --forget` can be used to unmark a file as copied. |
|
15 | * `hg copy --forget` can be used to unmark a file as copied. | |
16 |
|
16 | |||
|
17 | == New Experimental Features == | |||
17 |
|
18 | |||
18 | == New Experimental Features == |
|
19 | * `hg copy` now supports a `--at-rev` argument to mark files as | |
|
20 | copied in the specified commit. It only works with `--after` for | |||
|
21 | now (i.e., it's only useful for marking files copied using non-hg | |||
|
22 | `cp` as copied). | |||
19 |
|
23 | |||
20 | * Use `hg copy --forget --at-rev REV` to unmark already committed |
|
24 | * Use `hg copy --forget --at-rev REV` to unmark already committed | |
21 | copies. |
|
25 | copies. |
@@ -120,10 +120,14 b' Commit issue 1476 with a rename on the o' | |||||
120 | $ hg log -r tip -C -v | grep copies |
|
120 | $ hg log -r tip -C -v | grep copies | |
121 | copies: b2 (b1) |
|
121 | copies: b2 (b1) | |
122 |
|
122 | |||
123 | Test unmarking copies in merge commit |
|
123 | Test marking/unmarking copies in merge commit | |
124 |
|
124 | |||
125 | $ hg copy --forget --at-rev . b2 |
|
125 | $ hg copy --forget --at-rev . b2 | |
126 | abort: cannot unmark copy in merge commit |
|
126 | abort: cannot mark/unmark copy in merge commit | |
|
127 | [255] | |||
|
128 | ||||
|
129 | $ hg copy --after --at-rev . b1 b2 | |||
|
130 | abort: cannot mark/unmark copy in merge commit | |||
127 | [255] |
|
131 | [255] | |
128 |
|
132 | |||
129 | $ cd .. |
|
133 | $ cd .. |
This diff has been collapsed as it changes many lines, (718 lines changed) Show them Hide them | |||||
@@ -6,693 +6,51 b'' | |||||
6 | $ echo d1/b > d1/b |
|
6 | $ echo d1/b > d1/b | |
7 | $ echo d2/b > d2/b |
|
7 | $ echo d2/b > d2/b | |
8 | $ hg add d1/a d1/b d1/ba d1/d11/a1 d2/b |
|
8 | $ hg add d1/a d1/b d1/ba d1/d11/a1 d2/b | |
9 |
$ hg commit -m " |
|
9 | $ hg commit -m "intial" | |
10 |
|
||||
11 | rename a single file |
|
|||
12 |
|
||||
13 | $ hg rename d1/d11/a1 d2/c |
|
|||
14 | $ hg --config ui.portablefilenames=abort rename d1/a d1/con.xml |
|
|||
15 | abort: filename contains 'con', which is reserved on Windows: d1/con.xml |
|
|||
16 | [255] |
|
|||
17 | $ hg sum |
|
|||
18 | parent: 0:9b4b6e7b2c26 tip |
|
|||
19 | 1 |
|
|||
20 | branch: default |
|
|||
21 | commit: 1 renamed |
|
|||
22 | update: (current) |
|
|||
23 | phases: 1 draft |
|
|||
24 | $ hg status -C |
|
|||
25 | A d2/c |
|
|||
26 | d1/d11/a1 |
|
|||
27 | R d1/d11/a1 |
|
|||
28 | $ hg update -C |
|
|||
29 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
30 | $ rm d2/c |
|
|||
31 |
|
||||
32 | rename a single file using absolute paths |
|
|||
33 |
|
||||
34 | $ hg rename `pwd`/d1/d11/a1 `pwd`/d2/c |
|
|||
35 | $ hg status -C |
|
|||
36 | A d2/c |
|
|||
37 | d1/d11/a1 |
|
|||
38 | R d1/d11/a1 |
|
|||
39 | $ hg update -C |
|
|||
40 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
41 | $ rm d2/c |
|
|||
42 |
|
10 | |||
43 | rename --after a single file |
|
|||
44 |
|
11 | |||
45 | $ mv d1/d11/a1 d2/c |
|
12 | Test single file | |
46 | $ hg rename --after d1/d11/a1 d2/c |
|
|||
47 | $ hg status -C |
|
|||
48 | A d2/c |
|
|||
49 | d1/d11/a1 |
|
|||
50 | R d1/d11/a1 |
|
|||
51 | $ hg update -C |
|
|||
52 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
53 | $ rm d2/c |
|
|||
54 |
|
||||
55 | rename --after a single file when src and tgt already tracked |
|
|||
56 |
|
||||
57 | $ mv d1/d11/a1 d2/c |
|
|||
58 | $ hg addrem -s 0 |
|
|||
59 | removing d1/d11/a1 |
|
|||
60 | adding d2/c |
|
|||
61 | $ hg rename --after d1/d11/a1 d2/c |
|
|||
62 | $ hg status -C |
|
|||
63 | A d2/c |
|
|||
64 | d1/d11/a1 |
|
|||
65 | R d1/d11/a1 |
|
|||
66 | $ hg update -C |
|
|||
67 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
68 | $ rm d2/c |
|
|||
69 |
|
||||
70 | rename --after a single file to a nonexistent target filename |
|
|||
71 |
|
||||
72 | $ hg rename --after d1/a dummy |
|
|||
73 | d1/a: not recording move - dummy does not exist |
|
|||
74 | [1] |
|
|||
75 |
|
||||
76 | move a single file to an existing directory |
|
|||
77 |
|
13 | |||
78 | $ hg rename d1/d11/a1 d2 |
|
14 | # One recoded copy, one copy to record after commit | |
79 | $ hg status -C |
|
15 | $ hg cp d1/b d1/c | |
80 | A d2/a1 |
|
16 | $ cp d1/b d1/d | |
81 | d1/d11/a1 |
|
17 | $ hg add d1/d | |
82 | R d1/d11/a1 |
|
18 | $ hg ci -m 'copy d1/b to d1/c and d1/d' | |
83 | $ hg update -C |
|
19 | $ hg st -C --change . | |
84 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
20 | A d1/c | |
85 | $ rm d2/a1 |
|
|||
86 |
|
||||
87 | move --after a single file to an existing directory |
|
|||
88 |
|
||||
89 | $ mv d1/d11/a1 d2 |
|
|||
90 | $ hg rename --after d1/d11/a1 d2 |
|
|||
91 | $ hg status -C |
|
|||
92 | A d2/a1 |
|
|||
93 | d1/d11/a1 |
|
|||
94 | R d1/d11/a1 |
|
|||
95 | $ hg update -C |
|
|||
96 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
97 | $ rm d2/a1 |
|
|||
98 |
|
||||
99 | rename a file using a relative path |
|
|||
100 |
|
||||
101 | $ (cd d1/d11; hg rename ../../d2/b e) |
|
|||
102 | $ hg status -C |
|
|||
103 | A d1/d11/e |
|
|||
104 | d2/b |
|
|||
105 | R d2/b |
|
|||
106 | $ hg update -C |
|
|||
107 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
108 | $ rm d1/d11/e |
|
|||
109 |
|
||||
110 | rename --after a file using a relative path |
|
|||
111 |
|
||||
112 | $ (cd d1/d11; mv ../../d2/b e; hg rename --after ../../d2/b e) |
|
|||
113 | $ hg status -C |
|
|||
114 | A d1/d11/e |
|
|||
115 | d2/b |
|
|||
116 | R d2/b |
|
|||
117 | $ hg update -C |
|
|||
118 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
119 | $ rm d1/d11/e |
|
|||
120 |
|
||||
121 | rename directory d1 as d3 |
|
|||
122 |
|
||||
123 | $ hg rename d1/ d3 |
|
|||
124 | moving d1/a to d3/a |
|
|||
125 | moving d1/b to d3/b |
|
|||
126 | moving d1/ba to d3/ba |
|
|||
127 | moving d1/d11/a1 to d3/d11/a1 |
|
|||
128 | $ hg status -C |
|
|||
129 | A d3/a |
|
|||
130 | d1/a |
|
|||
131 | A d3/b |
|
|||
132 | d1/b |
|
|||
133 | A d3/ba |
|
|||
134 | d1/ba |
|
|||
135 | A d3/d11/a1 |
|
|||
136 | d1/d11/a1 |
|
|||
137 | R d1/a |
|
|||
138 | R d1/b |
|
|||
139 | R d1/ba |
|
|||
140 | R d1/d11/a1 |
|
|||
141 | $ hg update -C |
|
|||
142 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
143 | $ rm -rf d3 |
|
|||
144 |
|
||||
145 | rename --after directory d1 as d3 |
|
|||
146 |
|
||||
147 | $ mv d1 d3 |
|
|||
148 | $ hg rename --after d1 d3 |
|
|||
149 | moving d1/a to d3/a |
|
|||
150 | moving d1/b to d3/b |
|
|||
151 | moving d1/ba to d3/ba |
|
|||
152 | moving d1/d11/a1 to d3/d11/a1 |
|
|||
153 | $ hg status -C |
|
|||
154 | A d3/a |
|
|||
155 | d1/a |
|
|||
156 | A d3/b |
|
|||
157 | d1/b |
|
21 | d1/b | |
158 |
A d |
|
22 | A d1/d | |
159 | d1/ba |
|
23 | # Errors out without --after for now | |
160 | A d3/d11/a1 |
|
24 | $ hg cp --at-rev . d1/b d1/d | |
161 | d1/d11/a1 |
|
25 | abort: --at-rev requires --after | |
162 | R d1/a |
|
26 | [255] | |
163 | R d1/b |
|
27 | # Errors out with non-existent destination | |
164 | R d1/ba |
|
28 | $ hg cp -A --at-rev . d1/b d1/non-existent | |
165 | R d1/d11/a1 |
|
29 | abort: d1/non-existent: copy destination does not exist in 8a9d70fa20c9 | |
166 | $ hg update -C |
|
30 | [255] | |
167 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
31 | # Successful invocation | |
168 | $ rm -rf d3 |
|
32 | $ hg cp -A --at-rev . d1/b d1/d | |
169 |
|
33 | saved backup bundle to $TESTTMP/.hg/strip-backup/8a9d70fa20c9-973ae357-copy.hg | ||
170 | move a directory using a relative path |
|
34 | # New copy is recorded, and previously recorded copy is also still there | |
171 |
|
35 | $ hg st -C --change . | ||
172 | $ (cd d2; mkdir d3; hg rename ../d1/d11 d3) |
|
36 | A d1/c | |
173 | moving ../d1/d11/a1 to d3/d11/a1 |
|
|||
174 | $ hg status -C |
|
|||
175 | A d2/d3/d11/a1 |
|
|||
176 | d1/d11/a1 |
|
|||
177 | R d1/d11/a1 |
|
|||
178 | $ hg update -C |
|
|||
179 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
180 | $ rm -rf d2/d3 |
|
|||
181 |
|
||||
182 | move --after a directory using a relative path |
|
|||
183 |
|
||||
184 | $ (cd d2; mkdir d3; mv ../d1/d11 d3; hg rename --after ../d1/d11 d3) |
|
|||
185 | moving ../d1/d11/a1 to d3/d11/a1 |
|
|||
186 | $ hg status -C |
|
|||
187 | A d2/d3/d11/a1 |
|
|||
188 | d1/d11/a1 |
|
|||
189 | R d1/d11/a1 |
|
|||
190 | $ hg update -C |
|
|||
191 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
192 | $ rm -rf d2/d3 |
|
|||
193 |
|
||||
194 | move directory d1/d11 to an existing directory d2 (removes empty d1) |
|
|||
195 |
|
||||
196 | $ hg rename d1/d11/ d2 |
|
|||
197 | moving d1/d11/a1 to d2/d11/a1 |
|
|||
198 | $ hg status -C |
|
|||
199 | A d2/d11/a1 |
|
|||
200 | d1/d11/a1 |
|
|||
201 | R d1/d11/a1 |
|
|||
202 | $ hg update -C |
|
|||
203 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
204 | $ rm -rf d2/d11 |
|
|||
205 |
|
||||
206 | move directories d1 and d2 to a new directory d3 |
|
|||
207 |
|
||||
208 | $ mkdir d3 |
|
|||
209 | $ hg rename d1 d2 d3 |
|
|||
210 | moving d1/a to d3/d1/a |
|
|||
211 | moving d1/b to d3/d1/b |
|
|||
212 | moving d1/ba to d3/d1/ba |
|
|||
213 | moving d1/d11/a1 to d3/d1/d11/a1 |
|
|||
214 | moving d2/b to d3/d2/b |
|
|||
215 | $ hg status -C |
|
|||
216 | A d3/d1/a |
|
|||
217 | d1/a |
|
|||
218 | A d3/d1/b |
|
|||
219 | d1/b |
|
37 | d1/b | |
220 |
A |
|
38 | A d1/d | |
221 | d1/ba |
|
|||
222 | A d3/d1/d11/a1 |
|
|||
223 | d1/d11/a1 |
|
|||
224 | A d3/d2/b |
|
|||
225 | d2/b |
|
|||
226 | R d1/a |
|
|||
227 | R d1/b |
|
|||
228 | R d1/ba |
|
|||
229 | R d1/d11/a1 |
|
|||
230 | R d2/b |
|
|||
231 | $ hg update -C |
|
|||
232 | 5 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
233 | $ rm -rf d3 |
|
|||
234 |
|
||||
235 | move --after directories d1 and d2 to a new directory d3 |
|
|||
236 |
|
||||
237 | $ mkdir d3 |
|
|||
238 | $ mv d1 d2 d3 |
|
|||
239 | $ hg rename --after d1 d2 d3 |
|
|||
240 | moving d1/a to d3/d1/a |
|
|||
241 | moving d1/b to d3/d1/b |
|
|||
242 | moving d1/ba to d3/d1/ba |
|
|||
243 | moving d1/d11/a1 to d3/d1/d11/a1 |
|
|||
244 | moving d2/b to d3/d2/b |
|
|||
245 | $ hg status -C |
|
|||
246 | A d3/d1/a |
|
|||
247 | d1/a |
|
|||
248 | A d3/d1/b |
|
|||
249 | d1/b |
|
39 | d1/b | |
250 | A d3/d1/ba |
|
|||
251 | d1/ba |
|
|||
252 | A d3/d1/d11/a1 |
|
|||
253 | d1/d11/a1 |
|
|||
254 | A d3/d2/b |
|
|||
255 | d2/b |
|
|||
256 | R d1/a |
|
|||
257 | R d1/b |
|
|||
258 | R d1/ba |
|
|||
259 | R d1/d11/a1 |
|
|||
260 | R d2/b |
|
|||
261 | $ hg update -C |
|
|||
262 | 5 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
263 | $ rm -rf d3 |
|
|||
264 |
|
40 | |||
265 | move everything under directory d1 to existing directory d2, do not |
|
41 | Test using directory as destination | |
266 | overwrite existing files (d2/b) |
|
|||
267 |
|
42 | |||
268 | $ hg rename d1/* d2 |
|
43 | $ hg co 0 | |
269 | d2/b: not overwriting - file already committed |
|
44 | 0 files updated, 0 files merged, 2 files removed, 0 files unresolved | |
270 | ('hg rename --force' to replace the file by recording a rename) |
|
45 | $ cp -R d1 d3 | |
271 | moving d1/d11/a1 to d2/d11/a1 |
|
46 | $ hg add d3 | |
272 | [1] |
|
47 | adding d3/a | |
273 | $ hg status -C |
|
48 | adding d3/b | |
274 | A d2/a |
|
49 | adding d3/ba | |
275 | d1/a |
|
50 | adding d3/d11/a1 | |
276 | A d2/ba |
|
51 | $ hg ci -m 'copy d1/ to d3/' | |
277 | d1/ba |
|
52 | created new head | |
278 | A d2/d11/a1 |
|
53 | $ hg cp -A --at-rev . d1 d3 | |
279 | d1/d11/a1 |
|
54 | abort: d3: --at-rev does not support a directory as destination | |
280 | R d1/a |
|
|||
281 | R d1/ba |
|
|||
282 | R d1/d11/a1 |
|
|||
283 | $ diff -u d1/b d2/b |
|
|||
284 | --- d1/b * (glob) |
|
|||
285 | +++ d2/b * (glob) |
|
|||
286 | @@ * (glob) |
|
|||
287 | -d1/b |
|
|||
288 | +d2/b |
|
|||
289 | [1] |
|
|||
290 | $ hg update -C |
|
|||
291 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
292 | $ rm d2/a d2/ba d2/d11/a1 |
|
|||
293 |
|
||||
294 | attempt to move one file into a non-existent directory |
|
|||
295 |
|
||||
296 | $ hg rename d1/a dx/ |
|
|||
297 | abort: destination dx/ is not a directory |
|
|||
298 | [255] |
|
|||
299 | $ hg status -C |
|
|||
300 | $ hg update -C |
|
|||
301 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
302 |
|
||||
303 | attempt to move potentially more than one file into a non-existent directory |
|
|||
304 |
|
||||
305 | $ hg rename 'glob:d1/**' dx |
|
|||
306 | abort: with multiple sources, destination must be an existing directory |
|
|||
307 | [255] |
|
55 | [255] | |
308 |
|
56 | |||
309 | move every file under d1 to d2/d21 |
|
|||
310 |
|
||||
311 | $ mkdir d2/d21 |
|
|||
312 | $ hg rename 'glob:d1/**' d2/d21 |
|
|||
313 | moving d1/a to d2/d21/a |
|
|||
314 | moving d1/b to d2/d21/b |
|
|||
315 | moving d1/ba to d2/d21/ba |
|
|||
316 | moving d1/d11/a1 to d2/d21/a1 |
|
|||
317 | $ hg status -C |
|
|||
318 | A d2/d21/a |
|
|||
319 | d1/a |
|
|||
320 | A d2/d21/a1 |
|
|||
321 | d1/d11/a1 |
|
|||
322 | A d2/d21/b |
|
|||
323 | d1/b |
|
|||
324 | A d2/d21/ba |
|
|||
325 | d1/ba |
|
|||
326 | R d1/a |
|
|||
327 | R d1/b |
|
|||
328 | R d1/ba |
|
|||
329 | R d1/d11/a1 |
|
|||
330 | $ hg update -C |
|
|||
331 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
332 | $ rm -rf d2/d21 |
|
|||
333 |
|
||||
334 | move --after some files under d1 to d2/d21 |
|
|||
335 |
|
||||
336 | $ mkdir d2/d21 |
|
|||
337 | $ mv d1/a d1/d11/a1 d2/d21 |
|
|||
338 | $ hg rename --after 'glob:d1/**' d2/d21 |
|
|||
339 | moving d1/a to d2/d21/a |
|
|||
340 | d1/b: not recording move - d2/d21/b does not exist |
|
|||
341 | d1/ba: not recording move - d2/d21/ba does not exist |
|
|||
342 | moving d1/d11/a1 to d2/d21/a1 |
|
|||
343 | [1] |
|
|||
344 | $ hg status -C |
|
|||
345 | A d2/d21/a |
|
|||
346 | d1/a |
|
|||
347 | A d2/d21/a1 |
|
|||
348 | d1/d11/a1 |
|
|||
349 | R d1/a |
|
|||
350 | R d1/d11/a1 |
|
|||
351 | $ hg update -C |
|
|||
352 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
353 | $ rm -rf d2/d21 |
|
|||
354 |
|
||||
355 | move every file under d1 starting with an 'a' to d2/d21 (regexp) |
|
|||
356 |
|
||||
357 | $ mkdir d2/d21 |
|
|||
358 | $ hg rename 're:d1/([^a][^/]*/)*a.*' d2/d21 |
|
|||
359 | moving d1/a to d2/d21/a |
|
|||
360 | moving d1/d11/a1 to d2/d21/a1 |
|
|||
361 | $ hg status -C |
|
|||
362 | A d2/d21/a |
|
|||
363 | d1/a |
|
|||
364 | A d2/d21/a1 |
|
|||
365 | d1/d11/a1 |
|
|||
366 | R d1/a |
|
|||
367 | R d1/d11/a1 |
|
|||
368 | $ hg update -C |
|
|||
369 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
370 | $ rm -rf d2/d21 |
|
|||
371 |
|
||||
372 | attempt to overwrite an existing file |
|
|||
373 |
|
||||
374 | $ echo "ca" > d1/ca |
|
|||
375 | $ hg rename d1/ba d1/ca |
|
|||
376 | d1/ca: not overwriting - file exists |
|
|||
377 | ('hg rename --after' to record the rename) |
|
|||
378 | [1] |
|
|||
379 | $ hg status -C |
|
|||
380 | ? d1/ca |
|
|||
381 | $ hg update -C |
|
|||
382 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
383 |
|
||||
384 | forced overwrite of an existing file |
|
|||
385 |
|
||||
386 | $ echo "ca" > d1/ca |
|
|||
387 | $ hg rename --force d1/ba d1/ca |
|
|||
388 | $ hg status -C |
|
|||
389 | A d1/ca |
|
|||
390 | d1/ba |
|
|||
391 | R d1/ba |
|
|||
392 | $ hg update -C |
|
|||
393 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
394 | $ rm d1/ca |
|
|||
395 |
|
||||
396 | attempt to overwrite an existing broken symlink |
|
|||
397 |
|
||||
398 | #if symlink |
|
|||
399 | $ ln -s ba d1/ca |
|
|||
400 | $ hg rename --traceback d1/ba d1/ca |
|
|||
401 | d1/ca: not overwriting - file exists |
|
|||
402 | ('hg rename --after' to record the rename) |
|
|||
403 | [1] |
|
|||
404 | $ hg status -C |
|
|||
405 | ? d1/ca |
|
|||
406 | $ hg update -C |
|
|||
407 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
408 | $ rm d1/ca |
|
|||
409 |
|
||||
410 | replace a symlink with a file |
|
|||
411 |
|
||||
412 | $ ln -s ba d1/ca |
|
|||
413 | $ hg rename --force d1/ba d1/ca |
|
|||
414 | $ hg status -C |
|
|||
415 | A d1/ca |
|
|||
416 | d1/ba |
|
|||
417 | R d1/ba |
|
|||
418 | $ hg update -C |
|
|||
419 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
420 | $ rm d1/ca |
|
|||
421 | #endif |
|
|||
422 |
|
||||
423 | do not copy more than one source file to the same destination file |
|
|||
424 |
|
||||
425 | $ mkdir d3 |
|
|||
426 | $ hg rename d1/* d2/* d3 |
|
|||
427 | moving d1/d11/a1 to d3/d11/a1 |
|
|||
428 | d3/b: not overwriting - d2/b collides with d1/b |
|
|||
429 | [1] |
|
|||
430 | $ hg status -C |
|
|||
431 | A d3/a |
|
|||
432 | d1/a |
|
|||
433 | A d3/b |
|
|||
434 | d1/b |
|
|||
435 | A d3/ba |
|
|||
436 | d1/ba |
|
|||
437 | A d3/d11/a1 |
|
|||
438 | d1/d11/a1 |
|
|||
439 | R d1/a |
|
|||
440 | R d1/b |
|
|||
441 | R d1/ba |
|
|||
442 | R d1/d11/a1 |
|
|||
443 | $ hg update -C |
|
|||
444 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
445 | $ rm -rf d3 |
|
|||
446 |
|
||||
447 | move a whole subtree with "hg rename ." |
|
|||
448 |
|
||||
449 | $ mkdir d3 |
|
|||
450 | $ (cd d1; hg rename . ../d3) |
|
|||
451 | moving a to ../d3/d1/a |
|
|||
452 | moving b to ../d3/d1/b |
|
|||
453 | moving ba to ../d3/d1/ba |
|
|||
454 | moving d11/a1 to ../d3/d1/d11/a1 |
|
|||
455 | $ hg status -C |
|
|||
456 | A d3/d1/a |
|
|||
457 | d1/a |
|
|||
458 | A d3/d1/b |
|
|||
459 | d1/b |
|
|||
460 | A d3/d1/ba |
|
|||
461 | d1/ba |
|
|||
462 | A d3/d1/d11/a1 |
|
|||
463 | d1/d11/a1 |
|
|||
464 | R d1/a |
|
|||
465 | R d1/b |
|
|||
466 | R d1/ba |
|
|||
467 | R d1/d11/a1 |
|
|||
468 | $ hg update -C |
|
|||
469 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
470 | $ rm -rf d3 |
|
|||
471 |
|
||||
472 | move a whole subtree with "hg rename --after ." |
|
|||
473 |
|
||||
474 | $ mkdir d3 |
|
|||
475 | $ mv d1/* d3 |
|
|||
476 | $ (cd d1; hg rename --after . ../d3) |
|
|||
477 | moving a to ../d3/a |
|
|||
478 | moving b to ../d3/b |
|
|||
479 | moving ba to ../d3/ba |
|
|||
480 | moving d11/a1 to ../d3/d11/a1 |
|
|||
481 | $ hg status -C |
|
|||
482 | A d3/a |
|
|||
483 | d1/a |
|
|||
484 | A d3/b |
|
|||
485 | d1/b |
|
|||
486 | A d3/ba |
|
|||
487 | d1/ba |
|
|||
488 | A d3/d11/a1 |
|
|||
489 | d1/d11/a1 |
|
|||
490 | R d1/a |
|
|||
491 | R d1/b |
|
|||
492 | R d1/ba |
|
|||
493 | R d1/d11/a1 |
|
|||
494 | $ hg update -C |
|
|||
495 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
496 | $ rm -rf d3 |
|
|||
497 |
|
||||
498 | move the parent tree with "hg rename .." |
|
|||
499 |
|
||||
500 | $ (cd d1/d11; hg rename .. ../../d3) |
|
|||
501 | moving ../a to ../../d3/a |
|
|||
502 | moving ../b to ../../d3/b |
|
|||
503 | moving ../ba to ../../d3/ba |
|
|||
504 | moving a1 to ../../d3/d11/a1 |
|
|||
505 | $ hg status -C |
|
|||
506 | A d3/a |
|
|||
507 | d1/a |
|
|||
508 | A d3/b |
|
|||
509 | d1/b |
|
|||
510 | A d3/ba |
|
|||
511 | d1/ba |
|
|||
512 | A d3/d11/a1 |
|
|||
513 | d1/d11/a1 |
|
|||
514 | R d1/a |
|
|||
515 | R d1/b |
|
|||
516 | R d1/ba |
|
|||
517 | R d1/d11/a1 |
|
|||
518 | $ hg update -C |
|
|||
519 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
520 | $ rm -rf d3 |
|
|||
521 |
|
||||
522 | skip removed files |
|
|||
523 |
|
||||
524 | $ hg remove d1/b |
|
|||
525 | $ hg rename d1 d3 |
|
|||
526 | moving d1/a to d3/a |
|
|||
527 | moving d1/ba to d3/ba |
|
|||
528 | moving d1/d11/a1 to d3/d11/a1 |
|
|||
529 | $ hg status -C |
|
|||
530 | A d3/a |
|
|||
531 | d1/a |
|
|||
532 | A d3/ba |
|
|||
533 | d1/ba |
|
|||
534 | A d3/d11/a1 |
|
|||
535 | d1/d11/a1 |
|
|||
536 | R d1/a |
|
|||
537 | R d1/b |
|
|||
538 | R d1/ba |
|
|||
539 | R d1/d11/a1 |
|
|||
540 | $ hg update -C |
|
|||
541 | 4 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
542 | $ rm -rf d3 |
|
|||
543 |
|
||||
544 | transitive rename |
|
|||
545 |
|
||||
546 | $ hg rename d1/b d1/bb |
|
|||
547 | $ hg rename d1/bb d1/bc |
|
|||
548 | $ hg status -C |
|
|||
549 | A d1/bc |
|
|||
550 | d1/b |
|
|||
551 | R d1/b |
|
|||
552 | $ hg update -C |
|
|||
553 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
554 | $ rm d1/bc |
|
|||
555 |
|
||||
556 | transitive rename --after |
|
|||
557 |
|
||||
558 | $ hg rename d1/b d1/bb |
|
|||
559 | $ mv d1/bb d1/bc |
|
|||
560 | $ hg rename --after d1/bb d1/bc |
|
|||
561 | $ hg status -C |
|
|||
562 | A d1/bc |
|
|||
563 | d1/b |
|
|||
564 | R d1/b |
|
|||
565 | $ hg update -C |
|
|||
566 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
567 | $ rm d1/bc |
|
|||
568 |
|
||||
569 | $ echo "# idempotent renames (d1/b -> d1/bb followed by d1/bb -> d1/b)" |
|
|||
570 | # idempotent renames (d1/b -> d1/bb followed by d1/bb -> d1/b) |
|
|||
571 | $ hg rename d1/b d1/bb |
|
|||
572 | $ echo "some stuff added to d1/bb" >> d1/bb |
|
|||
573 | $ hg rename d1/bb d1/b |
|
|||
574 | $ hg status -C |
|
|||
575 | M d1/b |
|
|||
576 | $ hg update -C |
|
|||
577 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
578 |
|
||||
579 | overwriting with renames (issue1959) |
|
|||
580 |
|
||||
581 | $ hg rename d1/a d1/c |
|
|||
582 | $ hg rename d1/b d1/a |
|
|||
583 | $ hg status -C |
|
|||
584 | M d1/a |
|
|||
585 | d1/b |
|
|||
586 | A d1/c |
|
|||
587 | d1/a |
|
|||
588 | R d1/b |
|
|||
589 | $ hg diff --git |
|
|||
590 | diff --git a/d1/a b/d1/a |
|
|||
591 | --- a/d1/a |
|
|||
592 | +++ b/d1/a |
|
|||
593 | @@ -1,1 +1,1 @@ |
|
|||
594 | -d1/a |
|
|||
595 | +d1/b |
|
|||
596 | diff --git a/d1/b b/d1/b |
|
|||
597 | deleted file mode 100644 |
|
|||
598 | --- a/d1/b |
|
|||
599 | +++ /dev/null |
|
|||
600 | @@ -1,1 +0,0 @@ |
|
|||
601 | -d1/b |
|
|||
602 | diff --git a/d1/a b/d1/c |
|
|||
603 | copy from d1/a |
|
|||
604 | copy to d1/c |
|
|||
605 | $ hg update -C |
|
|||
606 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
607 | $ rm d1/c # The file was marked as added, so 'hg update' action was 'forget' |
|
|||
608 |
|
||||
609 | check illegal path components |
|
|||
610 |
|
||||
611 | $ hg rename d1/d11/a1 .hg/foo |
|
|||
612 | abort: path contains illegal component: .hg/foo |
|
|||
613 | [255] |
|
|||
614 | $ hg status -C |
|
|||
615 | $ hg rename d1/d11/a1 ../foo |
|
|||
616 | abort: ../foo not under root '$TESTTMP' |
|
|||
617 | [255] |
|
|||
618 | $ hg status -C |
|
|||
619 |
|
||||
620 | $ mv d1/d11/a1 .hg/foo |
|
|||
621 | $ hg rename --after d1/d11/a1 .hg/foo |
|
|||
622 | abort: path contains illegal component: .hg/foo |
|
|||
623 | [255] |
|
|||
624 | $ hg status -C |
|
|||
625 | ! d1/d11/a1 |
|
|||
626 | $ hg update -C |
|
|||
627 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
628 | $ rm .hg/foo |
|
|||
629 |
|
||||
630 | $ hg rename d1/d11/a1 .hg |
|
|||
631 | abort: path contains illegal component: .hg/a1 |
|
|||
632 | [255] |
|
|||
633 | $ hg --config extensions.largefiles= rename d1/d11/a1 .hg |
|
|||
634 | The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !) |
|
|||
635 | abort: path contains illegal component: .hg/a1 |
|
|||
636 | [255] |
|
|||
637 | $ hg status -C |
|
|||
638 | $ hg rename d1/d11/a1 .. |
|
|||
639 | abort: ../a1 not under root '$TESTTMP' |
|
|||
640 | [255] |
|
|||
641 | $ hg --config extensions.largefiles= rename d1/d11/a1 .. |
|
|||
642 | The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !) |
|
|||
643 | abort: ../a1 not under root '$TESTTMP' |
|
|||
644 | [255] |
|
|||
645 | $ hg status -C |
|
|||
646 |
|
||||
647 | $ mv d1/d11/a1 .hg |
|
|||
648 | $ hg rename --after d1/d11/a1 .hg |
|
|||
649 | abort: path contains illegal component: .hg/a1 |
|
|||
650 | [255] |
|
|||
651 | $ hg status -C |
|
|||
652 | ! d1/d11/a1 |
|
|||
653 | $ hg update -C |
|
|||
654 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
|||
655 | $ rm .hg/a1 |
|
|||
656 |
|
||||
657 | $ (cd d1/d11; hg rename ../../d2/b ../../.hg/foo) |
|
|||
658 | abort: path contains illegal component: .hg/foo |
|
|||
659 | [255] |
|
|||
660 | $ hg status -C |
|
|||
661 | $ (cd d1/d11; hg rename ../../d2/b ../../../foo) |
|
|||
662 | abort: ../../../foo not under root '$TESTTMP' |
|
|||
663 | [255] |
|
|||
664 | $ hg status -C |
|
|||
665 |
|
||||
666 | check that stat information such as mtime is preserved on rename - it's unclear |
|
|||
667 | whether the `touch` and `stat` commands are portable, so we mimic them using |
|
|||
668 | python. Not all platforms support precision of even one-second granularity, so |
|
|||
669 | we allow a rather generous fudge factor here; 1234567890 is 2009, and the |
|
|||
670 | primary thing we care about is that it's not the machine's current time; |
|
|||
671 | hopefully it's really unlikely for a machine to have such a broken clock that |
|
|||
672 | this test fails. :) |
|
|||
673 |
|
||||
674 | $ mkdir mtime |
|
|||
675 | Create the file (as empty), then update its mtime and atime to be 1234567890. |
|
|||
676 | >>> import os |
|
|||
677 | >>> filename = "mtime/f" |
|
|||
678 | >>> mtime = 1234567890 |
|
|||
679 | >>> open(filename, "w").close() |
|
|||
680 | >>> os.utime(filename, (mtime, mtime)) |
|
|||
681 | $ hg ci -qAm 'add mtime dir' |
|
|||
682 | "hg cp" does not preserve the mtime, so it should be newer than the 2009 |
|
|||
683 | timestamp. |
|
|||
684 | $ hg cp -q mtime mtime_cp |
|
|||
685 | >>> from __future__ import print_function |
|
|||
686 | >>> import os |
|
|||
687 | >>> filename = "mtime_cp/f" |
|
|||
688 | >>> print(os.stat(filename).st_mtime < 1234567999) |
|
|||
689 | False |
|
|||
690 | "hg mv" preserves the mtime, so it should be ~equal to the 2009 timestamp |
|
|||
691 | (modulo some fudge factor due to not every system supporting 1s-level |
|
|||
692 | precision). |
|
|||
693 | $ hg mv -q mtime mtime_mv |
|
|||
694 | >>> from __future__ import print_function |
|
|||
695 | >>> import os |
|
|||
696 | >>> filename = "mtime_mv/f" |
|
|||
697 | >>> print(os.stat(filename).st_mtime < 1234567999) |
|
|||
698 | True |
|
General Comments 0
You need to be logged in to leave comments.
Login now