changeset 429:688d03d6997a

Pull from TAH -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Pull from TAH manifest hash: 600d04efbd836d555d11a3bd9d821d1d8c0a9790 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCuPFxywK+sNU5EO8RAjfzAKC18Zc2EOkXhy1zcpgGnyPHnFMdmgCfW5Ut I5HSWqZMt8H0WJx1Or7ajNc= =27D5 -----END PGP SIGNATURE-----
author mpm@selenic.com
date Tue, 21 Jun 2005 21:04:49 -0800
parents 183c87d4e1a0 (diff) 36e644d28edf (current diff)
children 5b22029b5aa2
files .hgignore TODO contrib/hgit mercurial/commands.py mercurial/hg.py mercurial/lock.py mercurial/mpatch.c mercurial/transaction.py mercurial/version.py setup.py tests/run-tests tests/test-help tests/test-help.out tests/test-simple-update.out
diffstat 33 files changed, 1095 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/git-viz/git-cat-file	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/git-viz/git-diff-tree	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/git-viz/git-rev-list	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/git-viz/git-rev-tree	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+op=`basename $0 | sed -e 's/^git-//'`
+exec hgit $op "$@"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/git-viz/hg-viz	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+if test x"$1" != x ; then
+  cd $1
+fi
+
+if [ ! -d ".hg" ]; then
+    echo "${1:-.} is not a mercurial repository" 1>&2
+    echo "Aborting" 1>&2
+    exit 1
+fi
+if [ ! -d ".git" ]; then
+    mkdir -v ".git"
+fi
+if [ -e ".git/HEAD" ]; then
+    if [ ! -e ".git/HEAD.hg-viz-save" ]; then
+        mv -v ".git/HEAD" ".git/HEAD.hg-viz-save"
+    else
+        rm -vf ".git/HEAD"
+    fi
+fi
+hg history | head -1 | awk -F: '{print $3}' > .git/HEAD
+git-viz
+
--- a/contrib/hgit	Sun Jun 19 21:04:32 2005 +0100
+++ b/contrib/hgit	Tue Jun 21 21:04:49 2005 -0800
@@ -38,12 +38,12 @@
 
         for f in c:
             # TODO get file permissions
