Example #1
0
    def add_from_other_repo(self,
                            other_repo,
                            committish,
                            src="",
                            dest="",
                            exclude=()):
        """Copies files from another repository over to this one."""
        def _copy_blob(blob_id):
            # Copy object over to this repo
            local_id = self.repo.create_blob(other_repo[blob_id].read_raw())
            # Two blobs with same content MUST have the same id in both repos
            assert local_id == blob_id

        commit = resolve_committish(other_repo, committish)
        node = commit.tree
        src = posixpath.normpath(src)
        dest = posixpath.normpath(dest)

        # Traverse down to the proper subtree or blob
        if src != ".":
            for part in src.split(os.sep):
                if not isinstance(node, pygit2.Tree):
                    # We reached a leaf and hence can't descend further
                    raise KeyError(part)
                node /= part

        if isinstance(node, pygit2.Blob):
            # Copy only a single file
            if dest == ".":
                # When nothing is specified as destination, keep the file's name
                dest = posixpath.split(src)[1]
            _copy_blob(node.id)
            self.index.add(pygit2.IndexEntry(dest, node.id, node.filemode))
            return

        assert isinstance(node, pygit2.Tree)
        # Read tree into in-memory index and then copy the entries over
        index = pygit2.Index()
        index.read_tree(node)
        for entry in index:
            # Check if file (or the directory the file is in) is in exclude list
            for path in exclude:
                if entry.path == path or entry.path.startswith(f"{path}/"):
                    break
            else:
                _copy_blob(entry.id)
                self.index.add(
                    pygit2.IndexEntry(
                        posixpath.normpath(posixpath.join(dest, entry.path)),
                        entry.id,
                        entry.mode,
                    ))
Example #2
0
def test_entry_eq(testrepo):
    index = testrepo.index
    hello_entry = index['hello.txt']
    entry = pygit2.IndexEntry(hello_entry.path, hello_entry.id,
                              hello_entry.mode)
    assert hello_entry == entry

    entry = pygit2.IndexEntry("README.md", hello_entry.id, hello_entry.mode)
    assert hello_entry != entry
    oid = Oid(hex='0907563af06c7464d62a70cdd135a6ba7d2b41d8')
    entry = pygit2.IndexEntry(hello_entry.path, oid, hello_entry.mode)
    assert hello_entry != entry
    entry = pygit2.IndexEntry(hello_entry.path, hello_entry.id,
                              pygit2.GIT_FILEMODE_BLOB_EXECUTABLE)
    assert hello_entry != entry
Example #3
0
def _posthoc_main(driver: MergeDriver, args: typing.List[str]):
    """
    Apply merge driver logic to a repository which is already in a conflicted
    state, running the driver on any conflicted files.
    """
    repo_dir = pygit2.discover_repository(os.getcwd())
    repo = pygit2.Repository(repo_dir)
    conflicts = repo.index.conflicts
    if not conflicts:
        print("There are no unresolved conflicts.")
        return 0

    all_success = True
    index_changed = False
    any_attempted = False
    for base, left, right in list(conflicts):
        if not base or not left or not right:
            # (not left) or (not right): deleted in one branch, modified in the other.
            # (not base): added differently in both branches.
            # In either case, there's nothing we can do for now.
            continue

        path = left.path
        if not _applies_to(repo, driver, path):
            # Skip the file if it's not the right extension.
            continue

        any_attempted = True
        driver.pre_announce(path)
        io_base = io.BytesIO(repo[base.id].data)
        io_left = io.BytesIO(repo[left.id].data)
        io_right = io.BytesIO(repo[right.id].data)
        success, merge_result = driver.merge(io_base, io_left, io_right)
        if merge_result:
            # If we got anything, write it to the working directory.
            with open(os.path.join(repo.workdir, path), 'wb') as io_output:
                driver.to_file(io_output, merge_result)

            if success:
                # If we were successful, mark the conflict as resolved.
                with open(os.path.join(repo.workdir, path),
                          'rb') as io_readback:
                    contents = io_readback.read()
                merged_id = repo.create_blob(contents)
                repo.index.add(pygit2.IndexEntry(path, merged_id, left.mode))
                del conflicts[path]
                index_changed = True
        if not success:
            all_success = False
        driver.post_announce(success, merge_result)

    if index_changed:
        repo.index.write()

    if not any_attempted:
        print("There are no unresolved", driver.driver_id, "conflicts.")

    if not all_success:
        # Not usually observed, but indicate the failure just in case.
        return 1
