merge with crew.

This commit is contained in:
Vadim Gelfer 2006-02-03 00:52:31 -08:00
commit 74c20c0bae
6 changed files with 322 additions and 152 deletions

View File

@ -2,36 +2,36 @@ shopt -s extglob
_hg_command_list()
{
hg --debug help 2>/dev/null | \
"$hg" --debug help 2>/dev/null | \
awk 'function command_line(line) {
gsub(/,/, "", line)
gsub(/:.*/, "", line)
split(line, aliases)
command = aliases[1]
delete aliases[1]
print command
for (i in aliases)
if (index(command, aliases[i]) != 1)
print aliases[i]
}
/^list of commands:/ {commands=1}
commands && /^ debug/ {a[i++] = $0; next;}
commands && /^ [^ ]/ {command_line($0)}
/^global options:/ {exit 0}
END {for (i in a) command_line(a[i])}'
gsub(/,/, "", line)
gsub(/:.*/, "", line)
split(line, aliases)
command = aliases[1]
delete aliases[1]
print command
for (i in aliases)
if (index(command, aliases[i]) != 1)
print aliases[i]
}
/^list of commands:/ {commands=1}
commands && /^ debug/ {a[i++] = $0; next;}
commands && /^ [^ ]/ {command_line($0)}
/^global options:/ {exit 0}
END {for (i in a) command_line(a[i])}'
}
_hg_option_list()
{
hg -v help $1 2> /dev/null | \
awk '/^ *-/ {
for (i = 1; i <= NF; i ++) {
"$hg" -v help $1 2>/dev/null | \
awk '/^ *-/ {
for (i = 1; i <= NF; i ++) {
if (index($i, "-") != 1)
break;
break;
print $i;
}
}'
}
}'
}
@ -56,29 +56,29 @@ _hg_commands()
_hg_paths()
{
local paths="$(hg paths 2> /dev/null | sed -e 's/ = .*$//')"
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W '$paths' -- "$cur" ))
local paths="$("$hg" paths 2>/dev/null | sed -e 's/ = .*$//')"
COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur"))
}
_hg_repos()
{
local i
for i in $( compgen -d -- "$cur" ); do
test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
for i in $(compgen -d -- "$cur"); do
test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
done
}
_hg_status()
{
local files="$( hg status -n$1 . 2> /dev/null)"
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W '$files' -- "$cur" ))
local files="$("$hg" status -n$1 . 2>/dev/null)"
COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
}
_hg_tags()
{
local tags="$(hg tags 2> /dev/null |
sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//')"
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W '$tags' -- "$cur") )
local tags="$("$hg" tags 2>/dev/null |
sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//')"
COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$tags' -- "$cur"))
}
# this is "kind of" ugly...
@ -87,7 +87,7 @@ _hg_count_non_option()
local i count=0
local filters="$1"
for (( i=1; $i<=$COMP_CWORD; i++ )); do
for ((i=1; $i<=$COMP_CWORD; i++)); do
if [[ "${COMP_WORDS[i]}" != -* ]]; then
if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
continue
@ -104,6 +104,7 @@ _hg()
local cur prev cmd opts i
# global options that receive an argument
local global_args='--cwd|-R|--repository'
local hg="$1"
COMPREPLY=()
cur="$2"
@ -112,7 +113,7 @@ _hg()
# searching for the command
# (first non-option argument that doesn't follow a global option that
# receives an argument)
for (( i=1; $i<=$COMP_CWORD; i++ )); do
for ((i=1; $i<=$COMP_CWORD; i++)); do
if [[ ${COMP_WORDS[i]} != -* ]]; then
if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
cmd="${COMP_WORDS[i]}"
@ -124,7 +125,7 @@ _hg()
if [[ "$cur" == -* ]]; then
opts=$(_hg_option_list $cmd)
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur") )
COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
return
fi
@ -146,7 +147,7 @@ _hg()
fi
# canonicalize command name
cmd=$(hg -q help "$cmd" 2> /dev/null | sed -e 's/^hg //; s/ .*//; 1q')
cmd=$("$hg" -q help "$cmd" 2>/dev/null | sed -e 's/^hg //; s/ .*//; 1q')
if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" = --rev ]; then
_hg_tags
@ -190,17 +191,17 @@ _hg()
if [ $count = 1 ]; then
_hg_paths
fi
_hg_repos
_hg_repos
;;
debugindex|debugindexdot)
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -X "!*.i" -- "$cur" ))
COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"))
;;
debugdata)
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -X "!*.d" -- "$cur" ))
COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"))
;;
esac
}
complete -o bashdefault -o default -F _hg hg 2> /dev/null \
complete -o bashdefault -o default -F _hg hg 2>/dev/null \
|| complete -o default -F _hg hg

