def gecko_push()

in sync/landing.py [0:0]


def gecko_push(git_gecko: Repo,
               git_wpt: Repo,
               repository_name: str,
               hg_rev: str,
               raise_on_error: bool = False,
               base_rev: Any | None = None,
               ) -> None:
    rev = git_gecko.rev_parse(cinnabar(git_gecko).hg2git(hg_rev))
    last_sync_point, base_commit = LandingSync.prev_gecko_commit(git_gecko,
                                                                 repository_name)

    if base_rev is None and git_gecko.is_ancestor(rev, base_commit.commit):
        logger.info("Last sync point moved past commit")
        return

    landed_central = repository_name == "mozilla-central"
    revish = f"{base_commit.sha1}..{rev.hexsha}"

    landing_sync = current(git_gecko, git_wpt)
    for commit in git_gecko.iter_commits(revish,
                                         reverse=True):
        gecko_commit = sync_commit.GeckoCommit(git_gecko, commit.hexsha)
        logger.debug("Processing commit %s" % gecko_commit.sha1)
        if landed_central and gecko_commit.is_landing:
            logger.info("Found wptsync landing in commit %s" % gecko_commit.sha1)
            if gecko_commit.bug is None:
                logger.error("Commit %s looked link a landing, but had no bug" %
                             gecko_commit.sha1)
                continue
            syncs = LandingSync.for_bug(git_gecko,
                                        git_wpt,
                                        gecko_commit.bug,
                                        statuses=None,
                                        flat=True)
            if syncs:
                sync = syncs[0]
                logger.info("Found sync %s" % sync.process_name)
                with SyncLock("landing", None) as lock:
                    assert isinstance(lock, SyncLock)
                    with syncs[0].as_mut(lock):
                        sync.finish()
            else:
                logger.error("Failed to find sync for commit")
        elif gecko_commit.is_backout:
            backed_out, _ = gecko_commit.landing_commits_backed_out()
            if backed_out:
                logger.info("Commit %s backs out wpt sync landings" % gecko_commit.sha1)
            for backed_out_commit in backed_out:
                bug = backed_out_commit.bug
                syncs = []
                if bug is not None:
                    syncs = LandingSync.for_bug(git_gecko, git_wpt, bug,
                                                statuses=None, flat=True)
                if syncs:
                    # TODO: should really check if commit is actually part of the sync if there's >1
                    # TODO: reopen landing? But that affects the invariant that there is only one
                    sync = syncs[0]
                    logger.info("Found sync %s" % sync.process_name)
                    with SyncLock("landing", None) as lock:
                        assert isinstance(lock, SyncLock)
                        with sync.as_mut(lock):
                            sync.error = "Landing was backed out"  # type: ignore
                else:
                    logger.error("Failed to find sync for commit")
        elif gecko_commit.is_downstream:
            syncs = []
            bug = gecko_commit.bug
            if bug is not None:
                syncs = LandingSync.for_bug(git_gecko, git_wpt, bug,
                                            statuses=None, flat=True)
            for sync in syncs:
                sync = syncs[0]
                with SyncLock("landing", None) as lock:
                    assert isinstance(lock, SyncLock)
                    with sync.as_mut(lock):
                        sync.finish()

    # TODO: Locking here
    with SyncLock("landing", None) as lock:
        assert isinstance(lock, SyncLock)
        with last_sync_point.as_mut(lock):
            assert last_sync_point.commit is not None
            if not git_gecko.is_ancestor(rev, last_sync_point.commit.commit):
                last_sync_point.commit = rev.hexsha  # type: ignore

    if landing_sync and landing_sync.status == "complete":
        start_next_landing()