Show More
@@ -0,0 +1,45 b'' | |||
|
1 | #!/bin/sh | |
|
2 | # http://www.selenic.com/mercurial/bts/issue322 | |
|
3 | ||
|
4 | echo % file replaced with directory | |
|
5 | ||
|
6 | hg init a | |
|
7 | cd a | |
|
8 | echo a > a | |
|
9 | hg commit -Ama | |
|
10 | rm a | |
|
11 | mkdir a | |
|
12 | echo a > a/a | |
|
13 | ||
|
14 | echo % should fail - would corrupt dirstate | |
|
15 | hg add a/a | |
|
16 | ||
|
17 | echo % should fail - if add succeeded, would corrupt manifest | |
|
18 | hg commit -mb | |
|
19 | ||
|
20 | echo % should fail if commit succeeded - manifest is corrupt | |
|
21 | hg verify | |
|
22 | ||
|
23 | cd .. | |
|
24 | echo % should succeed, but manifest is corrupt | |
|
25 | hg --debug --traceback clone a b | |
|
26 | ||
|
27 | echo % directory replaced with file | |
|
28 | ||
|
29 | hg init c | |
|
30 | cd c | |
|
31 | mkdir a | |
|
32 | echo a > a/a | |
|
33 | hg commit -Ama | |
|
34 | ||
|
35 | rm -rf a | |
|
36 | echo a > a | |
|
37 | ||
|
38 | echo % should fail - would corrupt dirstate | |
|
39 | hg add a | |
|
40 | ||
|
41 | echo % should fail - if add succeeded, would corrupt manifest | |
|
42 | hg commit -mb a | |
|
43 | ||
|
44 | echo % should fail if commit succeeded - manifest is corrupt | |
|
45 | hg verify |
@@ -4,6 +4,7 b' Goffredo Baroncelli <kreijack at libero.' | |||
|
4 | 4 | Muli Ben-Yehuda <mulix at mulix.org> |
|
5 | 5 | Mikael Berthe <mikael at lilotux.net> |
|
6 | 6 | Benoit Boissinot <bboissin at gmail.com> |
|
7 | Brendan Cully <brendan at kublai.com> | |
|
7 | 8 | Vincent Danjean <vdanjean.ml at free.fr> |
|
8 | 9 | Jake Edge <jake at edge2.net> |
|
9 | 10 | Michael Fetterman <michael.fetterman at intel.com> |
@@ -252,6 +252,9 b' class queue:' | |||
|
252 | 252 | |
|
253 | 253 | for line in file(pf): |
|
254 | 254 | line = line.rstrip() |
|
255 | if line.startswith('diff --git'): | |
|
256 | diffstart = 2 | |
|
257 | break | |
|
255 | 258 | if diffstart: |
|
256 | 259 | if line.startswith('+++ '): |
|
257 | 260 | diffstart = 2 |
@@ -298,8 +301,10 b' class queue:' | |||
|
298 | 301 | return (message, comments, user, date, diffstart > 1) |
|
299 | 302 | |
|
300 | 303 | def printdiff(self, repo, node1, node2=None, files=None, |
|
301 |
fp=None, changes=None, opts= |
|
|
302 | patch.diff(repo, node1, node2, files, | |
|
304 | fp=None, changes=None, opts={}): | |
|
305 | fns, matchfn, anypats = cmdutil.matchpats(repo, files, opts) | |
|
306 | ||
|
307 | patch.diff(repo, node1, node2, fns, match=matchfn, | |
|
303 | 308 | fp=fp, changes=changes, opts=self.diffopts()) |
|
304 | 309 | |
|
305 | 310 | def mergeone(self, repo, mergeq, head, patch, rev, wlock): |
@@ -408,7 +413,7 b' class queue:' | |||
|
408 | 413 | self.ui.warn("patch failed, unable to continue (try -v)\n") |
|
409 | 414 | return (False, [], False) |
|
410 | 415 | |
|
411 |
return (True, files |
|
|
416 | return (True, files, fuzz) | |
|
412 | 417 | |
|
413 | 418 | def apply(self, repo, series, list=False, update_status=True, |
|
414 | 419 | strict=False, patchdir=None, merge=None, wlock=None): |
@@ -421,42 +426,37 b' class queue:' | |||
|
421 | 426 | lock = repo.lock() |
|
422 | 427 | tr = repo.transaction() |
|
423 | 428 | n = None |
|
424 | for patch in series: | |
|
425 | pushable, reason = self.pushable(patch) | |
|
429 | for patchname in series: | |
|
430 | pushable, reason = self.pushable(patchname) | |
|
426 | 431 | if not pushable: |
|
427 | self.explain_pushable(patch, all_patches=True) | |
|
432 | self.explain_pushable(patchname, all_patches=True) | |
|
428 | 433 | continue |
|
429 | self.ui.warn("applying %s\n" % patch) | |
|
430 | pf = os.path.join(patchdir, patch) | |
|
434 | self.ui.warn("applying %s\n" % patchname) | |
|
435 | pf = os.path.join(patchdir, patchname) | |
|
431 | 436 | |
|
432 | 437 | try: |
|
433 | message, comments, user, date, patchfound = self.readheaders(patch) | |
|
438 | message, comments, user, date, patchfound = self.readheaders(patchname) | |
|
434 | 439 | except: |
|
435 |
self.ui.warn("Unable to read %s\n" % p |
|
|
440 | self.ui.warn("Unable to read %s\n" % patchname) | |
|
436 | 441 | err = 1 |
|
437 | 442 | break |
|
438 | 443 | |
|
439 | 444 | if not message: |
|
440 | message = "imported patch %s\n" % patch | |
|
445 | message = "imported patch %s\n" % patchname | |
|
441 | 446 | else: |
|
442 | 447 | if list: |
|
443 | message.append("\nimported patch %s" % patch) | |
|
448 | message.append("\nimported patch %s" % patchname) | |
|
444 | 449 | message = '\n'.join(message) |
|
445 | 450 | |
|
446 | 451 | (patcherr, files, fuzz) = self.patch(repo, pf) |
|
447 | 452 | patcherr = not patcherr |
|
448 | 453 | |
|
449 |
if merge and |
|
|
454 | if merge and files: | |
|
450 | 455 | # Mark as merged and update dirstate parent info |
|
451 | repo.dirstate.update(repo.dirstate.filterfiles(files), 'm') | |
|
456 | repo.dirstate.update(repo.dirstate.filterfiles(files.keys()), 'm') | |
|
452 | 457 | p1, p2 = repo.dirstate.parents() |
|
453 | 458 | repo.dirstate.setparents(p1, merge) |
|
454 | if len(files) > 0: | |
|
455 | cwd = repo.getcwd() | |
|
456 | cfiles = files | |
|
457 | if cwd: | |
|
458 | cfiles = [util.pathto(cwd, f) for f in files] | |
|
459 | cmdutil.addremove(repo, cfiles, wlock=wlock) | |
|
459 | files = patch.updatedir(self.ui, repo, files, wlock=wlock) | |
|
460 | 460 | n = repo.commit(files, message, user, date, force=1, lock=lock, |
|
461 | 461 | wlock=wlock) |
|
462 | 462 | |
@@ -464,11 +464,11 b' class queue:' | |||
|
464 | 464 | raise util.Abort(_("repo commit failed")) |
|
465 | 465 | |
|
466 | 466 | if update_status: |
|
467 | self.applied.append(statusentry(revlog.hex(n), patch)) | |
|
467 | self.applied.append(statusentry(revlog.hex(n), patchname)) | |
|
468 | 468 | |
|
469 | 469 | if patcherr: |
|
470 | 470 | if not patchfound: |
|
471 | self.ui.warn("patch %s is empty\n" % patch) | |
|
471 | self.ui.warn("patch %s is empty\n" % patchname) | |
|
472 | 472 | err = 0 |
|
473 | 473 | else: |
|
474 | 474 | self.ui.warn("patch failed, rejects left in working dir\n") |
@@ -904,15 +904,15 b' class queue:' | |||
|
904 | 904 | else: |
|
905 | 905 | self.ui.write("Patch queue now empty\n") |
|
906 | 906 | |
|
907 |
def diff(self, repo, |
|
|
907 | def diff(self, repo, pats, opts): | |
|
908 | 908 | top = self.check_toppatch(repo) |
|
909 | 909 | if not top: |
|
910 | 910 | self.ui.write("No patches applied\n") |
|
911 | 911 | return |
|
912 | 912 | qp = self.qparents(repo, top) |
|
913 |
self.printdiff(repo, qp, files= |
|
|
913 | self.printdiff(repo, qp, files=pats, opts=opts) | |
|
914 | 914 | |
|
915 |
def refresh(self, repo, |
|
|
915 | def refresh(self, repo, pats=None, **opts): | |
|
916 | 916 | if len(self.applied) == 0: |
|
917 | 917 | self.ui.write("No patches applied\n") |
|
918 | 918 | return |
@@ -925,7 +925,7 b' class queue:' | |||
|
925 | 925 | message, comments, user, date, patchfound = self.readheaders(patch) |
|
926 | 926 | |
|
927 | 927 | patchf = self.opener(patch, "w") |
|
928 | msg = msg.rstrip() | |
|
928 | msg = opts.get('msg', '').rstrip() | |
|
929 | 929 | if msg: |
|
930 | 930 | if comments: |
|
931 | 931 | # Remove existing message. |
@@ -939,6 +939,7 b' class queue:' | |||
|
939 | 939 | comments = "\n".join(comments) + '\n\n' |
|
940 | 940 | patchf.write(comments) |
|
941 | 941 | |
|
942 | fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
|
942 | 943 | tip = repo.changelog.tip() |
|
943 | 944 | if top == tip: |
|
944 | 945 | # if the top of our patch queue is also the tip, there is an |
@@ -956,7 +957,7 b' class queue:' | |||
|
956 | 957 | # caching against the next repo.status call |
|
957 | 958 | # |
|
958 | 959 | mm, aa, dd, aa2, uu = repo.status(patchparent, tip)[:5] |
|
959 | if short: | |
|
960 | if opts.get('short'): | |
|
960 | 961 | filelist = mm + aa + dd |
|
961 | 962 | else: |
|
962 | 963 | filelist = None |
@@ -992,16 +993,27 b' class queue:' | |||
|
992 | 993 | m = list(util.unique(mm)) |
|
993 | 994 | r = list(util.unique(dd)) |
|
994 | 995 | a = list(util.unique(aa)) |
|
995 |
filelist = |
|
|
996 | filelist = filter(matchfn, util.unique(m + r + a)) | |
|
996 | 997 | self.printdiff(repo, patchparent, files=filelist, |
|
997 | 998 | changes=(m, a, r, [], u), fp=patchf) |
|
998 | 999 | patchf.close() |
|
999 | 1000 | |
|
1000 | 1001 | changes = repo.changelog.read(tip) |
|
1001 | 1002 | repo.dirstate.setparents(*cparents) |
|
1003 | copies = [(f, repo.dirstate.copied(f)) for f in a] | |
|
1002 | 1004 | repo.dirstate.update(a, 'a') |
|
1005 | for dst, src in copies: | |
|
1006 | repo.dirstate.copy(src, dst) | |
|
1003 | 1007 | repo.dirstate.update(r, 'r') |
|
1008 | # if the patch excludes a modified file, mark that file with mtime=0 | |
|
1009 | # so status can see it. | |
|
1010 | mm = [] | |
|
1011 | for i in range(len(m)-1, -1, -1): | |
|
1012 | if not matchfn(m[i]): | |
|
1013 | mm.append(m[i]) | |
|
1014 | del m[i] | |
|
1004 | 1015 | repo.dirstate.update(m, 'n') |
|
1016 | repo.dirstate.update(mm, 'n', st_mtime=0) | |
|
1005 | 1017 | repo.dirstate.forget(forget) |
|
1006 | 1018 | |
|
1007 | 1019 | if not msg: |
@@ -1216,7 +1228,7 b' class queue:' | |||
|
1216 | 1228 | if not self.ui.verbose: |
|
1217 | 1229 | p = pname |
|
1218 | 1230 | else: |
|
1219 | p = str(self.series.index(pname)) + " " + p | |
|
1231 | p = str(self.series.index(pname)) + " " + pname | |
|
1220 | 1232 | return p |
|
1221 | 1233 | |
|
1222 | 1234 | def top(self, repo): |
@@ -1411,17 +1423,24 b' def new(ui, repo, patch, **opts):' | |||
|
1411 | 1423 | changes unless -f is specified, in which case the patch will |
|
1412 | 1424 | be initialised with them. |
|
1413 | 1425 | |
|
1414 | -m or -l set the patch header as well as the commit message. | |
|
1415 |
If ne |
|
|
1426 | -e, -m or -l set the patch header as well as the commit message. | |
|
1427 | If none is specified, the patch header is empty and the | |
|
1416 | 1428 | commit message is 'New patch: PATCH'""" |
|
1417 | 1429 | q = repo.mq |
|
1418 | 1430 | message = commands.logmessage(opts) |
|
1431 | if opts['edit']: | |
|
1432 | message = ui.edit(message, ui.username()) | |
|
1419 | 1433 | q.new(repo, patch, msg=message, force=opts['force']) |
|
1420 | 1434 | q.save_dirty() |
|
1421 | 1435 | return 0 |
|
1422 | 1436 | |
|
1423 | def refresh(ui, repo, **opts): | |
|
1424 |
"""update the current patch |
|
|
1437 | def refresh(ui, repo, *pats, **opts): | |
|
1438 | """update the current patch | |
|
1439 | ||
|
1440 | If any file patterns are provided, the refreshed patch will contain only | |
|
1441 | the modifications that match those patterns; the remaining modifications | |
|
1442 | will remain in the working directory. | |
|
1443 | """ | |
|
1425 | 1444 | q = repo.mq |
|
1426 | 1445 | message = commands.logmessage(opts) |
|
1427 | 1446 | if opts['edit']: |
@@ -1430,14 +1449,13 b' def refresh(ui, repo, **opts):' | |||
|
1430 | 1449 | patch = q.applied[-1].name |
|
1431 | 1450 | (message, comment, user, date, hasdiff) = q.readheaders(patch) |
|
1432 | 1451 | message = ui.edit('\n'.join(message), user or ui.username()) |
|
1433 |
q.refresh(repo, msg=message, |
|
|
1452 | q.refresh(repo, pats, msg=message, **opts) | |
|
1434 | 1453 | q.save_dirty() |
|
1435 | 1454 | return 0 |
|
1436 | 1455 | |
|
1437 |
def diff(ui, repo, * |
|
|
1456 | def diff(ui, repo, *pats, **opts): | |
|
1438 | 1457 | """diff of the current patch""" |
|
1439 | # deep in the dirstate code, the walkhelper method wants a list, not a tuple | |
|
1440 | repo.mq.diff(repo, list(files)) | |
|
1458 | repo.mq.diff(repo, pats, opts) | |
|
1441 | 1459 | return 0 |
|
1442 | 1460 | |
|
1443 | 1461 | def fold(ui, repo, *files, **opts): |
@@ -1469,20 +1487,21 b' def fold(ui, repo, *files, **opts):' | |||
|
1469 | 1487 | patches = [] |
|
1470 | 1488 | messages = [] |
|
1471 | 1489 | for f in files: |
|
1472 |
p |
|
|
1473 |
if p |
|
|
1474 |
ui.warn(_('Skipping already folded patch %s') % p |
|
|
1475 |
if q.isapplied(p |
|
|
1476 |
raise util.Abort(_('qfold cannot fold already applied patch %s') % p |
|
|
1477 |
patches.append(p |
|
|
1490 | p = q.lookup(f) | |
|
1491 | if p in patches or p == parent: | |
|
1492 | ui.warn(_('Skipping already folded patch %s') % p) | |
|
1493 | if q.isapplied(p): | |
|
1494 | raise util.Abort(_('qfold cannot fold already applied patch %s') % p) | |
|
1495 | patches.append(p) | |
|
1478 | 1496 | |
|
1479 |
for p |
|
|
1497 | for p in patches: | |
|
1480 | 1498 | if not message: |
|
1481 |
messages.append(q.readheaders(p |
|
|
1482 |
pf = q.join(p |
|
|
1499 | messages.append(q.readheaders(p)[0]) | |
|
1500 | pf = q.join(p) | |
|
1483 | 1501 | (patchsuccess, files, fuzz) = q.patch(repo, pf) |
|
1484 | 1502 | if not patchsuccess: |
|
1485 |
raise util.Abort(_('Error folding patch %s') % p |
|
|
1503 | raise util.Abort(_('Error folding patch %s') % p) | |
|
1504 | patch.updatedir(ui, repo, files) | |
|
1486 | 1505 | |
|
1487 | 1506 | if not message: |
|
1488 | 1507 | message, comments, user = q.readheaders(parent)[0:3] |
@@ -1495,29 +1514,26 b' def fold(ui, repo, *files, **opts):' | |||
|
1495 | 1514 | message = ui.edit(message, user or ui.username()) |
|
1496 | 1515 | |
|
1497 | 1516 | q.refresh(repo, msg=message) |
|
1498 | ||
|
1499 | for patch in patches: | |
|
1500 | q.delete(repo, patch, keep=opts['keep']) | |
|
1501 | ||
|
1517 | q.delete(repo, patches, keep=opts['keep']) | |
|
1502 | 1518 | q.save_dirty() |
|
1503 | 1519 | |
|
1504 | 1520 | def guard(ui, repo, *args, **opts): |
|
1505 | 1521 | '''set or print guards for a patch |
|
1506 | 1522 | |
|
1507 |
|
|
|
1508 |
guards is aways pushed. |
|
|
1509 |
pushed only if qselect command |
|
|
1510 |
|
|
|
1511 | guard "foo". | |
|
1523 | Guards control whether a patch can be pushed. A patch with no | |
|
1524 | guards is always pushed. A patch with a positive guard ("+foo") is | |
|
1525 | pushed only if the qselect command has activated it. A patch with | |
|
1526 | a negative guard ("-foo") is never pushed if the qselect command | |
|
1527 | has activated it. | |
|
1512 | 1528 | |
|
1513 |
|
|
|
1514 |
|
|
|
1529 | With no arguments, print the currently active guards. | |
|
1530 | With arguments, set guards for the named patch. | |
|
1515 | 1531 | |
|
1516 |
|
|
|
1517 |
hg will not interpret "-foo" as a |
|
|
1532 | To set a negative guard "-foo" on topmost patch ("--" is needed so | |
|
1533 | hg will not interpret "-foo" as an option): | |
|
1518 | 1534 | hg qguard -- -foo |
|
1519 | 1535 | |
|
1520 |
|
|
|
1536 | To set guards on another patch: | |
|
1521 | 1537 | hg qguard other.patch +2.6.17 -stable |
|
1522 | 1538 | ''' |
|
1523 | 1539 | def status(idx): |
@@ -1723,32 +1739,34 b' def strip(ui, repo, rev, **opts):' | |||
|
1723 | 1739 | def select(ui, repo, *args, **opts): |
|
1724 | 1740 | '''set or print guarded patches to push |
|
1725 | 1741 | |
|
1726 |
|
|
|
1727 |
qselect to tell mq which guards to use. |
|
|
1742 | Use the qguard command to set or print guards on patch, then use | |
|
1743 | qselect to tell mq which guards to use. A patch will be pushed if it | |
|
1744 | has no guards or any positive guards match the currently selected guard, | |
|
1745 | but will not be pushed if any negative guards match the current guard. | |
|
1746 | For example: | |
|
1728 | 1747 | |
|
1729 |
qguard foo.patch -stable (n |
|
|
1730 |
qguard bar.patch +stable (pos |
|
|
1748 | qguard foo.patch -stable (negative guard) | |
|
1749 | qguard bar.patch +stable (positive guard) | |
|
1731 | 1750 | qselect stable |
|
1732 | 1751 | |
|
1733 |
|
|
|
1734 |
|
|
|
1735 | match). patch is pushed if any posative guards match and no | |
|
1736 | nagative guards match. | |
|
1752 | This activates the "stable" guard. mq will skip foo.patch (because | |
|
1753 | it has a negative match) but push bar.patch (because it | |
|
1754 | has a positive match). | |
|
1737 | 1755 | |
|
1738 |
|
|
|
1739 |
|
|
|
1756 | With no arguments, prints the currently active guards. | |
|
1757 | With one argument, sets the active guard. | |
|
1740 | 1758 | |
|
1741 |
|
|
|
1742 |
|
|
|
1743 |
patches with n |
|
|
1759 | Use -n/--none to deactivate guards (no other arguments needed). | |
|
1760 | When no guards are active, patches with positive guards are skipped | |
|
1761 | and patches with negative guards are pushed. | |
|
1744 | 1762 | |
|
1745 |
qselect can change guards o |
|
|
1746 |
guarded patches by default. |
|
|
1747 |
patch that is not guarded. |
|
|
1748 | back to current patch afterwards, but skip guarded patches. | |
|
1763 | qselect can change the guards on applied patches. It does not pop | |
|
1764 | guarded patches by default. Use --pop to pop back to the last applied | |
|
1765 | patch that is not guarded. Use --reapply (which implies --pop) to push | |
|
1766 | back to the current patch afterwards, but skip guarded patches. | |
|
1749 | 1767 | |
|
1750 |
|
|
|
1751 |
other arguments needed). |
|
|
1768 | Use -s/--series to print a list of all guards in the series file (no | |
|
1769 | other arguments needed). Use -v for more information.''' | |
|
1752 | 1770 | |
|
1753 | 1771 | q = repo.mq |
|
1754 | 1772 | guards = q.active() |
@@ -1885,7 +1903,10 b' cmdtable = {' | |||
|
1885 | 1903 | (commit, |
|
1886 | 1904 | commands.table["^commit|ci"][1], |
|
1887 | 1905 | 'hg qcommit [OPTION]... [FILE]...'), |
|
1888 | "^qdiff": (diff, [], 'hg qdiff [FILE]...'), | |
|
1906 | "^qdiff": (diff, | |
|
1907 | [('I', 'include', [], _('include names matching the given patterns')), | |
|
1908 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], | |
|
1909 | 'hg qdiff [-I] [-X] [FILE]...'), | |
|
1889 | 1910 | "qdelete|qremove|qrm": |
|
1890 | 1911 | (delete, |
|
1891 | 1912 | [('k', 'keep', None, _('keep patch file'))], |
@@ -1914,10 +1935,11 b' cmdtable = {' | |||
|
1914 | 1935 | 'hg qinit [-c]'), |
|
1915 | 1936 | "qnew": |
|
1916 | 1937 | (new, |
|
1917 |
[(' |
|
|
1938 | [('e', 'edit', None, _('edit commit message')), | |
|
1939 | ('m', 'message', '', _('use <text> as commit message')), | |
|
1918 | 1940 | ('l', 'logfile', '', _('read the commit message from <file>')), |
|
1919 | 1941 | ('f', 'force', None, _('import uncommitted changes into patch'))], |
|
1920 | 'hg qnew [-m TEXT] [-l FILE] [-f] PATCH'), | |
|
1942 | 'hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH'), | |
|
1921 | 1943 | "qnext": (next, [], 'hg qnext'), |
|
1922 | 1944 | "qprev": (prev, [], 'hg qprev'), |
|
1923 | 1945 | "^qpop": |
@@ -1939,8 +1961,10 b' cmdtable = {' | |||
|
1939 | 1961 | [('e', 'edit', None, _('edit commit message')), |
|
1940 | 1962 | ('m', 'message', '', _('change commit message with <text>')), |
|
1941 | 1963 | ('l', 'logfile', '', _('change commit message with <file> content')), |
|
1942 |
('s', 'short', None, 'short refresh') |
|
|
1943 | 'hg qrefresh [-e] [-m TEXT] [-l FILE] [-s]'), | |
|
1964 | ('s', 'short', None, 'short refresh'), | |
|
1965 | ('I', 'include', [], _('include names matching the given patterns')), | |
|
1966 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], | |
|
1967 | 'hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] FILES...'), | |
|
1944 | 1968 | 'qrename|qmv': |
|
1945 | 1969 | (rename, [], 'hg qrename PATCH1 [PATCH2]'), |
|
1946 | 1970 | "qrestore": |
@@ -1526,7 +1526,6 b' def grep(ui, repo, pattern, *pats, **opt' | |||
|
1526 | 1526 | if st == 'window': |
|
1527 | 1527 | incrementing = rev |
|
1528 | 1528 | matches.clear() |
|
1529 | copies.clear() | |
|
1530 | 1529 | elif st == 'add': |
|
1531 | 1530 | change = repo.changelog.read(repo.lookup(str(rev))) |
|
1532 | 1531 | mf = repo.manifest.read(change[0]) |
@@ -1535,20 +1534,19 b' def grep(ui, repo, pattern, *pats, **opt' | |||
|
1535 | 1534 | if fn in skip: |
|
1536 | 1535 | continue |
|
1537 | 1536 | fstate.setdefault(fn, {}) |
|
1538 | copies.setdefault(rev, {}) | |
|
1539 | 1537 | try: |
|
1540 | 1538 | grepbody(fn, rev, getfile(fn).read(mf[fn])) |
|
1541 | 1539 | if follow: |
|
1542 | 1540 | copied = getfile(fn).renamed(mf[fn]) |
|
1543 | 1541 | if copied: |
|
1544 |
copies |
|
|
1542 | copies.setdefault(rev, {})[fn] = copied[0] | |
|
1545 | 1543 | except KeyError: |
|
1546 | 1544 | pass |
|
1547 | 1545 | elif st == 'iter': |
|
1548 | 1546 | states = matches[rev].items() |
|
1549 | 1547 | states.sort() |
|
1550 | 1548 | for fn, m in states: |
|
1551 |
copy = copies |
|
|
1549 | copy = copies.get(rev, {}).get(fn) | |
|
1552 | 1550 | if fn in skip: |
|
1553 | 1551 | if copy: |
|
1554 | 1552 | skip[copy] = True |
@@ -1571,7 +1569,7 b' def grep(ui, repo, pattern, *pats, **opt' | |||
|
1571 | 1569 | for fn, state in fstate: |
|
1572 | 1570 | if fn in skip: |
|
1573 | 1571 | continue |
|
1574 |
if fn not in copies |
|
|
1572 | if fn not in copies.get(prev[fn], {}): | |
|
1575 | 1573 | display(fn, rev, {}, state) |
|
1576 | 1574 | return (count == 0 and 1) or 0 |
|
1577 | 1575 | |
@@ -1683,44 +1681,7 b' def import_(ui, repo, patch1, *patches, ' | |||
|
1683 | 1681 | ui.debug(_('message:\n%s\n') % message) |
|
1684 | 1682 | |
|
1685 | 1683 | files, fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root) |
|
1686 | removes = [] | |
|
1687 | if len(files) > 0: | |
|
1688 | cfiles = files.keys() | |
|
1689 | copies = [] | |
|
1690 | copts = {'after': False, 'force': False} | |
|
1691 | cwd = repo.getcwd() | |
|
1692 | if cwd: | |
|
1693 | cfiles = [util.pathto(cwd, f) for f in files.keys()] | |
|
1694 | for f in files: | |
|
1695 | ctype, gp = files[f] | |
|
1696 | if ctype == 'RENAME': | |
|
1697 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |
|
1698 | removes.append(gp.oldpath) | |
|
1699 | elif ctype == 'COPY': | |
|
1700 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |
|
1701 | elif ctype == 'DELETE': | |
|
1702 | removes.append(gp.path) | |
|
1703 | for src, dst, after in copies: | |
|
1704 | absdst = os.path.join(repo.root, dst) | |
|
1705 | if not after and os.path.exists(absdst): | |
|
1706 | raise util.Abort(_('patch creates existing file %s') % dst) | |
|
1707 | if cwd: | |
|
1708 | src, dst = [util.pathto(cwd, f) for f in (src, dst)] | |
|
1709 | copts['after'] = after | |
|
1710 | errs, copied = docopy(ui, repo, (src, dst), copts, wlock=wlock) | |
|
1711 | if errs: | |
|
1712 | raise util.Abort(errs) | |
|
1713 | if removes: | |
|
1714 | repo.remove(removes, True, wlock=wlock) | |
|
1715 | for f in files: | |
|
1716 | ctype, gp = files[f] | |
|
1717 | if gp and gp.mode: | |
|
1718 | x = gp.mode & 0100 != 0 | |
|
1719 | dst = os.path.join(repo.root, gp.path) | |
|
1720 | util.set_exec(dst, x) | |
|
1721 | cmdutil.addremove(repo, cfiles, wlock=wlock) | |
|
1722 | files = files.keys() | |
|
1723 | files.extend([r for r in removes if r not in files]) | |
|
1684 | files = patch.updatedir(ui, repo, files, wlock=wlock) | |
|
1724 | 1685 | repo.commit(files, message, user, date, wlock=wlock, lock=lock) |
|
1725 | 1686 | finally: |
|
1726 | 1687 | os.unlink(tmpname) |
@@ -3281,18 +3242,11 b' def findext(name):' | |||
|
3281 | 3242 | return sys.modules[v] |
|
3282 | 3243 | raise KeyError(name) |
|
3283 | 3244 | |
|
3284 | def dispatch(args): | |
|
3285 | for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': | |
|
3286 | num = getattr(signal, name, None) | |
|
3287 | if num: signal.signal(num, catchterm) | |
|
3288 | ||
|
3289 | try: | |
|
3290 | u = ui.ui(traceback='--traceback' in sys.argv[1:]) | |
|
3291 | except util.Abort, inst: | |
|
3292 | sys.stderr.write(_("abort: %s\n") % inst) | |
|
3293 | return -1 | |
|
3294 | ||
|
3295 | for ext_name, load_from_name in u.extensions(): | |
|
3245 | def load_extensions(ui): | |
|
3246 | added = [] | |
|
3247 | for ext_name, load_from_name in ui.extensions(): | |
|
3248 | if ext_name in external: | |
|
3249 | continue | |
|
3296 | 3250 | try: |
|
3297 | 3251 | if load_from_name: |
|
3298 | 3252 | # the module will be loaded in sys.modules |
@@ -3312,23 +3266,36 b' def dispatch(args):' | |||
|
3312 | 3266 | except ImportError: |
|
3313 | 3267 | mod = importh(ext_name) |
|
3314 | 3268 | external[ext_name] = mod.__name__ |
|
3269 | added.append((mod, ext_name)) | |
|
3315 | 3270 | except (util.SignalInterrupt, KeyboardInterrupt): |
|
3316 | 3271 | raise |
|
3317 | 3272 | except Exception, inst: |
|
3318 |
u.warn(_("*** failed to import extension %s: %s\n") % |
|
|
3319 | if u.print_exc(): | |
|
3273 | ui.warn(_("*** failed to import extension %s: %s\n") % | |
|
3274 | (ext_name, inst)) | |
|
3275 | if ui.print_exc(): | |
|
3320 | 3276 | return 1 |
|
3321 | 3277 | |
|
3322 | for name in external.itervalues(): | |
|
3323 | mod = sys.modules[name] | |
|
3278 | for mod, name in added: | |
|
3324 | 3279 | uisetup = getattr(mod, 'uisetup', None) |
|
3325 | 3280 | if uisetup: |
|
3326 | uisetup(u) | |
|
3281 | uisetup(ui) | |
|
3327 | 3282 | cmdtable = getattr(mod, 'cmdtable', {}) |
|
3328 | 3283 | for t in cmdtable: |
|
3329 | 3284 | if t in table: |
|
3330 | u.warn(_("module %s overrides %s\n") % (name, t)) | |
|
3285 | ui.warn(_("module %s overrides %s\n") % (name, t)) | |
|
3331 | 3286 | table.update(cmdtable) |
|
3287 | ||
|
3288 | def dispatch(args): | |
|
3289 | for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': | |
|
3290 | num = getattr(signal, name, None) | |
|
3291 | if num: signal.signal(num, catchterm) | |
|
3292 | ||
|
3293 | try: | |
|
3294 | u = ui.ui(traceback='--traceback' in sys.argv[1:], | |
|
3295 | readhooks=[load_extensions]) | |
|
3296 | except util.Abort, inst: | |
|
3297 | sys.stderr.write(_("abort: %s\n") % inst) | |
|
3298 | return -1 | |
|
3332 | 3299 | |
|
3333 | 3300 | try: |
|
3334 | 3301 | cmd, func, args, options, cmdoptions = parse(u, args) |
@@ -96,31 +96,59 b' class filelog(revlog):' | |||
|
96 | 96 | return child |
|
97 | 97 | |
|
98 | 98 | # find all ancestors |
|
99 | needed = {node:1} | |
|
100 |
|
|
|
99 | needed = {(self, node):1} | |
|
100 | files = [self] | |
|
101 | visit = [(self, node)] | |
|
101 | 102 | while visit: |
|
102 | n = visit.pop(0) | |
|
103 |
|
|
|
104 |
|
|
|
105 |
|
|
|
106 | visit.append(p) | |
|
103 | f, n = visit.pop(0) | |
|
104 | rn = f.renamed(n) | |
|
105 | if rn: | |
|
106 | f, n = rn | |
|
107 | f = filelog(self.opener, f, self.defversion) | |
|
108 | files.insert(0, f) | |
|
109 | if (f, n) not in needed: | |
|
110 | needed[(f, n)] = 1 | |
|
111 | else: | |
|
112 | needed[(f, n)] += 1 | |
|
113 | for p in f.parents(n): | |
|
114 | if p == nullid: | |
|
115 | continue | |
|
116 | if (f, p) not in needed: | |
|
117 | needed[(f, p)] = 1 | |
|
118 | visit.append((f, p)) | |
|
107 | 119 | else: |
|
108 | 120 | # count how many times we'll use this |
|
109 | needed[p] += 1 | |
|
121 | needed[(f, p)] += 1 | |
|
110 | 122 | |
|
111 | # sort by revision which is a topological order | |
|
112 | visit = [ (self.rev(n), n) for n in needed.keys() ] | |
|
113 | visit.sort() | |
|
123 | # sort by revision (per file) which is a topological order | |
|
124 | visit = [] | |
|
125 | for f in files: | |
|
126 | fn = [(f.rev(n[1]), f, n[1]) for n in needed.keys() if n[0] == f] | |
|
127 | fn.sort() | |
|
128 | visit.extend(fn) | |
|
114 | 129 | hist = {} |
|
115 | 130 | |
|
116 |
for |
|
|
117 | curr = decorate(self.read(n), self.linkrev(n)) | |
|
118 | for p in self.parents(n): | |
|
131 | for i in range(len(visit)): | |
|
132 | r, f, n = visit[i] | |
|
133 | curr = decorate(f.read(n), f.linkrev(n)) | |
|
134 | if r == -1: | |
|
135 | continue | |
|
136 | parents = f.parents(n) | |
|
137 | # follow parents across renames | |
|
138 | if r < 1 and i > 0: | |
|
139 | j = i | |
|
140 | while j > 0 and visit[j][1] == f: | |
|
141 | j -= 1 | |
|
142 | parents = (visit[j][2],) | |
|
143 | f = visit[j][1] | |
|
144 | else: | |
|
145 | parents = f.parents(n) | |
|
146 | for p in parents: | |
|
119 | 147 | if p != nullid: |
|
120 | 148 | curr = pair(hist[p], curr) |
|
121 | 149 | # trim the history of unneeded revs |
|
122 | needed[p] -= 1 | |
|
123 | if not needed[p]: | |
|
150 | needed[(f, p)] -= 1 | |
|
151 | if not needed[(f, p)]: | |
|
124 | 152 | del hist[p] |
|
125 | 153 | hist[n] = curr |
|
126 | 154 |
@@ -11,6 +11,28 b' from node import *' | |||
|
11 | 11 | demandload(globals(), "cmdutil mdiff util") |
|
12 | 12 | demandload(globals(), "cStringIO email.Parser errno os re shutil sys tempfile") |
|
13 | 13 | |
|
14 | # helper functions | |
|
15 | ||
|
16 | def copyfile(src, dst, basedir=None): | |
|
17 | if not basedir: | |
|
18 | basedir = os.getcwd() | |
|
19 | ||
|
20 | abssrc, absdst = [os.path.join(basedir, n) for n in (src, dst)] | |
|
21 | if os.path.exists(absdst): | |
|
22 | raise util.Abort(_("cannot create %s: destination already exists") % | |
|
23 | dst) | |
|
24 | ||
|
25 | targetdir = os.path.dirname(absdst) | |
|
26 | if not os.path.isdir(targetdir): | |
|
27 | os.makedirs(targetdir) | |
|
28 | try: | |
|
29 | shutil.copyfile(abssrc, absdst) | |
|
30 | shutil.copymode(abssrc, absdst) | |
|
31 | except shutil.Error, inst: | |
|
32 | raise util.Abort(str(inst)) | |
|
33 | ||
|
34 | # public functions | |
|
35 | ||
|
14 | 36 | def extract(ui, fileobj): |
|
15 | 37 | '''extract patch from data read from fileobj. |
|
16 | 38 | |
@@ -174,21 +196,7 b' def dogitpatch(patchname, gitpatches):' | |||
|
174 | 196 | if not p.copymod: |
|
175 | 197 | continue |
|
176 | 198 | |
|
177 |
|
|
|
178 | raise util.Abort(_("cannot create %s: destination already exists") % | |
|
179 | p.path) | |
|
180 | ||
|
181 | (src, dst) = [os.path.join(os.getcwd(), n) | |
|
182 | for n in (p.oldpath, p.path)] | |
|
183 | ||
|
184 | targetdir = os.path.dirname(dst) | |
|
185 | if not os.path.isdir(targetdir): | |
|
186 | os.makedirs(targetdir) | |
|
187 | try: | |
|
188 | shutil.copyfile(src, dst) | |
|
189 | shutil.copymode(src, dst) | |
|
190 | except shutil.Error, inst: | |
|
191 | raise util.Abort(str(inst)) | |
|
199 | copyfile(p.oldpath, p.path) | |
|
192 | 200 | |
|
193 | 201 | # rewrite patch hunk |
|
194 | 202 | while pfline < p.lineno: |
@@ -281,6 +289,45 b' def diffopts(ui, opts={}):' | |||
|
281 | 289 | ignoreblanklines=(opts.get('ignore_blank_lines') or |
|
282 | 290 | ui.configbool('diff', 'ignoreblanklines', None))) |
|
283 | 291 | |
|
292 | def updatedir(ui, repo, patches, wlock=None): | |
|
293 | '''Update dirstate after patch application according to metadata''' | |
|
294 | if not patches: | |
|
295 | return | |
|
296 | copies = [] | |
|
297 | removes = [] | |
|
298 | cfiles = patches.keys() | |
|
299 | copts = {'after': False, 'force': False} | |
|
300 | cwd = repo.getcwd() | |
|
301 | if cwd: | |
|
302 | cfiles = [util.pathto(cwd, f) for f in patches.keys()] | |
|
303 | for f in patches: | |
|
304 | ctype, gp = patches[f] | |
|
305 | if ctype == 'RENAME': | |
|
306 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |
|
307 | removes.append(gp.oldpath) | |
|
308 | elif ctype == 'COPY': | |
|
309 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |
|
310 | elif ctype == 'DELETE': | |
|
311 | removes.append(gp.path) | |
|
312 | for src, dst, after in copies: | |
|
313 | if not after: | |
|
314 | copyfile(src, dst, repo.root) | |
|
315 | repo.copy(src, dst, wlock=wlock) | |
|
316 | if removes: | |
|
317 | repo.remove(removes, True, wlock=wlock) | |
|
318 | for f in patches: | |
|
319 | ctype, gp = patches[f] | |
|
320 | if gp and gp.mode: | |
|
321 | x = gp.mode & 0100 != 0 | |
|
322 | dst = os.path.join(repo.root, gp.path) | |
|
323 | util.set_exec(dst, x) | |
|
324 | cmdutil.addremove(repo, cfiles, wlock=wlock) | |
|
325 | files = patches.keys() | |
|
326 | files.extend([r for r in removes if r not in files]) | |
|
327 | files.sort() | |
|
328 | ||
|
329 | return files | |
|
330 | ||
|
284 | 331 | def diff(repo, node1=None, node2=None, files=None, match=util.always, |
|
285 | 332 | fp=None, changes=None, opts=None): |
|
286 | 333 | '''print diff of changes to files between two nodes, or node and |
@@ -296,10 +343,27 b' def diff(repo, node1=None, node2=None, f' | |||
|
296 | 343 | |
|
297 | 344 | if not node1: |
|
298 | 345 | node1 = repo.dirstate.parents()[0] |
|
346 | ||
|
347 | clcache = {} | |
|
348 | def getchangelog(n): | |
|
349 | if n not in clcache: | |
|
350 | clcache[n] = repo.changelog.read(n) | |
|
351 | return clcache[n] | |
|
352 | mcache = {} | |
|
353 | def getmanifest(n): | |
|
354 | if n not in mcache: | |
|
355 | mcache[n] = repo.manifest.read(n) | |
|
356 | return mcache[n] | |
|
357 | fcache = {} | |
|
358 | def getfile(f): | |
|
359 | if f not in fcache: | |
|
360 | fcache[f] = repo.file(f) | |
|
361 | return fcache[f] | |
|
362 | ||
|
299 | 363 | # reading the data for node1 early allows it to play nicely |
|
300 | 364 | # with repo.status and the revlog cache. |
|
301 |
change = |
|
|
302 |
mmap = |
|
|
365 | change = getchangelog(node1) | |
|
366 | mmap = getmanifest(change[0]) | |
|
303 | 367 | date1 = util.datestr(change[2]) |
|
304 | 368 | |
|
305 | 369 | if not changes: |
@@ -320,17 +384,32 b' def diff(repo, node1=None, node2=None, f' | |||
|
320 | 384 | if not modified and not added and not removed: |
|
321 | 385 | return |
|
322 | 386 | |
|
387 | def renamedbetween(f, n1, n2): | |
|
388 | r1, r2 = map(repo.changelog.rev, (n1, n2)) | |
|
389 | src = None | |
|
390 | while r2 > r1: | |
|
391 | cl = getchangelog(n2)[0] | |
|
392 | m = getmanifest(cl) | |
|
393 | try: | |
|
394 | src = getfile(f).renamed(m[f]) | |
|
395 | except KeyError: | |
|
396 | return None | |
|
397 | if src: | |
|
398 | f = src[0] | |
|
399 | n2 = repo.changelog.parents(n2)[0] | |
|
400 | r2 = repo.changelog.rev(n2) | |
|
401 | return src | |
|
402 | ||
|
323 | 403 | if node2: |
|
324 |
change = |
|
|
325 |
mmap2 = |
|
|
404 | change = getchangelog(node2) | |
|
405 | mmap2 = getmanifest(change[0]) | |
|
326 | 406 | _date2 = util.datestr(change[2]) |
|
327 | 407 | def date2(f): |
|
328 | 408 | return _date2 |
|
329 | 409 | def read(f): |
|
330 |
return |
|
|
410 | return getfile(f).read(mmap2[f]) | |
|
331 | 411 | def renamed(f): |
|
332 | src = repo.file(f).renamed(mmap2[f]) | |
|
333 | return src and src[0] or None | |
|
412 | return renamedbetween(f, node1, node2) | |
|
334 | 413 | else: |
|
335 | 414 | tz = util.makedate()[1] |
|
336 | 415 | _date2 = util.datestr() |
@@ -343,7 +422,18 b' def diff(repo, node1=None, node2=None, f' | |||
|
343 | 422 | def read(f): |
|
344 | 423 | return repo.wread(f) |
|
345 | 424 | def renamed(f): |
|
346 |
|
|
|
425 | src = repo.dirstate.copies.get(f) | |
|
426 | parent = repo.dirstate.parents()[0] | |
|
427 | if src: | |
|
428 | f = src[0] | |
|
429 | of = renamedbetween(f, node1, parent) | |
|
430 | if of: | |
|
431 | return of | |
|
432 | elif src: | |
|
433 | cl = getchangelog(parent)[0] | |
|
434 | return (src, getmanifest(cl)[src]) | |
|
435 | else: | |
|
436 | return None | |
|
347 | 437 | |
|
348 | 438 | if repo.ui.quiet: |
|
349 | 439 | r = None |
@@ -357,7 +447,7 b' def diff(repo, node1=None, node2=None, f' | |||
|
357 | 447 | src = renamed(f) |
|
358 | 448 | if src: |
|
359 | 449 | copied[f] = src |
|
360 | srcs = [x[1] for x in copied.items()] | |
|
450 | srcs = [x[1][0] for x in copied.items()] | |
|
361 | 451 | |
|
362 | 452 | all = modified + added + removed |
|
363 | 453 | all.sort() |
@@ -366,7 +456,7 b' def diff(repo, node1=None, node2=None, f' | |||
|
366 | 456 | tn = None |
|
367 | 457 | dodiff = True |
|
368 | 458 | if f in mmap: |
|
369 |
to = |
|
|
459 | to = getfile(f).read(mmap[f]) | |
|
370 | 460 | if f not in removed: |
|
371 | 461 | tn = read(f) |
|
372 | 462 | if opts.git: |
@@ -385,13 +475,13 b' def diff(repo, node1=None, node2=None, f' | |||
|
385 | 475 | else: |
|
386 | 476 | mode = gitmode(util.is_exec(repo.wjoin(f), None)) |
|
387 | 477 | if f in copied: |
|
388 | a = copied[f] | |
|
478 | a, arev = copied[f] | |
|
389 | 479 | omode = gitmode(mmap.execf(a)) |
|
390 | 480 | addmodehdr(header, omode, mode) |
|
391 | 481 | op = a in removed and 'rename' or 'copy' |
|
392 | 482 | header.append('%s from %s\n' % (op, a)) |
|
393 | 483 | header.append('%s to %s\n' % (op, f)) |
|
394 |
to = |
|
|
484 | to = getfile(a).read(arev) | |
|
395 | 485 | else: |
|
396 | 486 | header.append('new file mode %s\n' % mode) |
|
397 | 487 | elif f in removed: |
@@ -12,11 +12,13 b' demandload(globals(), "ConfigParser mdif' | |||
|
12 | 12 | |
|
13 | 13 | class ui(object): |
|
14 | 14 | def __init__(self, verbose=False, debug=False, quiet=False, |
|
15 |
interactive=True, traceback=False, parentui=None |
|
|
15 | interactive=True, traceback=False, parentui=None, | |
|
16 | readhooks=[]): | |
|
16 | 17 | self.overlay = {} |
|
17 | 18 | if parentui is None: |
|
18 | 19 | # this is the parent of all ui children |
|
19 | 20 | self.parentui = None |
|
21 | self.readhooks = list(readhooks) | |
|
20 | 22 | self.cdata = ConfigParser.SafeConfigParser() |
|
21 | 23 | self.readconfig(util.rcpath()) |
|
22 | 24 | |
@@ -34,6 +36,7 b' class ui(object):' | |||
|
34 | 36 | else: |
|
35 | 37 | # parentui may point to an ui object which is already a child |
|
36 | 38 | self.parentui = parentui.parentui or parentui |
|
39 | self.readhooks = list(parentui.readhooks or readhooks) | |
|
37 | 40 | parent_cdata = self.parentui.cdata |
|
38 | 41 | self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults()) |
|
39 | 42 | # make interpolation work |
@@ -78,6 +81,8 b' class ui(object):' | |||
|
78 | 81 | for name, path in self.configitems("paths"): |
|
79 | 82 | if path and "://" not in path and not os.path.isabs(path): |
|
80 | 83 | self.cdata.set("paths", name, os.path.join(root, path)) |
|
84 | for hook in self.readhooks: | |
|
85 | hook(self) | |
|
81 | 86 | |
|
82 | 87 | def setconfig(self, section, name, val): |
|
83 | 88 | self.overlay[(section, name)] = val |
@@ -28,6 +28,6 b' writing tests:' | |||
|
28 | 28 | |
|
29 | 29 | - diff will show the current time |
|
30 | 30 | |
|
31 |
use hg diff | sed "s/\( |
|
|
32 | dates | |
|
33 | ||
|
31 | use hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
32 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
33 | to strip dates |
@@ -17,7 +17,7 b' while test $count -lt 32 ; do' | |||
|
17 | 17 | test $count -eq 0 && hg add |
|
18 | 18 | hg ci -m "msg $count" -d "$count 0" |
|
19 | 19 | echo % committed changeset $count |
|
20 |
count= |
|
|
20 | count=`expr $count + 1` | |
|
21 | 21 | done |
|
22 | 22 | |
|
23 | 23 | echo % log |
@@ -8,7 +8,11 b' hg init a' | |||
|
8 | 8 | cd a |
|
9 | 9 | echo a > a |
|
10 | 10 | hg add |
|
11 | hg extdiff -o -Nr | |
|
11 | diff -N /dev/null /dev/null 2> /dev/null | |
|
12 | if [ $? -ne 0 ]; then | |
|
13 | opt="-p gdiff" | |
|
14 | fi | |
|
15 | hg extdiff -o -Nr $opt | |
|
12 | 16 | |
|
13 | 17 | echo "[extdiff]" >> $HGTMP/.hgrc |
|
14 | 18 | echo "cmd.falabala=echo" >> $HGTMP/.hgrc |
@@ -8,22 +8,26 b" hg ci -Amstart -d '0 0'" | |||
|
8 | 8 | echo new > new |
|
9 | 9 | hg ci -Amnew -d '0 0' |
|
10 | 10 | echo '% new file' |
|
11 |
hg diff --git -r 0 | sed "s/\( |
|
|
11 | hg diff --git -r 0 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
12 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
12 | 13 | |
|
13 | 14 | hg cp new copy |
|
14 | 15 | hg ci -mcopy -d '0 0' |
|
15 | 16 | echo '% copy' |
|
16 |
hg diff --git -r 1:tip | sed "s/\( |
|
|
17 | hg diff --git -r 1:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
18 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
17 | 19 | |
|
18 | 20 | hg mv copy rename |
|
19 | 21 | hg ci -mrename -d '0 0' |
|
20 | 22 | echo '% rename' |
|
21 |
hg diff --git -r 2:tip | sed "s/\( |
|
|
23 | hg diff --git -r 2:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
24 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
22 | 25 | |
|
23 | 26 | hg rm rename |
|
24 | 27 | hg ci -mdelete -d '0 0' |
|
25 | 28 | echo '% delete' |
|
26 |
hg diff --git -r 3:tip | sed "s/\( |
|
|
29 | hg diff --git -r 3:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
30 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
27 | 31 | |
|
28 | 32 | cat > src <<EOF |
|
29 | 33 | 1 |
@@ -36,11 +40,13 b" hg ci -Amsrc -d '0 0'" | |||
|
36 | 40 | chmod +x src |
|
37 | 41 | hg ci -munexec -d '0 0' |
|
38 | 42 | echo '% chmod 644' |
|
39 |
hg diff --git -r 5:tip | sed "s/\( |
|
|
43 | hg diff --git -r 5:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
44 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
40 | 45 | |
|
41 | 46 | hg mv src dst |
|
42 | 47 | chmod -x dst |
|
43 | 48 | echo a >> dst |
|
44 | 49 | hg ci -mrenamemod -d '0 0' |
|
45 | 50 | echo '% rename+mod+chmod' |
|
46 |
hg diff --git -r 6:tip | sed "s/\( |
|
|
51 | hg diff --git -r 6:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
52 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" |
@@ -126,3 +126,30 b' echo x>x' | |||
|
126 | 126 | hg ci -Ama |
|
127 | 127 | hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/' |
|
128 | 128 | hg unbundle .hg/strip-backup/* |
|
129 | ||
|
130 | cat >>$HGTMP/.hgrc <<EOF | |
|
131 | [diff] | |
|
132 | git = True | |
|
133 | EOF | |
|
134 | cd .. | |
|
135 | hg init git | |
|
136 | cd git | |
|
137 | hg qinit | |
|
138 | ||
|
139 | hg qnew -m'new file' new | |
|
140 | echo foo > new | |
|
141 | chmod +x new | |
|
142 | hg add new | |
|
143 | hg qrefresh | |
|
144 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
145 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/new | |
|
146 | ||
|
147 | hg qnew -m'copy file' copy | |
|
148 | hg cp new copy | |
|
149 | hg qrefresh | |
|
150 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
|
151 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/copy | |
|
152 | ||
|
153 | hg qpop | |
|
154 | hg qpush | |
|
155 | hg qdiff |
@@ -127,3 +127,22 b' adding manifests' | |||
|
127 | 127 | adding file changes |
|
128 | 128 | added 1 changesets with 1 changes to 1 files |
|
129 | 129 | (run 'hg update' to get a working copy) |
|
130 | new file | |
|
131 | ||
|
132 | diff --git a/new b/new | |
|
133 | new file mode 100755 | |
|
134 | --- /dev/null | |
|
135 | +++ b/new | |
|
136 | @@ -0,0 +1,1 @@ | |
|
137 | +foo | |
|
138 | copy file | |
|
139 | ||
|
140 | diff --git a/new b/copy | |
|
141 | copy from new | |
|
142 | copy to copy | |
|
143 | Now at: new | |
|
144 | applying copy | |
|
145 | Now at: copy | |
|
146 | diff --git a/new b/copy | |
|
147 | copy from new | |
|
148 | copy to copy |
General Comments 0
You need to be logged in to leave comments.
Login now