Пример #1
0
    def test_tree_changes(self):
        blob_a1 = make_object(Blob, data=b"a1")
        blob_a2 = make_object(Blob, data=b"a2")
        blob_b = make_object(Blob, data=b"b")
        for blob in [blob_a1, blob_a2, blob_b]:
            self.store.add_object(blob)

        blobs_1 = [(b"a", blob_a1.id, 0o100644), (b"b", blob_b.id, 0o100644)]
        tree1_id = commit_tree(self.store, blobs_1)
        blobs_2 = [(b"a", blob_a2.id, 0o100644), (b"b", blob_b.id, 0o100644)]
        tree2_id = commit_tree(self.store, blobs_2)
        change_a = (
            (b"a", b"a"),
            (0o100644, 0o100644),
            (blob_a1.id, blob_a2.id),
        )
        self.assertEqual([change_a],
                         list(self.store.tree_changes(tree1_id, tree2_id)))
        self.assertEqual(
            [
                change_a,
                ((b"b", b"b"), (0o100644, 0o100644), (blob_b.id, blob_b.id)),
            ],
            list(
                self.store.tree_changes(tree1_id,
                                        tree2_id,
                                        want_unchanged=True)),
        )
Пример #2
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
Пример #3
0
    def test_iter_tree_contents_include_trees(self):
        blob_a = make_object(Blob, data='a')
        blob_b = make_object(Blob, data='b')
        blob_c = make_object(Blob, data='c')
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
          ('a', blob_a.id, 0100644),
          ('ad/b', blob_b.id, 0100644),
          ('ad/bd/c', blob_c.id, 0100755),
          ]
        tree_id = commit_tree(self.store, blobs)
        tree = self.store[tree_id]
        tree_ad = self.store[tree['ad'][1]]
        tree_bd = self.store[tree_ad['bd'][1]]

        expected = [
          TreeEntry('', 0040000, tree_id),
          TreeEntry('a', 0100644, blob_a.id),
          TreeEntry('ad', 0040000, tree_ad.id),
          TreeEntry('ad/b', 0100644, blob_b.id),
          TreeEntry('ad/bd', 0040000, tree_bd.id),
          TreeEntry('ad/bd/c', 0100755, blob_c.id),
          ]
        actual = self.store.iter_tree_contents(tree_id, include_trees=True)
        self.assertEquals(expected, list(actual))
Пример #4
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
Пример #5
0
    def test_iter_tree_contents_include_trees(self):
        blob_a = make_object(Blob, data=b'a')
        blob_b = make_object(Blob, data=b'b')
        blob_c = make_object(Blob, data=b'c')
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
          (b'a', blob_a.id, 0o100644),
          (b'ad/b', blob_b.id, 0o100644),
          (b'ad/bd/c', blob_c.id, 0o100755),
          ]
        tree_id = commit_tree(self.store, blobs)
        tree = self.store[tree_id]
        tree_ad = self.store[tree[b'ad'][1]]
        tree_bd = self.store[tree_ad[b'bd'][1]]

        expected = [
          TreeEntry(b'', 0o040000, tree_id),
          TreeEntry(b'a', 0o100644, blob_a.id),
          TreeEntry(b'ad', 0o040000, tree_ad.id),
          TreeEntry(b'ad/b', 0o100644, blob_b.id),
          TreeEntry(b'ad/bd', 0o040000, tree_bd.id),
          TreeEntry(b'ad/bd/c', 0o100755, blob_c.id),
          ]
        actual = self.store.iter_tree_contents(tree_id, include_trees=True)
        self.assertEqual(expected, list(actual))
Пример #6
0
 def disable_ff_and_make_dummy_commit(self):
     # disable non-fast-forward pushes to the server
     dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
     run_git_or_fail(['config', 'receive.denyNonFastForwards', 'true'],
                     cwd=dest.path)
     b = objects.Blob.from_string('hi')
     dest.object_store.add_object(b)
     t = index.commit_tree(dest.object_store, [('hi', b.id, 0100644)])