Example #4
0
    def add(self, key, value):
        """Add a value for a key to the working tree, staging it for commit.

        >>> repo.add('added', 'but not committed!')
        >>> repo.index('added')
        u'but not committed!'
        >>> repo.show('added')
        KeyError: 'There is no key at added'

        :param key: The key to add
        :type key: string
        :param value: The value to insert
        :type value: anything that runs through :func:`json.dumps`

        :raises:
            :class:`NotJsonError <jsongit.NotJsonError>`
            :class:`InvalidKeyError <jsongit.InvalidKeyError>`
        """
        self._key2ref(key)  # throw InvalidKeyError
        try:
            blob_id = self._repo.write(pygit2.GIT_OBJ_BLOB, self._dumps(value))
        except ValueError as e:
            raise NotJsonError(e)
        except TypeError as e:
            raise NotJsonError(e)

        if key in self._repo.index:
            self._repo.index.remove(key)
        self._repo.index.add(
            pygit2.IndexEntry(key, blob_id, pygit2.GIT_FILEMODE_BLOB))
        self._repo.index.write()
Example #5
0
def test_create_entry_aspath(testrepo):
    index = testrepo.index
    hello_entry = index[Path('hello.txt')]
    entry = pygit2.IndexEntry(Path('README.md'), hello_entry.id,
                              hello_entry.mode)
    index.add(entry)
    index.write_tree()
Example #6
0
def createCommits(repo, commitsData, destHead, branchName):
    index = pygit2.Index()

    destCommit = destHead
    index.read_tree(destCommit.tree)

    for commitData in commitsData:
        srcCommit = commitData.commit
        tree = commitData.commit.tree
        for file in commitData.files:
            try:
                fileObject = tree[file]
                index.add(
                    pygit2.IndexEntry(file, fileObject.id,
                                      pygit2.GIT_FILEMODE_BLOB))
            except KeyError:
                removeFileFromTree(index, file)

        destTree = index.write_tree(repo)

        diff = repo[destTree].diff_to_tree(destCommit.tree)

        if len(diff):
            destCommitId = repo.create_commit('refs/heads/' + branchName,
                                              srcCommit.author,
                                              srcCommit.committer,
                                              srcCommit.message, destTree,
                                              [destCommit.id])
            destCommit = repo[destCommitId]
            print srcCommit.id
Example #7
0
    def _write(self, path: Path, value: str) -> None:

        blob = self.repo.create_blob(value)

        # Check if the blob is identical, then just return.
        previous_blob: Optional[pygit2.Object] = None
        if self._current_session_branch is not None:
            # Try in session index.
            previous_blob = self._read_blob(
                f"refs/heads/{self._current_session_branch}", path)
        else:
            # Try in namespace branch.
            previous_blob = self._read_blob(
                f"refs/heads/{self.namespace_branch}", path)

        if previous_blob is not None:
            if blob == previous_blob.oid:
                return

        if self._current_session_index is None:
            raise Exception("There should be a index setup")

        new_entry = pygit2.IndexEntry(str(path), blob,
                                      pygit2.GIT_FILEMODE_BLOB)

        self._current_session_index.add(new_entry)
Example #8
0
def apply_changes(repo, version, contents, path):
    # Apply the requested change to the git repository
    branch_name = BRANCHES[version.channel]
    git_repo = repo.git_repository
    blob_id = git_repo.create_blob(contents)

    # Initialize the index from the tree structure of the most
    # recent commit in `branch`
    tree = git_repo.revparse_single(branch_name).tree
    index = git_repo.index
    index.read_tree(tree)

    # Add / update the index
    path = os.path.join(EXTRACTED_PREFIX, path)
    entry = pygit2.IndexEntry(path, blob_id, pygit2.GIT_FILEMODE_BLOB)
    index.add(entry)

    tree = index.write_tree()

    # Now apply a new commit
    author = pygit2.Signature('test', '*****@*****.**')
    committer = pygit2.Signature('test', '*****@*****.**')

    branch = git_repo.branches.get(branch_name)

    # Create commit and properly update branch and reflog
    oid = git_repo.create_commit(None, author, committer, '...', tree,
                                 [branch.target])
    commit = git_repo.get(oid)
    branch.set_target(commit.hex)

    # To make sure the serializer makes use of the new commit we'll have
    # to update the `git_hash` values on the version object.
    version.update(git_hash=commit.hex)
