Example #1
0
    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
        c = Commit()
        if tree is None:
            index = self.open_index()
            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
        try:
            old_head = self.refs["HEAD"]
            c.parents = [old_head]
            self.object_store.add_object(c)
            ok = self.refs.set_if_equals("HEAD", old_head, c.id)
        except KeyError:
            c.parents = []
            self.object_store.add_object(c)
            ok = self.refs.add_if_new("HEAD", c.id)
        if not ok:
            # Fail if the atomic compare-and-swap failed, leaving the commit and
            # all its objects as garbage.
            raise CommitError("HEAD changed during commit")

        return c.id
Example #2
0
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 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
Example #4
0
    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
Example #5
0
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
Example #6
0
    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)
Example #7
0
File: repo.py Project: 198d/clask
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
Example #8
0
    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 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
Example #10
0
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
Example #11
0
def create_commit(metadata, parents, tree_id):
	"""Create a new Git commit object, and add it to the object store.

	Args:
	  metadata: Dictionary containing metadata to construct the commit,
	      including commit message and author data.
	  parents: The parents of this commit.
	  tree: The tree of files to use for this commit.
	Returns:
	  New commit object.
	"""
	commit = Commit()
	commit.tree = tree_id
	commit.author = "%s <%s>" % (metadata["GIT_AUTHOR_NAME"],
	                             metadata["GIT_AUTHOR_EMAIL"])
	commit.author_time = \
	    utc_time_from_string(metadata["GIT_AUTHOR_DATE"])
	commit.author_timezone = 0

	commit.committer = "%s <%s>" % (metadata["GIT_COMMITTER_NAME"],
	                                metadata["GIT_COMMITTER_EMAIL"])
	commit.commit_time = \
	    utc_time_from_string(metadata["GIT_COMMITTER_DATE"])
	commit.commit_timezone = 0

	commit.encoding = "UTF-8"
	commit.message = metadata["MESSAGE"]
	commit.parents = parents
	gitrepo.object_store.add_object(commit)

	return commit
Example #12
0
 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
Example #13
0
 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_:
         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:
                 assert filecmd.dataref.startswith(b":"), \
                        ("non-marker refs not supported yet (%r)" %
                         filecmd.dataref)
                 blob_id = self.markers[filecmd.dataref[1:]]
             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:
         if merge.startswith(b':'):
             merge = self.markers[merge[1:]]
         commit.parents.append(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
Example #14
0
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
Example #15
0
File: db.py Project: mbr/qwapp
	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
Example #16
0
 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()
Example #17
0
    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)
Example #18
0
    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)
Example #19
0
File: db.py Project: mbr/qwapp
	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
Example #20
0
def create_commit(metadata, parents, tree_id):
    """Create a new Git commit object, and add it to the object store.

	Args:
	  metadata: Dictionary containing metadata to construct the commit,
	      including commit message and author data.
	  parents: The parents of this commit.
	  tree: The tree of files to use for this commit.
	Returns:
	  New commit object.
	"""
    commit = Commit()
    commit.tree = tree_id
    commit.author = "%s <%s>" % (metadata["GIT_AUTHOR_NAME"],
                                 metadata["GIT_AUTHOR_EMAIL"])
    commit.author_time = \
        utc_time_from_string(metadata["GIT_AUTHOR_DATE"])
    commit.author_timezone = 0

    commit.committer = "%s <%s>" % (metadata["GIT_COMMITTER_NAME"],
                                    metadata["GIT_COMMITTER_EMAIL"])
    commit.commit_time = \
        utc_time_from_string(metadata["GIT_COMMITTER_DATE"])
    commit.commit_timezone = 0

    commit.encoding = "UTF-8"
    commit.message = metadata["MESSAGE"]
    commit.parents = parents
    gitrepo.object_store.add_object(commit)

    return commit
Example #21
0
    def export_hg_commit(self, rev):
        self.ui.note(_("converting revision %s\n") % hex(rev))

        oldenc = self.swap_out_encoding()

        ctx = self.repo.changectx(rev)
        extra = ctx.extra()

        commit = Commit()

        (time, timezone) = ctx.date()
        commit.author = self.get_git_author(ctx)
        commit.author_time = int(time)
        commit.author_timezone = -timezone

        if 'committer' in extra:
            # fixup timezone
            (name, timestamp, timezone) = extra['committer'].rsplit(' ', 2)
            commit.committer = name
            commit.commit_time = timestamp

            # work around a timezone format change
            if int(timezone) % 60 != 0: #pragma: no cover
                timezone = parse_timezone(timezone)
                # Newer versions of Dulwich return a tuple here
                if isinstance(timezone, tuple):
                    timezone, neg_utc = timezone
                    commit._commit_timezone_neg_utc = neg_utc
            else:
                timezone = -int(timezone)
            commit.commit_timezone = timezone
        else:
            commit.committer = commit.author
            commit.commit_time = commit.author_time
            commit.commit_timezone = commit.author_timezone

        commit.parents = []
        for parent in self.get_git_parents(ctx):
            hgsha = hex(parent.node())
            git_sha = self.map_git_get(hgsha)
            if git_sha:
                commit.parents.append(git_sha)

        commit.message = self.get_git_message(ctx)

        if 'encoding' in extra:
            commit.encoding = extra['encoding']

        tree_sha = commit_tree(self.git.object_store, self.iterblobs(ctx))
        commit.tree = tree_sha

        self.git.object_store.add_object(commit)
        self.map_set(commit.id, ctx.hex())

        self.swap_out_encoding(oldenc)
        return commit.id
