64 termsize = scmplatform.termsize |
64 termsize = scmplatform.termsize |
65 |
65 |
66 |
66 |
67 @attr.s(slots=True, repr=False) |
67 @attr.s(slots=True, repr=False) |
68 class status(object): |
68 class status(object): |
69 '''Struct with a list of files per status. |
69 """Struct with a list of files per status. |
70 |
70 |
71 The 'deleted', 'unknown' and 'ignored' properties are only |
71 The 'deleted', 'unknown' and 'ignored' properties are only |
72 relevant to the working copy. |
72 relevant to the working copy. |
73 ''' |
73 """ |
74 |
74 |
75 modified = attr.ib(default=attr.Factory(list)) |
75 modified = attr.ib(default=attr.Factory(list)) |
76 added = attr.ib(default=attr.Factory(list)) |
76 added = attr.ib(default=attr.Factory(list)) |
77 removed = attr.ib(default=attr.Factory(list)) |
77 removed = attr.ib(default=attr.Factory(list)) |
78 deleted = attr.ib(default=attr.Factory(list)) |
78 deleted = attr.ib(default=attr.Factory(list)) |
121 for subpath in missing: |
121 for subpath in missing: |
122 yield subpath, ctx2.nullsub(subpath, ctx1) |
122 yield subpath, ctx2.nullsub(subpath, ctx1) |
123 |
123 |
124 |
124 |
125 def nochangesfound(ui, repo, excluded=None): |
125 def nochangesfound(ui, repo, excluded=None): |
126 '''Report no changes for push/pull, excluded is None or a list of |
126 """Report no changes for push/pull, excluded is None or a list of |
127 nodes excluded from the push/pull. |
127 nodes excluded from the push/pull. |
128 ''' |
128 """ |
129 secretlist = [] |
129 secretlist = [] |
130 if excluded: |
130 if excluded: |
131 for n in excluded: |
131 for n in excluded: |
132 ctx = repo[n] |
132 ctx = repo[n] |
133 if ctx.phase() >= phases.secret and not ctx.extinct(): |
133 if ctx.phase() >= phases.secret and not ctx.extinct(): |
333 raise error.InputError(msg) |
333 raise error.InputError(msg) |
334 ui.warn(_(b"warning: %s\n") % msg) |
334 ui.warn(_(b"warning: %s\n") % msg) |
335 |
335 |
336 |
336 |
337 def checkportabilityalert(ui): |
337 def checkportabilityalert(ui): |
338 '''check if the user's config requests nothing, a warning, or abort for |
338 """check if the user's config requests nothing, a warning, or abort for |
339 non-portable filenames''' |
339 non-portable filenames""" |
340 val = ui.config(b'ui', b'portablefilenames') |
340 val = ui.config(b'ui', b'portablefilenames') |
341 lval = val.lower() |
341 lval = val.lower() |
342 bval = stringutil.parsebool(val) |
342 bval = stringutil.parsebool(val) |
343 abort = pycompat.iswindows or lval == b'abort' |
343 abort = pycompat.iswindows or lval == b'abort' |
344 warn = bval or lval == b'warn' |
344 warn = bval or lval == b'warn' |
400 cl._filteredrevs_hashcache[maxrev] = key |
400 cl._filteredrevs_hashcache[maxrev] = key |
401 return key |
401 return key |
402 |
402 |
403 |
403 |
404 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False): |
404 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False): |
405 '''yield every hg repository under path, always recursively. |
405 """yield every hg repository under path, always recursively. |
406 The recurse flag will only control recursion into repo working dirs''' |
406 The recurse flag will only control recursion into repo working dirs""" |
407 |
407 |
408 def errhandler(err): |
408 def errhandler(err): |
409 if err.filename == path: |
409 if err.filename == path: |
410 raise err |
410 raise err |
411 |
411 |
791 if windowsize < sizelimit: |
791 if windowsize < sizelimit: |
792 windowsize *= 2 |
792 windowsize *= 2 |
793 |
793 |
794 |
794 |
795 def walkchangerevs(repo, revs, makefilematcher, prepare): |
795 def walkchangerevs(repo, revs, makefilematcher, prepare): |
796 '''Iterate over files and the revs in a "windowed" way. |
796 """Iterate over files and the revs in a "windowed" way. |
797 |
797 |
798 Callers most commonly need to iterate backwards over the history |
798 Callers most commonly need to iterate backwards over the history |
799 in which they are interested. Doing so has awful (quadratic-looking) |
799 in which they are interested. Doing so has awful (quadratic-looking) |
800 performance, so we use iterators in a "windowed" way. |
800 performance, so we use iterators in a "windowed" way. |
801 |
801 |
803 window, we first walk forwards to gather data, then in the desired |
803 window, we first walk forwards to gather data, then in the desired |
804 order (usually backwards) to display it. |
804 order (usually backwards) to display it. |
805 |
805 |
806 This function returns an iterator yielding contexts. Before |
806 This function returns an iterator yielding contexts. Before |
807 yielding each context, the iterator will first call the prepare |
807 yielding each context, the iterator will first call the prepare |
808 function on each context in the window in forward order.''' |
808 function on each context in the window in forward order.""" |
809 |
809 |
810 if not revs: |
810 if not revs: |
811 return [] |
811 return [] |
812 change = repo.__getitem__ |
812 change = repo.__getitem__ |
813 |
813 |
895 '''Create a new uipathfn that treats the file as relative to subpath.''' |
895 '''Create a new uipathfn that treats the file as relative to subpath.''' |
896 return lambda f: uipathfn(posixpath.join(subpath, f)) |
896 return lambda f: uipathfn(posixpath.join(subpath, f)) |
897 |
897 |
898 |
898 |
899 def anypats(pats, opts): |
899 def anypats(pats, opts): |
900 '''Checks if any patterns, including --include and --exclude were given. |
900 """Checks if any patterns, including --include and --exclude were given. |
901 |
901 |
902 Some commands (e.g. addremove) use this condition for deciding whether to |
902 Some commands (e.g. addremove) use this condition for deciding whether to |
903 print absolute or relative paths. |
903 print absolute or relative paths. |
904 ''' |
904 """ |
905 return bool(pats or opts.get(b'include') or opts.get(b'exclude')) |
905 return bool(pats or opts.get(b'include') or opts.get(b'exclude')) |
906 |
906 |
907 |
907 |
908 def expandpats(pats): |
908 def expandpats(pats): |
909 '''Expand bare globs when running on windows. |
909 """Expand bare globs when running on windows. |
910 On posix we assume it already has already been done by sh.''' |
910 On posix we assume it already has already been done by sh.""" |
911 if not util.expandglobs: |
911 if not util.expandglobs: |
912 return list(pats) |
912 return list(pats) |
913 ret = [] |
913 ret = [] |
914 for kindpat in pats: |
914 for kindpat in pats: |
915 kind, pat = matchmod._patsplit(kindpat, None) |
915 kind, pat = matchmod._patsplit(kindpat, None) |
926 |
926 |
927 |
927 |
928 def matchandpats( |
928 def matchandpats( |
929 ctx, pats=(), opts=None, globbed=False, default=b'relpath', badfn=None |
929 ctx, pats=(), opts=None, globbed=False, default=b'relpath', badfn=None |
930 ): |
930 ): |
931 '''Return a matcher and the patterns that were used. |
931 """Return a matcher and the patterns that were used. |
932 The matcher will warn about bad matches, unless an alternate badfn callback |
932 The matcher will warn about bad matches, unless an alternate badfn callback |
933 is provided.''' |
933 is provided.""" |
934 if opts is None: |
934 if opts is None: |
935 opts = {} |
935 opts = {} |
936 if not globbed and default == b'relpath': |
936 if not globbed and default == b'relpath': |
937 pats = expandpats(pats or []) |
937 pats = expandpats(pats or []) |
938 |
938 |
999 return None |
999 return None |
1000 return vfs.vfs(repo.wvfs.join(origbackuppath)) |
1000 return vfs.vfs(repo.wvfs.join(origbackuppath)) |
1001 |
1001 |
1002 |
1002 |
1003 def backuppath(ui, repo, filepath): |
1003 def backuppath(ui, repo, filepath): |
1004 '''customize where working copy backup files (.orig files) are created |
1004 """customize where working copy backup files (.orig files) are created |
1005 |
1005 |
1006 Fetch user defined path from config file: [ui] origbackuppath = <path> |
1006 Fetch user defined path from config file: [ui] origbackuppath = <path> |
1007 Fall back to default (filepath with .orig suffix) if not specified |
1007 Fall back to default (filepath with .orig suffix) if not specified |
1008 |
1008 |
1009 filepath is repo-relative |
1009 filepath is repo-relative |
1010 |
1010 |
1011 Returns an absolute path |
1011 Returns an absolute path |
1012 ''' |
1012 """ |
1013 origvfs = getorigvfs(ui, repo) |
1013 origvfs = getorigvfs(ui, repo) |
1014 if origvfs is None: |
1014 if origvfs is None: |
1015 return repo.wjoin(filepath + b".orig") |
1015 return repo.wjoin(filepath + b".orig") |
1016 |
1016 |
1017 origbackupdir = origvfs.dirname(filepath) |
1017 origbackupdir = origvfs.dirname(filepath) |
1298 return 1 |
1298 return 1 |
1299 return ret |
1299 return ret |
1300 |
1300 |
1301 |
1301 |
1302 def marktouched(repo, files, similarity=0.0): |
1302 def marktouched(repo, files, similarity=0.0): |
1303 '''Assert that files have somehow been operated upon. files are relative to |
1303 """Assert that files have somehow been operated upon. files are relative to |
1304 the repo root.''' |
1304 the repo root.""" |
1305 m = matchfiles(repo, files, badfn=lambda x, y: rejected.append(x)) |
1305 m = matchfiles(repo, files, badfn=lambda x, y: rejected.append(x)) |
1306 rejected = [] |
1306 rejected = [] |
1307 |
1307 |
1308 added, unknown, deleted, removed, forgotten = _interestingfiles(repo, m) |
1308 added, unknown, deleted, removed, forgotten = _interestingfiles(repo, m) |
1309 |
1309 |
1333 return 1 |
1333 return 1 |
1334 return 0 |
1334 return 0 |
1335 |
1335 |
1336 |
1336 |
1337 def _interestingfiles(repo, matcher): |
1337 def _interestingfiles(repo, matcher): |
1338 '''Walk dirstate with matcher, looking for files that addremove would care |
1338 """Walk dirstate with matcher, looking for files that addremove would care |
1339 about. |
1339 about. |
1340 |
1340 |
1341 This is different from dirstate.status because it doesn't care about |
1341 This is different from dirstate.status because it doesn't care about |
1342 whether files are modified or clean.''' |
1342 whether files are modified or clean.""" |
1343 added, unknown, deleted, removed, forgotten = [], [], [], [], [] |
1343 added, unknown, deleted, removed, forgotten = [], [], [], [], [] |
1344 audit_path = pathutil.pathauditor(repo.root, cached=True) |
1344 audit_path = pathutil.pathauditor(repo.root, cached=True) |
1345 |
1345 |
1346 ctx = repo[None] |
1346 ctx = repo[None] |
1347 dirstate = repo.dirstate |
1347 dirstate = repo.dirstate |
1392 renames[new] = old |
1392 renames[new] = old |
1393 return renames |
1393 return renames |
1394 |
1394 |
1395 |
1395 |
1396 def _markchanges(repo, unknown, deleted, renames): |
1396 def _markchanges(repo, unknown, deleted, renames): |
1397 '''Marks the files in unknown as added, the files in deleted as removed, |
1397 """Marks the files in unknown as added, the files in deleted as removed, |
1398 and the files in renames as copied.''' |
1398 and the files in renames as copied.""" |
1399 wctx = repo[None] |
1399 wctx = repo[None] |
1400 with repo.wlock(): |
1400 with repo.wlock(): |
1401 wctx.forget(deleted) |
1401 wctx.forget(deleted) |
1402 wctx.add(unknown) |
1402 wctx.add(unknown) |
1403 for new, old in pycompat.iteritems(renames): |
1403 for new, old in pycompat.iteritems(renames): |
1422 rcache = {} |
1422 rcache = {} |
1423 if endrev is None: |
1423 if endrev is None: |
1424 endrev = len(repo) |
1424 endrev = len(repo) |
1425 |
1425 |
1426 def getrenamed(fn, rev): |
1426 def getrenamed(fn, rev): |
1427 '''looks up all renames for a file (up to endrev) the first |
1427 """looks up all renames for a file (up to endrev) the first |
1428 time the file is given. It indexes on the changerev and only |
1428 time the file is given. It indexes on the changerev and only |
1429 parses the manifest if linkrev != changerev. |
1429 parses the manifest if linkrev != changerev. |
1430 Returns rename info for fn at changerev rev.''' |
1430 Returns rename info for fn at changerev rev.""" |
1431 if fn not in rcache: |
1431 if fn not in rcache: |
1432 rcache[fn] = {} |
1432 rcache[fn] = {} |
1433 fl = repo.file(fn) |
1433 fl = repo.file(fn) |
1434 for i in fl: |
1434 for i in fl: |
1435 lr = fl.linkrev(i) |
1435 lr = fl.linkrev(i) |
1546 ds.copy(src, dst) |
1546 ds.copy(src, dst) |
1547 repo._quick_access_changeid_invalidate() |
1547 repo._quick_access_changeid_invalidate() |
1548 |
1548 |
1549 |
1549 |
1550 def filterrequirements(requirements): |
1550 def filterrequirements(requirements): |
1551 """ filters the requirements into two sets: |
1551 """filters the requirements into two sets: |
1552 |
1552 |
1553 wcreq: requirements which should be written in .hg/requires |
1553 wcreq: requirements which should be written in .hg/requires |
1554 storereq: which should be written in .hg/store/requires |
1554 storereq: which should be written in .hg/store/requires |
1555 |
1555 |
1556 Returns (wcreq, storereq) |
1556 Returns (wcreq, storereq) |
1869 else: |
1869 else: |
1870 self.ui.debug(b'%s:%s %d%s\n' % (self.topic, item, self.pos, unit)) |
1870 self.ui.debug(b'%s:%s %d%s\n' % (self.topic, item, self.pos, unit)) |
1871 |
1871 |
1872 |
1872 |
1873 def gdinitconfig(ui): |
1873 def gdinitconfig(ui): |
1874 """helper function to know if a repo should be created as general delta |
1874 """helper function to know if a repo should be created as general delta""" |
1875 """ |
|
1876 # experimental config: format.generaldelta |
1875 # experimental config: format.generaldelta |
1877 return ui.configbool(b'format', b'generaldelta') or ui.configbool( |
1876 return ui.configbool(b'format', b'generaldelta') or ui.configbool( |
1878 b'format', b'usegeneraldelta' |
1877 b'format', b'usegeneraldelta' |
1879 ) |
1878 ) |
1880 |
1879 |
1881 |
1880 |
1882 def gddeltaconfig(ui): |
1881 def gddeltaconfig(ui): |
1883 """helper function to know if incoming delta should be optimised |
1882 """helper function to know if incoming delta should be optimised""" |
1884 """ |
|
1885 # experimental config: format.generaldelta |
1883 # experimental config: format.generaldelta |
1886 return ui.configbool(b'format', b'generaldelta') |
1884 return ui.configbool(b'format', b'generaldelta') |
1887 |
1885 |
1888 |
1886 |
1889 class simplekeyvaluefile(object): |
1887 class simplekeyvaluefile(object): |