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