Example #9
0
 def __setitem__(self, key, value):
     _check_key(key)
     if self._dumper:
         value = self._dumper(value)
     blob_id = self._repo.create_blob(value)
     self._index.add(
         pygit2.IndexEntry(key, blob_id, pygit2.GIT_FILEMODE_BLOB))
Example #10
0
    def write(self, path):
        """
        Serialise this MergeIndex to the given path.
        Regular entries, conflicts, and resolves are each serialised separately,
        so that they can be roundtripped accurately.
        """
        index = pygit2.Index(str(path))
        index.clear()

        for e in self.entries.values():
            index.add(pygit2.IndexEntry(e.path, e.id, e.mode))
        for e in self._serialise_conflicts():
            index.add(pygit2.IndexEntry(e.path, e.id, e.mode))
        for e in self._serialise_resolves():
            index.add(pygit2.IndexEntry(e.path, e.id, e.mode))
        index.write()
Example #11
0
def test_create_entry(testrepo):
    index = testrepo.index
    hello_entry = index['hello.txt']
    entry = pygit2.IndexEntry('README.md', hello_entry.id, hello_entry.mode)
    index.add(entry)
    tree_id = index.write_tree()
    assert '60e769e57ae1d6a2ab75d8d253139e6260e1f912' == str(tree_id)
Example #12
0
 def add_tree(self, tree):
     # type: (Dict[Text, bytes]) -> None
     self.has_changes = True
     for path, data in iteritems(tree):
         blob = self.pygit2_repo.create_blob(data)
         index_entry = pygit2.IndexEntry(path, blob,
                                         pygit2.GIT_FILEMODE_BLOB)
         self.index.add(index_entry)
Example #13
0
def main(repo, *, use_workdir=False):
    if repo.index.conflicts:
        print("You need to resolve merge conflicts first.")
        return 1

    try:
        repo.lookup_reference('MERGE_HEAD')
        print("Not running mapmerge for merge commit.")
        return 0
    except KeyError:
        pass

    target_statuses = pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_INDEX_NEW
    skip_to_file_statuses = pygit2.GIT_STATUS_WT_DELETED | pygit2.GIT_STATUS_WT_MODIFIED
    if use_workdir:
        target_statuses |= pygit2.GIT_STATUS_WT_MODIFIED | pygit2.GIT_STATUS_WT_NEW
        skip_to_file_statuses &= ~pygit2.GIT_STATUS_WT_MODIFIED

    changed = 0
    for path, status in repo.status().items():
        if path.endswith(".dmm") and (status & target_statuses):
            # read the index
            index_entry = repo.index[path]
            if use_workdir:
                index_map = dmm.DMM.from_file(os.path.join(repo.workdir, path))
            else:
                index_map = dmm.DMM.from_bytes(repo[index_entry.id].read_raw())

            try:
                head_blob = repo[repo[repo.head.target].tree[path].id]
            except KeyError:
                # New map, no entry in HEAD
                print(f"Converting new map: {path}", flush=True)
                assert (status & pygit2.GIT_STATUS_INDEX_NEW)
                merged_map = index_map
            else:
                # Entry in HEAD, merge the index over it
                print(f"Converting map: {path}", flush=True)
                assert not (status & pygit2.GIT_STATUS_INDEX_NEW)
                head_map = dmm.DMM.from_bytes(head_blob.read_raw())
                merged_map = merge_map(index_map, head_map)

            # write to the index
            blob_id = repo.create_blob(merged_map.to_bytes())
            repo.index.add(pygit2.IndexEntry(path, blob_id, index_entry.mode))
            changed += 1

            # write to the working directory if that's clean
            if status & skip_to_file_statuses:
                print(
                    f"Warning: {path} has unindexed changes, not overwriting them"
                )
            else:
                merged_map.to_file(os.path.join(repo.workdir, path))

    if changed:
        repo.index.write()
    return 0
