mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 10:32:10 +00:00
59cfdaaff0
See USAGE for documentation. This tool will be needed to upload to the upstream repository, as we will no longer be able to use repo. Currently, for testing it still points to the chromiumos repository. BUG=b:221088786 TEST=Follow USAGE Change-Id: I4a8d88a8354942f0ddfb7f9420ef1cf7f5885867 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3687419 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
164 lines
5 KiB
Python
Executable file
164 lines
5 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright 2022 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
from impl.common import confirm, run_commands, cmd, CROSVM_ROOT
|
|
import sys
|
|
|
|
USAGE = """\
|
|
./tools/cl [upload|rebase|status]
|
|
|
|
Upload changes to the upstream crosvm gerrit.
|
|
|
|
Multiple projects have their own downstream repository of crosvm and tooling
|
|
to upload to those.
|
|
|
|
This tool allows developers to send commits to the upstream gerrit review site
|
|
of crosvm and helps rebase changes if needed.
|
|
|
|
You need to be on a local branch tracking a remote one. `repo start` does this
|
|
for AOSP and chromiumos, or you can do this yourself:
|
|
|
|
$ git checkout -b mybranch --track origin/main
|
|
|
|
Then to upload commits you have made:
|
|
|
|
[mybranch] $ ./tools/cl upload
|
|
|
|
If you are tracking a different branch (e.g. aosp/main or cros/chromeos), the upload may
|
|
fail if your commits do not apply cleanly. This tool can help rebase the changes, it will
|
|
create a new branch tracking origin/main and cherry-picks your commits.
|
|
|
|
[mybranch] $ ./tools/cl rebase
|
|
[mybranch-upstream] ... resolve conflicts
|
|
[mybranch-upstream] $ git add .
|
|
[mybranch-upstream] $ git cherry-pick --continue
|
|
[mybranch-upstream] $ ./tools/cl upload
|
|
|
|
"""
|
|
|
|
GERRIT_URL = "https://chromium-review.googlesource.com"
|
|
CROSVM_URL = "https://chromium.googlesource.com/chromiumos/platform/crosvm"
|
|
|
|
git = cmd("git")
|
|
curl = cmd("curl --silent --fail")
|
|
chmod = cmd("chmod")
|
|
|
|
|
|
def get_upstream(branch: str = ""):
|
|
try:
|
|
return git(f"rev-parse --abbrev-ref --symbolic-full-name {branch}@{{u}}").stdout()
|
|
except:
|
|
return None
|
|
|
|
|
|
def list_local_changes(branch: str = ""):
|
|
upstream = get_upstream(branch)
|
|
if not upstream:
|
|
return []
|
|
for line in git(f"log --oneline --first-parent {upstream}..{branch or 'HEAD'}").lines():
|
|
yield line.split(" ", 1)
|
|
|
|
|
|
def list_local_branches():
|
|
return git("for-each-ref --format=%(refname:short) refs/heads").lines()
|
|
|
|
|
|
def get_active_upstream():
|
|
upstream = get_upstream()
|
|
if not upstream:
|
|
raise Exception("You are not tracking an upstream branch.")
|
|
parts = upstream.split("/")
|
|
if len(parts) != 2:
|
|
raise Exception(f"Your upstream branch '{upstream}' is not remote.")
|
|
return (parts[0], parts[1])
|
|
|
|
|
|
def prerequisites():
|
|
print("This tool is experimental and a work in progress, please use carefully.")
|
|
print()
|
|
|
|
if not git("remote get-url origin").success():
|
|
print("Setting up origin")
|
|
git("remote add origin", CROSVM_URL).fg()
|
|
if git("remote get-url origin").stdout() != CROSVM_URL:
|
|
print("Your remote 'origin' does not point to the main crosvm repository.")
|
|
if confirm(f"Do you want to fix it?"):
|
|
git("remote set-url origin", CROSVM_URL).fg()
|
|
else:
|
|
sys.exit(1)
|
|
|
|
# Install gerrit commit hook
|
|
hook_path = CROSVM_ROOT / ".git/hooks/commit-msg"
|
|
if not hook_path.exists():
|
|
hook_path.parent.mkdir(exist_ok=True)
|
|
curl(f"{GERRIT_URL}/tools/hooks/commit-msg").write_to(hook_path)
|
|
chmod("+x", hook_path).fg()
|
|
|
|
|
|
def status():
|
|
"""
|
|
Lists all branches and their local commits.
|
|
"""
|
|
for branch in list_local_branches():
|
|
print("Branch", branch, "tracking", get_upstream(branch))
|
|
changes = [*list_local_changes(branch)]
|
|
for sha, title in changes:
|
|
print(" ", title)
|
|
if not changes:
|
|
print(" No changes")
|
|
print()
|
|
|
|
|
|
def rebase():
|
|
"""
|
|
Rebases changes from the current branch onto origin/main.
|
|
|
|
Will create a new branch called 'current-branch'-upstream tracking origin/main. Changes from
|
|
the current branch will then be rebased into the -upstream branch.
|
|
"""
|
|
prerequisites()
|
|
branch_name = git("branch --show-current").stdout()
|
|
upstream_branch_name = branch_name + "-upstream"
|
|
|
|
print(f"Checking out '{upstream_branch_name}'")
|
|
rev = git("rev-parse", upstream_branch_name).stdout(check=False)
|
|
if rev:
|
|
print(f"Leaving behind previous revision of {upstream_branch_name}: {rev}")
|
|
git("checkout -B", upstream_branch_name, "origin/main").fg(quiet=True)
|
|
|
|
print(f"Cherry-picking changes from {branch_name}")
|
|
git(f"cherry-pick {branch_name}@{{u}}..{branch_name}").fg()
|
|
|
|
|
|
def upload():
|
|
"""
|
|
Uploads changes to the crosvm main branch.
|
|
"""
|
|
prerequisites()
|
|
|
|
remote, branch = get_active_upstream()
|
|
changes = [*list_local_changes()]
|
|
if not changes:
|
|
print("No changes to upload")
|
|
return
|
|
|
|
print("Uploading to origin/main:")
|
|
for sha, title in changes:
|
|
print(" ", sha, title)
|
|
print()
|
|
|
|
if (remote, branch) != ("origin", "main"):
|
|
print(f"WARNING! Your changes are based on {remote}/{branch}, not origin/main.")
|
|
print("If gerrit rejects your changes, try `./tools/cl rebase -h`.")
|
|
print()
|
|
if not confirm("Upload anyway?"):
|
|
return
|
|
print()
|
|
|
|
git("push", remote, f"HEAD:refs/for/{branch}").fg()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_commands(upload, rebase, status, usage=USAGE)
|