Пример #7
0
    def test_tree_changes(self):
        blob_a1 = make_object(Blob, data='a1')
        blob_a2 = make_object(Blob, data='a2')
        blob_b = make_object(Blob, data='b')
        for blob in [blob_a1, blob_a2, blob_b]:
            self.store.add_object(blob)

        blobs_1 = [('a', blob_a1.id, 0100644), ('b', blob_b.id, 0100644)]
        tree1_id = commit_tree(self.store, blobs_1)
        blobs_2 = [('a', blob_a2.id, 0100644), ('b', blob_b.id, 0100644)]
        tree2_id = commit_tree(self.store, blobs_2)
        change_a = (('a', 'a'), (0100644, 0100644), (blob_a1.id, blob_a2.id))
        self.assertEquals([change_a],
                          list(self.store.tree_changes(tree1_id, tree2_id)))
        self.assertEquals(
          [change_a, (('b', 'b'), (0100644, 0100644), (blob_b.id, blob_b.id))],
          list(self.store.tree_changes(tree1_id, tree2_id,
                                       want_unchanged=True)))
Пример #8
0
 def test_single_blob(self):
     blob = Blob()
     blob.data = b"foo"
     self.store.add_object(blob)
     blobs = [(b"bla", blob.id, stat.S_IFREG)]
     rootid = commit_tree(self.store, blobs)
     self.assertEqual(rootid, b"1a1e80437220f9312e855c37ac4398b68e5c1d50")
     self.assertEqual((stat.S_IFREG, blob.id), self.store[rootid][b"bla"])
     self.assertEqual(set([rootid, blob.id]), set(self.store._data.keys()))
Пример #9
0
 def test_single_blob(self):
     blob = Blob()
     blob.data = b"foo"
     self.store.add_object(blob)
     blobs = [(b"bla", blob.id, stat.S_IFREG)]
     rootid = commit_tree(self.store, blobs)
     self.assertEqual(rootid, b"1a1e80437220f9312e855c37ac4398b68e5c1d50")
     self.assertEqual((stat.S_IFREG, blob.id), self.store[rootid][b"bla"])
     self.assertEqual(set([rootid, blob.id]), set(self.store._data.keys()))
Пример #10
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
Пример #11
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
Пример #12
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
Пример #13
0
 def make_dummy_commit(self, dest):
     b = objects.Blob.from_string(b'hi')
     dest.object_store.add_object(b)
     t = index.commit_tree(dest.object_store, [(b'hi', b.id, 0o100644)])
     c = objects.Commit()
     c.author = c.committer = b'Foo Bar <*****@*****.**>'
     c.author_time = c.commit_time = 0
     c.author_timezone = c.commit_timezone = 0
     c.message = b'hi'
     c.tree = t
     dest.object_store.add_object(c)
     return c.id
Пример #14
0
    def test_tree_changes(self):
        blob_a1 = make_object(Blob, data='a1')
        blob_a2 = make_object(Blob, data='a2')
        blob_b = make_object(Blob, data='b')
        for blob in [blob_a1, blob_a2, blob_b]:
            self.store.add_object(blob)

        blobs_1 = [('a', blob_a1.id, 0100644), ('b', blob_b.id, 0100644)]
        tree1_id = commit_tree(self.store, blobs_1)
        blobs_2 = [('a', blob_a2.id, 0100644), ('b', blob_b.id, 0100644)]
        tree2_id = commit_tree(self.store, blobs_2)
        change_a = (('a', 'a'), (0100644, 0100644), (blob_a1.id, blob_a2.id))
        self.assertEqual([change_a],
                         list(self.store.tree_changes(tree1_id, tree2_id)))
        self.assertEqual([
            change_a, (('b', 'b'), (0100644, 0100644), (blob_b.id, blob_b.id))
        ],
                         list(
                             self.store.tree_changes(tree1_id,
                                                     tree2_id,
                                                     want_unchanged=True)))