Example #14
0
 def test_create_entry(self):
     index = self.repo.index
     hello_entry = index['hello.txt']
     entry = pygit2.IndexEntry('README.md', hello_entry.oid,
                               hello_entry.mode)
     index.add(entry)
     tree_id = index.write_tree()
     self.assertEqual('60e769e57ae1d6a2ab75d8d253139e6260e1f912',
                      str(tree_id))
Example #15
0
 def _write_feature():
     feature = next(feature_iter)
     dest_path, dest_data = dataset.encode_feature(
         feature, **kwargs)
     blob_id = repo.create_blob(dest_data)
     entry = pygit2.IndexEntry(f"{dataset.path}/{dest_path}",
                               blob_id,
                               pygit2.GIT_FILEMODE_BLOB)
     index.add(entry)
Example #16
0
def write_feature_to_dataset_entry(feature, dataset, repo):
    """
    Adds the given feature to the given dataset by writing a blob to the sno repo.
    Returns the IndexEntry that refers to that blob - this IndexEntry still needs
    to be written to the repo to complete the write.
    """
    feature_path, feature_data = dataset.encode_feature(feature)
    blob_id = repo.create_blob(feature_data)
    return pygit2.IndexEntry(feature_path, blob_id, pygit2.GIT_FILEMODE_BLOB)
Example #17
0
    def write_resolved_tree(self, repo):
        """
        Write all the merged entries and the resolved conflicts to a tree in the given repo.
        Resolved conflicts will be written the same as merged entries in the resulting tree.
        Only works when all conflicts are resolved.
        """
        assert not self.unresolved_conflicts
        index = pygit2.Index()

        # Entries that were merged automatically by libgit2, often trivially:
        for e in self.entries.values():
            index.add(pygit2.IndexEntry(e.path, e.id, e.mode))

        # libgit2 leaves entries in the main part of the index, even if they are conflicts.
        # We make sure this index only contains merged entries and resolved conflicts.
        index.remove_all(list(self._conflicts_paths()))

        # Entries that have been explicitly selected to resolve conflicts:
        for e in self._resolves_entries():
            index.add(pygit2.IndexEntry(e.path, e.id, e.mode))

        return index.write_tree(repo)
Example #18
0
    def unstage(self, path):

        self._logger.info("Unstage {}".format(path))
        index = self.index
        index.remove(path)
        head_tree = self.head.tree
        if path in head_tree:
            # Restore index to HEAD
            tree_entry = head_tree[path]
            index_entry = git.IndexEntry(path, tree_entry.oid, tree_entry.filemode)
            self._logger.info("Reset index to HEAD for {}".format(path))
            index.add(index_entry)
        index.write()
Example #19
0
 def add_from_fs(self, dir_to_add, prefix=""):
     """Add all files under dir_to_add to index recursively."""
     for root, dirnames, filenames in os.walk(dir_to_add):
         if filenames:
             rel_root = os.path.relpath(root, dir_to_add)
         for filename in filenames:
             disk_path = os.path.join(root, filename)
             repo_path = posixpath.normpath(
                 posixpath.join(prefix, rel_root, filename))
             self.index.add(
                 pygit2.IndexEntry(
                     repo_path,
                     self.repo.create_blob_fromdisk(disk_path),
                     os.stat(disk_path).st_mode,
                 ))
Example #20
0
def add_other_files(app, myRepo, myIndex, overrides):
    logging.info("Agregando otros archivos, overrides: " +
                 repr(overrides.keys()))
    file_name = get_filepath(app.package_name, app.md5)
    zipfile = ZipFile(file_name, 'r')
    for filename in zipfile.namelist():
        if filename in overrides:
            logging.info("Storing " + filename + " from overrides\n")
            myBytes = overrides[filename]
        else:
            myBytes = zipfile.read(filename)
            logging.info("Storing " + filename + "from zip")
        contents = myRepo.create_blob(myBytes)
        myIndex.add(
            pygit2.IndexEntry(filename, contents, pygit2.GIT_FILEMODE_BLOB))
    zipfile.close()
