def tag_handler(self, cmd): """Process a TagCommand.""" tag = Tag() tag.tagger = cmd.tagger tag.message = cmd.message tag.name = cmd.tag self.repo.add_object(tag) self.repo.refs["refs/tags/" + tag.name] = tag.id
def test_parse(self): x = Tag() x.set_raw_string(self.make_tag_text()) self.assertEqual("Linus Torvalds <*****@*****.**>", x.tagger) self.assertEqual("v2.6.22-rc7", x.name) object_type, object_sha = x.object self.assertEqual("a38d6181ff27824c79fc7df825164a212eff6a3f", object_sha) self.assertEqual(Commit, object_type) self.assertEqual(datetime.datetime.utcfromtimestamp(x.tag_time), datetime.datetime(2007, 7, 1, 19, 54, 34)) self.assertEqual(-25200, x.tag_timezone)
def test_parse_no_message(self): x = Tag() x.set_raw_string(self.make_tag_text(message=None)) self.assertEqual(None, x.message) self.assertEqual( b'Linus Torvalds <*****@*****.**>', x.tagger) self.assertEqual(datetime.datetime.utcfromtimestamp(x.tag_time), datetime.datetime(2007, 7, 1, 19, 54, 34)) self.assertEqual(-25200, x.tag_timezone) self.assertEqual(b'v2.6.22-rc7', x.name)
def create_tag_object(name, head): """Create an annotated tag object from the given history. This rewrites a 'tag creation' history so that the head is a tag instead of a commit. This relies on the fact that in Subversion, tags are created using a 'svn cp' copy. Args: name: Name of the tag. head: Object ID of the head commit of a chain to be tagged. Returns: The object ID of an annotated tag object, or the value of 'head' if the tag could not be created. """ head_commit = gitrepo.get_object(head) # The tree of the commit should exactly match the tree of its parent. # If not, then is not a pure 'tagging' commit. if len(head_commit.parents) != 1: return head head_hat_commit = gitrepo.get_object(head_commit.parents[0]) if head_commit.tree != head_hat_commit.tree: return head tag = Tag() tag.name = name tag.message = head_commit.message tag.tag_time = head_commit.commit_time tag.tag_timezone = head_commit.commit_timezone tag.object = (Commit, head_hat_commit.id) tag.tagger = head_commit.committer gitrepo.object_store.add_object(tag) return tag.id
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_check_tag_with_overflow_time(self): """Date with overflow should raise an ObjectFormatException when checked """ author = 'Some Dude <*****@*****.**> %s +0000' % (MAX_TIME + 1, ) tag = Tag.from_string(self.make_tag_text(tagger=(author.encode()))) with self.assertRaises(ObjectFormatException): tag.check()
def test_parse_no_tagger(self): x = Tag() x.set_raw_string("""object a38d6181ff27824c79fc7df825164a212eff6a3f type commit tag v2.6.22-rc7 Linux 2.6.22-rc7 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql OK2XeQOiEeXtT76rV4t2WR4= =ivrA -----END PGP SIGNATURE----- """) self.assertEquals(None, x.tagger) self.assertEquals("v2.6.22-rc7", x.name)
def test_serialize_simple(self): x = Tag() x.tagger = "Jelmer Vernooij <*****@*****.**>" x.name = "0.1" x.message = "Tag 0.1" x.object = (3, "d80c186a03f423a81b39df39dc87fd269736ca86") x.tag_time = 423423423 x.tag_timezone = 0 self.assertEquals("""object d80c186a03f423a81b39df39dc87fd269736ca86 type blob tag 0.1 tagger Jelmer Vernooij <*****@*****.**> 423423423 +0000 Tag 0.1""", x.as_raw_string())
def tag_create( repo, tag, author=None, message=None, annotated=False, objectish="HEAD", tag_time=None, tag_timezone=None, sign=False): """Creates a tag in git via dulwich calls: :param repo: Path to repository :param tag: tag string :param author: tag author (optional, if annotated is set) :param message: tag message (optional) :param annotated: whether to create an annotated tag :param objectish: object the tag should point at, defaults to HEAD :param tag_time: Optional time for annotated tag :param tag_timezone: Optional timezone for annotated tag :param sign: GPG Sign the tag """ with open_repo_closing(repo) as r: object = parse_object(r, objectish) if annotated: # Create the tag object tag_obj = Tag() if author is None: # TODO(jelmer): Don't use repo private method. author = r._get_user_identity(r.get_config_stack()) tag_obj.tagger = author tag_obj.message = message tag_obj.name = tag tag_obj.object = (type(object), object.id) if tag_time is None: tag_time = int(time.time()) tag_obj.tag_time = tag_time if tag_timezone is None: # TODO(jelmer) Use current user timezone rather than UTC tag_timezone = 0 elif isinstance(tag_timezone, str): tag_timezone = parse_timezone(tag_timezone) tag_obj.tag_timezone = tag_timezone if sign: import gpg with gpg.Context(armor=True) as c: tag_obj.signature, unused_result = c.sign( tag_obj.as_raw_string()) r.object_store.add_object(tag_obj) tag_id = tag_obj.id else: tag_id = object.id r.refs[_make_tag_ref(tag)] = tag_id
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 test_parse_ctime(self): x = Tag() x.set_raw_string("""object a38d6181ff27824c79fc7df825164a212eff6a3f type commit tag v2.6.22-rc7 tagger Linus Torvalds <*****@*****.**> Sun Jul 1 12:54:34 2007 -0700 Linux 2.6.22-rc7 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql OK2XeQOiEeXtT76rV4t2WR4= =ivrA -----END PGP SIGNATURE----- """) self.assertEquals("Linus Torvalds <*****@*****.**>", x.tagger) self.assertEquals("v2.6.22-rc7", x.name)
def test_check_tag_with_overflow_time(self): """Date with overflow should raise an ObjectFormatException when checked """ author = 'Some Dude <*****@*****.**> %s +0000' % (MAX_TIME+1, ) tag = Tag.from_string(self.make_tag_text( tagger=(author.encode()))) with self.assertRaises(ObjectFormatException): tag.check()
def add_tag(self, tag_name): commit = self._repo['refs/heads/master'] tag = Tag() tag.name = tag_name tag.message = 'Tagged %s as %s' % (commit.id, tag_name) tag.tagger = self._author tag.object = (Commit, commit.id) tag.tag_time = int(time()) tag.tag_timezone = self._time_zone self._update_store(tag) self._repo.refs['refs/tags/%s' % tag_name] = tag.id
def do_import(commits, repo_loc, overwrite = True, author_="Règlement général <*****@*****.**>"): if exists(repo_loc): if overwrite: print("Deleting existing output directory: %s" % repo_loc) shutil.rmtree(repo_loc) os.mkdir(repo_loc) repo = Repo.init(repo_loc) else: repo = Repo(repo_loc) else: os.mkdir(repo_loc) repo = Repo.init(repo_loc) print("Importing %d commit(s)" % len(commits)) for i, commit in enumerate(commits): date = commit[0] print("Commit %d dated %s, %d items" % (i, str(date), len(commit[1]))) print(" authored by %s" % author_) paths_added, paths_removed = create_tree(commit, repo_loc, readme=False, main=commit[2] if len(commit) == 3 else {}) repo.stage([path.encode(sys.getfilesystemencoding()) for path in set(paths_added)]) index = repo.open_index() print(" Removing %d files" % len(paths_removed)) for p in paths_removed: del index[p.encode(sys.getfilesystemencoding())] index.write() author = bytes(author_, "UTF-8") repo.do_commit( bytes("Version du %s" % date.strftime(FMT), "UTF-8"), committer=author, commit_timestamp=date.timestamp(), commit_timezone=int(TZ_PARIS.localize(date).strftime("%z")) * 36) ## create tag tag_name = bytes(date.strftime(ISO_8601), "UTF-8") object = parse_object(repo, "HEAD") tag = Tag() tag.tagger = author tag.name = tag_name tag.message = b'' tag.object = (type(object), object.id) tag.tag_time = int(time.time()) tag.tag_timezone = int(TZ_PARIS.localize(date).strftime("%z")) * 36 repo.object_store.add_object(tag) tag_id = tag.id repo.refs[b'refs/tags/' + tag_name] = tag_id repo.close()
def add_tag(self, tag_name): commit = self._repo['refs/heads/master'] tag = Tag() tag.name = tag_name tag.message = 'Tagged %s as %s' % (commit.id, tag_name) tag.tagger = self._author tag.object = (Commit, commit.id) tag.tag_time = int(time()) tag.tag_timezone = self._time_zone self._update_store(tag) self.refs['refs/tags/%s' % tag_name] = tag.id
def tag_create(repo, tag, author=None, message=None, annotated=False, objectish="HEAD", tag_time=None, tag_timezone=None): """Creates a tag in git via dulwich calls: :param repo: Path to repository :param tag: tag string :param author: tag author (optional, if annotated is set) :param message: tag message (optional) :param annotated: whether to create an annotated tag :param objectish: object the tag should point at, defaults to HEAD :param tag_time: Optional time for annotated tag :param tag_timezone: Optional timezone for annotated tag """ with open_repo_closing(repo) as r: object = parse_object(r, objectish) if annotated: # Create the tag object tag_obj = Tag() if author is None: # TODO(jelmer): Don't use repo private method. author = r._get_user_identity() tag_obj.tagger = author tag_obj.message = message tag_obj.name = tag tag_obj.object = (type(object), object.id) tag_obj.tag_time = tag_time if tag_time is None: tag_time = int(time.time()) if tag_timezone is None: # TODO(jelmer) Use current user timezone rather than UTC tag_timezone = 0 elif isinstance(tag_timezone, str): tag_timezone = parse_timezone(tag_timezone) tag_obj.tag_timezone = tag_timezone r.object_store.add_object(tag_obj) tag_id = tag_obj.id else: tag_id = object.id r.refs[b'refs/tags/' + tag] = tag_id
def test_tag_annotated(self): reva = self.simple_commit_a() o = Tag() o.name = b"foo" o.tagger = b"Jelmer <*****@*****.**>" o.message = b"add tag" o.object = (Commit, reva) o.tag_timezone = 0 o.tag_time = 42 r = GitRepo(".") r.object_store.add_object(o) r[b'refs/tags/foo'] = o.id thebranch = Branch.open('.') self.assertEqual( {"foo": default_mapping.revision_id_foreign_to_bzr(reva)}, thebranch.tags.get_tag_dict())
def _dulwich_tag(self, tag, author, message=None): """ Creates a tag in git via dulwich calls: **tag** - string :: "<project>-[start|sync]-<timestamp>" **author** - string :: "Your Name <*****@*****.**>" """ if not message: message = tag # Open the repo _repo = Repo(self.config['top_dir']) master_branch = 'master' # Build the commit object blob = Blob.from_string("empty") tree = Tree() tree.add(tag, 0100644, blob.id) commit = Commit() commit.tree = tree.id commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time()) tz = parse_timezone('-0200')[0] commit.commit_timezone = commit.author_timezone = tz commit.encoding = "UTF-8" commit.message = 'Tagging repo for deploy: ' + message # Add objects to the repo store instance 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_branch] = commit.id # Build the tag object and tag tag = Tag() tag.tagger = author tag.message = message tag.name = tag tag.object = (Commit, commit.id) tag.tag_time = commit.author_time tag.tag_timezone = tz object_store.add_object(tag) _repo['refs/tags/' + tag] = tag.id
def test_tagged_tree(self): r = self.make_git_repo("d") os.chdir("d") bb = GitBranchBuilder() bb.set_file("foobar", b"fooll\nbar\n", False) mark = bb.commit(b"Somebody <*****@*****.**>", b"nextmsg") marks = bb.finish() gitsha = marks[mark] tag = Tag() tag.name = b"sometag" tag.tag_time = int(time.time()) tag.tag_timezone = 0 tag.tagger = b"Somebody <*****@*****.**>" tag.message = b"Created tag pointed at tree" tag.object = (Tree, r[gitsha].tree) r.object_store.add_object(tag) r[b"refs/tags/sometag"] = tag os.chdir("..") oldrepo = self.open_git_repo("d") revid = oldrepo.get_mapping().revision_id_foreign_to_bzr(gitsha) newrepo = self.clone_git_repo("d", "f") self.assertEqual(set([revid]), set(newrepo.all_revision_ids()))
def tag_create( repo, tag, author=None, message=None, annotated=False, objectish="HEAD", tag_time=None, tag_timezone=None ): """Creates a tag in git via dulwich calls: :param repo: Path to repository :param tag: tag string :param author: tag author (optional, if annotated is set) :param message: tag message (optional) :param annotated: whether to create an annotated tag :param objectish: object the tag should point at, defaults to HEAD :param tag_time: Optional time for annotated tag :param tag_timezone: Optional timezone for annotated tag """ with open_repo_closing(repo) as r: object = parse_object(r, objectish) if annotated: # Create the tag object tag_obj = Tag() if author is None: # TODO(jelmer): Don't use repo private method. author = r._get_user_identity() tag_obj.tagger = author tag_obj.message = message tag_obj.name = tag tag_obj.object = (type(object), object.id) tag_obj.tag_time = tag_time if tag_time is None: tag_time = int(time.time()) if tag_timezone is None: # TODO(jelmer) Use current user timezone rather than UTC tag_timezone = 0 elif isinstance(tag_timezone, str): tag_timezone = parse_timezone(tag_timezone) tag_obj.tag_timezone = tag_timezone r.object_store.add_object(tag_obj) tag_id = tag_obj.id else: tag_id = object.id r.refs[b"refs/tags/" + tag] = tag_id
def tag(repo, tag, author, message): """Creates a tag in git via dulwich calls: :param repo: Path to repository :param tag: tag string :param author: tag author :param repo: tag message """ r = open_repo(repo) # Create the tag object tag_obj = Tag() tag_obj.tagger = author tag_obj.message = message tag_obj.name = tag tag_obj.object = (Commit, r.refs['HEAD']) tag_obj.tag_time = int(time.time()) tag_obj.tag_timezone = parse_timezone('-0200')[0] # Add tag to the object store r.object_store.add_object(tag_obj) r.refs['refs/tags/' + tag] = tag_obj.id
def _dulwich_tag(self, tag, author, message=DEFAULT_TAG_MSG): """ Creates a tag in git via dulwich calls: Parameters: tag - string :: "<project>-[start|sync]-<timestamp>" author - string :: "Your Name <*****@*****.**>" """ # Open the repo _repo = Repo(self.config['top_dir']) # Create the tag object tag_obj = Tag() tag_obj.tagger = author tag_obj.message = message tag_obj.name = tag tag_obj.object = (Commit, _repo.refs['HEAD']) tag_obj.tag_time = int(time()) tag_obj.tag_timezone = parse_timezone('-0200')[0] # Add tag to the object store _repo.object_store.add_object(tag_obj) _repo['refs/tags/' + tag] = tag_obj.id
commit_id = repo.do_commit("first commit") commit = repo.get_object(commit_id) print commit # get tree corresponding to the head commit # tree_id = repo["HEAD"].tree # print tree_id object_store = repo.object_store tags = repo.refs.subkeys("refs/tags") print tags tz = parse_timezone('-0200')[0] tag_message = "Tag Annotation" tag = Tag() tag.tagger = author tag.message = "message" tag.name = "v0.1" tag.object = (Commit, commit.id) tag.tag_time = commit.author_time tag.tag_timezone = tz object_store.add_object(tag) repo['refs/tags/HI'] = tag.id tags = repo.refs.subkeys("refs/tags") print tags
def test_parse_no_tagger(self): x = Tag() x.set_raw_string(self.make_tag_text(tagger=None)) self.assertEquals(None, x.tagger) self.assertEquals("v2.6.22-rc7", x.name)
def export_commit(self, rev, tree_sha, parent_lookup, lossy, verifiers): """Turn a Bazaar revision in to a Git commit :param tree_sha: Tree sha for the commit :param parent_lookup: Function for looking up the GIT sha equiv of a bzr revision :param lossy: Whether to store roundtripping information. :param verifiers: Verifiers info :return dulwich.objects.Commit represent the revision: """ from dulwich.objects import Commit, Tag commit = Commit() commit.tree = tree_sha if not lossy: metadata = CommitSupplement() metadata.verifiers = verifiers else: metadata = None parents = [] for p in rev.parent_ids: try: git_p = parent_lookup(p) except KeyError: git_p = None if metadata is not None: metadata.explicit_parent_ids = rev.parent_ids if git_p is not None: if len(git_p) != 40: raise AssertionError("unexpected length for %r" % git_p) parents.append(git_p) commit.parents = parents try: encoding = rev.properties[u'git-explicit-encoding'] except KeyError: encoding = rev.properties.get(u'git-implicit-encoding', 'utf-8') try: commit.encoding = rev.properties[u'git-explicit-encoding'].encode( 'ascii') except KeyError: pass commit.committer = fix_person_identifier(rev.committer.encode( encoding)) commit.author = fix_person_identifier( rev.get_apparent_authors()[0].encode(encoding)) # TODO(jelmer): Don't use this hack. long = getattr(__builtins__, 'long', int) commit.commit_time = long(rev.timestamp) if u'author-timestamp' in rev.properties: commit.author_time = long(rev.properties[u'author-timestamp']) else: commit.author_time = commit.commit_time commit._commit_timezone_neg_utc = ( u"commit-timezone-neg-utc" in rev.properties) commit.commit_timezone = rev.timezone commit._author_timezone_neg_utc = ( u"author-timezone-neg-utc" in rev.properties) if u'author-timezone' in rev.properties: commit.author_timezone = int(rev.properties[u'author-timezone']) else: commit.author_timezone = commit.commit_timezone if u'git-gpg-signature' in rev.properties: commit.gpgsig = rev.properties[u'git-gpg-signature'].encode( 'utf-8', 'surrogateescape') commit.message = self._encode_commit_message(rev, rev.message, encoding) if not isinstance(commit.message, bytes): raise TypeError(commit.message) if metadata is not None: try: mapping_registry.parse_revision_id(rev.revision_id) except errors.InvalidRevisionId: metadata.revision_id = rev.revision_id mapping_properties = set( [u'author', u'author-timezone', u'author-timezone-neg-utc', u'commit-timezone-neg-utc', u'git-implicit-encoding', u'git-gpg-signature', u'git-explicit-encoding', u'author-timestamp', u'file-modes']) for k, v in rev.properties.items(): if k not in mapping_properties: metadata.properties[k] = v if not lossy and metadata: if self.roundtripping: commit.message = inject_bzr_metadata(commit.message, metadata, encoding) else: raise NoPushSupport( None, None, self, revision_id=rev.revision_id) if not isinstance(commit.message, bytes): raise TypeError(commit.message) i = 0 propname = u'git-mergetag-0' while propname in rev.properties: commit.mergetag.append(Tag.from_string(rev.properties[propname])) i += 1 propname = u'git-mergetag-%d' % i if u'git-extra' in rev.properties: commit.extra.extend( [l.split(b' ', 1) for l in rev.properties[u'git-extra'].splitlines()]) return commit
def test_parse_no_tagger(self): x = Tag() x.set_raw_string(self.make_tag_text(tagger=None)) self.assertEqual(None, x.tagger) self.assertEqual("v2.6.22-rc7", x.name)