mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
merge.
This commit is contained in:
commit
00af865078
@ -216,6 +216,6 @@ http://selenic.com/mailman/listinfo/mercurial[Mailing list]
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2005 Matt Mackall.
|
||||
Copyright \(C) 2005, 2006 Matt Mackall.
|
||||
Free use of this software is granted under the terms of the GNU General
|
||||
Public License (GPL).
|
||||
|
@ -30,6 +30,6 @@ hg(1) - the command line interface to Mercurial SCM
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2005 Matt Mackall.
|
||||
Copyright \(C) 2005, 2006 Matt Mackall.
|
||||
Free use of this software is granted under the terms of the GNU General
|
||||
Public License (GPL).
|
||||
|
@ -862,6 +862,6 @@ http://selenic.com/mailman/listinfo/mercurial[メーリングリスト]
|
||||
|
||||
著作権情報
|
||||
-----
|
||||
Copyright (C) 2005 Matt Mackall.
|
||||
Copyright (C) 2005, 2006 Matt Mackall.
|
||||
このソフトウェアの自由な使用は GNU 一般公有使用許諾 (GPL) のもとで
|
||||
認められます。
|
||||
|
@ -32,6 +32,6 @@ hg(1) - Mercurial システムへのコマンドラインインターフェイ
|
||||
|
||||
著作権情報
|
||||
----
|
||||
Copyright (C) 2005 Matt Mackall.
|
||||
Copyright (C) 2005, 2006 Matt Mackall.
|
||||
このソフトウェアの自由な使用は GNU 一般公有使用許諾 (GPL) のもとで
|
||||
認められます。
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Minimal support for git commands on an hg repository
|
||||
#
|
||||
# Copyright 2005 Chris Mason <mason@suse.com>
|
||||
# Copyright 2005, 2006 Chris Mason <mason@suse.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
15
hgext/mq.py
15
hgext/mq.py
@ -1,7 +1,6 @@
|
||||
|
||||
# queue.py - patch queues for mercurial
|
||||
#
|
||||
# Copyright 2005 Chris Mason <mason@suse.com>
|
||||
# Copyright 2005, 2006 Chris Mason <mason@suse.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
@ -31,9 +30,9 @@ refresh contents of top applied patch qrefresh
|
||||
'''
|
||||
|
||||
from mercurial.demandload import *
|
||||
demandload(globals(), "os sys re struct traceback errno bz2")
|
||||
from mercurial.i18n import gettext as _
|
||||
from mercurial import ui, hg, revlog, commands, util
|
||||
demandload(globals(), "os sys re struct traceback errno bz2")
|
||||
demandload(globals(), "mercurial:commands,hg,revlog,ui,util")
|
||||
|
||||
commands.norepo += " qclone qversion"
|
||||
|
||||
@ -561,7 +560,7 @@ class queue:
|
||||
r = self.qrepo()
|
||||
if r: r.add([patch])
|
||||
if commitfiles:
|
||||
self.refresh(repo, msg=None, short=True)
|
||||
self.refresh(repo, short=True)
|
||||
|
||||
def strip(self, repo, rev, update=True, backup="all", wlock=None):
|
||||
def limitheads(chlog, stop):
|
||||
@ -888,7 +887,6 @@ class queue:
|
||||
top = self.check_toppatch(repo)
|
||||
qp = self.qparents(repo, rev)
|
||||
changes = repo.changelog.read(qp)
|
||||
mf1 = repo.manifest.readflags(changes[0])
|
||||
mmap = repo.manifest.read(changes[0])
|
||||
(c, a, r, d, u) = repo.changes(qp, top)
|
||||
if d:
|
||||
@ -897,7 +895,7 @@ class queue:
|
||||
getfile(f, mmap[f])
|
||||
for f in r:
|
||||
getfile(f, mmap[f])
|
||||
util.set_exec(repo.wjoin(f), mf1[f])
|
||||
util.set_exec(repo.wjoin(f), mmap.execf[f])
|
||||
repo.dirstate.update(c + r, 'n')
|
||||
for f in a:
|
||||
try: os.unlink(repo.wjoin(f))
|
||||
@ -922,7 +920,7 @@ class queue:
|
||||
qp = self.qparents(repo, top)
|
||||
commands.dodiff(sys.stdout, self.ui, repo, qp, None, files)
|
||||
|
||||
def refresh(self, repo, msg=None, short=False):
|
||||
def refresh(self, repo, msg='', short=False):
|
||||
if len(self.applied) == 0:
|
||||
self.ui.write("No patches applied\n")
|
||||
return
|
||||
@ -1988,4 +1986,3 @@ cmdtable = {
|
||||
"qtop": (top, [], 'hg qtop'),
|
||||
"qunapplied": (unapplied, [], 'hg qunapplied [PATCH]'),
|
||||
}
|
||||
|
||||
|
@ -163,12 +163,12 @@ def archive(repo, dest, node, kind, decode=True, matchfn=None,
|
||||
change = repo.changelog.read(node)
|
||||
mn = change[0]
|
||||
archiver = archivers[kind](dest, prefix, mtime or change[2][0])
|
||||
mf = repo.manifest.read(mn).items()
|
||||
mff = repo.manifest.readflags(mn)
|
||||
mf.sort()
|
||||
m = repo.manifest.read(mn)
|
||||
items = m.items()
|
||||
items.sort()
|
||||
write('.hg_archival.txt', 0644,
|
||||
'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node)))
|
||||
for filename, filenode in mf:
|
||||
write(filename, mff[filename] and 0755 or 0644,
|
||||
for filename, filenode in items:
|
||||
write(filename, m.execf(filename) and 0755 or 0644,
|
||||
repo.file(filename).read(filenode))
|
||||
archiver.done()
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
bdiff.c - efficient binary diff extension for Mercurial
|
||||
|
||||
Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# changelog.py - changelog class for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# commands.py - command processing for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
@ -10,9 +10,9 @@ from node import *
|
||||
from i18n import gettext as _
|
||||
demandload(globals(), "os re sys signal shutil imp urllib pdb")
|
||||
demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo")
|
||||
demandload(globals(), "fnmatch mdiff difflib random signal tempfile time")
|
||||
demandload(globals(), "fnmatch mdiff difflib patch random signal tempfile time")
|
||||
demandload(globals(), "traceback errno socket version struct atexit sets bz2")
|
||||
demandload(globals(), "archival cStringIO changegroup email.Parser")
|
||||
demandload(globals(), "archival cStringIO changegroup")
|
||||
demandload(globals(), "hgweb.server sshserver")
|
||||
|
||||
class UnknownCommand(Exception):
|
||||
@ -633,7 +633,7 @@ def show_version(ui):
|
||||
ui.write(_("Mercurial Distributed SCM (version %s)\n")
|
||||
% version.get_version())
|
||||
ui.status(_(
|
||||
"\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
|
||||
"\nCopyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>\n"
|
||||
"This is free software; see the source for copying conditions. "
|
||||
"There is NO\nwarranty; "
|
||||
"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
|
||||
@ -1333,9 +1333,9 @@ def debugrebuildstate(ui, repo, rev=None):
|
||||
rev = repo.lookup(rev)
|
||||
change = repo.changelog.read(rev)
|
||||
n = change[0]
|
||||
files = repo.manifest.readflags(n)
|
||||
files = repo.manifest.read(n)
|
||||
wlock = repo.wlock()
|
||||
repo.dirstate.rebuild(rev, files.iteritems())
|
||||
repo.dirstate.rebuild(rev, files)
|
||||
|
||||
def debugcheckstate(ui, repo):
|
||||
"""validate the correctness of the current dirstate"""
|
||||
@ -1843,84 +1843,23 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
d = opts["base"]
|
||||
strip = opts["strip"]
|
||||
|
||||
mailre = re.compile(r'(?:From |[\w-]+:)')
|
||||
|
||||
# attempt to detect the start of a patch
|
||||
# (this heuristic is borrowed from quilt)
|
||||
diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
|
||||
'retrieving revision [0-9]+(\.[0-9]+)*$|' +
|
||||
'(---|\*\*\*)[ \t])', re.MULTILINE)
|
||||
|
||||
wlock = repo.wlock()
|
||||
lock = repo.lock()
|
||||
|
||||
for patch in patches:
|
||||
pf = os.path.join(d, patch)
|
||||
for p in patches:
|
||||
pf = os.path.join(d, p)
|
||||
|
||||
message = None
|
||||
user = None
|
||||
date = None
|
||||
hgpatch = False
|
||||
|
||||
p = email.Parser.Parser()
|
||||
if pf == '-':
|
||||
msg = p.parse(sys.stdin)
|
||||
ui.status(_("applying patch from stdin\n"))
|
||||
tmpname, message, user, date = patch.extract(ui, sys.stdin)
|
||||
else:
|
||||
msg = p.parse(file(pf))
|
||||
ui.status(_("applying %s\n") % patch)
|
||||
ui.status(_("applying %s\n") % p)
|
||||
tmpname, message, user, date = patch.extract(ui, file(pf))
|
||||
|
||||
if tmpname is None:
|
||||
raise util.Abort(_('no diffs found'))
|
||||
|
||||
fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
|
||||
tmpfp = os.fdopen(fd, 'w')
|
||||
try:
|
||||
message = msg['Subject']
|
||||
if message:
|
||||
message = message.replace('\n\t', ' ')
|
||||
ui.debug('Subject: %s\n' % message)
|
||||
user = msg['From']
|
||||
if user:
|
||||
ui.debug('From: %s\n' % user)
|
||||
diffs_seen = 0
|
||||
ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
|
||||
for part in msg.walk():
|
||||
content_type = part.get_content_type()
|
||||
ui.debug('Content-Type: %s\n' % content_type)
|
||||
if content_type not in ok_types:
|
||||
continue
|
||||
payload = part.get_payload(decode=True)
|
||||
m = diffre.search(payload)
|
||||
if m:
|
||||
ui.debug(_('found patch at byte %d\n') % m.start(0))
|
||||
diffs_seen += 1
|
||||
hgpatch = False
|
||||
fp = cStringIO.StringIO()
|
||||
if message:
|
||||
fp.write(message)
|
||||
fp.write('\n')
|
||||
for line in payload[:m.start(0)].splitlines():
|
||||
if line.startswith('# HG changeset patch'):
|
||||
ui.debug(_('patch generated by hg export\n'))
|
||||
hgpatch = True
|
||||
# drop earlier commit message content
|
||||
fp.seek(0)
|
||||
fp.truncate()
|
||||
elif hgpatch:
|
||||
if line.startswith('# User '):
|
||||
user = line[7:]
|
||||
ui.debug('From: %s\n' % user)
|
||||
elif line.startswith("# Date "):
|
||||
date = line[7:]
|
||||
if not line.startswith('# '):
|
||||
fp.write(line)
|
||||
fp.write('\n')
|
||||
message = fp.getvalue()
|
||||
if tmpfp:
|
||||
tmpfp.write(payload)
|
||||
if not payload.endswith('\n'):
|
||||
tmpfp.write('\n')
|
||||
elif not diffs_seen and message and content_type == 'text/plain':
|
||||
message += '\n' + payload
|
||||
|
||||
if opts['message']:
|
||||
# pickup the cmdline msg
|
||||
message = opts['message']
|
||||
@ -1932,17 +1871,45 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
message = None
|
||||
ui.debug(_('message:\n%s\n') % message)
|
||||
|
||||
tmpfp.close()
|
||||
if not diffs_seen:
|
||||
raise util.Abort(_('no diffs found'))
|
||||
|
||||
files = util.patch(strip, tmpname, ui, cwd=repo.root)
|
||||
files = patch.patch(strip, tmpname, ui, cwd=repo.root)
|
||||
removes = []
|
||||
if len(files) > 0:
|
||||
cfiles = files
|
||||
cfiles = files.keys()
|
||||
copies = []
|
||||
copts = {'after': False, 'force': False}
|
||||
cwd = repo.getcwd()
|
||||
if cwd:
|
||||
cfiles = [util.pathto(cwd, f) for f in files]
|
||||
cfiles = [util.pathto(cwd, f) for f in files.keys()]
|
||||
for f in files:
|
||||
ctype, gp = files[f]
|
||||
if ctype == 'RENAME':
|
||||
copies.append((gp.oldpath, gp.path, gp.copymod))
|
||||
removes.append(gp.oldpath)
|
||||
elif ctype == 'COPY':
|
||||
copies.append((gp.oldpath, gp.path, gp.copymod))
|
||||
elif ctype == 'DELETE':
|
||||
removes.append(gp.path)
|
||||
for src, dst, after in copies:
|
||||
absdst = os.path.join(repo.root, dst)
|
||||
if not after and os.path.exists(absdst):
|
||||
raise util.Abort(_('patch creates existing file %s') % dst)
|
||||
if cwd:
|
||||
src, dst = [util.pathto(cwd, f) for f in (src, dst)]
|
||||
copts['after'] = after
|
||||
errs, copied = docopy(ui, repo, (src, dst), copts, wlock=wlock)
|
||||
if errs:
|
||||
raise util.Abort(errs)
|
||||
if removes:
|
||||
repo.remove(removes, True, wlock=wlock)
|
||||
for f in files:
|
||||
ctype, gp = files[f]
|
||||
if gp and gp.mode:
|
||||
x = gp.mode & 0100 != 0
|
||||
dst = os.path.join(repo.root, gp.path)
|
||||
util.set_exec(dst, x)
|
||||
addremove_lock(ui, repo, cfiles, {}, wlock=wlock)
|
||||
files = files.keys()
|
||||
files.extend([r for r in removes if r not in files])
|
||||
repo.commit(files, message, user, date, wlock=wlock, lock=lock)
|
||||
finally:
|
||||
os.unlink(tmpname)
|
||||
@ -2178,12 +2145,12 @@ def manifest(ui, repo, rev=None):
|
||||
else:
|
||||
n = repo.manifest.tip()
|
||||
m = repo.manifest.read(n)
|
||||
mf = repo.manifest.readflags(n)
|
||||
files = m.keys()
|
||||
files.sort()
|
||||
|
||||
for f in files:
|
||||
ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
|
||||
ui.write("%40s %3s %s\n" % (hex(m[f]),
|
||||
m.execf(f) and "755" or "644", f))
|
||||
|
||||
def merge(ui, repo, node=None, force=None, branch=None):
|
||||
"""Merge working directory with another revision
|
||||
|
@ -1,6 +1,6 @@
|
||||
# context.py - changeset and file context objects for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2006 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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
dirstate.py - working directory tracking for mercurial
|
||||
|
||||
Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2005, 2006 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.
|
||||
@ -238,8 +238,8 @@ class dirstate(object):
|
||||
self.clear()
|
||||
umask = os.umask(0)
|
||||
os.umask(umask)
|
||||
for f, mode in files:
|
||||
if mode:
|
||||
for f in files:
|
||||
if files.execf(f):
|
||||
self.map[f] = ('n', ~umask, -1, 0)
|
||||
else:
|
||||
self.map[f] = ('n', ~umask & 0666, -1, 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# filelog.py - file history class for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,7 @@
|
||||
# hg.py - repository classes for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
|
||||
#
|
||||
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# hgweb/hgweb_mod.py - Web interface for a repository.
|
||||
#
|
||||
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
@ -398,7 +398,7 @@ class hgweb(object):
|
||||
parent=self.siblings(fl.parents(n), fl.rev, file=f),
|
||||
child=self.siblings(fl.children(n), fl.rev, file=f),
|
||||
rename=self.renamelink(fl, n),
|
||||
permissions=self.repo.manifest.readflags(mfn)[f])
|
||||
permissions=self.repo.manifest.read(mfn).execf(f))
|
||||
|
||||
def fileannotate(self, f, node):
|
||||
bcache = {}
|
||||
@ -452,7 +452,7 @@ class hgweb(object):
|
||||
rename=self.renamelink(fl, n),
|
||||
parent=self.siblings(fl.parents(n), fl.rev, file=f),
|
||||
child=self.siblings(fl.children(n), fl.rev, file=f),
|
||||
permissions=self.repo.manifest.readflags(mfn)[f])
|
||||
permissions=self.repo.manifest.read(mfn).execf(f))
|
||||
|
||||
def manifest(self, mnode, path):
|
||||
man = self.repo.manifest
|
||||
@ -462,7 +462,6 @@ class hgweb(object):
|
||||
rev = man.rev(mn)
|
||||
changerev = man.linkrev(mn)
|
||||
node = self.repo.changelog.node(changerev)
|
||||
mff = man.readflags(mn)
|
||||
|
||||
files = {}
|
||||
|
||||
@ -496,7 +495,7 @@ class hgweb(object):
|
||||
"filenode": hex(fnode),
|
||||
"parity": self.stripes(parity),
|
||||
"basename": f,
|
||||
"permissions": mff[full]}
|
||||
"permissions": mf.execf(full)}
|
||||
parity += 1
|
||||
|
||||
def dirlist(**map):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
|
||||
#
|
||||
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# hgweb/request.py - An http request from either CGI or the standalone server.
|
||||
#
|
||||
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# hgweb/server.py - The standalone hg web server.
|
||||
#
|
||||
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# httprangereader.py - just what it says
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,7 @@
|
||||
# httprepo.py - HTTP repository proxy classes for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
i18n.py - internationalization support for mercurial
|
||||
|
||||
Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# localrepo.py - read/write repository class for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
@ -470,8 +470,7 @@ class localrepository(repo.repository):
|
||||
p2 = p2 or self.dirstate.parents()[1] or nullid
|
||||
c1 = self.changelog.read(p1)
|
||||
c2 = self.changelog.read(p2)
|
||||
m1 = self.manifest.read(c1[0])
|
||||
mf1 = self.manifest.readflags(c1[0])
|
||||
m1 = self.manifest.read(c1[0]).copy()
|
||||
m2 = self.manifest.read(c2[0])
|
||||
changed = []
|
||||
|
||||
@ -484,36 +483,32 @@ class localrepository(repo.repository):
|
||||
wlock = self.wlock()
|
||||
l = self.lock()
|
||||
tr = self.transaction()
|
||||
mm = m1.copy()
|
||||
mfm = mf1.copy()
|
||||
linkrev = self.changelog.count()
|
||||
for f in files:
|
||||
try:
|
||||
t = self.wread(f)
|
||||
tm = util.is_exec(self.wjoin(f), mfm.get(f, False))
|
||||
m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f)))
|
||||
r = self.file(f)
|
||||
mfm[f] = tm
|
||||
|
||||
(entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2)
|
||||
if entry:
|
||||
mm[f] = entry
|
||||
m1[f] = entry
|
||||
continue
|
||||
|
||||
mm[f] = r.add(t, {}, tr, linkrev, fp1, fp2)
|
||||
m1[f] = r.add(t, {}, tr, linkrev, fp1, fp2)
|
||||
changed.append(f)
|
||||
if update_dirstate:
|
||||
self.dirstate.update([f], "n")
|
||||
except IOError:
|
||||
try:
|
||||
del mm[f]
|
||||
del mfm[f]
|
||||
del m1[f]
|
||||
if update_dirstate:
|
||||
self.dirstate.forget([f])
|
||||
except:
|
||||
# deleted from p2?
|
||||
pass
|
||||
|
||||
mnode = self.manifest.add(mm, mfm, tr, linkrev, c1[0], c2[0])
|
||||
mnode = self.manifest.add(m1, tr, linkrev, c1[0], c2[0])
|
||||
user = user or self.ui.username()
|
||||
n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date)
|
||||
tr.close()
|
||||
@ -544,8 +539,7 @@ class localrepository(repo.repository):
|
||||
p1, p2 = self.dirstate.parents()
|
||||
c1 = self.changelog.read(p1)
|
||||
c2 = self.changelog.read(p2)
|
||||
m1 = self.manifest.read(c1[0])
|
||||
mf1 = self.manifest.readflags(c1[0])
|
||||
m1 = self.manifest.read(c1[0]).copy()
|
||||
m2 = self.manifest.read(c2[0])
|
||||
|
||||
if not commit and not remove and not force and p2 == nullid:
|
||||
@ -571,7 +565,7 @@ class localrepository(repo.repository):
|
||||
for f in commit:
|
||||
self.ui.note(f + "\n")
|
||||
try:
|
||||
mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False))
|
||||
m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f)))
|
||||
t = self.wread(f)
|
||||
except IOError:
|
||||
self.ui.warn(_("trouble committing %s!\n") % f)
|
||||
@ -598,12 +592,11 @@ class localrepository(repo.repository):
|
||||
changed.append(f)
|
||||
|
||||
# update manifest
|
||||
m1 = m1.copy()
|
||||
m1.update(new)
|
||||
for f in remove:
|
||||
if f in m1:
|
||||
del m1[f]
|
||||
mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0],
|
||||
mn = self.manifest.add(m1, tr, linkrev, c1[0], c2[0],
|
||||
(new, remove))
|
||||
|
||||
# add changeset
|
||||
@ -816,7 +809,6 @@ class localrepository(repo.repository):
|
||||
def undelete(self, list, wlock=None):
|
||||
p = self.dirstate.parents()[0]
|
||||
mn = self.changelog.read(p)[0]
|
||||
mf = self.manifest.readflags(mn)
|
||||
m = self.manifest.read(mn)
|
||||
if not wlock:
|
||||
wlock = self.wlock()
|
||||
@ -826,7 +818,7 @@ class localrepository(repo.repository):
|
||||
else:
|
||||
t = self.file(f).read(m[f])
|
||||
self.wwrite(f, t)
|
||||
util.set_exec(self.wjoin(f), mf[f])
|
||||
util.set_exec(self.wjoin(f), m.execf(f))
|
||||
self.dirstate.update([f], "n")
|
||||
|
||||
def copy(self, source, dest, wlock=None):
|
||||
|
@ -1,6 +1,6 @@
|
||||
# lock.py - simple locking scheme for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# manifest.py - manifest revision class for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
@ -10,6 +10,31 @@ from i18n import gettext as _
|
||||
from demandload import *
|
||||
demandload(globals(), "array bisect struct")
|
||||
|
||||
class manifestdict(dict):
|
||||
def __init__(self, mapping=None, flags=None):
|
||||
if mapping is None: mapping = {}
|
||||
if flags is None: flags = {}
|
||||
dict.__init__(self, mapping)
|
||||
self._flags = flags
|
||||
def flags(self, f):
|
||||
return self._flags.get(f, "")
|
||||
def execf(self, f):
|
||||
"test for executable in manifest flags"
|
||||
return "x" in self.flags(f)
|
||||
def linkf(self, f):
|
||||
"test for symlink in manifest flags"
|
||||
return "l" in self.flags(f)
|
||||
def rawset(self, f, entry):
|
||||
self[f] = bin(entry[:40])
|
||||
fl = entry[40:-1]
|
||||
if fl: self._flags[f] = fl
|
||||
def set(self, f, execf=False, linkf=False):
|
||||
if linkf: self._flags[f] = "l"
|
||||
elif execf: self._flags[f] = "x"
|
||||
else: self._flags[f] = ""
|
||||
def copy(self):
|
||||
return manifestdict(dict.copy(self), dict.copy(self._flags))
|
||||
|
||||
class manifest(revlog):
|
||||
def __init__(self, opener, defversion=REVLOGV0):
|
||||
self.mapcache = None
|
||||
@ -18,26 +43,18 @@ class manifest(revlog):
|
||||
defversion)
|
||||
|
||||
def read(self, node):
|
||||
if node == nullid: return {} # don't upset local cache
|
||||
if node == nullid: return manifestdict() # don't upset local cache
|
||||
if self.mapcache and self.mapcache[0] == node:
|
||||
return self.mapcache[1]
|
||||
text = self.revision(node)
|
||||
map = {}
|
||||
flag = {}
|
||||
self.listcache = array.array('c', text)
|
||||
lines = text.splitlines(1)
|
||||
mapping = manifestdict()
|
||||
for l in lines:
|
||||
(f, n) = l.split('\0')
|
||||
map[f] = bin(n[:40])
|
||||
flag[f] = (n[40:-1] == "x")
|
||||
self.mapcache = (node, map, flag)
|
||||
return map
|
||||
|
||||
def readflags(self, node):
|
||||
if node == nullid: return {} # don't upset local cache
|
||||
if not self.mapcache or self.mapcache[0] != node:
|
||||
self.read(node)
|
||||
return self.mapcache[2]
|
||||
mapping.rawset(f, n)
|
||||
self.mapcache = (node, mapping)
|
||||
return mapping
|
||||
|
||||
def diff(self, a, b):
|
||||
return mdiff.textdiff(str(a), str(b))
|
||||
@ -86,7 +103,7 @@ class manifest(revlog):
|
||||
'''look up entry for a single file efficiently.
|
||||
return (node, flag) pair if found, (None, None) if not.'''
|
||||
if self.mapcache and node == self.mapcache[0]:
|
||||
return self.mapcache[1].get(f), self.mapcache[2].get(f)
|
||||
return self.mapcache[1].get(f), self.mapcache[1].flags(f)
|
||||
text = self.revision(node)
|
||||
start, end = self._search(text, f)
|
||||
if start == end:
|
||||
@ -95,7 +112,7 @@ class manifest(revlog):
|
||||
f, n = l.split('\0')
|
||||
return bin(n[:40]), n[40:-1] == 'x'
|
||||
|
||||
def add(self, map, flags, transaction, link, p1=None, p2=None,
|
||||
def add(self, map, transaction, link, p1=None, p2=None,
|
||||
changed=None):
|
||||
# apply the changes collected during the bisect loop to our addlist
|
||||
# return a delta suitable for addrevision
|
||||
@ -123,9 +140,7 @@ class manifest(revlog):
|
||||
|
||||
# if this is changed to support newlines in filenames,
|
||||
# be sure to check the templates/ dir again (especially *-raw.tmpl)
|
||||
text = ["%s\000%s%s\n" %
|
||||
(f, hex(map[f]), flags[f] and "x" or '')
|
||||
for f in files]
|
||||
text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) for f in files]
|
||||
self.listcache = array.array('c', "".join(text))
|
||||
cachedelta = None
|
||||
else:
|
||||
@ -151,8 +166,7 @@ class manifest(revlog):
|
||||
# bs will either be the index of the item or the insert point
|
||||
start, end = self._search(addbuf, f, start)
|
||||
if w[1] == 0:
|
||||
l = "%s\000%s%s\n" % (f, hex(map[f]),
|
||||
flags[f] and "x" or '')
|
||||
l = "%s\000%s%s\n" % (f, hex(map[f]), map.flags(f))
|
||||
else:
|
||||
l = ""
|
||||
if start == end and w[1] == 1:
|
||||
@ -183,6 +197,6 @@ class manifest(revlog):
|
||||
|
||||
n = self.addrevision(buffer(self.listcache), transaction, link, p1, \
|
||||
p2, cachedelta)
|
||||
self.mapcache = (n, map, flags)
|
||||
self.mapcache = (n, map)
|
||||
|
||||
return n
|
||||
|
@ -1,6 +1,6 @@
|
||||
# mdiff.py - diff and patch routines for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -84,11 +84,8 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
m2n = repo.changelog.read(p2)[0]
|
||||
man = repo.manifest.ancestor(m1n, m2n)
|
||||
m1 = repo.manifest.read(m1n)
|
||||
mf1 = repo.manifest.readflags(m1n)
|
||||
m2 = repo.manifest.read(m2n).copy()
|
||||
mf2 = repo.manifest.readflags(m2n)
|
||||
ma = repo.manifest.read(man)
|
||||
mfa = repo.manifest.readflags(man)
|
||||
|
||||
if not forcemerge and not overwrite:
|
||||
for f in unknown:
|
||||
@ -113,12 +110,11 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
|
||||
# construct a working dir manifest
|
||||
mw = m1.copy()
|
||||
mfw = mf1.copy()
|
||||
umap = dict.fromkeys(unknown)
|
||||
|
||||
for f in added + modified + unknown:
|
||||
mw[f] = ""
|
||||
mfw[f] = util.is_exec(repo.wjoin(f), mfw.get(f, False))
|
||||
mw.set(f, util.is_exec(repo.wjoin(f), mw.execf(f)))
|
||||
|
||||
for f in deleted + removed:
|
||||
if f in mw:
|
||||
@ -155,28 +151,28 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
repo.ui.debug(_(" %s versions differ, resolve\n") % f)
|
||||
# merge executable bits
|
||||
# "if we changed or they changed, change in merge"
|
||||
a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
|
||||
a, b, c = ma.execf(f), mw.execf(f), m2.execf(f)
|
||||
mode = ((a^b) | (a^c)) ^ a
|
||||
merge[f] = (m1.get(f, nullid), m2[f], mode)
|
||||
merge[f] = (mode, m1.get(f, nullid), m2[f])
|
||||
s = 1
|
||||
# are we clobbering?
|
||||
# is remote's version newer?
|
||||
# or are we going back in time?
|
||||
elif overwrite or m2[f] != a or (p2 == pa and mw[f] == m1[f]):
|
||||
repo.ui.debug(_(" remote %s is newer, get\n") % f)
|
||||
get[f] = m2[f]
|
||||
get[f] = (m2.execf(f), m2[f])
|
||||
s = 1
|
||||
elif f in umap or f in added:
|
||||
# this unknown file is the same as the checkout
|
||||
# we need to reset the dirstate if the file was added
|
||||
get[f] = m2[f]
|
||||
get[f] = (m2.execf(f), m2[f])
|
||||
|
||||
if not s and mfw[f] != mf2[f]:
|
||||
if not s and mw.execf(f) != m2.execf(f):
|
||||
if overwrite:
|
||||
repo.ui.debug(_(" updating permissions for %s\n") % f)
|
||||
util.set_exec(repo.wjoin(f), mf2[f])
|
||||
util.set_exec(repo.wjoin(f), m2.execf(f))
|
||||
else:
|
||||
a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
|
||||
a, b, c = ma.execf(f), mw.execf(f), m2.execf(f)
|
||||
mode = ((a^b) | (a^c)) ^ a
|
||||
if mode != b:
|
||||
repo.ui.debug(_(" updating permissions for %s\n")
|
||||
@ -221,14 +217,14 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
(_("remote changed %s which local deleted\n") % f) +
|
||||
_("(k)eep or (d)elete?"), _("[kd]"), _("k"))
|
||||
if r == _("k"):
|
||||
get[f] = n
|
||||
get[f] = (m2.execf(f), n)
|
||||
elif f not in ma:
|
||||
repo.ui.debug(_("remote created %s\n") % f)
|
||||
get[f] = n
|
||||
get[f] = (m2.execf(f), n)
|
||||
else:
|
||||
if overwrite or p2 == pa: # going backwards?
|
||||
repo.ui.debug(_("local deleted %s, recreating\n") % f)
|
||||
get[f] = n
|
||||
get[f] = (m2.execf(f), n)
|
||||
else:
|
||||
repo.ui.debug(_("local deleted %s\n") % f)
|
||||
|
||||
@ -236,7 +232,7 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
|
||||
if overwrite:
|
||||
for f in merge:
|
||||
get[f] = merge[f][1]
|
||||
get[f] = merge[f][:2]
|
||||
merge = {}
|
||||
|
||||
if linear_path or overwrite:
|
||||
@ -254,12 +250,13 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
files = get.keys()
|
||||
files.sort()
|
||||
for f in files:
|
||||
flag, node = get[f]
|
||||
if f[0] == "/":
|
||||
continue
|
||||
repo.ui.note(_("getting %s\n") % f)
|
||||
t = repo.file(f).read(get[f])
|
||||
t = repo.file(f).read(node)
|
||||
repo.wwrite(f, t)
|
||||
util.set_exec(repo.wjoin(f), mf2[f])
|
||||
util.set_exec(repo.wjoin(f), flag)
|
||||
if not partial:
|
||||
if branchmerge:
|
||||
repo.dirstate.update([f], 'n', st_mtime=-1)
|
||||
@ -272,7 +269,7 @@ def update(repo, node, branchmerge=False, force=False, partial=None,
|
||||
files.sort()
|
||||
for f in files:
|
||||
repo.ui.status(_("merging %s\n") % f)
|
||||
my, other, flag = merge[f]
|
||||
flag, my, other = merge[f]
|
||||
ret = merge3(repo, f, my, other, xp1, xp2)
|
||||
if ret:
|
||||
unresolved.append(f)
|
||||
|
@ -14,7 +14,7 @@
|
||||
allocation of intermediate Python objects. Working memory is about 2x
|
||||
the total number of hunks.
|
||||
|
||||
Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2005, 2006 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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
node.py - basic nodeid manipulation for mercurial
|
||||
|
||||
Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2005, 2006 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.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Used for the py2exe distutil.
|
||||
# This module must be the first mercurial module imported in setup.py
|
||||
#
|
||||
# Copyright 2005 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
|
||||
# Copyright 2005, 2006 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
251
mercurial/patch.py
Normal file
251
mercurial/patch.py
Normal file
@ -0,0 +1,251 @@
|
||||
# patch.py - patch file parsing routines
|
||||
#
|
||||
# Copyright 2006 Brendan Cully <brendan@kublai.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
from demandload import demandload
|
||||
from i18n import gettext as _
|
||||
demandload(globals(), "util")
|
||||
demandload(globals(), "cStringIO email.Parser os re shutil tempfile")
|
||||
|
||||
def extract(ui, fileobj):
|
||||
'''extract patch from data read from fileobj.
|
||||
|
||||
patch can be normal patch or contained in email message.
|
||||
|
||||
return tuple (filename, message, user, date). any item in returned
|
||||
tuple can be None. if filename is None, fileobj did not contain
|
||||
patch. caller must unlink filename when done.'''
|
||||
|
||||
# attempt to detect the start of a patch
|
||||
# (this heuristic is borrowed from quilt)
|
||||
diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
|
||||
'retrieving revision [0-9]+(\.[0-9]+)*$|' +
|
||||
'(---|\*\*\*)[ \t])', re.MULTILINE)
|
||||
|
||||
fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
|
||||
tmpfp = os.fdopen(fd, 'w')
|
||||
try:
|
||||
hgpatch = False
|
||||
|
||||
msg = email.Parser.Parser().parse(fileobj)
|
||||
|
||||
message = msg['Subject']
|
||||
user = msg['From']
|
||||
# should try to parse msg['Date']
|
||||
date = None
|
||||
|
||||
if message:
|
||||
message = message.replace('\n\t', ' ')
|
||||
ui.debug('Subject: %s\n' % message)
|
||||
if user:
|
||||
ui.debug('From: %s\n' % user)
|
||||
diffs_seen = 0
|
||||
ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
|
||||
|
||||
for part in msg.walk():
|
||||
content_type = part.get_content_type()
|
||||
ui.debug('Content-Type: %s\n' % content_type)
|
||||
if content_type not in ok_types:
|
||||
continue
|
||||
payload = part.get_payload(decode=True)
|
||||
m = diffre.search(payload)
|
||||
if m:
|
||||
ui.debug(_('found patch at byte %d\n') % m.start(0))
|
||||
diffs_seen += 1
|
||||
cfp = cStringIO.StringIO()
|
||||
if message:
|
||||
cfp.write(message)
|
||||
cfp.write('\n')
|
||||
for line in payload[:m.start(0)].splitlines():
|
||||
if line.startswith('# HG changeset patch'):
|
||||
ui.debug(_('patch generated by hg export\n'))
|
||||
hgpatch = True
|
||||
# drop earlier commit message content
|
||||
cfp.seek(0)
|
||||
cfp.truncate()
|
||||
elif hgpatch:
|
||||
if line.startswith('# User '):
|
||||
user = line[7:]
|
||||
ui.debug('From: %s\n' % user)
|
||||
elif line.startswith("# Date "):
|
||||
date = line[7:]
|
||||
if not line.startswith('# '):
|
||||
cfp.write(line)
|
||||
cfp.write('\n')
|
||||
message = cfp.getvalue()
|
||||
if tmpfp:
|
||||
tmpfp.write(payload)
|
||||
if not payload.endswith('\n'):
|
||||
tmpfp.write('\n')
|
||||
elif not diffs_seen and message and content_type == 'text/plain':
|
||||
message += '\n' + payload
|
||||
except:
|
||||
tmpfp.close()
|
||||
os.unlink(tmpname)
|
||||
raise
|
||||
|
||||
tmpfp.close()
|
||||
if not diffs_seen:
|
||||
os.unlink(tmpname)
|
||||
return None, message, user, date
|
||||
return tmpname, message, user, date
|
||||
|
||||
def readgitpatch(patchname):
|
||||
"""extract git-style metadata about patches from <patchname>"""
|
||||
class gitpatch:
|
||||
"op is one of ADD, DELETE, RENAME, MODIFY or COPY"
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.oldpath = None
|
||||
self.mode = None
|
||||
self.op = 'MODIFY'
|
||||
self.copymod = False
|
||||
self.lineno = 0
|
||||
|
||||
# Filter patch for git information
|
||||
gitre = re.compile('diff --git a/(.*) b/(.*)')
|
||||
pf = file(patchname)
|
||||
gp = None
|
||||
gitpatches = []
|
||||
# Can have a git patch with only metadata, causing patch to complain
|
||||
dopatch = False
|
||||
|
||||
lineno = 0
|
||||
for line in pf:
|
||||
lineno += 1
|
||||
if line.startswith('diff --git'):
|
||||
m = gitre.match(line)
|
||||
if m:
|
||||
if gp:
|
||||
gitpatches.append(gp)
|
||||
src, dst = m.group(1,2)
|
||||
gp = gitpatch(dst)
|
||||
gp.lineno = lineno
|
||||
elif gp:
|
||||
if line.startswith('--- '):
|
||||
if gp.op in ('COPY', 'RENAME'):
|
||||
gp.copymod = True
|
||||
dopatch = 'filter'
|
||||
gitpatches.append(gp)
|
||||
gp = None
|
||||
if not dopatch:
|
||||
dopatch = True
|
||||
continue
|
||||
if line.startswith('rename from '):
|
||||
gp.op = 'RENAME'
|
||||
gp.oldpath = line[12:].rstrip()
|
||||
elif line.startswith('rename to '):
|
||||
gp.path = line[10:].rstrip()
|
||||
elif line.startswith('copy from '):
|
||||
gp.op = 'COPY'
|
||||
gp.oldpath = line[10:].rstrip()
|
||||
elif line.startswith('copy to '):
|
||||
gp.path = line[8:].rstrip()
|
||||
elif line.startswith('deleted file'):
|
||||
gp.op = 'DELETE'
|
||||
elif line.startswith('new file mode '):
|
||||
gp.op = 'ADD'
|
||||
gp.mode = int(line.rstrip()[-3:], 8)
|
||||
elif line.startswith('new mode '):
|
||||
gp.mode = int(line.rstrip()[-3:], 8)
|
||||
if gp:
|
||||
gitpatches.append(gp)
|
||||
|
||||
if not gitpatches:
|
||||
dopatch = True
|
||||
|
||||
return (dopatch, gitpatches)
|
||||
|
||||
def dogitpatch(patchname, gitpatches):
|
||||
"""Preprocess git patch so that vanilla patch can handle it"""
|
||||
pf = file(patchname)
|
||||
pfline = 1
|
||||
|
||||
fd, patchname = tempfile.mkstemp(prefix='hg-patch-')
|
||||
tmpfp = os.fdopen(fd, 'w')
|
||||
|
||||
try:
|
||||
for i in range(len(gitpatches)):
|
||||
p = gitpatches[i]
|
||||
if not p.copymod:
|
||||
continue
|
||||
|
||||
if os.path.exists(p.path):
|
||||
raise util.Abort(_("cannot create %s: destination already exists") %
|
||||
p.path)
|
||||
|
||||
(src, dst) = [os.path.join(os.getcwd(), n)
|
||||
for n in (p.oldpath, p.path)]
|
||||
|
||||
targetdir = os.path.dirname(dst)
|
||||
if not os.path.isdir(targetdir):
|
||||
os.makedirs(targetdir)
|
||||
try:
|
||||
shutil.copyfile(src, dst)
|
||||
shutil.copymode(src, dst)
|
||||
except shutil.Error, inst:
|
||||
raise util.Abort(str(inst))
|
||||
|
||||
# rewrite patch hunk
|
||||
while pfline < p.lineno:
|
||||
tmpfp.write(pf.readline())
|
||||
pfline += 1
|
||||
tmpfp.write('diff --git a/%s b/%s\n' % (p.path, p.path))
|
||||
line = pf.readline()
|
||||
pfline += 1
|
||||
while not line.startswith('--- a/'):
|
||||
tmpfp.write(line)
|
||||
line = pf.readline()
|
||||
pfline += 1
|
||||
tmpfp.write('--- a/%s\n' % p.path)
|
||||
|
||||
line = pf.readline()
|
||||
while line:
|
||||
tmpfp.write(line)
|
||||
line = pf.readline()
|
||||
except:
|
||||
tmpfp.close()
|
||||
os.unlink(patchname)
|
||||
raise
|
||||
|
||||
tmpfp.close()
|
||||
return patchname
|
||||
|
||||
def patch(strip, patchname, ui, cwd=None):
|
||||
"""apply the patch <patchname> to the working directory.
|
||||
a list of patched files is returned"""
|
||||
|
||||
(dopatch, gitpatches) = readgitpatch(patchname)
|
||||
|
||||
files = {}
|
||||
if dopatch:
|
||||
if dopatch == 'filter':
|
||||
patchname = dogitpatch(patchname, gitpatches)
|
||||
patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch')
|
||||
args = []
|
||||
if cwd:
|
||||
args.append('-d %s' % util.shellquote(cwd))
|
||||
fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
|
||||
util.shellquote(patchname)))
|
||||
|
||||
if dopatch == 'filter':
|
||||
False and os.unlink(patchname)
|
||||
|
||||
for line in fp:
|
||||
line = line.rstrip()
|
||||
ui.status("%s\n" % line)
|
||||
if line.startswith('patching file '):
|
||||
pf = util.parse_patch_output(line)
|
||||
files.setdefault(pf, (None, None))
|
||||
code = fp.close()
|
||||
if code:
|
||||
raise util.Abort(_("patch command failed: %s") %
|
||||
util.explain_exit(code)[0])
|
||||
|
||||
for gp in gitpatches:
|
||||
files[gp.path] = (gp.op, gp)
|
||||
|
||||
return files
|
@ -1,6 +1,6 @@
|
||||
# remoterepo - remote repositort proxy classes for mercurial
|
||||
# remoterepo - remote repository proxy classes for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,7 @@
|
||||
# repo.py - repository base classes for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
@ -4,7 +4,7 @@ revlog.py - storage back-end for mercurial
|
||||
This provides efficient delta storage with O(1) retrieve and append
|
||||
and O(changes) merge between branches
|
||||
|
||||
Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# sshrepo.py - ssh repository proxy class for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,7 @@
|
||||
# sshserver.py - ssh protocol server support for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# This provides read-only repo access to repositories exported via static http
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -6,7 +6,7 @@
|
||||
# effectively log-structured, this should amount to simply truncating
|
||||
# anything that isn't referenced in the changelog.
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# ui.py - user interface bits for mercurial
|
||||
#
|
||||
# Copyright 2005 Matt Mackall <mpm@selenic.com>
|
||||
# Copyright 2005, 2006 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.
|
||||
|
@ -2,6 +2,8 @@
|
||||
util.py - Mercurial utility functions and platform specfic implementations
|
||||
|
||||
Copyright 2005 K. Thananchayan <thananck@yahoo.com>
|
||||
Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
|
||||
Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
@ -93,27 +95,6 @@ def find_in_path(name, path, default=None):
|
||||
return p_name
|
||||
return default
|
||||
|
||||
def patch(strip, patchname, ui, cwd=None):
|
||||
"""apply the patch <patchname> to the working directory.
|
||||
a list of patched files is returned"""
|
||||
patcher = find_in_path('gpatch', os.environ.get('PATH', ''), 'patch')
|
||||
args = []
|
||||
if cwd:
|
||||
args.append('-d %s' % shellquote(cwd))
|
||||
fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
|
||||
shellquote(patchname)))
|
||||
files = {}
|
||||
for line in fp:
|
||||
line = line.rstrip()
|
||||
ui.status("%s\n" % line)
|
||||
if line.startswith('patching file '):
|
||||
pf = parse_patch_output(line)
|
||||
files.setdefault(pf, 1)
|
||||
code = fp.close()
|
||||
if code:
|
||||
raise Abort(_("patch command failed: %s") % explain_exit(code)[0])
|
||||
return files.keys()
|
||||
|
||||
def binary(s):
|
||||
"""return true if a string is binary data using diff's heuristic"""
|
||||
if s and '\0' in s[:4096]:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2005 by Intevation GmbH
|
||||
# Copyright (C) 2005, 2006 by Intevation GmbH
|
||||
# Author(s):
|
||||
# Thomas Arendsen Hein <thomas@intevation.de>
|
||||
#
|
||||
|
122
tests/test-git-import
Executable file
122
tests/test-git-import
Executable file
@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
|
||||
hg init a
|
||||
cd a
|
||||
|
||||
echo % new file
|
||||
hg import -mnew - <<EOF
|
||||
diff --git a/new b/new
|
||||
new file mode 100644
|
||||
index 0000000..7898192
|
||||
--- /dev/null
|
||||
+++ b/new
|
||||
@@ -0,0 +1 @@
|
||||
+a
|
||||
EOF
|
||||
|
||||
echo % chmod +x
|
||||
hg import -msetx - <<EOF
|
||||
diff --git a/new b/new
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
EOF
|
||||
|
||||
test -x new || echo failed
|
||||
|
||||
echo % copy
|
||||
hg import -mcopy - <<EOF
|
||||
diff --git a/new b/copy
|
||||
old mode 100755
|
||||
new mode 100644
|
||||
similarity index 100%
|
||||
copy from new
|
||||
copy to copy
|
||||
diff --git a/new b/copyx
|
||||
similarity index 100%
|
||||
copy from new
|
||||
copy to copyx
|
||||
EOF
|
||||
|
||||
test -f copy -a ! -x copy || echo failed
|
||||
test -x copyx || echo failed
|
||||
cat copy
|
||||
hg cat copy
|
||||
|
||||
echo % rename
|
||||
hg import -mrename - <<EOF
|
||||
diff --git a/copy b/rename
|
||||
similarity index 100%
|
||||
rename from copy
|
||||
rename to rename
|
||||
EOF
|
||||
|
||||
hg locate
|
||||
|
||||
echo % delete
|
||||
hg import -mdelete - <<EOF
|
||||
diff --git a/copyx b/copyx
|
||||
deleted file mode 100755
|
||||
index 7898192..0000000
|
||||
--- a/copyx
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-a
|
||||
EOF
|
||||
|
||||
hg locate
|
||||
test -f copyx && echo failed || true
|
||||
|
||||
echo % regular diff
|
||||
hg import -mregular - <<EOF
|
||||
diff --git a/rename b/rename
|
||||
index 7898192..72e1fe3 100644
|
||||
--- a/rename
|
||||
+++ b/rename
|
||||
@@ -1 +1,5 @@
|
||||
a
|
||||
+a
|
||||
+a
|
||||
+a
|
||||
+a
|
||||
EOF
|
||||
|
||||
echo % copy and modify
|
||||
hg import -mcopymod - <<EOF
|
||||
diff --git a/rename b/copy2
|
||||
similarity index 80%
|
||||
copy from rename
|
||||
copy to copy2
|
||||
index 72e1fe3..b53c148 100644
|
||||
--- a/rename
|
||||
+++ b/copy2
|
||||
@@ -1,5 +1,5 @@
|
||||
a
|
||||
a
|
||||
-a
|
||||
+b
|
||||
a
|
||||
a
|
||||
EOF
|
||||
|
||||
hg cat copy2
|
||||
|
||||
echo % rename and modify
|
||||
hg import -mrenamemod - <<EOF
|
||||
diff --git a/copy2 b/rename2
|
||||
similarity index 80%
|
||||
rename from copy2
|
||||
rename to rename2
|
||||
index b53c148..8f81e29 100644
|
||||
--- a/copy2
|
||||
+++ b/rename2
|
||||
@@ -1,5 +1,5 @@
|
||||
a
|
||||
a
|
||||
b
|
||||
-a
|
||||
+c
|
||||
a
|
||||
EOF
|
||||
|
||||
hg locate copy2
|
||||
hg cat rename2
|
39
tests/test-git-import.out
Normal file
39
tests/test-git-import.out
Normal file
@ -0,0 +1,39 @@
|
||||
% new file
|
||||
applying patch from stdin
|
||||
patching file new
|
||||
% chmod +x
|
||||
applying patch from stdin
|
||||
% copy
|
||||
applying patch from stdin
|
||||
a
|
||||
a
|
||||
% rename
|
||||
applying patch from stdin
|
||||
copyx
|
||||
new
|
||||
rename
|
||||
% delete
|
||||
applying patch from stdin
|
||||
patching file copyx
|
||||
new
|
||||
rename
|
||||
% regular diff
|
||||
applying patch from stdin
|
||||
patching file rename
|
||||
% copy and modify
|
||||
applying patch from stdin
|
||||
patching file copy2
|
||||
a
|
||||
a
|
||||
b
|
||||
a
|
||||
a
|
||||
% rename and modify
|
||||
applying patch from stdin
|
||||
patching file rename2
|
||||
copy2: No such file or directory
|
||||
a
|
||||
a
|
||||
b
|
||||
c
|
||||
a
|
Loading…
Reference in New Issue
Block a user