Example #21
0
def main(repo):

    if repo.index.conflicts:
        print("You need to resolve merge conflicts first.")
        return 1

    changed = 0
    for path, status in repo.status().items():
        if path.endswith(".dmm") and (
                status &
            (pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_INDEX_NEW)):
            # read the index
            index_entry = repo.index[path]
            index_map = dmm.DMM.from_bytes(repo[index_entry.id].read_raw())

            try:
                head_blob = repo[repo[repo.head.target].tree[path].id]
            except KeyError:
                # New map, no entry in HEAD
                print("Converting new map: {}".format(path))
                assert (status & pygit2.GIT_STATUS_INDEX_NEW)
                merged_map = index_map
            else:
                # Entry in HEAD, merge the index over it
                print("Merging map: {}".format(path))
                assert not (status & pygit2.GIT_STATUS_INDEX_NEW)
                head_map = dmm.DMM.from_bytes(head_blob.read_raw())
                merged_map = merge_map(index_map, head_map)

            # write to the index
            blob_id = repo.create_blob(merged_map.to_bytes())
            repo.index.add(pygit2.IndexEntry(path, blob_id, index_entry.mode))
            changed += 1

            # write to the working directory if that's clean
            if status & (pygit2.GIT_STATUS_WT_DELETED
                         | pygit2.GIT_STATUS_WT_MODIFIED):
                print(
                    "Warning: {} has unindexed changes, not overwriting them".
                    format(path))
            else:
                merged_map.to_file(os.path.join(repo.workdir, path))

    if changed:
        repo.index.write()
        print("Merged {} maps.".format(changed))
    return 0
Example #22
0
    def setUp(self):
        self.maxDiff = None
        tests.reset_emulator()

        # TODO(ochang): Refactor out into common test utilities.
        self.original_clone = pygit2.clone_repository
        self.clone_repository_patcher = mock.patch('pygit2.clone_repository')
        mock_clone = self.clone_repository_patcher.start()
        mock_clone.side_effect = self.mock_clone

        patcher = mock.patch('osv.types.utcnow')
        mock_utcnow = patcher.start()
        mock_utcnow.return_value = datetime.datetime(2021, 1, 1)
        self.addCleanup(patcher.stop)

        # Initialise fake source_repo.
        self.tmp_dir = tempfile.TemporaryDirectory()
        self.remote_source_repo_path = os.path.join(self.tmp_dir.name,
                                                    'source_repo')
        repo = pygit2.init_repository(self.remote_source_repo_path, True)
        tree = repo.TreeBuilder().write()
        author = pygit2.Signature('OSV', '*****@*****.**')
        repo.create_commit('HEAD', author, author, 'Initial commit', tree, [])

        # Add a source.
        oid = repo.write(
            pygit2.GIT_OBJ_BLOB,
            self._load_test_data(os.path.join(TEST_DATA_DIR, 'BLAH-123.yaml')))
        repo.index.add(
            pygit2.IndexEntry('BLAH-123.yaml', oid, pygit2.GIT_FILEMODE_BLOB))
        repo.index.write()
        tree = repo.index.write_tree()
        repo.create_commit('HEAD', author, author, 'Changes', tree,
                           [repo.head.peel().oid])

        osv.SourceRepository(id='source',
                             name='source',
                             repo_url='file://' + self.remote_source_repo_path,
                             repo_username='').put()

        osv.Bug(id='BLAH-123', project='blah.com/package',
                ecosystem='golang').put()
