Use the right lookup in dbcache.Cache.__contains__
[trackgit.git] / patch.py
blob4cc256f0ec19b382bbc79d3c5fef8928c2bf85d2
1 import re
2 import sys
3 import os.path
5 import db
6 import dbcache
7 from git import git
9 _boundary_line_regex = re.compile(r'^---')
10 _diff_head_regex = re.compile(r'^diff --git a/(.*) b/(.*)$')
11 _index_line_regex = re.compile(r'^index ([a-f0-9]{7,})\.\.([a-f0-9]{7,}) ')
12 _all_zeros_regex = re.compile(r'^0+$')
14 class PatchError(Exception):
15 pass
17 class Patch(object):
19 file_cache = dbcache.Cache(db.Filename, db.Filename.name, db.Session())
21 def __init__(self, data):
22 self.blobs_pre = set()
23 self.blobs_post = set()
24 self.missing_files = False
25 self.data = data
26 self.notes = None
27 self._parse(data)
29 def _parse(self, data):
30 boundary_seen = False
31 diff_seen = False
32 filename = None
33 notes = []
34 for line in data.splitlines(True):
35 if _boundary_line_regex.match(line):
36 boundary_seen = True
37 continue
38 m = _diff_head_regex.match(line)
39 if m:
40 diff_seen = True
41 # at least the 'pre' filename should exist
42 filename = m.group(1)
43 continue
44 if diff_seen:
45 m = _index_line_regex.match(line)
46 if m:
47 if not _all_zeros_regex.match(m.group(1)):
48 self.blobs_pre.add(m.group(1))
49 self._check_file(filename)
50 self.blobs_post.add(m.group(2))
51 continue
52 if boundary_seen:
53 notes.append(line)
54 if diff_seen:
55 self.notes = ''.join(notes)
57 def _check_file(self, name):
58 if (not self.missing_files
59 and os.path.basename(name) not in self.file_cache):
60 self.missing_files = True
61 print 'patch for missing file "%s"' % name
63 def apply(self):
64 print 'trying to apply patch-%x' % id(self)
65 output, ret = git('am', input=self.data)
66 if ret != 0:
67 # clean up
68 git('am', '--abort')
69 git('reset', '--hard')
70 raise PatchError()
71 return output