-            print ":100664 100664 %s %s %s %s" % (hg.hex(mmap[f]), 
+            print ":100664 100664 %s %s M\t%s\t%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)
+            print ":000000 100664 %s %s N\t%s\t%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)
+            print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f)
     ##
 
     revs = []
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/bdiff.c	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,293 @@
+/*
+ bdiff.c - efficient binary diff extension for Mercurial
+
+ Copyright 2005 Matt Mackall <mpm@selenic.com>
+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License, incorporated herein by reference.
+
+ Based roughly on Python difflib
+*/
+
+#include <Python.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+
+typedef unsigned long uint32_t;
+
+static uint32_t htonl(uint32_t x)
+{
+	return ((x & 0x000000ffUL) << 24) |
+		((x & 0x0000ff00UL) <<  8) |
+		((x & 0x00ff0000UL) >>  8) |
+		((x & 0xff000000UL) >> 24);
+}
+
+#else
+  #include <netinet/in.h>
+  #include <sys/types.h>
+#endif
+
+struct line {
+	int h, len, n;
+	const char *l;
+};
+
+struct hunk {
+	int a1, a2, b1, b2;
+};
+
+struct hunklist {
+	struct hunk *base, *head;
+};
+
+static inline uint32_t rol32(uint32_t word, unsigned int shift)
+{
+        return (word << shift) | (word >> (32 - shift));
+}
+
+int splitlines(const char *a, int len, struct line **lr)
+{
+	int h, i;
+	const char *p, *b = a;
+	struct line *l;
+
+	/* count the lines */
+	i = 1; /* extra line for sentinel */
+	for (p = a; p < a + len; p++)
+		if (*p == '\n' || p == a + len - 1)
+			i++;
+
+	*lr = l = malloc(sizeof(struct line) * i);
+	if (!l)
+		return -1;
+
+	/* build the line array and calculate hashes */
+	h = 0;
+	for (p = a; p < a + len; p++) {
+		h = *p + rol32(h, 7); /* a simple hash from GNU diff */
+		if (*p == '\n' || p == a + len - 1) {
+			l->len = p - b + 1;
+			l->h = h;
+			l->l = b;
+			l->n = -1;
+			l++;
+			b = p + 1;
+			h = 0;
+		}
+	}
+
+	/* set up a sentinel */
+	l->h = l->len = 0;
+	l->l = a + len;
+	return i - 1;
+}
+
+int inline cmp(struct line *a, struct line *b)
+{
+	return a->len != b->len || memcmp(a->l, b->l, a->len);
+}
+
+static int equatelines(struct line *a, int an, struct line *b, int bn)
+{
+	int i, j, buckets = 1, t, *h, *l;
+
+	/* build a hash table of the next highest power of 2 */
+	while (buckets < bn + 1)
+		buckets *= 2;
+
+	h = malloc(buckets * sizeof(int));
+	l = calloc(buckets, sizeof(int));
+	buckets = buckets - 1;
+	if (!h || !l) {
+		free(h);
+		return 0;
+	}
+
+	/* clear the hash table */
+	for (i = 0; i <= buckets; i++)
+		h[i] = -1;
+
+	/* add lines to the hash table chains */
+	for (i = bn - 1; i >= 0; i--) {
+		/* find the equivalence class */
+		for (j = b[i].h & buckets; h[j] != -1; j = (j + 1) & buckets)
+			if (!cmp(b + i, b + h[j]))
+				break;
+
+		/* add to the head of the equivalence class */
+		b[i].n = h[j];
+		b[i].h = j;
+		h[j] = i;
+		l[j]++; /* keep track of popularity */
+	}
+
+	/* compute popularity threshold */
+	t = (bn >= 200) ? bn / 100 : bn + 1;
+
+	/* match items in a to their equivalence class in b */
+	for (i = 0; i < an; i++) {
+		/* find the equivalence class */
+		for (j = a[i].h & buckets; h[j] != -1; j = (j + 1) & buckets)
+			if (!cmp(a + i, b + h[j]))
+				break;
+
+		a[i].h = j; /* use equivalence class for quick compare */
+		if(l[j] <= t)
+			a[i].n = h[j]; /* point to head of match list */
+		else
+			a[i].n = -1; /* too popular */
+	}
+
+	/* discard hash tables */
+	free(h);
+	free(l);
+	return 1;
+}
+
+static int longest_match(struct line *a, struct line *b, int *jpos, int *jlen,
+			 int a1, int a2, int b1, int b2, int *omi, int *omj)
+{
+	int mi = a1, mj = b1, mk = 0, mb = 0, i, j, k;
+
+	for (i = a1; i < a2; i++) {
+		/* skip things before the current block */
+		for (j = a[i].n; j != -1 && j < b1; j = b[j].n)
+			;
+
+		/* loop through all lines match a[i] in b */
+		for (; j != -1 && j < b2; j = b[j].n) {
+			/* does this extend an earlier match? */
+			if (i > a1 && j > b1 && jpos[j - 1] == i)
+				k = jlen[j - 1] + 1;
+			else
+				k = 1;
+			jpos[j] = i + 1;
+			jlen[j] = k;
+
+			/* best match so far? */
+			if (k > mk) {
+				mi = i;
+				mj = j;
+				mk = k;
+			}
+		}
+	}
+
+	if (mk) {
+		mi = mi - mk + 1;
+		mj = mj - mk + 1;
+	}
+
+	/* expand match to include neighboring popular lines */
+	while (mi - mb > a1 && mj - mb > b1 &&
+	       a[mi - mb - 1].h == b[mj - mb - 1].h)
+		mb++;
+	while (mi + mk < a2 && mj + mk < b2 &&
+	       a[mi + mk].h == b[mj + mk].h)
+		mk++;
+
+	*omi = mi - mb;
+	*omj = mj - mb;
+	return mk + mb;
+}
+
+static void recurse(struct line *a, struct line *b, int *jpos, int *jlen,
+		    int a1, int a2, int b1, int b2, struct hunklist *l)
+{
+	int i, j, k;
+
+	/* find the longest match in this chunk */
+	k = longest_match(a, b, jpos, jlen, a1, a2, b1, b2, &i, &j);
+	if (!k)
+		return;
+
+	/* and recurse on the remaining chunks on either side */
+	recurse(a, b, jpos, jlen, a1, i, b1, j, l);
+	l->head->a1 = i;
+	l->head->a2 = i + k;
+	l->head->b1 = j;
+	l->head->b2 = j + k;
+	l->head++;
+	recurse(a, b, jpos, jlen, i + k, a2, j + k, b2, l);
+}
+
+static PyObject *bdiff(PyObject *self, PyObject *args)
+{
+	PyObject *sa, *sb, *result = NULL;
+	struct hunklist l;
+	struct hunk *h;
+	struct line *al, *bl;
+	char encode[12], *rb;
+	int an, bn, len = 0, t, la = 0, lb = 0, *jpos, *jlen;
+
+	if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb))
+		return NULL;
+
+	/* allocate and fill arrays */
+	an = splitlines(PyString_AsString(sa), PyString_Size(sa), &al);
+	bn = splitlines(PyString_AsString(sb), PyString_Size(sb), &bl);
+	t = equatelines(al, an, bl, bn);
+	jpos = calloc(bn, sizeof(int));
+	jlen = calloc(bn, sizeof(int));
+	l.head = l.base = malloc(sizeof(struct hunk) * ((an + bn) / 4 + 2));
+	if (!al || !bl || !jpos || !jlen || !l.base || !t)
+		goto nomem;
+
+	/* generate the matching block list */
+	recurse(al, bl, jpos, jlen, 0, an, 0, bn, &l);
+	l.head->a1 = an;
+	l.head->b1 = bn;
+	l.head++;
+
+	/* calculate length of output */
+	for(h = l.base; h != l.head; h++) {
+		if (h->a1 != la || h->b1 != lb)
+			len += 12 + bl[h->b1].l - bl[lb].l;
+		la = h->a2;
+		lb = h->b2;
+	}
+
+	result = PyString_FromStringAndSize(NULL, len);
+	if (!result)
+		goto nomem;
+
+	/* build binary patch */
+	rb = PyString_AsString(result);
+	la = lb = 0;
+
+	for(h = l.base; h != l.head; h++) {
+		if (h->a1 != la || h->b1 != lb) {
+			len = bl[h->b1].l - bl[lb].l;
+			*(uint32_t *)(encode)     = htonl(al[la].l - al->l);
+			*(uint32_t *)(encode + 4) = htonl(al[h->a1].l - al->l);
+			*(uint32_t *)(encode + 8) = htonl(len);
+			memcpy(rb, encode, 12);
+			memcpy(rb + 12, bl[lb].l, len);
+			rb += 12 + len;
+		}
+		la = h->a2;
+		lb = h->b2;
+	}
+
+nomem:
+	free(al);
+	free(bl);
+	free(jpos);
+	free(jlen);
+	free(l.base);
+	return result ? result : PyErr_NoMemory();
+}
+
+static char mdiff_doc[] = "Efficient binary diff.";
+
+static PyMethodDef methods[] = {
+	{"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
+	{NULL, NULL}
+};
+
+PyMODINIT_FUNC initbdiff(void)
+{
+	Py_InitModule3("bdiff", methods, mdiff_doc);
+}
--- a/mercurial/commands.py	Sun Jun 19 21:04:32 2005 +0100
+++ b/mercurial/commands.py	Tue Jun 21 21:04:49 2005 -0800
@@ -6,7 +6,7 @@
 # of the GNU General Public License, incorporated herein by reference.
 
 import os, re, sys, signal
-import fancyopts, ui, hg
+import fancyopts, ui, hg, util
 from demandload import *
 demandload(globals(), "mdiff time hgweb traceback random signal errno version")
 
@@ -16,20 +16,20 @@
     l = [ x for x in files if x in filters ]
 
     for t in filters:
-        if t and t[-1] != os.sep: t += os.sep
+        if t and t[-1] != "/": t += "/"
         l += [ x for x in files if x.startswith(t) ]
     return l
 
 def relfilter(repo, files):
     if os.getcwd() != repo.root:
         p = os.getcwd()[len(repo.root) + 1: ]
-        return filterfiles([p], files)
+        return filterfiles([util.pconvert(p)], files)
     return files
 
 def relpath(repo, args):
     if os.getcwd() != repo.root:
         p = os.getcwd()[len(repo.root) + 1: ]
-        return [ os.path.normpath(os.path.join(p, x)) for x in args ]
+        return [ util.pconvert(os.path.normpath(os.path.join(p, x))) for x in args ]
     return args
 
 def dodiff(ui, repo, path, files = None, node1 = None, node2 = None):
@@ -47,7 +47,7 @@
         (c, a, d, u) = repo.diffdir(path, node1)
         if not node1:
             node1 = repo.dirstate.parents()[0]
-        def read(f): return file(os.path.join(repo.root, f)).read()
+        def read(f): return repo.wfile(f).read()
 
     if ui.quiet:
         r = None
@@ -285,7 +285,7 @@
         sys.stdout.write(chunk)
 
 def debugindex(ui, file):
-    r = hg.revlog(open, file, "")
+    r = hg.revlog(hg.opener(""), file, "")
     print "   rev    offset  length   base linkrev"+\
           " p1           p2           nodeid"
     for i in range(r.count()):
@@ -295,7 +295,7 @@
             hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
 
 def debugindexdot(ui, file):
-    r = hg.revlog(open, file, "")
+    r = hg.revlog(hg.opener(""), file, "")
     print "digraph G {"
     for i in range(r.count()):
         e = r.index[i]
@@ -485,17 +485,27 @@
             addremove(ui, repo, *files)
         repo.commit(files, text)
 
-def pull(ui, repo, source="default"):
+def pull(ui, repo, source="default", **opts):
     """pull changes from the specified source"""
     paths = {}
     for name, path in ui.configitems("paths"):
         paths[name] = path
 
-    if source in paths: source = paths[source]
+    if source in paths:
+        source = paths[source]
+
+    ui.status('pulling from %s\n' % (source))
     
     other = hg.repository(ui, source)
     cg = repo.getchangegroup(other)
-    repo.addchangegroup(cg)
+    r = repo.addchangegroup(cg)
+    if cg and not r:
+        if opts['update']:
+            return update(ui, repo)
+	else:
+            ui.status("(run 'hg update' to get a working copy)\n")
+
+    return r
 
 def push(ui, repo, dest="default-push"):
     """push changes to the specified destination"""
@@ -533,7 +543,7 @@
         os.kill(child, signal.SIGTERM)
         return r
 
-def rawcommit(ui, repo, flist, **rc):
+def rawcommit(ui, repo, *flist, **rc):
     "raw commit interface"
 
     text = rc['text']
@@ -544,7 +554,7 @@
         print "missing commit text"
         return 1
 
-    files = relpath(repo, flist)
+    files = relpath(repo, list(flist))
     if rc['files']:
         files += open(rc['files']).read().splitlines()
         
@@ -579,6 +589,35 @@
     for f in d: print "R", f
     for f in u: print "?", f
 
+def tag(ui, repo, name, rev = None, **opts):
+    """add a tag for the current tip or a given revision"""
+    
+    if name == "tip":
+	ui.warn("abort: 'tip' is a reserved name!\n")
+	return -1
+
+    (c, a, d, u) = repo.diffdir(repo.root)
+    for x in (c, a, d, u):
+	if ".hgtags" in x:
+	    ui.warn("abort: working copy of .hgtags is changed!\n")
+            ui.status("(please commit .hgtags manually)\n")
+	    return -1
+
+    if rev:
+        r = hg.hex(repo.lookup(rev))
+    else:
+        r = hg.hex(repo.changelog.tip())
+
+    add = 0
+    if not os.path.exists(repo.wjoin(".hgtags")): add = 1
+    repo.wfile(".hgtags", "a").write("%s %s\n" % (r, name))
+    if add: repo.add([".hgtags"])
+
+    if not opts['text']:
+        opts['text'] = "Added tag %s for changeset %s" % (name, r)
+
+    repo.commit([".hgtags"], opts['text'], opts['user'], opts['date'])
+
 def tags(ui, repo):
     """list repository tags"""
     
@@ -662,7 +701,9 @@
                       ('b', 'base', "", 'base path'),
                       ('q', 'quiet', "", 'silence diff')],
                      "hg import [options] patches"),