Example #23
0
 def fetch(self, uni_id, robot_id):
     print("fetch({}, {})".format(uni_id, robot_id))
     # Clone student repository
     if self.clone_repository(uni_id):
         # Get output.txt
         if self.sftp_file("9" + robot_id, "output.txt", "get"):
             # Remove log directory from repository
             path = os.getcwd() + "/student/logs"
             try:
                 shutil.rmtree(path)
             except:
                 pass
             os.mkdir("student/logs")
             # Rename based on timestamp
             filename = str(int(time.time())) + ".txt"
             relpath = "student/logs/" + filename
             os.rename("output.txt", relpath)
             # Add log to git commit
             s = pygit2.Signature('Roboproge Logmaster', '*****@*****.**')
             file_contents = ""
             with open(relpath) as f:
                 for line in f.readlines():
                     file_contents += line
             contents = self.repository.create_blob(file_contents)
             self.repository.index.add(
                 pygit2.IndexEntry("logs/" + filename, contents,
                                   pygit2.GIT_FILEMODE_BLOB))
             self.repository.index.write()
             tree = self.repository.index.write_tree()
             master = self.repository.lookup_branch("master")
             self.repository.create_commit('refs/heads/master', s, s,
                                           'Log upload', tree,
                                           [master.target])
             # Push commit
             self.repository.remotes["origin"].push(
                 ["refs/heads/master"], callbacks=self.callbacks)
             # Remove repository
             self.remove_student_repository()
         else:
             print("Unable to download output file!")
     else:
         print("Unable to clone repository!")
Example #24
0
    def _save(self, name, content):
        """Save the File content under the given path name.

            @param name: file path, relative to the repository root
            @param content: File content (temporary or in-memory file object)
            @return: the name under which the content was saved
        """
        path = self._git_path(name)
        if hasattr(content, 'temporary_file_path'):
            blob_id = self.repository.create_blob_fromdisk(content.temporary_file_path())
            content.close()
        else:
            # TODO Yes, we're loading a potentially big file in memory
            # Use create_blob_fromiobase when available
            blob_id = self.repository.create_blob(content.read())
        # The index is a flatten representation of the repository tree
        index = self.repository.index
        index.add(pygit2.IndexEntry(path, blob_id, pygit2.GIT_FILEMODE_BLOB))
        tree_id = index.write_tree()
        self._commit(app_config.SAVE_MESSAGE, tree_id)
        return name
Example #25
0
def stage_apk(app, overrides):
    myRepo = pygit2.Repository(repo_name(app.package_name))
    master = myRepo.lookup_branch("master")
    #	if master == None:
    #myTreeGen = myRepo.TreeBuilder()
    #	else:
    #		lastcommit = myRepo.get(master.target)
    #		lastTree = lastcommit.tree.oid
    #myTreeGen = myRepo.TreeBuilder(lastTree)
    myIndex = myRepo.index
    for sourcefile in app.sourcefile_set.all():
        logging.info("Storing " + sourcefile.file_name + "\n")
        src = (sourcefile.file_contents).encode('ascii', 'replace').replace(
            "\\n", "\n")
        contents = myRepo.create_blob(src)
        myIndex.add(
            pygit2.IndexEntry(sourcefile.file_name + ".java", contents,
                              pygit2.GIT_FILEMODE_BLOB))
    logging.info("Listo el codigo fuente")
    add_other_files(app, myRepo, myIndex, overrides)
    #myTreeGen.insert(sourcefile.file_name, contents, pygit2.GIT_FILEMODE_BLOB)
    #myTree = myTreeGen.write()
    myTree = myIndex.write_tree()
    version = app.version
    author = pygit2.Signature("Alice Author", "*****@*****.**")
    committer = pygit2.Signature("Alice Author", "*****@*****.**")
    if master == None:
        myRepo.create_commit('refs/heads/master', author, committer, version,
                             myTree, [])
    else:
        myRepo.create_commit('refs/heads/master', author, committer, version,
                             myTree, [master.target])
    myRepo.create_branch(version, myRepo.head.get_object())
    myRemote = myRepo.remotes[0]
    #myRemote.credentials = pygit2.UserPass("marvin",marvin_git_passwd)
    credentials = pygit2.UserPass("marvin", marvin_git_passwd)
    callbacks = pygit2.RemoteCallbacks(credentials=credentials)
    myRemote.push(["refs/heads/master"], callbacks=callbacks)
    myRemote.push(["refs/heads/" + version], callbacks=callbacks)
