def test_send_pack_no_sideband64k_with_update_ref_error(self): # No side-bank-64k reported by server shouldn't try to parse # side band data pkts = ['55dcc6bf963f922e1ed5c4bbaaefcfacef57b1d7 capabilities^{}' '\x00 report-status delete-refs ofs-delta\n', '', "unpack ok", "ng refs/foo/bar pre-receive hook declined", ''] for pkt in pkts: if pkt == '': self.rin.write("0000") else: self.rin.write("%04x%s" % (len(pkt)+4, pkt)) self.rin.seek(0) tree = Tree() commit = Commit() commit.tree = tree commit.parents = [] commit.author = commit.committer = 'test user' commit.commit_time = commit.author_time = 1174773719 commit.commit_timezone = commit.author_timezone = 0 commit.encoding = 'UTF-8' commit.message = 'test message' def determine_wants(refs): return {'refs/foo/bar': commit.id, } def generate_pack_contents(have, want): return [(commit, None), (tree, ''), ] self.assertRaises(UpdateRefsError, self.client.send_pack, "blah", determine_wants, generate_pack_contents)
def update_content(self, new_content, author, email, message): new_content = new_content.encode('UTF-8') author = author.encode('UTF-8') message = message.encode('UTF-8') email = email.encode('UTF-8') # create blob, add to existing tree blob = Blob.from_string(new_content) self.tree[self.title] = (0100644, blob.id) # commit commit = Commit() commit.tree = self.tree.id commit.parents = [self.head.id] commit.author = commit.committer = "%s <%s>" % (author, email) commit.commit_time = commit.author_time = int(time()) tz = parse_timezone('+0100')[0] # FIXME: get proper timezone commit.commit_timezone = commit.author_timezone = tz commit.encoding = 'UTF-8' commit.message = message # save everything object_store = self.repo.object_store object_store.add_object(blob) object_store.add_object(self.tree) object_store.add_object(commit) self.repo.refs['refs/heads/master'] = commit.id
def delete_file(self, subdir, filename, commit_msg): try: subdir_tree = _walk_git_repo_tree(self.repo, self.current_tree, subdir) except KeyError: raise FileNotFoundException('No subdir named %r' % subdir) if not filename in subdir_tree: raise FileNotFoundException('%r not in %s' % (filename, subdir)) del subdir_tree[filename] # create new root tree tree = self.current_tree tree.add(stat.S_IFDIR, subdir, subdir_tree.id) # create commit # FIXME: factor this out! commit = Commit() commit.parents = [self.current_commit.id] commit.tree = tree.id commit.author = commit.committer = self.wiki_user commit.commit_time = commit.author_time = int(time.time()) commit.commit_timezone = commit.author_timezone = parse_timezone(time.timezone)[0] commit.encoding = 'UTF-8' commit.message = commit_msg.encode('utf-8') # store all objects self.repo.object_store.add_object(subdir_tree) self.repo.object_store.add_object(tree) self.repo.object_store.add_object(commit) # update the branch self.repo.refs[self.head] = commit.id
def test_send_pack_no_sideband64k_with_update_ref_error(self): # No side-bank-64k reported by server shouldn't try to parse # side band data pkts = [b'55dcc6bf963f922e1ed5c4bbaaefcfacef57b1d7 capabilities^{}' b'\x00 report-status delete-refs ofs-delta\n', b'', b"unpack ok", b"ng refs/foo/bar pre-receive hook declined", b''] for pkt in pkts: if pkt == b'': self.rin.write(b"0000") else: self.rin.write(("%04x" % (len(pkt)+4)).encode('ascii') + pkt) self.rin.seek(0) tree = Tree() commit = Commit() commit.tree = tree commit.parents = [] commit.author = commit.committer = b'test user' commit.commit_time = commit.author_time = 1174773719 commit.commit_timezone = commit.author_timezone = 0 commit.encoding = b'UTF-8' commit.message = b'test message' def update_refs(refs): return {b'refs/foo/bar': commit.id, } def generate_pack_data(have, want, ofs_delta=False): return pack_objects_to_data([(commit, None), (tree, ''), ]) self.assertRaises(UpdateRefsError, self.client.send_pack, "blah", update_refs, generate_pack_data)
def create_commit(data, marker='Default', blob=None): if not blob: blob = Blob.from_string('The blob content %s' % marker) tree = Tree() tree.add("thefile_%s" % marker, 0o100644, blob.id) cmt = Commit() if data: assert isinstance(data[-1], Commit) cmt.parents = [data[-1].id] cmt.tree = tree.id author = "John Doe %s <*****@*****.**>" % marker cmt.author = cmt.committer = author tz = parse_timezone('-0200')[0] cmt.commit_time = cmt.author_time = int(time()) cmt.commit_timezone = cmt.author_timezone = tz cmt.encoding = "UTF-8" cmt.message = "The commit message %s" % marker tag = Tag() tag.tagger = "*****@*****.**" tag.message = "Annotated tag" tag.tag_timezone = parse_timezone('-0200')[0] tag.tag_time = cmt.author_time tag.object = (Commit, cmt.id) tag.name = "v_%s_0.1" % marker return blob, tree, tag, cmt
def __init_code__(): # initialize the repo if it doesn't exists, or load it if it does if not path.exists(LOGS_PATH): print "creating folder "+ LOGS_PATH mkdir(LOGS_PATH) repo = Repo.init(LOGS_PATH) blob = Blob.from_string("data") tree =Tree() tree.add(0100644, "initfile", blob.id) c = Commit() c.tree = tree.id author = "Writer [email protected]" c.author=c.committer=author c.commit_time=c.author_time=int(time()) tz = parse_timezone('+0200') c.commit_timezone=c.author_timezone=tz c.encoding="UTF-8" c.message="initial commit" store = repo.object_store store.add_object(blob) store.add_object(tree) store.add_object(c) repo.refs['refs/heads/master'] = c.id repo.refs['HEAD'] = 'ref: refs/heads/master' print "success!" else: #this is how to create a Repo object from an existing repository from dulwich.errors import NotGitRepository try: repo = Repo(LOGS_PATH) except NotGitRepository as e: raise GitFileError("Error: the path %s exists but is not a git repository."%LOGS_PATH) return repo
def git_repo_init(gitdir): os.mkdir(gitdir) repo = Repo.init_bare(gitdir) blob = Blob.from_string("""Why, Hello there! This is your friendly Legislation tracker, Billy here. This is a git repo full of everything I write to the DB. This isn't super useful unless you're debugging production issues. Fondly, Bill, your local Billy instance.""") tree = Tree() tree.add("README", 0100644, blob.id) commit = Commit() commit.tree = tree.id author = "Billy <billy@localhost>" commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time()) tz = parse_timezone('-0400')[0] commit.commit_timezone = commit.author_timezone = tz commit.encoding = "UTF-8" commit.message = "Initial commit" repo.object_store.add_object(blob) repo.object_store.add_object(tree) repo.object_store.add_object(commit) repo.refs['refs/heads/master'] = commit.id
def git_am_patch_split(f): """Parse a git-am-style patch and split it up into bits. :param f: File-like object to parse :return: Tuple with commit object, diff contents and git version """ msg = rfc822.Message(f) c = Commit() c.author = msg["from"] c.committer = msg["from"] if msg["subject"].startswith("[PATCH"): subject = msg["subject"].split("]", 1)[1][1:] else: subject = msg["subject"] c.message = subject for l in f: if l == "---\n": break c.message += l diff = "" for l in f: if l == "-- \n": break diff += l version = f.next().rstrip("\n") return c, diff, version
def _update_file(self, name, subdir, filename, data, commit_msg): # first, create a new blob for the data blob = Blob.from_string(data.encode('utf-8')) # fetch the old tree object, add new page try: subdir_tree = _walk_git_repo_tree(self.repo, self.current_tree, subdir) except KeyError: # we need to create the subdir_tree as well, since it does not exist # yet subdir_tree = Tree() subdir_tree.add(_git_default_file_mode, filename, blob.id) # create new root tree tree = self.current_tree tree.add(stat.S_IFDIR, subdir, subdir_tree.id) # create commit commit = Commit() commit.parents = [self.current_commit.id] commit.tree = tree.id commit.author = commit.committer = self.wiki_user commit.commit_time = commit.author_time = int(time.time()) commit.commit_timezone = commit.author_timezone = parse_timezone(time.timezone)[0] commit.encoding = 'UTF-8' commit.message = commit_msg.encode('utf-8') # store all objects self.repo.object_store.add_object(blob) self.repo.object_store.add_object(subdir_tree) self.repo.object_store.add_object(tree) self.repo.object_store.add_object(commit) # update the branch self.repo.refs[self.head] = commit.id
def test_emit_commit(self): b = Blob() b.data = "FOO" t = Tree() t.add(stat.S_IFREG | 0644, "foo", b.id) c = Commit() c.committer = c.author = "Jelmer <jelmer@host>" c.author_time = c.commit_time = 1271345553 c.author_timezone = c.commit_timezone = 0 c.message = "msg" c.tree = t.id self.store.add_objects([(b, None), (t, None), (c, None)]) self.fastexporter.emit_commit(c, "refs/heads/master") self.assertEquals("""blob mark :1 data 3 FOO commit refs/heads/master mark :2 author Jelmer <jelmer@host> 1271345553 +0000 committer Jelmer <jelmer@host> 1271345553 +0000 data 3 msg M 644 1 foo """, self.stream.getvalue())
def test_simple_bytesio(self): f = BytesIO() c = Commit() c.committer = c.author = b"Jelmer <*****@*****.**>" c.commit_time = c.author_time = 1271350201 c.commit_timezone = c.author_timezone = 0 c.message = b"This is the first line\nAnd this is the second line.\n" c.tree = Tree().id write_commit_patch(f, c, b"CONTENTS", (1, 1), version="custom") f.seek(0) lines = f.readlines() self.assertTrue(lines[0].startswith(b"From 0b0d34d1b5b596c928adc9a727a4b9e03d025298")) self.assertEqual(lines[1], b"From: Jelmer <*****@*****.**>\n") self.assertTrue(lines[2].startswith(b"Date: ")) self.assertEqual( [ b"Subject: [PATCH 1/1] This is the first line\n", b"And this is the second line.\n", b"\n", b"\n", b"---\n", ], lines[3:8], ) self.assertEqual([b"CONTENTS-- \n", b"custom\n"], lines[-2:]) if len(lines) >= 12: # diffstat may not be present self.assertEqual(lines[8], b" 0 files changed\n")
def oldcreate(self, name): """ create a new repo :param name: the name to give the new repo :type name: string """ repo = Repo.init_bare(name) from dulwich.objects import Tree tree = Tree() from dulwich.objects import Commit, parse_timezone from time import time commit = Commit() commit.tree = tree.id #is the tree.id the sha1 of the files contained in tree author = "New Project Wizard <wizard@host>" commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time()) tz = parse_timezone('+1000')[0] commit.commit_timezone = commit.author_timezone = tz commit.encoding = "UTF-8" commit.message = "New Project." object_store = repo.object_store #then add the tree object_store.add_object(tree) #then add the commit object_store.add_object(commit) repo.refs['refs/heads/master'] = commit.id return {"success":"%s.git created" % name}
def write(files): repo = Repo(repo_path) blobs = {} dirs = {} def add_to_dirs(path): dirname = os.path.dirname(path) if path == '': return add_to_dirs(dirname) names = dirs.get(dirname, []) if path not in names: names.append(path) dirs[dirname] = names def savedir(dirname): tree = Tree() names = dirs[dirname] for name in names: basename = os.path.basename(name) sha = blobs.get(name, None) if sha is not None: tree.add(basename.encode('utf-8'), 0100644, sha) continue subtree = savedir(name) tree.add(basename.encode('utf-8'), 040000, subtree.id) repo.object_store.add_object(tree) return tree for metadata in files: blob = Blob.from_string(metadata.content) repo.object_store.add_object(blob) blobs[metadata.path[1:]] = blob.id add_to_dirs(metadata.path[1:]) tree = savedir('') commit = Commit() commit.tree = tree.id commit.author = author.encode('utf-8') commit.author_time = author_time commit.author_timezone = author_timezone commit.committer = committer.encode('utf-8') commit.commit_time = commit_time commit.commit_timezone = commit_timezone commit.encoding = encoding.encode('utf-8') commit.message = message.encode('utf-8') repo.object_store.add_object(commit) repo[ref] = commit.id
def _create_commit(self): commit = Commit() commit.author = commit.committer = self._author commit.commit_time = commit.author_time = int(time()) commit.commit_timezone = commit.author_timezone = self._time_zone commit.encoding = self._encoding return commit
def commit_handler(self, cmd): """Process a CommitCommand.""" commit = Commit() if cmd.author is not None: author = cmd.author else: author = cmd.committer (author_name, author_email, author_timestamp, author_timezone) = author (committer_name, committer_email, commit_timestamp, commit_timezone) = cmd.committer commit.author = "%s <%s>" % (author_name, author_email) commit.author_timezone = author_timezone commit.author_time = int(author_timestamp) commit.committer = "%s <%s>" % (committer_name, committer_email) commit.commit_timezone = commit_timezone commit.commit_time = int(commit_timestamp) commit.message = cmd.message commit.parents = [] contents = {} commit.tree = commit_tree( self.repo.object_store, ((path, hexsha, mode) for (path, (mode, hexsha)) in contents.iteritems()) ) if self.last_commit is not None: commit.parents.append(self.last_commit) commit.parents += cmd.merges self.repo.object_store.add_object(commit) self.repo[cmd.ref] = commit.id self.last_commit = commit.id if cmd.mark: self.markers[cmd.mark] = commit.id
def _commit(tree_dict, message): head = _get_current_head() tree = _get_current_tree() for name, contents in list(tree_dict.items()): if contents is None: del tree[name] else: blob = Blob.from_string(contents) _repo.object_store.add_object(blob) tree[name] = (0o100644, blob.id) commit = Commit() commit.parents = [head.id] if head else [] commit.tree = tree.id commit.author = commit.committer = "{0} <{1}>".format(_config.get("user", "name"), _config.get("user", "email")) commit.author_time = commit.commit_time = int(time()) commit.author_timezone = commit.commit_timezone = 0 commit.encoding = "UTF-8" commit.message = message _repo.object_store.add_object(tree) _repo.object_store.add_object(commit) _repo["refs/heads/clask"] = commit.id
def test_full_tree(self): c = self.make_commit(commit_time=30) t = Tree() t.add(b'data-x', 0o644, Blob().id) c.tree = t c1 = Commit() c1.set_raw_string(c.as_raw_string()) self.assertEqual(t.id, c1.tree) self.assertEqual(c.as_raw_string(), c1.as_raw_string())
def commit_handler(self, cmd): """Process a CommitCommand.""" commit = Commit() if cmd.author is not None: author = cmd.author else: author = cmd.committer (author_name, author_email, author_timestamp, author_timezone) = author (committer_name, committer_email, commit_timestamp, commit_timezone) = cmd.committer commit.author = author_name + b" <" + author_email + b">" commit.author_timezone = author_timezone commit.author_time = int(author_timestamp) commit.committer = committer_name + b" <" + committer_email + b">" commit.commit_timezone = commit_timezone commit.commit_time = int(commit_timestamp) commit.message = cmd.message commit.parents = [] if cmd.from_: cmd.from_ = self.lookup_object(cmd.from_) self._reset_base(cmd.from_) for filecmd in cmd.iter_files(): if filecmd.name == b"filemodify": if filecmd.data is not None: blob = Blob.from_string(filecmd.data) self.repo.object_store.add(blob) blob_id = blob.id else: blob_id = self.lookup_object(filecmd.dataref) self._contents[filecmd.path] = (filecmd.mode, blob_id) elif filecmd.name == b"filedelete": del self._contents[filecmd.path] elif filecmd.name == b"filecopy": self._contents[filecmd.dest_path] = self._contents[ filecmd.src_path] elif filecmd.name == b"filerename": self._contents[filecmd.new_path] = self._contents[ filecmd.old_path] del self._contents[filecmd.old_path] elif filecmd.name == b"filedeleteall": self._contents = {} else: raise Exception("Command %s not supported" % filecmd.name) commit.tree = commit_tree( self.repo.object_store, ((path, hexsha, mode) for (path, (mode, hexsha)) in self._contents.items())) if self.last_commit != ZERO_SHA: commit.parents.append(self.last_commit) for merge in cmd.merges: commit.parents.append(self.lookup_object(merge)) self.repo.object_store.add_object(commit) self.repo[cmd.ref] = commit.id self.last_commit = commit.id if cmd.mark: self.markers[cmd.mark] = commit.id
def _do_commit(self, tree, parents, author, timezone, message): commit = Commit() commit.tree = tree if type(tree) in (str, unicode) else tree.id commit.parents = parents commit.author = commit.committer = author.encode(self._encoding) commit.commit_time = commit.author_time = int(time()) commit.commit_timezone = commit.author_timezone = timezone commit.encoding = self._encoding commit.message = message self._repo.object_store.add_object(commit) return commit.id
def make_base(self): c = Commit() c.tree = 'd80c186a03f423a81b39df39dc87fd269736ca86' c.parents = ['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'] c.author = 'James Westby <*****@*****.**>' c.committer = 'James Westby <*****@*****.**>' c.commit_time = 1174773719 c.author_time = 1174773719 c.commit_timezone = 0 c.author_timezone = 0 c.message = 'Merge ../b\n' return c
def create_commit(marker=None): blob = Blob.from_string('The blob content %s' % marker) tree = Tree() tree.add("thefile %s" % marker, 0o100644, blob.id) cmt = Commit() cmt.tree = tree.id cmt.author = cmt.committer = "John Doe <*****@*****.**>" cmt.message = "%s" % marker tz = parse_timezone('-0200')[0] cmt.commit_time = cmt.author_time = int(time.time()) cmt.commit_timezone = cmt.author_timezone = tz return cmt, tree, blob
def do_commit(repo, tree, blobs, message, author, ref = "master"): commit = Commit() commit.tree = tree.id commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time.time()) tz = time.timezone if (time.daylight == 0) else time.altzone commit.commit_timezone = commit.author_timezone = tz commit.encoding = "UTF-8" commit.message = message for blob in blobs: repo.object_store.add_object(blob) repo.object_store.add_object(tree) repo.object_store.add_object(commit) repo.refs['refs/heads/%s' % ref] = commit.id
def test_deserialize_mergetags(self): tag = make_object( Tag, object=(Commit, b'a38d6181ff27824c79fc7df825164a212eff6a3f'), object_type_name=b'commit', name=b'v2.6.22-rc7', tag_time=1183319674, tag_timezone=0, tagger=b'Linus Torvalds <*****@*****.**>', message=default_message) commit = self.make_commit(mergetag=[tag, tag]) d = Commit() d._deserialize(commit.as_raw_chunks()) self.assertEqual(commit, d)
def init_the_git(config): path = config.get('Local', 'path') repo = Repo.init(path) blob = Blob.from_string(open(os.path.join(path, '.git-dropbox.cnf')).read()) tree = Tree() tree.add(".git-dropbox.cnf", 0100644, blob.id) commit = Commit() commit.tree = tree.id commit.author = config.get('Local', 'user') commit.committer = 'Git-dropbox' commit.commit_time = int(time()) commit.author_time = os.path.getctime(os.path.join(path, '.git-dropbox.cnf')) commit.commit_timezone = commit.author_timezone = parse_timezone('-0200')[0] commit.encoding = 'UTF-8' commit.message = 'Initial commit' object_store = repo.object_store object_store.add_object(blob) object_store.add_object(tree) object_store.add_object(commit) repo.refs['refs/heads/master'] = commit.id
def do_commit(self, message, committer=None, author=None, commit_timestamp=None, commit_timezone=None, author_timestamp=None, author_timezone=None, tree=None): """Create a new commit. :param message: Commit message :param committer: Committer fullname :param author: Author fullname (defaults to committer) :param commit_timestamp: Commit timestamp (defaults to now) :param commit_timezone: Commit timestamp timezone (defaults to GMT) :param author_timestamp: Author timestamp (defaults to commit timestamp) :param author_timezone: Author timestamp timezone (defaults to commit timestamp timezone) :param tree: SHA1 of the tree root to use (if not specified the current index will be committed). :return: New commit SHA1 """ import time index = self.open_index() c = Commit() if tree is None: c.tree = index.commit(self.object_store) else: c.tree = tree # TODO: Allow username to be missing, and get it from .git/config if committer is None: raise ValueError("committer not set") c.committer = committer if commit_timestamp is None: commit_timestamp = time.time() c.commit_time = int(commit_timestamp) if commit_timezone is None: # FIXME: Use current user timezone rather than UTC commit_timezone = 0 c.commit_timezone = commit_timezone if author is None: author = committer c.author = author if author_timestamp is None: author_timestamp = commit_timestamp c.author_time = int(author_timestamp) if author_timezone is None: author_timezone = commit_timezone c.author_timezone = author_timezone c.message = message self.object_store.add_object(c) self.refs["HEAD"] = c.id return c.id
def test_parse_header_trailing_newline(self): c = Commit.from_string(b'''\ tree a7d6277f78d3ecd0230a1a5df6db00b1d9c521ac parent c09b6dec7a73760fbdb478383a3c926b18db8bbe author Neil Matatall <*****@*****.**> 1461964057 -1000 committer Neil Matatall <*****@*****.**> 1461964057 -1000 gpgsig -----BEGIN PGP SIGNATURE----- wsBcBAABCAAQBQJXI80ZCRA6pcNDcVZ70gAAarcIABs72xRX3FWeox349nh6ucJK CtwmBTusez2Zwmq895fQEbZK7jpaGO5TRO4OvjFxlRo0E08UFx3pxZHSpj6bsFeL hHsDXnCaotphLkbgKKRdGZo7tDqM84wuEDlh4MwNe7qlFC7bYLDyysc81ZX5lpMm 2MFF1TvjLAzSvkT7H1LPkuR3hSvfCYhikbPOUNnKOo0sYjeJeAJ/JdAVQ4mdJIM0 gl3REp9+A+qBEpNQI7z94Pg5Bc5xenwuDh3SJgHvJV6zBWupWcdB3fAkVd4TPnEZ nHxksHfeNln9RKseIDcy4b2ATjhDNIJZARHNfr6oy4u3XPW4svRqtBsLoMiIeuI= =ms6q -----END PGP SIGNATURE----- 3.3.0 version bump and docs ''') # noqa: W291,W293 self.assertEqual([], c.extra) self.assertEqual(b'''\ -----BEGIN PGP SIGNATURE----- wsBcBAABCAAQBQJXI80ZCRA6pcNDcVZ70gAAarcIABs72xRX3FWeox349nh6ucJK CtwmBTusez2Zwmq895fQEbZK7jpaGO5TRO4OvjFxlRo0E08UFx3pxZHSpj6bsFeL hHsDXnCaotphLkbgKKRdGZo7tDqM84wuEDlh4MwNe7qlFC7bYLDyysc81ZX5lpMm 2MFF1TvjLAzSvkT7H1LPkuR3hSvfCYhikbPOUNnKOo0sYjeJeAJ/JdAVQ4mdJIM0 gl3REp9+A+qBEpNQI7z94Pg5Bc5xenwuDh3SJgHvJV6zBWupWcdB3fAkVd4TPnEZ nHxksHfeNln9RKseIDcy4b2ATjhDNIJZARHNfr6oy4u3XPW4svRqtBsLoMiIeuI= =ms6q -----END PGP SIGNATURE-----\n''', c.gpgsig)
def verify_revision_signature(self, revision_id, gpg_strategy): """Verify the signature on a revision. :param revision_id: the revision to verify :gpg_strategy: the GPGStrategy object to used :return: gpg.SIGNATURE_VALID or a failed SIGNATURE_ value """ from breezy import gpg with self.lock_read(): git_commit_id, mapping = self.lookup_bzr_revision_id(revision_id) try: commit = self._git.object_store[git_commit_id] except KeyError: raise errors.NoSuchRevision(self, revision_id) if commit.gpgsig is None: return gpg.SIGNATURE_NOT_SIGNED, None without_sig = Commit.from_string(commit.as_raw_string()) without_sig.gpgsig = None (result, key, plain_text) = gpg_strategy.verify(without_sig.as_raw_string(), commit.gpgsig) return (result, key)
def create_log(repo, contents, filename, overwrite=False): """creates a log with the specified content. This function creates a log file in the git repository specified by LOGS_PATH in settings.py. If a file with name filename exists, False is returned, unless overwrite=True. Arguments: contents the contents of the log, as a simple string filename the specific filename to use. overwrite whether or not to overwrite existing files. defaults to False, does change behavior when filename=None. Returns: False on failure, the filename to which the log was saved on success. Raises: GitFileError when the file exists while overwrite is False """ if not filename: return "Error: empty filename" if not contents: return "Error: empty contents" if type(contents) is list: contents=''.join(contents) if path.exists(path.join(LOGS_PATH, filename)) and not overwrite: return "Error: file exists, overwrite not specified" #create file blob = Blob.from_string(contents) tree = get_latest_tree(repo) tree[filename]=(default_perms, blob.id) commit = Commit() commit.tree=tree.id commit.parents=[repo.head()] commit.author = commit.committer = "Logwriter [email protected]" commit.commit_time = commit.author_time = int(time()) commit.commit_timezone = commit.author_timezone = parse_timezone('+0100') commit.encoding = "UTF-8" commit.message = "Writing log file %s"%(filename) store=repo.object_store store.add_object(blob) store.add_object(tree) store.add_object(commit) repo.refs['refs/heads/master'] = commit.id return True
def commit(self): # FIXME: this breaks if git repository just got initialized and no # inital commit has been done before. # FIXME: the working copy/tree has to be updated as well otherwise the # newly commited file will be out of sync with the working copy # (maybe we have to add the file to the index/stage? check how # RabbitVCS does it.) # TODO: maybe commit should be a method of the file object so that one # could write: # fh = open("file", 'w') # fh.write("blabla") # fh.close() # fh.commit() if self.opened: blob = Blob.from_raw_chunks(Blob.type_num, self._fh.readlines()) else: raise FileNotOpenError # FIXME: get mode from physical file mode = 0100644 head = self.repo.refs['refs/heads/' + self.branch] # head = self.repo.head() prev_commit = self.repo[head] tree = self.repo[prev_commit.tree] tree[self.path] = (mode, blob.id) # populate Git commit object commit = Commit() commit.tree = tree.id commit.parents = [head] commit.author = commit.committer = self.author commit.commit_time = commit.author_time = int(time.time()) commit.commit_timezone = commit.author_timezone = 0 commit.encoding = "UTF-8" # FIXME: create useful commit message commit.message = "Committing %s" % self.path self.repo.object_store.add_object(blob) self.repo.object_store.add_object(tree) self.repo.object_store.add_object(commit) self.repo.refs['refs/heads/' + self.branch] = commit.id
def _create_top_commit(self): # get the top commit, create empty one if it does not exist commit = Commit() # commit metadata author = self.AUTHOR.encode('utf8') commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time.time()) if self.TIMEZONE is not None: tz = self.TIMEZONE else: tz = time.timezone if (time.localtime().tm_isdst) else time.altzone commit.commit_timezone = commit.author_timezone = tz commit.encoding = b'UTF-8' return commit
def test_check_commit_with_overflow_date(self): """Date with overflow should raise an ObjectFormatException when checked """ identity_with_wrong_time = ( b'Igor Sysoev <*****@*****.**> 18446743887488505614 +42707004') commit0 = Commit.from_string(self.make_commit_text( author=identity_with_wrong_time, committer=default_committer)) commit1 = Commit.from_string(self.make_commit_text( author=default_committer, committer=identity_with_wrong_time)) # Those fails when triggering the check() method for commit in [commit0, commit1]: with self.assertRaises(ObjectFormatException): commit.check()
def test_unknown_extra(self): c = Commit() c.tree = b"cc9462f7f8263ef5adfbeff2fb936bb36b504cba" c.message = b"Some message" c.committer = b"Committer" c.commit_time = 4 c.author_time = 5 c.commit_timezone = 60 * 5 c.author_timezone = 60 * 3 c.author = b"Author" c._extra.append((b"iamextra", b"foo")) mapping = BzrGitMappingv1() self.assertRaises(UnknownCommitExtra, mapping.import_commit, c, mapping.revision_id_foreign_to_bzr) mapping.import_commit(c, mapping.revision_id_foreign_to_bzr, strict=False)
def create_commit(repo, files=None, tree=None, parent=None, author=AUTHOR, message="No message given"): object_store = repo.object_store if not tree: tree = Tree() for f in files: blob = Blob.from_string(f[2]) object_store.add_object(blob) tree.add(f[0], f[1], blob.id) commit = Commit() if parent: commit.parents = [parent] else: commit.parents = [] # Check that we have really updated the tree if parent: parent_commit = repo.get_object(parent) if parent_commit.tree == tree.id: raise NoChangesException() commit.tree = tree.id commit.author = commit.committer = author commit.commit_time = commit.author_time = get_ts() tz = parse_timezone('+0100')[0] commit.commit_timezone = commit.author_timezone = tz commit.encoding = "UTF-8" commit.message = message object_store.add_object(tree) object_store.add_object(commit) return commit
def test_implicit_encoding_utf8(self): c = Commit() c.tree = b"cc9462f7f8263ef5adfbeff2fb936bb36b504cba" c.message = b"Some message" c.committer = b"Committer" c.commit_time = 4 c.author_time = 5 c.commit_timezone = 60 * 5 c.author_timezone = 60 * 3 c.author = u"Authér".encode("utf-8") mapping = BzrGitMappingv1() rev, roundtrip_revid, verifiers = mapping.import_commit( c, mapping.revision_id_foreign_to_bzr) self.assertEqual(None, roundtrip_revid) self.assertEqual({}, verifiers) self.assertEqual(u"Authér", rev.properties[u'author']) self.assertTrue(u"git-explicit-encoding" not in rev.properties) self.assertTrue(u"git-implicit-encoding" not in rev.properties)
def revision_to_commit(rev, mapping, tree_sha): """ Turn a Bazaar revision in to a Git commit :param tree_sha: HACK parameter (until we can retrieve this from the mapping) :return dulwich.objects.Commit represent the revision: """ commit = Commit() commit._tree = tree_sha for p in rev.parent_ids: commit._parents.append(mapping.revision_id_bzr_to_foreign(p)) commit._message = rev.message commit._committer = rev.committer if 'author' in rev.properties: commit._author = rev.properties['author'] else: commit._author = rev.committer commit._commit_time = long(rev.timestamp) commit.serialize() return commit
def reset_repo(self): # ensure head exists tree = Tree() commit = Commit() commit.tree = tree.id commit.author = commit.committer = self.wiki_user commit.commit_time = commit.author_time = int(time.time()) commit.commit_timezone = commit.author_timezone = parse_timezone( time.timezone)[0] commit.encoding = 'UTF-8' commit.message = u'Automatic initalization by qwapp.'.encode('utf-8') # store all objects self.repo.object_store.add_object(tree) self.repo.object_store.add_object(commit) # update the branch self.repo.refs[self.head] = commit.id
def do_commit(self, message=None, committer=None, author=None, commit_timestamp=None, commit_timezone=None, author_timestamp=None, author_timezone=None, tree=None, encoding=None, ref='HEAD', merge_heads=None): """Create a new commit. :param message: Commit message :param committer: Committer fullname :param author: Author fullname (defaults to committer) :param commit_timestamp: Commit timestamp (defaults to now) :param commit_timezone: Commit timestamp timezone (defaults to GMT) :param author_timestamp: Author timestamp (defaults to commit timestamp) :param author_timezone: Author timestamp timezone (defaults to commit timestamp timezone) :param tree: SHA1 of the tree root to use (if not specified the current index will be committed). :param encoding: Encoding :param ref: Optional ref to commit to (defaults to current branch) :param merge_heads: Merge heads (defaults to .git/MERGE_HEADS) :return: New commit SHA1 """ import time c = Commit() if tree is None: index = self.open_index() c.tree = index.commit(self.object_store) else: if len(tree) != 40: raise ValueError("tree must be a 40-byte hex sha string") c.tree = tree try: self.hooks['pre-commit'].execute() except HookError, e: raise CommitError(e)
def _commit(self, tree): """ commit a tree used only by the init ``tree`` tree to commit """ commit = Commit() commit.tree = tree.id commit.encoding = "UTF-8" commit.committer = commit.author = 'debexpo <%s>' % ( pylons.config['debexpo.email']) commit.commit_time = commit.author_time = int(time()) tz = parse_timezone('-0200')[0] commit.commit_timezone = commit.author_timezone = tz commit.message = " " self.repo.object_store.add_object(tree) self.repo.object_store.add_object(commit) self.repo.refs["HEAD"] = commit.id log.debug('commiting') return commit.id
def _create_commit(tree, reason='', branch=False, parents=None, request=None): """ Creates a new commit based on the provided information. """ commit = Commit() if request and 'flatpages.git.author_name' in request.registry.settings: author = request.registry.settings['flatpages.git.author_name'] else: author = 'Anonymous' if request and 'flatpages.git.author_email' in request.registry.settings: author_email = request.registry.settings['flatpages.git.author_email'] author = '{0} <{1}>'.format(author, author_email) else: if request: author = '{0} <anonymous@{0}>'.format(request.host) else: author = '{0} <anonymous@{0}example.com>' # TODO: Right now, all times are in UTC time. Even though everything should # use UTC time in a perfect world - this isn't the case in the real world. commit.commit_timezone = commit.author_timezone = parse_timezone('0000')[0] commit.commit_time = commit.author_time = int(time.time()) commit.author = commit.committer = author commit.tree = tree.id commit.encoding = 'UTF-8' commit.message = reason if parents: commit.parents = parents return commit
def delete_file(self, subdir, filename, commit_msg): try: subdir_tree = _walk_git_repo_tree(self.repo, self.current_tree, subdir) except KeyError: raise FileNotFoundException('No subdir named %r' % subdir) if not filename in subdir_tree: raise FileNotFoundException('%r not in %s' % (filename, subdir)) del subdir_tree[filename] # create new root tree tree = self.current_tree tree.add(stat.S_IFDIR, subdir, subdir_tree.id) # create commit # FIXME: factor this out! commit = Commit() commit.parents = [self.current_commit.id] commit.tree = tree.id commit.author = commit.committer = self.wiki_user commit.commit_time = commit.author_time = int(time.time()) commit.commit_timezone = commit.author_timezone = parse_timezone( time.timezone)[0] commit.encoding = 'UTF-8' commit.message = commit_msg.encode('utf-8') # store all objects self.repo.object_store.add_object(subdir_tree) self.repo.object_store.add_object(tree) self.repo.object_store.add_object(commit) # update the branch self.repo.refs[self.head] = commit.id
def commit(self, name, email='*****@*****.**', message='wip', parents=None): if not self.is_head: return False # initial-commit if not self.snapshot_commit: parents = [] elif not parents: parents = [self.snapshot_commit.id] if not self.snapshot_commit or self.root_node.git_object.id != self.snapshot_commit.tree: c = Commit() c.tree = self.root_node.git_object.id c.parents = parents c.author = c.committer = '%s <%s>' % (name.encode('utf-8'), email.encode('utf-8')) c.commit_time = c.author_time = int(time()) c.commit_timezone = c.author_timezone = 0 c.encoding = "UTF-8" c.message = message self.repo.object_store.add_object(c) self.repo.refs[self.ref] = c.id return c return False
def _do_commit(self, index, author, message, ctime, parent_rev=None): committer = b'%s <>' % author.encode('utf8') commit = Commit() commit.tree = index.commit(self.repo.object_store) commit.author = commit.committer = committer commit.commit_time = commit.author_time = ctime commit.encoding = b'UTF-8' commit.commit_timezone = commit.author_timezone = 0 commit.message = message.encode('utf8') try: curr_head = self.repo.head() commit.parents = [curr_head] # if parent_rev and len(parent_rev) == 40: # commit.parents.append(parent_rev.encode('ascii')) except KeyError: curr_head = None self.repo.object_store.add_object(commit) self.repo.refs.set_if_equals(b'HEAD', curr_head, commit.id, message=b"commit: " + commit.message, committer=commit.committer, timestamp=ctime, timezone=0) index.write()
def create_commit(data, marker=b"Default", blob=None): if not blob: blob = Blob.from_string(b"The blob content " + marker) tree = Tree() tree.add(b"thefile_" + marker, 0o100644, blob.id) cmt = Commit() if data: assert isinstance(data[-1], Commit) cmt.parents = [data[-1].id] cmt.tree = tree.id author = b"John Doe " + marker + b" <*****@*****.**>" cmt.author = cmt.committer = author tz = parse_timezone(b"-0200")[0] cmt.commit_time = cmt.author_time = int(time()) cmt.commit_timezone = cmt.author_timezone = tz cmt.encoding = b"UTF-8" cmt.message = b"The commit message " + marker tag = Tag() tag.tagger = b"*****@*****.**" tag.message = b"Annotated tag" tag.tag_timezone = parse_timezone(b"-0200")[0] tag.tag_time = cmt.author_time tag.object = (Commit, cmt.id) tag.name = b"v_" + marker + b"_0.1" return blob, tree, tag, cmt
def test_git_submodule_exists(self): repo_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, repo_dir) with Repo.init(repo_dir) as repo: filea = Blob.from_string(b'file alalala') subtree = Tree() subtree[b'a'] = (stat.S_IFREG | 0o644, filea.id) c = Commit() c.tree = subtree.id c.committer = c.author = b'Somebody <*****@*****.**>' c.commit_time = c.author_time = 42342 c.commit_timezone = c.author_timezone = 0 c.parents = [] c.message = b'Subcommit' tree = Tree() tree[b'c'] = (S_IFGITLINK, c.id) os.mkdir(os.path.join(repo_dir, 'c')) repo.object_store.add_objects( [(o, None) for o in [tree]]) build_index_from_tree( repo.path, repo.index_path(), repo.object_store, tree.id) # Verify index entries index = repo.open_index() self.assertEqual(len(index), 1) # filea apath = os.path.join(repo.path, 'c/a') self.assertFalse(os.path.exists(apath)) # dir c cpath = os.path.join(repo.path, 'c') self.assertTrue(os.path.isdir(cpath)) self.assertEqual(index[b'c'][4], S_IFGITLINK) # mode self.assertEqual(index[b'c'][8], c.id) # sha
def test_send_pack_no_sideband64k_with_update_ref_error(self): # No side-bank-64k reported by server shouldn't try to parse # side band data pkts = [b'55dcc6bf963f922e1ed5c4bbaaefcfacef57b1d7 capabilities^{}' b'\x00 report-status delete-refs ofs-delta\n', b'', b"unpack ok", b"ng refs/foo/bar pre-receive hook declined", b''] for pkt in pkts: if pkt == b'': self.rin.write(b"0000") else: self.rin.write(("%04x" % (len(pkt)+4)).encode('ascii') + pkt) self.rin.seek(0) tree = Tree() commit = Commit() commit.tree = tree commit.parents = [] commit.author = commit.committer = b'test user' commit.commit_time = commit.author_time = 1174773719 commit.commit_timezone = commit.author_timezone = 0 commit.encoding = b'UTF-8' commit.message = b'test message' def determine_wants(refs): return {b'refs/foo/bar': commit.id, } def generate_pack_contents(have, want): return [(commit, None), (tree, ''), ] self.assertRaises(UpdateRefsError, self.client.send_pack, "blah", determine_wants, generate_pack_contents)
def test_simple_bytesio(self): f = BytesIO() c = Commit() c.committer = c.author = b"Jelmer <*****@*****.**>" c.commit_time = c.author_time = 1271350201 c.commit_timezone = c.author_timezone = 0 c.message = b"This is the first line\nAnd this is the second line.\n" c.tree = Tree().id write_commit_patch(f, c, b"CONTENTS", (1, 1), version="custom") f.seek(0) lines = f.readlines() self.assertTrue(lines[0].startswith( b"From 0b0d34d1b5b596c928adc9a727a4b9e03d025298")) self.assertEqual(lines[1], b"From: Jelmer <*****@*****.**>\n") self.assertTrue(lines[2].startswith(b"Date: ")) self.assertEqual([ b"Subject: [PATCH 1/1] This is the first line\n", b"And this is the second line.\n", b"\n", b"\n", b"---\n" ], lines[3:8]) self.assertEqual([b"CONTENTS-- \n", b"custom\n"], lines[-2:]) if len(lines) >= 12: # diffstat may not be present self.assertEqual(lines[8], b" 0 files changed\n")
def step_impl_given(context): context.test_git_repo_dir = tempfile.mkdtemp('paasta_tools_deployments_json_itest') context.test_git_repo = Repo.init(context.test_git_repo_dir) print 'Temp repo in %s' % context.test_git_repo_dir blob = Blob.from_string("My file content\n") tree = Tree() tree.add("spam", 0100644, blob.id) commit = Commit() commit.author = commit.committer = "itest author" commit.commit_time = commit.author_time = int(time()) commit.commit_timezone = commit.author_timezone = parse_timezone('-0200')[0] commit.message = "Initial commit" commit.tree = tree.id object_store = context.test_git_repo.object_store object_store.add_object(blob) object_store.add_object(tree) object_store.add_object(commit) context.test_git_repo.refs['refs/heads/paasta-test_cluster.test_instance'] = commit.id context.expected_commit = commit.id
def test_commit(self): c = Commit() c.tree = b"cc9462f7f8263ef5adfbeff2fb936bb36b504cba" c.message = b"Some message" c.committer = b"Committer" c.commit_time = 4 c.author_time = 5 c.commit_timezone = 60 * 5 c.author_timezone = 60 * 3 c.author = b"Author" mapping = BzrGitMappingv1() rev, roundtrip_revid, verifiers = mapping.import_commit( c, mapping.revision_id_foreign_to_bzr) self.assertEqual(None, roundtrip_revid) self.assertEqual({}, verifiers) self.assertEqual(u"Some message", rev.message) self.assertEqual(u"Committer", rev.committer) self.assertEqual(u"Author", rev.properties[u'author']) self.assertEqual(300, rev.timezone) self.assertEqual([], rev.parent_ids) self.assertEqual("5", rev.properties[u'author-timestamp']) self.assertEqual("180", rev.properties[u'author-timezone']) self.assertEqual(b"git-v1:" + c.id, rev.revision_id)
def step_impl_given(context): context.test_git_repo_dir = tempfile.mkdtemp("paasta_tools_deployments_json_itest") context.test_git_repo = Repo.init(context.test_git_repo_dir) paasta_print("Temp repo in %s" % context.test_git_repo_dir) blob = Blob.from_string(b"My file content\n") tree = Tree() tree.add(b"spam", 0o0100644, blob.id) commit = Commit() commit.author = commit.committer = b"itest author" commit.commit_time = commit.author_time = int(time()) commit.commit_timezone = commit.author_timezone = parse_timezone(b"-0200")[0] commit.message = b"Initial commit" commit.tree = tree.id object_store = context.test_git_repo.object_store object_store.add_object(blob) object_store.add_object(tree) object_store.add_object(commit) context.test_git_repo.refs[b"refs/heads/master"] = commit.id context.expected_commit_as_bytes = commit.id context.expected_commit = context.expected_commit_as_bytes.decode()
def test_parse_gpgsig(self): c = Commit.from_string( b"""tree aaff74984cccd156a469afa7d9ab10e4777beb24 author Jelmer Vernooij <*****@*****.**> 1412179807 +0200 committer Jelmer Vernooij <*****@*****.**> 1412179807 +0200 gpgsig -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCgAGBQJULCdfAAoJEACAbyvXKaRXuKwP/RyP9PA49uAvu8tQVCC/uBa8 vi975+xvO14R8Pp8k2nps7lSxCdtCd+xVT1VRHs0wNhOZo2YCVoU1HATkPejqSeV NScTHcxnk4/+bxyfk14xvJkNp7FlQ3npmBkA+lbV0Ubr33rvtIE5jiJPyz+SgWAg xdBG2TojV0squj00GoH/euK6aX7GgZtwdtpTv44haCQdSuPGDcI4TORqR6YSqvy3 GPE+3ZqXPFFb+KILtimkxitdwB7CpwmNse2vE3rONSwTvi8nq3ZoQYNY73CQGkUy qoFU0pDtw87U3niFin1ZccDgH0bB6624sLViqrjcbYJeg815Htsu4rmzVaZADEVC XhIO4MThebusdk0AcNGjgpf3HRHk0DPMDDlIjm+Oao0cqovvF6VyYmcb0C+RmhJj dodLXMNmbqErwTk3zEkW0yZvNIYXH7m9SokPCZa4eeIM7be62X6h1mbt0/IU6Th+ v18fS0iTMP/Viug5und+05C/v04kgDo0CPphAbXwWMnkE4B6Tl9sdyUYXtvQsL7x 0+WP1gL27ANqNZiI07Kz/BhbBAQI/+2TFT7oGr0AnFPQ5jHp+3GpUf6OKuT1wT3H ND189UFuRuubxb42vZhpcXRbqJVWnbECTKVUPsGZqat3enQUB63uM4i6/RdONDZA fDeF1m4qYs+cUXKNUZ03 =X6RT -----END PGP SIGNATURE----- foo """) self.assertEqual(b'foo\n', c.message) self.assertEqual([], c.extra) self.assertEqual( b"""-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCgAGBQJULCdfAAoJEACAbyvXKaRXuKwP/RyP9PA49uAvu8tQVCC/uBa8 vi975+xvO14R8Pp8k2nps7lSxCdtCd+xVT1VRHs0wNhOZo2YCVoU1HATkPejqSeV NScTHcxnk4/+bxyfk14xvJkNp7FlQ3npmBkA+lbV0Ubr33rvtIE5jiJPyz+SgWAg xdBG2TojV0squj00GoH/euK6aX7GgZtwdtpTv44haCQdSuPGDcI4TORqR6YSqvy3 GPE+3ZqXPFFb+KILtimkxitdwB7CpwmNse2vE3rONSwTvi8nq3ZoQYNY73CQGkUy qoFU0pDtw87U3niFin1ZccDgH0bB6624sLViqrjcbYJeg815Htsu4rmzVaZADEVC XhIO4MThebusdk0AcNGjgpf3HRHk0DPMDDlIjm+Oao0cqovvF6VyYmcb0C+RmhJj dodLXMNmbqErwTk3zEkW0yZvNIYXH7m9SokPCZa4eeIM7be62X6h1mbt0/IU6Th+ v18fS0iTMP/Viug5und+05C/v04kgDo0CPphAbXwWMnkE4B6Tl9sdyUYXtvQsL7x 0+WP1gL27ANqNZiI07Kz/BhbBAQI/+2TFT7oGr0AnFPQ5jHp+3GpUf6OKuT1wT3H ND189UFuRuubxb42vZhpcXRbqJVWnbECTKVUPsGZqat3enQUB63uM4i6/RdONDZA fDeF1m4qYs+cUXKNUZ03 =X6RT -----END PGP SIGNATURE-----""", c.gpgsig)
def test_simple(self): c = Commit.from_string(self.make_commit_text()) self.assertEqual('Merge ../b\n', c.message) self.assertEqual('James Westby <*****@*****.**>', c.author) self.assertEqual('James Westby <*****@*****.**>', c.committer) self.assertEqual('d80c186a03f423a81b39df39dc87fd269736ca86', c.tree) self.assertEqual(['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'], c.parents) expected_time = datetime.datetime(2007, 3, 24, 22, 1, 59) self.assertEqual(expected_time, datetime.datetime.utcfromtimestamp(c.commit_time)) self.assertEqual(0, c.commit_timezone) self.assertEqual(expected_time, datetime.datetime.utcfromtimestamp(c.author_time)) self.assertEqual(0, c.author_timezone) self.assertEqual(None, c.encoding)
def test_mangled_author_line(self): """Mangled author line should successfully parse""" author_line = ( b'Karl MacMillan <*****@*****.**> <"Karl MacMillan ' b'<*****@*****.**>"> 1197475547 -0500' ) expected_identity = ( b'Karl MacMillan <*****@*****.**> <"Karl MacMillan ' b'<*****@*****.**>">' ) commit = Commit.from_string( self.make_commit_text(author=author_line) ) # The commit parses properly self.assertEqual(commit.author, expected_identity) # But the check fails because the author identity is bogus with self.assertRaises(ObjectFormatException): commit.check()
def git_prelod(abbr): if not hasattr(settings, "ENABLE_GIT") or not settings.ENABLE_GIT: return global git_active_repo global git_active_commit global git_active_tree global git_old_tree global HEAD gitdir = "%s/%s.git" % (settings.GIT_PATH, abbr) if not os.path.exists(gitdir): git_repo_init(gitdir) git_active_repo = Repo(gitdir) git_active_commit = Commit() HEAD = git_active_repo.head() commit = git_active_repo.commit(HEAD) tree = git_active_repo.tree(commit.tree) git_old_tree = tree.id git_active_tree = tree
def make_commit(repo, tree, message, author, timezone, encoding="UTF-8"): """build a Commit object""" commit = Commit() try: commit.parents = [repo.head()] except KeyError: #the initial commit has no parent pass if isinstance(tree, dulwich.objects.Tree): tree_id = tree.id elif isinstance(tree, str): tree_id = tree commit.tree = tree_id commit.message = message commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time()) commit.commit_timezone = commit.author_timezone = parse_timezone(timezone) commit.encoding = encoding return commit
def parse_patch_message(msg, encoding=None): """Extract a Commit object and patch from an e-mail message. Args: msg: An email message (email.message.Message) encoding: Encoding to use to encode Git commits Returns: Tuple with commit object, diff contents and git version """ c = Commit() c.author = msg["from"].encode(encoding) c.committer = msg["from"].encode(encoding) try: patch_tag_start = msg["subject"].index("[PATCH") except ValueError: subject = msg["subject"] else: close = msg["subject"].index("] ", patch_tag_start) subject = msg["subject"][close + 2:] c.message = (subject.replace("\n", "") + "\n").encode(encoding) first = True body = msg.get_payload(decode=True) lines = body.splitlines(True) line_iter = iter(lines) for line in line_iter: if line == b"---\n": break if first: if line.startswith(b"From: "): c.author = line[len(b"From: "):].rstrip() else: c.message += b"\n" + line first = False else: c.message += line diff = b"" for line in line_iter: if line == b"-- \n": break diff += line try: version = next(line_iter).rstrip(b"\n") except StopIteration: version = None return c, diff, version