def list_generate(bad, good):
    notable_hashes = []
    start = None
    end = None

    if git.is_ancestor('fix-pack-base-7010', bad):
        if git.is_ancestor('fix-pack-base-7010', good):
            start = bad if git.is_ancestor(bad, good) else good
            end = bad if start == good else good
            notable_hashes = sublist_generate(start + '~1', end)
        else:
            start = bad
            end = good
            notable_hashes = notable_hashes + sublist_generate(
                'cc57347219da4911d30b154188a99c6a628f6079', end)
            notable_hashes = notable_hashes + sublist_generate(
                start + '~1', 'fix-pack-de-27-7010')
    else:
        if git.is_ancestor('fix-pack-base-7010', good):
            start = good
            end = bad

            notable_hashes = notable_hashes + sublist_generate(
                'cc57347219da4911d30b154188a99c6a628f6079', end)
            notable_hashes = notable_hashes + sublist_generate(
                start + '~1', 'fix-pack-de-27-7010')
        else:
            bad_first = git.is_ancestor(bad, good)
            good_first = git.is_ancestor(good, bad)

            if bad_first and not good_first:
                start = bad
                end = good
            elif good_first and not bad_first:
                start = good
                end = bad
            else:
                common_ancestor = git.merge_base(bad, good).strip()

                bad_first = len(
                    git.log('--pretty=%H',
                            '%s..%s' % (common_ancestor, bad)).split('\n'))
                good_first = len(
                    git.log('--pretty=%H',
                            '%s..%s' % (common_ancestor, good)).split('\n'))

                start = common_ancestor
                end = bad if bad_first > good_first else good

            notable_hashes = sublist_generate(start + '~1', end)

    if end == good:
        notable_hashes[0]['status'] = 'good'
        notable_hashes[-1]['status'] = 'bad'
    else:
        notable_hashes[-1]['status'] = 'good'
        notable_hashes[0]['status'] = 'bad'

    generate_html(notable_hashes)
Example #2
0
    def post(self):
        review_req = flask.request.json
        print review_req

        try:
            project = review_req['project']
            title = review_req.get('title', '')
            latest_round = review_req['latest_round']

            project_id = project['project_id']
            base_branch = latest_round['merge_base_branch']
            base_commit = latest_round['merge_base_commit']
            review_branch = latest_round['branch_tip_name']
            review_commit = latest_round['branch_tip_commit']
            reviewers = review_req.get('reviewers', []) or []
            observers = review_req.get('observers', []) or []

        except KeyError as e:
            flask.abort(400, str(e))

        # TODO: make sure there isn't already a review with these specs

        # find common ancestor
        base_commit = git.merge_base(project_id, base_commit, review_commit)
        authors = list(git.rev_list_authors(project_id, base_commit, review_commit))
        reviewers = list(set(reviewers))
        observers = list(set(observers))

        logger.debug('Creating review from %s@%s -> %s@%s; title=%s',
                     review_branch,
                     review_commit[0:7],
                     base_branch,
                     base_commit[0:7],
                     title)

        review = model.Review(project_id=project_id, status='new', title=title, authors=authors, reviewers=reviewers, observers=observers)
        db.session().add(review)

        round = create_round(review, base_branch, base_commit, review_branch, review_commit)
        db.session().add(round)

        db.session().commit()

        logger.debug('Review %d: created.', review.review_id)
        return {'review_id': review.review_id}
Example #3
0
    def put(self, review_id):
        # for adding rounds
        print flask.request.json

        review = db.session().query(model.Review).filter_by(review_id=review_id).one()
        branches = git.branch_list(review.project_id)

        # extract and validate arguments
        base_branch = flask.request.json.get('merge_base_branch')
        review_branch = flask.request.json.get('branch_tip_name')

        base_commit = [branch for branch in branches if branch['name'] == base_branch]
        review_commit = [branch for branch in branches if branch['name'] == review_branch]

        if review_branch is None or len(base_commit) != 1 or len(review_commit) != 1:
            flask.abort(400)

        base_commit = base_commit[0]['commit']
        review_commit = review_commit[0]['commit']

        # replace HEAD of base branch with merge-base of the two branches
        base_commit = git.merge_base(review.project_id, base_commit, review_commit)

        # if this is the same as the latest round, don't add it
        latest_round = review.rounds[-1]

        if (latest_round.merge_base_branch == base_branch and
            latest_round.merge_base_commit == base_commit and
            latest_round.branch_tip_name == review_branch and
            latest_round.branch_tip_commit == review_commit):
            return self.get(review_id)

        # create round from base to branch
        round = create_round(review, base_branch, base_commit, review_branch, review_commit)
        db.session().add(round)

        db.session().commit()

        return self.get(review_id)