Example #22
0
    def export_hg_commit(self, rev):
        self.ui.note(_("converting revision %s\n") % hex(rev))

        oldenc = self.swap_out_encoding()

        ctx = self.repo.changectx(rev)
        extra = ctx.extra()

        commit = Commit()

        (time, timezone) = ctx.date()
        commit.author = self.get_git_author(ctx)
        commit.author_time = int(time)
        commit.author_timezone = -timezone

        if 'committer' in extra:
            # fixup timezone
            (name, timestamp, timezone) = extra['committer'].rsplit(' ', 2)
            commit.committer = name
            commit.commit_time = timestamp

            # work around a timezone format change
            if int(timezone) % 60 != 0: #pragma: no cover
                timezone = parse_timezone(timezone)
                # Newer versions of Dulwich return a tuple here
                if isinstance(timezone, tuple):
                    timezone, neg_utc = timezone
                    commit._commit_timezone_neg_utc = neg_utc
            else:
                timezone = -int(timezone)
            commit.commit_timezone = timezone
        else:
            commit.committer = commit.author
            commit.commit_time = commit.author_time
            commit.commit_timezone = commit.author_timezone

        commit.parents = []
        for parent in self.get_git_parents(ctx):
            hgsha = hex(parent.node())
            git_sha = self.map_git_get(hgsha)
            if git_sha:
                commit.parents.append(git_sha)

        commit.message = self.get_git_message(ctx)

        if 'encoding' in extra:
            commit.encoding = extra['encoding']

        tree_sha = commit_tree(self.git.object_store, self.iterblobs(ctx))
        commit.tree = tree_sha

        self.git.object_store.add_object(commit)
        self.map_set(commit.id, ctx.hex())

        self.swap_out_encoding(oldenc)
        return commit.id
Example #23
0
 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
Example #24
0
 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
Example #25
0
 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
Example #26
0
 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
Example #27
0
    def commit(self):
        # XXX: evidence for the rest of
        # this functions is supposed not to exist
        # yes, its that
        # XXX: generate all objects at once and
        #     add them as pack instead of legacy objects
        r = self.repo.repo
        store = r.object_store
        new_objects = []
        names = sorted(self.contents)
        nametree = defaultdict(list)
        for name in names:
            base = name.strip('/')
            while base:
                nbase = os.path.dirname(base)
                nametree[nbase].append(base)
                base = nbase

        if self.base_commit:
            tree = r.tree(self.base_commit.commit.tree)
            tree._ensure_parsed()
            print tree._entries
        else:
            tree = Tree()

        for src, dest in self.renames:
            src = src.strip('/')
            dest = dest.strip('/')
            tree[dest] = tree[src]
            del tree[src]

        for name in names:
            blob = Blob()
            blob.data = self.contents[name]
            new_objects.append((blob, name))
            tree.add(0555, os.path.basename(name), blob.id)

        new_objects.append((tree, ''))
        commit = Commit()
        if self.base_commit:
            commit.parents = [self.base_commit.commit.id]
        commit.tree = tree.id
        commit.message = self.extra['message']
        commit.committer = self.author
        commit.commit_time = int(self.time_unix)
        commit.commit_timezone = self.time_offset
        commit.author = self.author
        commit.author_time = int(self.time_unix)
        commit.author_timezone = self.time_offset
        new_objects.append((commit, ''))
        store.add_objects(new_objects)
        self.repo.repo.refs['HEAD'] = commit.id
Example #28
0
 def commit(self, message):
     self._validate_unicode_text(message, 'commit message')
     c = Commit()
     c.parents = [
         self.repository.lookup_bzr_revision_id(revid)[0]
         for revid in self.parents
     ]
     c.tree = commit_tree(self.store, self._iterblobs())
     encoding = self._revprops.pop(u'git-explicit-encoding', 'utf-8')
     c.encoding = encoding.encode('ascii')
     c.committer = fix_person_identifier(self._committer.encode(encoding))
     try:
         author = self._revprops.pop('author')
     except KeyError:
         try:
             authors = self._revprops.pop('authors').splitlines()
         except KeyError:
             author = self._committer
         else:
             if len(authors) > 1:
                 raise Exception("Unable to convert multiple authors")
             elif len(authors) == 0:
                 author = self._committer
             else:
                 author = authors[0]
     c.author = fix_person_identifier(author.encode(encoding))
     bugstext = self._revprops.pop('bugs', None)
     if bugstext is not None:
         message += "\n"
         for url, status in bugtracker.decode_bug_urls(bugstext):
             if status == bugtracker.FIXED:
                 message += "Fixes: %s\n" % url
             elif status == bugtracker.RELATED:
                 message += "Bug: %s\n" % url
             else:
                 raise bugtracker.InvalidBugStatus(status)
     if self._revprops:
         raise NotImplementedError(self._revprops)
     c.commit_time = int(self._timestamp)
     c.author_time = int(self._timestamp)
     c.commit_timezone = self._timezone
     c.author_timezone = self._timezone
     c.message = message.encode(encoding)
     if (self._config_stack.get('create_signatures') ==
             _mod_config.SIGN_ALWAYS):
         strategy = gpg.GPGStrategy(self._config_stack)
         c.gpgsig = strategy.sign(c.as_raw_string(), gpg.MODE_DETACH)
     self.store.add_object(c)
     self.repository.commit_write_group()
     self._new_revision_id = self._mapping.revision_id_foreign_to_bzr(c.id)
     return self._new_revision_id
