##// END OF EJS Templates
Merge with TAH...
mpm@selenic.com -
r547:4fc63e22 merge default
parent child Browse files
Show More
@@ -1,46 +1,44 b''
1 1 General:
2 2 - Better documentation
3 3 - More regression tests
4 4 - More specific try/except.
5 5 - less code duplication, more code in the right places
6 6 - python 2.2 support
7 7 - better import support
8 8 - export to git
9 9 - Add standard files: ChangeLog? What else?
10 10 - Code cleanup: apply http://python.org/peps/pep-0008.html
11 11 - Replace all remaining print statements with appropriate ui function
12 12
13 13 Core:
14 14 - difflib creating/removing files (fixed except dates: should be epoch)
15 15 - directory foo.d or foo.i with existing file foo (use some quoting?)
16 16 - get various options from hgrc (e.g. history always -v, tip always -q)
17 17 - better push support (hack exists)
18 - hg over ssh:// and https://
19 - commit mailinglist/trigger/hooks
18 - hg over ssh:// and https:// and rsync://
19 - hooks for new changesets getting pulled/imported etc.
20 20 - make showing removed files (in history etc.) faster.
21 21
22 22 Commands:
23 23 - hg add <directory> should work
24 24 - hg status <filename>: file rev, changeset rev, changed, added,
25 25 deleted, sha-1
26 26 - select to pull a subset of the heads
27 27 - commands.py: number of args too much magic (e.g. in patch())
28 28 - automatic pull fallback to old-http://
29 - hg pull http://example.com doesn't say that no repo was found
30 - hg annotate -u and hgweb annotate with long $EMAIL
31 29 - hg pull default in a subdir doesn't work, if it is a relative path
32 30 - optionally only show merges (two parents or parent != changeset-1, etc.)
33 31
34 32 Web:
35 33 - show tags in hgweb
36 34 - show parent changeset number in hgweb
37 35 - optionally only show merges (two parents or parent != changeset-1, etc.)
38 36 - one hgweb with many repos (another script)
39 37 - hgweb tip link too verbose
40 38 - hgweb: deliver static files (e.g. favicon, stylesheets)
41 39 - hgweb personalization: timezone (display/change), display of
42 40 features
43 41 - hg export 240 shows -tkmerge (good), hgweb does not (bad).
44 42 - some web servers think hgweb.cgi.[di] is a CGI script with old-http://
45 43 (use quoting (see foo.d in Core) or document server configurations?)
46 44 - link children in hgweb
@@ -1,47 +1,47 b''
1 #!/bin/bash
1 #!/bin/sh
2 2 #
3 3 # This is an example of using HGEDITOR to automate the signing of
4 4 # commits and so on.
5 5
6 6 T1=""; T2=""
7 7 cleanup_exit() {
8 8 rm -f "$T1" "$T2"
9 9 exit $1
10 10 }
11 11
12 12 case "${EDITOR:=vi}" in
13 13 emacs)
14 14 EDITOR="$EDITOR -nw"
15 15 ;;
16 16 gvim|vim)
17 17 EDITOR="$EDITOR -f -o"
18 18 ;;
19 19 esac
20 20
21 21 if grep -q "^HG: merge resolve" "$1" ; then
22 22 # we don't sign merges
23 23 exec $EDITOR "$1"
24 24 else
25 25 T1=`mktemp`; T2=`mktemp`
26 26 MANIFEST=`grep '^HG: manifest hash' "$1" | cut -b 19-`
27 27
28 28 echo -e "\n\nmanifest hash: $MANIFEST" >> "$T1"
29 29 grep -vE '^(HG: manifest hash .*)?$' "$1" >> "$T1"
30 30 (
31 31 cd "`hg root`"
32 32 grep '^HG: changed' "$1" | cut -b 13- | while read changed; do
33 33 hg diff "$changed" >> "$T2"
34 34 done
35 35 )
36 36
37 37 CHECKSUM=`md5sum "$T1"`
38 38 $EDITOR "$T1" "$T2" || cleanup_exit $?
39 39 echo "$CHECKSUM" | md5sum -c 2>/dev/null && cleanup_exit 0
40 40 {
41 41 head -1 "$T1"
42 42 echo
43 43 grep -v "^HG:" "$T1" | gpg -a -u "${HGUSER:-$EMAIL}" --clearsign
44 44 } > "$T2" && mv "$T2" "$1"
45 45 cleanup_exit $?
46 46 fi
47 47
@@ -1,83 +1,83 b''
1 #!/bin/bash
1 #!/bin/sh
2 2 #
3 3 # hgmerge - default merge helper for Mercurial
4 4 #
5 5 # This tries to find a way to do three-way merge on the current system.
6 6 # The result ought to end up in $1.
7 7
8 8 set -e # bail out quickly on failure
9 9
10 10 LOCAL=$1
11 11 BASE=$2
12 12 OTHER=$3
13 13
14 14 EDITOR="${EDITOR:-vi}"
15 15
16 16 # Back up our file
17 17 cp $LOCAL $LOCAL.orig
18 18
19 19 # Attempt to do a non-interactive merge
20 20 if which merge > /dev/null ; then
21 21 if merge $LOCAL $BASE $OTHER 2> /dev/null; then
22 22 # success!
23 23 exit 0
24 24 fi
25 25 cp $LOCAL.orig $LOCAL
26 26 elif which diff3 > /dev/null ; then
27 27 if diff3 -m $LOCAL.orig $BASE $OTHER > $LOCAL ; then
28 28 # success
29 29 exit 0
30 30 fi
31 31 cp $LOCAL.orig $LOCAL
32 32 fi
33 33
34 34 if [ -n "$DISPLAY" ]; then
35 35 # try using kdiff3, which is fairly nice
36 36 if which kdiff3 > /dev/null ; then
37 37 if kdiff3 --auto $BASE $LOCAL $OTHER -o $LOCAL ; then
38 38 exit 0
39 39 else
40 40 exit 1
41 41 fi
42 42 fi
43 43
44 44 # try using tkdiff, which is a bit less sophisticated
45 45 if which tkdiff > /dev/null ; then
46 46 if tkdiff $LOCAL $OTHER -a $BASE -o $LOCAL ; then
47 47 exit 0
48 48 else
49 49 exit 1
50 50 fi
51 51 fi
52 52 fi
53 53
54 54 # Attempt to do a merge with $EDITOR
55 55 if which merge > /dev/null ; then
56 56 echo "conflicts detected in $LOCAL"
57 57 merge $LOCAL $BASE $OTHER 2>/dev/null || $EDITOR $LOCAL
58 58 exit 0
59 59 fi
60 60
61 61 if which diff3 > /dev/null ; then
62 62 echo "conflicts detected in $LOCAL"
63 63 diff3 -m $LOCAL.orig $BASE $OTHER > $LOCAL || $EDITOR $LOCAL
64 64 exit 0
65 65 fi
66 66
67 67 # attempt to manually merge with diff and patch
68 68 if which diff > /dev/null ; then
69 69 if which patch > /dev/null ; then
70 70 T=`mktemp`
71 71 diff -u $BASE $OTHER > $T
72 72 if patch $LOCAL < $T ; then
73 73 exit 0
74 74 else
75 75 $EDITOR $LOCAL $LOCAL.rej
76 76 fi
77 77 rm $T
78 78 exit 1
79 79 fi
80 80 fi
81 81
82 82 echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!"
83 83 exit 1
@@ -1,919 +1,921 b''
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import os, re, sys, signal
9 9 import fancyopts, ui, hg, util
10 10 from demandload import *
11 11 demandload(globals(), "mdiff time hgweb traceback random signal errno version")
12 12
13 13 class UnknownCommand(Exception): pass
14 14
15 15 def filterfiles(filters, files):
16 16 l = [ x for x in files if x in filters ]
17 17
18 18 for t in filters:
19 19 if t and t[-1] != "/": t += "/"
20 20 l += [ x for x in files if x.startswith(t) ]
21 21 return l
22 22
23 23 def relfilter(repo, files):
24 24 if os.getcwd() != repo.root:
25 25 p = os.getcwd()[len(repo.root) + 1: ]
26 26 return filterfiles([util.pconvert(p)], files)
27 27 return files
28 28
29 29 def relpath(repo, args):
30 30 if os.getcwd() != repo.root:
31 31 p = os.getcwd()[len(repo.root) + 1: ]
32 32 return [ util.pconvert(os.path.normpath(os.path.join(p, x))) for x in args ]
33 33 return args
34 34
35 35 def dodiff(ui, repo, files = None, node1 = None, node2 = None):
36 36 def date(c):
37 37 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
38 38
39 39 (c, a, d, u) = repo.changes(None, node1, files)
40 40 if files:
41 41 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
42 42
43 43 if not c and not a and not d:
44 44 return
45 45
46 46 if node2:
47 47 change = repo.changelog.read(node2)
48 48 mmap2 = repo.manifest.read(change[0])
49 49 def read(f): return repo.file(f).read(mmap2[f])
50 50 date2 = date(change)
51 51 else:
52 52 date2 = time.asctime()
53 53 if not node1:
54 54 node1 = repo.dirstate.parents()[0]
55 55 def read(f): return repo.wfile(f).read()
56 56
57 57 if ui.quiet:
58 58 r = None
59 59 else:
60 60 hexfunc = ui.verbose and hg.hex or hg.short
61 61 r = [hexfunc(node) for node in [node1, node2] if node]
62 62
63 63 change = repo.changelog.read(node1)
64 64 mmap = repo.manifest.read(change[0])
65 65 date1 = date(change)
66 66
67 67 for f in c:
68 68 to = None
69 69 if f in mmap:
70 70 to = repo.file(f).read(mmap[f])
71 71 tn = read(f)
72 72 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
73 73 for f in a:
74 74 to = None
75 75 tn = read(f)
76 76 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
77 77 for f in d:
78 78 to = repo.file(f).read(mmap[f])
79 79 tn = None
80 80 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
81 81
82 82 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None):
83 83 """show a single changeset or file revision"""
84 84 changelog = repo.changelog
85 85 if filelog:
86 86 log = filelog
87 87 filerev = rev
88 88 node = filenode = filelog.node(filerev)
89 89 changerev = filelog.linkrev(filenode)
90 90 changenode = changenode or changelog.node(changerev)
91 91 else:
92 92 log = changelog
93 93 changerev = rev
94 94 if changenode is None:
95 95 changenode = changelog.node(changerev)
96 96 elif not changerev:
97 97 rev = changerev = changelog.rev(changenode)
98 98 node = changenode
99 99
100 100 if ui.quiet:
101 101 ui.write("%d:%s\n" % (rev, hg.hex(node)))
102 102 return
103 103
104 104 changes = changelog.read(changenode)
105 105
106 106 parents = [(log.rev(parent), hg.hex(parent))
107 107 for parent in log.parents(node)
108 108 if ui.debugflag or parent != hg.nullid]
109 109 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
110 110 parents = []
111 111
112 112 if filelog:
113 113 ui.write("revision: %d:%s\n" % (filerev, hg.hex(filenode)))
114 114 for parent in parents:
115 115 ui.write("parent: %d:%s\n" % parent)
116 116 ui.status("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
117 117 else:
118 118 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
119 119 for tag in repo.nodetags(changenode):
120 120 ui.status("tag: %s\n" % tag)
121 121 for parent in parents:
122 122 ui.write("parent: %d:%s\n" % parent)
123 123 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
124 124 hg.hex(changes[0])))
125 125 ui.status("user: %s\n" % changes[1])
126 126 ui.status("date: %s\n" % time.asctime(
127 127 time.localtime(float(changes[2].split(' ')[0]))))
128 128 if ui.debugflag:
129 129 files = repo.changes(changelog.parents(changenode)[0], changenode)
130 130 for key, value in zip(["files:", "files+:", "files-:"], files):
131 131 if value:
132 132 ui.note("%-12s %s\n" % (key, " ".join(value)))
133 133 else:
134 134 ui.note("files: %s\n" % " ".join(changes[3]))
135 135 description = changes[4].strip()
136 136 if description:
137 137 if ui.verbose:
138 138 ui.status("description:\n")
139 139 ui.status(description)
140 ui.status("\n")
140 ui.status("\n\n")
141 141 else:
142 142 ui.status("summary: %s\n" % description.splitlines()[0])
143 143 ui.status("\n")
144 144
145 145 def show_version(ui):
146 146 """output version and copyright information"""
147 147 ui.write("Mercurial version %s\n" % version.get_version())
148 148 ui.status(
149 149 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
150 150 "This is free software; see the source for copying conditions. "
151 151 "There is NO\nwarranty; "
152 152 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
153 153 )
154 154
155 155 def help(ui, cmd=None):
156 156 '''show help for a given command or all commands'''
157 157 if cmd:
158 158 try:
159 159 i = find(cmd)
160 160 ui.write("%s\n\n" % i[2])
161 161
162 162 if i[1]:
163 163 for s, l, d, c in i[1]:
164 164 opt=' '
165 165 if s: opt = opt + '-' + s + ' '
166 166 if l: opt = opt + '--' + l + ' '
167 167 if d: opt = opt + '(' + str(d) + ')'
168 168 ui.write(opt, "\n")
169 169 if c: ui.write(' %s\n' % c)
170 170 ui.write("\n")
171 171
172 172 ui.write(i[0].__doc__, "\n")
173 173 except UnknownCommand:
174 174 ui.warn("hg: unknown command %s\n" % cmd)
175 175 sys.exit(0)
176 176 else:
177 177 if not ui.quiet:
178 178 show_version(ui)
179 179 ui.write('\n')
180 180 ui.write('hg commands:\n\n')
181 181
182 182 h = {}
183 183 for c, e in table.items():
184 184 f = c.split("|")[0]
185 185 if f.startswith("debug"):
186 186 continue
187 187 d = ""
188 188 if e[0].__doc__:
189 189 d = e[0].__doc__.splitlines(0)[0].rstrip()
190 190 h[f] = d
191 191
192 192 fns = h.keys()
193 193 fns.sort()
194 194 m = max(map(len, fns))
195 195 for f in fns:
196 196 ui.write(' %-*s %s\n' % (m, f, h[f]))
197 197
198 198 # Commands start here, listed alphabetically
199 199
200 200 def add(ui, repo, file, *files):
201 201 '''add the specified files on the next commit'''
202 202 repo.add(relpath(repo, (file,) + files))
203 203
204 204 def addremove(ui, repo, *files):
205 205 """add all new files, delete all missing files"""
206 206 if files:
207 207 files = relpath(repo, files)
208 208 d = []
209 209 u = []
210 210 for f in files:
211 211 p = repo.wjoin(f)
212 212 s = repo.dirstate.state(f)
213 213 isfile = os.path.isfile(p)
214 214 if s != 'r' and not isfile:
215 215 d.append(f)
216 216 elif s not in 'nmai' and isfile:
217 217 u.append(f)
218 218 else:
219 219 (c, a, d, u) = repo.changes(None, None)
220 220 repo.add(u)
221 221 repo.remove(d)
222 222
223 223 def annotate(u, repo, file, *files, **ops):
224 224 """show changeset information per file line"""
225 225 def getnode(rev):
226 226 return hg.short(repo.changelog.node(rev))
227 227
228 228 def getname(rev):
229 229 try:
230 230 return bcache[rev]
231 231 except KeyError:
232 232 cl = repo.changelog.read(repo.changelog.node(rev))
233 233 name = cl[1]
234 234 f = name.find('@')
235 235 if f >= 0:
236 236 name = name[:f]
237 237 f = name.find('<')
238 238 if f >= 0:
239 239 name = name[f+1:]
240 240 bcache[rev] = name
241 241 return name
242 242
243 243 bcache = {}
244 244 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
245 245 if not ops['user'] and not ops['changeset']:
246 246 ops['number'] = 1
247 247
248 248 node = repo.dirstate.parents()[0]
249 249 if ops['revision']:
250 250 node = repo.changelog.lookup(ops['revision'])
251 251 change = repo.changelog.read(node)
252 252 mmap = repo.manifest.read(change[0])
253 253 for f in relpath(repo, (file,) + files):
254 254 lines = repo.file(f).annotate(mmap[f])
255 255 pieces = []
256 256
257 257 for o, f in opmap:
258 258 if ops[o]:
259 259 l = [ f(n) for n,t in lines ]
260 260 m = max(map(len, l))
261 261 pieces.append([ "%*s" % (m, x) for x in l])
262 262
263 263 for p,l in zip(zip(*pieces), lines):
264 264 u.write(" ".join(p) + ": " + l[1])
265 265
266 266 def cat(ui, repo, file, rev = []):
267 267 """output the latest or given revision of a file"""
268 268 r = repo.file(relpath(repo, [file])[0])
269 269 n = r.tip()
270 270 if rev: n = r.lookup(rev)
271 271 sys.stdout.write(r.read(n))
272 272
273 273 def clone(ui, source, dest = None, **opts):
274 274 """make a copy of an existing repository"""
275 275 source = ui.expandpath(source)
276 276
277 277 if dest is None:
278 278 dest = os.path.basename(os.path.normpath(source))
279 279
280 280 if os.path.exists(dest):
281 281 ui.warn("abort: destination '%s' already exists\n" % dest)
282 282 return 1
283 283
284 284 class dircleanup:
285 285 def __init__(self, dir):
286 286 self.dir = dir
287 287 os.mkdir(dir)
288 288 def close(self):
289 289 self.dir = None
290 290 def __del__(self):
291 291 if self.dir:
292 292 import shutil
293 293 shutil.rmtree(self.dir, True)
294 294
295 295 d = dircleanup(dest)
296 296
297 297 link = 0
298 if not source.startswith("http://"):
298 if not (source.startswith("http://") or
299 source.startswith("hg://") or
300 source.startswith("old-http://")):
299 301 d1 = os.stat(dest).st_dev
300 302 d2 = os.stat(source).st_dev
301 303 if d1 == d2: link = 1
302 304
303 305 if link:
304 306 ui.note("copying by hardlink\n")
305 307 util.system("cp -al '%s'/.hg '%s'/.hg" % (source, dest))
306 308 try:
307 309 os.remove(os.path.join(dest, ".hg", "dirstate"))
308 310 except: pass
309 311
310 312 repo = hg.repository(ui, dest)
311 313
312 314 else:
313 315 repo = hg.repository(ui, dest, create=1)
314 316 other = hg.repository(ui, source)
315 317 fetch = repo.findincoming(other)
316 318 if fetch:
317 319 cg = other.changegroup(fetch)
318 320 repo.addchangegroup(cg)
319 321
320 322 f = repo.opener("hgrc", "w")
321 323 f.write("[paths]\n")
322 324 f.write("default = %s\n" % source)
323 325
324 326 if not opts['noupdate']:
325 327 update(ui, repo)
326 328
327 329 d.close()
328 330
329 331 def commit(ui, repo, *files, **opts):
330 332 """commit the specified files or all outstanding changes"""
331 333 text = opts['text']
332 334 if not text and opts['logfile']:
333 335 try: text = open(opts['logfile']).read()
334 336 except IOError: pass
335 337
336 338 if opts['addremove']:
337 339 addremove(ui, repo, *files)
338 340 repo.commit(relpath(repo, files), text, opts['user'], opts['date'])
339 341
340 342 def copy(ui, repo, source, dest):
341 343 """mark a file as copied or renamed for the next commit"""
342 344 return repo.copy(*relpath(repo, (source, dest)))
343 345
344 346 def debugcheckdirstate(ui, repo):
345 347 parent1, parent2 = repo.dirstate.parents()
346 348 dc = repo.dirstate.dup()
347 349 keys = dc.keys()
348 350 keys.sort()
349 351 m1n = repo.changelog.read(parent1)[0]
350 352 m2n = repo.changelog.read(parent2)[0]
351 353 m1 = repo.manifest.read(m1n)
352 354 m2 = repo.manifest.read(m2n)
353 355 errors = 0
354 356 for f in dc:
355 357 state = repo.dirstate.state(f)
356 358 if state in "nr" and f not in m1:
357 359 print "%s in state %s, but not listed in manifest1" % (f, state)
358 360 errors += 1
359 361 if state in "a" and f in m1:
360 362 print "%s in state %s, but also listed in manifest1" % (f, state)
361 363 errors += 1
362 364 if state in "m" and f not in m1 and f not in m2:
363 365 print "%s in state %s, but not listed in either manifest" % (f, state)
364 366 errors += 1
365 367 for f in m1:
366 368 state = repo.dirstate.state(f)
367 369 if state not in "nrm":
368 370 print "%s in manifest1, but listed as state %s" % (f, state)
369 371 errors += 1
370 372 if errors:
371 373 print ".hg/dirstate inconsistent with current parent's manifest, aborting"
372 374 sys.exit(1)
373 375
374 376 def debugdumpdirstate(ui, repo):
375 377 dc = repo.dirstate.dup()
376 378 keys = dc.keys()
377 379 keys.sort()
378 380 for file in keys:
379 381 print "%s => %c" % (file, dc[file][0])
380 382
381 383 def debugindex(ui, file):
382 384 r = hg.revlog(hg.opener(""), file, "")
383 385 print " rev offset length base linkrev"+\
384 386 " p1 p2 nodeid"
385 387 for i in range(r.count()):
386 388 e = r.index[i]
387 389 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
388 390 i, e[0], e[1], e[2], e[3],
389 391 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
390 392
391 393 def debugindexdot(ui, file):
392 394 r = hg.revlog(hg.opener(""), file, "")
393 395 print "digraph G {"
394 396 for i in range(r.count()):
395 397 e = r.index[i]
396 398 print "\t%d -> %d" % (r.rev(e[4]), i)
397 399 if e[5] != hg.nullid:
398 400 print "\t%d -> %d" % (r.rev(e[5]), i)
399 401 print "}"
400 402
401 403 def diff(ui, repo, *files, **opts):
402 404 """diff working directory (or selected files)"""
403 405 revs = []
404 406 if opts['rev']:
405 407 revs = map(lambda x: repo.lookup(x), opts['rev'])
406 408
407 409 if len(revs) > 2:
408 410 ui.warn("too many revisions to diff\n")
409 411 sys.exit(1)
410 412
411 413 if files:
412 414 files = relpath(repo, files)
413 415 else:
414 416 files = relpath(repo, [""])
415 417
416 418 dodiff(ui, repo, files, *revs)
417 419
418 420 def export(ui, repo, changeset):
419 421 """dump the changeset header and diffs for a revision"""
420 422 node = repo.lookup(changeset)
421 423 prev, other = repo.changelog.parents(node)
422 424 change = repo.changelog.read(node)
423 425 print "# HG changeset patch"
424 426 print "# User %s" % change[1]
425 427 print "# Node ID %s" % hg.hex(node)
426 428 print "# Parent %s" % hg.hex(prev)
427 429 print
428 430 if other != hg.nullid:
429 431 print "# Parent %s" % hg.hex(other)
430 432 print change[4].rstrip()
431 433 print
432 434
433 435 dodiff(ui, repo, None, prev, node)
434 436
435 437 def forget(ui, repo, file, *files):
436 438 """don't add the specified files on the next commit"""
437 439 repo.forget(relpath(repo, (file,) + files))
438 440
439 441 def heads(ui, repo):
440 442 """show current repository heads"""
441 443 for n in repo.changelog.heads():
442 444 show_changeset(ui, repo, changenode=n)
443 445
444 446 def identify(ui, repo):
445 447 """print information about the working copy"""
446 448 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
447 449 if not parents:
448 450 ui.write("unknown\n")
449 451 return
450 452
451 453 hexfunc = ui.verbose and hg.hex or hg.short
452 454 (c, a, d, u) = repo.changes(None, None)
453 455 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
454 456 (c or a or d) and "+" or "")]
455 457
456 458 if not ui.quiet:
457 459 # multiple tags for a single parent separated by '/'
458 460 parenttags = ['/'.join(tags)
459 461 for tags in map(repo.nodetags, parents) if tags]
460 462 # tags for multiple parents separated by ' + '
461 463 output.append(' + '.join(parenttags))
462 464
463 465 ui.write("%s\n" % ' '.join(output))
464 466
465 467 def import_(ui, repo, patch1, *patches, **opts):
466 468 """import an ordered set of patches"""
467 469 try:
468 470 import psyco
469 471 psyco.full()
470 472 except:
471 473 pass
472 474
473 475 patches = (patch1,) + patches
474 476
475 477 d = opts["base"]
476 478 strip = opts["strip"]
477 479
478 480 for patch in patches:
479 481 ui.status("applying %s\n" % patch)
480 482 pf = os.path.join(d, patch)
481 483
482 484 text = ""
483 485 for l in file(pf):
484 486 if l[:4] == "--- ": break
485 487 text += l
486 488
487 489 # make sure text isn't empty
488 490 if not text: text = "imported patch %s\n" % patch
489 491
490 492 f = os.popen("patch -p%d < %s" % (strip, pf))
491 493 files = []
492 494 for l in f.read().splitlines():
493 495 l.rstrip('\r\n');
494 496 ui.status("%s\n" % l)
495 497 if l[:14] == 'patching file ':
496 498 pf = l[14:]
497 499 if pf not in files:
498 500 files.append(pf)
499 501 patcherr = f.close()
500 502 if patcherr:
501 503 sys.stderr.write("patch failed")
502 504 sys.exit(1)
503 505
504 506 if len(files) > 0:
505 507 addremove(ui, repo, *files)
506 508 repo.commit(files, text)
507 509
508 510 def init(ui, source=None):
509 511 """create a new repository in the current directory"""
510 512
511 513 if source:
512 514 ui.warn("no longer supported: use \"hg clone\" instead\n")
513 515 sys.exit(1)
514 516 repo = hg.repository(ui, ".", create=1)
515 517
516 518 def log(ui, repo, f = None):
517 519 """show the revision history of the repository or a single file"""
518 520 if f:
519 521 f = relpath(repo, [f])[0]
520 522 r = repo.file(f)
521 523 for i in range(r.count() - 1, -1, -1):
522 524 show_changeset(ui, repo, filelog=r, rev=i)
523 525 else:
524 526 for i in range(repo.changelog.count() - 1, -1, -1):
525 527 show_changeset(ui, repo, rev=i)
526 528
527 529 def manifest(ui, repo, rev = []):
528 530 """output the latest or given revision of the project manifest"""
529 531 n = repo.manifest.tip()
530 532 if rev:
531 533 n = repo.manifest.lookup(rev)
532 534 m = repo.manifest.read(n)
533 535 mf = repo.manifest.readflags(n)
534 536 files = m.keys()
535 537 files.sort()
536 538
537 539 for f in files:
538 540 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
539 541
540 542 def parents(ui, repo, node = None):
541 543 '''show the parents of the current working dir'''
542 544 if node:
543 545 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
544 546 else:
545 547 p = repo.dirstate.parents()
546 548
547 549 for n in p:
548 550 if n != hg.nullid:
549 551 show_changeset(ui, repo, changenode=n)
550 552
551 553 def pull(ui, repo, source="default", **opts):
552 554 """pull changes from the specified source"""
553 555 source = ui.expandpath(source)
554 556
555 557 ui.status('pulling from %s\n' % (source))
556 558
557 559 other = hg.repository(ui, source)
558 560 fetch = repo.findincoming(other)
559 561 if not fetch:
560 562 ui.status("no changes found\n")
561 563 return
562 564
563 565 cg = other.changegroup(fetch)
564 566 r = repo.addchangegroup(cg)
565 567 if cg and not r:
566 568 if opts['update']:
567 569 return update(ui, repo)
568 570 else:
569 571 ui.status("(run 'hg update' to get a working copy)\n")
570 572
571 573 return r
572 574
573 575 def push(ui, repo, dest="default-push"):
574 576 """push changes to the specified destination"""
575 577 dest = ui.expandpath(dest)
576 578
577 579 if not dest.startswith("ssh://"):
578 580 ui.warn("abort: can only push to ssh:// destinations currently\n")
579 581 return 1
580 582
581 583 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest)
582 584 if not m:
583 585 ui.warn("abort: couldn't parse destination %s\n" % dest)
584 586 return 1
585 587
586 588 user, host, port, path = map(m.group, (2, 3, 5, 7))
587 589 uhost = user and ("%s@%s" % (user, host)) or host
588 590 port = port and (" -p %s") % port or ""
589 591 path = path or ""
590 592
591 593 sport = random.randrange(30000, 60000)
592 594 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'"
593 595 cmd = cmd % (uhost, port, sport+1, sport, path, sport+1)
594 596
595 597 child = os.fork()
596 598 if not child:
597 599 sys.stdout = file("/dev/null", "w")
598 600 sys.stderr = sys.stdout
599 601 hgweb.server(repo.root, "pull", "", "localhost", sport)
600 602 else:
601 603 ui.status("connecting to %s\n" % host)
602 604 r = os.system(cmd)
603 605 os.kill(child, signal.SIGTERM)
604 606 return r
605 607
606 608 def rawcommit(ui, repo, *flist, **rc):
607 609 "raw commit interface"
608 610
609 611 text = rc['text']
610 612 if not text and rc['logfile']:
611 613 try: text = open(rc['logfile']).read()
612 614 except IOError: pass
613 615 if not text and not rc['logfile']:
614 616 print "missing commit text"
615 617 return 1
616 618
617 619 files = relpath(repo, list(flist))
618 620 if rc['files']:
619 621 files += open(rc['files']).read().splitlines()
620 622
621 623 rc['parent'] = map(repo.lookup, rc['parent'])
622 624
623 625 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
624 626
625 627 def recover(ui, repo):
626 628 """roll back an interrupted transaction"""
627 629 repo.recover()
628 630
629 631 def remove(ui, repo, file, *files):
630 632 """remove the specified files on the next commit"""
631 633 repo.remove(relpath(repo, (file,) + files))
632 634
633 635 def root(ui, repo):
634 636 """print the root (top) of the current working dir"""
635 637 ui.write(repo.root + "\n")
636 638
637 639 def serve(ui, repo, **opts):
638 640 """export the repository via HTTP"""
639 641 hgweb.server(repo.root, opts["name"], opts["templates"],
640 642 opts["address"], opts["port"])
641 643
642 644 def status(ui, repo):
643 645 '''show changed files in the working directory
644 646
645 647 C = changed
646 648 A = added
647 649 R = removed
648 650 ? = not tracked'''
649 651
650 652 (c, a, d, u) = repo.changes(None, None)
651 653 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
652 654
653 655 for f in c: print "C", f
654 656 for f in a: print "A", f
655 657 for f in d: print "R", f
656 658 for f in u: print "?", f
657 659
658 660 def tag(ui, repo, name, rev = None, **opts):
659 661 """add a tag for the current tip or a given revision"""
660 662
661 663 if name == "tip":
662 664 ui.warn("abort: 'tip' is a reserved name!\n")
663 665 return -1
664 666
665 667 (c, a, d, u) = repo.changes(None, None)
666 668 for x in (c, a, d, u):
667 669 if ".hgtags" in x:
668 670 ui.warn("abort: working copy of .hgtags is changed!\n")
669 671 ui.status("(please commit .hgtags manually)\n")
670 672 return -1
671 673
672 674 if rev:
673 675 r = hg.hex(repo.lookup(rev))
674 676 else:
675 677 r = hg.hex(repo.changelog.tip())
676 678
677 679 add = 0
678 680 if not os.path.exists(repo.wjoin(".hgtags")): add = 1
679 681 repo.wfile(".hgtags", "a").write("%s %s\n" % (r, name))
680 682 if add: repo.add([".hgtags"])
681 683
682 684 if not opts['text']:
683 685 opts['text'] = "Added tag %s for changeset %s" % (name, r)
684 686
685 687 repo.commit([".hgtags"], opts['text'], opts['user'], opts['date'])
686 688
687 689 def tags(ui, repo):
688 690 """list repository tags"""
689 691
690 692 l = repo.tagslist()
691 693 l.reverse()
692 694 for t, n in l:
693 695 try:
694 696 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
695 697 except KeyError:
696 698 r = " ?:?"
697 699 ui.write("%-30s %s\n" % (t, r))
698 700
699 701 def tip(ui, repo):
700 702 """show the tip revision"""
701 703 n = repo.changelog.tip()
702 704 show_changeset(ui, repo, changenode=n)
703 705
704 706 def undo(ui, repo):
705 707 """undo the last transaction"""
706 708 repo.undo()
707 709
708 710 def update(ui, repo, node=None, merge=False, clean=False):
709 711 '''update or merge working directory
710 712
711 713 If there are no outstanding changes in the working directory and
712 714 there is a linear relationship between the current version and the
713 715 requested version, the result is the requested version.
714 716
715 717 Otherwise the result is a merge between the contents of the
716 718 current working directory and the requested version. Files that
717 719 changed between either parent are marked as changed for the next
718 720 commit and a commit must be performed before any further updates
719 721 are allowed.
720 722 '''
721 723 node = node and repo.lookup(node) or repo.changelog.tip()
722 724 return repo.update(node, allow=merge, force=clean)
723 725
724 726 def verify(ui, repo):
725 727 """verify the integrity of the repository"""
726 728 return repo.verify()
727 729
728 730 # Command options and aliases are listed here, alphabetically
729 731
730 732 table = {
731 733 "add": (add, [], "hg add [files]"),
732 734 "addremove": (addremove, [], "hg addremove [files]"),
733 735 "annotate": (annotate,
734 736 [('r', 'revision', '', 'revision'),
735 737 ('u', 'user', None, 'show user'),
736 738 ('n', 'number', None, 'show revision number'),
737 739 ('c', 'changeset', None, 'show changeset')],
738 740 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
739 741 "cat": (cat, [], 'hg cat <file> [rev]'),
740 742 "clone": (clone, [('U', 'noupdate', None, 'skip update after cloning')],
741 743 'hg clone [options] <source> [dest]'),
742 744 "commit|ci": (commit,
743 745 [('t', 'text', "", 'commit text'),
744 746 ('A', 'addremove', None, 'run add/remove during commit'),
745 747 ('l', 'logfile', "", 'commit text file'),
746 748 ('d', 'date', "", 'data'),
747 749 ('u', 'user', "", 'user')],
748 750 'hg commit [files]'),
749 751 "copy": (copy, [], 'hg copy <source> <dest>'),
750 752 "debugcheckdirstate": (debugcheckdirstate, [], 'debugcheckdirstate'),
751 753 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'),
752 754 "debugindex": (debugindex, [], 'debugindex <file>'),
753 755 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
754 756 "diff": (diff, [('r', 'rev', [], 'revision')],
755 757 'hg diff [-r A] [-r B] [files]'),
756 758 "export": (export, [], "hg export <changeset>"),
757 759 "forget": (forget, [], "hg forget [files]"),
758 760 "heads": (heads, [], 'hg heads'),
759 761 "help": (help, [], 'hg help [command]'),
760 762 "identify|id": (identify, [], 'hg identify'),
761 763 "import|patch": (import_,
762 764 [('p', 'strip', 1, 'path strip'),
763 765 ('b', 'base', "", 'base path')],
764 766 "hg import [options] <patches>"),
765 767 "init": (init, [], 'hg init'),
766 768 "log|history": (log, [], 'hg log [file]'),
767 769 "manifest": (manifest, [], 'hg manifest [rev]'),
768 770 "parents": (parents, [], 'hg parents [node]'),
769 771 "pull": (pull,
770 772 [('u', 'update', None, 'update working directory')],
771 773 'hg pull [options] [source]'),
772 774 "push": (push, [], 'hg push <destination>'),
773 775 "rawcommit": (rawcommit,
774 776 [('p', 'parent', [], 'parent'),
775 777 ('d', 'date', "", 'data'),
776 778 ('u', 'user', "", 'user'),
777 779 ('F', 'files', "", 'file list'),
778 780 ('t', 'text', "", 'commit text'),
779 781 ('l', 'logfile', "", 'commit text file')],
780 782 'hg rawcommit [options] [files]'),
781 783 "recover": (recover, [], "hg recover"),
782 784 "remove|rm": (remove, [], "hg remove [files]"),
783 785 "root": (root, [], "hg root"),
784 786 "serve": (serve, [('p', 'port', 8000, 'listen port'),
785 787 ('a', 'address', '', 'interface address'),
786 788 ('n', 'name', os.getcwd(), 'repository name'),
787 789 ('t', 'templates', "", 'template map')],
788 790 "hg serve [options]"),
789 791 "status": (status, [], 'hg status'),
790 792 "tag": (tag, [('t', 'text', "", 'commit text'),
791 793 ('d', 'date', "", 'date'),
792 794 ('u', 'user', "", 'user')],
793 795 'hg tag [options] <name> [rev]'),
794 796 "tags": (tags, [], 'hg tags'),
795 797 "tip": (tip, [], 'hg tip'),
796 798 "undo": (undo, [], 'hg undo'),
797 799 "update|up|checkout|co":
798 800 (update,
799 801 [('m', 'merge', None, 'allow merging of conflicts'),
800 802 ('C', 'clean', None, 'overwrite locally modified files')],
801 803 'hg update [options] [node]'),
802 804 "verify": (verify, [], 'hg verify'),
803 805 "version": (show_version, [], 'hg version'),
804 806 }
805 807
806 808 norepo = "clone init version help debugindex debugindexdot"
807 809
808 810 def find(cmd):
809 811 for e in table.keys():
810 812 if re.match("(%s)$" % e, cmd):
811 813 return table[e]
812 814
813 815 raise UnknownCommand(cmd)
814 816
815 817 class SignalInterrupt(Exception): pass
816 818
817 819 def catchterm(*args):
818 820 raise SignalInterrupt
819 821
820 822 def run():
821 823 sys.exit(dispatch(sys.argv[1:]))
822 824
823 825 def dispatch(args):
824 826 options = {}
825 827 opts = [('v', 'verbose', None, 'verbose'),
826 828 ('d', 'debug', None, 'debug'),
827 829 ('q', 'quiet', None, 'quiet'),
828 830 ('p', 'profile', None, 'profile'),
829 831 ('R', 'repository', "", 'repository root directory'),
830 832 ('', 'traceback', None, 'print traceback on exception'),
831 833 ('y', 'noninteractive', None, 'run non-interactively'),
832 834 ('', 'version', None, 'output version information and exit'),
833 835 ]
834 836
835 837 args = fancyopts.fancyopts(args, opts, options,
836 838 'hg [options] <command> [options] [files]')
837 839
838 840 if not args:
839 841 cmd = "help"
840 842 else:
841 843 cmd, args = args[0], args[1:]
842 844
843 845 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
844 846 not options["noninteractive"])
845 847
846 848 if options["version"]:
847 849 show_version(u)
848 850 sys.exit(0)
849 851
850 852 try:
851 853 i = find(cmd)
852 854 except UnknownCommand:
853 855 u.warn("hg: unknown command '%s'\n" % cmd)
854 856 help(u)
855 857 sys.exit(1)
856 858
857 859 signal.signal(signal.SIGTERM, catchterm)
858 860
859 861 cmdoptions = {}
860 862 try:
861 863 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
862 864 except fancyopts.getopt.GetoptError, inst:
863 865 u.warn("hg %s: %s\n" % (cmd, inst))
864 866 help(u, cmd)
865 867 sys.exit(-1)
866 868
867 869 try:
868 870 try:
869 871 if cmd not in norepo.split():
870 872 path = options["repository"] or ""
871 873 repo = hg.repository(ui=u, path=path)
872 874 d = lambda: i[0](u, repo, *args, **cmdoptions)
873 875 else:
874 876 d = lambda: i[0](u, *args, **cmdoptions)
875 877
876 878 if options['profile']:
877 879 import hotshot, hotshot.stats
878 880 prof = hotshot.Profile("hg.prof")
879 881 r = prof.runcall(d)
880 882 prof.close()
881 883 stats = hotshot.stats.load("hg.prof")
882 884 stats.strip_dirs()
883 885 stats.sort_stats('time', 'calls')
884 886 stats.print_stats(40)
885 887 return r
886 888 else:
887 889 return d()
888 890 except:
889 891 if options['traceback']:
890 892 traceback.print_exc()
891 893 raise
892 894 except util.CommandError, inst:
893 895 u.warn("abort: %s\n" % inst.args)
894 896 except hg.RepoError, inst:
895 897 u.warn("abort: ", inst, "!\n")
896 898 except SignalInterrupt:
897 899 u.warn("killed!\n")
898 900 except KeyboardInterrupt:
899 901 u.warn("interrupted!\n")
900 902 except IOError, inst:
901 903 if hasattr(inst, "code"):
902 904 u.warn("abort: %s\n" % inst)
903 905 elif hasattr(inst, "reason"):
904 906 u.warn("abort: error %d: %s\n" % (inst.reason[0], inst.reason[1]))
905 907 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
906 908 u.warn("broken pipe\n")
907 909 else:
908 910 raise
909 911 except TypeError, inst:
910 912 # was this an argument error?
911 913 tb = traceback.extract_tb(sys.exc_info()[2])
912 914 if len(tb) > 2: # no
913 915 raise
914 916 u.debug(inst, "\n")
915 917 u.warn("%s: invalid arguments\n" % i[0].__name__)
916 918 help(u, cmd)
917 919
918 920 sys.exit(-1)
919 921
@@ -1,86 +1,88 b''
1 #!/bin/sh
2
1 3 set -e
2 4 set -x
3 5
4 6 # skip commit logs
5 7 export HGMERGE=tkmerge
6 8 export EDITOR=true
7 9
8 10 rm -rf m m1 m2
9 11 mkdir m
10 12 cd m
11 13
12 14 echo "m this that"
13 15 echo "this" > a
14 16 echo "that" > b
15 17 hg init
16 18 hg addremove
17 19 hg commit
18 20 echo "a:" `hg dump a` "b:" `hg dump b`
19 21 echo
20 22
21 23 cd ..
22 24 echo "m2 this that "
23 25 mkdir m2
24 26 cd m2
25 27 hg branch ../m
26 28 hg checkout
27 29 echo "a:" `hg dump a` "b:" `hg dump b`
28 30 echo
29 31
30 32 cd ../m
31 33 echo "m this1 that "
32 34 echo "this1" > a
33 35 hg commit
34 36 echo "a:" `hg dump a` "b:" `hg dump b`
35 37 echo
36 38
37 39 cd ..
38 40 echo "m1 this1 that "
39 41 mkdir m1
40 42 cd m1
41 43 hg branch ../m
42 44 hg checkout
43 45 echo "a:" `hg dump a` "b:" `hg dump b`
44 46 echo
45 47
46 48 cd ../m1
47 49 echo "m1 this1 that1"
48 50 echo "that1" > b
49 51 hg commit
50 52 echo "a:" `hg dump a` "b:" `hg dump b`
51 53 echo
52 54
53 55 cd ../m2
54 56 echo "m2 this that2"
55 57 echo "that2" > b
56 58 hg commit
57 59 echo "a:" `hg dump a` "b:" `hg dump b`
58 60 echo
59 61
60 62 cd ../m1
61 63 echo "m1:m2 this1 that1 that2"
62 64 hg merge ../m2 # b should conflict, a should be fine
63 65 echo "a:" `hg dump a` "b:" `hg dump b`
64 66 echo
65 67
66 68 cd ../m2
67 69 echo "m2 this2 that2"
68 70 echo "this2" > a
69 71 hg commit
70 72 echo "a:" `hg dump a` "b:" `hg dump b`
71 73 echo
72 74
73 75 cd ../m2
74 76 echo "m2:m this12 that2"
75 77 hg merge ../m # a should conflict, b should be fine
76 78 echo "a:" `hg dump a` "b:" `hg dump b`
77 79 echo
78 80
79 81 # now here's the interesting bit
80 82 # if we choose ancestor by file, no conflicts
81 83 # otherwise we've got two equally close ancestors, each with a conflict
82 84 # if we go back to the root, we'll have both conflicts again
83 85 echo "m2:m1 this12 that12"
84 86 hg merge ../m1 # should be clean
85 87 echo "a:" `hg dump a` "b:" `hg dump b`
86 88 echo
@@ -1,100 +1,98 b''
1 #!/bin/bash
2
3 set -e
1 #!/bin/sh -e
4 2
5 3 export LANG=C
6 4 export LC_CTYPE="C"
7 5 export LC_NUMERIC="C"
8 6 export LC_TIME="C"
9 7 export LC_COLLATE="C"
10 8 export LC_MONETARY="C"
11 9 export LC_MESSAGES="C"
12 10 export LC_PAPER="C"
13 11 export LC_NAME="C"
14 12 export LC_ADDRESS="C"
15 13 export LC_TELEPHONE="C"
16 14 export LC_MEASUREMENT="C"
17 15 export LC_IDENTIFICATION="C"
18 16 export LC_ALL=""
19 17
20 18 umask 022
21 19
22 20 tests=0
23 21 failed=0
24 22 H=$PWD
25 23
26 24 if [ -d /usr/lib64 ]; then
27 25 lib=lib64
28 26 else
29 27 lib=lib
30 28 fi
31 29
32 30 TESTPATH=$PWD/install/bin
33 31 export PATH=$TESTPATH:$PATH
34 32 export PYTHONPATH=$PWD/install/$lib/python
35 33
36 34 rm -rf install
37 35 cd ..
38 36 ${PYTHON:-python} setup.py install --home=tests/install > tests/install.err
39 37 if [ $? != 0 ] ; then
40 38 cat tests/install.err
41 39 fi
42 40 cd $H
43 41 rm install.err
44 42
45 43 function run_one
46 44 {
47 45 rm -f $1.err
48 46 export TZ=GMT
49 47 D=`mktemp -d`
50 if [ "$D" == "" ] ; then
48 if [ "$D" = "" ] ; then
51 49 echo mktemp failed!
52 50 fi
53 51
54 52 cd $D
55 53 fail=0
56 54
57 55 if ! $H/$1 > .out 2>&1 ; then
58 56 echo $1 failed with error code $?
59 57 fail=1
60 58 fi
61 59
62 60 if [ -s .out -a ! -r $H/$1.out ] ; then
63 61 echo $1 generated unexpected output:
64 62 cat .out
65 63 cp .out $H/$1.err
66 64 fail=1
67 65 elif [ -r $H/$1.out ] && ! diff -u $H/$1.out .out > /dev/null ; then
68 66 echo $1 output changed:
69 67 diff -u $H/$1.out .out && true
70 68 cp .out $H/$1.err
71 69 fail=1
72 70 fi
73 71
74 72 cd $H
75 73 rm -r $D
76 74 return $fail
77 75 }
78 76
79 77 TESTS=$@
80 if [ "$TESTS" == "" ] ; then
78 if [ "$TESTS" = "" ] ; then
81 79 TESTS=`ls test-* | grep -Ev "\.|~"`
82 80 fi
83 81
84 82 for f in $TESTS ; do
85 83 echo -n "."
86 84 if ! run_one $f ; then
87 85 failed=$[$failed + 1]
88 86 fi
89 87 tests=$[$tests + 1]
90 88 done
91 89
92 90 rm -rf install
93 91
94 92 echo
95 93 echo Ran $tests tests, $failed failed
96 94
97 95 if [ $failed -gt 0 ] ; then
98 96 exit 1
99 97 fi
100 98
@@ -1,26 +1,27 b''
1 #!/bin/bash -x
1 #!/bin/sh -x
2 2
3 3 hg clone http://localhost:20059/ copy
4 4 echo $?
5 5 ls copy
6 6
7 7 cat > dumb.py <<EOF
8 8 import BaseHTTPServer, SimpleHTTPServer, signal
9 9
10 10 def run(server_class=BaseHTTPServer.HTTPServer,
11 11 handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler):
12 12 server_address = ('localhost', 20059)
13 13 httpd = server_class(server_address, handler_class)
14 14 httpd.serve_forever()
15 15
16 16 signal.signal(signal.SIGTERM, lambda x: sys.exit(0))
17 17 run()
18 18 EOF
19 19
20 20 python dumb.py 2>/dev/null &
21 sleep 2
21 22
22 23 hg clone http://localhost:20059/foo copy2
23 24 echo $?
24 25
25 26 set +x
26 27 kill $!
@@ -1,21 +1,22 b''
1 1 + hg clone http://localhost:20059/ copy
2 2 requesting all changes
3 3 adding changesets
4 4 abort: error 111: Connection refused
5 5 transaction abort!
6 6 rollback completed
7 7 + echo 255
8 8 255
9 9 + ls copy
10 10 ls: copy: No such file or directory
11 11 + cat
12 12 + python dumb.py
13 + sleep 2
13 14 + hg clone http://localhost:20059/foo copy2
14 15 requesting all changes
15 16 adding changesets
16 17 abort: HTTP Error 404: File not found
17 18 transaction abort!
18 19 rollback completed
19 20 + echo 255
20 21 255
21 22 + set +x
@@ -1,13 +1,13 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -x
4 4 mkdir t
5 5 cd t
6 6 hg init
7 7 echo a > a
8 8 hg add a
9 9 hg commit -t "test" -u test -d "0 0"
10 10 hg history
11 11 hg manifest
12 12 hg cat a
13 hg verify No newline at end of file
13 hg verify
@@ -1,17 +1,17 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -x
4 4 hg init
5 5 echo "nothing" > a
6 6 hg add a
7 7 hg commit -t ancestor -u test -d "0 0"
8 8 echo "something" > a
9 9 hg commit -t branch1 -u test -d "0 0"
10 10 hg co 0
11 11 echo "something else" > a
12 12 hg commit -t branch2 -u test -d "0 0"
13 13 export HGMERGE=merge
14 14 hg -d up -m 1
15 15 hg id
16 16 grep -Ev ">>>|<<<" a
17 17 hg status
@@ -1,20 +1,20 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -x
4 4 hg init
5 5 echo a > a
6 6 hg add a
7 7 hg commit -t "1" -u test -d "0 0"
8 8 hg status
9 9 cp a b
10 10 hg copy a b
11 11 hg status
12 12 hg -d commit -t "2" -u test -d "0 0"
13 13 hg history
14 14 hg log a
15 15 hexdump -C .hg/data/b.d
16 16 hg cat b > bsum
17 17 md5sum bsum
18 18 hg cat a > asum
19 19 md5sum asum
20 20 hg verify
@@ -1,11 +1,11 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -x
4 4
5 5 hg -q help
6 6 hg add -h
7 7 hg help diff
8 8 hg help foo
9 9 hg -q commands
10 10
11 11 exit 0
@@ -1,21 +1,21 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 mkdir test
4 4 cd test
5 5 echo foo>foo
6 6 hg init
7 7 hg addremove
8 8 hg commit -t "1"
9 9 hg verify
10 10 hg serve -p 20059 2>/dev/null &
11 11 cd ..
12 12
13 13 hg clone http://localhost:20059/ copy
14 14 cd copy
15 15 hg verify
16 16 hg co
17 17 cat foo
18 18 hg manifest
19 19 hg pull
20 20
21 21 kill $!
@@ -1,111 +1,117 b''
1 1 + hg -d init
2 2 + echo this is a1
3 3 + hg -d add a
4 4 + hg -d commit -t0 -d '0 0' -u user
5 5 a
6 6 + echo this is b1
7 7 + hg -d add b
8 8 + hg -d commit -t1 -d '0 0' -u user
9 9 b
10 10 + hg -d manifest 1
11 11 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
12 12 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
13 13 + echo this is c1
14 14 + hg -d rawcommit -p 1 -d '0 0' -u user -t2 c
15 15 + hg -d manifest 2
16 16 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
17 17 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
18 18 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
19 19 + hg -d parents
20 20 changeset: 2:c4ef0ef0554dff3ceade68d75539e4f208a2be0a
21 21 tag: tip
22 22 parent: 1:3cefbe5cc27b3a068b7a6899ddff22a9874a7e69
23 23 parent: -1:0000000000000000000000000000000000000000
24 24 manifest: 2:f5d7a10be55c91e08fbd4f527ab313aff2761fc6
25 25 user: user
26 26 date: Thu Jan 1 00:00:00 1970
27 27 files+: c
28 28 description:
29 29 2
30 30
31
31 32 + rm b
32 33 + hg -d rawcommit -p 2 -d '0 0' -u user -t3 b
33 34 + hg -d manifest 3
34 35 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
35 36 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
36 37 + hg -d parents
37 38 changeset: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
38 39 tag: tip
39 40 parent: 2:c4ef0ef0554dff3ceade68d75539e4f208a2be0a
40 41 parent: -1:0000000000000000000000000000000000000000
41 42 manifest: 3:1102cb6dde652ec2ba8cc2777e464853afa67cef
42 43 user: user
43 44 date: Thu Jan 1 00:00:00 1970
44 45 files-: b
45 46 description:
46 47 3
47 48
49
48 50 + echo this is a22
49 51 + hg -d rawcommit -p 3 -d '0 0' -u user -t4 a
50 52 + hg -d manifest 4
51 53 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
52 54 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
53 55 + hg -d parents
54 56 changeset: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
55 57 tag: tip
56 58 parent: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
57 59 parent: -1:0000000000000000000000000000000000000000
58 60 manifest: 4:cf4021621d6357e928385ffeee996f87c0bf991d
59 61 user: user
60 62 date: Thu Jan 1 00:00:00 1970
61 63 files: a
62 64 description:
63 65 4
64 66
67
65 68 + echo this is c22
66 69 + hg -d rawcommit -p 1 -d '0 0' -u user -t5 c
67 70 + hg -d manifest 5
68 71 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
69 72 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
70 73 3570202ceac2b52517df64ebd0a062cb0d8fe33a 644 c
71 74 + hg -d parents
72 75 changeset: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
73 76 parent: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
74 77 parent: -1:0000000000000000000000000000000000000000
75 78 manifest: 4:cf4021621d6357e928385ffeee996f87c0bf991d
76 79 user: user
77 80 date: Thu Jan 1 00:00:00 1970
78 81 files: a
79 82 description:
80 83 4
81 84
85
82 86 + hg -d rawcommit -p 4 -p 5 -d '0 0' -u user -t6
83 87 + hg -d manifest 6
84 88 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
85 89 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
86 90 + hg -d parents
87 91 changeset: 6:aaf55aee7b6249fd7d4ba295d98c4492ec2740d7
88 92 tag: tip
89 93 parent: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
90 94 parent: 5:f8292b00383d88b470efcb2ea9c71409832ec9d6
91 95 manifest: 6:71c4262e09a89666ee12a92fefa12085aad53243
92 96 user: user
93 97 date: Thu Jan 1 00:00:00 1970
94 98 description:
95 99 6
96 100
101
97 102 + hg -d rawcommit -p 6 -d '0 0' -u user -t7
98 103 + hg -d manifest 7
99 104 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
100 105 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
101 106 + hg -d parents
102 107 changeset: 7:836ff890ac9ecb8c4b7c209b3e8b93f8805ca5f0
103 108 tag: tip
104 109 parent: 6:aaf55aee7b6249fd7d4ba295d98c4492ec2740d7
105 110 parent: -1:0000000000000000000000000000000000000000
106 111 manifest: 7:c15305fbac9dd3f49bffcc17d659b2d06d10b9a2
107 112 user: user
108 113 date: Thu Jan 1 00:00:00 1970
109 114 description:
110 115 7
111 116
117
@@ -1,24 +1,24 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -ex
4 4
5 5 mkdir test
6 6 cd test
7 7 echo foo>foo
8 8 hg init
9 9 hg addremove
10 10 hg commit -t "1"
11 11 hg verify
12 12
13 13 hg clone . ../branch
14 14 cd ../branch
15 15 hg co
16 16 echo bar>>foo
17 17 hg commit -t "2"
18 18
19 19 cd ../test
20 20 hg pull ../branch
21 21 hg verify
22 22 hg co
23 23 cat foo
24 24 hg manifest
@@ -1,34 +1,34 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -x
4 4 mkdir t
5 5 cd t
6 6 hg init
7 7 hg id
8 8 echo a > a
9 9 hg add a
10 10 hg commit -t "test" -u test -d "0 0"
11 11 hg co
12 12 hg identify
13 13 T=`hg -q tip | cut -d : -f 2`
14 14 echo "$T first" > .hgtags
15 15 cat .hgtags
16 16 hg add .hgtags
17 17 hg commit -t "add tags" -u test -d "0 0"
18 18 hg tags
19 19 hg identify
20 20 echo bb > a
21 21 hg status
22 22 hg identify
23 23 hg co first
24 24 hg id
25 25 hg -v id
26 26 hg status
27 27 echo 1 > b
28 28 hg add b
29 29 hg commit -t "branch" -u test -d "0 0"
30 30 hg id
31 31 hg co -m 1
32 32 hg id
33 33 hg status
34 34
@@ -1,16 +1,16 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 set -x
4 4 mkdir t
5 5 cd t
6 6 hg init
7 7 echo a > a
8 8 hg add a
9 9 hg commit -t "test" -u test -d "0 0"
10 10 hg verify
11 11 hg parents
12 12 hg status
13 13 hg undo
14 14 hg verify
15 15 hg parents
16 16 hg status
@@ -1,35 +1,35 b''
1 #!/bin/bash
1 #!/bin/sh
2 2
3 3 export HGMERGE=true
4 4
5 5 set -ex
6 6 mkdir r1
7 7 cd r1
8 8 hg init
9 9 echo a > a
10 10 hg addremove
11 11 hg commit -t "1" -u test -d "0 0"
12 12
13 13 hg clone . ../r2
14 14 cd ../r2
15 15 hg up
16 16 echo abc > a
17 17 hg diff > ../d
18 18 sed "s/\(\(---\|+++\).*\)\t.*/\1/" < ../d
19 19
20 20 cd ../r1
21 21 echo b > b
22 22 echo a2 > a
23 23 hg addremove
24 24 hg commit -t "2" -u test -d "0 0"
25 25
26 26 cd ../r2
27 27 hg -q pull ../r1
28 28 hg status
29 29 hg -d up
30 30 hg -d up -m
31 31 hg parents
32 32 hg -v history
33 33 hg diff > ../d
34 34 sed "s/\(\(---\|+++\).*\)\t.*/\1/" < ../d
35 35
@@ -1,72 +1,74 b''
1 1 + mkdir r1
2 2 + cd r1
3 3 + hg init
4 4 + echo a
5 5 + hg addremove
6 6 + hg commit -t 1 -u test -d '0 0'
7 7 + hg clone . ../r2
8 8 + cd ../r2
9 9 + hg up
10 10 + echo abc
11 11 + hg diff
12 12 + sed 's/\(\(---\|+++\).*\)\t.*/\1/'
13 13 diff -r c19d34741b0a a
14 14 --- a/a
15 15 +++ b/a
16 16 @@ -1,1 +1,1 @@
17 17 -a
18 18 +abc
19 19 + cd ../r1
20 20 + echo b
21 21 + echo a2
22 22 + hg addremove
23 23 + hg commit -t 2 -u test -d '0 0'
24 24 + cd ../r2
25 25 + hg -q pull ../r1
26 26 + hg status
27 27 C a
28 28 + hg -d up
29 29 resolving manifests
30 30 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
31 31 a versions differ, resolve
32 32 remote created b
33 33 getting b
34 34 merging a
35 35 resolving a
36 36 file a: other d730145abbf9 ancestor b789fdd96dc2
37 37 + hg -d up -m
38 38 resolving manifests
39 39 ancestor 1165e8bd193e local 1165e8bd193e remote 1165e8bd193e
40 40 + hg parents
41 41 changeset: 1:1e71731e6fbb5b35fae293120dea6964371c13c6
42 42 tag: tip
43 43 user: test
44 44 date: Thu Jan 1 00:00:00 1970
45 45 summary: 2
46 46
47 47 + hg -v history
48 48 changeset: 1:1e71731e6fbb5b35fae293120dea6964371c13c6
49 49 tag: tip
50 50 manifest: 1:1165e8bd193e17ad7d321d846fcf27ff3f412758
51 51 user: test
52 52 date: Thu Jan 1 00:00:00 1970
53 53 files: a b
54 54 description:
55 55 2
56 56
57
57 58 changeset: 0:c19d34741b0a4ced8e4ba74bb834597d5193851e
58 59 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
59 60 user: test
60 61 date: Thu Jan 1 00:00:00 1970
61 62 files: a
62 63 description:
63 64 1
64 65
66
65 67 + hg diff
66 68 + sed 's/\(\(---\|+++\).*\)\t.*/\1/'
67 69 diff -r 1e71731e6fbb a
68 70 --- a/a
69 71 +++ b/a
70 72 @@ -1,1 +1,1 @@
71 73 -a2
72 74 +abc
General Comments 0
You need to be logged in to leave comments. Login now