diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e856b377a..7f43e8d1d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -3,8 +3,8 @@ ## New in git-machete 3.29.0 - added: git config keys `machete.github.prDescriptionIntroStyle` and `machete.gitlab.mrDescriptionIntroStyle` -- added: ability to turn off PR/MR description intro completely by setting the git config keys to `none` (suggested by @tir38) -- added: ability to also include downstream PRs/MRs in PR/MR description intro (suggested by @aouaki) +- added: ability to turn off PR/MR description intro completely by setting the git config key to `none` (suggested by @tir38) +- added: ability to include downstream PRs/MRs in PR/MR description intro by setting the git config key to `full` (suggested by @aouaki) - changed: layout and ordering of PRs/MRs in PR/MR description intro to better match `git machete status` ## New in git-machete 3.28.0 diff --git a/ci/checks/prohibit-github-in-gitlab-files.sh b/ci/checks/prohibit-github-in-gitlab-files.sh new file mode 100755 index 000000000..6932959b1 --- /dev/null +++ b/ci/checks/prohibit-github-in-gitlab-files.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e -o pipefail -u + +if git grep -E -i -n -e 'github' --and --not -e 'report this error|valid GitLab project' -- '*gitlab*' ':!**/prohibit-*-in-*-files.sh'; then + echo + echo 'Stray usage of `github` in GitLab-related file(s), is it a copy-paste error?' + exit 1 +fi diff --git a/ci/checks/prohibit-gitlab-in-github-files.sh b/ci/checks/prohibit-gitlab-in-github-files.sh new file mode 100755 index 000000000..91a648feb --- /dev/null +++ b/ci/checks/prohibit-gitlab-in-github-files.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e -o pipefail -u + +if git grep -E -i -n -e 'gitlab' --and --not -e 'valid GitHub repo' -- '*github*' ':!**/prohibit-*-in-*-files.sh'; then + echo + echo 'Stray usage of `gitlab` in GitHub-related file(s), is it a copy-paste error?' + exit 1 +fi diff --git a/ci/checks/run-all-checks.sh b/ci/checks/run-all-checks.sh index c947c8a57..00dd90222 100755 --- a/ci/checks/run-all-checks.sh +++ b/ci/checks/run-all-checks.sh @@ -31,6 +31,8 @@ prohibit-exempli-gratia-in-rst.sh prohibit-fork-point-in-git-context.sh prohibit-id-est-in-rst.sh prohibit-double-backticks-in-python.sh +prohibit-github-in-gitlab-files.sh +prohibit-gitlab-in-github-files.sh prohibit-markdown-links-in-rst.sh prohibit-mrs-in-github-files.sh prohibit-prs-in-gitlab-files.sh diff --git a/docs/man/git-machete.1 b/docs/man/git-machete.1 index cec4a36d2..3da9edc1c 100644 --- a/docs/man/git-machete.1 +++ b/docs/man/git-machete.1 @@ -361,10 +361,18 @@ Setting this config key to \fBtrue\fP will force \fBgit machete github create\-p from the message body of the first unique commit of the branch, even if \fB\&.git/info/description\fP and/or \fB\&.github/pull_request_template.md\fP is present. .TP .B \fBmachete.github.prDescriptionIntroStyle\fP: -Select the style of the intro prepended to PR description: -* \fBfull\fP \-\-\- include both a chain of upstream PRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream PRs -* \fBup\-only\fP \-\-\- default, include only a chain of upstream PRs -* \fBnone\fP \-\-\- prepend no intro to the PR description at all +.INDENT 7.0 +.TP +.B Select the style of the intro prepended to PR description: +.INDENT 7.0 +.IP \(bu 2 +\fBfull\fP \-\-\- include both a chain of upstream PRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream PRs +.IP \(bu 2 +\fBup\-only\fP \-\-\- default, include only a chain of upstream PRs +.IP \(bu 2 +\fBnone\fP \-\-\- prepend no intro to the PR description at all +.UNINDENT +.UNINDENT .TP .B \fBmachete.gitlab.{domain,remote,namespace,project}\fP: .INDENT 7.0 @@ -399,10 +407,18 @@ Setting this config key to \fBtrue\fP will force \fBgit machete gitlab create\-m from the message body of the first unique commit of the branch, even if \fB\&.git/info/description\fP and/or \fB\&.gitlab/merge_request_templates/Default.md\fP is present. .TP .B \fBmachete.gitlab.mrDescriptionIntroStyle\fP: -Select the style of the intro prepended to MR description: -* \fBfull\fP \-\-\- include both a chain of upstream MRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream MRs -* \fBup\-only\fP \-\-\- default, include only a chain of upstream MRs -* \fBnone\fP \-\-\- prepend no intro to the MR description at all +.INDENT 7.0 +.TP +.B Select the style of the intro prepended to MR description: +.INDENT 7.0 +.IP \(bu 2 +\fBfull\fP \-\-\- include both a chain of upstream MRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream MRs +.IP \(bu 2 +\fBup\-only\fP \-\-\- default, include only a chain of upstream MRs +.IP \(bu 2 +\fBnone\fP \-\-\- prepend no intro to the MR description at all +.UNINDENT +.UNINDENT .TP .B \fBmachete.overrideForkPoint..to\fP: Executing \fBgit machete fork\-point \-\-override\-to[\-parent|\-inferred|=] []\fP sets up a fork point override for \fB\fP\&. @@ -1024,7 +1040,7 @@ Sets the base of the current (or specified) branch\(aqs PR to upstream (parent) If after changing the base the PR ends up stacked atop another PR, the PR description posted to GitHub will be prepended with an intro section listing the entire related chain of PRs. .sp -This header will be updated or removed accordingly with the subsequent runs of \fBretarget\-pr\fP, even if the base branch is already up to date. +This intro will be updated or removed accordingly with the subsequent runs of \fBretarget\-pr\fP, even if the base branch is already up to date. .sp \fBOptions:\fP .INDENT 7.0 @@ -1089,10 +1105,18 @@ Setting this config key to \fBtrue\fP will force \fBgit machete github create\-p from the message body of the first unique commit of the branch, even if \fB\&.git/info/description\fP and/or \fB\&.github/pull_request_template.md\fP is present. .TP .B \fBmachete.github.prDescriptionIntroStyle\fP (\fBcreate\-pr\fP, \fBrestack\-pr\fP and \fBretarget\-pr\fP): -Select the style of the intro prepended to PR description: -* \fBfull\fP \-\-\- include both a chain of upstream PRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream PRs -* \fBup\-only\fP \-\-\- default, include only a chain of upstream PRs -* \fBnone\fP \-\-\- prepend no intro to the PR description at all +.INDENT 7.0 +.TP +.B Select the style of the intro prepended to PR description: +.INDENT 7.0 +.IP \(bu 2 +\fBfull\fP \-\-\- include both a chain of upstream PRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream PRs +.IP \(bu 2 +\fBup\-only\fP \-\-\- default, include only a chain of upstream PRs +.IP \(bu 2 +\fBnone\fP \-\-\- prepend no intro to the PR description at all +.UNINDENT +.UNINDENT .UNINDENT .sp \fBEnvironment variables (all subcommands):\fP @@ -1254,7 +1278,7 @@ Sets the target of the current (or specified) branch\(aqs MR to upstream (parent If after changing the target the MR ends up stacked atop another MR, the MR description posted to GitLab will be prepended with an intro section listing the entire related chain of MRs. .sp -This header will be updated or removed accordingly with the subsequent runs of \fBretarget\-mr\fP, even if the target branch is already up to date. +This intro will be updated or removed accordingly with the subsequent runs of \fBretarget\-mr\fP, even if the target branch is already up to date. .sp \fBOptions:\fP .INDENT 7.0 @@ -1305,10 +1329,18 @@ Setting this config key to \fBtrue\fP will force \fBgit machete gitlab create\-m from the message body of the first unique commit of the branch, even if \fB\&.git/info/description\fP and/or \fB\&.gitlab/merge_request_templates/Default.md\fP is present. .TP .B \fBmachete.gitlab.mrDescriptionIntroStyle\fP (\fBcreate\-mr\fP, \fBrestack\-mr\fP and \fBretarget\-mr\fP): -Select the style of the intro prepended to PR description: -* \fBfull\fP \-\-\- include both a chain of upstream PRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream PRs -* \fBup\-only\fP \-\-\- default, include only a chain of upstream PRs -* \fBnone\fP \-\-\- prepend no intro to the PR description at all +.INDENT 7.0 +.TP +.B Select the style of the intro prepended to MR description: +.INDENT 7.0 +.IP \(bu 2 +\fBfull\fP \-\-\- include both a chain of upstream MRs (typically leading to \fBmain\fP, \fBmaster\fP, \fBdevelop\fP etc.) and a tree of downstream MRs +.IP \(bu 2 +\fBup\-only\fP \-\-\- default, include only a chain of upstream MRs +.IP \(bu 2 +\fBnone\fP \-\-\- prepend no intro to the MR description at all +.UNINDENT +.UNINDENT .UNINDENT .sp \fBEnvironment variables (all subcommands):\fP diff --git a/docs/source/cli/github.rst b/docs/source/cli/github.rst index c330710b4..272f8c3d2 100644 --- a/docs/source/cli/github.rst +++ b/docs/source/cli/github.rst @@ -115,7 +115,7 @@ Creates, checks out and manages GitHub PRs while keeping them reflected in branc If after changing the base the PR ends up stacked atop another PR, the PR description posted to GitHub will be prepended with an intro section listing the entire related chain of PRs. - This header will be updated or removed accordingly with the subsequent runs of ``retarget-pr``, even if the base branch is already up to date. + This intro will be updated or removed accordingly with the subsequent runs of ``retarget-pr``, even if the base branch is already up to date. **Options:** diff --git a/docs/source/cli/gitlab.rst b/docs/source/cli/gitlab.rst index 65eb230c6..947444b0e 100644 --- a/docs/source/cli/gitlab.rst +++ b/docs/source/cli/gitlab.rst @@ -116,7 +116,7 @@ Creates, checks out and manages GitLab MRs while keeping them reflected in branc If after changing the target the MR ends up stacked atop another MR, the MR description posted to GitLab will be prepended with an intro section listing the entire related chain of MRs. - This header will be updated or removed accordingly with the subsequent runs of ``retarget-mr``, even if the target branch is already up to date. + This intro will be updated or removed accordingly with the subsequent runs of ``retarget-mr``, even if the target branch is already up to date. **Options:** @@ -136,7 +136,7 @@ Creates, checks out and manages GitLab MRs while keeping them reflected in branc .. include:: git-config-keys/gitlab_forceDescriptionFromCommitMessage.rst ``machete.gitlab.mrDescriptionIntroStyle`` (``create-mr``, ``restack-mr`` and ``retarget-mr``): - .. include:: git-config-keys/github_prDescriptionIntroStyle.rst + .. include:: git-config-keys/gitlab_mrDescriptionIntroStyle.rst **Environment variables (all subcommands):** diff --git a/docs/source/git-config-keys/github_prDescriptionIntroStyle.rst b/docs/source/git-config-keys/github_prDescriptionIntroStyle.rst index c104e1d19..2948906bb 100644 --- a/docs/source/git-config-keys/github_prDescriptionIntroStyle.rst +++ b/docs/source/git-config-keys/github_prDescriptionIntroStyle.rst @@ -1,4 +1,4 @@ Select the style of the intro prepended to PR description: -* ``full`` --- include both a chain of upstream PRs (typically leading to ``main``, ``master``, ``develop`` etc.) and a tree of downstream PRs -* ``up-only`` --- default, include only a chain of upstream PRs -* ``none`` --- prepend no intro to the PR description at all + * ``full`` --- include both a chain of upstream PRs (typically leading to ``main``, ``master``, ``develop`` etc.) and a tree of downstream PRs + * ``up-only`` --- default, include only a chain of upstream PRs + * ``none`` --- prepend no intro to the PR description at all diff --git a/docs/source/git-config-keys/gitlab_mrDescriptionIntroStyle.rst b/docs/source/git-config-keys/gitlab_mrDescriptionIntroStyle.rst index 93e9bd881..8465072d9 100644 --- a/docs/source/git-config-keys/gitlab_mrDescriptionIntroStyle.rst +++ b/docs/source/git-config-keys/gitlab_mrDescriptionIntroStyle.rst @@ -1,4 +1,4 @@ Select the style of the intro prepended to MR description: -* ``full`` --- include both a chain of upstream MRs (typically leading to ``main``, ``master``, ``develop`` etc.) and a tree of downstream MRs -* ``up-only`` --- default, include only a chain of upstream MRs -* ``none`` --- prepend no intro to the MR description at all + * ``full`` --- include both a chain of upstream MRs (typically leading to ``main``, ``master``, ``develop`` etc.) and a tree of downstream MRs + * ``up-only`` --- default, include only a chain of upstream MRs + * ``none`` --- prepend no intro to the MR description at all diff --git a/git_machete/client.py b/git_machete/client.py index ef23a274c..4299f49cf 100644 --- a/git_machete/client.py +++ b/git_machete/client.py @@ -2260,7 +2260,7 @@ def checkout_pull_requests(self, @staticmethod def __get_downwards_tree_excluding_pr(original_pr: PullRequest, all_open_prs: List[PullRequest]) -> List[Tuple[PullRequest, int]]: - """Returns pairs of (PR, level below the given PR)""" + """Returns pairs of (PR, depth below the given PR)""" visited_head_branches: Set[str] = set([]) @@ -2631,11 +2631,9 @@ def __generate_pr_description_intro(self, code_hosting_client: CodeHostingClient # For determining the PR chain, we need to fetch all PRs from the repo. # We could just fetch them straight away... but this list can be quite long for commercial monorepos, - # esp. given that GitHub and GitLab limit the single page to 100 PRs (so multiple HTTP requests may be needed). + # esp. given that GitHub and GitLab limit the single page to 100 PRs/MRs (so multiple HTTP requests may be needed). # As a slight optimization, in the default UP_ONLY style, # let's fetch the full PR list only if the current PR has a base PR at all. - # In FULL style, we need to check for downstream PRs as well, so the full PR list needs to be fetched anyway. - # That's also the performance reason behind selecting UP_ONLY and not FULL as the default style. prs_for_base_branch = code_hosting_client.get_open_pull_requests_by_head(LocalBranchShortName(pr.base)) if style == PRDescriptionIntroStyle.UP_ONLY and len(prs_for_base_branch) == 0: return '' diff --git a/git_machete/generated_docs.py b/git_machete/generated_docs.py index f86756188..4a7e90458 100644 --- a/git_machete/generated_docs.py +++ b/git_machete/generated_docs.py @@ -250,10 +250,14 @@ from the message body of the first unique commit of the branch, even if `.git/info/description` and/or `.github/pull_request_template.md` is present. `machete.github.prDescriptionIntroStyle`: - Select the style of the intro prepended to PR description: - * `full` — include both a chain of upstream PRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream PRs - * `up-only` — default, include only a chain of upstream PRs - * `none` — prepend no intro to the PR description at all + + Select the style of the intro prepended to PR description: + + * `full` — include both a chain of upstream PRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream PRs + + * `up-only` — default, include only a chain of upstream PRs + + * `none` — prepend no intro to the PR description at all `machete.gitlab.{domain,remote,namespace,project}`: @@ -283,10 +287,14 @@ from the message body of the first unique commit of the branch, even if `.git/info/description` and/or `.gitlab/merge_request_templates/Default.md` is present. `machete.gitlab.mrDescriptionIntroStyle`: - Select the style of the intro prepended to MR description: - * `full` — include both a chain of upstream MRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream MRs - * `up-only` — default, include only a chain of upstream MRs - * `none` — prepend no intro to the MR description at all + + Select the style of the intro prepended to MR description: + + * `full` — include both a chain of upstream MRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream MRs + + * `up-only` — default, include only a chain of upstream MRs + + * `none` — prepend no intro to the MR description at all `machete.overrideForkPoint..to`: @@ -671,7 +679,7 @@ If after changing the base the PR ends up stacked atop another PR, the PR description posted to GitHub will be prepended with an intro section listing the entire related chain of PRs. - This header will be updated or removed accordingly with the subsequent runs of `retarget-pr`, even if the base branch is already up to date. + This intro will be updated or removed accordingly with the subsequent runs of `retarget-pr`, even if the base branch is already up to date. Options: @@ -728,10 +736,14 @@ from the message body of the first unique commit of the branch, even if `.git/info/description` and/or `.github/pull_request_template.md` is present. `machete.github.prDescriptionIntroStyle` (`create-pr`, `restack-pr` and `retarget-pr`): - Select the style of the intro prepended to PR description: - * `full` — include both a chain of upstream PRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream PRs - * `up-only` — default, include only a chain of upstream PRs - * `none` — prepend no intro to the PR description at all + + Select the style of the intro prepended to PR description: + + * `full` — include both a chain of upstream PRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream PRs + + * `up-only` — default, include only a chain of upstream PRs + + * `none` — prepend no intro to the PR description at all Environment variables (all subcommands): `GITHUB_TOKEN` @@ -858,7 +870,7 @@ If after changing the target the MR ends up stacked atop another MR, the MR description posted to GitLab will be prepended with an intro section listing the entire related chain of MRs. - This header will be updated or removed accordingly with the subsequent runs of `retarget-mr`, even if the target branch is already up to date. + This intro will be updated or removed accordingly with the subsequent runs of `retarget-mr`, even if the target branch is already up to date. Options: @@ -902,10 +914,14 @@ from the message body of the first unique commit of the branch, even if `.git/info/description` and/or `.gitlab/merge_request_templates/Default.md` is present. `machete.gitlab.mrDescriptionIntroStyle` (`create-mr`, `restack-mr` and `retarget-mr`): - Select the style of the intro prepended to PR description: - * `full` — include both a chain of upstream PRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream PRs - * `up-only` — default, include only a chain of upstream PRs - * `none` — prepend no intro to the PR description at all + + Select the style of the intro prepended to MR description: + + * `full` — include both a chain of upstream MRs (typically leading to `main`, `master`, `develop` etc.) and a tree of downstream MRs + + * `up-only` — default, include only a chain of upstream MRs + + * `none` — prepend no intro to the MR description at all Environment variables (all subcommands): `GITLAB_TOKEN` diff --git a/git_machete/github.py b/git_machete/github.py index 081c3adcf..925d7014f 100644 --- a/git_machete/github.py +++ b/git_machete/github.py @@ -248,7 +248,7 @@ def __fire_github_api_request(self, method: str, path: str, request_body: Option "Skipped adding reviewers to the pull request.") else: raise UnexpectedMacheteException( - f'GitLab API returned 422 (Unprocessable Entity) HTTP status with error message: `{error_reason}`.') + f'GitHub API returned 422 (Unprocessable Entity) HTTP status with error message: `{error_reason}`.') elif err.code in (http.HTTPStatus.UNAUTHORIZED, http.HTTPStatus.FORBIDDEN): first_line = f'GitHub API returned `{err.code}` HTTP status with error message: `{err.reason}`\n' last_line = 'You can also use a different token provider - see `git machete help github` for details.' diff --git a/tests/test_github_retarget_pr.py b/tests/test_github_retarget_pr.py index 57a2455d4..78ac32c6e 100644 --- a/tests/test_github_retarget_pr.py +++ b/tests/test_github_retarget_pr.py @@ -118,20 +118,20 @@ def test_github_retarget_pr_explicit_branch(self, mocker: MockerFixture) -> None branch_second_commit_msg = "Second commit on branch." ( self.repo_sandbox.new_branch("root") - .commit("First commit on root.") - .new_branch("branch-1") - .commit(branch_first_commit_msg) - .commit(branch_second_commit_msg) - .push() - .new_branch('feature') - .commit('introduce feature') - .push() - .check_out('root') - .new_branch('branch-without-pr') - .commit('branch-without-pr') - .push() - .add_remote('new_origin', 'https://github.com/user/repo.git') - .check_out('root') + .commit("First commit on root.") + .new_branch("branch-1") + .commit(branch_first_commit_msg) + .commit(branch_second_commit_msg) + .push() + .new_branch('feature') + .commit('introduce feature') + .push() + .check_out('root') + .new_branch('branch-without-pr') + .commit('branch-without-pr') + .push() + .add_remote('new_origin', 'https://github.com/user/repo.git') + .check_out('root') ) body: str = \ @@ -200,21 +200,21 @@ def test_github_retarget_pr_multiple_non_origin_remotes(self, mocker: MockerFixt # branch feature present in each remote, no branch tracking data ( self.repo_sandbox.remove_remote() - .new_branch("root") - .add_remote('origin_1', origin_1_remote_path) - .add_remote('origin_2', origin_2_remote_path) - .commit("First commit on root.") - .push(remote='origin_1') - .push(remote='origin_2') - .new_branch("branch-1") - .commit(branch_first_commit_msg) - .commit(branch_second_commit_msg) - .push(remote='origin_1') - .push(remote='origin_2') - .new_branch('feature') - .commit('introduce feature') - .push(remote='origin_1', set_upstream=False) - .push(remote='origin_2', set_upstream=False) + .new_branch("root") + .add_remote('origin_1', origin_1_remote_path) + .add_remote('origin_2', origin_2_remote_path) + .commit("First commit on root.") + .push(remote='origin_1') + .push(remote='origin_2') + .new_branch("branch-1") + .commit(branch_first_commit_msg) + .commit(branch_second_commit_msg) + .push(remote='origin_1') + .push(remote='origin_2') + .new_branch('feature') + .commit('introduce feature') + .push(remote='origin_1', set_upstream=False) + .push(remote='origin_2', set_upstream=False) ) body: str = \ @@ -235,10 +235,10 @@ def test_github_retarget_pr_multiple_non_origin_remotes(self, mocker: MockerFixt # branch feature_1 present in each remote, tracking data present ( self.repo_sandbox.check_out('feature') - .new_branch('feature_1') - .commit('introduce feature 1') - .push(remote='origin_1') - .push(remote='origin_2') + .new_branch('feature_1') + .commit('introduce feature 1') + .push(remote='origin_1') + .push(remote='origin_2') ) body = \ @@ -314,9 +314,9 @@ def test_github_retarget_pr_multiple_non_origin_remotes(self, mocker: MockerFixt # branch feature_3 present in only one remote: origin_1 and has tracking data ( self.repo_sandbox.check_out('feature_2') - .new_branch('feature_3') - .commit('introduce feature 3') - .push(remote='origin_1') + .new_branch('feature_3') + .commit('introduce feature 3') + .push(remote='origin_1') ) body = \ diff --git a/tests/test_gitlab.py b/tests/test_gitlab.py index e3ef9cd84..e426576df 100644 --- a/tests/test_gitlab.py +++ b/tests/test_gitlab.py @@ -166,7 +166,7 @@ def git_config_key(key: str, value: str) -> Iterator[None]: 'but no remote seems to correspond to example-org/example-repo (namespace/project) on GitLab.\n' 'Consider pointing to the remote via machete.gitlab.remote config key') - self.repo_sandbox.add_remote("new-origin", "https://github.com/example-org/example-repo.git") # not a valid GitLab repo URL + self.repo_sandbox.add_remote("new-origin", "https://github.com/example-org/example-repo.git") # not a valid GitLab project URL with git_config_key('machete.gitlab.remote', "new-origin"): assert_failure( ['gitlab', 'checkout-mrs', '--all'],