View File

@ -1,6 +1,14 @@
import os, tempfile, binascii, errno
# GnuPG signing extension for Mercurial
#
# Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
import os, tempfile, binascii
from mercurial import util
from mercurial import node as hgnode
from mercurial.i18n import gettext as _
class gpg:
def __init__(self, path, key=None):
@ -14,6 +22,7 @@ class gpg:
def verify(self, data, sig):
""" returns of the good and bad signatures"""
try:
# create temporary files
fd, sigfile = tempfile.mkstemp(prefix="hggpgsig")
fp = os.fdopen(fd, 'wb')
fp.write(sig)
@ -22,8 +31,8 @@ class gpg:
fp = os.fdopen(fd, 'wb')
fp.write(data)
fp.close()
gpgcmd = "%s --logger-fd 1 --status-fd 1 --verify \"%s\" \"%s\"" % (self.path, sigfile, datafile)
#gpgcmd = "%s --status-fd 1 --verify \"%s\" \"%s\"" % (self.path, sigfile, datafile)
gpgcmd = ("%s --logger-fd 1 --status-fd 1 --verify "
"\"%s\" \"%s\"" % (self.path, sigfile, datafile))
ret = util.filter("", gpgcmd)
except:
for f in (sigfile, datafile):
@ -41,7 +50,7 @@ class gpg:
continue
l = l[9:]
if l.startswith("ERRSIG"):
err = "error while verifying signature"
err = _("error while verifying signature")
break
elif l.startswith("VALIDSIG"):
# fingerprint of the primary key
@ -61,12 +70,97 @@ class gpg:
return err, keys
def newgpg(ui, **opts):
"""create a new gpg instance"""
gpgpath = ui.config("gpg", "cmd", "gpg")
gpgkey = opts.get('key')
if not gpgkey:
gpgkey = ui.config("gpg", "key", None)
return gpg(gpgpath, gpgkey)
def sigwalk(repo):
"""
walk over every sigs, yields a couple
((node, version, sig), (filename, linenumber))
"""
def parsefile(fileiter, context):
ln = 1
for l in fileiter:
if not l:
continue
yield (l.split(" ", 2), (context, ln))
ln +=1
fl = repo.file(".hgsigs")
h = fl.heads()
h.reverse()
# read the heads
for r in h:
fn = ".hgsigs|%s" % hgnode.short(r)
for item in parsefile(fl.read(r).splitlines(), fn):
yield item
try:
# read local signatures
fn = "localsigs"
for item in parsefile(repo.opener(fn), fn):
yield item
except IOError:
pass
def getkeys(ui, repo, mygpg, sigdata, context):
"""get the keys who signed a data"""
fn, ln = context
node, version, sig = sigdata
prefix = "%s:%d" % (fn, ln)
node = hgnode.bin(node)
data = node2txt(repo, node, version)
sig = binascii.a2b_base64(sig)
err, keys = mygpg.verify(data, sig)
if err:
ui.warn("%s:%d %s\n" % (fn, ln , err))
return None
validkeys = []
# warn for expired key and/or sigs
for key in keys:
if key[0] == "BADSIG":
ui.write(_("%s Bad signature from \"%s\"\n") % (prefix, key[2]))
continue
if key[0] == "EXPSIG":
ui.write(_("%s Note: Signature has expired"
" (signed by: \"%s\")\n") % (prefix, key[2]))
elif key[0] == "EXPKEYSIG":
ui.write(_("%s Note: This key has expired"
" (signed by: \"%s\")\n") % (prefix, key[2]))
validkeys.append((key[1], key[2], key[3]))
return validkeys
def sigs(ui, repo):
"""list signed changesets"""
mygpg = newgpg(ui)
revs = {}
for data, context in sigwalk(repo):
node, version, sig = data
fn, ln = context
try:
n = repo.lookup(node)
except KeyError:
ui.warn(_("%s:%d node does not exist\n") % (fn, ln))
continue
r = repo.changelog.rev(n)
keys = getkeys(ui, repo, mygpg, data, context)
if not keys:
continue
revs.setdefault(r, [])
revs[r].extend(keys)
nodes = list(revs)
nodes.reverse()
for rev in nodes:
for k in revs[rev]:
r = "%5d:%s" % (rev, hgnode.hex(repo.changelog.node(rev)))
ui.write("%-30s %s\n" % (keystr(ui, k), r))
def check(ui, repo, rev):
"""verify all the signatures there may be for a particular revision"""
mygpg = newgpg(ui)
@ -74,63 +168,30 @@ def check(ui, repo, rev):
hexrev = hgnode.hex(rev)
keys = []
def addsig(fn, ln, l):
if not l: return
n, v, sig = l.split(" ", 2)
if n == hexrev:
data = node2txt(repo, rev, v)
sig = binascii.a2b_base64(sig)
err, k = mygpg.verify(data, sig)
if not err:
keys.append((k, fn, ln))
else:
ui.warn("%s:%d %s\n" % (fn, ln , err))
fl = repo.file(".hgsigs")
h = fl.heads()
h.reverse()
# read the heads
for r in h:
ln = 1
for l in fl.read(r).splitlines():
addsig(".hgsigs|%s" % hgnode.short(r), ln, l)
ln +=1
try:
# read local signatures
ln = 1
f = repo.opener("localsigs")
for l in f:
addsig("localsigs", ln, l)
ln +=1
except IOError:
pass
for data, context in sigwalk(repo):
node, version, sig = data
if node == hexrev:
k = getkeys(ui, repo, mygpg, data, context)
if k:
keys.extend(k)
if not keys:
ui.write("%s not signed\n" % hgnode.short(rev))
ui.write(_("No valid signature for %s\n") % hgnode.short(rev))
return
valid = []
# warn for expired key and/or sigs
for k, fn, ln in keys:
prefix = "%s:%d" % (fn, ln)
for key in k:
if key[0] == "BADSIG":
ui.write("%s Bad signature from \"%s\"\n" % (prefix, key[2]))
continue
if key[0] == "EXPSIG":
ui.write("%s Note: Signature has expired"
" (signed by: \"%s\")\n" % (prefix, key[2]))
elif key[0] == "EXPKEYSIG":
ui.write("%s Note: This key has expired"
" (signed by: \"%s\")\n" % (prefix, key[2]))
valid.append((key[1], key[2], key[3]))
# print summary
ui.write("%s is signed by:\n" % hgnode.short(rev))
for keyid, user, fingerprint in valid:
role = getrole(ui, fingerprint)
ui.write(" %s (%s)\n" % (user, role))
for key in keys:
ui.write(" %s\n" % keystr(ui, key))
def getrole(ui, fingerprint):
return ui.config("gpg", fingerprint, "no role defined")
def keystr(ui, key):
"""associate a string to a key (username, comment)"""
keyid, user, fingerprint = key
comment = ui.config("gpg", fingerprint, None)
if comment:
return "%s (%s)" % (user, comment)
else:
return user
def sign(ui, repo, *revs, **opts):
"""add a signature for the current tip or a given revision"""
@ -150,7 +211,7 @@ def sign(ui, repo, *revs, **opts):
data = node2txt(repo, n, sigver)
sig = mygpg.sign(data)
if not sig:
raise util.Abort("Error while signing")
raise util.Abort(_("Error while signing"))
sig = binascii.b2a_base64(sig)
sig = sig.replace("\n", "")
sigmessage += "%s %s %s\n" % (hexnode, sigver, sig)
@ -162,9 +223,9 @@ def sign(ui, repo, *revs, **opts):
for x in repo.changes():
if ".hgsigs" in x and not opts["force"]:
raise util.Abort("working copy of .hgsigs is changed "
"(please commit .hgsigs manually"
"or use --force)")
raise util.Abort(_("working copy of .hgsigs is changed "
"(please commit .hgsigs manually "
"or use --force)"))
repo.wfile(".hgsigs", "ab").write(sigmessage)
@ -176,7 +237,8 @@ def sign(ui, repo, *revs, **opts):
message = opts['message']
if not message:
message = "\n".join(["Added signature for changeset %s" % hgnode.hex(n)
message = "\n".join([_("Added signature for changeset %s")
% hgnode.hex(n)
for n in nodes])
try:
repo.commit([".hgsigs"], message, opts['user'], opts['date'])
@ -188,19 +250,20 @@ def node2txt(repo, node, ver):
if ver == "0":
return "%s\n" % hgnode.hex(node)
else:
util.Abort("unknown signature version")
raise util.Abort(_("unknown signature version"))
cmdtable = {
"sign":
(sign,
[('l', 'local', None, "make the signature local"),
('f', 'force', None, "sign even if the sigfile is modified"),
('', 'no-commit', None, "do not commit the sigfile after signing"),
('m', 'message', "", "commit message"),
('d', 'date', "", "date code"),
('u', 'user', "", "user"),
('k', 'key', "", "the key id to sign with")],
"hg sign [OPTION]... REVISIONS"),
"sigcheck": (check, [], 'hg sigcheck REVISION')
[('l', 'local', None, _("make the signature local")),
('f', 'force', None, _("sign even if the sigfile is modified")),
('', 'no-commit', None, _("do not commit the sigfile after signing")),
('m', 'message', "", _("commit message")),
('d', 'date', "", _("date code")),
('u', 'user', "", _("user")),
('k', 'key', "", _("the key id to sign with"))],
_("hg sign [OPTION]... [REVISION]...")),
"sigcheck": (check, [], _('hg sigcheck REVISION')),
"sigs": (sigs, [], _('hg sigs')),
}

View File

@ -1,7 +1,5 @@
#!/usr/bin/python
#
# Interactive script for sending a collection of Mercurial changesets
# as a series of patch emails.
# Command for sending a collection of Mercurial changesets as a series
# of patch emails.
#
# The series is started off with a "[PATCH 0 of N]" introduction,
# which describes the series as a whole.
@ -50,9 +48,9 @@
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from mercurial import commands
from mercurial import fancyopts
from mercurial import hg
from mercurial import ui
from mercurial.i18n import gettext as _
import os
import popen2
import smtplib
@ -89,6 +87,17 @@ def diffstat(patch):
except: pass
def patchbomb(ui, repo, *revs, **opts):
'''send changesets as a series of patch emails
The series starts with a "[PATCH 0 of N]" introduction, which
describes the series as a whole.
Each patch email has a Subject line of "[PATCH M of N] ...", using
the first line of the changeset description as the subject text.
The message contains two or three body parts. First, the rest of
the changeset description. Next, (optionally) if the diffstat
program is installed, the result of running diffstat on the patch.
Finally, the patch itself, as generated by "hg export".'''
def prompt(prompt, default = None, rest = ': ', empty_ok = False):
if default: prompt += ' [%s]' % default
prompt += rest
@ -97,7 +106,7 @@ def patchbomb(ui, repo, *revs, **opts):
if r: return r
if default is not None: return default
if empty_ok: return r
ui.warn('Please enter a valid value.\n')
ui.warn(_('Please enter a valid value.\n'))
def confirm(s):
if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
@ -109,7 +118,7 @@ def patchbomb(ui, repo, *revs, **opts):
if summary:
ui.write(summary, '\n')
ui.write(s, '\n')
confirm('Does the diffstat above look okay')
confirm(_('Does the diffstat above look okay'))
return s
def makepatch(patch, idx, total):
@ -162,20 +171,20 @@ def patchbomb(ui, repo, *revs, **opts):
self.container.append(''.join(self.lines).split('\n'))
self.lines = []
commands.export(ui, repo, *args, **{'output': exportee(patches),
commands.export(ui, repo, *revs, **{'output': exportee(patches),
'switch_parent': False,
'text': None})
jumbo = []
msgs = []
ui.write('This patch series consists of %d patches.\n\n' % len(patches))
ui.write(_('This patch series consists of %d patches.\n\n') % len(patches))
for p, i in zip(patches, range(len(patches))):
jumbo.extend(p)
msgs.append(makepatch(p, i + 1, len(patches)))
ui.write('\nWrite the introductory message for the patch series.\n\n')
ui.write(_('\nWrite the introductory message for the patch series.\n\n'))
sender = (opts['from'] or ui.config('patchbomb', 'from') or
prompt('From', ui.username()))
@ -193,7 +202,7 @@ def patchbomb(ui, repo, *revs, **opts):
to = getaddrs('to', 'To')
cc = getaddrs('cc', 'Cc', '')
ui.write('Finish with ^D or a dot on a line by itself.\n\n')
ui.write(_('Finish with ^D or a dot on a line by itself.\n\n'))
body = []
@ -208,7 +217,7 @@ def patchbomb(ui, repo, *revs, **opts):
ui.write('\n')
if opts['diffstat']:
d = cdiffstat('Final summary:\n', jumbo)
d = cdiffstat(_('Final summary:\n'), jumbo)
if d: msg.attach(MIMEText(d))
msgs.insert(0, msg)
@ -252,25 +261,15 @@ def patchbomb(ui, repo, *revs, **opts):
if not opts['test']:
s.close()
if __name__ == '__main__':
optspec = [('c', 'cc', [], 'email addresses of copy recipients'),
('d', 'diffstat', None, 'add diffstat output to messages'),
('f', 'from', '', 'email address of sender'),
('', 'plain', None, 'omit hg patch header'),
('n', 'test', None, 'print messages that would be sent'),
('s', 'subject', '', 'subject of introductory message'),
('t', 'to', [], 'email addresses of recipients')]
options = {}
try:
args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts + optspec,
options)
except fancyopts.getopt.GetoptError, inst:
u = ui.ui()
u.warn('error: %s' % inst)
sys.exit(1)
u = ui.ui(options["verbose"], options["debug"], options["quiet"],
not options["noninteractive"])
repo = hg.repository(ui = u)
patchbomb(u, repo, *args, **options)
cmdtable = {
'email':
(patchbomb,
[('c', 'cc', [], 'email addresses of copy recipients'),
('d', 'diffstat', None, 'add diffstat output to messages'),
('f', 'from', '', 'email address of sender'),
('', 'plain', None, 'omit hg patch header'),
('n', 'test', None, 'print messages that would be sent'),
('s', 'subject', '', 'subject of introductory message'),
('t', 'to', [], 'email addresses of recipients')],
"hg email [OPTION]... [REV]...")
}

View File

@ -1399,6 +1399,13 @@ class localrepository(object):
modified, added, removed, deleted, unknown = self.changes()
# 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)
if allow and linear_path:
raise util.Abort(_("there is nothing to merge, "
"just use 'hg update'"))
if allow and not forcemerge:
if modified or added or removed:
raise util.Abort(_("outstanding uncommited changes"))
@ -1411,10 +1418,6 @@ class localrepository(object):
raise util.Abort(_("'%s' already exists in the working"
" dir and differs from remote") % f)
# 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"))

View File

@ -24,11 +24,34 @@ hg commit -m "2" -d "0 0"
cd ../r2
hg -q pull ../r1
hg status
hg parents
hg --debug up
hg parents
hg --debug up 0
hg parents
hg --debug up -m || echo failed
hg --debug up -f -m
hg parents
hg --debug up
hg parents
hg -v history
hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
-e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/"
# create a second head
cd ../r1
hg up 0
echo b2 > b
echo a3 > a
hg addremove
hg commit -m "3" -d "0 0"
cd ../r2
hg -q pull ../r1
hg status
hg parents
hg --debug up || echo failed
hg --debug up -m || echo failed
hg --debug up -f -m
hg parents
hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
-e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/"

View File

@ -7,6 +7,11 @@ diff -r c19d34741b0a a
+abc
adding b
M a
changeset: 0:c19d34741b0a
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 1
resolving manifests
force None allow None moddirstate True linear True
ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
@ -16,11 +21,38 @@ getting b
merging a
resolving a
file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
abort: outstanding uncommited changes
failed
changeset: 1:1e71731e6fbb
tag: tip
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 2
resolving manifests
force None allow 1 moddirstate True linear True
ancestor 1165e8bd193e local 1165e8bd193e remote 1165e8bd193e
force None allow None moddirstate True linear True
ancestor a0c8bcbbb45c local 1165e8bd193e remote a0c8bcbbb45c
remote deleted b
removing b
changeset: 0:c19d34741b0a
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 1
abort: there is nothing to merge, just use 'hg update'
failed
changeset: 0:c19d34741b0a
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 1
resolving manifests
force None allow None moddirstate True linear True
ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
a versions differ, resolve
remote created b
getting b
merging a
resolving a
file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
changeset: 1:1e71731e6fbb
tag: tip
user: test
@ -44,6 +76,55 @@ description:
1
diff -r 1e71731e6fbb a
--- a/a
+++ b/a
@@ -1,1 +1,1 @@ a2
-a2
+abc
adding b
M a
changeset: 1:1e71731e6fbb
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 2
resolving manifests
force None allow None moddirstate True linear False
ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
a versions differ, resolve
b versions differ, resolve
this update spans a branch affecting the following files:
a (resolve)
b (resolve)
aborting update spanning branches!
(use update -m to merge across branches or -C to lose changes)
failed
abort: outstanding uncommited changes
failed
resolving manifests
force None allow 1 moddirstate True linear False
ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
a versions differ, resolve
b versions differ, resolve
merging a
resolving a
file a: my d730145abbf9 other 13e0d5f949fa ancestor b789fdd96dc2
merging b
resolving b
file b: my 1e88685f5dde other 61de8c7723ca ancestor 000000000000
changeset: 1:1e71731e6fbb
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 2
changeset: 2:83c51d0caff4
tag: tip
parent: 0:c19d34741b0a
user: test
date: Thu Jan 1 00:00:00 1970 +0000
summary: 3
diff -r 1e71731e6fbb a
--- a/a
+++ b/a