Example #29
0
def do_commit():
	global droid, localrepo, repo
	if localrepo==None:
		droid.makeToast("Set local repository first!")
	else:
 		object_store = repo.object_store
 		progress_to_log()
		if repo["refs/heads/master"] == None:
			tree = Tree()
		else:
			tree = object_store[repo["refs/heads/master"].tree]
		if do_tree_for_commit(tree):
			object_store.add_object(tree)
			commit = Commit()
			commit.tree = tree.id
			if repo.refs["refs/heads/master"] == None:
				commit.parents = []
				def_comment = "Initial commit"
			else:
				commit.parents = [repo.refs["refs/heads/master"]]
				def_comment = ""
			name = droid.fullQueryDetail("editName").result["text"]
			email = droid.fullQueryDetail("editEmail").result["text"]
			author = name + " <" + email + ">"
			commit.author = commit.committer = author
			commit.commit_time = commit.author_time = int(time())
			tz = parse_timezone('+0000')[0]
			commit.commit_timezone = commit.author_timezone = tz
			commit.encoding = "UTF-8"
			commit.message = showinput("Message", "Enter commit message", def_comment)
			if commit.message:
				object_store.add_object(commit)
				repo.refs['refs/heads/master'] = commit.id
			else:
				droid.makeToast("Commit cancelled.")
 		else:
 			droid.makeToast("Nothing to commit.")
Example #30
0
    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
Example #31
0
    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
Example #32
0
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
Example #33
0
def make_commit(repo, tree_id, message):
    """Build a commit object on the same pattern. Only changing values are
    required as parameters.
    """
    commit = Commit()
    try:
        commit.parents = [repo.head()]
    except KeyError:
        # The initial commit has no parent
        pass
    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 = TZ
    commit.encoding = ENCODING
    return commit
Example #34
0
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
Example #35
0
File: git.py Project: mbr/unleash
    def to_commit(self):
        new_commit = Commit()
        new_commit.parents = self.parent_ids

        new_commit.tree = self.tree.id
        new_commit.author = self.author
        new_commit.committer = self.committer

        new_commit.author_time = self.author_time
        new_commit.commit_time = self.commit_time

        new_commit.commit_timezone = self.commit_timezone
        new_commit.author_timezone = self.author_timezone

        new_commit.encoding = self.encoding
        new_commit.message = self.message.encode(self.encoding)

        return new_commit
Example #36
0
    def test_send_pack_new_ref(self):
        self.rin.write(
            '0064310ca9477129b8586fa2afc779c1f57cf64bba6c '
            'refs/heads/master\x00 report-status delete-refs ofs-delta\n'
            '0000000eunpack ok\n'
            '0019ok refs/heads/blah12\n'
            '0000')
        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/heads/blah12': commit.id,
                'refs/heads/master': '310ca9477129b8586fa2afc779c1f57cf64bba6c'
            }

        def generate_pack_contents(have, want):
            return [
                (commit, None),
                (tree, ''),
            ]

        f = BytesIO()
        write_pack_objects(f, generate_pack_contents(None, None))
        self.client.send_pack('/', determine_wants, generate_pack_contents)
        self.assertIn(self.rout.getvalue(), [
            '007f0000000000000000000000000000000000000000 %s '
            'refs/heads/blah12\x00report-status ofs-delta0000%s' %
            (commit.id, f.getvalue()),
            '007f0000000000000000000000000000000000000000 %s '
            'refs/heads/blah12\x00ofs-delta report-status0000%s' %
            (commit.id, f.getvalue())
        ])
Example #37
0
    def test_send_pack_new_ref(self):
        self.rin.write(
            b'0064310ca9477129b8586fa2afc779c1f57cf64bba6c '
            b'refs/heads/master\x00 report-status delete-refs ofs-delta\n'
            b'0000000eunpack ok\n'
            b'0019ok refs/heads/blah12\n'
            b'0000')
        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/heads/blah12': commit.id,
                b'refs/heads/master':
                b'310ca9477129b8586fa2afc779c1f57cf64bba6c'
            }

        def generate_pack_data(have, want, ofs_delta=False):
            return pack_objects_to_data([
                (commit, None),
                (tree, b''),
            ])

        f = BytesIO()
        write_pack_data(f, *generate_pack_data(None, None))
        self.client.send_pack(b'/', update_refs, generate_pack_data)
        self.assertIn(self.rout.getvalue(), [
            b'007f0000000000000000000000000000000000000000 ' + commit.id +
            b' refs/heads/blah12\x00report-status ofs-delta0000' +
            f.getvalue(), b'007f0000000000000000000000000000000000000000 ' +
            commit.id + b' refs/heads/blah12\x00ofs-delta report-status0000' +
            f.getvalue()
        ])
Example #38
0
    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
Example #39
0
    def test_send_pack_new_ref(self):
        self.rin.write(
            b'0064310ca9477129b8586fa2afc779c1f57cf64bba6c '
            b'refs/heads/master\x00 report-status delete-refs ofs-delta\n'
            b'0000000eunpack ok\n'
            b'0019ok refs/heads/blah12\n'
            b'0000')
        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/heads/blah12': commit.id,
                b'refs/heads/master':
                    b'310ca9477129b8586fa2afc779c1f57cf64bba6c'
            }

        def generate_pack_data(have, want, ofs_delta=False):
            return pack_objects_to_data([(commit, None), (tree, b''), ])

        f = BytesIO()
        write_pack_data(f, *generate_pack_data(None, None))
        self.client.send_pack(b'/', determine_wants, generate_pack_data)
        self.assertIn(
            self.rout.getvalue(),
            [b'007f0000000000000000000000000000000000000000 ' + commit.id +
             b' refs/heads/blah12\x00report-status ofs-delta0000' +
             f.getvalue(),
             b'007f0000000000000000000000000000000000000000 ' + commit.id +
             b' refs/heads/blah12\x00ofs-delta report-status0000' +
             f.getvalue()])
