annotate upmana/mercurial/patch.py @ 179:5609ac142298 alpha

Traipse Alpha 'OpenRPG' {100114-03} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Keeping up with Beta) New Features: Added Bookmarks Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager New TrueDebug Class in orpg_log (See documentation for usage) Portable Mercurial Tip of the Day added, from Core and community New Reference Syntax added for custom PC sheets New Child Reference for gametree New Parent Reference for gametree New Gametree Recursion method, mapping, context sensitivity, and effeciency.. New Features node with bonus nodes and Node Referencing help added Dieroller structure from Core New DieRoller portability for odd Dice Added 7th Sea die roller; ie [7k3] = [7d10.takeHighest(3).open(10)] New 'Mythos' System die roller added Added new vs. die roller method for WoD; ie [3v3] = [3d10.vs(3)]. Included for Mythos roller also New Warhammer FRPG Die Roller (Special thanks to Puu-san for the support) New EZ_Tree Reference system. Push a button, Traipse the tree, get a reference (Beta!) Fixes: Fix to Text based Server Fix to Remote Admin Commands Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Fix to Map from gametree not showing to all clients Fix to gametree about menus Fix to Password Manager check on startup Fix to PC Sheets from tool nodes. They now use the tabber_panel Fix to Whiteboard ID to prevent random line or text deleting. Fixes to Server, Remote Server, and Server GUI Fix to Update Manager; cleaner clode for saved repositories Fixes made to Settings Panel and now reactive settings when Ok is pressed Fixes to Alternity roller's attack roll. Uses a simple Tuple instead of a Splice Fix to Use panel of Forms and Tabbers. Now longer enters design mode Fix made Image Fetching. New fetching image and new failed image Modified ID's to prevent non updated clients from ruining the fix. default_manifest.xml renamed to default_upmana.xml
author sirebral
date Thu, 14 Jan 2010 21:22:21 -0600
parents 496dbf12a6cb
children
rev   line source
121
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1 # patch.py - patch file parsing routines
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
2 #
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
3 # Copyright 2006 Brendan Cully <brendan@kublai.com>
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
4 # Copyright 2007 Chris Mason <chris.mason@oracle.com>
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
5 #
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
6 # This software may be used and distributed according to the terms of the
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
7 # GNU General Public License version 2, incorporated herein by reference.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
8
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
9 from i18n import _
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
10 from node import hex, nullid, short
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
11 import base85, cmdutil, mdiff, util, diffhelpers, copies
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
12 import cStringIO, email.Parser, os, re, math
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
13 import sys, tempfile, zlib
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
14
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
15 gitre = re.compile('diff --git a/(.*) b/(.*)')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
16
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
17 class PatchError(Exception):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
18 pass
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
19
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
20 class NoHunks(PatchError):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
21 pass
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
22
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
23 # helper functions
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
24
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
25 def copyfile(src, dst, basedir):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
26 abssrc, absdst = [util.canonpath(basedir, basedir, x) for x in [src, dst]]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
27 if os.path.exists(absdst):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
28 raise util.Abort(_("cannot create %s: destination already exists") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
29 dst)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
30
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
31 dstdir = os.path.dirname(absdst)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
32 if dstdir and not os.path.isdir(dstdir):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
33 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
34 os.makedirs(dstdir)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
35 except IOError:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
36 raise util.Abort(
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
37 _("cannot create %s: unable to create destination directory")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
38 % dst)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
39
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
40 util.copyfile(abssrc, absdst)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
41
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
42 # public functions
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
43
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
44 def extract(ui, fileobj):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
45 '''extract patch from data read from fileobj.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
46
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
47 patch can be a normal patch or contained in an email message.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
48
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
49 return tuple (filename, message, user, date, node, p1, p2).
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
50 Any item in the returned tuple can be None. If filename is None,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
51 fileobj did not contain a patch. Caller must unlink filename when done.'''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
52
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
53 # attempt to detect the start of a patch
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
54 # (this heuristic is borrowed from quilt)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
55 diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
56 r'retrieving revision [0-9]+(\.[0-9]+)*$|'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
57 r'(---|\*\*\*)[ \t])', re.MULTILINE)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
58
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
59 fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
60 tmpfp = os.fdopen(fd, 'w')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
61 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
62 msg = email.Parser.Parser().parse(fileobj)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
63
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
64 subject = msg['Subject']
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
65 user = msg['From']
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
66 gitsendmail = 'git-send-email' in msg.get('X-Mailer', '')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
67 # should try to parse msg['Date']
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
68 date = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
69 nodeid = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
70 branch = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
71 parents = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
72
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
73 if subject:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
74 if subject.startswith('[PATCH'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
75 pend = subject.find(']')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
76 if pend >= 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
77 subject = subject[pend+1:].lstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
78 subject = subject.replace('\n\t', ' ')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
79 ui.debug('Subject: %s\n' % subject)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
80 if user:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
81 ui.debug('From: %s\n' % user)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
82 diffs_seen = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
83 ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
84 message = ''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
85 for part in msg.walk():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
86 content_type = part.get_content_type()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
87 ui.debug('Content-Type: %s\n' % content_type)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
88 if content_type not in ok_types:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
89 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
90 payload = part.get_payload(decode=True)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
91 m = diffre.search(payload)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
92 if m:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
93 hgpatch = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
94 ignoretext = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
95
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
96 ui.debug(_('found patch at byte %d\n') % m.start(0))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
97 diffs_seen += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
98 cfp = cStringIO.StringIO()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
99 for line in payload[:m.start(0)].splitlines():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
100 if line.startswith('# HG changeset patch'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
101 ui.debug(_('patch generated by hg export\n'))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
102 hgpatch = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
103 # drop earlier commit message content
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
104 cfp.seek(0)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
105 cfp.truncate()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
106 subject = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
107 elif hgpatch:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
108 if line.startswith('# User '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
109 user = line[7:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
110 ui.debug('From: %s\n' % user)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
111 elif line.startswith("# Date "):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
112 date = line[7:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
113 elif line.startswith("# Branch "):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
114 branch = line[9:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
115 elif line.startswith("# Node ID "):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
116 nodeid = line[10:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
117 elif line.startswith("# Parent "):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
118 parents.append(line[10:])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
119 elif line == '---' and gitsendmail:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
120 ignoretext = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
121 if not line.startswith('# ') and not ignoretext:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
122 cfp.write(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
123 cfp.write('\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
124 message = cfp.getvalue()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
125 if tmpfp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
126 tmpfp.write(payload)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
127 if not payload.endswith('\n'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
128 tmpfp.write('\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
129 elif not diffs_seen and message and content_type == 'text/plain':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
130 message += '\n' + payload
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
131 except:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
132 tmpfp.close()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
133 os.unlink(tmpname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
134 raise
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
135
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
136 if subject and not message.startswith(subject):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
137 message = '%s\n%s' % (subject, message)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
138 tmpfp.close()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
139 if not diffs_seen:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
140 os.unlink(tmpname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
141 return None, message, user, date, branch, None, None, None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
142 p1 = parents and parents.pop(0) or None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
143 p2 = parents and parents.pop(0) or None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
144 return tmpname, message, user, date, branch, nodeid, p1, p2
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
145
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
146 GP_PATCH = 1 << 0 # we have to run patch
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
147 GP_FILTER = 1 << 1 # there's some copy/rename operation
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
148 GP_BINARY = 1 << 2 # there's a binary patch
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
149
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
150 class patchmeta(object):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
151 """Patched file metadata
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
152
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
153 'op' is the performed operation within ADD, DELETE, RENAME, MODIFY
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
154 or COPY. 'path' is patched file path. 'oldpath' is set to the
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
155 origin file when 'op' is either COPY or RENAME, None otherwise. If
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
156 file mode is changed, 'mode' is a tuple (islink, isexec) where
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
157 'islink' is True if the file is a symlink and 'isexec' is True if
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
158 the file is executable. Otherwise, 'mode' is None.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
159 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
160 def __init__(self, path):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
161 self.path = path
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
162 self.oldpath = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
163 self.mode = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
164 self.op = 'MODIFY'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
165 self.lineno = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
166 self.binary = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
167
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
168 def setmode(self, mode):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
169 islink = mode & 020000
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
170 isexec = mode & 0100
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
171 self.mode = (islink, isexec)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
172
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
173 def readgitpatch(lr):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
174 """extract git-style metadata about patches from <patchname>"""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
175
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
176 # Filter patch for git information
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
177 gp = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
178 gitpatches = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
179 # Can have a git patch with only metadata, causing patch to complain
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
180 dopatch = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
181
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
182 lineno = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
183 for line in lr:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
184 lineno += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
185 if line.startswith('diff --git'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
186 m = gitre.match(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
187 if m:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
188 if gp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
189 gitpatches.append(gp)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
190 src, dst = m.group(1, 2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
191 gp = patchmeta(dst)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
192 gp.lineno = lineno
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
193 elif gp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
194 if line.startswith('--- '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
195 if gp.op in ('COPY', 'RENAME'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
196 dopatch |= GP_FILTER
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
197 gitpatches.append(gp)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
198 gp = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
199 dopatch |= GP_PATCH
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
200 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
201 if line.startswith('rename from '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
202 gp.op = 'RENAME'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
203 gp.oldpath = line[12:].rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
204 elif line.startswith('rename to '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
205 gp.path = line[10:].rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
206 elif line.startswith('copy from '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
207 gp.op = 'COPY'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
208 gp.oldpath = line[10:].rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
209 elif line.startswith('copy to '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
210 gp.path = line[8:].rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
211 elif line.startswith('deleted file'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
212 gp.op = 'DELETE'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
213 # is the deleted file a symlink?
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
214 gp.setmode(int(line.rstrip()[-6:], 8))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
215 elif line.startswith('new file mode '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
216 gp.op = 'ADD'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
217 gp.setmode(int(line.rstrip()[-6:], 8))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
218 elif line.startswith('new mode '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
219 gp.setmode(int(line.rstrip()[-6:], 8))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
220 elif line.startswith('GIT binary patch'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
221 dopatch |= GP_BINARY
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
222 gp.binary = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
223 if gp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
224 gitpatches.append(gp)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
225
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
226 if not gitpatches:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
227 dopatch = GP_PATCH
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
228
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
229 return (dopatch, gitpatches)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
230
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
231 class linereader(object):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
232 # simple class to allow pushing lines back into the input stream
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
233 def __init__(self, fp, textmode=False):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
234 self.fp = fp
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
235 self.buf = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
236 self.textmode = textmode
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
237
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
238 def push(self, line):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
239 if line is not None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
240 self.buf.append(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
241
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
242 def readline(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
243 if self.buf:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
244 l = self.buf[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
245 del self.buf[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
246 return l
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
247 l = self.fp.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
248 if self.textmode and l.endswith('\r\n'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
249 l = l[:-2] + '\n'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
250 return l
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
251
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
252 def __iter__(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
253 while 1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
254 l = self.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
255 if not l:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
256 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
257 yield l
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
258
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
259 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
260 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
261 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
262
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
263 class patchfile(object):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
264 def __init__(self, ui, fname, opener, missing=False, eol=None):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
265 self.fname = fname
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
266 self.eol = eol
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
267 self.opener = opener
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
268 self.ui = ui
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
269 self.lines = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
270 self.exists = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
271 self.missing = missing
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
272 if not missing:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
273 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
274 self.lines = self.readlines(fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
275 self.exists = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
276 except IOError:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
277 pass
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
278 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
279 self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
280
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
281 self.hash = {}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
282 self.dirty = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
283 self.offset = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
284 self.rej = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
285 self.fileprinted = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
286 self.printfile(False)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
287 self.hunks = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
288
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
289 def readlines(self, fname):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
290 fp = self.opener(fname, 'r')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
291 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
292 return list(linereader(fp, self.eol is not None))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
293 finally:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
294 fp.close()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
295
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
296 def writelines(self, fname, lines):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
297 fp = self.opener(fname, 'w')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
298 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
299 if self.eol and self.eol != '\n':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
300 for l in lines:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
301 if l and l[-1] == '\n':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
302 l = l[:-1] + self.eol
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
303 fp.write(l)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
304 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
305 fp.writelines(lines)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
306 finally:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
307 fp.close()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
308
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
309 def unlink(self, fname):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
310 os.unlink(fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
311
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
312 def printfile(self, warn):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
313 if self.fileprinted:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
314 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
315 if warn or self.ui.verbose:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
316 self.fileprinted = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
317 s = _("patching file %s\n") % self.fname
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
318 if warn:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
319 self.ui.warn(s)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
320 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
321 self.ui.note(s)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
322
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
323
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
324 def findlines(self, l, linenum):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
325 # looks through the hash and finds candidate lines. The
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
326 # result is a list of line numbers sorted based on distance
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
327 # from linenum
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
328 def sorter(a, b):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
329 vala = abs(a - linenum)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
330 valb = abs(b - linenum)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
331 return cmp(vala, valb)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
332
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
333 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
334 cand = self.hash[l]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
335 except:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
336 return []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
337
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
338 if len(cand) > 1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
339 # resort our list of potentials forward then back.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
340 cand.sort(sorter)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
341 return cand
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
342
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
343 def hashlines(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
344 self.hash = {}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
345 for x, s in enumerate(self.lines):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
346 self.hash.setdefault(s, []).append(x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
347
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
348 def write_rej(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
349 # our rejects are a little different from patch(1). This always
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
350 # creates rejects in the same form as the original patch. A file
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
351 # header is inserted so that you can run the reject through patch again
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
352 # without having to type the filename.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
353
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
354 if not self.rej:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
355 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
356
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
357 fname = self.fname + ".rej"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
358 self.ui.warn(
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
359 _("%d out of %d hunks FAILED -- saving rejects to file %s\n") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
360 (len(self.rej), self.hunks, fname))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
361
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
362 def rejlines():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
363 base = os.path.basename(self.fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
364 yield "--- %s\n+++ %s\n" % (base, base)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
365 for x in self.rej:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
366 for l in x.hunk:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
367 yield l
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
368 if l[-1] != '\n':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
369 yield "\n\ No newline at end of file\n"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
370
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
371 self.writelines(fname, rejlines())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
372
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
373 def write(self, dest=None):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
374 if not self.dirty:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
375 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
376 if not dest:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
377 dest = self.fname
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
378 self.writelines(dest, self.lines)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
379
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
380 def close(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
381 self.write()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
382 self.write_rej()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
383
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
384 def apply(self, h, reverse):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
385 if not h.complete():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
386 raise PatchError(_("bad hunk #%d %s (%d %d %d %d)") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
387 (h.number, h.desc, len(h.a), h.lena, len(h.b),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
388 h.lenb))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
389
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
390 self.hunks += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
391 if reverse:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
392 h.reverse()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
393
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
394 if self.missing:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
395 self.rej.append(h)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
396 return -1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
397
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
398 if self.exists and h.createfile():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
399 self.ui.warn(_("file %s already exists\n") % self.fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
400 self.rej.append(h)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
401 return -1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
402
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
403 if isinstance(h, githunk):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
404 if h.rmfile():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
405 self.unlink(self.fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
406 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
407 self.lines[:] = h.new()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
408 self.offset += len(h.new())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
409 self.dirty = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
410 return 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
411
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
412 # fast case first, no offsets, no fuzz
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
413 old = h.old()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
414 # patch starts counting at 1 unless we are adding the file
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
415 if h.starta == 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
416 start = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
417 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
418 start = h.starta + self.offset - 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
419 orig_start = start
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
420 if diffhelpers.testhunk(old, self.lines, start) == 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
421 if h.rmfile():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
422 self.unlink(self.fname)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
423 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
424 self.lines[start : start + h.lena] = h.new()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
425 self.offset += h.lenb - h.lena
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
426 self.dirty = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
427 return 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
428
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
429 # ok, we couldn't match the hunk. Lets look for offsets and fuzz it
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
430 self.hashlines()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
431 if h.hunk[-1][0] != ' ':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
432 # if the hunk tried to put something at the bottom of the file
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
433 # override the start line and use eof here
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
434 search_start = len(self.lines)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
435 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
436 search_start = orig_start
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
437
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
438 for fuzzlen in xrange(3):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
439 for toponly in [ True, False ]:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
440 old = h.old(fuzzlen, toponly)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
441
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
442 cand = self.findlines(old[0][1:], search_start)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
443 for l in cand:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
444 if diffhelpers.testhunk(old, self.lines, l) == 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
445 newlines = h.new(fuzzlen, toponly)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
446 self.lines[l : l + len(old)] = newlines
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
447 self.offset += len(newlines) - len(old)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
448 self.dirty = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
449 if fuzzlen:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
450 fuzzstr = "with fuzz %d " % fuzzlen
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
451 f = self.ui.warn
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
452 self.printfile(True)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
453 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
454 fuzzstr = ""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
455 f = self.ui.note
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
456 offset = l - orig_start - fuzzlen
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
457 if offset == 1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
458 msg = _("Hunk #%d succeeded at %d %s"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
459 "(offset %d line).\n")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
460 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
461 msg = _("Hunk #%d succeeded at %d %s"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
462 "(offset %d lines).\n")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
463 f(msg % (h.number, l+1, fuzzstr, offset))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
464 return fuzzlen
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
465 self.printfile(True)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
466 self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
467 self.rej.append(h)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
468 return -1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
469
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
470 class hunk(object):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
471 def __init__(self, desc, num, lr, context, create=False, remove=False):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
472 self.number = num
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
473 self.desc = desc
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
474 self.hunk = [ desc ]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
475 self.a = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
476 self.b = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
477 if context:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
478 self.read_context_hunk(lr)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
479 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
480 self.read_unified_hunk(lr)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
481 self.create = create
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
482 self.remove = remove and not create
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
483
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
484 def read_unified_hunk(self, lr):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
485 m = unidesc.match(self.desc)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
486 if not m:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
487 raise PatchError(_("bad hunk #%d") % self.number)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
488 self.starta, foo, self.lena, self.startb, foo2, self.lenb = m.groups()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
489 if self.lena is None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
490 self.lena = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
491 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
492 self.lena = int(self.lena)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
493 if self.lenb is None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
494 self.lenb = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
495 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
496 self.lenb = int(self.lenb)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
497 self.starta = int(self.starta)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
498 self.startb = int(self.startb)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
499 diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb, self.a, self.b)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
500 # if we hit eof before finishing out the hunk, the last line will
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
501 # be zero length. Lets try to fix it up.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
502 while len(self.hunk[-1]) == 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
503 del self.hunk[-1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
504 del self.a[-1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
505 del self.b[-1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
506 self.lena -= 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
507 self.lenb -= 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
508
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
509 def read_context_hunk(self, lr):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
510 self.desc = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
511 m = contextdesc.match(self.desc)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
512 if not m:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
513 raise PatchError(_("bad hunk #%d") % self.number)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
514 foo, self.starta, foo2, aend, foo3 = m.groups()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
515 self.starta = int(self.starta)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
516 if aend is None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
517 aend = self.starta
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
518 self.lena = int(aend) - self.starta
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
519 if self.starta:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
520 self.lena += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
521 for x in xrange(self.lena):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
522 l = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
523 if l.startswith('---'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
524 lr.push(l)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
525 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
526 s = l[2:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
527 if l.startswith('- ') or l.startswith('! '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
528 u = '-' + s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
529 elif l.startswith(' '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
530 u = ' ' + s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
531 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
532 raise PatchError(_("bad hunk #%d old text line %d") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
533 (self.number, x))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
534 self.a.append(u)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
535 self.hunk.append(u)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
536
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
537 l = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
538 if l.startswith('\ '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
539 s = self.a[-1][:-1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
540 self.a[-1] = s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
541 self.hunk[-1] = s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
542 l = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
543 m = contextdesc.match(l)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
544 if not m:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
545 raise PatchError(_("bad hunk #%d") % self.number)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
546 foo, self.startb, foo2, bend, foo3 = m.groups()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
547 self.startb = int(self.startb)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
548 if bend is None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
549 bend = self.startb
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
550 self.lenb = int(bend) - self.startb
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
551 if self.startb:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
552 self.lenb += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
553 hunki = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
554 for x in xrange(self.lenb):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
555 l = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
556 if l.startswith('\ '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
557 s = self.b[-1][:-1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
558 self.b[-1] = s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
559 self.hunk[hunki-1] = s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
560 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
561 if not l:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
562 lr.push(l)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
563 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
564 s = l[2:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
565 if l.startswith('+ ') or l.startswith('! '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
566 u = '+' + s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
567 elif l.startswith(' '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
568 u = ' ' + s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
569 elif len(self.b) == 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
570 # this can happen when the hunk does not add any lines
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
571 lr.push(l)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
572 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
573 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
574 raise PatchError(_("bad hunk #%d old text line %d") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
575 (self.number, x))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
576 self.b.append(s)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
577 while True:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
578 if hunki >= len(self.hunk):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
579 h = ""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
580 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
581 h = self.hunk[hunki]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
582 hunki += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
583 if h == u:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
584 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
585 elif h.startswith('-'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
586 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
587 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
588 self.hunk.insert(hunki-1, u)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
589 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
590
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
591 if not self.a:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
592 # this happens when lines were only added to the hunk
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
593 for x in self.hunk:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
594 if x.startswith('-') or x.startswith(' '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
595 self.a.append(x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
596 if not self.b:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
597 # this happens when lines were only deleted from the hunk
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
598 for x in self.hunk:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
599 if x.startswith('+') or x.startswith(' '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
600 self.b.append(x[1:])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
601 # @@ -start,len +start,len @@
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
602 self.desc = "@@ -%d,%d +%d,%d @@\n" % (self.starta, self.lena,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
603 self.startb, self.lenb)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
604 self.hunk[0] = self.desc
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
605
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
606 def reverse(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
607 self.create, self.remove = self.remove, self.create
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
608 origlena = self.lena
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
609 origstarta = self.starta
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
610 self.lena = self.lenb
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
611 self.starta = self.startb
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
612 self.lenb = origlena
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
613 self.startb = origstarta
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
614 self.a = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
615 self.b = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
616 # self.hunk[0] is the @@ description
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
617 for x in xrange(1, len(self.hunk)):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
618 o = self.hunk[x]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
619 if o.startswith('-'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
620 n = '+' + o[1:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
621 self.b.append(o[1:])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
622 elif o.startswith('+'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
623 n = '-' + o[1:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
624 self.a.append(n)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
625 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
626 n = o
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
627 self.b.append(o[1:])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
628 self.a.append(o)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
629 self.hunk[x] = o
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
630
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
631 def fix_newline(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
632 diffhelpers.fix_newline(self.hunk, self.a, self.b)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
633
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
634 def complete(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
635 return len(self.a) == self.lena and len(self.b) == self.lenb
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
636
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
637 def createfile(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
638 return self.starta == 0 and self.lena == 0 and self.create
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
639
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
640 def rmfile(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
641 return self.startb == 0 and self.lenb == 0 and self.remove
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
642
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
643 def fuzzit(self, l, fuzz, toponly):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
644 # this removes context lines from the top and bottom of list 'l'. It
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
645 # checks the hunk to make sure only context lines are removed, and then
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
646 # returns a new shortened list of lines.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
647 fuzz = min(fuzz, len(l)-1)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
648 if fuzz:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
649 top = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
650 bot = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
651 hlen = len(self.hunk)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
652 for x in xrange(hlen-1):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
653 # the hunk starts with the @@ line, so use x+1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
654 if self.hunk[x+1][0] == ' ':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
655 top += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
656 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
657 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
658 if not toponly:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
659 for x in xrange(hlen-1):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
660 if self.hunk[hlen-bot-1][0] == ' ':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
661 bot += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
662 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
663 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
664
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
665 # top and bot now count context in the hunk
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
666 # adjust them if either one is short
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
667 context = max(top, bot, 3)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
668 if bot < context:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
669 bot = max(0, fuzz - (context - bot))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
670 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
671 bot = min(fuzz, bot)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
672 if top < context:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
673 top = max(0, fuzz - (context - top))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
674 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
675 top = min(fuzz, top)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
676
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
677 return l[top:len(l)-bot]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
678 return l
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
679
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
680 def old(self, fuzz=0, toponly=False):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
681 return self.fuzzit(self.a, fuzz, toponly)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
682
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
683 def newctrl(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
684 res = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
685 for x in self.hunk:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
686 c = x[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
687 if c == ' ' or c == '+':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
688 res.append(x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
689 return res
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
690
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
691 def new(self, fuzz=0, toponly=False):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
692 return self.fuzzit(self.b, fuzz, toponly)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
693
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
694 class githunk(object):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
695 """A git hunk"""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
696 def __init__(self, gitpatch):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
697 self.gitpatch = gitpatch
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
698 self.text = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
699 self.hunk = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
700
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
701 def createfile(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
702 return self.gitpatch.op in ('ADD', 'RENAME', 'COPY')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
703
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
704 def rmfile(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
705 return self.gitpatch.op == 'DELETE'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
706
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
707 def complete(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
708 return self.text is not None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
709
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
710 def new(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
711 return [self.text]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
712
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
713 class binhunk(githunk):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
714 'A binary patch file. Only understands literals so far.'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
715 def __init__(self, gitpatch):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
716 super(binhunk, self).__init__(gitpatch)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
717 self.hunk = ['GIT binary patch\n']
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
718
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
719 def extract(self, lr):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
720 line = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
721 self.hunk.append(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
722 while line and not line.startswith('literal '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
723 line = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
724 self.hunk.append(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
725 if not line:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
726 raise PatchError(_('could not extract binary patch'))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
727 size = int(line[8:].rstrip())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
728 dec = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
729 line = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
730 self.hunk.append(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
731 while len(line) > 1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
732 l = line[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
733 if l <= 'Z' and l >= 'A':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
734 l = ord(l) - ord('A') + 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
735 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
736 l = ord(l) - ord('a') + 27
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
737 dec.append(base85.b85decode(line[1:-1])[:l])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
738 line = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
739 self.hunk.append(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
740 text = zlib.decompress(''.join(dec))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
741 if len(text) != size:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
742 raise PatchError(_('binary patch is %d bytes, not %d') %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
743 len(text), size)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
744 self.text = text
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
745
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
746 class symlinkhunk(githunk):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
747 """A git symlink hunk"""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
748 def __init__(self, gitpatch, hunk):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
749 super(symlinkhunk, self).__init__(gitpatch)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
750 self.hunk = hunk
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
751
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
752 def complete(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
753 return True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
754
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
755 def fix_newline(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
756 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
757
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
758 def parsefilename(str):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
759 # --- filename \t|space stuff
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
760 s = str[4:].rstrip('\r\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
761 i = s.find('\t')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
762 if i < 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
763 i = s.find(' ')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
764 if i < 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
765 return s
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
766 return s[:i]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
767
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
768 def selectfile(afile_orig, bfile_orig, hunk, strip, reverse):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
769 def pathstrip(path, count=1):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
770 pathlen = len(path)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
771 i = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
772 if count == 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
773 return '', path.rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
774 while count > 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
775 i = path.find('/', i)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
776 if i == -1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
777 raise PatchError(_("unable to strip away %d dirs from %s") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
778 (count, path))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
779 i += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
780 # consume '//' in the path
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
781 while i < pathlen - 1 and path[i] == '/':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
782 i += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
783 count -= 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
784 return path[:i].lstrip(), path[i:].rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
785
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
786 nulla = afile_orig == "/dev/null"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
787 nullb = bfile_orig == "/dev/null"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
788 abase, afile = pathstrip(afile_orig, strip)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
789 gooda = not nulla and util.lexists(afile)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
790 bbase, bfile = pathstrip(bfile_orig, strip)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
791 if afile == bfile:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
792 goodb = gooda
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
793 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
794 goodb = not nullb and os.path.exists(bfile)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
795 createfunc = hunk.createfile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
796 if reverse:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
797 createfunc = hunk.rmfile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
798 missing = not goodb and not gooda and not createfunc()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
799 # If afile is "a/b/foo" and bfile is "a/b/foo.orig" we assume the
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
800 # diff is between a file and its backup. In this case, the original
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
801 # file should be patched (see original mpatch code).
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
802 isbackup = (abase == bbase and bfile.startswith(afile))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
803 fname = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
804 if not missing:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
805 if gooda and goodb:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
806 fname = isbackup and afile or bfile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
807 elif gooda:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
808 fname = afile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
809
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
810 if not fname:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
811 if not nullb:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
812 fname = isbackup and afile or bfile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
813 elif not nulla:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
814 fname = afile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
815 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
816 raise PatchError(_("undefined source and destination files"))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
817
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
818 return fname, missing
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
819
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
820 def scangitpatch(lr, firstline):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
821 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
822 Git patches can emit:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
823 - rename a to b
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
824 - change b
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
825 - copy a to c
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
826 - change c
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
827
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
828 We cannot apply this sequence as-is, the renamed 'a' could not be
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
829 found for it would have been renamed already. And we cannot copy
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
830 from 'b' instead because 'b' would have been changed already. So
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
831 we scan the git patch for copy and rename commands so we can
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
832 perform the copies ahead of time.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
833 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
834 pos = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
835 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
836 pos = lr.fp.tell()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
837 fp = lr.fp
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
838 except IOError:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
839 fp = cStringIO.StringIO(lr.fp.read())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
840 gitlr = linereader(fp, lr.textmode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
841 gitlr.push(firstline)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
842 (dopatch, gitpatches) = readgitpatch(gitlr)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
843 fp.seek(pos)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
844 return dopatch, gitpatches
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
845
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
846 def iterhunks(ui, fp, sourcefile=None, textmode=False):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
847 """Read a patch and yield the following events:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
848 - ("file", afile, bfile, firsthunk): select a new target file.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
849 - ("hunk", hunk): a new hunk is ready to be applied, follows a
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
850 "file" event.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
851 - ("git", gitchanges): current diff is in git format, gitchanges
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
852 maps filenames to gitpatch records. Unique event.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
853
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
854 If textmode is True, input line-endings are normalized to LF.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
855 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
856 changed = {}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
857 current_hunk = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
858 afile = ""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
859 bfile = ""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
860 state = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
861 hunknum = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
862 emitfile = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
863 git = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
864
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
865 # our states
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
866 BFILE = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
867 context = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
868 lr = linereader(fp, textmode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
869 dopatch = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
870 # gitworkdone is True if a git operation (copy, rename, ...) was
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
871 # performed already for the current file. Useful when the file
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
872 # section may have no hunk.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
873 gitworkdone = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
874
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
875 while True:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
876 newfile = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
877 x = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
878 if not x:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
879 break
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
880 if current_hunk:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
881 if x.startswith('\ '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
882 current_hunk.fix_newline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
883 yield 'hunk', current_hunk
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
884 current_hunk = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
885 gitworkdone = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
886 if ((sourcefile or state == BFILE) and ((not context and x[0] == '@') or
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
887 ((context is not False) and x.startswith('***************')))):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
888 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
889 if context is None and x.startswith('***************'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
890 context = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
891 gpatch = changed.get(bfile)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
892 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
893 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
894 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
895 if remove:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
896 gpatch = changed.get(afile[2:])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
897 if gpatch and gpatch.mode[0]:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
898 current_hunk = symlinkhunk(gpatch, current_hunk)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
899 except PatchError, err:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
900 ui.debug(err)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
901 current_hunk = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
902 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
903 hunknum += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
904 if emitfile:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
905 emitfile = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
906 yield 'file', (afile, bfile, current_hunk)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
907 elif state == BFILE and x.startswith('GIT binary patch'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
908 current_hunk = binhunk(changed[bfile])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
909 hunknum += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
910 if emitfile:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
911 emitfile = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
912 yield 'file', ('a/' + afile, 'b/' + bfile, current_hunk)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
913 current_hunk.extract(lr)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
914 elif x.startswith('diff --git'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
915 # check for git diff, scanning the whole patch file if needed
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
916 m = gitre.match(x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
917 if m:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
918 afile, bfile = m.group(1, 2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
919 if not git:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
920 git = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
921 dopatch, gitpatches = scangitpatch(lr, x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
922 yield 'git', gitpatches
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
923 for gp in gitpatches:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
924 changed[gp.path] = gp
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
925 # else error?
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
926 # copy/rename + modify should modify target, not source
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
927 gp = changed.get(bfile)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
928 if gp and gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
929 afile = bfile
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
930 gitworkdone = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
931 newfile = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
932 elif x.startswith('---'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
933 # check for a unified diff
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
934 l2 = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
935 if not l2.startswith('+++'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
936 lr.push(l2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
937 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
938 newfile = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
939 context = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
940 afile = parsefilename(x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
941 bfile = parsefilename(l2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
942 elif x.startswith('***'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
943 # check for a context diff
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
944 l2 = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
945 if not l2.startswith('---'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
946 lr.push(l2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
947 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
948 l3 = lr.readline()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
949 lr.push(l3)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
950 if not l3.startswith("***************"):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
951 lr.push(l2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
952 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
953 newfile = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
954 context = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
955 afile = parsefilename(x)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
956 bfile = parsefilename(l2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
957
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
958 if newfile:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
959 emitfile = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
960 state = BFILE
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
961 hunknum = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
962 if current_hunk:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
963 if current_hunk.complete():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
964 yield 'hunk', current_hunk
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
965 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
966 raise PatchError(_("malformed patch %s %s") % (afile,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
967 current_hunk.desc))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
968
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
969 if hunknum == 0 and dopatch and not gitworkdone:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
970 raise NoHunks
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
971
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
972 def applydiff(ui, fp, changed, strip=1, sourcefile=None, reverse=False,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
973 eol=None):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
974 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
975 Reads a patch from fp and tries to apply it.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
976
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
977 The dict 'changed' is filled in with all of the filenames changed
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
978 by the patch. Returns 0 for a clean patch, -1 if any rejects were
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
979 found and 1 if there was any fuzz.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
980
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
981 If 'eol' is None, the patch content and patched file are read in
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
982 binary mode. Otherwise, line endings are ignored when patching then
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
983 normalized to 'eol' (usually '\n' or \r\n').
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
984 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
985 rejects = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
986 err = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
987 current_file = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
988 gitpatches = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
989 opener = util.opener(os.getcwd())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
990 textmode = eol is not None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
991
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
992 def closefile():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
993 if not current_file:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
994 return 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
995 current_file.close()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
996 return len(current_file.rej)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
997
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
998 for state, values in iterhunks(ui, fp, sourcefile, textmode):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
999 if state == 'hunk':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1000 if not current_file:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1001 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1002 current_hunk = values
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1003 ret = current_file.apply(current_hunk, reverse)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1004 if ret >= 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1005 changed.setdefault(current_file.fname, None)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1006 if ret > 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1007 err = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1008 elif state == 'file':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1009 rejects += closefile()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1010 afile, bfile, first_hunk = values
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1011 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1012 if sourcefile:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1013 current_file = patchfile(ui, sourcefile, opener, eol=eol)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1014 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1015 current_file, missing = selectfile(afile, bfile, first_hunk,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1016 strip, reverse)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1017 current_file = patchfile(ui, current_file, opener, missing, eol)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1018 except PatchError, err:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1019 ui.warn(str(err) + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1020 current_file, current_hunk = None, None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1021 rejects += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1022 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1023 elif state == 'git':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1024 gitpatches = values
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1025 cwd = os.getcwd()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1026 for gp in gitpatches:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1027 if gp.op in ('COPY', 'RENAME'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1028 copyfile(gp.oldpath, gp.path, cwd)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1029 changed[gp.path] = gp
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1030 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1031 raise util.Abort(_('unsupported parser state: %s') % state)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1032
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1033 rejects += closefile()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1034
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1035 if rejects:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1036 return -1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1037 return err
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1038
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1039 def diffopts(ui, opts={}, untrusted=False):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1040 def get(key, name=None, getter=ui.configbool):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1041 return (opts.get(key) or
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1042 getter('diff', name or key, None, untrusted=untrusted))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1043 return mdiff.diffopts(
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1044 text=opts.get('text'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1045 git=get('git'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1046 nodates=get('nodates'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1047 showfunc=get('show_function', 'showfunc'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1048 ignorews=get('ignore_all_space', 'ignorews'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1049 ignorewsamount=get('ignore_space_change', 'ignorewsamount'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1050 ignoreblanklines=get('ignore_blank_lines', 'ignoreblanklines'),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1051 context=get('unified', getter=ui.config))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1052
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1053 def updatedir(ui, repo, patches, similarity=0):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1054 '''Update dirstate after patch application according to metadata'''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1055 if not patches:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1056 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1057 copies = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1058 removes = set()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1059 cfiles = patches.keys()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1060 cwd = repo.getcwd()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1061 if cwd:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1062 cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1063 for f in patches:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1064 gp = patches[f]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1065 if not gp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1066 continue
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1067 if gp.op == 'RENAME':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1068 copies.append((gp.oldpath, gp.path))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1069 removes.add(gp.oldpath)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1070 elif gp.op == 'COPY':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1071 copies.append((gp.oldpath, gp.path))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1072 elif gp.op == 'DELETE':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1073 removes.add(gp.path)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1074 for src, dst in copies:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1075 repo.copy(src, dst)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1076 if (not similarity) and removes:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1077 repo.remove(sorted(removes), True)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1078 for f in patches:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1079 gp = patches[f]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1080 if gp and gp.mode:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1081 islink, isexec = gp.mode
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1082 dst = repo.wjoin(gp.path)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1083 # patch won't create empty files
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1084 if gp.op == 'ADD' and not os.path.exists(dst):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1085 flags = (isexec and 'x' or '') + (islink and 'l' or '')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1086 repo.wwrite(gp.path, '', flags)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1087 elif gp.op != 'DELETE':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1088 util.set_flags(dst, islink, isexec)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1089 cmdutil.addremove(repo, cfiles, similarity=similarity)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1090 files = patches.keys()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1091 files.extend([r for r in removes if r not in files])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1092 return sorted(files)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1093
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1094 def externalpatch(patcher, args, patchname, ui, strip, cwd, files):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1095 """use <patcher> to apply <patchname> to the working directory.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1096 returns whether patch was applied with fuzz factor."""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1097
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1098 fuzz = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1099 if cwd:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1100 args.append('-d %s' % util.shellquote(cwd))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1101 fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1102 util.shellquote(patchname)))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1103
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1104 for line in fp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1105 line = line.rstrip()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1106 ui.note(line + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1107 if line.startswith('patching file '):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1108 pf = util.parse_patch_output(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1109 printed_file = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1110 files.setdefault(pf, None)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1111 elif line.find('with fuzz') >= 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1112 fuzz = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1113 if not printed_file:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1114 ui.warn(pf + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1115 printed_file = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1116 ui.warn(line + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1117 elif line.find('saving rejects to file') >= 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1118 ui.warn(line + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1119 elif line.find('FAILED') >= 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1120 if not printed_file:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1121 ui.warn(pf + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1122 printed_file = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1123 ui.warn(line + '\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1124 code = fp.close()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1125 if code:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1126 raise PatchError(_("patch command failed: %s") %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1127 util.explain_exit(code)[0])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1128 return fuzz
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1129
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1130 def internalpatch(patchobj, ui, strip, cwd, files={}, eolmode='strict'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1131 """use builtin patch to apply <patchobj> to the working directory.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1132 returns whether patch was applied with fuzz factor."""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1133
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1134 if eolmode is None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1135 eolmode = ui.config('patch', 'eol', 'strict')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1136 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1137 eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode.lower()]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1138 except KeyError:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1139 raise util.Abort(_('Unsupported line endings type: %s') % eolmode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1140
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1141 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1142 fp = file(patchobj, 'rb')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1143 except TypeError:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1144 fp = patchobj
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1145 if cwd:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1146 curdir = os.getcwd()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1147 os.chdir(cwd)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1148 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1149 ret = applydiff(ui, fp, files, strip=strip, eol=eol)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1150 finally:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1151 if cwd:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1152 os.chdir(curdir)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1153 if ret < 0:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1154 raise PatchError
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1155 return ret > 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1156
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1157 def patch(patchname, ui, strip=1, cwd=None, files={}, eolmode='strict'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1158 """Apply <patchname> to the working directory.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1159
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1160 'eolmode' specifies how end of lines should be handled. It can be:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1161 - 'strict': inputs are read in binary mode, EOLs are preserved
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1162 - 'crlf': EOLs are ignored when patching and reset to CRLF
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1163 - 'lf': EOLs are ignored when patching and reset to LF
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1164 - None: get it from user settings, default to 'strict'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1165 'eolmode' is ignored when using an external patcher program.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1166
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1167 Returns whether patch was applied with fuzz factor.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1168 """
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1169 patcher = ui.config('ui', 'patch')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1170 args = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1171 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1172 if patcher:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1173 return externalpatch(patcher, args, patchname, ui, strip, cwd,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1174 files)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1175 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1176 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1177 return internalpatch(patchname, ui, strip, cwd, files, eolmode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1178 except NoHunks:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1179 patcher = util.find_exe('gpatch') or util.find_exe('patch') or 'patch'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1180 ui.debug(_('no valid hunks found; trying with %r instead\n') %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1181 patcher)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1182 if util.needbinarypatch():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1183 args.append('--binary')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1184 return externalpatch(patcher, args, patchname, ui, strip, cwd,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1185 files)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1186 except PatchError, err:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1187 s = str(err)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1188 if s:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1189 raise util.Abort(s)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1190 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1191 raise util.Abort(_('patch failed to apply'))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1192
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1193 def b85diff(to, tn):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1194 '''print base85-encoded binary diff'''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1195 def gitindex(text):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1196 if not text:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1197 return '0' * 40
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1198 l = len(text)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1199 s = util.sha1('blob %d\0' % l)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1200 s.update(text)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1201 return s.hexdigest()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1202
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1203 def fmtline(line):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1204 l = len(line)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1205 if l <= 26:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1206 l = chr(ord('A') + l - 1)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1207 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1208 l = chr(l - 26 + ord('a') - 1)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1209 return '%c%s\n' % (l, base85.b85encode(line, True))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1210
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1211 def chunk(text, csize=52):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1212 l = len(text)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1213 i = 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1214 while i < l:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1215 yield text[i:i+csize]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1216 i += csize
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1217
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1218 tohash = gitindex(to)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1219 tnhash = gitindex(tn)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1220 if tohash == tnhash:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1221 return ""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1222
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1223 # TODO: deltas
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1224 ret = ['index %s..%s\nGIT binary patch\nliteral %s\n' %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1225 (tohash, tnhash, len(tn))]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1226 for l in chunk(zlib.compress(tn)):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1227 ret.append(fmtline(l))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1228 ret.append('\n')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1229 return ''.join(ret)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1230
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1231 def _addmodehdr(header, omode, nmode):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1232 if omode != nmode:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1233 header.append('old mode %s\n' % omode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1234 header.append('new mode %s\n' % nmode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1235
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1236 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1237 '''yields diff of changes to files between two nodes, or node and
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1238 working directory.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1239
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1240 if node1 is None, use first dirstate parent instead.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1241 if node2 is None, compare node1 with working directory.'''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1242
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1243 if opts is None:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1244 opts = mdiff.defaultopts
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1245
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1246 if not node1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1247 node1 = repo.dirstate.parents()[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1248
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1249 def lrugetfilectx():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1250 cache = {}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1251 order = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1252 def getfilectx(f, ctx):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1253 fctx = ctx.filectx(f, filelog=cache.get(f))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1254 if f not in cache:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1255 if len(cache) > 20:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1256 del cache[order.pop(0)]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1257 cache[f] = fctx._filelog
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1258 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1259 order.remove(f)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1260 order.append(f)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1261 return fctx
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1262 return getfilectx
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1263 getfilectx = lrugetfilectx()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1264
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1265 ctx1 = repo[node1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1266 ctx2 = repo[node2]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1267
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1268 if not changes:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1269 changes = repo.status(ctx1, ctx2, match=match)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1270 modified, added, removed = changes[:3]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1271
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1272 if not modified and not added and not removed:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1273 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1274
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1275 date1 = util.datestr(ctx1.date())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1276 man1 = ctx1.manifest()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1277
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1278 if repo.ui.quiet:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1279 r = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1280 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1281 hexfunc = repo.ui.debugflag and hex or short
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1282 r = [hexfunc(node) for node in [node1, node2] if node]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1283
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1284 if opts.git:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1285 copy, diverge = copies.copies(repo, ctx1, ctx2, repo[nullid])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1286 copy = copy.copy()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1287 for k, v in copy.items():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1288 copy[v] = k
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1289
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1290 gone = set()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1291 gitmode = {'l': '120000', 'x': '100755', '': '100644'}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1292
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1293 for f in sorted(modified + added + removed):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1294 to = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1295 tn = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1296 dodiff = True
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1297 header = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1298 if f in man1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1299 to = getfilectx(f, ctx1).data()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1300 if f not in removed:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1301 tn = getfilectx(f, ctx2).data()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1302 a, b = f, f
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1303 if opts.git:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1304 if f in added:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1305 mode = gitmode[ctx2.flags(f)]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1306 if f in copy:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1307 a = copy[f]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1308 omode = gitmode[man1.flags(a)]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1309 _addmodehdr(header, omode, mode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1310 if a in removed and a not in gone:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1311 op = 'rename'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1312 gone.add(a)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1313 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1314 op = 'copy'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1315 header.append('%s from %s\n' % (op, a))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1316 header.append('%s to %s\n' % (op, f))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1317 to = getfilectx(a, ctx1).data()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1318 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1319 header.append('new file mode %s\n' % mode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1320 if util.binary(tn):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1321 dodiff = 'binary'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1322 elif f in removed:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1323 # have we already reported a copy above?
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1324 if f in copy and copy[f] in added and copy[copy[f]] == f:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1325 dodiff = False
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1326 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1327 header.append('deleted file mode %s\n' %
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1328 gitmode[man1.flags(f)])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1329 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1330 omode = gitmode[man1.flags(f)]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1331 nmode = gitmode[ctx2.flags(f)]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1332 _addmodehdr(header, omode, nmode)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1333 if util.binary(to) or util.binary(tn):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1334 dodiff = 'binary'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1335 r = None
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1336 header.insert(0, mdiff.diffline(r, a, b, opts))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1337 if dodiff:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1338 if dodiff == 'binary':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1339 text = b85diff(to, tn)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1340 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1341 text = mdiff.unidiff(to, date1,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1342 # ctx2 date may be dynamic
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1343 tn, util.datestr(ctx2.date()),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1344 a, b, r, opts=opts)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1345 if header and (text or len(header) > 1):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1346 yield ''.join(header)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1347 if text:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1348 yield text
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1349
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1350 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1351 opts=None):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1352 '''export changesets as hg patches.'''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1353
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1354 total = len(revs)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1355 revwidth = max([len(str(rev)) for rev in revs])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1356
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1357 def single(rev, seqno, fp):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1358 ctx = repo[rev]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1359 node = ctx.node()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1360 parents = [p.node() for p in ctx.parents() if p]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1361 branch = ctx.branch()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1362 if switch_parent:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1363 parents.reverse()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1364 prev = (parents and parents[0]) or nullid
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1365
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1366 if not fp:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1367 fp = cmdutil.make_file(repo, template, node, total=total,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1368 seqno=seqno, revwidth=revwidth,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1369 mode='ab')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1370 if fp != sys.stdout and hasattr(fp, 'name'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1371 repo.ui.note("%s\n" % fp.name)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1372
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1373 fp.write("# HG changeset patch\n")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1374 fp.write("# User %s\n" % ctx.user())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1375 fp.write("# Date %d %d\n" % ctx.date())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1376 if branch and (branch != 'default'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1377 fp.write("# Branch %s\n" % branch)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1378 fp.write("# Node ID %s\n" % hex(node))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1379 fp.write("# Parent %s\n" % hex(prev))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1380 if len(parents) > 1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1381 fp.write("# Parent %s\n" % hex(parents[1]))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1382 fp.write(ctx.description().rstrip())
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1383 fp.write("\n\n")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1384
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1385 for chunk in diff(repo, prev, node, opts=opts):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1386 fp.write(chunk)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1387
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1388 for seqno, rev in enumerate(revs):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1389 single(rev, seqno+1, fp)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1390
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1391 def diffstatdata(lines):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1392 filename, adds, removes = None, 0, 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1393 for line in lines:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1394 if line.startswith('diff'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1395 if filename:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1396 yield (filename, adds, removes)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1397 # set numbers to 0 anyway when starting new file
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1398 adds, removes = 0, 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1399 if line.startswith('diff --git'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1400 filename = gitre.search(line).group(1)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1401 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1402 # format: "diff -r ... -r ... filename"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1403 filename = line.split(None, 5)[-1]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1404 elif line.startswith('+') and not line.startswith('+++'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1405 adds += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1406 elif line.startswith('-') and not line.startswith('---'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1407 removes += 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1408 if filename:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1409 yield (filename, adds, removes)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1410
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1411 def diffstat(lines, width=80):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1412 output = []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1413 stats = list(diffstatdata(lines))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1414
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1415 maxtotal, maxname = 0, 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1416 totaladds, totalremoves = 0, 0
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1417 for filename, adds, removes in stats:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1418 totaladds += adds
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1419 totalremoves += removes
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1420 maxname = max(maxname, len(filename))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1421 maxtotal = max(maxtotal, adds+removes)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1422
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1423 countwidth = len(str(maxtotal))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1424 graphwidth = width - countwidth - maxname
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1425 if graphwidth < 10:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1426 graphwidth = 10
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1427
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1428 factor = max(int(math.ceil(float(maxtotal) / graphwidth)), 1)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1429
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1430 for filename, adds, removes in stats:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1431 # If diffstat runs out of room it doesn't print anything, which
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1432 # isn't very useful, so always print at least one + or - if there
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1433 # were at least some changes
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1434 pluses = '+' * max(adds/factor, int(bool(adds)))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1435 minuses = '-' * max(removes/factor, int(bool(removes)))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1436 output.append(' %-*s | %*.d %s%s\n' % (maxname, filename, countwidth,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1437 adds+removes, pluses, minuses))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1438
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1439 if stats:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1440 output.append(' %d files changed, %d insertions(+), %d deletions(-)\n'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1441 % (len(stats), totaladds, totalremoves))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1442
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1443 return ''.join(output)