Пример #15
0
 def test_nested(self):
     blob = Blob()
     blob.data = "foo"
     self.store.add_object(blob)
     blobs = [("bla/bar", blob.id, stat.S_IFREG)]
     rootid = commit_tree(self.store, blobs)
     self.assertEqual(rootid, "d92b959b216ad0d044671981196781b3258fa537")
     dirid = self.store[rootid]["bla"][1]
     self.assertEqual(dirid, "c1a1deb9788150829579a8b4efa6311e7b638650")
     self.assertEqual((stat.S_IFDIR, dirid), self.store[rootid]["bla"])
     self.assertEqual((stat.S_IFREG, blob.id), self.store[dirid]["bar"])
     self.assertEqual(set([rootid, dirid, blob.id]), set(self.store._data.keys()))
Пример #16
0
    def push(self, committer=None, author=None, message=None):
        """Create a new stash.

        Args:
          committer: Optional committer name to use
          author: Optional author name to use
          message: Optional commit message
        """
        # First, create the index commit.
        commit_kwargs = {}
        if committer is not None:
            commit_kwargs["committer"] = committer
        if author is not None:
            commit_kwargs["author"] = author

        index = self._repo.open_index()
        index_tree_id = index.commit(self._repo.object_store)
        index_commit_id = self._repo.do_commit(
            ref=None,
            tree=index_tree_id,
            message=b"Index stash",
            merge_heads=[self._repo.head()],
            no_verify=True,
            **commit_kwargs
        )

        # Then, the working tree one.
        stash_tree_id = commit_tree(
            self._repo.object_store,
            iter_fresh_objects(
                index,
                os.fsencode(self._repo.path),
                object_store=self._repo.object_store,
            ),
        )

        if message is None:
            message = b"A stash on " + self._repo.head()

        # TODO(jelmer): Just pass parents into do_commit()?
        self._repo.refs[self._ref] = self._repo.head()

        cid = self._repo.do_commit(
            ref=self._ref,
            tree=stash_tree_id,
            message=message,
            merge_heads=[index_commit_id],
            no_verify=True,
            **commit_kwargs
        )

        return cid
Пример #17
0
 def test_nested(self):
     blob = Blob()
     blob.data = b"foo"
     self.store.add_object(blob)
     blobs = [(b"bla/bar", blob.id, stat.S_IFREG)]
     rootid = commit_tree(self.store, blobs)
     self.assertEqual(rootid, b"d92b959b216ad0d044671981196781b3258fa537")
     dirid = self.store[rootid][b"bla"][1]
     self.assertEqual(dirid, b"c1a1deb9788150829579a8b4efa6311e7b638650")
     self.assertEqual((stat.S_IFDIR, dirid), self.store[rootid][b"bla"])
     self.assertEqual((stat.S_IFREG, blob.id), self.store[dirid][b"bar"])
     self.assertEqual(set([rootid, dirid, blob.id]),
                      set(self.store._data.keys()))
Пример #18
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
Пример #19
0
 def commit_tree(self, entries):
     commit_blobs = []
     for entry in entries:
         if len(entry) == 2:
             path, obj = entry
             mode = F
         else:
             path, obj, mode = entry
         if isinstance(obj, Blob):
             self.store.add_object(obj)
             sha = obj.id
         else:
             sha = obj
         commit_blobs.append((path, sha, mode))
     return self.store[commit_tree(self.store, commit_blobs)]
Пример #20
0
 def commit_tree(self, entries):
     commit_blobs = []
     for entry in entries:
         if len(entry) == 2:
             path, obj = entry
             mode = F
         else:
             path, obj, mode = entry
         if isinstance(obj, Blob):
             self.store.add_object(obj)
             sha = obj.id
         else:
             sha = obj
         commit_blobs.append((path, sha, mode))
     return self.store[commit_tree(self.store, commit_blobs)]
