in bot/tools/copy_diff.py [0:0]
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--source-url",
help="Phabricator source endpoint",
default="https://phabricator.services.mozilla.com/api/",
)
parser.add_argument(
"--source-token",
help="Phabricator source api token",
default=os.environ.get("PHABRICATOR_SOURCE_TOKEN"),
)
parser.add_argument(
"--dest-url",
help="Phabricator destination endpoint",
default="https://phabricator-dev.allizom.org/api/",
)
parser.add_argument(
"--dest-token",
help="Phabricator destination api token",
default=os.environ.get("PHABRICATOR_DEST_TOKEN"),
)
parser.add_argument(
"revision_id",
type=int,
help="Phabricator source revision ID to copy on the destination server",
)
args = parser.parse_args()
source = build_phabricator_api("Source", args.source_url, args.source_token)
print(f"Connected on source: {source.url}")
dest = build_phabricator_api("Destination", args.dest_url, args.dest_token)
print(f"Connected on destination: {dest.url}")
# Load the revision to get the top diff PHID
print(f"Loading revision {args.revision_id}")
revision = source.load_revision(rev_id=args.revision_id)
diff_phid = revision["fields"]["diffPHID"]
# Get the source repo
repo_phid = revision["fields"]["repositoryPHID"]
source_repos = source.request(
"diffusion.repository.search", constraints={"phids": [repo_phid]}
)
assert len(source_repos["data"]) == 1, "Missing repository details"
source_repo = source_repos["data"][0]
print(f"Source revision is on repository {source_repo['fields']['shortName']}")
# Get the matching repo on destination
dest_repos = dest.request(
"diffusion.repository.search",
constraints={"shortNames": [source_repo["fields"]["shortName"]]},
)
assert len(dest_repos["data"]) == 1, "Missing same repo on destination"
dest_repo = dest_repos["data"][0]
print(f"Found matching repository on destination as {dest_repo['phid']}")
# Load the diffs to get the numerical ID
print(f"Loading diffs for {diff_phid}")
source_diffs = source.search_diffs(
diff_phid=diff_phid, attachments={"commits": True}
)
assert len(source_diffs) == 1, "Should only find one diff"
source_diff = source_diffs[0]
# Build the new diff properties using source commits
commits = source_diff["attachments"]["commits"]["commits"]
assert len(commits) > 0, "Missing commits on source diff"
new_properties = {
commit["identifier"]: {
"author": commit["author"]["name"],
"authorEmail": commit["author"]["email"],
"time": 0,
"message": commit["message"],
"commit": commit["identifier"],
"tree": None,
"parents": commit["parents"],
}
for commit in commits
}
# Load top raw diff
raw_diff = source.load_raw_diff(source_diff["id"])
print(f"Loading raw source diff {source_diff['id']}")
# Upload it on target repo
new_diff = dest.request(
"differential.createrawdiff", diff=raw_diff, repositoryPHID=dest_repo["phid"]
)
print(f"Created new diff {new_diff['id']} - {new_diff['phid']}")
# Attach commit information to setup the author
dest.request(
"differential.setdiffproperty",
diff_id=new_diff["id"],
name="local:commits",
data=json.dumps(new_properties),
)
print("Set diff properties")
# Finally create the revision to link all the pieces
new_rev = dest.request(
"differential.revision.edit",
transactions=[
{"type": "update", "value": new_diff["phid"]},
{"type": "title", "value": revision["fields"]["title"]},
{"type": "summary", "value": "Code review bot debug clone."},
],
)
print(f"New revision created as {dest.url}/D{new_rev['object']['id']}")