annotate upmana/mercurial/patch.py @ 37:a1b3b4494bdb ornery-orc

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