Example #4
0
    def _check_new_branch(self, branch, input_work_dir, output_work_dir,
                          output_reference):
        # try to find merge-base in input tree,
        # assumes master branch is always mirrored
        #
        # this handles the case of having created a new branch,
        # and asking for that to be mirrored into the prune tree.
        base_id = git.merge_base('origin/' + self.master,
                                 'origin/' + branch,
                                 tree=input_work_dir)
        git.clone(output_reference, output_work_dir, options=['-q'])
        git.set_origin_url(self._output_tree, output_work_dir)

        # try to find the merge-base or its parent/grandparent/... in the
        # output tree - since it should have been branched from the master
        # (or in any case we look at the merge-base between master and it)
        # this should exist - HOWEVER: some commits might not be mirrored,
        # so look for the *parent [with a reasonable limit]
        for offset in range(0, self.max_parents):
            search = git.rev_parse(rev='%s~%d' % (base_id, offset),
                                   tree=input_work_dir)
            self.debug('search for %s~%d=%s:' % (base_id, offset, search))
            grep = '%s: %s' % (self._commit_id_prefix, search)
            out_commits = git.log(options=[
                '--grep', grep, '--format=format:%H',
                'origin/' + self.output_branch_name(self.master)
            ],
                                  tree=output_work_dir)
            out_commits = out_commits.split()
            if not out_commits or len(out_commits) > 1:
                self.debug('not found')
                continue
            start_commit = out_commits[0]
            self.debug('found at %s' % start_commit)
            return start_commit
        raise Exception('failed to find parent/grandparent/...')
Example #5
0
    def _check_new_branch(self, branch, input_work_dir, output_work_dir,
                          output_reference):
        # This handles the case of having created a new branch,
        # and asking for that to be mirrored into the prune tree.
        #
        # Try to find a starting point in the input tree. We assume
        # this will basically always succeed, since the master branch
        # is always mirrored, we _should_ find something (but can fail
        # if somebody created a branch without a merge-base.)

        # unfortunately we now need to do this first, to sort out which
        # branches we already know in the output
        git.clone(output_reference, output_work_dir, options=['-q'])

        self.debug("trying to find starting point for new branch %s" % branch)
        candidate_branches = []
        for other in self._branches:
            if other == branch:
                continue
            out_branch = 'origin/' + self.output_branch_name(other)
            try:
                git.rev_parse(out_branch, tree=output_work_dir)
            except:
                self.debug("    branch %s doesn't exist in output %s (yet)" %
                           (out_branch, output_work_dir))
                continue
            candidate_branches.append(other)

        potential_merge_bases = []
        for other in candidate_branches:
            try:
                base = git.merge_base('origin/' + other,
                                      'origin/' + branch,
                                      tree=input_work_dir)
                potential_merge_bases.append(base)
                self.debug("    base to %s is %s" % (other, base))
            except git.GitError:
                self.debug("    no base to %s" % (other, ))
        bases = git.independent_commits(potential_merge_bases,
                                        tree=input_work_dir)
        self.debug("found starting points %s" % (", ".join(bases)))
        assert len(bases) == 1, "No single merge base found: %r" % bases
        base_id = bases[0]

        base_branch = None
        for other in candidate_branches:
            if git.merge_base('origin/' + other, base_id,
                              tree=input_work_dir) == base_id:
                base_branch = 'origin/' + self.output_branch_name(other)
                break
        assert base_branch, "This shouldn't happen, found no base branch?!"

        # try to find the merge-base or its parent/grandparent/... in the
        # output tree - since it should have been branched from the master
        # (or in any case we look at the merge-base between master and it)
        # this should exist - HOWEVER: some commits might not be mirrored,
        # so look for the *parent [with a reasonable limit]
        for offset in range(0, self.max_parents):
            search = git.rev_parse(rev='%s~%d' % (base_id, offset),
                                   tree=input_work_dir)
            self.debug('search for %s~%d=%s:' % (base_id, offset, search))
            grep = '%s: %s' % (self._commit_id_prefix, search)
            out_commits = git.log(
                options=['--grep', grep, '--format=format:%H', base_branch],
                tree=output_work_dir)
            out_commits = out_commits.split()
            if not out_commits or len(out_commits) > 1:
                self.debug('not found')
                continue
            start_commit = out_commits[0]
            self.debug('found at %s' % start_commit)
            return start_commit
        raise Exception('failed to find parent/grandparent/...')