Example #40
0
    def new(self, repo):
        """
        Create a new version of a repo.Local object.

        :param repo: Instance of repo.Local.

        :return: New Version instance.
        """
        #TODO: subclass Commit, pass parent as init param
        try:
            # create new commit instance and set metadata
            commit = Commit()
            author = os.environ.get('USER')
            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 = ''

            # set previous version as parent to this one
            parent = repo.versions(-1)
            if parent:
                commit.parents = [parent.id]

            # create new tree, add entries from previous version
            tree = Tree()
            curr = repo.versions(-1)
            if curr:
                for item in curr.items():
                    tree.addItem(item)
            commit.tree = tree.id

            # create new version, and add tree
            version = Version(repo=repo, commit=commit, tree=tree)
            return version

        except Exception, e:
            traceback.print_exc()
            return VersionError(e)
Example #41
0
    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
Example #42
0
    def test_send_pack_new_ref(self):
        self.rin.write(
            '0064310ca9477129b8586fa2afc779c1f57cf64bba6c '
            'refs/heads/master\x00 report-status delete-refs ofs-delta\n'
            '0000000eunpack ok\n'
            '0019ok refs/heads/blah12\n'
            '0000')
        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/heads/blah12': commit.id,
                'refs/heads/master': '310ca9477129b8586fa2afc779c1f57cf64bba6c'
            }

        def generate_pack_contents(have, want):
            return [(commit, None), (tree, ''), ]

        f = BytesIO()
        write_pack_objects(f, generate_pack_contents(None, None))
        self.client.send_pack('/', determine_wants, generate_pack_contents)
        self.assertIn(
            self.rout.getvalue(),
            ['007f0000000000000000000000000000000000000000 %s '
             'refs/heads/blah12\x00report-status ofs-delta0000%s'
             % (commit.id, f.getvalue()),
             '007f0000000000000000000000000000000000000000 %s '
             'refs/heads/blah12\x00ofs-delta report-status0000%s'
             % (commit.id, f.getvalue())])
Example #43
0
    def write(self, data):
        commit = Commit()

        # commit metadata
        author = b"tinydb"
        commit.author = commit.committer = author
        commit.commit_time = commit.author_time = int(time.time())
        tz = time.timezone if (time.localtime().tm_isdst) else time.altzone
        commit.commit_timezone = commit.author_timezone = tz
        commit.encoding = b'UTF-8'
        commit.message = (
            'Updated by tinydb-git {}'.format(__version__).encode('utf8'))

        # prepare blob
        blob = Blob.from_string(self._serialize(data))

        try:
            parent_commit = self.repo[self._refname]
        except KeyError:
            # branch does not exist, start with an empty tree
            tree = Tree()
        else:
            commit.parents = [parent_commit.id]
            tree = self.repo[parent_commit.tree]

        # no subdirs in filename, add directly to tree
        tree.add(self.filename, 0o100644, blob.id)

        commit.tree = tree.id

        # add objects
        self.repo.object_store.add_object(blob)
        self.repo.object_store.add_object(tree)
        self.repo.object_store.add_object(commit)

        # update refs
        self.repo.refs[self._refname] = commit.id
Example #44
0
    def write(self, data):
        commit = Commit()

        # commit metadata
        author = b"tinydb"
        commit.author = commit.committer = author
        commit.commit_time = commit.author_time = int(time.time())
        tz = time.timezone if (time.localtime().tm_isdst) else time.altzone
        commit.commit_timezone = commit.author_timezone = tz
        commit.encoding = b'UTF-8'
        commit.message = ('Updated by tinydb-git {}'.format(__version__)
                          .encode('utf8'))

        # prepare blob
        blob = Blob.from_string(self._serialize(data))

        try:
            parent_commit = self.repo[self._refname]
        except KeyError:
            # branch does not exist, start with an empty tree
            tree = Tree()
        else:
            commit.parents = [parent_commit.id]
            tree = self.repo[parent_commit.tree]

        # no subdirs in filename, add directly to tree
        tree.add(self.filename, 0o100644, blob.id)

        commit.tree = tree.id

        # add objects
        self.repo.object_store.add_object(blob)
        self.repo.object_store.add_object(tree)
        self.repo.object_store.add_object(commit)

        # update refs
        self.repo.refs[self._refname] = commit.id
Example #45
0
    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 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
Example #47
0
File: todo.py Project: mbr/git-todo
    def create_todo_commit(self, text, message, author_name, author_email,
                           parent_id=None):
        author = '{} <{}>'.format(author_name, author_email).encode('utf8')

        # create TODO branch
        blob = Blob.from_string(text.encode('utf8'))
        tree = Tree()
        tree.add(b'TODO', 0o100644, blob.id)

        commit = Commit()
        commit.tree = tree.id
        commit.message = message.encode('utf8')
        commit.encoding = 'UTF-8'

        if parent_id:
            commit.parents = [parent_id]

        tz = arrow.now().utcoffset().seconds
        commit.author = commit.committer = author
        commit.author_time = commit.commit_time = int(time())
        commit.commit_timezone = commit.author_timezone = tz

        # add objects to repo
        return commit, tree, blob