-    "pull|merge": (pull, [], 'hg pull [source]'),
+    "pull|merge": (pull, 
+                  [('u', 'update', None, 'update working directory')],
+		  'hg pull [options] [source]'),
     "push": (push, [], 'hg push <destination>'),
     "rawcommit": (rawcommit,
                   [('p', 'parent', [], 'parent'),
@@ -680,6 +721,10 @@
                       ('t', 'templates', "", 'template map')],
               "hg serve [options]"),
     "status": (status, [], 'hg status'),
+    "tag": (tag,  [('t', 'text', "", 'commit text'),
+                   ('d', 'date', "", 'date'),
+                   ('u', 'user', "", 'user')],
+            'hg tag [options] <name> [rev]'),
     "tags": (tags, [], 'hg tags'),
     "tip": (tip, [], 'hg tip'),
     "undo": (undo, [], 'hg undo'),
--- a/mercurial/hg.py	Sun Jun 19 21:04:32 2005 +0100
+++ b/mercurial/hg.py	Tue Jun 21 21:04:49 2005 -0800
@@ -6,6 +6,7 @@
 # of the GNU General Public License, incorporated herein by reference.
 
 import sys, struct, os
+import util
 from revlog import *
 from demandload import *
 demandload(globals(), "re lock urllib urllib2 transaction time socket")