Example #26
0
    def setUp(self):
        self.maxDiff = None  # pylint: disable=invalid-name
        self.tmp_dir = tempfile.mkdtemp()
        self.remote_source_repo_path = os.path.join(self.tmp_dir,
                                                    'source_repo')

        patcher = mock.patch('osv.types.utcnow')
        mock_utcnow = patcher.start()
        mock_utcnow.return_value = datetime.datetime(2021, 1, 1)
        self.addCleanup(patcher.stop)

        # Initialise fake source_repo.
        repo = pygit2.init_repository(self.remote_source_repo_path, True)
        tree = repo.TreeBuilder().write()
        author = pygit2.Signature('OSV', '*****@*****.**')
        repo.create_commit('HEAD', author, author, 'Initial commit', tree, [])

        # Add a fake user change.
        with open(os.path.join(self.remote_source_repo_path, '2021-111.yaml'),
                  'w') as f:
            f.write('')

        oid = repo.write(pygit2.GIT_OBJ_BLOB, '')
        repo.index.add(
            pygit2.IndexEntry('2021-111.yaml', oid, pygit2.GIT_FILEMODE_BLOB))
        repo.index.write()
        tree = repo.index.write_tree()
        author = pygit2.Signature('User', 'user@email')
        repo.create_commit('HEAD', author, author, 'Changes', tree,
                           [repo.head.peel().oid])

        osv.SourceRepository(id='oss-fuzz',
                             name='oss-fuzz',
                             repo_url='file://' + self.remote_source_repo_path,
                             repo_username='').put()

        osv.Bug(
            id='2017-134',
            affected=['FILE5_29', 'FILE5_30'],
            affected_fuzzy=['5-29', '5-30'],
            confidence=100,
            details=(
                'OSS-Fuzz report: '
                'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064\n\n'
                'Crash type: Heap-buffer-overflow READ 1\n'
                'Crash state:\ncdf_file_property_info\ncdf_file_summary_info\n'
                'cdf_check_summary_info\n'),
            ecosystem='',
            fixed='19ccebafb7663c422c714e0c67fa4775abf91c43',
            has_affected=True,
            issue_id='1064',
            project='file',
            public=True,
            reference_urls=[
                'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064'
            ],
            regressed='17ee4cf670c363de8d2ea4a4897d7a699837873f',
            repo_url='https://github.com/file/file.git',
            search_indices=['file', '2017-134', '2017', '134'],
            severity='MEDIUM',
            sort_key='2017-0000134',
            source_id='oss-fuzz:5417710252982272',
            status=1,
            summary='Heap-buffer-overflow in cdf_file_property_info',
            timestamp=datetime.datetime(2021, 1, 15, 0, 0, 24, 559102)).put()
def add_update_to_repo(sess, repo, filename, data):
    blob_id = repo.create_blob(data)

    entry = pygit2.IndexEntry(filename, blob_id, pygit2.GIT_FILEMODE_BLOB)
    repo.index.add(entry)
    repo.index.write()
Example #28
0
 def add_file(self, path, contents):
   """Adds a file."""
   oid = self._repo.write(pygit2.GIT_OBJ_BLOB, contents)
   self._repo.index.add(pygit2.IndexEntry(path, oid, pygit2.GIT_FILEMODE_BLOB))
   self._repo.index.write()
