##// END OF EJS Templates
merge with mpm
Benoit Boissinot -
r9535:75d290db merge default
parent child Browse files
Show More
@@ -0,0 +1,218 b''
1 #!/usr/bin/env python
2
3 """\
4 Reorder a revlog (by default the the manifest file in the current
5 repository) to save space. Specifically, this topologically sorts the
6 revisions in the revlog so that revisions on the same branch are adjacent
7 as much as possible. This is a workaround for the fact that Mercurial
8 computes deltas relative to the previous revision rather than relative to a
9 parent revision. This is *not* safe to run on a changelog.
10 """
11
12 # Originally written by Benoit Boissinot <benoit.boissinot at ens-lyon.org>
13 # as a patch to rewrite-log. Cleaned up, refactored, documented, and
14 # renamed by Greg Ward <greg at gerg.ca>.
15
16 # XXX would be nice to have a way to verify the repository after shrinking,
17 # e.g. by comparing "before" and "after" states of random changesets
18 # (maybe: export before, shrink, export after, diff).
19
20 import sys, os, tempfile
21 import optparse
22 from mercurial import ui as ui_, hg, revlog, transaction, node, util
23
24 def toposort(rl):
25 write = sys.stdout.write
26
27 children = {}
28 root = []
29 # build children and roots
30 write('reading %d revs ' % len(rl))
31 try:
32 for i in rl:
33 children[i] = []
34 parents = [p for p in rl.parentrevs(i) if p != node.nullrev]
35 # in case of duplicate parents
36 if len(parents) == 2 and parents[0] == parents[1]:
37 del parents[1]
38 for p in parents:
39 assert p in children
40 children[p].append(i)
41
42 if len(parents) == 0:
43 root.append(i)
44
45 if i % 1000 == 0:
46 write('.')
47 finally:
48 write('\n')
49
50 # XXX this is a reimplementation of the 'branchsort' topo sort
51 # algorithm in hgext.convert.convcmd... would be nice not to duplicate
52 # the algorithm
53 write('sorting ...')
54 visit = root
55 ret = []
56 while visit:
57 i = visit.pop(0)
58 ret.append(i)
59 if i not in children:
60 # This only happens if some node's p1 == p2, which can
61 # happen in the manifest in certain circumstances.
62 continue
63 next = []
64 for c in children.pop(i):
65 parents_unseen = [p for p in rl.parentrevs(c)
66 if p != node.nullrev and p in children]
67 if len(parents_unseen) == 0:
68 next.append(c)
69 visit = next + visit
70 write('\n')
71 return ret
72
73 def writerevs(r1, r2, order, tr):
74 write = sys.stdout.write
75 write('writing %d revs ' % len(order))
76 try:
77 count = 0
78 for rev in order:
79 n = r1.node(rev)
80 p1, p2 = r1.parents(n)
81 l = r1.linkrev(rev)
82 t = r1.revision(n)
83 n2 = r2.addrevision(t, tr, l, p1, p2)
84
85 if count % 1000 == 0:
86 write('.')
87 count += 1
88 finally:
89 write('\n')
90
91 def report(olddatafn, newdatafn):
92 oldsize = float(os.stat(olddatafn).st_size)
93 newsize = float(os.stat(newdatafn).st_size)
94
95 # argh: have to pass an int to %d, because a float >= 2^32
96 # blows up under Python 2.5 or earlier
97 sys.stdout.write('old file size: %12d bytes (%6.1f MiB)\n'
98 % (int(oldsize), oldsize/1024/1024))
99 sys.stdout.write('new file size: %12d bytes (%6.1f MiB)\n'
100 % (int(newsize), newsize/1024/1024))
101
102 shrink_percent = (oldsize - newsize) / oldsize * 100
103 shrink_factor = oldsize / newsize
104 sys.stdout.write('shrinkage: %.1f%% (%.1fx)\n'
105 % (shrink_percent, shrink_factor))
106
107 def main():
108
109 # Unbuffer stdout for nice progress output.
110 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
111 write = sys.stdout.write
112
113 parser = optparse.OptionParser(description=__doc__)
114 parser.add_option('-R', '--repository',
115 default=os.path.curdir,
116 metavar='REPO',
117 help='repository root directory [default: current dir]')
118 parser.add_option('--revlog',
119 metavar='FILE',
120 help='shrink FILE [default: REPO/hg/store/00manifest.i]')
121 (options, args) = parser.parse_args()
122 if args:
123 parser.error('too many arguments')
124
125 # Open the specified repository.
126 ui = ui_.ui()
127 repo = hg.repository(ui, options.repository)
128 if not repo.local():
129 parser.error('not a local repository: %s' % options.repository)
130
131 if options.revlog is None:
132 indexfn = repo.sjoin('00manifest.i')
133 else:
134 if not options.revlog.endswith('.i'):
135 parser.error('--revlog option must specify the revlog index file '
136 '(*.i), not %s' % options.revlog)
137
138 indexfn = os.path.realpath(options.revlog)
139 store = repo.sjoin('')
140 if not indexfn.startswith(store):
141 parser.error('--revlog option must specify a revlog in %s, not %s'
142 % (store, indexfn))
143
144 datafn = indexfn[:-2] + '.d'
145 if not os.path.exists(indexfn):
146 parser.error('no such file: %s' % indexfn)
147 if '00changelog' in indexfn:
148 parser.error('shrinking the changelog will corrupt your repository')
149 if not os.path.exists(datafn):
150 # This is just a lazy shortcut because I can't be bothered to
151 # handle all the special cases that entail from no .d file.
152 parser.error('%s does not exist: revlog not big enough '
153 'to be worth shrinking' % datafn)
154
155 oldindexfn = indexfn + '.old'
156 olddatafn = datafn + '.old'
157 if os.path.exists(oldindexfn) or os.path.exists(olddatafn):
158 parser.error('one or both of\n'
159 ' %s\n'
160 ' %s\n'
161 'exists from a previous run; please clean up before '
162 'running again'
163 % (oldindexfn, olddatafn))
164
165 write('shrinking %s\n' % indexfn)
166 prefix = os.path.basename(indexfn)[:-1]
167 (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn),
168 prefix=prefix,
169 suffix='.i')
170 tmpdatafn = tmpindexfn[:-2] + '.d'
171 os.close(tmpfd)
172
173 r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), indexfn)
174 r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), tmpindexfn)
175
176 # Don't use repo.transaction(), because then things get hairy with
177 # paths: some need to be relative to .hg, and some need to be
178 # absolute. Doing it this way keeps things simple: everything is an
179 # absolute path.
180 lock = repo.lock(wait=False)
181 tr = transaction.transaction(sys.stderr.write,
182 open,
183 repo.sjoin('journal'))
184
185 try:
186 try:
187 order = toposort(r1)
188 writerevs(r1, r2, order, tr)
189 report(datafn, tmpdatafn)
190 tr.close()
191 except:
192 # Abort transaction first, so we truncate the files before
193 # deleting them.
194 tr.abort()
195 if os.path.exists(tmpindexfn):
196 os.unlink(tmpindexfn)
197 if os.path.exists(tmpdatafn):
198 os.unlink(tmpdatafn)
199 raise
200 finally:
201 lock.release()
202
203 os.link(indexfn, oldindexfn)
204 os.link(datafn, olddatafn)
205 os.rename(tmpindexfn, indexfn)
206 os.rename(tmpdatafn, datafn)
207 write('note: old revlog saved in:\n'
208 ' %s\n'
209 ' %s\n'
210 '(You can delete those files when you are satisfied that your\n'
211 'repository is still sane. '
212 'Running \'hg verify\' is strongly recommended.)\n'
213 % (oldindexfn, olddatafn))
214
215 try:
216 main()
217 except KeyboardInterrupt:
218 sys.exit("interrupted")
@@ -530,3 +530,20 b' complete -o bashdefault -o default -F _h'
530 530 return
531 531 }
532 532
533 # shelve
534 _hg_shelves()
535 {
536 local shelves="$("$hg" unshelve -l . 2>/dev/null)"
537 local IFS=$'\n'
538 COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur"))
539 }
540
541 _hg_cmd_shelve()
542 {
543 _hg_status "mard"
544 }
545
546 _hg_cmd_unshelve()
547 {
548 _hg_shelves
549 }
@@ -95,6 +95,6 b' COPYING'
95 95 -------
96 96 Copyright \(C) 2005-2009 Matt Mackall.
97 97 Free use of this software is granted under the terms of the GNU General
98 Public License (GPL).
98 Public License version 2.
99 99
100 100 .. include:: common.txt
@@ -106,6 +106,6 b' COPYING'
106 106 This manual page is copyright 2006 Vadim Gelfer.
107 107 Mercurial is copyright 2005-2009 Matt Mackall.
108 108 Free use of this software is granted under the terms of the GNU General
109 Public License (GPL).
109 Public License version 2.
110 110
111 111 .. include:: common.txt
@@ -946,6 +946,6 b' COPYING'
946 946 This manual page is copyright 2005 Bryan O'Sullivan.
947 947 Mercurial is copyright 2005-2009 Matt Mackall.
948 948 Free use of this software is granted under the terms of the GNU General
949 Public License (GPL).
949 Public License version 2.
950 950
951 951 .. include:: common.txt
@@ -160,9 +160,8 b' def colorqseries(orig, ui, repo, *dummy,'
160 160 return retval
161 161
162 162 _patch_effects = { 'applied': ['blue', 'bold', 'underline'],
163 'missing': ['red', 'bold'],
164 'unapplied': ['black', 'bold'], }
165
163 'missing': ['red', 'bold'],
164 'unapplied': ['black', 'bold'], }
166 165 def colorwrap(orig, s):
167 166 '''wrap ui.write for colored diff output'''
168 167 lines = s.split('\n')
@@ -153,11 +153,13 b" protomap = {'http': httpcheck,"
153 153 def issvnurl(url):
154 154 try:
155 155 proto, path = url.split('://', 1)
156 path = urllib.url2pathname(path)
156 if proto == 'file':
157 path = urllib.url2pathname(path)
157 158 except ValueError:
158 159 proto = 'file'
159 160 path = os.path.abspath(url)
160 path = path.replace(os.sep, '/')
161 if proto == 'file':
162 path = path.replace(os.sep, '/')
161 163 check = protomap.get(proto, lambda p, p2: False)
162 164 while '/' in path:
163 165 if check(path, proto):
@@ -42,9 +42,9 b' fast (at least faster than having to com'
42 42 '''
43 43
44 44 from mercurial.i18n import _
45 from mercurial.node import short
45 from mercurial.node import short, nullid
46 46 from mercurial import cmdutil, util, commands
47 import os, shlex, shutil, tempfile
47 import os, shlex, shutil, tempfile, re
48 48
49 49 def snapshot(ui, repo, files, node, tmproot):
50 50 '''snapshot files as of some revision
@@ -69,7 +69,7 b' def snapshot(ui, repo, files, node, tmpr'
69 69 for fn in files:
70 70 wfn = util.pconvert(fn)
71 71 if not wfn in ctx:
72 # skipping new file after a merge ?
72 # File doesn't exist; could be a bogus modify
73 73 continue
74 74 ui.note(' %s\n' % wfn)
75 75 dest = os.path.join(base, wfn)
@@ -96,52 +96,95 b' def dodiff(ui, repo, diffcmd, diffopts, '
96 96
97 97 revs = opts.get('rev')
98 98 change = opts.get('change')
99 args = ' '.join(diffopts)
100 do3way = '$parent2' in args
99 101
100 102 if revs and change:
101 103 msg = _('cannot specify --rev and --change at the same time')
102 104 raise util.Abort(msg)
103 105 elif change:
104 106 node2 = repo.lookup(change)
105 node1 = repo[node2].parents()[0].node()
107 node1a, node1b = repo.changelog.parents(node2)
106 108 else:
107 node1, node2 = cmdutil.revpair(repo, revs)
109 node1a, node2 = cmdutil.revpair(repo, revs)
110 if not revs:
111 node1b = repo.dirstate.parents()[1]
112 else:
113 node1b = nullid
114
115 # Disable 3-way merge if there is only one parent
116 if do3way:
117 if node1b == nullid:
118 do3way = False
108 119
109 120 matcher = cmdutil.match(repo, pats, opts)
110 modified, added, removed = repo.status(node1, node2, matcher)[:3]
111 if not (modified or added or removed):
112 return 0
121 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
122 if do3way:
123 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
124 else:
125 mod_b, add_b, rem_b = set(), set(), set()
126 modadd = mod_a | add_a | mod_b | add_b
127 common = modadd | rem_a | rem_b
128 if not common:
129 return 0
113 130
114 131 tmproot = tempfile.mkdtemp(prefix='extdiff.')
115 dir2root = ''
116 132 try:
117 # Always make a copy of node1
118 dir1 = snapshot(ui, repo, modified + removed, node1, tmproot)[0]
119 changes = len(modified) + len(removed) + len(added)
133 # Always make a copy of node1a (and node1b, if applicable)
134 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
135 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
136 if do3way:
137 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
138 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
139 else:
140 dir1b = None
141
142 fns_and_mtime = []
120 143
121 144 # If node2 in not the wc or there is >1 change, copy it
122 if node2 or changes > 1:
123 dir2, fns_and_mtime = snapshot(ui, repo, modified + added, node2, tmproot)
145 dir2root = ''
146 if node2:
147 dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
148 elif len(common) > 1:
149 #we only actually need to get the files to copy back to the working
150 #dir in this case (because the other cases are: diffing 2 revisions
151 #or single file -- in which case the file is already directly passed
152 #to the diff tool).
153 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot)
124 154 else:
125 155 # This lets the diff tool open the changed file directly
126 156 dir2 = ''
127 157 dir2root = repo.root
128 fns_and_mtime = []
129 158
130 159 # If only one change, diff the files instead of the directories
131 if changes == 1 :
132 if len(modified):
133 dir1 = os.path.join(dir1, util.localpath(modified[0]))
134 dir2 = os.path.join(dir2root, dir2, util.localpath(modified[0]))
135 elif len(removed) :
136 dir1 = os.path.join(dir1, util.localpath(removed[0]))
137 dir2 = os.devnull
138 else:
139 dir1 = os.devnull
140 dir2 = os.path.join(dir2root, dir2, util.localpath(added[0]))
160 # Handle bogus modifies correctly by checking if the files exist
161 if len(common) == 1:
162 common_file = util.localpath(common.pop())
163 dir1a = os.path.join(dir1a, common_file)
164 if not os.path.isfile(os.path.join(tmproot, dir1a)):
165 dir1a = os.devnull
166 if do3way:
167 dir1b = os.path.join(dir1b, common_file)
168 if not os.path.isfile(os.path.join(tmproot, dir1b)):
169 dir1b = os.devnull
170 dir2 = os.path.join(dir2root, dir2, common_file)
141 171
142 cmdline = ('%s %s %s %s' %
143 (util.shellquote(diffcmd), ' '.join(diffopts),
144 util.shellquote(dir1), util.shellquote(dir2)))
172 # Function to quote file/dir names in the argument string
173 # When not operating in 3-way mode, an empty string is returned for parent2
174 replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b, child=dir2)
175 def quote(match):
176 key = match.group()[1:]
177 if not do3way and key == 'parent2':
178 return ''
179 return util.shellquote(replace[key])
180
181 # Match parent2 first, so 'parent1?' will match both parent1 and parent
182 regex = '\$(parent2|parent1?|child)'
183 if not do3way and not re.search(regex, args):
184 args += ' $parent1 $child'
185 args = re.sub(regex, quote, args)
186 cmdline = util.shellquote(diffcmd) + ' ' + args
187
145 188 ui.debug('running %r in %s\n' % (cmdline, tmproot))
146 189 util.system(cmdline, cwd=tmproot)
147 190
@@ -173,11 +216,11 b' def extdiff(ui, repo, *pats, **opts):'
173 216 that revision is compared to the working directory, and, when no
174 217 revisions are specified, the working directory files are compared
175 218 to its parent.'''
176 program = opts['program'] or 'diff'
177 if opts['program']:
178 option = opts['option']
179 else:
180 option = opts['option'] or ['-Npru']
219 program = opts.get('program')
220 option = opts.get('option')
221 if not program:
222 program = 'diff'
223 option = option or ['-Npru']
181 224 return dodiff(ui, repo, program, option, pats, opts)
182 225
183 226 cmdtable = {
@@ -17,28 +17,7 b' from client import client, QueryFailed'
17 17
18 18 def serve(ui, repo, **opts):
19 19 '''start an inotify server for this repository'''
20 timeout = opts.get('timeout')
21 if timeout:
22 timeout = float(timeout) * 1e3
23
24 class service(object):
25 def init(self):
26 try:
27 self.master = server.master(ui, repo.dirstate,
28 repo.root, timeout)
29 except server.AlreadyStartedException, inst:
30 raise util.Abort(str(inst))
31
32 def run(self):
33 try:
34 self.master.run()
35 finally:
36 self.master.shutdown()
37
38 service = service()
39 logfile = ui.config('inotify', 'log')
40 cmdutil.service(opts, initfn=service.init, runfn=service.run,
41 logfile=logfile)
20 server.start(ui, repo.dirstate, repo.root, opts)
42 21
43 22 def debuginotify(ui, repo, **opts):
44 23 '''debugging information for inotify extension
@@ -34,7 +34,8 b' def start_server(function):'
34 34 self.ui.debug('(starting inotify server)\n')
35 35 try:
36 36 try:
37 server.start(self.ui, self.dirstate, self.root)
37 server.start(self.ui, self.dirstate, self.root,
38 dict(daemon=True, daemon_pipefds=''))
38 39 except server.AlreadyStartedException, inst:
39 40 # another process may have started its own
40 41 # inotify server while this one was starting.
@@ -7,7 +7,7 b''
7 7 # GNU General Public License version 2, incorporated herein by reference.
8 8
9 9 from mercurial.i18n import _
10 from mercurial import osutil, util
10 from mercurial import cmdutil, osutil, util
11 11 import common
12 12 import errno, os, select, socket, stat, struct, sys, tempfile, time
13 13
@@ -823,52 +823,29 b' class master(object):'
823 823 sys.exit(0)
824 824 pollable.run()
825 825
826 def start(ui, dirstate, root):
827 def closefds(ignore):
828 # (from python bug #1177468)
829 # close all inherited file descriptors
830 # Python 2.4.1 and later use /dev/urandom to seed the random module's RNG
831 # a file descriptor is kept internally as os._urandomfd (created on demand
832 # the first time os.urandom() is called), and should not be closed
833 try:
834 os.urandom(4)
835 urandom_fd = getattr(os, '_urandomfd', None)
836 except AttributeError:
837 urandom_fd = None
838 ignore.append(urandom_fd)
839 for fd in range(3, 256):
840 if fd in ignore:
841 continue
826 def start(ui, dirstate, root, opts):
827 timeout = opts.get('timeout')
828 if timeout:
829 timeout = float(timeout) * 1e3
830
831 class service(object):
832 def init(self):
842 833 try:
843 os.close(fd)
844 except OSError:
845 pass
846
847 m = master(ui, dirstate, root)
848 sys.stdout.flush()
849 sys.stderr.flush()
834 self.master = master(ui, dirstate, root, timeout)
835 except AlreadyStartedException, inst:
836 raise util.Abort(str(inst))
850 837
851 pid = os.fork()
852 if pid:
853 return pid
854
855 closefds(pollable.instances.keys())
856 os.setsid()
857
858 fd = os.open('/dev/null', os.O_RDONLY)
859 os.dup2(fd, 0)
860 if fd > 0:
861 os.close(fd)
838 def run(self):
839 try:
840 self.master.run()
841 finally:
842 self.master.shutdown()
862 843
863 fd = os.open(ui.config('inotify', 'log', '/dev/null'),
864 os.O_RDWR | os.O_CREAT | os.O_TRUNC)
865 os.dup2(fd, 1)
866 os.dup2(fd, 2)
867 if fd > 2:
868 os.close(fd)
844 runargs = None
845 if 'inserve' not in sys.argv:
846 runargs = [sys.argv[0], 'inserve', '-R', root]
869 847
870 try:
871 m.run()
872 finally:
873 m.shutdown()
874 os._exit(0)
848 service = service()
849 logfile = ui.config('inotify', 'log')
850 cmdutil.service(opts, initfn=service.init, runfn=service.run,
851 logfile=logfile, runargs=runargs)
@@ -244,12 +244,14 b' class kwfilelog(filelog.filelog):'
244 244 return t2 != text
245 245 return revlog.revlog.cmp(self, node, text)
246 246
247 def _status(ui, repo, kwt, unknown, *pats, **opts):
247 def _status(ui, repo, kwt, *pats, **opts):
248 248 '''Bails out if [keyword] configuration is not active.
249 249 Returns status of working directory.'''
250 250 if kwt:
251 match = cmdutil.match(repo, pats, opts)
252 return repo.status(match=match, unknown=unknown, clean=True)
251 unknown = (opts.get('unknown') or opts.get('all')
252 or opts.get('untracked'))
253 return repo.status(match=cmdutil.match(repo, pats, opts), clean=True,
254 unknown=unknown)
253 255 if ui.configitems('keyword'):
254 256 raise util.Abort(_('[keyword] patterns cannot match'))
255 257 raise util.Abort(_('no [keyword] patterns configured'))
@@ -259,7 +261,7 b' def _kwfwrite(ui, repo, expand, *pats, *'
259 261 if repo.dirstate.parents()[1] != nullid:
260 262 raise util.Abort(_('outstanding uncommitted merge'))
261 263 kwt = kwtools['templater']
262 status = _status(ui, repo, kwt, False, *pats, **opts)
264 status = _status(ui, repo, kwt, *pats, **opts)
263 265 modified, added, removed, deleted = status[:4]
264 266 if modified or added or removed or deleted:
265 267 raise util.Abort(_('outstanding uncommitted changes'))
@@ -380,30 +382,32 b' def files(ui, repo, *pats, **opts):'
380 382 See "hg help keyword" on how to construct patterns both for
381 383 inclusion and exclusion of files.
382 384
383 Use -u/--untracked to list untracked files as well.
384
385 With -a/--all and -v/--verbose the codes used to show the status
385 With -A/--all and -v/--verbose the codes used to show the status
386 386 of files are::
387 387
388 388 K = keyword expansion candidate
389 k = keyword expansion candidate (untracked)
389 k = keyword expansion candidate (not tracked)
390 390 I = ignored
391 i = ignored (untracked)
391 i = ignored (not tracked)
392 392 '''
393 393 kwt = kwtools['templater']
394 status = _status(ui, repo, kwt, opts.get('untracked'), *pats, **opts)
394 status = _status(ui, repo, kwt, *pats, **opts)
395 cwd = pats and repo.getcwd() or ''
395 396 modified, added, removed, deleted, unknown, ignored, clean = status
396 files = sorted(modified + added + clean)
397 files = []
398 if not (opts.get('unknown') or opts.get('untracked')) or opts.get('all'):
399 files = sorted(modified + added + clean)
397 400 wctx = repo[None]
398 401 kwfiles = [f for f in files if kwt.iskwfile(f, wctx.flags)]
399 kwuntracked = [f for f in unknown if kwt.iskwfile(f, wctx.flags)]
400 cwd = pats and repo.getcwd() or ''
401 kwfstats = (not opts.get('ignore') and
402 (('K', kwfiles), ('k', kwuntracked),) or ())
402 kwunknown = [f for f in unknown if kwt.iskwfile(f, wctx.flags)]
403 if not opts.get('ignore') or opts.get('all'):
404 showfiles = kwfiles, kwunknown
405 else:
406 showfiles = [], []
403 407 if opts.get('all') or opts.get('ignore'):
404 kwfstats += (('I', [f for f in files if f not in kwfiles]),
405 ('i', [f for f in unknown if f not in kwuntracked]),)
406 for char, filenames in kwfstats:
408 showfiles += ([f for f in files if f not in kwfiles],
409 [f for f in unknown if f not in kwunknown])
410 for char, filenames in zip('KkIi', showfiles):
407 411 fmt = (opts.get('all') or ui.verbose) and '%s %%s\n' % char or '%s\n'
408 412 for f in filenames:
409 413 ui.write(fmt % repo.pathto(f, cwd))
@@ -545,9 +549,12 b' cmdtable = {'
545 549 _('hg kwexpand [OPTION]... [FILE]...')),
546 550 'kwfiles':
547 551 (files,
548 [('a', 'all', None, _('show keyword status flags of all files')),
552 [('A', 'all', None, _('show keyword status flags of all files')),
549 553 ('i', 'ignore', None, _('show files excluded from expansion')),
550 ('u', 'untracked', None, _('additionally show untracked files')),
554 ('u', 'unknown', None, _('only show unknown (not tracked) files')),
555 ('a', 'all', None,
556 _('show keyword status flags of all files (DEPRECATED)')),
557 ('u', 'untracked', None, _('only show untracked files (DEPRECATED)')),
551 558 ] + commands.walkopts,
552 559 _('hg kwfiles [OPTION]... [FILE]...')),
553 560 'kwshrink': (shrink, commands.walkopts,
@@ -43,6 +43,7 b' Optional configuration items::'
43 43 diffstat = True # add a diffstat before the diff content
44 44 sources = serve # notify if source of incoming changes in this list
45 45 # (serve == ssh or http, push, pull, bundle)
46 merge = False # send notification for merges (default True)
46 47 [email]
47 48 from = user@host.com # email address to send as if none given
48 49 [web]
@@ -111,6 +112,7 b' class notifier(object):'
111 112 self.test = self.ui.configbool('notify', 'test', True)
112 113 self.charsets = mail._charsets(self.ui)
113 114 self.subs = self.subscribers()
115 self.merge = self.ui.configbool('notify', 'merge', True)
114 116
115 117 mapfile = self.ui.config('notify', 'style')
116 118 template = (self.ui.config('notify', hooktype) or
@@ -166,10 +168,13 b' class notifier(object):'
166 168 return self.ui.config('web', 'baseurl') + (path or self.root)
167 169
168 170 def node(self, ctx, **props):
169 '''format one changeset.'''
171 '''format one changeset, unless it is a suppressed merge.'''
172 if not self.merge and len(ctx.parents()) > 1:
173 return False
170 174 self.t.show(ctx, changes=ctx.changeset(),
171 175 baseurl=self.ui.config('web', 'baseurl'),
172 176 root=self.repo.root, webroot=self.root, **props)
177 return True
173 178
174 179 def skipsource(self, source):
175 180 '''true if incoming changes from this source should be skipped.'''
@@ -283,16 +288,29 b' def hook(ui, repo, hooktype, node=None, '
283 288 return
284 289
285 290 ui.pushbuffer()
291 data = ''
292 count = 0
286 293 if hooktype == 'changegroup':
287 294 start, end = ctx.rev(), len(repo)
288 count = end - start
289 295 for rev in xrange(start, end):
290 n.node(repo[rev])
291 n.diff(ctx, repo['tip'])
296 if n.node(repo[rev]):
297 count += 1
298 else:
299 data += ui.popbuffer()
300 ui.note(_('notify: suppressing notification for merge %d:%s\n') %
301 (rev, repo[rev].hex()[:12]))
302 ui.pushbuffer()
303 if count:
304 n.diff(ctx, repo['tip'])
292 305 else:
293 count = 1
294 n.node(ctx)
306 if not n.node(ctx):
307 ui.popbuffer()
308 ui.note(_('notify: suppressing notification for merge %d:%s\n') %
309 (ctx.rev(), ctx.hex()[:12]))
310 return
311 count += 1
295 312 n.diff(ctx)
296 313
297 data = ui.popbuffer()
298 n.send(ctx, count, data)
314 data += ui.popbuffer()
315 if count:
316 n.send(ctx, count, data)
@@ -17,8 +17,8 b' msgid ""'
17 17 msgstr ""
18 18 "Project-Id-Version: Mercurial\n"
19 19 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
20 "POT-Creation-Date: 2009-07-20 23:05+0200\n"
21 "PO-Revision-Date: 2009-07-21 00:18+0200\n"
20 "POT-Creation-Date: 2009-09-29 00:26+0200\n"
21 "PO-Revision-Date: 2009-09-29 00:41+0200\n"
22 22 "Last-Translator: <mg@lazybytes.net>\n"
23 23 "Language-Team: Danish\n"
24 24 "MIME-Version: 1.0\n"
@@ -1007,7 +1007,8 b' msgstr "CVS pserver godkendelse fejlede"'
1007 1007 #, python-format
1008 1008 msgid ""
1009 1009 "unexpected response from CVS server (expected \"Valid-requests\", but got %r)"
1010 msgstr "uventet svar fra CVS serveren (forventede \"Valid-requests\", men fik %r)"
1010 msgstr ""
1011 "uventet svar fra CVS serveren (forventede \"Valid-requests\", men fik %r)"
1011 1012
1012 1013 #, python-format
1013 1014 msgid "%d bytes missing from remote file"
@@ -1086,6 +1087,10 b' msgstr ""'
1086 1087 msgid "%d changeset entries\n"
1087 1088 msgstr "%d ændringer\n"
1088 1089
1090 #, python-format
1091 msgid "darcs version 2.1 or newer needed (found %r)"
1092 msgstr ""
1093
1089 1094 msgid "Python ElementTree module is not available"
1090 1095 msgstr "Python ElementTree modulet er ikke tilstede"
1091 1096
@@ -1492,10 +1497,6 b' msgid "merging with %d:%s\\n"'
1492 1497 msgstr "sammenføjer med %d:%s\n"
1493 1498
1494 1499 #, python-format
1495 msgid "Automated merge with %s"
1496 msgstr "Automatisk sammenføjning med %s"
1497
1498 #, python-format
1499 1500 msgid "new changeset %d:%s merges remote changes with local\n"
1500 1501 msgstr "ny ændring %d:%s fletter fjernændringer sammen med lokale\n"
1501 1502
@@ -1576,10 +1577,6 b' msgstr ""'
1576 1577 "arbejdskopien af .hgsigs er ændret (deponer venligst .hgsigs manuelt eller "
1577 1578 "brug --force)"
1578 1579
1579 #, python-format
1580 msgid "Added signature for changeset %s"
1581 msgstr "Tilføjede underskrift af ændring %s"
1582
1583 1580 msgid "unknown signature version"
1584 1581 msgstr "ukendt underskrift-version"
1585 1582
@@ -2133,7 +2130,9 b' msgstr ""'
2133 2130 msgid ""
2134 2131 "\n"
2135 2132 "%s keywords written to %s:\n"
2136 msgstr "\n%s nøgleord skrevet til %s:\n"
2133 msgstr ""
2134 "\n"
2135 "%s nøgleord skrevet til %s:\n"
2137 2136
2138 2137 msgid "unhooked all commit hooks\n"
2139 2138 msgstr ""
@@ -3789,22 +3788,22 b' msgid ""'
3789 3788 msgstr ""
3790 3789
3791 3790 msgid "cannot use both abort and continue"
3792 msgstr ""
3791 msgstr "abort og continue kan ikke angives samtidig"
3793 3792
3794 3793 msgid "cannot use collapse with continue or abort"
3795 msgstr ""
3794 msgstr "continue eller abort kan ikke angives samtidig med collapse"
3796 3795
3797 3796 msgid "abort and continue do not allow specifying revisions"
3798 msgstr ""
3797 msgstr "abort og continue tillader ikke at der angives revisioner"
3799 3798
3800 3799 msgid "cannot specify both a revision and a base"
3801 msgstr ""
3800 msgstr "man kan ikke angive både en revision og en basis"
3802 3801
3803 3802 msgid "nothing to rebase\n"
3804 3803 msgstr ""
3805 3804
3806 3805 msgid "cannot use both keepbranches and extrafn"
3807 msgstr ""
3806 msgstr "man kan ikke bruge både keepbranches og extrafn"
3808 3807
3809 3808 msgid "rebase merging completed\n"
3810 3809 msgstr ""
@@ -3817,7 +3816,7 b' msgstr ""'
3817 3816
3818 3817 #, python-format
3819 3818 msgid "%d revisions have been skipped\n"
3820 msgstr ""
3819 msgstr "sprang %d revisioner over\n"
3821 3820
3822 3821 msgid " set parents\n"
3823 3822 msgstr ""
@@ -4275,7 +4274,7 b' msgid ""'
4275 4274 msgstr ""
4276 4275
4277 4276 #, python-format
4278 msgid "[win32mbcs] filename conversion fail with %s encoding\n"
4277 msgid "[win32mbcs] filename conversion failed with %s encoding\n"
4279 4278 msgstr ""
4280 4279
4281 4280 msgid "[win32mbcs] cannot activate on this platform.\n"
@@ -4668,12 +4667,27 b' msgid ""'
4668 4667 " be expensive.\n"
4669 4668 " "
4670 4669 msgstr ""
4670 "tilføj alle nye filer, fjern alle manglende filer\n"
4671 "\n"
4672 " Tilføj alle nye filer og fjern alle manglende filer fra depotet.\n"
4673 "\n"
4674 " Nye filer bliver ignoreret hvis de matcher et af mønstrene i\n"
4675 " .hgignore. Som ved add, så træder disse ændringer først i kræft\n"
4676 " ved næste commit.\n"
4677 "\n"
4678 " Brug -s/--similarity tilvalget for at opdage omdøbte filer. Med en\n"
4679 " parameter større end 0 bliver hver fjernet fil sammenlignet med\n"
4680 " enhver tilføjet fil og filer der er tilstrækkelig ens bliver\n"
4681 " opført som omdøbte. Dette tilvalg tager et procenttal mellem 0\n"
4682 " (slået fra) og 100 (filer skal være identiske) som parameter. At\n"
4683 " opdage omdøbninger på denne måde kan være dyrt.\n"
4684 " "
4671 4685
4672 4686 msgid "similarity must be a number"
4673 msgstr ""
4687 msgstr "lighedsgrad skal være et tal"
4674 4688
4675 4689 msgid "similarity must be between 0 and 100"
4676 msgstr ""
4690 msgstr "lighedsgrad skal være mellem 0 og 100"
4677 4691
4678 4692 msgid ""
4679 4693 "show changeset information by line for each file\n"
@@ -4705,10 +4719,10 b' msgstr ""'
4705 4719 " "
4706 4720
4707 4721 msgid "at least one filename or pattern is required"
4708 msgstr ""
4722 msgstr "kræver mindst et filnavn eller mønster"
4709 4723
4710 4724 msgid "at least one of -n/-c is required for -l"
4711 msgstr ""
4725 msgstr "brug af -l kræver mindst en af -n/-c"
4712 4726
4713 4727 #, python-format
4714 4728 msgid "%s: binary file\n"
@@ -4744,10 +4758,10 b' msgid "no working directory: please spec'
4744 4758 msgstr "intet arbejdskatalog: angive venligst en revision"
4745 4759
4746 4760 msgid "repository root cannot be destination"
4747 msgstr ""
4761 msgstr "depotets rod kan ikke bruges som destination"
4748 4762
4749 4763 msgid "cannot archive plain files to stdout"
4750 msgstr ""
4764 msgstr "flade filer kan ikke arkiveres til standarduddata"
4751 4765
4752 4766 msgid ""
4753 4767 "reverse effect of earlier changeset\n"
@@ -4806,11 +4820,7 b' msgid "%s is not a parent of %s"'
4806 4820 msgstr "%s er ikke forælder til %s"
4807 4821
4808 4822 msgid "cannot use --parent on non-merge changeset"
4809 msgstr ""
4810
4811 #, python-format
4812 msgid "Backed out changeset %s"
4813 msgstr ""
4823 msgstr "kan ikke bruge --parent på en ændringer som ikke er en sammenføjning"
4814 4824
4815 4825 #, python-format
4816 4826 msgid "changeset %s backs out changeset %s\n"
@@ -4824,7 +4834,7 b' msgid "the backout changeset is a new he'
4824 4834 msgstr ""
4825 4835
4826 4836 msgid "(use \"backout --merge\" if you want to auto-merge)\n"
4827 msgstr ""
4837 msgstr "(brug \"backout --merge\" hvis du vil sammenføje automatisk)\n"
4828 4838
4829 4839 msgid ""
4830 4840 "subdivision search of changesets\n"
@@ -4872,7 +4882,7 b' msgid "cannot bisect (no known bad revis'
4872 4882 msgstr ""
4873 4883
4874 4884 msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
4875 msgstr ""
4885 msgstr "(formen 'hg bisect <kommando>' er forældet)\n"
4876 4886
4877 4887 msgid "incompatible arguments"
4878 4888 msgstr "inkompatible argumenter"
@@ -4883,7 +4893,7 b' msgstr "kan ikke finde program: %s"'
4883 4893
4884 4894 #, python-format
4885 4895 msgid "failed to execute %s"
4886 msgstr ""
4896 msgstr "kunne ikke køre %s"
4887 4897
4888 4898 #, python-format
4889 4899 msgid "%s killed"
@@ -4917,10 +4927,27 b' msgid ""'
4917 4927 " 'hg commit --close-branch' to mark this branch as closed.\n"
4918 4928 " "
4919 4929 msgstr ""
4930 "angiv eller vis navnet på den aktuelle gren\n"
4931 "\n"
4932 " Uden noget argument vises navnet på den nuværende gren. Med et\n"
4933 " argument angives arbejdskatalogets grennavn (grenen eksisterer\n"
4934 " ikke i depotet før næste deponering). Det anbefales at den primære\n"
4935 " udvikling foretages på 'default' grenen.\n"
4936 "\n"
4937 " Med mindre -f/--force bruges, så vil branch ikke lade dig bruge et\n"
4938 " grennavn som allerede eksisterer, selv hvis det er inaktivt.\n"
4939 "\n"
4940 " Brug -C/--clean for at nulstille arbejdskatalogs gren til samme\n"
4941 " gren dets forældre-ændring og derved negere end tidligere ændring.\n"
4942 "\n"
4943 " Brug kommandoen 'hg update' for at skifte til en eksisterende\n"
4944 " gren. Brug 'hg commit --close-branch' for at markere denne gren\n"
4945 " som lukket.\n"
4946 " "
4920 4947
4921 4948 #, python-format
4922 4949 msgid "reset working directory to branch %s\n"
4923 msgstr ""
4950 msgstr "nulstil arbejdskataloget til gren %s\n"
4924 4951
4925 4952 msgid "a branch of the same name already exists (use --force to override)"
4926 4953 msgstr ""
@@ -5003,6 +5030,22 b' msgid ""'
5003 5030 " %p root-relative path name of file being printed\n"
5004 5031 " "
5005 5032 msgstr ""
5033 "udskriv den aktuelle eller en given revision af filer\n"
5034 "\n"
5035 " Udskriver de angivne filer som de så ud ved den givne revision.\n"
5036 " Hvis der ikke angves en revision, så bruges forældre-revisionen\n"
5037 " til arbejdskataloget, eller spidsen hvis der ikke er hentet noget\n"
5038 " arbejdskatalog.\n"
5039 "\n"
5040 " Output kan gemmes i en fil hvis navn angives med et formatstreng.\n"
5041 " Reglerne for formatteringen er de samme som for export-kommandoen\n"
5042 " med følgende tilføjelser:\n"
5043 "\n"
5044 " %s grundnavn for filen som udskrives\n"
5045 " %d katalognavn for filen som blvier udskrevet\n"
5046 " eller '.' hvis filen er i katalogets rod\n"
5047 " %p rod-relativ sti for filen som bliver udkrevet\n"
5048 " "
5006 5049
5007 5050 msgid ""
5008 5051 "make a copy of an existing repository\n"
@@ -5525,24 +5568,29 b' msgid ""'
5525 5568 "\n"
5526 5569 " With no arguments, show all repository head changesets.\n"
5527 5570 "\n"
5528 " Repository \"heads\" are changesets that don't have child\n"
5529 " changesets. They are where development generally takes place and\n"
5530 " are the usual targets for update and merge operations.\n"
5571 " Repository \"heads\" are changesets with no child changesets. They are\n"
5572 " where development generally takes place and are the usual targets\n"
5573 " for update and merge operations.\n"
5531 5574 "\n"
5532 5575 " If one or more REV is given, the \"branch heads\" will be shown for\n"
5533 " the named branch associated with that revision. The name of the\n"
5534 " branch is called the revision's branch tag.\n"
5535 "\n"
5536 " Branch heads are revisions on a given named branch that do not have\n"
5537 " any descendants on the same branch. A branch head could be a true head\n"
5538 " or it could be the last changeset on a branch before a new branch\n"
5539 " was created. If none of the branch heads are true heads, the branch\n"
5540 " is considered inactive. If -c/--closed is specified, also show branch\n"
5541 " heads marked closed (see hg commit --close-branch).\n"
5542 "\n"
5543 " If STARTREV is specified only those heads (or branch heads) that\n"
5544 " are descendants of STARTREV will be displayed.\n"
5545 " "
5576 " the named branch associated with the specified changeset(s).\n"
5577 "\n"
5578 " Branch heads are changesets on a named branch with no descendants on\n"
5579 " the same branch. A branch head could be a \"true\" (repository) head,\n"
5580 " or it could be the last changeset on that branch before it was\n"
5581 " merged into another branch, or it could be the last changeset on the\n"
5582 " branch before a new branch was created. If none of the branch heads\n"
5583 " are true heads, the branch is considered inactive.\n"
5584 "\n"
5585 " If -c/--closed is specified, also show branch heads marked closed\n"
5586 " (see hg commit --close-branch).\n"
5587 "\n"
5588 " If STARTREV is specified, only those heads that are descendants of\n"
5589 " STARTREV will be displayed.\n"
5590 " "
5591 msgstr ""
5592
5593 msgid "you must specify a branch to use --closed"
5546 5594 msgstr ""
5547 5595
5548 5596 #, python-format
@@ -6403,17 +6451,9 b' msgid "tag \'%s\' is not a local tag"'
6403 6451 msgstr "mærkaten '%s' er ikke en lokal mærkat"
6404 6452
6405 6453 #, python-format
6406 msgid "Removed tag %s"
6407 msgstr "Mærke %s er fjernet"
6408
6409 #, python-format
6410 6454 msgid "tag '%s' already exists (use -f to force)"
6411 6455 msgstr "mærkaten '%s' eksisterer allerede (brug -f for at gennemtvinge)"
6412 6456
6413 #, python-format
6414 msgid "Added tag %s for changeset %s"
6415 msgstr "Tilføjede mærkat %s til ændring %s"
6416
6417 6457 msgid ""
6418 6458 "list repository tags\n"
6419 6459 "\n"
@@ -6511,6 +6551,9 b' msgstr ""'
6511 6551 " Se 'hg help dates' for en liste af gyldige formater til -d/--date.\n"
6512 6552 " "
6513 6553
6554 msgid "cannot specify both -c/--check and -C/--clean"
6555 msgstr "man kan ikke angive både -c/--check og -C/--clean"
6556
6514 6557 msgid "uncommitted local changes"
6515 6558 msgstr "udeponerede lokale ændringer"
6516 6559
@@ -6525,6 +6568,14 b' msgid ""'
6525 6568 " integrity of their crosslinks and indices.\n"
6526 6569 " "
6527 6570 msgstr ""
6571 "verificer depotets integritet\n"
6572 "\n"
6573 " Verificer integreteten af det aktuelle depot.\n"
6574 "\n"
6575 " Dette vil lave en udførlig kontrol af depotets integritet.\n"
6576 " Hashværdier og tjeksummer valideres for hver indgang i\n"
6577 " historikfilen, manifæstet og fulgte filer. Desuden valideres\n"
6578 " integriteten af deres krydslinks og indekser."
6528 6579
6529 6580 msgid "output version and copyright information"
6530 6581 msgstr "udskriv version- og copyrightinformation"
@@ -6539,6 +6590,11 b' msgid ""'
6539 6590 "This is free software; see the source for copying conditions. There is NO\n"
6540 6591 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6541 6592 msgstr ""
6593 "\n"
6594 "Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> og andre\n"
6595 "Dette er frit programmel; se kildekoden for kopieringsbetingelser. Der\n"
6596 "gives INGEN GARANTI; ikke engang for SALGBARHED eller EGNETHED FOR\n"
6597 "NOGET BESTEMT FORMÅL.\n"
6542 6598
6543 6599 msgid "repository root directory or symbolic path name"
6544 6600 msgstr "depotrodfolder eller symbolsk stinavn"
@@ -6721,10 +6777,10 b' msgid "[-gbsr] [-c CMD] [REV]"'
6721 6777 msgstr "[-gbsr] [-c KOMMANDO] [REV]"
6722 6778
6723 6779 msgid "set branch name even if it shadows an existing branch"
6724 msgstr ""
6780 msgstr "sæt grennavnet selv hvis det overskygger en eksisterende gren"
6725 6781
6726 6782 msgid "reset branch name to parent branch name"
6727 msgstr ""
6783 msgstr "nulstil grennavnet til forældre-grennavnet"
6728 6784
6729 6785 msgid "[-fC] [NAME]"
6730 6786 msgstr "[-fC] [NAVN]"
@@ -6732,8 +6788,8 b' msgstr "[-fC] [NAVN]"'
6732 6788 msgid "show only branches that have unmerged heads"
6733 6789 msgstr "vil kun grene som har usammenføjne hoveder"
6734 6790
6735 msgid "show normal and closed heads"
6736 msgstr "vis normale og lukkede hoveder"
6791 msgid "show normal and closed branches"
6792 msgstr "vis normale og lukkede grene"
6737 6793
6738 6794 msgid "[-a]"
6739 6795 msgstr "[-a]"
@@ -6847,7 +6903,7 b' msgid "[OPTION]... [-r REV1 [-r REV2]] ['
6847 6903 msgstr "[TILVALG]... [-r REV1 [-r REV2]] [FIL]..."
6848 6904
6849 6905 msgid "diff against the second parent"
6850 msgstr ""
6906 msgstr "find forskelle i forhold til den anden forældre"
6851 6907
6852 6908 msgid "[OPTION]... [-o OUTFILESPEC] REV..."
6853 6909 msgstr "[TILVALG]... [-o UDFILSPECIFIKATION] REV..."
@@ -6879,8 +6935,11 b' msgstr "[TILVALG]... M\xc3\x98NSTER [FIL]..."'
6879 6935 msgid "show only heads which are descendants of REV"
6880 6936 msgstr "vis kun hoveder som er efterkommere af REV"
6881 6937
6882 msgid "show only the active heads from open branches"
6883 msgstr "vis kun aktive hoveder fra åbne grene"
6938 msgid "show only the active branch heads from open branches"
6939 msgstr "vis kun de aktive grenhoveder fra åbne grene"
6940
6941 msgid "show normal and closed branch heads"
6942 msgstr "vis normale og lukkede grenhoveder"
6884 6943
6885 6944 msgid "[-r STARTREV] [REV]..."
6886 6945 msgstr "[-r STARTREV] [REV]..."
@@ -7766,22 +7825,21 b' msgid ""'
7766 7825 " Mercurial supports several ways to specify individual revisions.\n"
7767 7826 "\n"
7768 7827 " A plain integer is treated as a revision number. Negative integers\n"
7769 " are treated as topological offsets from the tip, with -1 denoting\n"
7770 " the tip. As such, negative numbers are only useful if you've\n"
7771 " memorized your local tree numbers and want to save typing a single\n"
7772 " digit. This editor suggests copy and paste.\n"
7828 " are treated as sequential offsets from the tip, with -1 denoting\n"
7829 " the tip, -2 denoting the revision prior to the tip, and so forth.\n"
7773 7830 "\n"
7774 7831 " A 40-digit hexadecimal string is treated as a unique revision\n"
7775 7832 " identifier.\n"
7776 7833 "\n"
7777 7834 " A hexadecimal string less than 40 characters long is treated as a\n"
7778 " unique revision identifier, and referred to as a short-form\n"
7835 " unique revision identifier and is referred to as a short-form\n"
7779 7836 " identifier. A short-form identifier is only valid if it is the\n"
7780 7837 " prefix of exactly one full-length identifier.\n"
7781 7838 "\n"
7782 " Any other string is treated as a tag name, which is a symbolic\n"
7783 " name associated with a revision identifier. Tag names may not\n"
7784 " contain the \":\" character.\n"
7839 " Any other string is treated as a tag or branch name. A tag name is\n"
7840 " a symbolic name associated with a revision identifier. A branch\n"
7841 " name denotes the tipmost revision of that branch. Tag and branch\n"
7842 " names must not contain the \":\" character.\n"
7785 7843 "\n"
7786 7844 " The reserved name \"tip\" is a special tag that always identifies\n"
7787 7845 " the most recent revision.\n"
@@ -7943,13 +8001,19 b' msgid ""'
7943 8001 " - nonempty: Any text. Returns '(none)' if the string is empty.\n"
7944 8002 " - hgdate: Date. Returns the date as a pair of numbers:\n"
7945 8003 " \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
7946 " - isodate: Date. Returns the date in ISO 8601 format.\n"
8004 " - isodate: Date. Returns the date in ISO 8601 format: \"2009-08-18\n"
8005 " 13:00 +0200\".\n"
8006 " - isodatesec: Date. Returns the date in ISO 8601 format, including\n"
8007 " seconds: \"2009-08-18 13:00:13 +0200\". See also the\n"
8008 " rfc3339date filter.\n"
7947 8009 " - localdate: Date. Converts a date to local date.\n"
7948 8010 " - obfuscate: Any text. Returns the input text rendered as a\n"
7949 8011 " sequence of XML entities.\n"
7950 8012 " - person: Any text. Returns the text before an email address.\n"
7951 8013 " - rfc822date: Date. Returns a date using the same format used\n"
7952 " in email headers.\n"
8014 " in email headers: \"Tue, 18 Aug 2009 13:00:13 +0200\".\n"
8015 " - rfc3339date: Date. Returns a date using the Internet date format\n"
8016 " specified in RFC 3339: \"2009-08-18T13:00:13+02:00\".\n"
7953 8017 " - short: Changeset hash. Returns the short form of a changeset\n"
7954 8018 " hash, i.e. a 12-byte hexadecimal string.\n"
7955 8019 " - shortdate: Date. Returns a date like \"2006-09-18\".\n"
@@ -9812,22 +9812,21 b' msgid ""'
9812 9812 " Mercurial supports several ways to specify individual revisions.\n"
9813 9813 "\n"
9814 9814 " A plain integer is treated as a revision number. Negative integers\n"
9815 " are treated as topological offsets from the tip, with -1 denoting\n"
9816 " the tip. As such, negative numbers are only useful if you've\n"
9817 " memorized your local tree numbers and want to save typing a single\n"
9818 " digit. This editor suggests copy and paste.\n"
9815 " are treated as sequential offsets from the tip, with -1 denoting\n"
9816 " the tip, -2 denoting the revision prior to the tip, and so forth.\n"
9819 9817 "\n"
9820 9818 " A 40-digit hexadecimal string is treated as a unique revision\n"
9821 9819 " identifier.\n"
9822 9820 "\n"
9823 9821 " A hexadecimal string less than 40 characters long is treated as a\n"
9824 " unique revision identifier, and referred to as a short-form\n"
9822 " unique revision identifier and is referred to as a short-form\n"
9825 9823 " identifier. A short-form identifier is only valid if it is the\n"
9826 9824 " prefix of exactly one full-length identifier.\n"
9827 9825 "\n"
9828 " Any other string is treated as a tag name, which is a symbolic\n"
9829 " name associated with a revision identifier. Tag names may not\n"
9830 " contain the \":\" character.\n"
9826 " Any other string is treated as a tag or branch name. A tag name is\n"
9827 " a symbolic name associated with a revision identifier. A branch\n"
9828 " name denotes the tipmost revision of that branch. Tag and branch\n"
9829 " names must not contain the \":\" character.\n"
9831 9830 "\n"
9832 9831 " The reserved name \"tip\" is a special tag that always identifies\n"
9833 9832 " the most recent revision.\n"
@@ -9846,23 +9845,22 b' msgstr ""'
9846 9845 " individuais.\n"
9847 9846 "\n"
9848 9847 " Um simples inteiro é tratado como um número de revisão. Inteiros\n"
9849 " negativos são tratados como contados topologicamente a partir da\n"
9850 " tip, com -1 denotando a tip. Assim, números negativos são úteis\n"
9851 " apenas se você memorizou os números de sua árvore local e quiser\n"
9852 " evitar digitar um único caractere. Este editor sugere copiar e\n"
9853 " colar.\n"
9848 " negativos são contados a partir da tip, com -1 denotando a tip,\n"
9849 " -2 denotando a revisão anterior à tip, e assim por diante.\n"
9854 9850 "\n"
9855 9851 " Uma string hexadecimal de 40 dígitos é tratada como um\n"
9856 9852 " identificador único de revisão.\n"
9857 9853 "\n"
9858 9854 " Uma string hexadecimal de menos de 40 caracteres é tratada como\n"
9859 " um identificador único de revisão, e referida como um\n"
9860 " identificador curto. Um identificador curto é válido apenas se\n"
9861 " for o prefixo de um identificador completo.\n"
9862 "\n"
9863 " Qualquer outra string é tratada como um nome de etiqueta, que é\n"
9864 " um nome simbólico associado a um identificador de revisão. Nomes\n"
9865 " de etiqueta não podem conter o caractere \":\".\n"
9855 " um identificador único de revisão, chamado de identificador\n"
9856 " curto. Um identificador curto é válido apenas se for o prefixo\n"
9857 " de um identificador completo.\n"
9858 "\n"
9859 " Qualquer outra string é tratada como um nome de etiqueta ou\n"
9860 " ramo. Um nome de etiqueta é um nome simbólico associado a um\n"
9861 " identificador de revisão. Um nome de ramo denota a revisão mais\n"
9862 " recente de tal ramo. Nomes de etiqueta ou de ramo não podem\n"
9863 " conter o caractere \":\".\n"
9866 9864 "\n"
9867 9865 " O nome reservado \"tip\" é uma etiqueta especial que sempre\n"
9868 9866 " identifica a revisão mais recente.\n"
@@ -10076,13 +10074,19 b' msgid ""'
10076 10074 " - nonempty: Any text. Returns '(none)' if the string is empty.\n"
10077 10075 " - hgdate: Date. Returns the date as a pair of numbers:\n"
10078 10076 " \"1157407993 25200\" (Unix timestamp, timezone offset).\n"
10079 " - isodate: Date. Returns the date in ISO 8601 format.\n"
10077 " - isodate: Date. Returns the date in ISO 8601 format: \"2009-08-18\n"
10078 " 13:00 +0200\".\n"
10079 " - isodatesec: Date. Returns the date in ISO 8601 format, including\n"
10080 " seconds: \"2009-08-18 13:00:13 +0200\". See also the\n"
10081 " rfc3339date filter.\n"
10080 10082 " - localdate: Date. Converts a date to local date.\n"
10081 10083 " - obfuscate: Any text. Returns the input text rendered as a\n"
10082 10084 " sequence of XML entities.\n"
10083 10085 " - person: Any text. Returns the text before an email address.\n"
10084 10086 " - rfc822date: Date. Returns a date using the same format used\n"
10085 " in email headers.\n"
10087 " in email headers: \"Tue, 18 Aug 2009 13:00:13 +0200\".\n"
10088 " - rfc3339date: Date. Returns a date using the Internet date format\n"
10089 " specified in RFC 3339: \"2009-08-18T13:00:13+02:00\".\n"
10086 10090 " - short: Changeset hash. Returns the short form of a changeset\n"
10087 10091 " hash, i.e. a 12-byte hexadecimal string.\n"
10088 10092 " - shortdate: Date. Returns a date like \"2006-09-18\".\n"
@@ -10186,14 +10190,17 b' msgstr ""'
10186 10190 " - nonempty: Qualquer texto. Devolve (none) se o texto for vazio.\n"
10187 10191 " - hgdate: Data. Devolve a data como um par de números:\n"
10188 10192 " \"1157407993 25200\" (timestamp Unix, defasagem de fuso)\n"
10189 " - isodate: Data. Devolve a data em formato ISO 8601.\n"
10193 " - isodate: Data. Devolve a data em formato ISO 8601: \"2009-08-18\n"
10194 " 13:00 +0200\".\n"
10190 10195 " - localdate: Data. Converte para data local.\n"
10191 10196 " - obfuscate: Qualquer texto. Devolve o texto de entrada\n"
10192 10197 " renderizado como uma seqüência de entidades XML.\n"
10193 10198 " - person: Qualquer texto. Devolve o texto antes de um endereço\n"
10194 10199 " de e-mail.\n"
10195 " - rfc822date: Data. Devolve uma data usando o mesmo formato\n"
10196 " utilizado em cabeçalhos de e-mail.\n"
10200 " - rfc822date: Data. Devolve uma data usando o mesmo formato utilizado\n"
10201 " em cabeçalhos de e-mail: \"Tue, 18 Aug 2009 13:00:13 +0200\".\n"
10202 " - rfc3339date: Data. Devolve uma data usando o formato de data da\n"
10203 " Internet especificado na RFC 3339: \"2009-08-18T13:00:13+02:00\".\n"
10197 10204 " - short: Hash do changeset. Devolve a forma curta do hash de\n"
10198 10205 " um changeset, ou seja, uma string hexadecimal de 12 bytes.\n"
10199 10206 " - shortdate: Data. Devolve uma data como \"2006-09-18\".\n"
@@ -546,24 +546,26 b' def copy(ui, repo, pats, opts, rename=Fa'
546 546
547 547 return errors
548 548
549 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None):
549 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
550 runargs=None):
550 551 '''Run a command as a service.'''
551 552
552 553 if opts['daemon'] and not opts['daemon_pipefds']:
553 554 rfd, wfd = os.pipe()
554 args = sys.argv[:]
555 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
555 if not runargs:
556 runargs = sys.argv[:]
557 runargs.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
556 558 # Don't pass --cwd to the child process, because we've already
557 559 # changed directory.
558 for i in xrange(1,len(args)):
559 if args[i].startswith('--cwd='):
560 del args[i]
560 for i in xrange(1,len(runargs)):
561 if runargs[i].startswith('--cwd='):
562 del runargs[i]
561 563 break
562 elif args[i].startswith('--cwd'):
563 del args[i:i+2]
564 elif runargs[i].startswith('--cwd'):
565 del runargs[i:i+2]
564 566 break
565 567 pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
566 args[0], args)
568 runargs[0], runargs)
567 569 os.close(wfd)
568 570 os.read(rfd, 1)
569 571 if parentfn:
@@ -1356,23 +1356,25 b' def heads(ui, repo, *branchrevs, **opts)'
1356 1356
1357 1357 With no arguments, show all repository head changesets.
1358 1358
1359 Repository "heads" are changesets that don't have child
1360 changesets. They are where development generally takes place and
1361 are the usual targets for update and merge operations.
1359 Repository "heads" are changesets with no child changesets. They are
1360 where development generally takes place and are the usual targets
1361 for update and merge operations.
1362 1362
1363 1363 If one or more REV is given, the "branch heads" will be shown for
1364 the named branch associated with that revision. The name of the
1365 branch is called the revision's branch tag.
1366
1367 Branch heads are revisions on a given named branch that do not have
1368 any descendants on the same branch. A branch head could be a true head
1369 or it could be the last changeset on a branch before a new branch
1370 was created. If none of the branch heads are true heads, the branch
1371 is considered inactive. If -c/--closed is specified, also show branch
1372 heads marked closed (see hg commit --close-branch).
1373
1374 If STARTREV is specified only those heads (or branch heads) that
1375 are descendants of STARTREV will be displayed.
1364 the named branch associated with the specified changeset(s).
1365
1366 Branch heads are changesets on a named branch with no descendants on
1367 the same branch. A branch head could be a "true" (repository) head,
1368 or it could be the last changeset on that branch before it was
1369 merged into another branch, or it could be the last changeset on the
1370 branch before a new branch was created. If none of the branch heads
1371 are true heads, the branch is considered inactive.
1372
1373 If -c/--closed is specified, also show branch heads marked closed
1374 (see hg commit --close-branch).
1375
1376 If STARTREV is specified, only those heads that are descendants of
1377 STARTREV will be displayed.
1376 1378 """
1377 1379 if opts.get('rev'):
1378 1380 start = repo.lookup(opts['rev'])
@@ -38,6 +38,9 b' def _decdirs(dirs, path):'
38 38 class dirstate(object):
39 39
40 40 def __init__(self, opener, ui, root):
41 '''Create a new dirstate object. opener is an open()-like callable
42 that can be used to open the dirstate file; root is the root of the
43 directory tracked by the dirstate.'''
41 44 self._opener = opener
42 45 self._root = root
43 46 self._rootdir = os.path.join(root, '')
@@ -47,6 +50,8 b' class dirstate(object):'
47 50
48 51 @propertycache
49 52 def _map(self):
53 '''Return the dirstate contents as a map from filename to
54 (state, mode, size, time).'''
50 55 self._read()
51 56 return self._map
52 57
@@ -169,12 +174,14 b' class dirstate(object):'
169 174 return path
170 175
171 176 def __getitem__(self, key):
172 ''' current states:
173 n normal
174 m needs merging
175 r marked for removal
176 a marked for addition
177 ? not tracked'''
177 '''Return the current state of key (a filename) in the dirstate.
178 States are:
179 n normal
180 m needs merging
181 r marked for removal
182 a marked for addition
183 ? not tracked
184 '''
178 185 return self._map.get(key, ("?",))[0]
179 186
180 187 def __contains__(self, key):
@@ -373,13 +380,9 b' class dirstate(object):'
373 380 return
374 381 st = self._opener("dirstate", "w", atomictemp=True)
375 382
376 try:
377 gran = int(self._ui.config('dirstate', 'granularity', 1))
378 except ValueError:
379 gran = 1
380 if gran > 0:
381 hlimit = util.fstat(st).st_mtime
382 llimit = hlimit - gran
383 # use the modification time of the newly created temporary file as the
384 # filesystem's notion of 'now'
385 now = int(util.fstat(st).st_mtime)
383 386
384 387 cs = cStringIO.StringIO()
385 388 copymap = self._copymap
@@ -389,9 +392,19 b' class dirstate(object):'
389 392 for f, e in self._map.iteritems():
390 393 if f in copymap:
391 394 f = "%s\0%s" % (f, copymap[f])
392 if gran > 0 and e[0] == 'n' and llimit < e[3] <= hlimit:
393 # file was updated too recently, ignore stat data
394 e = (e[0], 0, -1, -1)
395
396 if e[0] == 'n' and e[3] == now:
397 # The file was last modified "simultaneously" with the current
398 # write to dirstate (i.e. within the same second for file-
399 # systems with a granularity of 1 sec). This commonly happens
400 # for at least a couple of files on 'update'.
401 # The user could change the file without changing its size
402 # within the same second. Invalidate the file's stat data in
403 # dirstate, forcing future 'status' calls to compare the
404 # contents of the file. This prevents mistakenly treating such
405 # files as clean.
406 e = (e[0], 0, -1, -1) # mark entry as 'unset'
407
395 408 e = pack(_format, e[0], e[1], e[2], e[3], len(f))
396 409 write(e)
397 410 write(f)
@@ -411,11 +424,11 b' class dirstate(object):'
411 424
412 425 def walk(self, match, unknown, ignored):
413 426 '''
414 walk recursively through the directory tree, finding all files
415 matched by the match function
427 Walk recursively through the directory tree, finding all files
428 matched by match.
416 429
417 results are yielded in a tuple (filename, stat), where stat
418 and st is the stat result if the file was found in the directory.
430 Return a dict mapping filename to stat-like object (either
431 mercurial.osutil.stat instance or return value of os.stat()).
419 432 '''
420 433
421 434 def fwarn(f, msg):
@@ -553,12 +566,38 b' class dirstate(object):'
553 566 return results
554 567
555 568 def status(self, match, ignored, clean, unknown):
569 '''Determine the status of the working copy relative to the
570 dirstate and return a tuple of lists (unsure, modified, added,
571 removed, deleted, unknown, ignored, clean), where:
572
573 unsure:
574 files that might have been modified since the dirstate was
575 written, but need to be read to be sure (size is the same
576 but mtime differs)
577 modified:
578 files that have definitely been modified since the dirstate
579 was written (different size or mode)
580 added:
581 files that have been explicitly added with hg add
582 removed:
583 files that have been explicitly removed with hg remove
584 deleted:
585 files that have been deleted through other means ("missing")
586 unknown:
587 files not in the dirstate that are not ignored
588 ignored:
589 files not in the dirstate that are ignored
590 (by _dirignore())
591 clean:
592 files that have definitely not been modified since the
593 dirstate was written
594 '''
556 595 listignored, listclean, listunknown = ignored, clean, unknown
557 596 lookup, modified, added, unknown, ignored = [], [], [], [], []
558 597 removed, deleted, clean = [], [], []
559 598
560 599 dmap = self._map
561 ladd = lookup.append
600 ladd = lookup.append # aka "unsure"
562 601 madd = modified.append
563 602 aadd = added.append
564 603 uadd = unknown.append
@@ -165,17 +165,11 b' def testpid(pid):'
165 165 return inst.errno != errno.ESRCH
166 166
167 167 def explain_exit(code):
168 """return a 2-tuple (desc, code) describing a process's status"""
169 if os.WIFEXITED(code):
170 val = os.WEXITSTATUS(code)
171 return _("exited with status %d") % val, val
172 elif os.WIFSIGNALED(code):
173 val = os.WTERMSIG(code)
174 return _("killed by signal %d") % val, val
175 elif os.WIFSTOPPED(code):
176 val = os.WSTOPSIG(code)
177 return _("stopped by signal %d") % val, val
178 raise ValueError(_("invalid exit code"))
168 """return a 2-tuple (desc, code) describing a subprocess status
169 (codes from kill are negative - not os.system/wait encoding)"""
170 if code >= 0:
171 return _("exited with status %d") % code, code
172 return _("killed by signal %d") % -code, -code
179 173
180 174 def isowner(st):
181 175 """Return True if the stat object st is from the current user."""
@@ -48,8 +48,7 b' def stream_out(repo, untrusted=False):'
48 48 try:
49 49 repo.ui.debug('scanning\n')
50 50 for name, ename, size in repo.store.walk():
51 # for backwards compat, name was partially encoded
52 entries.append((store.encodedir(name), size))
51 entries.append((name, size))
53 52 total_bytes += size
54 53 finally:
55 54 lock.release()
@@ -62,6 +61,7 b' def stream_out(repo, untrusted=False):'
62 61 yield '%d %d\n' % (len(entries), total_bytes)
63 62 for name, size in entries:
64 63 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
65 yield '%s\0%d\n' % (name, size)
64 # partially encode name over the wire for backwards compat
65 yield '%s\0%d\n' % (store.encodedir(name), size)
66 66 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
67 67 yield chunk
@@ -167,7 +167,7 b' class hgsubrepo(object):'
167 167 self._repo.ui.note(_('removing subrepo %s\n') % self._path)
168 168 hg.clean(self._repo, node.nullid, False)
169 169
170 def get(self, state):
170 def _get(self, state):
171 171 source, revision = state
172 172 try:
173 173 self._repo.lookup(revision)
@@ -178,9 +178,13 b' class hgsubrepo(object):'
178 178 other = hg.repository(self._repo.ui, srcurl)
179 179 self._repo.pull(other)
180 180
181 def get(self, state):
182 self._get(state)
183 source, revision = state
181 184 hg.clean(self._repo, revision, False)
182 185
183 186 def merge(self, state):
187 self._get(state)
184 188 hg.merge(self._repo, state[1], remind=False)
185 189
186 190 def push(self, force):
@@ -357,41 +357,26 b' def system(cmd, environ={}, cwd=None, on'
357 357 if val is True:
358 358 return '1'
359 359 return str(val)
360 oldenv = {}
361 for k in environ:
362 oldenv[k] = os.environ.get(k)
363 if cwd is not None:
364 oldcwd = os.getcwd()
365 360 origcmd = cmd
366 361 if os.name == 'nt':
367 362 cmd = '"%s"' % cmd
368 try:
369 for k, v in environ.iteritems():
370 os.environ[k] = py2shell(v)
371 os.environ['HG'] = hgexecutable()
372 if cwd is not None and oldcwd != cwd:
373 os.chdir(cwd)
374 rc = os.system(cmd)
375 if sys.platform == 'OpenVMS' and rc & 1:
376 rc = 0
377 if rc and onerr:
378 errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]),
379 explain_exit(rc)[0])
380 if errprefix:
381 errmsg = '%s: %s' % (errprefix, errmsg)
382 try:
383 onerr.warn(errmsg + '\n')
384 except AttributeError:
385 raise onerr(errmsg)
386 return rc
387 finally:
388 for k, v in oldenv.iteritems():
389 if v is None:
390 del os.environ[k]
391 else:
392 os.environ[k] = v
393 if cwd is not None and oldcwd != cwd:
394 os.chdir(oldcwd)
363 env = dict(os.environ)
364 env.update((k, py2shell(v)) for k, v in environ.iteritems())
365 env['HG'] = hgexecutable()
366 rc = subprocess.call(cmd, shell=True, close_fds=closefds,
367 env=env, cwd=cwd)
368 if sys.platform == 'OpenVMS' and rc & 1:
369 rc = 0
370 if rc and onerr:
371 errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]),
372 explain_exit(rc)[0])
373 if errprefix:
374 errmsg = '%s: %s' % (errprefix, errmsg)
375 try:
376 onerr.warn(errmsg + '\n')
377 except AttributeError:
378 raise onerr(errmsg)
379 return rc
395 380
396 381 def checksignature(func):
397 382 '''wrap a function with code to check for calling errors'''
@@ -1280,9 +1265,12 b' def wrap(line, hangindent, width=None):'
1280 1265 padding = '\n' + ' ' * hangindent
1281 1266 # To avoid corrupting multi-byte characters in line, we must wrap
1282 1267 # a Unicode string instead of a bytestring.
1283 u = line.decode(encoding.encoding)
1284 w = padding.join(textwrap.wrap(u, width=width - hangindent))
1285 return w.encode(encoding.encoding)
1268 try:
1269 u = line.decode(encoding.encoding)
1270 w = padding.join(textwrap.wrap(u, width=width - hangindent))
1271 return w.encode(encoding.encoding)
1272 except UnicodeDecodeError:
1273 return padding.join(textwrap.wrap(line, width=width - hangindent))
1286 1274
1287 1275 def iterlines(iterator):
1288 1276 for chunk in iterator:
@@ -5,6 +5,11 b' cp "$TESTDIR"/printenv.py .'
5 5 hg init test
6 6 cd test
7 7 echo foo>foo
8 mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
9 echo foo>foo.d/foo
10 echo bar>foo.d/bAr.hg.d/BaR
11 echo bar>foo.d/baR.d.hg/bAR
12
8 13 hg commit -A -m 1
9 14 hg --config server.uncompressed=True serve -p $HGPORT -d --pid-file=../hg1.pid
10 15 hg serve -p $HGPORT1 -d --pid-file=../hg2.pid
@@ -1,4 +1,7 b''
1 1 adding foo
2 adding foo.d/bAr.hg.d/BaR
3 adding foo.d/baR.d.hg/bAR
4 adding foo.d/foo
2 5 abort: cannot start server at ':20060':
3 6 % clone via stream
4 7 streaming all changes
@@ -10,31 +13,31 b' checking changesets'
10 13 checking manifests
11 14 crosschecking files in changesets and manifests
12 15 checking files
13 1 files, 1 changesets, 1 total revisions
16 4 files, 1 changesets, 4 total revisions
14 17 % try to clone via stream, should use pull instead
15 18 requesting all changes
16 19 adding changesets
17 20 adding manifests
18 21 adding file changes
19 added 1 changesets with 1 changes to 1 files
22 added 1 changesets with 4 changes to 4 files
20 23 updating working directory
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 25 % clone via pull
23 26 requesting all changes
24 27 adding changesets
25 28 adding manifests
26 29 adding file changes
27 added 1 changesets with 1 changes to 1 files
30 added 1 changesets with 4 changes to 4 files
28 31 updating working directory
29 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
32 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 33 checking changesets
31 34 checking manifests
32 35 crosschecking files in changesets and manifests
33 36 checking files
34 1 files, 1 changesets, 1 total revisions
37 4 files, 1 changesets, 4 total revisions
35 38 adding bar
36 39 % pull
37 changegroup hook: HG_NODE=cfbd11a1fa315300a080c3de8fe36b0fc5820acf HG_SOURCE=pull HG_URL=http://localhost/
40 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=http://localhost/
38 41 pulling from http://localhost/
39 42 searching for changes
40 43 adding changesets
@@ -1,5 +1,5 b''
1 1 % fail
2 could not talk to new inotify server: No such file or directory
2 abort: could not start server: File exists
3 3 abort: could not start server: File exists
4 4 % inserve
5 5 % status
@@ -48,6 +48,11 b" echo 'ignore $Id$' > b"
48 48 echo % cat
49 49 cat a b
50 50
51 echo % no kwfiles
52 hg kwfiles
53 echo % untracked candidates
54 hg -v kwfiles --unknown
55
51 56 echo % addremove
52 57 hg addremove
53 58 echo % status
@@ -162,6 +167,10 b' hg status'
162 167
163 168 echo % kwfiles
164 169 hg kwfiles
170 echo % ignored files
171 hg -v kwfiles --ignore
172 echo % all files
173 hg kwfiles --all
165 174
166 175 echo % diff --rev
167 176 hg diff --rev 1 | grep -v 'b/c'
@@ -42,6 +42,9 b' expand $Id$'
42 42 do not process $Id:
43 43 xxx $
44 44 ignore $Id$
45 % no kwfiles
46 % untracked candidates
47 k a
45 48 % addremove
46 49 adding a
47 50 adding b
@@ -181,6 +184,14 b' xxx $'
181 184 % kwfiles
182 185 a
183 186 c
187 % ignored files
188 I b
189 I sym
190 % all files
191 K a
192 K c
193 I b
194 I sym
184 195 % diff --rev
185 196 diff -r ef63ca68695b c
186 197 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -35,6 +35,7 b' Optional configuration items:'
35 35 diffstat = True # add a diffstat before the diff content
36 36 sources = serve # notify if source of incoming changes in this list
37 37 # (serve == ssh or http, push, pull, bundle)
38 merge = False # send notification for merges (default True)
38 39 [email]
39 40 from = user@host.com # email address to send as if none given
40 41 [web]
General Comments 0
You need to be logged in to leave comments. Login now