@@ -336,8 +337,8 @@
                     os.makedirs(d)
             else:
                 if s.st_nlink > 1:
-                    file(f + ".tmp", "w").write(file(f).read())
-                    os.rename(f+".tmp", f)
+                    file(f + ".tmp", "wb").write(file(f, "rb").read())
+                    util.rename(f+".tmp", f)
 
         return file(f, mode)
 
@@ -353,11 +354,15 @@
             if not path:
                 p = os.getcwd()
                 while not os.path.isdir(os.path.join(p, ".hg")):
+                    oldp = p
                     p = os.path.dirname(p)
-                    if p == "/": raise "No repo found"
+                    if p == oldp: raise "No repo found"
                 path = p
             self.path = os.path.join(path, ".hg")
 
+            if not create and not os.path.isdir(self.path):
+                raise "repository %s not found" % self.path
+
         self.root = path
         self.ui = ui
 
@@ -383,10 +388,10 @@
         if self.ignorelist is None:
             self.ignorelist = []
             try:
-                l = self.wfile(".hgignore")
+                l = file(self.wjoin(".hgignore"))
                 for pat in l:
                     if pat != "\n":
-                        self.ignorelist.append(re.compile(pat[:-1]))
+                        self.ignorelist.append(re.compile(util.pconvert(pat[:-1])))
             except IOError: pass
         for pat in self.ignorelist:
             if pat.search(f): return True
@@ -477,7 +482,7 @@
             self.ui.status("attempting to rollback last transaction\n")
             transaction.rollback(self.opener, self.join("undo"))
             self.dirstate = None
-            os.rename(self.join("undo.dirstate"), self.join("dirstate"))
+            util.rename(self.join("undo.dirstate"), self.join("dirstate"))
             self.dirstate = dirstate(self.opener, self.ui, self.root)
         else:
             self.ui.warn("no undo information available\n")
@@ -566,7 +571,7 @@
             try:
                 fp = self.wjoin(f)
                 mf1[f] = is_exec(fp)
-                t = file(fp).read()
+                t = self.wfile(f).read()
             except IOError:
                 self.warn("trouble committing %s!\n" % f)
                 raise
@@ -585,7 +590,9 @@
 
         # update manifest
         m1.update(new)
-        for f in remove: del m1[f]
+        for f in remove:
+            if f in m1:
+                del m1[f]
         mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0])
 
         # add changeset
@@ -634,7 +641,7 @@
             if ".hg" in subdirs: subdirs.remove(".hg")
             
             for f in files:
-                fn = os.path.join(d, f)
+                fn = util.pconvert(os.path.join(d, f))
                 try: s = os.stat(os.path.join(self.root, fn))
                 except: continue
                 if fn in dc:
@@ -706,6 +713,9 @@
             p = self.wjoin(f)
             if os.path.isfile(p):
                 self.ui.warn("%s still exists!\n" % f)
+            elif self.dirstate.state(f) == 'a':
+                self.ui.warn("%s never committed!\n" % f)
+                self.dirstate.forget(f)
             elif f not in self.dirstate:
                 self.ui.warn("%s not tracked!\n" % f)
             else:
@@ -1001,10 +1011,14 @@
         m2 = self.manifest.read(m2n)
         mf2 = self.manifest.readflags(m2n)
         ma = self.manifest.read(man)
-        mfa = self.manifest.readflags(m2n)
+        mfa = self.manifest.readflags(man)
 
         (c, a, d, u) = self.diffdir(self.root)
 
+        # is this a jump, or a merge?  i.e. is there a linear path
+        # from p1 to p2?
+        linear_path = (pa == p1 or pa == p2)
+
         # resolve the manifest to determine which files
         # we care about merging
         self.ui.note("resolving manifests\n")
@@ -1025,17 +1039,33 @@
         for f in d:
             if f in mw: del mw[f]
 
+            # If we're jumping between revisions (as opposed to merging),
+            # and if neither the working directory nor the target rev has
+            # the file, then we need to remove it from the dirstate, to
+            # prevent the dirstate from listing the file when it is no
+            # longer in the manifest.
+            if linear_path and f not in m2:
+                self.dirstate.forget((f,))
+
         for f, n in mw.iteritems():
             if f in m2:
                 s = 0
 
