Show More
@@ -13,6 +13,7 import hg, util, revlog, bundlerepo, ext | |||
|
13 | 13 | import difflib, patch, time, help, mdiff, tempfile |
|
14 | 14 | import version, socket |
|
15 | 15 | import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect |
|
16 | import merge as merge_ | |
|
16 | 17 | |
|
17 | 18 | # Commands start here, listed alphabetically |
|
18 | 19 | |
@@ -2236,6 +2237,35 def rename(ui, repo, *pats, **opts): | |||
|
2236 | 2237 | finally: |
|
2237 | 2238 | del wlock |
|
2238 | 2239 | |
|
2240 | def resolve(ui, repo, *pats, **opts): | |
|
2241 | """resolve file merges from a branch merge or update | |
|
2242 | ||
|
2243 | This command will attempt to resolve unresolved merges from the | |
|
2244 | last update or merge command. This will use the local file | |
|
2245 | revision preserved at the last update or merge to cleanly retry | |
|
2246 | the file merge attempt. With no file or options specified, this | |
|
2247 | command will attempt to resolve all unresolved files. | |
|
2248 | """ | |
|
2249 | ||
|
2250 | if len([x for x in opts if opts[x]]) > 1: | |
|
2251 | raise util.Abort(_("too many options specified")) | |
|
2252 | ||
|
2253 | ms = merge_.mergestate(repo) | |
|
2254 | mf = util.matcher(repo.root, "", pats, [], [])[1] | |
|
2255 | ||
|
2256 | for f in ms: | |
|
2257 | if mf(f): | |
|
2258 | if opts.get("list"): | |
|
2259 | ui.write("%s %s\n" % (ms[f].upper(), f)) | |
|
2260 | elif opts.get("mark"): | |
|
2261 | ms.mark(f, "r") | |
|
2262 | elif opts.get("unmark"): | |
|
2263 | ms.mark(f, "u") | |
|
2264 | else: | |
|
2265 | wctx = repo.workingctx() | |
|
2266 | mctx = wctx.parents()[-1] | |
|
2267 | ms.resolve(f, wctx, mctx) | |
|
2268 | ||
|
2239 | 2269 | def revert(ui, repo, *pats, **opts): |
|
2240 | 2270 | """restore individual files or dirs to an earlier state |
|
2241 | 2271 | |
@@ -3196,6 +3226,12 table = { | |||
|
3196 | 3226 | _('forcibly copy over an existing managed file')), |
|
3197 | 3227 | ] + walkopts + dryrunopts, |
|
3198 | 3228 | _('hg rename [OPTION]... SOURCE... DEST')), |
|
3229 | "resolve": | |
|
3230 | (resolve, | |
|
3231 | [('l', 'list', None, _('list state of files needing merge')), | |
|
3232 | ('m', 'mark', None, _('mark files as resolved')), | |
|
3233 | ('u', 'unmark', None, _('unmark files as resolved'))], | |
|
3234 | ('hg resolve [OPTION] [FILES...]')), | |
|
3199 | 3235 | "revert": |
|
3200 | 3236 | (revert, |
|
3201 | 3237 | [('a', 'all', None, _('revert all changes when no arguments given')), |
@@ -271,15 +271,7 def update(repo, node): | |||
|
271 | 271 | stats = _merge.update(repo, node, False, False, None) |
|
272 | 272 | _showstats(repo, stats) |
|
273 | 273 | if stats[3]: |
|
274 |
repo.ui.status(_(" |
|
|
275 | " locally modified files.\n")) | |
|
276 | if stats[1]: | |
|
277 | repo.ui.status(_("You can finish the partial merge using:\n")) | |
|
278 | else: | |
|
279 | repo.ui.status(_("You can redo the full merge using:\n")) | |
|
280 | # len(pl)==1, otherwise _merge.update() would have raised util.Abort: | |
|
281 | repo.ui.status(_(" hg update %s\n hg update %s\n") | |
|
282 | % (pl[0].rev(), repo.changectx(node).rev())) | |
|
274 | repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) | |
|
283 | 275 | return stats[3] > 0 |
|
284 | 276 | |
|
285 | 277 | def clean(repo, node, show_stats=True): |
@@ -294,11 +286,7 def merge(repo, node, force=None, remind | |||
|
294 | 286 | _showstats(repo, stats) |
|
295 | 287 | if stats[3]: |
|
296 | 288 | pl = repo.parents() |
|
297 |
repo.ui.status(_(" |
|
|
298 | " you can redo the full merge using:\n" | |
|
299 | " hg update -C %s\n" | |
|
300 | " hg merge %s\n") | |
|
301 | % (pl[0].rev(), pl[1].rev())) | |
|
289 | repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) | |
|
302 | 290 | elif remind: |
|
303 | 291 | repo.ui.status(_("(branch merge, don't forget to commit)\n")) |
|
304 | 292 | return stats[3] > 0 |
@@ -5,7 +5,7 | |||
|
5 | 5 | # This software may be used and distributed according to the terms |
|
6 | 6 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | 7 | |
|
8 | from node import nullid, nullrev, hex | |
|
8 | from node import nullid, nullrev, hex, bin | |
|
9 | 9 | from i18n import _ |
|
10 | 10 | import errno, util, os, filemerge, copies, shutil |
|
11 | 11 | |
@@ -13,27 +13,49 class mergestate(object): | |||
|
13 | 13 | '''track 3-way merge state of individual files''' |
|
14 | 14 | def __init__(self, repo): |
|
15 | 15 | self._repo = repo |
|
16 | self._read() | |
|
17 | def reset(self, node): | |
|
16 | 18 | self._state = {} |
|
17 | self._data = {} | |
|
18 | def reset(self, node): | |
|
19 | 19 | self._local = node |
|
20 | 20 | shutil.rmtree(self._repo.join("merge"), True) |
|
21 | def _read(self): | |
|
22 | self._state = {} | |
|
23 | try: | |
|
24 | f = self._repo.opener("merge/state") | |
|
25 | self._local = bin(f.readline()[:-1]) | |
|
26 | for l in f: | |
|
27 | bits = l[:-1].split("\0") | |
|
28 | self._state[bits[0]] = bits[1:] | |
|
29 | except IOError, err: | |
|
30 | if err.errno != errno.ENOENT: | |
|
31 | raise | |
|
32 | def _write(self): | |
|
33 | f = self._repo.opener("merge/state", "w") | |
|
34 | f.write(hex(self._local) + "\n") | |
|
35 | for d, v in self._state.items(): | |
|
36 | f.write("\0".join([d] + v) + "\n") | |
|
21 | 37 | def add(self, fcl, fco, fca, fd, flags): |
|
22 | 38 | hash = util.sha1(fcl.path()).hexdigest() |
|
23 | 39 | self._repo.opener("merge/" + hash, "w").write(fcl.data()) |
|
24 | self._state[fd] = 'u' | |
|
25 | self._data[fd] = (hash, fcl.path(), fca.path(), hex(fca.filenode()), | |
|
26 | fco.path(), flags) | |
|
40 | self._state[fd] = ['u', hash, fcl.path(), fca.path(), | |
|
41 | hex(fca.filenode()), fco.path(), flags] | |
|
42 | self._write() | |
|
27 | 43 | def __contains__(self, dfile): |
|
28 | 44 | return dfile in self._state |
|
29 | 45 | def __getitem__(self, dfile): |
|
30 | return self._state[dfile] | |
|
46 | return self._state[dfile][0] | |
|
47 | def __iter__(self): | |
|
48 | l = self._state.keys() | |
|
49 | l.sort() | |
|
50 | for f in l: | |
|
51 | yield f | |
|
31 | 52 | def mark(self, dfile, state): |
|
32 | self._state[dfile] = state | |
|
53 | self._state[dfile][0] = state | |
|
54 | self._write() | |
|
33 | 55 | def resolve(self, dfile, wctx, octx): |
|
34 | 56 | if self[dfile] == 'r': |
|
35 | 57 | return 0 |
|
36 |
hash, lfile, afile, anode, ofile, flags = self._ |
|
|
58 | state, hash, lfile, afile, anode, ofile, flags = self._state[dfile] | |
|
37 | 59 | f = self._repo.opener("merge/" + hash) |
|
38 | 60 | self._repo.wwrite(dfile, f.read(), flags) |
|
39 | 61 | fcd = wctx[dfile] |
@@ -41,7 +63,6 class mergestate(object): | |||
|
41 | 63 | fca = self._repo.filectx(afile, fileid=anode) |
|
42 | 64 | r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca) |
|
43 | 65 | if not r: |
|
44 | util.set_flags(self._repo.wjoin(dfile), flags) | |
|
45 | 66 | self.mark(dfile, 'r') |
|
46 | 67 | return r |
|
47 | 68 |
@@ -18,9 +18,7 merging a | |||
|
18 | 18 | warning: conflicts during merge. |
|
19 | 19 | merging a failed! |
|
20 | 20 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
21 | There are unresolved merges, you can redo the full merge using: | |
|
22 | hg update -C 2 | |
|
23 | hg merge 1 | |
|
21 | use 'hg resolve' to retry unresolved file merges | |
|
24 | 22 | M a |
|
25 | 23 | ? a.orig |
|
26 | 24 | % should fail |
@@ -4,9 +4,7 merging a | |||
|
4 | 4 | warning: conflicts during merge. |
|
5 | 5 | merging a failed! |
|
6 | 6 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
7 | There are unresolved merges, you can redo the full merge using: | |
|
8 | hg update -C 2 | |
|
9 | hg merge 1 | |
|
7 | use 'hg resolve' to retry unresolved file merges | |
|
10 | 8 | e7fe8eb3e180+0d24b7662d3e+ tip |
|
11 | 9 | <<<<<<< local |
|
12 | 10 | something else |
@@ -265,9 +265,7 merging b | |||
|
265 | 265 | warning: conflicts during merge. |
|
266 | 266 | merging b failed! |
|
267 | 267 | 2 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
268 | There are unresolved merges, you can redo the full merge using: | |
|
269 | hg update -C 2 | |
|
270 | hg merge 4 | |
|
268 | use 'hg resolve' to retry unresolved file merges | |
|
271 | 269 | assuming destination b-hg |
|
272 | 270 | initializing svn repo 'b-hg' |
|
273 | 271 | initializing svn wc 'b-hg-wc' |
@@ -33,6 +33,7 push | |||
|
33 | 33 | recover |
|
34 | 34 | remove |
|
35 | 35 | rename |
|
36 | resolve | |
|
36 | 37 | revert |
|
37 | 38 | rollback |
|
38 | 39 | root |
@@ -79,6 +80,7 debugwalk | |||
|
79 | 80 | recover |
|
80 | 81 | remove |
|
81 | 82 | rename |
|
83 | resolve | |
|
82 | 84 | revert |
|
83 | 85 | rollback |
|
84 | 86 | root |
@@ -183,6 +183,7 list of commands: | |||
|
183 | 183 | recover roll back an interrupted transaction |
|
184 | 184 | remove remove the specified files on the next commit |
|
185 | 185 | rename rename files; equivalent of copy + remove |
|
186 | resolve resolve file merges from a branch merge or update | |
|
186 | 187 | revert restore individual files or dirs to an earlier state |
|
187 | 188 | rollback roll back the last transaction |
|
188 | 189 | root print the root (top) of the current working dir |
@@ -236,6 +237,7 list of commands: | |||
|
236 | 237 | recover roll back an interrupted transaction |
|
237 | 238 | remove remove the specified files on the next commit |
|
238 | 239 | rename rename files; equivalent of copy + remove |
|
240 | resolve resolve file merges from a branch merge or update | |
|
239 | 241 | revert restore individual files or dirs to an earlier state |
|
240 | 242 | rollback roll back the last transaction |
|
241 | 243 | root print the root (top) of the current working dir |
@@ -74,6 +74,7 list of commands: | |||
|
74 | 74 | recover roll back an interrupted transaction |
|
75 | 75 | remove remove the specified files on the next commit |
|
76 | 76 | rename rename files; equivalent of copy + remove |
|
77 | resolve resolve file merges from a branch merge or update | |
|
77 | 78 | revert restore individual files or dirs to an earlier state |
|
78 | 79 | rollback roll back the last transaction |
|
79 | 80 | root print the root (top) of the current working dir |
@@ -123,6 +124,7 use "hg -v help" to show aliases and glo | |||
|
123 | 124 | recover roll back an interrupted transaction |
|
124 | 125 | remove remove the specified files on the next commit |
|
125 | 126 | rename rename files; equivalent of copy + remove |
|
127 | resolve resolve file merges from a branch merge or update | |
|
126 | 128 | revert restore individual files or dirs to an earlier state |
|
127 | 129 | rollback roll back the last transaction |
|
128 | 130 | root print the root (top) of the current working dir |
@@ -21,10 +21,7 merging zzz1_merge_ok | |||
|
21 | 21 | merging zzz2_merge_bad |
|
22 | 22 | merging zzz2_merge_bad failed! |
|
23 | 23 | 3 files updated, 1 files merged, 2 files removed, 1 files unresolved |
|
24 | There are unresolved merges with locally modified files. | |
|
25 | You can finish the partial merge using: | |
|
26 | hg update 0 | |
|
27 | hg update 1 | |
|
24 | use 'hg resolve' to retry unresolved file merges | |
|
28 | 25 | 2 files updated, 0 files merged, 3 files removed, 0 files unresolved |
|
29 | 26 | --- a/zzz1_merge_ok |
|
30 | 27 | +++ b/zzz1_merge_ok |
@@ -42,10 +39,7 merging zzz2_merge_bad | |||
|
42 | 39 | warning: conflicts during merge. |
|
43 | 40 | merging zzz2_merge_bad failed! |
|
44 | 41 | 3 files updated, 1 files merged, 2 files removed, 1 files unresolved |
|
45 | There are unresolved merges with locally modified files. | |
|
46 | You can finish the partial merge using: | |
|
47 | hg update 0 | |
|
48 | hg update 1 | |
|
42 | use 'hg resolve' to retry unresolved file merges | |
|
49 | 43 | 2 files updated, 0 files merged, 3 files removed, 0 files unresolved |
|
50 | 44 | --- a/zzz1_merge_ok |
|
51 | 45 | +++ b/zzz1_merge_ok |
@@ -13,10 +13,7 merging file1 | |||
|
13 | 13 | warning: conflicts during merge. |
|
14 | 14 | merging file1 failed! |
|
15 | 15 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
16 | There are unresolved merges with locally modified files. | |
|
17 | You can redo the full merge using: | |
|
18 | hg update 0 | |
|
19 | hg update 1 | |
|
16 | use 'hg resolve' to retry unresolved file merges | |
|
20 | 17 | diff -r f248da0d4c3e file1 |
|
21 | 18 | --- a/file1 |
|
22 | 19 | +++ b/file1 |
@@ -11,9 +11,7 merging test.txt | |||
|
11 | 11 | warning: conflicts during merge. |
|
12 | 12 | merging test.txt failed! |
|
13 | 13 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
14 | There are unresolved merges, you can redo the full merge using: | |
|
15 | hg update -C 1 | |
|
16 | hg merge 2 | |
|
14 | use 'hg resolve' to retry unresolved file merges | |
|
17 | 15 | pulling from ../test-a |
|
18 | 16 | searching for changes |
|
19 | 17 | adding changesets |
@@ -33,9 +31,7 my test.txt@451c744aabcc+ other test.txt | |||
|
33 | 31 | warning: conflicts during merge. |
|
34 | 32 | merging test.txt failed! |
|
35 | 33 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
36 | There are unresolved merges, you can redo the full merge using: | |
|
37 | hg update -C 3 | |
|
38 | hg merge 4 | |
|
34 | use 'hg resolve' to retry unresolved file merges | |
|
39 | 35 | one |
|
40 | 36 | <<<<<<< local |
|
41 | 37 | two-point-five |
@@ -23,9 +23,31 hg ci -Am 'change foo' -d '0 0' | |||
|
23 | 23 | |
|
24 | 24 | # test with the rename on the remote side |
|
25 | 25 | HGMERGE=false hg merge |
|
26 | hg resolve -l | |
|
26 | 27 | |
|
27 | 28 | # test with the rename on the local side |
|
28 | 29 | hg up -C 1 |
|
29 | 30 | HGMERGE=false hg merge |
|
30 | 31 | |
|
32 | echo % show unresolved | |
|
33 | hg resolve -l | |
|
34 | ||
|
35 | echo % unmark baz | |
|
36 | hg resolve -u baz | |
|
37 | ||
|
38 | echo % show | |
|
39 | hg resolve -l | |
|
40 | ||
|
41 | echo % re-resolve baz | |
|
42 | hg resolve baz | |
|
43 | ||
|
44 | echo % after | |
|
45 | hg resolve -l | |
|
46 | ||
|
47 | echo % resolve all | |
|
48 | hg resolve | |
|
49 | ||
|
50 | echo % after | |
|
51 | hg resolve -l | |
|
52 | ||
|
31 | 53 | true |
@@ -7,14 +7,31 merging bar | |||
|
7 | 7 | merging bar failed! |
|
8 | 8 | merging foo and baz to baz |
|
9 | 9 | 1 files updated, 1 files merged, 0 files removed, 1 files unresolved |
|
10 | There are unresolved merges, you can redo the full merge using: | |
|
11 | hg update -C 2 | |
|
12 | hg merge 1 | |
|
10 | use 'hg resolve' to retry unresolved file merges | |
|
11 | U bar | |
|
12 | R baz | |
|
13 | 13 | 3 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
14 | 14 | merging bar |
|
15 | 15 | merging bar failed! |
|
16 | 16 | merging baz and foo to baz |
|
17 | 17 | 1 files updated, 1 files merged, 0 files removed, 1 files unresolved |
|
18 | There are unresolved merges, you can redo the full merge using: | |
|
19 | hg update -C 1 | |
|
20 | hg merge 2 | |
|
18 | use 'hg resolve' to retry unresolved file merges | |
|
19 | % show unresolved | |
|
20 | U bar | |
|
21 | R baz | |
|
22 | % unmark baz | |
|
23 | % show | |
|
24 | U bar | |
|
25 | U baz | |
|
26 | % re-resolve baz | |
|
27 | merging baz and foo to baz | |
|
28 | % after | |
|
29 | U bar | |
|
30 | R baz | |
|
31 | % resolve all | |
|
32 | merging bar | |
|
33 | warning: conflicts during merge. | |
|
34 | merging bar failed! | |
|
35 | % after | |
|
36 | U bar | |
|
37 | R baz |
General Comments 0
You need to be logged in to leave comments.
Login now