Example #48
0
    def commit(self, message, author=None):
        commit = Commit()
        commit.tree = self.tree.id
        if author is None:
            config = self.repo.get_config_stack()
            author = self.repo._get_user_identity(config)
        else:
            author = author.encode(self.encoding)
        commit.author = commit.committer = author
        commit.commit_time = commit.author_time = int(time())
        tz = timezone
        commit.commit_timezone = commit.author_timezone = tz
        commit.message = message.encode(self.encoding)
        commit.encoding = self.encoding.encode('ascii')
        if self.org_commit_id:
            commit.parents = [self.org_commit_id]

        commit_id = commit.id
        self.changed_objects[commit_id] = commit
        self.repo.object_store.add_objects([
            (obj, None) for obj in self.changed_objects.values()
        ])
        self.repo.refs.set_if_equals(self.branch, self.org_commit_id,
                                     commit_id)

        if hasattr(self.repo, 'has_index') and self.repo.has_index():
            # Apply patch to working tree.
            try:
                subprocess.call(
                    ['git', 'cherry-pick', commit_id, '--no-commit'],
                    cwd=self.repo.path)
            except Exception:
                logging.getLogger(__name__).exception(
                    'Error updating working tree:')

        self.reset()
Example #49
0
    def export_hg_commit(self, rev, exporter):
        self.ui.note(_("converting revision %s\n") % hex_(rev))

        oldenc = self.swap_out_encoding()

        ctx = self.repo.changectx(rev)
        extra = ctx.extra()

        commit = Commit()

        (time, timezone) = ctx.date()
        # work around to bad timezone offets - dulwich does not handle
        # sub minute based timezones. In the one known case, it was a
        # manual edit that led to the unusual value. Based on that,
        # there is no reason to round one way or the other, so do the
        # simplest and round down.
        timezone -= (timezone % 60)
        commit.author = self.get_git_author(ctx)
        commit.author_time = int(time)
        commit.author_timezone = -timezone

        if 'committer' in extra:
            # fixup timezone
            (name, timestamp, timezone) = extra['committer'].rsplit(' ', 2)
            commit.committer = name
            commit.commit_time = timestamp

            # work around a timezone format change
            if int(timezone) % 60 != 0:  #pragma: no cover
                timezone = parse_timezone(timezone)
                # Newer versions of Dulwich return a tuple here
                if isinstance(timezone, tuple):
                    timezone, neg_utc = timezone
                    commit._commit_timezone_neg_utc = neg_utc
            else:
                timezone = -int(timezone)
            commit.commit_timezone = timezone
        else:
            commit.committer = commit.author
            commit.commit_time = commit.author_time
            commit.commit_timezone = commit.author_timezone

        commit.parents = []
        for parent in self.get_git_parents(ctx):
            hgsha = hex_(parent.node())
            git_sha = self.map_git_get(hgsha)
            if git_sha:
                if git_sha not in self.git.object_store:
                    raise hgutil.Abort(
                        _('Parent SHA-1 not present in Git'
                          'repo: %s' % git_sha))

                commit.parents.append(git_sha)

        commit.message = self.get_git_message(ctx)

        if 'encoding' in extra:
            commit.encoding = extra['encoding']

        for obj, nodeid in exporter.update_changeset(ctx):
            self.git.object_store.add_object(obj)

        tree_sha = exporter.root_tree_sha

        if tree_sha not in self.git.object_store:
            raise hgutil.Abort(
                _('Tree SHA-1 not present in Git repo: %s' % tree_sha))

        commit.tree = tree_sha

        self.git.object_store.add_object(commit)
        self.map_set(commit.id, ctx.hex())

        self.swap_out_encoding(oldenc)
        return commit.id