+                # is the wfile new since m1, and match m2?
+                if f not in m1:
+                    t1 = self.wfile(f).read()
+                    t2 = self.file(f).revision(m2[f])
+                    if cmp(t1, t2) == 0:
+                        mark[f] = 1
+                        n = m2[f]
+                    del t1, t2
+
                 # are files different?
                 if n != m2[f]:
                     a = ma.get(f, nullid)
                     # are both different from the ancestor?
                     if n != a and m2[f] != a:
                         self.ui.debug(" %s versions differ, resolve\n" % f)
-                        merge[f] = (m1.get(f, nullid), m2[f])
                         # merge executable bits
                         # "if we changed or they changed, change in merge"
                         a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
@@ -1066,9 +1096,11 @@
                 del m2[f]
             elif f in ma:
                 if not force and n != ma[f]:
-                    r = self.ui.prompt(
-                        (" local changed %s which remote deleted\n" % f) +
-                        "(k)eep or (d)elete?", "[kd]", "k")
+                    r = ""
+                    if linear_path or allow:
+                        r = self.ui.prompt(
+                            (" local changed %s which remote deleted\n" % f) +
+                            "(k)eep or (d)elete?", "[kd]", "k")
                     if r == "d":
                         remove.append(f)
                 else:
@@ -1087,9 +1119,11 @@
         for f, n in m2.iteritems():
             if f[0] == "/": continue
             if not force and f in ma and n != ma[f]:
-                r = self.ui.prompt(
-                    ("remote changed %s which local deleted\n" % f) +
-                    "(k)eep or (d)elete?", "[kd]", "k")
+                r = ""
+                if linear_path or allow:
+                    r = self.ui.prompt(
+                        ("remote changed %s which local deleted\n" % f) +
+                        "(k)eep or (d)elete?", "[kd]", "k")
                 if r == "d": remove.append(f)
             else:
                 self.ui.debug("remote created %s\n" % f)
@@ -1102,7 +1136,7 @@
                 get[f] = merge[f][1]
             merge = {}
 
-        if pa == p1 or pa == p2:
+        if linear_path:
             # we don't need to do any magic, just jump to the new rev
             mode = 'n'
             p1, p2 = p2, nullid
@@ -1166,7 +1200,7 @@
         def temp(prefix, node):
             pre = "%s~%s." % (os.path.basename(fn), prefix)
             (fd, name) = tempfile.mkstemp("", pre)
-            f = os.fdopen(fd, "w")
+            f = os.fdopen(fd, "wb")
             f.write(fl.revision(node))
             f.close()
             return name
--- a/mercurial/lock.py	Sun Jun 19 21:04:32 2005 +0100
+++ b/mercurial/lock.py	Tue Jun 21 21:04:49 2005 -0800
@@ -6,6 +6,7 @@
 # of the GNU General Public License, incorporated herein by reference.
 
 import os, time
+import util
 
 class LockHeld(Exception):
     pass
@@ -34,10 +35,10 @@
     def trylock(self):
         pid = os.getpid()
         try:
-            os.symlink(str(pid), self.f)
+            util.makelock(str(pid), self.f)
             self.held = 1
         except:
-            raise LockHeld(os.readlink(self.f))
+            raise LockHeld(util.readlock(self.f))
 
     def release(self):
         if self.held:
--- a/mercurial/mpatch.c	Sun Jun 19 21:04:32 2005 +0100
+++ b/mercurial/mpatch.c	Tue Jun 21 21:04:49 2005 -0800
@@ -23,8 +23,22 @@
 #include <Python.h>
 #include <stdlib.h>
 #include <string.h>
-#include <netinet/in.h>
-#include <sys/types.h>
+#ifdef _WIN32
+
+typedef unsigned long uint32_t;
+
+static uint32_t ntohl(uint32_t x)
+{
+	return ((x & 0x000000ffUL) << 24) |
+		((x & 0x0000ff00UL) <<  8) |
+		((x & 0x00ff0000UL) >>  8) |
+		((x & 0xff000000UL) >> 24);
+}
+
+#else
+  #include <netinet/in.h>
+  #include <sys/types.h>
+#endif
 
 static char mpatch_doc[] = "Efficient binary patching.";
 
--- a/mercurial/transaction.py	Sun Jun 19 21:04:32 2005 +0100
+++ b/mercurial/transaction.py	Tue Jun 21 21:04:49 2005 -0800
@@ -12,6 +12,7 @@
 # of the GNU General Public License, incorporated herein by reference.
 
 import os
+import util
 
 class transaction:
     def __init__(self, opener, journal, after = None):
@@ -46,7 +47,7 @@
         self.file.close()
         self.entries = []
         if self.after:
-            os.rename(self.journal, self.after)
+            util.rename(self.journal, self.after)
         else:
             os.unlink(self.journal)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/util.py	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,39 @@
