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