Example #50
0
    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=b'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
        if merge_heads is None:
            # FIXME: Read merge heads from .git/MERGE_HEADS
            merge_heads = []
        # 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
        if encoding is not None:
            c.encoding = encoding
        if message is None:
            # FIXME: Try to read commit message from .git/MERGE_MSG
            raise ValueError("No commit message specified")
        c.message = message
        try:
            old_head = self.refs[ref]
            c.parents = [old_head] + merge_heads
            self.object_store.add_object(c)
            ok = self.refs.set_if_equals(ref, old_head, c.id)
        except KeyError:
            c.parents = merge_heads
            self.object_store.add_object(c)
            ok = self.refs.add_if_new(ref, c.id)
        if not ok:
            # Fail if the atomic compare-and-swap failed, leaving the commit and
            # all its objects as garbage.
            raise CommitError("%s changed during commit" % (ref,))

        return c.id
    def __setitem__(self, path, raw):
        # XXX: I don't have much idea, what I'm doing here and I might
        # just corrupt your repository...

        # Mark directory as special (None, None) marker value
        if raw is None:
            super(Head, self).__setitem__(path, (None, None))
            return

        # Get old mode or use the default
        try:
            mode = super(Head, self).__getitem__(path)[1]
        except KeyError:
            mode = 0100644

        # Get existing entries for the content tree
        entries = [(key, sha_mode[0], cleanup_mode(sha_mode[1]))
                   for key, sha_mode in super(Head, self).iteritems()
                   if sha_mode[0] is not None and key is not path]

        # Get author
        # TODO: refactor to use plone.api or maybe use product_config
        from Products.CMFCore.utils import getToolByName
        portal_members = getToolByName(getSite(), 'portal_membership')
        member = portal_members.getAuthenticatedMember()
        author = '{0:s} <{1:s}>'.format(
            member.getProperty('fullname', '') or member.getId(),
            member.getProperty('email', '') or '*****@*****.**'
        )

        # Get timezone
        tz_diff = dateutil.tz.tzlocal().utcoffset(datetime.datetime.now())

        # Create commit
        commit = Commit()
        commit.author = author
        commit.committer = commit.author
        commit.commit_time = int(time.time())
        commit.author_time = commit.commit_time
        commit.commit_timezone = tz_diff.seconds
        commit.author_timezone = tz_diff.seconds
        if tz_diff < datetime.timedelta(0):
            commit._author_timezone_neg_utc = True
            commit._commit_timezone_neg_utc = True
        commit.encoding = 'UTF-8'
        commit.message = 'Update {0:s}'.format(path)
        commit.parents = [self._head]

        # Create blob and commit tree
        blob = Blob.from_string(raw)
        entries.append((path, blob.id, cleanup_mode(mode)))
        commit.tree = commit_tree(self._repo.object_store, entries)

        # Save blob and commit
        self._repo.object_store.add_object(blob)
        self._repo.object_store.add_object(commit)

        def determine_wants(haves):
            # Set new head for the branch
            return {self.__name__: commit.id}

        # Push to remote
        refs = self.__parent__._client.send_pack(
            self.__parent__._host_path,
            determine_wants,
            self._repo.object_store.generate_pack_contents,
            progress=logger.info
        )
        # Update heads
        for ref, sha in refs.items():
            if sha in self._repo.object_store:
                self._repo.refs[ref] = sha

        # Update "index"
        super(Head, self).__setitem__(path, (blob.id, mode))
    def __setitem__(self, path, raw):
        # XXX: I don't have much idea, what I'm doing here and I might
        # just corrupt your repository...

        # Mark directory as special (None, None) marker value
        if raw is None:
            super(Head, self).__setitem__(path, (None, None))
            return

        # Get old mode or use the default
        try:
            mode = super(Head, self).__getitem__(path)[1]
        except KeyError:
            mode = 0100644

        # Get existing entries for the content tree
        entries = [(key, sha_mode[0], cleanup_mode(sha_mode[1]))
                   for key, sha_mode in super(Head, self).iteritems()
                   if sha_mode[0] is not None and key is not path]

        # Get author
        # TODO: refactor to use plone.api or maybe use product_config
        from Products.CMFCore.utils import getToolByName
        portal_members = getToolByName(getSite(), 'portal_membership')
        member = portal_members.getAuthenticatedMember()
        author = '{0:s} <{1:s}>'.format(
            member.getProperty('fullname', '') or member.getId(),
            member.getProperty('email', '') or '*****@*****.**')

        # Get timezone
        tz_diff = dateutil.tz.tzlocal().utcoffset(datetime.datetime.now())

        # Create commit
        commit = Commit()
        commit.author = author
        commit.committer = commit.author
        commit.commit_time = int(time.time())
        commit.author_time = commit.commit_time
        commit.commit_timezone = tz_diff.seconds
        commit.author_timezone = tz_diff.seconds
        if tz_diff < datetime.timedelta(0):
            commit._author_timezone_neg_utc = True
            commit._commit_timezone_neg_utc = True
        commit.encoding = 'UTF-8'
        commit.message = 'Update {0:s}'.format(path)
        commit.parents = [self._head]

        # Create blob and commit tree
        blob = Blob.from_string(raw)
        entries.append((path, blob.id, cleanup_mode(mode)))
        commit.tree = commit_tree(self._repo.object_store, entries)

        # Save blob and commit
        self._repo.object_store.add_object(blob)
        self._repo.object_store.add_object(commit)

        def determine_wants(haves):
            # Set new head for the branch
            return {self.__name__: commit.id}

        # Push to remote
        refs = self.__parent__._client.send_pack(
            self.__parent__._host_path,
            determine_wants,
            self._repo.object_store.generate_pack_contents,
            progress=logger.info)
        # Update heads
        for ref, sha in refs.items():
            if sha in self._repo.object_store:
                self._repo.refs[ref] = sha

        # Update "index"
        super(Head, self).__setitem__(path, (blob.id, mode))
    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=b'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 as e:
            raise CommitError(e)
        except KeyError:  # no hook defined, silent fallthrough
            pass

        if merge_heads is None:
            # FIXME: Read merge heads from .git/MERGE_HEADS
            merge_heads = []
        if committer is None:
            # FIXME: Support GIT_COMMITTER_NAME/GIT_COMMITTER_EMAIL environment
            # variables
            committer = self._get_user_identity()
        c.committer = committer
        if commit_timestamp is None:
            # FIXME: Support GIT_COMMITTER_DATE environment variable
            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:
            # FIXME: Support GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL environment
            # variables
            author = committer
        c.author = author
        if author_timestamp is None:
            # FIXME: Support GIT_AUTHOR_DATE environment variable
            author_timestamp = commit_timestamp
        c.author_time = int(author_timestamp)
        if author_timezone is None:
            author_timezone = commit_timezone
        c.author_timezone = author_timezone
        if encoding is not None:
            c.encoding = encoding
        if message is None:
            # FIXME: Try to read commit message from .git/MERGE_MSG
            raise ValueError("No commit message specified")

        try:
            c.message = self.hooks['commit-msg'].execute(message)
            if c.message is None:
                c.message = message
        except HookError as e:
            raise CommitError(e)
        except KeyError:  # no hook defined, message not modified
            c.message = message

        if ref is None:
            # Create a dangling commit
            c.parents = merge_heads
            self.object_store.add_object(c)
        else:
            try:
                old_head = self.refs[ref]
                c.parents = [old_head] + merge_heads
                self.object_store.add_object(c)
                ok = self.refs.set_if_equals(ref, old_head, c.id)
            except KeyError:
                c.parents = merge_heads
                self.object_store.add_object(c)
                ok = self.refs.add_if_new(ref, c.id)
            if not ok:
                # Fail if the atomic compare-and-swap failed, leaving the commit and
                # all its objects as garbage.
                raise CommitError("%s changed during commit" % (ref,))

        try:
            self.hooks['post-commit'].execute()
        except HookError as e:  # silent failure
            warnings.warn("post-commit hook failed: %s" % e, UserWarning)
        except KeyError:  # no hook defined, silent fallthrough
            pass

        return c.id