Пример #21
0
    def test_iter_tree_contents(self):
        blob_a = make_object(Blob, data='a')
        blob_b = make_object(Blob, data='b')
        blob_c = make_object(Blob, data='c')
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
          ('a', blob_a.id, 0100644),
          ('ad/b', blob_b.id, 0100644),
          ('ad/bd/c', blob_c.id, 0100755),
          ('ad/c', blob_c.id, 0100644),
          ('c', blob_c.id, 0100644),
          ]
        tree_id = commit_tree(self.store, blobs)
        self.assertEquals([TreeEntry(p, m, h) for (p, h, m) in blobs],
                          list(self.store.iter_tree_contents(tree_id)))
Пример #22
0
    def setUp(self):
        super(CommitTreeChangesTests, self).setUp()
        self.store = MemoryObjectStore()
        self.blob_a = make_object(Blob, data=b'a')
        self.blob_b = make_object(Blob, data=b'b')
        self.blob_c = make_object(Blob, data=b'c')
        for blob in [self.blob_a, self.blob_b, self.blob_c]:
            self.store.add_object(blob)

        blobs = [
          (b'a', self.blob_a.id, 0o100644),
          (b'ad/b', self.blob_b.id, 0o100644),
          (b'ad/bd/c', self.blob_c.id, 0o100755),
          (b'ad/c', self.blob_c.id, 0o100644),
          (b'c', self.blob_c.id, 0o100644),
          ]
        self.tree_id = commit_tree(self.store, blobs)
Пример #23
0
    def setUp(self):
        super(CommitTreeChangesTests, self).setUp()
        self.store = MemoryObjectStore()
        self.blob_a = make_object(Blob, data=b"a")
        self.blob_b = make_object(Blob, data=b"b")
        self.blob_c = make_object(Blob, data=b"c")
        for blob in [self.blob_a, self.blob_b, self.blob_c]:
            self.store.add_object(blob)

        blobs = [
            (b"a", self.blob_a.id, 0o100644),
            (b"ad/b", self.blob_b.id, 0o100644),
            (b"ad/bd/c", self.blob_c.id, 0o100755),
            (b"ad/c", self.blob_c.id, 0o100644),
            (b"c", self.blob_c.id, 0o100644),
        ]
        self.tree_id = commit_tree(self.store, blobs)
Пример #24
0
    def setUp(self):
        TestCase.setUp(self)
        self.store = MemoryObjectStore()
        blob_a = make_object(Blob, data=b'a')
        blob_b = make_object(Blob, data=b'b')
        blob_c = make_object(Blob, data=b'c')
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
          (b'a', blob_a.id, 0o100644),
          (b'ad/b', blob_b.id, 0o100644),
          (b'ad/bd/c', blob_c.id, 0o100755),
          (b'ad/c', blob_c.id, 0o100644),
          (b'c', blob_c.id, 0o100644),
          ]
        self.tree_id = commit_tree(self.store, blobs)
Пример #25
0
    def test_iter_tree_contents(self):
        blob_a = make_object(Blob, data=b'a')
        blob_b = make_object(Blob, data=b'b')
        blob_c = make_object(Blob, data=b'c')
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
            (b'a', blob_a.id, 0o100644),
            (b'ad/b', blob_b.id, 0o100644),
            (b'ad/bd/c', blob_c.id, 0o100755),
            (b'ad/c', blob_c.id, 0o100644),
            (b'c', blob_c.id, 0o100644),
        ]
        tree_id = commit_tree(self.store, blobs)
        self.assertEqual([TreeEntry(p, m, h) for (p, h, m) in blobs],
                          list(self.store.iter_tree_contents(tree_id)))