+# util.py - utility functions and platform specfic implementations
+#
+# Copyright 2005 K. Thananchayan <thananck@yahoo.com>
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+import os
+
+def rename(src, dst):
+    try:
+        os.rename(src, dst)
+    except:
+        os.unlink(dst)
+        os.rename(src, dst)
+
+# Platfor specific varients
+if os.name == 'nt':
+    def pconvert(path):
+        return path.replace("\\", "/")
+
+    def makelock(info, pathname):
+        ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
+        os.write(ld, info)
+        os.close(ld)
+
+    def readlock(pathname):
+        return file(pathname).read()
+else:
+    def pconvert(path):
+        return path
+
+    def makelock(info, pathname):
+        os.symlink(info, pathname)
+
+    def readlock(pathname):
+        return os.readlink(pathname)
+
+
--- a/setup.py	Sun Jun 19 21:04:32 2005 +0100
+++ b/setup.py	Tue Jun 21 21:04:49 2005 -0800
@@ -23,19 +23,20 @@
 try:
     mercurial.version.remember_version(version)
     setup(name='mercurial',
-        version=mercurial.version.get_version(),
-        author='Matt Mackall',
-        author_email='mpm@selenic.com',
-        url='http://selenic.com/mercurial',
-        description='scalable distributed SCM',
-        license='GNU GPL',
-        packages=['mercurial'],
-        ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c'])],
-        data_files=[('mercurial/templates',
-                    ['templates/map'] +
-                    glob.glob('templates/map-*') +
-                    glob.glob('templates/*.tmpl'))], 
-        cmdclass = { 'install_data' : install_package_data },
-        scripts=['hg', 'hgmerge'])
+          version=mercurial.version.get_version(),
+          author='Matt Mackall',
+          author_email='mpm@selenic.com',
+          url='http://selenic.com/mercurial',
+          description='scalable distributed SCM',
+          license='GNU GPL',
+          packages=['mercurial'],
+          ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
+                       Extension('mercurial.bdiff', ['mercurial/bdiff.c'])],
+          data_files=[('mercurial/templates',
+                       ['templates/map'] +
+                       glob.glob('templates/map-*') +
+                       glob.glob('templates/*.tmpl'))], 
+          cmdclass = { 'install_data' : install_package_data },
+          scripts=['hg', 'hgmerge'])
 finally:
     mercurial.version.forget_version()
--- a/tests/run-tests	Sun Jun 19 21:04:32 2005 +0100
+++ b/tests/run-tests	Tue Jun 21 21:04:49 2005 -0800
@@ -6,8 +6,22 @@
 failed=0
 H=$PWD
 