Example #29
0
def main(repo):
    if repo.index.conflicts:
        print("You need to resolve merge conflicts first.")
        return 1

    # Ensure the index is clean.
    for path, status in repo.status().items():
        if status & pygit2.GIT_STATUS_IGNORED:
            continue
        if status & STATUS_INDEX:
            print("You have changes staged for commit. Commit them or unstage them first.")
            print("If you are about to commit maps for the first time, run `Run Before Committing.bat`.")
            return 1
        if path.endswith(".dmm") and (status & STATUS_WT):
            print("You have modified maps. Commit them first.")
            print("If you are about to commit maps for the first time, run `Run Before Committing.bat`.")
            return 1

    # Read the HEAD commit.
    head_commit = repo[repo.head.target]
    head_files = {}
    for path, blob in walk_tree(head_commit.tree):
        if path.endswith(".dmm"):
            data = blob.read_raw()
            if not data.startswith(TGM_HEADER):
                head_files[path] = dmm.DMM.from_bytes(data)

    if not head_files:
        print("All committed maps appear to be in the correct format.")
        print("If you are about to commit maps for the first time, run `Run Before Committing.bat`.")
        return 1

    # Work backwards to find a base for each map, converting as found.
    converted = {}
    if len(head_commit.parents) != 1:
        print("Unable to automatically fix anything because HEAD is a merge commit.")
        return 1
    commit_message_lines = []
    working_commit = head_commit.parents[0]
    while len(converted) < len(head_files):
        for path in head_files.keys() - converted.keys():
            try:
                blob = working_commit.tree[path]
            except KeyError:
                commit_message_lines.append(f"{'new':{ABBREV_LEN}}: {path}")
                print(f"Converting new map: {path}")
                converted[path] = head_files[path]
            else:
                data = blob.read_raw()
                if data.startswith(TGM_HEADER):
                    str_id = str(working_commit.id)[:ABBREV_LEN]
                    commit_message_lines.append(f"{str_id}: {path}")
                    print(f"Converting map: {path}")
                    converted[path] = merge_map(head_files[path], dmm.DMM.from_bytes(data))
        if len(working_commit.parents) != 1:
            print("A merge commit was encountered before good versions of these maps were found:")
            print("\n".join(f"    {x}" for x in head_files.keys() - base_files.keys()))
            return 1
        working_commit = working_commit.parents[0]

    # Okay, do the actual work.
    tree_builder = repo.TreeBuilder(head_commit.tree)
    for path, merged_map in converted.items():
        blob_oid = repo.create_blob(merged_map.to_bytes())
        insert_into_tree(repo, tree_builder, path, blob_oid)
        repo.index.add(pygit2.IndexEntry(path, blob_oid, repo.index[path].mode))
        merged_map.to_file(os.path.join(repo.workdir, path))

    # Save the index.
    repo.index.write()

    # Commit the index to the current branch.
    signature = pygit2.Signature(repo.config['user.name'], repo.config['user.email'])
    joined = "\n".join(commit_message_lines)
    repo.create_commit(
        repo.head.name,
        signature,  # author
        signature,  # committer
        f'Convert maps to TGM\n\n{joined}\n\nAutomatically commited by: {os.path.relpath(__file__, repo.workdir)}',
        tree_builder.write(),
        [head_commit.id],
    )

    # Success.
    print("Successfully committed a fixup. Push as needed.")
    return 0
Example #30
0
    def do_merge(self, synced_branch: pygit2.IndexEntry,
                 theirs_branch: pygit2.IndexEntry) -> None:
        theirs_commit = self.repo[theirs_branch.target]

        # synced_branch = self.repo.branches[synced_branch.name]
        merge_result, _ = self.repo.merge_analysis(theirs_branch.target,
                                                   synced_branch.name)

        if merge_result & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE:
            return

        merged_index = self.repo.merge_commits(synced_branch, theirs_commit)

        if merged_index.conflicts:

            for (base_index, ours_index,
                 theirs_index) in list(merged_index.conflicts):
                path = None

                base = None
                if base_index is not None:
                    base = sakdb_loads(
                        self.repo[base_index.oid].data.decode("utf-8"))
                    path = Path(base_index.path)
                ours = None
                if ours_index is not None:
                    ours = sakdb_loads(
                        self.repo[ours_index.oid].data.decode("utf-8"))
                    path = Path(ours_index.path)
                theirs = None
                if theirs_index is not None:
                    theirs = sakdb_loads(
                        self.repo[theirs_index.oid].data.decode("utf-8"))
                    path = Path(theirs_index.path)

                merged = merge(base, ours, theirs)
                if merged is None:
                    raise Exception(
                        "There was some unresolved merge conflict here.")

                merged_str = sakdb_dumps(merged)

                blob = self.repo.create_blob(merged_str)
                new_entry = pygit2.IndexEntry(str(path), blob,
                                              pygit2.GIT_FILEMODE_BLOB)
                merged_index.add(new_entry)

                del merged_index.conflicts[str(path)]

        user = self.repo.default_signature
        tree = merged_index.write_tree()
        message = f"Merge {theirs_branch.name}"

        # Move the namespace branch to the synced branch.
        self.repo.create_commit(
            synced_branch.name,
            user,
            user,
            message,
            tree,
            [synced_branch.target, theirs_branch.target],
        )