Example #54
0
    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=b'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 as e:
            raise CommitError(e)
        except KeyError:  # no hook defined, silent fallthrough
            pass

        if merge_heads is None:
            # FIXME: Read merge heads from .git/MERGE_HEADS
            merge_heads = []
        if committer is None:
            # FIXME: Support GIT_COMMITTER_NAME/GIT_COMMITTER_EMAIL environment
            # variables
            committer = self._get_user_identity()
        c.committer = committer
        if commit_timestamp is None:
            # FIXME: Support GIT_COMMITTER_DATE environment variable
            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:
            # FIXME: Support GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL environment
            # variables
            author = committer
        c.author = author
        if author_timestamp is None:
            # FIXME: Support GIT_AUTHOR_DATE environment variable
            author_timestamp = commit_timestamp
        c.author_time = int(author_timestamp)
        if author_timezone is None:
            author_timezone = commit_timezone
        c.author_timezone = author_timezone
        if encoding is not None:
            c.encoding = encoding
        if message is None:
            # FIXME: Try to read commit message from .git/MERGE_MSG
            raise ValueError("No commit message specified")

        try:
            c.message = self.hooks['commit-msg'].execute(message)
            if c.message is None:
                c.message = message
        except HookError as e:
            raise CommitError(e)
        except KeyError:  # no hook defined, message not modified
            c.message = message

        if ref is None:
            # Create a dangling commit
            c.parents = merge_heads
            self.object_store.add_object(c)
        else:
            try:
                old_head = self.refs[ref]
                c.parents = [old_head] + merge_heads
                self.object_store.add_object(c)
                ok = self.refs.set_if_equals(ref, old_head, c.id)
            except KeyError:
                c.parents = merge_heads
                self.object_store.add_object(c)
                ok = self.refs.add_if_new(ref, c.id)
            if not ok:
                # Fail if the atomic compare-and-swap failed, leaving the
                # commit and all its objects as garbage.
                raise CommitError("%s changed during commit" % (ref,))

        try:
            self.hooks['post-commit'].execute()
        except HookError as e:  # silent failure
            warnings.warn("post-commit hook failed: %s" % e, UserWarning)
        except KeyError:  # no hook defined, silent fallthrough
            pass

        return c.id
Example #55
0
    def do_commit(self,
                  message='',
                  author=None,
                  committer=None,
                  branch='master',
                  parent=None):
        if isinstance(message, unicode):
            message = message.encode('utf-8')
        repo = self.repo
        try:
            parent = self._get_commit(parent, branch)
            root = repo[parent.tree]
        except BranchDoesNotExist:
            if branch == 'master':  # initial commit
                root = Tree()
            else:
                raise

        cache = {}
        paths = set()
        objects = set()

        for path, (action, data) in self.changes.iteritems():
            path = clean_path(path)
            paths.add(path)
            dirname, filename = os.path.split(path)
            trees = self._collect(root, dirname, cache)

            if action == WRITE:
                blob = Blob.from_string(data)
                trees[-1][2][filename] = (self.file_mode, blob.id)
                cache[blob.id] = blob

            elif action == DELETE:
                del trees[-1][2][filename]

            elif action == RENAME:
                old = self._collect(root, data, cache)
                mode, name, obj = old[-1]
                del old[-2][2][name]
                trees[-1][2][filename] = (mode, obj.id)
                cache.update(self._link(old[:-1]))
                paths.add(data)

            cache.update(self._link(trees))
        else:
            objects.add(root)

        # collect all objects that have to be committed
        for path in paths:
            objects.update(
                [obj for mode, name, obj in self._collect(root, path, cache)])

        # create the commit
        c = Commit()
        if parent:
            c.parents = [parent.id]
        c.tree = root.id
        c.committer = committer or self.committer
        c.author = author or c.committer

        t = time.localtime()
        c.commit_time = c.author_time = int(time.mktime(t))
        c.commit_timezone = c.author_timezone = t.tm_isdst * 3600 - time.timezone
        c.encoding = "UTF-8"
        c.message = message
        objects.add(c)

        # write everything to disk
        for obj in objects:
            repo.object_store.add_object(obj)

        repo.refs['refs/heads/%s' % branch] = c.id

        return DulwichCommit(self, c)
