def add_metadata()

in sync/landing.py [0:0]


    def add_metadata(self, sync: DownstreamSync) -> None:
        logger.info("Adding metadata from downstream sync")

        if self.has_metadata_for_sync(sync):
            logger.info("Metadata already applied for PR %s" % sync.pr)
            return

        if not sync.metadata_commit or sync.metadata_commit.is_empty():
            logger.info("No metadata commit available for PR %s" % sync.pr)
            return

        worktree = self.gecko_worktree.get()

        success = gitutils.cherry_pick(worktree, sync.metadata_commit.sha1)

        if not success:
            logger.info("Cherry-pick failed, trying again with only test-related changes")
            # Try to reset all metadata files that aren't related to an affected test.
            affected_metadata = {os.path.join(env.config["gecko"]["path"]["meta"], item) + ".ini"
                                 for items in sync.affected_tests_readonly.values()
                                 for item in items}
            checkout = []
            status = gitutils.status(worktree)
            for head_path, data in status.items():
                if data["code"] not in {"DD", "AU", "UD", "UA", "DU", "AA", "UU"}:
                    # Only try to reset merge conflicts
                    continue
                path = data["rename"] if data["rename"] else head_path
                if path not in affected_metadata:
                    logger.debug("Resetting changes to %s" % head_path)
                    if data["code"] == "DU":
                        # Files that were deleted in master should just be removed
                        worktree.git.rm(head_path)
                    else:
                        checkout.append(head_path)
            logger.debug("Resetting changes to %s" % " ".join(checkout))
            try:
                worktree.git.checkout("HEAD", "--", *checkout)
                # Now try to commit again
                worktree.git.commit(c=sync.metadata_commit.sha1, no_edit=True)
                success = True
            except git.GitCommandError as e:
                if gitutils.handle_empty_commit(worktree, e):
                    return
                if sync.skip:
                    return
                success = False

        if not success:
            try:
                logger.info("Cherry-pick had merge conflicts trying to automatically resolve")
                status = gitutils.status(worktree)
                for head_path, data in status.items():
                    if data["code"] in {"DD", "UD", "DU"}:
                        # Deleted by remote or local
                        # Could do better here and have the mergetool handle this case
                        logger.info("Removing %s which was deleted somewhere" % head_path)
                        worktree.git.rm(head_path)
                    if data["code"] in {"UA", "AU"}:
                        logger.info("Adding %s which was added somewhere" % head_path)
                        worktree.git.add(head_path)
                logger.info("Running mergetool")
                worktree.git.mergetool(tool="metamerge",
                                       env={"MOZBUILD_STATE_PATH":
                                            repos.Gecko.get_state_path(env.config,
                                                                       worktree.working_dir)})
                worktree.git.commit(c=sync.metadata_commit.sha1, no_edit=True)
                worktree.git.clean(f=True)
                success = True
            except git.GitCommandError as e:
                if gitutils.handle_empty_commit(worktree, e):
                    return
                if sync.skip:
                    return
                logger.error("Failed trying to use mergetool to resolve conflicts")
                raise

        metadata_commit = sync_commit.GeckoCommit(worktree, worktree.head.commit)
        if metadata_commit.msg.startswith(b"Bug None"):
            # If the metadata commit didn't get a valid bug number for some reason,
            # we want to replace the placeholder bug number with the
            # either the sync or landing bug number, otherwise the push will be
            # rejected
            bug_number = sync.bug or self.bug
            new_message = b"Bug %s%s" % (str(bug_number).encode("utf8"),
                                         metadata_commit.msg[len(b"Bug None"):])
            sync_commit.create_commit(worktree, new_message, amend=True)