Merged with mercurial-identify (which includes upstream's current tip)
authorThomas Arendsen Hein <thomas@intevation.de>
Wed, 15 Jun 2005 08:32:29 +0100
changeset 349 b2293093b89e176707a3250f3e861382a0578aff
parent 348 442eb02cf87015019271160fc105a1e9694564f2 (current diff)
parent 340 97a897d32dfc802a3fd647c8b5458e7b761489a4 (diff)
child 350 b4e0e20646bbdd28ff6a7739250d6bd501445822
push id1
push usergszorc@mozilla.com
push dateWed, 18 Mar 2015 16:34:57 +0000
Merged with mercurial-identify (which includes upstream's current tip) -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Merged with mercurial-identify (which includes upstream's current tip) manifest hash: b135d201757b84bbe7f14a446d2b001fd0cc1aa2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFCr9mNW7P1GVgWeRoRAmTjAJ919wnvZXbKI27N0cDJCrumR3z4rQCcD6PO yZTmrT6p+gt6GBO+j5FVBn0= =HWn8 -----END PGP SIGNATURE-----
contrib/hgit
hgeditor
mercurial/commands.py
mercurial/hg.py
mercurial/ui.py
tests/README
tests/run-tests
tests/test-basic
tests/test-basic.out
tests/test-help
tests/test-help.out
tests/test-pull
tests/test-pull.out
tests/test-simple-update
tests/test-simple-update.out
tests/test-undo
tests/test-undo.out
tests/test-up-local-change
tests/test-up-local-change.out
--- a/contrib/hgit
+++ b/contrib/hgit
@@ -7,207 +7,207 @@
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
 
 import time, sys, signal
 from mercurial import hg, mdiff, fancyopts, commands, ui
     
 def difftree(args, repo):
     def __difftree(repo, files = None, node1 = None, node2 = None):
-	def date(c):
-	    return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
+        def date(c):
+            return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
 
-	if node2:
-	    change = repo.changelog.read(node2)
-	    mmap2 = repo.manifest.read(change[0])
-	    (c, a, d) = repo.diffrevs(node1, node2)
-	    def read(f): return repo.file(f).read(mmap2[f])
-	    date2 = date(change)
-	else:
-	    date2 = time.asctime()
-	    (c, a, d, u) = repo.diffdir(repo.root, node1)
-	    if not node1:
-		node1 = repo.dirstate.parents()[0]
-	    def read(f): return file(os.path.join(repo.root, f)).read()
+        if node2:
+            change = repo.changelog.read(node2)
+            mmap2 = repo.manifest.read(change[0])
+            (c, a, d) = repo.diffrevs(node1, node2)
+            def read(f): return repo.file(f).read(mmap2[f])
+            date2 = date(change)
+        else:
+            date2 = time.asctime()
+            (c, a, d, u) = repo.diffdir(repo.root, node1)
+            if not node1:
+                node1 = repo.dirstate.parents()[0]
+            def read(f): return file(os.path.join(repo.root, f)).read()
 
-	change = repo.changelog.read(node1)
-	mmap = repo.manifest.read(change[0])
-	date1 = date(change)
-	empty = "0" * 40;
+        change = repo.changelog.read(node1)
+        mmap = repo.manifest.read(change[0])
+        date1 = date(change)
+        empty = "0" * 40;
 
-	if files:
-	    c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
+        if files:
+            c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
 
-	for f in c:
-	    # TODO get file permissions
-	    print ":100664 100664 %s %s %s %s" % (hg.hex(mmap[f]), 
-	                                              hg.hex(mmap2[f]), f, f)
-	for f in a:
-	    print ":000000 100664 %s %s %s %s" % (empty, hg.hex(mmap2[f]), f, f)
-	for f in d:
-	    print ":100664 000000 %s %s %s %s" % (hg.hex(mmap[f]), empty, f, f)
+        for f in c:
+            # TODO get file permissions
+            print ":100664 100664 %s %s %s %s" % (hg.hex(mmap[f]), 
+                                                      hg.hex(mmap2[f]), f, f)
+        for f in a:
+            print ":000000 100664 %s %s %s %s" % (empty, hg.hex(mmap2[f]), f, f)
+        for f in d:
+            print ":100664 000000 %s %s %s %s" % (hg.hex(mmap[f]), empty, f, f)
     ##
 
     revs = []
     if args:
-	doptions = {}
-	opts = [('p', 'patch', None, 'patch'),
-		('r', 'recursive', None, 'recursive')]
-	args = fancyopts.fancyopts(args, opts, doptions,
+        doptions = {}
+        opts = [('p', 'patch', None, 'patch'),
+                ('r', 'recursive', None, 'recursive')]
+        args = fancyopts.fancyopts(args, opts, doptions,
                                    'hg diff-tree [options] sha1 sha1')
 
     if len(args) < 2:
-	help()
+        help()
         sys.exit(1)
     revs.append(repo.lookup(args[0]))
     revs.append(repo.lookup(args[1]))
     args = args[2:]
     if doptions['patch']:
-	commands.dodiff(repo, args, *revs)
+        commands.dodiff(repo, args, *revs)
     else:
-	__difftree(repo, args, *revs)
+        __difftree(repo, args, *revs)
 
 def catcommit(repo, n, prefix):
     nlprefix = '\n' + prefix;
     changes = repo.changelog.read(n)
     (p1, p2) = repo.changelog.parents(n)
     (h, h1, h2) = map(hg.hex, (n, p1, p2))
     (i1, i2) = map(repo.changelog.rev, (p1, p2))
     print "tree %s" % (h)
     if i1 != -1: print "%sparent %s" % (prefix, h1)
     if i2 != -1: print "%sparent %s" % (prefix, h2)
     date_ar = changes[2].split(' ')
     date = int(float(date_ar[0]))
     print "%sauthor <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
     print "%scommitter <%s> %s %s" % (prefix, changes[1], date, date_ar[1])
     print prefix
     if prefix != "":
-	print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
+        print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
     else:
-	print changes[4]
+        print changes[4]
 
 def catfile(args, ui, repo):
     doptions = {}
     opts = [('s', 'stdin', None, 'stdin')]
     args = fancyopts.fancyopts(args, opts, doptions,
-			       'hg cat-file type sha1')
+                               'hg cat-file type sha1')
 
     # in stdin mode, every line except the commit is prefixed with two
     # spaces.  This way the our caller can find the commit without magic
     # strings
     #
     prefix = ""
     if doptions['stdin']:
-	try:
-	    (type, r) = raw_input().split(' ');
-	    prefix = "  "
-	except EOFError:
-	    return
+        try:
+            (type, r) = raw_input().split(' ');
+            prefix = "  "
+        except EOFError:
+            return
 
     else:
-	if len(args) < 2:
-	    help()
-	    sys.exit(1)
+        if len(args) < 2:
+            help()
+            sys.exit(1)
         type = args[0]
-	r = args[1]
+        r = args[1]
 
     while r:
-	if type != "commit":
-	    sys.stderr.write("aborting hg cat-file only understands commits\n")
-	    sys.exit(1);
-	n = repo.changelog.lookup(r)
-	catcommit(repo, n, prefix)
-	if doptions['stdin']:
-	    try:
-		(type, r) = raw_input().split(' ');
-	    except EOFError:
-		break
-	else:
-	    break
+        if type != "commit":
+            sys.stderr.write("aborting hg cat-file only understands commits\n")
+            sys.exit(1);
+        n = repo.changelog.lookup(r)
+        catcommit(repo, n, prefix)
+        if doptions['stdin']:
+            try:
+                (type, r) = raw_input().split(' ');
+            except EOFError:
+                break
+        else:
+            break
 
 # git rev-tree is a confusing thing.  You can supply a number of
 # commit sha1s on the command line, and it walks the commit history
 # telling you which commits are reachable from the supplied ones via
 # a bitmask based on arg position.
 # you can specify a commit to stop at by starting the sha1 with ^
 def revtree(args, repo):
     # calculate and return the reachability bitmask for sha
     def is_reachable(ar, reachable, sha):
-	if len(ar) == 0:
-	    return 1
-	mask = 0
-	for i in range(len(ar)):
-	    if sha in reachable[i]:
-	        mask |= 1 << i
+        if len(ar) == 0:
+            return 1
+        mask = 0
+        for i in range(len(ar)):
+            if sha in reachable[i]:
+                mask |= 1 << i
 
-	return mask
+        return mask
 
     reachable = []
     stop_sha1 = []
     want_sha1 = []
 
     # figure out which commits they are asking for and which ones they
     # want us to stop on
     for i in range(len(args)):
         if args[i].count('^'):
-	    s = args[i].split('^')[1]
-	    stop_sha1.append(repo.changelog.lookup(s))
-	    want_sha1.append(s)
-	elif args[i] != 'HEAD':
-	    want_sha1.append(args[i])
+            s = args[i].split('^')[1]
+            stop_sha1.append(repo.changelog.lookup(s))
+            want_sha1.append(s)
+        elif args[i] != 'HEAD':
+            want_sha1.append(args[i])
     # calculate the graph for the supplied commits
     for i in range(len(want_sha1)):
-	reachable.append({});
-	n = repo.changelog.lookup(want_sha1[i]);
-	visit = [n];
-	reachable[i][n] = 1
-	while visit:
-	    n = visit.pop(0)
-	    if n in stop_sha1:
-		break
-	    for p in repo.changelog.parents(n):
-		if p not in reachable[i]:
-		    reachable[i][p] = 1
-		    visit.append(p)
-		if p in stop_sha1:
-		    break
+        reachable.append({});
+        n = repo.changelog.lookup(want_sha1[i]);
+        visit = [n];
+        reachable[i][n] = 1
+        while visit:
+            n = visit.pop(0)
+            if n in stop_sha1:
+                break
+            for p in repo.changelog.parents(n):
+                if p not in reachable[i]:
+                    reachable[i][p] = 1
+                    visit.append(p)
+                if p in stop_sha1:
+                    break
     # walk the repository looking for commits that are in our
     # reachability graph
     for i in range(repo.changelog.count()):
-	n = repo.changelog.node(i)
-	mask = is_reachable(want_sha1, reachable, n)
-	if mask:
-	    changes = repo.changelog.read(n)
-	    (p1, p2) = repo.changelog.parents(n)
-	    (h, h1, h2) = map(hg.hex, (n, p1, p2))
-	    (i1, i2) = map(repo.changelog.rev, (p1, p2))
+        n = repo.changelog.node(i)
+        mask = is_reachable(want_sha1, reachable, n)
+        if mask:
+            changes = repo.changelog.read(n)
+            (p1, p2) = repo.changelog.parents(n)
+            (h, h1, h2) = map(hg.hex, (n, p1, p2))
+            (i1, i2) = map(repo.changelog.rev, (p1, p2))
 
-	    date = changes[2].split(' ')[0]
-	    print "%s %s:%s" % (date, h, mask),
-	    mask = is_reachable(want_sha1, reachable, p1)
-	    if i1 != -1 and mask > 0:
-		print "%s:%s " % (h1, mask),
-	    mask = is_reachable(want_sha1, reachable, p2)
-	    if i2 != -1 and mask > 0:
-		print "%s:%s " % (h2, mask),
-	    print ""
+            date = changes[2].split(' ')[0]
+            print "%s %s:%s" % (date, h, mask),
+            mask = is_reachable(want_sha1, reachable, p1)
+            if i1 != -1 and mask > 0:
+                print "%s:%s " % (h1, mask),
+            mask = is_reachable(want_sha1, reachable, p2)
+            if i2 != -1 and mask > 0:
+                print "%s:%s " % (h2, mask),
+            print ""
 
 # git rev-list tries to order things by date, and has the ability to stop
 # at a given commit without walking the whole repo.  TODO add the stop
 # parameter
 def revlist(args, repo):
     doptions = {}
     opts = [('c', 'commit', None, 'commit')]
     args = fancyopts.fancyopts(args, opts, doptions,
-			       'hg rev-list')
+                               'hg rev-list')
     for i in range(repo.changelog.count()):