Пример #26
0
    def setUp(self):
        TestCase.setUp(self)
        self.store = MemoryObjectStore()
        blob_a = make_object(Blob, data='a')
        blob_b = make_object(Blob, data='b')
        blob_c = make_object(Blob, data='c')
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
          ('a', blob_a.id, 0100644),
          ('ad/b', blob_b.id, 0100644),
          ('ad/bd/c', blob_c.id, 0100755),
          ('ad/c', blob_c.id, 0100644),
          ('c', blob_c.id, 0100644),
          ]
        self.tree_id = commit_tree(self.store, blobs)
Пример #27
0
    def setUp(self):
        TestCase.setUp(self)
        self.store = MemoryObjectStore()
        blob_a = make_object(Blob, data=b"a")
        blob_b = make_object(Blob, data=b"b")
        blob_c = make_object(Blob, data=b"c")
        for blob in [blob_a, blob_b, blob_c]:
            self.store.add_object(blob)

        blobs = [
            (b"a", blob_a.id, 0o100644),
            (b"ad/b", blob_b.id, 0o100644),
            (b"ad/bd/c", blob_c.id, 0o100755),
            (b"ad/c", blob_c.id, 0o100644),
            (b"c", blob_c.id, 0o100644),
            (b"d", blob_c.id, S_IFGITLINK),
        ]
        self.tree_id = commit_tree(self.store, blobs)
Пример #28
0
    def push(self, committer=None, author=None, message=None):
        """Create a new stash.

        :param committer: Optional committer name to use
        :param author: Optional author name to use
        :param message: Optional commit message
        """
        # First, create the index commit.
        commit_kwargs = {}
        if committer is not None:
            commit_kwargs['committer'] = committer
        if author is not None:
            commit_kwargs['author'] = author

        index = self._repo.open_index()
        index_tree_id = index.commit(self._repo.object_store)
        index_commit_id = self._repo.do_commit(
            ref=None, tree=index_tree_id,
            message=b"Index stash",
            merge_heads=[self._repo.head()],
            **commit_kwargs)

        # Then, the working tree one.
        stash_tree_id = commit_tree(
                self._repo.object_store,
                iter_fresh_objects(
                    index, self._repo.path,
                    object_store=self._repo.object_store))

        if message is None:
            message = b"A stash on " + self._repo.head()

        # TODO(jelmer): Just pass parents into do_commit()?
        self._repo.refs[self._ref] = self._repo.head()

        cid = self._repo.do_commit(
            ref=self._ref, tree=stash_tree_id,
            message=message,
            merge_heads=[index_commit_id],
            **commit_kwargs)

        return cid
    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))
Пример #30
0
def build_commit_graph(object_store, commit_spec, trees=None, attrs=None):
    """Build a commit graph from a concise specification.

    Sample usage:
    >>> c1, c2, c3 = build_commit_graph(store, [[1], [2, 1], [3, 1, 2]])
    >>> store[store[c3].parents[0]] == c1
    True
    >>> store[store[c3].parents[1]] == c2
    True

    If not otherwise specified, commits will refer to the empty tree and have
    commit times increasing in the same order as the commit spec.

    Args:
      object_store: An ObjectStore to commit objects to.
      commit_spec: An iterable of iterables of ints defining the commit
        graph. Each entry defines one commit, and entries must be in
        topological order. The first element of each entry is a commit number,
        and the remaining elements are its parents. The commit numbers are only
        meaningful for the call to make_commits; since real commit objects are
        created, they will get created with real, opaque SHAs.
      trees: An optional dict of commit number -> tree spec for building
        trees for commits. The tree spec is an iterable of (path, blob, mode)
        or (path, blob) entries; if mode is omitted, it defaults to the normal
        file mode (0100644).
      attrs: A dict of commit number -> (dict of attribute -> value) for
        assigning additional values to the commits.
    Returns: The list of commit objects created.
    Raises:
      ValueError: If an undefined commit identifier is listed as a parent.
    """
    if trees is None:
        trees = {}
    if attrs is None:
        attrs = {}
    commit_time = 0
    nums = {}
    commits = []

    for commit in commit_spec:
        commit_num = commit[0]
        try:
            parent_ids = [nums[pn] for pn in commit[1:]]
        except KeyError as e:
            (missing_parent, ) = e.args
            raise ValueError("Unknown parent %i" % missing_parent)

        blobs = []
        for entry in trees.get(commit_num, []):
            if len(entry) == 2:
                path, blob = entry
                entry = (path, blob, F)
            path, blob, mode = entry
            blobs.append((path, blob.id, mode))
            object_store.add_object(blob)
        tree_id = commit_tree(object_store, blobs)

        commit_attrs = {
            "message": ("Commit %i" % commit_num).encode("ascii"),
            "parents": parent_ids,
            "tree": tree_id,
            "commit_time": commit_time,
        }
        commit_attrs.update(attrs.get(commit_num, {}))
        commit_obj = make_commit(**commit_attrs)

        # By default, increment the time by a lot. Out-of-order commits should
        # be closer together than this because their main cause is clock skew.
        commit_time = commit_attrs["commit_time"] + 100
        nums[commit_num] = commit_obj.id
        object_store.add_object(commit_obj)
        commits.append(commit_obj)

    return commits
    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))