Example #56
0
    def edit(self, content=None, username=None, *virtual_path, **keywords):
        '''id: the git id of the blob before it was edited
        branch: master (default)'''
        #setup the defaults
        branch = "master"
        url = ManagedPath(virtual_path)
        if "branch" in keywords: branch = keywords["branch"]
        sha = self.sha
        print "sha is: ", sha
        print "keywords: ", keywords

        commit = sha
        print "content is: ", content
        print "self.filename is: ", self.filename
        if content is None:
            repo = Repo(self.package.path())
            set_head(repo, branch)
            if not sha:
                print "repo.head() = ", repo.head()
                sha = dulwich.object_store.tree_lookup_path(repo.get_object, repo.get_object(repo.head()).tree, self.filename)[1]
            obj = repo.get_object(sha)
            
            contents = obj.as_pretty_string()
            return_contents = "<form action=\"" + cherrypy.url() + "\" method=\"POST\">"
            return_contents = return_contents + "<textarea name=content rows='20' cols='120'>" + contents + "</textarea><br />"
            #if the user isn't logged in ...
            if not hasattr(cherrypy.session, "login"): return_contents = return_contents + "username: <input type=text name=username value=\"anonymous\"><br />"
            if sha: return_contents = return_contents + "<input type=hidden name=id value=\"" + sha + "\">"
            return_contents = return_contents + "<input type=hidden name=\"branch\" value=\"" + branch + "\">"
            return_contents = return_contents + "<input type=submit name=submit value=edit></form>"
            self.content = return_contents
            self.branch = branch
            return self.respond()
        elif (sha or branch): #it's been edited
            if username==None and hasattr(cherrypy.session, "login"): 
                if cherrypy.session.login==None: raise ValueError, "FileViewer.edit: no username supplied"
            elif username==None or username=="anonymous":
                anon = True #whether or not the user is anonymous
                if SESSION_KEY in cherrypy.session.keys():
                    username = cherrypy.session[SESSION_KEY].username
                    anon = False
                else: username = "******"

                #at least until we get access control lists working
                if anon:
                    if branch=="master": #don't let anonymous users modify branch "master"
                        branch = "anonymous"
                    branch = "anonymous"
                
                #make the blob
                blob = Blob.from_string(content)
                
                repo = Repo(self.package.path())
                #change to the right branch
                last_head = repo.head()
                set_head(repo, "master")
                last_commit = repo.get_object(repo.head())
                tree = repo.tree(repo.get_object(repo.head()).tree)

                #set the file
                tree[self.filename] = (0100644, blob.id)
                
                #make the commit
                commit = Commit()
                commit.tree = tree.id
                commit.parents = [last_head]
                commit.author = commit.committer = username
                commit.commit_time = commit.author_time = int(time.time())
                commit.commit_timezone = commit.author_timezone = parse_timezone("-0600")
                commit.encoding = "UTF-8"
                commit.message = "not implemented yet"

                repo.object_store.add_object(blob)
                repo.object_store.add_object(tree)
                repo.object_store.add_object(commit)
                repo.refs["refs/heads/" + branch] = commit.id
                repo.refs["HEAD"] = "ref: refs/heads/" + branch
                new_link = "<a href=\"/package/" + self.package.name + ":" + branch + "/" + self.filename + "/" + blob.id + "\">go to the new version</a>"
                self.new_link = new_link

            self.content = add_newlines("edited (name=%s, branch=%s, sha=%s) new link: %s\n\n\n" % (username, branch, sha, new_link))
            self.content = self.content + "<pre>" + content + "</pre>"
            self.branch = branch

            return self.respond()
Example #57
0
# again, not in the object store yet
store.add_object(commit)

# nothing points at this Tree yet!
# ...so, we will add a "master" branch
repo.refs[b'refs/heads/master'] = commit.id
print("Head: {}".format(repo.head().decode('ascii')))

# next, create another commit, changing the contents of our file

b2 = Blob.from_string(b"Blobfish are fish, not people\n")
t2 = Tree()
t2.add(b"a_file.txt", 0o100644, b2.id)
c2 = Commit()
c2.tree = t2
c2.parents = [commit.id]  # note: parents, not parent!
c2.author = c2.committer = b"meejah <*****@*****.**>"
c2.commit_time = c2.author_time = int(time())  # seconds since epoch
c2.commit_timezone = c2.author_timezone = -7 * (60 * 60)  # seconds offset; MST
c2.encoding = b"utf8"
c2.message = b"blobfish are aquatic animals"

print("  blob: {}".format(b2.sha().hexdigest()))
print("  tree: {}".format(t2.sha().hexdigest()))
print("commit: {}".format(c2.sha().hexdigest()))

store.add_object(b2)
store.add_object(t2)
store.add_object(c2)

# actually extend master branch
Example #58
0
    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
        if merge_heads is None:
            # FIXME: Read merge heads from .git/MERGE_HEADS
            merge_heads = []
        # 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
        if encoding is not None:
            c.encoding = encoding
        if message is None:
            # FIXME: Try to read commit message from .git/MERGE_MSG
            raise ValueError("No commit message specified")
        c.message = message
        try:
            old_head = self.refs[ref]
            c.parents = [old_head] + merge_heads
            self.object_store.add_object(c)
            ok = self.refs.set_if_equals(ref, old_head, c.id)
        except KeyError:
            c.parents = merge_heads
            self.object_store.add_object(c)
            ok = self.refs.add_if_new(ref, c.id)
        if not ok:
            # Fail if the atomic compare-and-swap failed, leaving the commit and
            # all its objects as garbage.
            raise CommitError("%s changed during commit" % (ref,))

        return c.id
Example #59
0
    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