-	n = repo.changelog.node(i)
-	print hg.hex(n)
-	if doptions['commit']:
-	    catcommit(repo, n, '  ')
+        n = repo.changelog.node(i)
+        print hg.hex(n)
+        if doptions['commit']:
+            catcommit(repo, n, '  ')
 
 def catchterm(*args):
     raise SignalInterrupt
 
 def help():
     sys.stderr.write("commands:\n")
     sys.stderr.write("  hgit cat-file [type] sha1\n")
     sys.stderr.write("  hgit diff-tree [-p] [-r] sha1 sha1\n")
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -121,16 +121,28 @@ def show_changeset(ui, repo, rev=0, chan
         if ui.verbose:
             ui.status("description:\n")
             ui.status(description)
             ui.status("\n\n")
         else:
             ui.status("summary:     %s\n" % description.splitlines()[0])
     ui.status("\n")
 
+def tags_load(repo):
+    repo.lookup(0) # prime the cache
+    i = repo.tags.items()
+    n = []
+    for e in i:
+        try:
+            l = repo.changelog.rev(e[1])
+        except KeyError:
+            l = -2
+        n.append((l, e))
+    return n
+
 def help(ui, cmd=None):
     '''show help for a given command or all commands'''
     if cmd:
         try:
             i = find(cmd)
             ui.write("%s\n\n" % i[2])
 
             if i[1]:
@@ -307,16 +319,36 @@ def heads(ui, repo):
     for n in repo.changelog.heads():
         show_changeset(ui, repo, changenode=n)
 
 def history(ui, repo):
     """show the changelog history"""
     for i in range(repo.changelog.count() - 1, -1, -1):
         show_changeset(ui, repo, rev=i)
 
+def identify(ui, repo):
+    """print information about the working copy"""
+    (c, a, d, u) = repo.diffdir(repo.root)
+    mflag = (c or a or d or u) and "+" or ""
+    parents = [parent for parent in repo.dirstate.parents()
+                      if parent != hg.nullid]
+    if not parents:
+        ui.note("unknown\n")
+        return
+
+    tstring = ''
+    if not ui.quiet:
+        taglist = [e[1] for e in tags_load(repo)]
+        tstring = " %s" % ' + '.join([e[0] for e in taglist
+                                      if e[0] != 'tip' and e[1] in parents])
+
+    hexfunc = ui.verbose and hg.hex or hg.short
+    pstring = '+'.join([hexfunc(parent) for parent in parents])
+    ui.write("%s%s%s\n" % (pstring, mflag, tstring))
+
 def init(ui, source=None):
     """create a new repository or copy an existing one"""
 
     if source:
         paths = {}
         for name, path in ui.configitems("paths"):
             paths[name] = path
 
@@ -329,23 +361,30 @@ def init(ui, source=None):
             if d1 == d2: link = 1
 
         if link:
             ui.debug("copying by hardlink\n")
             os.system("cp -al %s/.hg .hg" % source)
             try:
                 os.remove(".hg/dirstate")
             except: pass
+
+            repo = hg.repository(ui, ".")
+
         else:
             repo = hg.repository(ui, ".", create=1)
             other = hg.repository(ui, source)
             cg = repo.getchangegroup(other)
             repo.addchangegroup(cg)
     else:
-        hg.repository(ui, ".", create=1)
+        repo = hg.repository(ui, ".", create=1)
+
+    f = repo.opener("hgrc", "w")
+    f.write("[paths]\n")
+    f.write("default = %s\n" % source)
 
 def log(ui, repo, f):
     """show the revision history of a single file"""
     f = relpath(repo, [f])[0]
 
     r = repo.file(f)
     for i in range(r.count() - 1, -1, -1):
         show_changeset(ui, repo, filelog=r, rev=i)
@@ -404,17 +443,17 @@ def patch(ui, repo, patch1, *patches, **
         files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
         f.close()
 
         if files:
             if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
                 raise "patch failed!"
         repo.commit(files, text)
 
-def pull(ui, repo, source):
+def pull(ui, repo, source="default"):
     """pull changes from the specified source"""
     paths = {}
     for name, path in ui.configitems("paths"):
         paths[name] = path
 
     if source in paths: source = paths[source]
     
     other = hg.repository(ui, source)
@@ -452,28 +491,28 @@ def push(ui, repo, dest):
         sys.stdout = file("/dev/null", "w")
         sys.stderr = sys.stdout
         hgweb.server(repo.root, "pull", "", "localhost", sport)
     else:
         r = os.system(cmd)
         os.kill(child, signal.SIGTERM)
         return r
 
-def rawcommit(ui, repo, files, **rc):
+def rawcommit(ui, repo, flist, **rc):
     "raw commit interface"
 
     text = rc['text']
     if not text and rc['logfile']:
         try: text = open(rc['logfile']).read()
         except IOError: pass
     if not text and not rc['logfile']:
         print "missing commit text"
         return 1
 
-    files = relpath(repo, files)
+    files = relpath(repo, flist)
     if rc['files']:
         files += open(rc['files']).read().splitlines()
         
     repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
  
 def recover(ui, repo):
     """roll back an interrupted transaction"""
     repo.recover()
@@ -500,25 +539,17 @@ def status(ui, repo):
 
     for f in c: print "C", f
     for f in a: print "A", f
     for f in d: print "R", f
     for f in u: print "?", f
 
 def tags(ui, repo):
     """list repository tags"""
-    repo.lookup(0) # prime the cache
-    i = repo.tags.items()
-    n = []
-    for e in i:
-        try:
-            l = repo.changelog.rev(e[1])
-        except KeyError:
-            l = -2
-        n.append((l, e))
+    n = tags_load(repo)
 
     n.sort()
     n.reverse()
     i = [ e[1] for e in n ]
     for k, n in i:
         try:
             r = repo.changelog.rev(n)
         except KeyError:
@@ -578,16 +609,17 @@ table = {
     "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
     "diff": (diff, [('r', 'rev', [], 'revision')],
              'hg diff [-r A] [-r B] [files]'),
     "export": (export, [], "hg export <changeset>"),
     "forget": (forget, [], "hg forget [files]"),
     "heads": (heads, [], 'hg heads'),
     "history": (history, [], 'hg history'),
     "help": (help, [], 'hg help [command]'),
+    "identify|id": (identify, [], 'hg identify'),
     "init": (init, [], 'hg init [url]'),
     "log": (log, [], 'hg log <file>'),
     "manifest|dumpmanifest": (manifest, [], 'hg manifest [rev]'),
     "parents": (parents, [], 'hg parents [node]'),
     "patch|import": (patch,
                      [('p', 'strip', 1, 'path strip'),
                       ('b', 'base', "", 'base path'),
                       ('q', 'quiet', "", 'silence diff')],
@@ -622,17 +654,17 @@ table = {
     "verify": (verify, [], 'hg verify'),
     }
 
 norepo = "init branch help debugindex debugindexdot"
 
 def find(cmd):
     i = None
     for e in table.keys():
-        if re.match(e + "$", cmd):
+        if re.match("(%s)$" % e, cmd):
             return table[e]
 
     raise UnknownCommand(cmd)
 
 class SignalInterrupt(Exception): pass
 
 def catchterm(*args):
     raise SignalInterrupt
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -333,16 +333,19 @@ class localrepository:
         self.wopener = opener(self.root)
         self.manifest = manifest(self.opener)
         self.changelog = changelog(self.opener)
         self.ignorelist = None
         self.tags = None
 
         if not self.remote:
             self.dirstate = dirstate(self.opener, ui, self.root)
+            try:
+                self.ui.readconfig(self.opener("hgrc"))
+            except IOError: pass
 
     def ignore(self, f):
         if self.ignorelist is None:
             self.ignorelist = []
             try:
                 l = self.wfile(".hgignore")
                 for pat in l:
                     if pat != "\n":
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -18,16 +18,19 @@ class ui:
         self.debugflag = self.configbool("ui", "debug")
         self.interactive = self.configbool("ui", "interactive", True)
 
         self.quiet = (self.quiet or quiet) and not verbose and not debug
         self.verbose = (self.verbose or verbose) or debug
         self.debugflag = (self.debugflag or debug)
         self.interactive = (self.interactive and interactive)
 
+    def readconfig(self, fp):
+        self.cdata.readfp(fp)
+
     def config(self, section, val, default=None):
         if self.cdata.has_option(section, val):
             return self.cdata.get(section, val)
         return default
 
     def configbool(self, section, val, default=False):
         if self.cdata.has_option(section, val):
             return self.cdata.getboolean(section, val)
new file mode 100644
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,36 @@
+A simple testing framework
+
+To run the tests, do:
+
+cd tests/
+./run-tests
+
+This finds all scripts in the test directory named test-* and executes
+them. The scripts can be either shell scripts or Python. Each test is
+run in a temporary directory that is removed when the test is complete.
+
+A test-<x> succeeds if the script returns success and its output
+matches test-<x>.out. If the new output doesn't match, it is stored in
+test-<x>.err.
+
+There are some tricky points here that you should be aware of when
+writing tests:
+
+- hg commit and hg up -m want user interaction
+
+  for commit use -t "text"
+  for hg up -m, set HGMERGE to something noninteractive (like true or merge)
+
+- changeset hashes will change based on user and date which make
+  things like hg history output change
+
+  use commit -t "test" -u test -d "0 0"
+
+- diff will show the current time
+
+  use hg diff | sed "s/\(\(---\|+++\).*\)\t.*/\1/" to strip dates
+
+- set -x and pipelines don't generate stable output
+
+  turn off set -x or break pipelines into pieces
+
deleted file mode 100644
--- a/tests/manifest-bug
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh -x
-
-set +e
-
-BASE=foo.base
-BR1=foo.br1
-BR2=foo.br2
-BR2_1=foo.br2_1
-
-mkdir $BASE
-cd $BASE
-hg init
-echo test > file
-hg add file
-EDITOR="echo 'initial commit' > " hg commit
-cd ..
-
-mkdir $BR1
-cd $BR1
-hg branch ../$BASE
-hg checkout
-echo test > file1
-hg addremove
-EDITOR="echo side commit >" hg commit
-cd ..
-
-mkdir $BR2
-cd $BR2
-hg branch ../$BASE
-hg checkout
-echo yet more >> file2
-hg addremove
-EDITOR="echo second update >" hg commit
-cd ..
-
-mkdir $BR2_1
-cd $BR2_1
-hg branch ../$BR2
-hg checkout
-EDITOR="echo commit merge >" hg merge ../$BR1
-
-hg checkout
new file mode 100755
--- /dev/null
+++ b/tests/run-tests
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+set -e
+
+tests=0
+failed=0
+H=$PWD
+
+for f in `ls test-* | grep -Ev "\.|~"` ; do
+    echo -n "."
+    D=`mktemp -d`
+    if [ "$D" == "" ] ; then
+	echo mktemp failed!
+    fi
+
+    cd $D
+    fail=0
+    if ! $H/$f > .out 2>&1 ; then
+	echo $f failed with error code $?
+	fail=1
+    fi
+    if [ -s .out -a ! -r $H/$f.out ] ; then
+	echo $f generated unexpected output:
+	cat .out
+	cp .out $H/$f.err
+	fail=1
+    elif ! diff -u $H/$f.out .out > /dev/null ; then
+	echo $f output changed:
+	diff -u $H/$f.out .out && true
+	cp .out $H/$f.err
+    fi
+
+    cd $H
+    rm -r $D
+
+    failed=$[$failed + $fail]
+    tests=$[$tests + 1]
+done
+
+echo
+echo Ran $tests tests, $failed failed
+
+if [ $failed -gt 0 ] ; then
+    exit 1
+fi
+
deleted file mode 100644
--- a/tests/simple-merge
+++ /dev/null
@@ -1,22 +0,0 @@
-set -ex
-export EDITOR=true
-rm -rf test branch
-
-mkdir test
-cd test
-echo foo>foo
-hg init
-hg addremove
-hg commit
-hg verify
-cd ..
-
-cp -a test branch
-cd branch
-echo bar>>foo
-hg commit
-
-cd ../test
-hg merge ../branch
-hg verify
-
new file mode 100755
--- /dev/null
+++ b/tests/test-basic
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -x
+mkdir t
+cd t
+hg init
+echo a > a
+hg add a
+hg commit -t "test" -u test -d "0 0"
+hg history
+hg manifest
+hg cat a
+hg verify
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tests/test-basic.out
@@ -0,0 +1,22 @@
++ mkdir t
++ cd t
++ hg init
++ echo a
++ hg add a
++ hg commit -t test -u test -d '0 0'
++ hg history
+changeset:   0:acb14030fe0a21b60322c440ad2d20cf7685a376
+user:        test
+date:        Wed Dec 31 16:00:00 1969
+summary:     test
+
++ hg manifest
+b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 644 a
++ hg cat a
+a
++ hg verify
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 1 changesets, 1 total revisions
new file mode 100755
--- /dev/null
+++ b/tests/test-help
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -x
+
+hg help
+hg add -h
+hg help diff
+hg help foo
+hg commands
+
+exit 0
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tests/test-help.out
@@ -0,0 +1,78 @@
++ hg help
+hg commands:
+
+ add         add the specified files on the next commit
+ addremove   add all new files, delete all missing files
+ annotate    show changeset information per file line
+ cat         output the latest or given revision of a file
+ commit      commit the specified files or all outstanding changes
+ diff        diff working directory (or selected files)
+ export      dump the changeset header and diffs for a revision
+ forget      don't add the specified files on the next commit
+ heads       show current repository heads
+ help        show help for a given command or all commands
+ history     show the changelog history
+ init        create a new repository or copy an existing one
+ log         show the revision history of a single file
+ manifest    output the latest or given revision of the project manifest
+ parents     show the parents of the current working dir
+ patch       import an ordered set of patches
+ pull        pull changes from the specified source
+ push        push changes to the specified destination
+ rawcommit   raw commit interface
+ recover     roll back an interrupted transaction
+ remove      remove the specified files on the next commit
+ serve       export the repository via HTTP
+ status      show changed files in the working directory
+ tags        list repository tags
+ tip         show the tip revision
+ undo        undo the last transaction
+ update      update or merge working directory
+ verify      verify the integrity of the repository
++ hg add -h
+hg add: option -h not recognized
+hg add [files]
+
+add the specified files on the next commit
++ hg help diff
+hg diff [-r A] [-r B] [files]
+
+ -r --rev 
+   revision
+
+diff working directory (or selected files)
++ hg help foo
+hg: unknown command foo
++ hg commands
+hg: unknown command 'commands'
+hg commands:
+
+ add         add the specified files on the next commit
+ addremove   add all new files, delete all missing files
+ annotate    show changeset information per file line
+ cat         output the latest or given revision of a file
+ commit      commit the specified files or all outstanding changes
+ diff        diff working directory (or selected files)
+ export      dump the changeset header and diffs for a revision
+ forget      don't add the specified files on the next commit
+ heads       show current repository heads
+ help        show help for a given command or all commands
+ history     show the changelog history
+ init        create a new repository or copy an existing one
+ log         show the revision history of a single file
+ manifest    output the latest or given revision of the project manifest
+ parents     show the parents of the current working dir
+ patch       import an ordered set of patches
+ pull        pull changes from the specified source
+ push        push changes to the specified destination
+ rawcommit   raw commit interface
+ recover     roll back an interrupted transaction
+ remove      remove the specified files on the next commit
+ serve       export the repository via HTTP
+ status      show changed files in the working directory
+ tags        list repository tags
+ tip         show the tip revision
+ undo        undo the last transaction
+ update      update or merge working directory
+ verify      verify the integrity of the repository
++ exit 0
new file mode 100755
--- /dev/null
+++ b/tests/test-pull
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+mkdir test
+cd test
+echo foo>foo
+hg init
+hg addremove
+hg commit -t "1"
+hg verify
+hg serve 2>/dev/null &
+C=$!
+cd ..
+
+mkdir copy
+cd copy
+hg init http://localhost:8000/
+hg verify
+hg co
+cat foo
+hg manifest
+
+kill $C
new file mode 100644
--- /dev/null
+++ b/tests/test-pull.out
@@ -0,0 +1,18 @@
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 1 changesets, 1 total revisions
+requesting all changes
+adding changesets
+adding manifests
+adding file revisions
+modified 1 files, added 1 changesets and 1 new revisions
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 1 changesets, 1 total revisions
+foo
+2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
+killed!
new file mode 100755
--- /dev/null
+++ b/tests/test-simple-update
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -ex
+
+mkdir test
+cd test
+echo foo>foo
+hg init
+hg addremove
+hg commit -t "1"
+hg verify
+cd ..
+
+mkdir branch
+cd branch
+hg init ../test
+hg co
+echo bar>>foo
+hg commit -t "2"
+
+cd ../test
+hg pull ../branch
+hg verify
+hg co
+cat foo
+hg manifest
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tests/test-simple-update.out
@@ -0,0 +1,38 @@
++ mkdir test
++ cd test
++ echo foo
++ hg init
++ hg addremove
++ hg commit -t 1
++ hg verify
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 1 changesets, 1 total revisions
++ cd ..
++ mkdir branch
++ cd branch
++ hg init ../test
++ hg co
++ echo bar
++ hg commit -t 2
++ cd ../test
++ hg pull ../branch
+searching for changes
+adding changesets
+adding manifests
+adding file revisions
+modified 1 files, added 1 changesets and 1 new revisions
++ hg verify
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 2 changesets, 2 total revisions
++ hg co
++ cat foo
+foo
+bar
++ hg manifest
+6f4310b00b9a147241b071a60c28a650827fb03d 644 foo
new file mode 100755
--- /dev/null
+++ b/tests/test-undo
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -x
+mkdir t
+cd t
+hg init
+echo a > a
+hg add a
+hg commit -t "test" -u test -d "0 0"
+hg verify
+hg parents
+hg status
+hg undo
+hg verify
+hg parents
+hg status
new file mode 100644
--- /dev/null
+++ b/tests/test-undo.out
@@ -0,0 +1,30 @@
++ mkdir t
++ cd t
++ hg init
++ echo a
++ hg add a
++ hg commit -t test -u test -d '0 0'
++ hg verify
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 1 changesets, 1 total revisions
++ hg parents
+changeset:   0:acb14030fe0a21b60322c440ad2d20cf7685a376
+user:        test
+date:        Wed Dec 31 16:00:00 1969
+summary:     test
+
++ hg status
++ hg undo
+attempting to rollback last transaction
++ hg verify
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+0 files, 0 changesets, 0 total revisions
++ hg parents
++ hg status
+A a
new file mode 100755
--- /dev/null
+++ b/tests/test-up-local-change
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+export HGMERGE=true
+
+set -ex
+mkdir r1
+cd r1
+hg init
+echo a > a
+hg addremove
+hg commit -t "1" -u test -d "0 0"
+
+cd ..
+mkdir r2
+cd r2
+hg init ../r1
+hg up
+echo abc > a
+hg diff > ../d
+sed "s/\(\(---\|+++\).*\)\t.*/\1/" < ../d
+
+cd ../r1
+echo b > b
+echo a2 > a
+hg addremove
+hg commit -t "2" -u test -d "0 0"
+
+cd ../r2
+hg -q pull ../r1
+hg status
+hg -d up
+hg -d up -m
+hg parents
+hg -v history
+hg diff > ../d
+sed "s/\(\(---\|+++\).*\)\t.*/\1/" < ../d
+
new file mode 100644
--- /dev/null
+++ b/tests/test-up-local-change.out
@@ -0,0 +1,70 @@
++ mkdir r1
++ cd r1
++ hg init
++ echo a
++ hg addremove
++ hg commit -t 1 -u test -d '0 0'
++ cd ..
++ mkdir r2
++ cd r2
++ hg init ../r1
++ hg up
++ echo abc
++ hg diff
++ sed 's/\(\(---\|+++\).*\)\t.*/\1/'
+--- a/a
++++ b/a
+@@ -1,1 +1,1 @@
+-a
++abc
++ cd ../r1
++ echo b
++ echo a2
++ hg addremove
++ hg commit -t 2 -u test -d '0 0'
++ cd ../r2
++ hg -q pull ../r1
++ hg status
+C a
++ hg -d up
+resolving manifests
+ ancestor a0c8bcbb local a0c8bcbb remote 1165e8bd
+ a versions differ, resolve
+remote created b
+getting b
+merging a
+resolving a
+file a: other d730145a ancestor b789fdd9
++ hg -d up -m
+resolving manifests
+ ancestor 1165e8bd local 1165e8bd remote 1165e8bd
++ hg parents
+changeset:   1:1e71731e6fbb5b35fae293120dea6964371c13c6
+user:        test
+date:        Wed Dec 31 16:00:00 1969
+summary:     2
+
++ hg -v history
+changeset:   1:1e71731e6fbb5b35fae293120dea6964371c13c6
+manifest:    1:1165e8bd193e17ad7d321d846fcf27ff3f412758
+user:        test
+date:        Wed Dec 31 16:00:00 1969
+files:       a b
+description:
+2
+
+changeset:   0:c19d34741b0a4ced8e4ba74bb834597d5193851e
+manifest:    0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
+user:        test
+date:        Wed Dec 31 16:00:00 1969
+files:       a
+description:
+1
+
++ hg diff
++ sed 's/\(\(---\|+++\).*\)\t.*/\1/'
+--- a/a
++++ b/a
+@@ -1,1 +1,1 @@
+-a2
++abc