Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ options:
-h, --help show this help message and exit
-V, --version show program's version number and exit
--dry-run Prints out the commands, but not executed
--pr-remote REMOTE Git remote to use for PR branches
--pr-remote REMOTE Git remote to use for PR branches (default:
remote.pushDefault or origin)
--upstream-remote REMOTE
Git remote to use for upstream branches
--abort Abort current cherry-pick and clean up branch
Expand Down Expand Up @@ -89,9 +90,11 @@ $ git remote add upstream https://github.com/python/cpython.git
```

By default, the PR branches used to submit pull requests back to the main
repository are pushed to `origin`. If this is incorrect, then the correct
remote will need be specified using the `--pr-remote` option (e.g.
`--pr-remote pr` to use a remote named `pr`).
repository are pushed to Git's `remote.pushDefault`, or `origin` if that is
not set. To set it for a group of checkouts, use an
[`includeIf`](https://git-scm.com/docs/git-config#_conditional_includes)
in your global Git config. To use a remote named `pr`, either pass
`--pr-remote pr` or set `remote.pushDefault` to `pr`.


## Cherry-picking 🐍🍒⛏️
Expand Down Expand Up @@ -122,7 +125,8 @@ Use the full commit hash for `cherry_picker.py`.

```
--dry-run Dry Run Mode. Prints out the commands, but not executed.
--pr-remote REMOTE Specify the git remote to push into. Default is 'origin'.
--pr-remote REMOTE Specify the git remote to push into. Default is
remote.pushDefault or 'origin'.
--upstream-remote REMOTE Specify the git remote to use for upstream branches.
Default is 'upstream' or 'origin' if the former doesn't exist.
--status Do `git status` in cpython directory.
Expand Down
30 changes: 18 additions & 12 deletions cherry_picker/cherry_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def __init__(
if dry_run:
print("Dry run requested, listing expected command sequence")

self.pr_remote = pr_remote
self.pr_remote = pr_remote or get_git_config_val("remote.pushDefault", "origin")
self.upstream_remote = upstream_remote
self.commit_sha1 = commit_sha1
self.branches = branches
Expand Down Expand Up @@ -727,12 +727,8 @@ class state:
def is_mirror(self) -> bool:
"""Return True if the current repository was created with --mirror."""

cmd = ["git", "config", "--local", "--get", "remote.origin.mirror"]
try:
out = self.run_cmd(cmd, required_real_result=True)
except subprocess.CalledProcessError:
return False
return out.startswith("true")
mirror = get_git_config_val("remote.origin.mirror", "", local=True)
return mirror.startswith("true")


def get_parser():
Expand All @@ -751,8 +747,11 @@ def get_parser():
parser.add_argument(
"--pr-remote",
metavar="REMOTE",
default="origin",
help="Git remote to use for PR branches",
default=None,
help=(
"Git remote to use for PR branches "
"(default: remote.pushDefault or origin)"
),
)
parser.add_argument(
"--upstream-remote",
Expand Down Expand Up @@ -1095,15 +1094,22 @@ def wipe_cfg_vals_from_git_cfg(*cfg_opts):
def load_val_from_git_cfg(cfg_key_suffix):
"""Retrieve one option from Git config."""
cfg_key = f'cherry-picker.{cfg_key_suffix.replace("_", "-")}'
cmd = "git", "config", "--local", "--get", cfg_key
return get_git_config_val(cfg_key, local=True)


def get_git_config_val(key, default=None, *, local=False):
"""Retrieve one option from Git config, or default if unset or empty."""
scope = ("--local",) if local else ()
cmd = "git", "config", *scope, "--get", key
try:
return (
value = (
subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
.strip()
.decode("utf-8")
)
except subprocess.CalledProcessError:
return None
value = None
return value or default


def from_git_rev_read(path):
Expand Down
10 changes: 10 additions & 0 deletions cherry_picker/test_cherry_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
get_commits_from_backport_branch,
get_current_branch,
get_full_sha_from_short,
get_git_config_val,
get_sha1_from,
get_state,
load_config,
Expand Down Expand Up @@ -317,6 +318,15 @@ def test_upstream_name(
assert cp.upstream == remote_name


@pytest.mark.parametrize(
"value,expected", ((None, "default"), ("", "default"), ("set", "set"))
)
def test_get_git_config_val(value, expected, tmp_git_repo_dir, git_config):
if value is not None:
git_config("--local", "cherry-picker.test-key", value)
assert get_git_config_val("cherry-picker.test-key", "default") == expected


@pytest.mark.parametrize(
"remote_to_add,remote_name,upstream_remote",
(
Expand Down
Loading