+TESTPATH=$PWD/install/bin
+export PATH=$TESTPATH:$PATH
+export PYTHONPATH=$PWD/install/lib/python
+
+rm -rf install
+cd ..
+${PYTHON:-python} setup.py install --home=tests/install > tests/install.err
+if [ $? != 0 ] ; then
+    cat tests/install.err
+fi
+cd $H
+rm install.err
+
 function run_one
 {
+    rm -f $1.err
     export TZ=GMT
     D=`mktemp -d`
     if [ "$D" == "" ] ; then
@@ -17,20 +31,20 @@
     cd $D
     fail=0
 
-    if ! $H/$f > .out 2>&1 ; then
-	echo $f failed with error code $?
+    if ! $H/$1 > .out 2>&1 ; then
+	echo $1 failed with error code $?
 	fail=1
     fi
 
-    if [ -s .out -a ! -r $H/$f.out ] ; then
-	echo $f generated unexpected output:
+    if [ -s .out -a ! -r $H/$1.out ] ; then
+	echo $1 generated unexpected output:
 	cat .out
-	cp .out $H/$f.err
+	cp .out $H/$1.err
 	fail=1
-    elif [ -r $H/$f.out ] && ! 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
+    elif [ -r $H/$1.out ] && ! diff -u $H/$1.out .out > /dev/null ; then
+	echo $1 output changed:
+	diff -u $H/$1.out .out && true
+	cp .out $H/$1.err
 	fail=1
     fi
 
@@ -52,6 +66,8 @@
     tests=$[$tests + 1]
 done
 
+rm -rf install
+
 echo
 echo Ran $tests tests, $failed failed
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-bdiff	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+import sys
+from mercurial import bdiff, mpatch
+
+def test1(a, b):
+    d = bdiff.bdiff(a, b)
+    c = a
+    if d:
+        c = mpatch.patches(a, [d])
+    if c != b:
+        print "***", `a`, `b`
+        print "bad:"
+        print `c`[:200]
+        print `d`
+
+def test(a, b):
+    print "***", `a`, `b`
+    test1(a, b)
+    test1(b, a)
+
+test("a\nc\n\n\n\n", "a\nb\n\n\n")
+test("a\nb\nc\n", "a\nc\n")
+test("", "")
+test("a\nb\nc", "a\nb\nc")
+test("a\nb\nc\nd\n", "a\nd\n")
+test("a\nb\nc\nd\n", "a\nc\ne\n")
+test("a\nb\nc\n", "a\nc\n")
+test("a\n", "c\na\nb\n")
+test("a\n", "")
+test("a\n", "b\nc\n")
+test("a\n", "c\na\n")
+test("", "adjfkjdjksdhfksj")
+test("", "ab")
+test("", "abc")
+test("a", "a")
+test("ab", "ab")
+test("abc", "abc")
+test("a\n", "a\n")
+test("a\nb", "a\nb")
+
+print "done"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-bdiff.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,20 @@
+*** 'a\nc\n\n\n\n' 'a\nb\n\n\n'
+*** 'a\nb\nc\n' 'a\nc\n'
+*** '' ''
+*** 'a\nb\nc' 'a\nb\nc'
+*** 'a\nb\nc\nd\n' 'a\nd\n'
+*** 'a\nb\nc\nd\n' 'a\nc\ne\n'
+*** 'a\nb\nc\n' 'a\nc\n'
+*** 'a\n' 'c\na\nb\n'
+*** 'a\n' ''
+*** 'a\n' 'b\nc\n'
+*** 'a\n' 'c\na\n'
+*** '' 'adjfkjdjksdhfksj'
+*** '' 'ab'
+*** '' 'abc'
+*** 'a' 'a'
+*** 'ab' 'ab'
+*** 'abc' 'abc'
+*** 'a\n' 'a\n'
+*** 'a\nb' 'a\nb'
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-flags	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,33 @@
+#!/bin/sh +ex
+
+mkdir test1
+cd test1
+
+hg init
+touch a b
+hg add a b
+hg ci -t "added a b" -u test -d "0 0"
+
+cd ..
+mkdir test2
+cd test2
+
+hg init
+hg merge ../test1
+hg co
+chmod +x a
+hg ci -t "chmod +x a" -u test -d "0 0"
+
+cd ../test1
+echo 123 >>a
+hg ci -t "a updated" -u test -d "0 0"
+
+hg merge ../test2
+hg heads
+hg history
+
+hg -dv co -m
+
+ls -l ../test[12]/a > foo
+cut -b 0-10 < foo
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-flags.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,51 @@
+pulling from ../test1
+requesting all changes
+adding changesets
+adding manifests
+adding file revisions
+modified 2 files, added 1 changesets and 2 new revisions
+(run 'hg update' to get a working copy)
+pulling from ../test2
+searching for changes
+adding changesets
+adding manifests
+adding file revisions
+modified 1 files, added 1 changesets and 1 new revisions
+(run 'hg update' to get a working copy)
+changeset:   2:3ef54330565526bebf37a0d9bf540c283fd133a1
+tag:         tip
+parent:      0:22a449e20da501ca558394c083ca470e9c81b9f7
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     chmod +x a
+
+changeset:   1:c6ecefc45368ed556d965f1c1086c6561a8b2ac5
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     a updated
+
+changeset:   2:3ef54330565526bebf37a0d9bf540c283fd133a1
+tag:         tip
+parent:      0:22a449e20da501ca558394c083ca470e9c81b9f7
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     chmod +x a
+
+changeset:   1:c6ecefc45368ed556d965f1c1086c6561a8b2ac5
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     a updated
+
+changeset:   0:22a449e20da501ca558394c083ca470e9c81b9f7
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     added a b
+
+resolving manifests
+ ancestor f328b97f7c11 local e7f06daf1cdb remote 629f0b785e0e
+ a versions differ, resolve
+merging a
+resolving a
+file a: other 37c42bd6cc03 ancestor b80de5d13875
+-rwxr-xr-x
+-rwxr-xr-x
--- a/tests/test-help.out	Sun Jun 19 21:04:32 2005 +0100
+++ b/tests/test-help.out	Tue Jun 21 21:04:49 2005 -0800
@@ -26,6 +26,7 @@
  remove      remove the specified files on the next commit
  serve       export the repository via HTTP
  status      show changed files in the working directory
+ tag         add a tag for the current tip or a given revision
  tags        list repository tags
  tip         show the tip revision
  undo        undo the last transaction
@@ -74,6 +75,7 @@
  remove      remove the specified files on the next commit
  serve       export the repository via HTTP
  status      show changed files in the working directory
+ tag         add a tag for the current tip or a given revision
  tags        list repository tags
  tip         show the tip revision
  undo        undo the last transaction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge1	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,85 @@
+#!/bin/sh -x
+
+cat <<'EOF' > merge
+#!/bin/sh
+echo merging for `basename $1`
+EOF
+chmod +x merge
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+
+hg update 0
+echo This is file c1 > c
+hg add c
+hg commit -t "commit #2" -d "0 0" -u user
+echo This is file b1 > b
+env HGMERGE=../merge hg update -m 1
+# no merges expected
+cd ..; /bin/rm -rf t
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+
+hg update 0
+echo This is file c1 > c
+hg add c
+hg commit -t "commit #2" -d "0 0" -u user
+echo This is file b2 > b
+env HGMERGE=../merge hg update -m 1
+# merge of b expected
+cd ..; /bin/rm -rf t
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+echo This is file b22 > b
+hg commit -t "commit #2" -d "0 0" -u user
+hg update 1
+echo This is file c1 > c
+hg add c
+hg commit -t "commit #3" -d "0 0" -u user
+echo This is file b22 > b
+env HGMERGE=../merge hg update -m 2
+# no merges expected
+cd ..; /bin/rm -rf t
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+echo This is file b22 > b
+hg commit -t "commit #2" -d "0 0" -u user
+hg update 1
+echo This is file c1 > c
+hg add c
+hg commit -t "commit #3" -d "0 0" -u user
+echo This is file b33 > b
+env HGMERGE=../merge hg update -m 2
+# merge of b expected
+cd ..; /bin/rm -rf t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge1.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,78 @@
++ cat
++ chmod +x merge
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ hg update 0
++ echo This is file c1
++ hg add c
++ hg commit -t 'commit #2' -d '0 0' -u user
++ echo This is file b1
++ env HGMERGE=../merge hg update -m 1
++ cd ..
++ /bin/rm -rf t
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ hg update 0
++ echo This is file c1
++ hg add c
++ hg commit -t 'commit #2' -d '0 0' -u user
++ echo This is file b2
++ env HGMERGE=../merge hg update -m 1
+merging for b
+merging b
++ cd ..
++ /bin/rm -rf t
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ echo This is file b22
++ hg commit -t 'commit #2' -d '0 0' -u user
++ hg update 1
++ echo This is file c1
++ hg add c
++ hg commit -t 'commit #3' -d '0 0' -u user
++ echo This is file b22
++ env HGMERGE=../merge hg update -m 2
++ cd ..
++ /bin/rm -rf t
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ echo This is file b22
++ hg commit -t 'commit #2' -d '0 0' -u user
++ hg update 1
++ echo This is file c1
++ hg add c
++ hg commit -t 'commit #3' -d '0 0' -u user
++ echo This is file b33
++ env HGMERGE=../merge hg update -m 2
+merging for b
+merging b
++ cd ..
++ /bin/rm -rf t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge2	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,48 @@
+#!/bin/sh -x
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+rm b
+hg update 0
+echo This is file b2 > b
+hg add b
+hg commit -t "commit #2" -d "0 0" -u user
+cd ..; /bin/rm -rf t
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+rm b
+hg update 0
+echo This is file b2 > b
+hg commit -A -t "commit #2" -d "0 0" -u user
+cd ..; /bin/rm -rf t
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+rm b
+hg remove b
+hg update 0
+echo This is file b2 > b
+hg commit -A -t "commit #2" -d "0 0" -u user
+cd ..; /bin/rm -rf t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge2.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,47 @@
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ rm b
++ hg update 0
++ echo This is file b2
++ hg add b
++ hg commit -t 'commit #2' -d '0 0' -u user
++ cd ..
++ /bin/rm -rf t
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ rm b
++ hg update 0
++ echo This is file b2
++ hg commit -A -t 'commit #2' -d '0 0' -u user
++ cd ..
++ /bin/rm -rf t
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ rm b
++ hg remove b
++ hg update 0
++ echo This is file b2
++ hg commit -A -t 'commit #2' -d '0 0' -u user
++ cd ..
++ /bin/rm -rf t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge3	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,10 @@
+#!/bin/sh -x
+
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+touch b
+hg add b
+rm b
+hg commit -A -t"comment #1" -d "0 0" -u user
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge3.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,9 @@
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ touch b
++ hg add b
++ rm b
++ hg commit -A '-tcomment #1' -d '0 0' -u user
+b never committed!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge4	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,17 @@
+#!/bin/sh -x
+
+hg init
+echo This is file a1 > a
+hg add a
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b1 > b
+hg add b
+hg commit -t "commit #1" -d "0 0" -u user
+hg update 0
+echo This is file c1 > c
+hg add c
+hg commit -t "commit #2" -d "0 0" -u user
+hg update -m 1
+rm b
+echo This is file c22 > c
+hg commit -t "commit #3" -d "0 0" -u user
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge4.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,15 @@
++ hg init
++ echo This is file a1
++ hg add a
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b1
++ hg add b
++ hg commit -t 'commit #1' -d '0 0' -u user
++ hg update 0
++ echo This is file c1
++ hg add c
++ hg commit -t 'commit #2' -d '0 0' -u user
++ hg update -m 1
++ rm b
++ echo This is file c22
++ hg commit -t 'commit #3' -d '0 0' -u user
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge5	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,21 @@
+#!/bin/sh -x
+
+mkdir t
+cd t
+hg init
+echo This is file a1 > a
+echo This is file b1 > b
+hg add a b
+hg commit -t "commit #0" -d "0 0" -u user
+echo This is file b22 > b
+hg commit -t"comment #1" -d "0 0" -u user
+hg update 0
+rm b
+hg commit -A -t"comment #2" -d "0 0" -u user
+# in theory, we shouldn't need the "yes k" below, but it prevents
+# this test from hanging when "hg update" erroneously prompts the
+# user for "keep or delete"
+yes k | hg update 1
+# we exit with 0 to avoid the unavoidable SIGPIPE from above causing
+# us to fail this test
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge5.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,18 @@
++ mkdir t
++ cd t
++ hg init
++ echo This is file a1
++ echo This is file b1
++ hg add a b
++ hg commit -t 'commit #0' -d '0 0' -u user
++ echo This is file b22
++ hg commit '-tcomment #1' -d '0 0' -u user
++ hg update 0
++ rm b
++ hg commit -A '-tcomment #2' -d '0 0' -u user
++ yes k
++ hg update 1
+this update spans a branch affecting the following files:
+aborting update spanning branches!
+(use update -m to perform a branch merge)
++ exit 0
--- a/tests/test-simple-update.out	Sun Jun 19 21:04:32 2005 +0100
+++ b/tests/test-simple-update.out	Tue Jun 21 21:04:49 2005 -0800
@@ -19,11 +19,13 @@
 + hg commit -t 2
 + cd ../test
 + hg pull ../branch
+pulling from ../branch
 searching for changes
 adding changesets
 adding manifests
 adding file revisions
 modified 1 files, added 1 changesets and 1 new revisions
+(run 'hg update' to get a working copy)
 + hg verify
 checking changesets
 checking manifests
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-tag	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,13 @@
+#!/bin/sh -x
+
+hg init
+echo a > a
+hg add a
+hg commit -t "test" -u test -d "0 0"
+hg history
+hg tag -u test -d "0 0" "bleah" 
+hg history
+
+echo foo >> .hgtags
+hg tag -u test -d "0 0" "bleah2" || echo "failed" 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-tag.out	Tue Jun 21 21:04:49 2005 -0800
@@ -0,0 +1,31 @@
++ hg init
++ echo a
++ hg add a
++ hg commit -t test -u test -d '0 0'
++ hg history
+changeset:   0:acb14030fe0a21b60322c440ad2d20cf7685a376
+tag:         tip
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     test
+
++ hg tag -u test -d '0 0' bleah
++ hg history
+changeset:   1:863197ef03781c4fc00276d83eb66c4cb9cd91df
+tag:         tip
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     Added tag bleah for changeset acb14030fe0a21b60322c440ad2d20cf7685a376
+
+changeset:   0:acb14030fe0a21b60322c440ad2d20cf7685a376
+tag:         bleah
+user:        test
+date:        Thu Jan  1 00:00:00 1970
+summary:     test
+
++ echo foo
++ hg tag -u test -d '0 0' bleah2
+abort: working copy of .hgtags is changed!
+(please commit .hgtags manually)
++ echo failed
+failed