Пример #32
0
 def make_dummy_commit(self, dest):
     b = objects.Blob.from_string('hi')
     dest.object_store.add_object(b)
     t = index.commit_tree(dest.object_store, [('hi', b.id, 0100644)])
Пример #33
0
def build_commit_graph(object_store, commit_spec, trees=None, attrs=None):
    """Build a commit graph from a concise specification.

    Sample usage:
    >>> c1, c2, c3 = build_commit_graph(store, [[1], [2, 1], [3, 1, 2]])
    >>> store[store[c3].parents[0]] == c1
    True
    >>> store[store[c3].parents[1]] == c2
    True

    If not otherwise specified, commits will refer to the empty tree and have
    commit times increasing in the same order as the commit spec.

    :param object_store: An ObjectStore to commit objects to.
    :param commit_spec: An iterable of iterables of ints defining the commit
        graph. Each entry defines one commit, and entries must be in topological
        order. The first element of each entry is a commit number, and the
        remaining elements are its parents. The commit numbers are only
        meaningful for the call to make_commits; since real commit objects are
        created, they will get created with real, opaque SHAs.
    :param trees: An optional dict of commit number -> tree spec for building
        trees for commits. The tree spec is an iterable of (path, blob, mode) or
        (path, blob) entries; if mode is omitted, it defaults to the normal file
        mode (0100644).
    :param attrs: A dict of commit number -> (dict of attribute -> value) for
        assigning additional values to the commits.
    :return: The list of commit objects created.
    :raise ValueError: If an undefined commit identifier is listed as a parent.
    """
    if trees is None:
        trees = {}
    if attrs is None:
        attrs = {}
    commit_time = 0
    nums = {}
    commits = []

    for commit in commit_spec:
        commit_num = commit[0]
        try:
            parent_ids = [nums[pn] for pn in commit[1:]]
        except KeyError as e:
            missing_parent, = e.args
            raise ValueError('Unknown parent %i' % missing_parent)

        blobs = []
        for entry in trees.get(commit_num, []):
            if len(entry) == 2:
                path, blob = entry
                entry = (path, blob, F)
            path, blob, mode = entry
            blobs.append((path, blob.id, mode))
            object_store.add_object(blob)
        tree_id = commit_tree(object_store, blobs)

        commit_attrs = {
            'message': 'Commit %i' % commit_num,
            'parents': parent_ids,
            'tree': tree_id,
            'commit_time': commit_time,
            }
        commit_attrs.update(attrs.get(commit_num, {}))
        commit_obj = make_commit(**commit_attrs)

        # By default, increment the time by a lot. Out-of-order commits should
        # be closer together than this because their main cause is clock skew.
        commit_time = commit_attrs['commit_time'] + 100
        nums[commit_num] = commit_obj.id
        object_store.add_object(commit_obj)
        commits.append(commit_obj)

    return commits