Repository: VirtusLab/git-machete
Pull request #1401 (2025-02-18 14:51:52)

Release v3.33.0


Patch:
diff --git a/README.md b/README.md
index 1d0c919..9265d7a 100644
--- a/README.md
+++ b/README.md
@@ -255,6 +255,16 @@ However, we still recommend using merge for the narrow case of [backporting hotf
 
 <br/>
 
+#### In what order should I merge stacked PRs?
+
+We recommend merging PRs from the top-most (closest to the root branch, typically `main` or `master`).
+In other words, PR should only be merged when its base is a root branch.
+
+This way, you don't end up with a big-ball-of-code PR at the end.
+Avoid such balls is one of the main reasons for opening small PRs in the first place.
+
+<br/>
+
 #### Sometimes when I run `update` or `traverse`, too many commits are taken into the rebase... how to fix that?
 
 Contrary to the popular misconception, git doesn't have a notion of
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index cac3d09..e3ff305 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,5 +1,9 @@
 # Release notes
 
+## New in git-machete 3.33.0
+
+- added: `--by=...` flag to `git machete git{hub,lab} update-{pr,mr}-descriptions`
+
 ## New in git-machete 3.32.1
 
 - fixed: `git machete github` and `gitlab` recognize SSH URLs with any user before `@`, not just `git`
diff --git a/ci/checks/utils.sh b/ci/checks/utils.sh
deleted file mode 100644
index e7360fb..0000000
--- a/ci/checks/utils.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-function error() {
-  red='\033[91m'
-  endc='\033[0m'
-
-  if [[ $# -ge 1 ]]; then
-    if [[ -t 1 ]]; then
-      echo -e "${red}>>> $* <<<${endc}"
-    else
-      echo -e ">>> $* <<<"
-    fi
-  fi
-}
-
-function die() {
-  echo
-  error "$@"
-  echo
-  exit 1
-}
diff --git a/completion/git-machete.completion.bash b/completion/git-machete.completion.bash
index 7a9806a..045ee35 100644
--- a/completion/git-machete.completion.bash
+++ b/completion/git-machete.completion.bash
@@ -27,7 +27,7 @@ _git_machete() {
   local githublab_checkout_opts="--all --by= --mine"
   local githublab_restack_opts="-U --update-related-descriptions"
   local githublab_retarget_opts="-b --branch= --ignore-if-missing -U --update-related-descriptions"
-  local githublab_update_descriptions_opts="--all --mine --related"
+  local githublab_update_descriptions_opts="--all --by= --mine --related"
   local reapply_opts="-f --fork-point="
   local slide_out_opts="-d --down-fork-point= --delete -M --merge -n --no-edit-merge --no-interactive-rebase --removed-from-remote"
   local squash_opts="-f --fork-point="
diff --git a/completion/git-machete.completion.zsh b/completion/git-machete.completion.zsh
index 854f1d2..2d17ae1 100644
--- a/completion/git-machete.completion.zsh
+++ b/completion/git-machete.completion.zsh
@@ -304,6 +304,7 @@ __git_machete_github_subcommands() {
         (update-pr-descriptions)
           _arguments \
             '(--all)'--all'[Update PR descriptions for all PRs in the repository]' \
+            '(--by)'--by='[Update PR descriptions for all PRs authored by the given GitHub user]' \
             '(--mine)'--mine'[Update PR descriptions for all PRs opened by the current user associated with the GitHub token]' \
             '(--related)'--related'[Update PR descriptions for all PRs that are upstream and/or downstream of the PR for the current branch]' \
             "${common_flags[@]}"
@@ -379,6 +380,7 @@ __git_machete_gitlab_subcommands() {
         (update-mr-descriptions)
           _arguments \
             '(--all)'--all'[Update MR descriptions for all MRs in the project]' \
+            '(--by)'--by='[Update MR descriptions for all MRs authored by the given GitLab user]' \
             '(--mine)'--mine'[Update MR descriptions for all MRs opened by the current user associated with the GitLab token]' \
             '(--related)'--related'[Update MR descriptions for all MRs that are upstream and/or downstream of the MR for the current branch]' \
             "${common_flags[@]}"
diff --git a/completion/git-machete.fish b/completion/git-machete.fish
index 18f287b..40f6de9 100644
--- a/completion/git-machete.fish
+++ b/completion/git-machete.fish
@@ -103,7 +103,7 @@ complete -c git-machete -n "__fish_seen_subcommand_from github; and not __fish_s
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from anno-prs;               and not __fish_seen_subcommand_from --with-urls"                   -f -l with-urls                                            -d 'Include PR URLs in the annotations'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from checkout-prs;           and not __fish_seen_subcommand_from --all"                         -f -l all                                                  -d 'Checkout all open PRs'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from checkout-prs;           and not __fish_seen_subcommand_from --by"                          -x -l by                                                   -d "Checkout someone's open PRs"
-complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from checkout-prs;           and not __fish_seen_subcommand_from --mine"                        -x -l mine                                                 -d 'Checkout open PRs for the current user associated with the GitHub token'
+complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from checkout-prs;           and not __fish_seen_subcommand_from --mine"                        -f -l mine                                                 -d 'Checkout open PRs for the current user associated with the GitHub token'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from create-pr;              and not __fish_seen_subcommand_from --draft"                       -f -l draft                                                -d 'Create the new PR as a draft'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from create-pr;              and not __fish_seen_subcommand_from --title"                       -x -l title                                                -d 'Set the title for new PR explicitly'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from create-pr;              and not __fish_seen_subcommand_from --update-related-descriptions" -f -l update-related-descriptions -s U                     -d 'Update the generated sections of PR descriptions that list the upstream and/or downstream PRs'
@@ -113,8 +113,9 @@ complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from retarget-pr;            and not __fish_seen_subcommand_from --ignore-if-missing"           -f -l ignore-if-missing                                    -d 'Ignore errors and quietly terminate execution if there is no PR opened for current (or specified) branch'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from retarget-pr;            and not __fish_seen_subcommand_from --update-related-descriptions" -f -l update-related-descriptions -s U                     -d 'Update the generated sections of PR descriptions that list the upstream and/or downstream PRs'
 complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from update-pr-descriptions; and not __fish_seen_subcommand_from --all"                         -f -l all                                                  -d 'Update PR descriptions for all PRs in the repository'
-complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from update-pr-descriptions; and not __fish_seen_subcommand_from --mine"                        -x -l mine                                                 -d 'Update PR descriptions for all PRs opened by the current user associated with the GitHub token'
-complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from update-pr-descriptions; and not __fish_seen_subcommand_from --related"                     -x -l related                                              -d 'Update PR descriptions for all PRs that are upstream and/or downstream of the PR for the current branch'
+complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from update-pr-descriptions; and not __fish_seen_subcommand_from --by"                          -x -l by                                                   -d 'Update PR descriptions for all PRs opened by the given user'
+complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from update-pr-descriptions; and not __fish_seen_subcommand_from --mine"                        -f -l mine                                                 -d 'Update PR descriptions for all PRs opened by the current user associated with the GitHub token'
+complete -c git-machete -n "__fish_seen_subcommand_from github; and __fish_seen_subcommand_from update-pr-descriptions; and not __fish_seen_subcommand_from --related"                     -f -l related                                              -d 'Update PR descriptions for all PRs that are upstream and/or downstream of the PR for the current branch'
 
 # git machete gitlab
 complete -c git-machete -n "not __fish_seen_subcommand_from $__machete_commands"                                                                                                           -f -a gitlab                                               -d 'Create, check out and manage GitLab MRs while keeping them reflected in git machete'
@@ -127,7 +128,7 @@ complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and not __fish_s
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from anno-mrs;               and not __fish_seen_subcommand_from --with-urls"                   -f -l with-urls                                            -d 'Include MR URLs in the annotations'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from checkout-mrs;           and not __fish_seen_subcommand_from --all"                         -f -l all                                                  -d 'Checkout all open MRs'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from checkout-mrs;           and not __fish_seen_subcommand_from --by"                          -x -l by                                                   -d "Checkout someone's open MRs"
-complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from checkout-mrs;           and not __fish_seen_subcommand_from --mine"                        -x -l mine                                                 -d 'Checkout open MRs for the current user associated with the GitLab token'
+complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from checkout-mrs;           and not __fish_seen_subcommand_from --mine"                        -f -l mine                                                 -d 'Checkout open MRs for the current user associated with the GitLab token'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from create-mr;              and not __fish_seen_subcommand_from --draft"                       -f -l draft                                                -d 'Create the new MR as a draft'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from create-mr;              and not __fish_seen_subcommand_from --title"                       -x -l title                                                -d 'Set the title for new MR explicitly'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from create-mr;              and not __fish_seen_subcommand_from --update-related-descriptions" -f -l update-related-descriptions -s U                     -d 'Update the generated sections of MR descriptions that list the upstream and/or downstream MRs'
@@ -137,8 +138,9 @@ complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from retarget-mr;            and not __fish_seen_subcommand_from --ignore-if-missing"           -f -l ignore-if-missing                                    -d 'Ignore errors and quietly terminate execution if there is no MR opened for current (or specified) branch'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from retarget-mr;            and not __fish_seen_subcommand_from --update-related-descriptions" -f -l update-related-descriptions -s U                     -d 'Update the generated sections of MR descriptions that list the upstream and/or downstream MRs'
 complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from update-mr-descriptions; and not __fish_seen_subcommand_from --all"                         -f -l all                                                  -d 'Update MR descriptions for all MRs in the project'
-complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from update-mr-descriptions; and not __fish_seen_subcommand_from --mine"                        -x -l mine                                                 -d 'Update MR descriptions for all MRs opened by the current user associated with the GitHub token'
-complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from update-mr-descriptions; and not __fish_seen_subcommand_from --related"                     -x -l related                                              -d 'Update MR descriptions for all MRs that are upstream and/or downstream of the MR for the current branch'
+complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from update-mr-descriptions; and not __fish_seen_subcommand_from --by"                          -f -l by                                                   -d 'Update MR descriptions for all MRs opened by the given user'
+complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from update-mr-descriptions; and not __fish_seen_subcommand_from --mine"                        -f -l mine                                                 -d 'Update MR descriptions for all MRs opened by the current user associated with the GitHub token'
+complete -c git-machete -n "__fish_seen_subcommand_from gitlab; and __fish_seen_subcommand_from update-mr-descriptions; and not __fish_seen_subcommand_from --related"                     -f -l related                                              -d 'Update MR descriptions for all MRs that are upstream and/or downstream of the MR for the current branch'
 
 # git machete go
 complete -c git-machete -n "not __fish_seen_subcommand_from $__machete_commands"                                                                   -f -a go    -d 'Check out the branch relative to the position of the current branch, accepts down/first/last/next/root/prev/up argument'
diff --git a/docs/man/git-machete.1 b/docs/man/git-machete.1
index 43900bf..707ce54 100644
--- a/docs/man/git-machete.1
+++ b/docs/man/git-machete.1
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "GIT-MACHETE" "1" "Feb 04, 2025" "" "git-machete"
+.TH "GIT-MACHETE" "1" "Feb 18, 2025" "" "git-machete"
 .SH NAME
-git-machete \- git-machete 3.32.1
+git-machete \- git-machete 3.33.0
 .sp
 git machete is a robust tool that \fBsimplifies your git workflows\fP\&.
 .sp
@@ -1090,7 +1090,7 @@ deletes unmanaged branches,
 deletes untracked managed branches that have no downstream branch.
 .UNINDENT
 .TP
-.B \fBupdate\-pr\-descriptions\fP:
+.B \fBupdate\-pr\-descriptions [\-\-all | \-\-by=<github\-login> | \-\-mine | \-\-related]\fP:
 Updates the generated sections (\(dqintros\(dq) of PR descriptions that list the upstream and/or downstream PRs
 (depending on \fBmachete.github.prDescriptionIntroStyle\fP git config key).
 .sp
@@ -1100,6 +1100,9 @@ Updates the generated sections (\(dqintros\(dq) of PR descriptions that list the
 .B  \-\-all
 Update PR descriptions for all PRs in the repository.
 .TP
+.BI \-\-by\fB= <github\-login>
+Update PR descriptions for all PRs authored by the given GitHub user, where \fB<github\-login>\fP is the GitHub account name.
+.TP
 .B  \-\-mine
 Update PR descriptions for all PRs opened by the current user associated with the GitHub token.
 .TP
@@ -1351,7 +1354,7 @@ Update the generated sections (\(dqintros\(dq) of MR descriptions that list the
 See help for \fBgit machete gitlab update\-mr\-descriptions \-\-related\fP for details.
 .UNINDENT
 .TP
-.B \fBupdate\-mr\-descriptions\fP:
+.B \fBupdate\-mr\-descriptions [\-\-all | \-\-by=<gitlab\-login> | \-\-mine | \-\-related]\fP:
 Updates the generated sections (\(dqintros\(dq) of MR descriptions that list the upstream and/or downstream MRs
 (depending on \fBmachete.gitlab.mrDescriptionIntroStyle\fP git config key).
 .sp
@@ -1361,6 +1364,9 @@ Updates the generated sections (\(dqintros\(dq) of MR descriptions that list the
 .B  \-\-all
 Update MR descriptions for all MRs in the project.
 .TP
+.BI \-\-by\fB= <gitlab\-login>
+Update MR descriptions for all MRs authored by the given GitLab user, where \fB<gitlab\-login>\fP is the GitLab account name.
+.TP
 .B  \-\-mine
 Update MR descriptions for all MRs opened by the current user associated with the GitLab token.
 .TP
diff --git a/docs/source/cli/github.rst b/docs/source/cli/github.rst
index 9ee56b9..a8d894a 100644
--- a/docs/source/cli/github.rst
+++ b/docs/source/cli/github.rst
@@ -146,19 +146,21 @@ Creates, checks out and manages GitHub PRs while keeping them reflected in branc
     #. deletes unmanaged branches,
     #. deletes untracked managed branches that have no downstream branch.
 
-``update-pr-descriptions``:
+``update-pr-descriptions [--all | --by=<github-login> | --mine | --related]``:
     Updates the generated sections ("intros") of PR descriptions that list the upstream and/or downstream PRs
     (depending on ``machete.github.prDescriptionIntroStyle`` git config key).
 
     **Options:**
 
-    --all         Update PR descriptions for all PRs in the repository.
+    --all                Update PR descriptions for all PRs in the repository.
 
-    --mine        Update PR descriptions for all PRs opened by the current user associated with the GitHub token.
+    --by=<github-login>  Update PR descriptions for all PRs authored by the given GitHub user, where ``<github-login>`` is the GitHub account name.
 
-    --related     Update PR descriptions for all PRs that are upstream and/or downstream of the PR for the current branch.
-                  If ``machete.github.prDescriptionIntroStyle`` is ``up-only`` (default), then only downstream PR descriptions are updated.
-                  If ``machete.github.prDescriptionIntroStyle`` is ``full``, then both downstream and upstream PR descriptions are updated.
+    --mine               Update PR descriptions for all PRs opened by the current user associated with the GitHub token.
+
+    --related            Update PR descriptions for all PRs that are upstream and/or downstream of the PR for the current branch.
+                         If ``machete.github.prDescriptionIntroStyle`` is ``up-only`` (default), then only downstream PR descriptions are updated.
+                         If ``machete.github.prDescriptionIntroStyle`` is ``full``, then both downstream and upstream PR descriptions are updated.
 
 **Git config keys:**
 
diff --git a/docs/source/cli/gitlab.rst b/docs/source/cli/gitlab.rst
index d725d2c..a5a1ba8 100644
--- a/docs/source/cli/gitlab.rst
+++ b/docs/source/cli/gitlab.rst
@@ -137,19 +137,21 @@ Creates, checks out and manages GitLab MRs while keeping them reflected in branc
     -U, --update-related-descriptions  Update the generated sections ("intros") of MR descriptions that list the upstream and/or downstream MRs.
                                        See help for ``git machete gitlab update-mr-descriptions --related`` for details.
 
-``update-mr-descriptions``:
+``update-mr-descriptions [--all | --by=<gitlab-login> | --mine | --related]``:
     Updates the generated sections ("intros") of MR descriptions that list the upstream and/or downstream MRs
     (depending on ``machete.gitlab.mrDescriptionIntroStyle`` git config key).
 
     **Options:**
 
-    --all         Update MR descriptions for all MRs in the project.
+    --all                Update MR descriptions for all MRs in the project.
 
-    --mine        Update MR descriptions for all MRs opened by the current user associated with the GitLab token.
+    --by=<gitlab-login>  Update MR descriptions for all MRs authored by the given GitLab user, where ``<gitlab-login>`` is the GitLab account name.
 
-    --related     Update MR descriptions for all MRs that are upstream and/or downstream of the MR for the current branch.
-                  If ``machete.gitlab.mrDescriptionIntroStyle`` is ``up-only`` (default), then only downstream MR descriptions are updated.
-                  If ``machete.gitlab.mrDescriptionIntroStyle`` is ``full``, then both downstream and upstream MR descriptions are updated.
+    --mine               Update MR descriptions for all MRs opened by the current user associated with the GitLab token.
+
+    --related            Update MR descriptions for all MRs that are upstream and/or downstream of the MR for the current branch.
+                         If ``machete.gitlab.mrDescriptionIntroStyle`` is ``up-only`` (default), then only downstream MR descriptions are updated.
+                         If ``machete.gitlab.mrDescriptionIntroStyle`` is ``full``, then both downstream and upstream MR descriptions are updated.
 
 **Git config keys:**
 
diff --git a/git_machete/__init__.py b/git_machete/__init__.py
index 8a2bdc9..c817857 100644
--- a/git_machete/__init__.py
+++ b/git_machete/__init__.py
@@ -1,1 +1,1 @@
-__version__ = '3.32.1'
+__version__ = '3.33.0'
diff --git a/git_machete/cli.py b/git_machete/cli.py
index bfbb86e..b97f118 100644
--- a/git_machete/cli.py
+++ b/git_machete/cli.py
@@ -760,8 +760,9 @@ def launch(orig_args: List[str]) -> None:
                                            f"`checkout-{pr_or_mr}s` and `update-{pr_or_mr}-descriptions` subcommands.")
             if cli_opts.opt_branch is not None and subcommand != f"retarget-{pr_or_mr}":
                 raise MacheteException(f"`--branch` option is only valid with `retarget-{pr_or_mr}` subcommand.")
-            if cli_opts.opt_by is not None and subcommand != f"checkout-{pr_or_mr}s":
-                raise MacheteException(f"`--by` option is only valid with `checkout-{pr_or_mr}s` subcommand.")
+            if cli_opts.opt_by is not None and subcommand not in (f"checkout-{pr_or_mr}s", f"update-{pr_or_mr}-descriptions"):
+                raise MacheteException(f"`--by` option is only valid with "
+                                       f"`checkout-{pr_or_mr}s` and `update-{pr_or_mr}-descriptions` subcommands.")
             if cli_opts.opt_draft and subcommand != f"create-{pr_or_mr}":
                 raise MacheteException(f"`--draft` option is only valid with `create-{pr_or_mr}` subcommand.")
             if cli_opts.opt_ignore_if_missing and subcommand != f"retarget-{pr_or_mr}":
@@ -819,12 +820,12 @@ def launch(orig_args: List[str]) -> None:
                 machete_client.delete_unmanaged(opt_squash_merge_detection=SquashMergeDetection.NONE, opt_yes=False)
                 machete_client.delete_untracked(opt_yes=cli_opts.opt_yes)
             elif subcommand == f"update-{pr_or_mr}-descriptions":
-                if len(set(parsed_cli_as_dict.keys()).intersection({'all', 'related', 'mine'})) != 1:
+                if len(set(parsed_cli_as_dict.keys()).intersection({'all', 'by', 'mine', 'related'})) != 1:
                     raise MacheteException(
                         f"`update-{pr_or_mr}-descriptions` subcommand must take exactly one of the following options: "
-                        '`--all`, `--mine`, `--related`')
+                        '`--all`, `--by=...`, `--mine`, `--related`')
                 machete_client.update_pull_request_descriptions(
-                    spec, all=cli_opts.opt_all, mine=cli_opts.opt_mine, related=cli_opts.opt_related)
+                    spec, all=cli_opts.opt_all, by=cli_opts.opt_by, mine=cli_opts.opt_mine, related=cli_opts.opt_related)
             else:  # an unknown subcommand is handled by argparse
                 raise UnexpectedMacheteException(f"Unknown subcommand: `{subcommand}`")
         elif cmd == "is-managed":
diff --git a/git_machete/client.py b/git_machete/client.py
index 522e97d..a0c594c 100644
--- a/git_machete/client.py
+++ b/git_machete/client.py
@@ -2251,7 +2251,8 @@ class MacheteClient:
                 f"of the {bold(branch)} branch.")
 
     def update_pull_request_descriptions(self, spec: CodeHostingSpec,
-                                         *, all: bool = False, mine: bool = False, related: bool = False) -> None:
+                                         *, all: bool = False, by: Optional[str] = None, mine: bool = False, related: bool = False
+                                         ) -> None:
         if self.__code_hosting_client is None:
             self.__init_code_hosting_client(spec)
 
@@ -2267,7 +2268,7 @@ class MacheteClient:
         else:
             related_to = None
         applicable_prs: List[PullRequest] = self.__get_applicable_pull_requests(
-            all=all, by=current_user if mine else None, related_to=related_to)
+            all=all, by=current_user if mine else by, related_to=related_to)
 
         for pr in applicable_prs:
             new_description = self.__get_updated_pull_request_description(pr)
diff --git a/git_machete/generated_docs.py b/git_machete/generated_docs.py
index af7fa27..35a4248 100644
--- a/git_machete/generated_docs.py
+++ b/git_machete/generated_docs.py
@@ -729,7 +729,7 @@ long_docs: Dict[str, str] = {
 
                  * deletes untracked managed branches that have no downstream branch.
 
-           `update-pr-descriptions`:
+           `update-pr-descriptions [--all | --by=<github-login> | --mine | --related]`:
  
               Updates the generated sections ("intros") of PR descriptions that list the upstream and/or downstream PRs
               (depending on `machete.github.prDescriptionIntroStyle` git config key).
@@ -739,6 +739,10 @@ long_docs: Dict[str, str] = {
                  <b>--all</b>
               Update PR descriptions for all PRs in the repository.
 
+                 <b>--by=<github-login></b>
+
+              Update PR descriptions for all PRs authored by the given GitHub user, where `<github-login>` is the GitHub account name.
+
                  <b>--mine</b>
               Update PR descriptions for all PRs opened by the current user associated with the GitHub token.
 
@@ -944,7 +948,7 @@ long_docs: Dict[str, str] = {
               Update the generated sections ("intros") of MR descriptions that list the upstream and/or downstream MRs.
               See help for `git machete gitlab update-mr-descriptions --related` for details.
 
-           `update-mr-descriptions`:
+           `update-mr-descriptions [--all | --by=<gitlab-login> | --mine | --related]`:
  
               Updates the generated sections ("intros") of MR descriptions that list the upstream and/or downstream MRs
               (depending on `machete.gitlab.mrDescriptionIntroStyle` git config key).
@@ -954,6 +958,10 @@ long_docs: Dict[str, str] = {
                  <b>--all</b>
               Update MR descriptions for all MRs in the project.
 
+                 <b>--by=<gitlab-login></b>
+
+              Update MR descriptions for all MRs authored by the given GitLab user, where `<gitlab-login>` is the GitLab account name.
+
                  <b>--mine</b>
               Update MR descriptions for all MRs opened by the current user associated with the GitLab token.
 
diff --git a/requirements/coverage.txt b/requirements/coverage.txt
index 124d9e7..12687f8 100644
--- a/requirements/coverage.txt
+++ b/requirements/coverage.txt
@@ -1,7 +1,7 @@
 coverage==6.2; python_version <= '3.6'
 coverage==7.2.7; python_version >= '3.7' and python_version < '3.8'
 coverage==7.6.1; python_version >= '3.8' and python_version < '3.9'
-coverage==7.6.10; python_version >= '3.9'
+coverage==7.6.12; python_version >= '3.9'
 
 pytest-cov==4.0.0; python_version <= '3.6'
 pytest-cov==4.1.0; python_version >= '3.7' and python_version < '3.8'
diff --git a/requirements/mypy.txt b/requirements/mypy.txt
index 132b08f..cb27acf 100644
--- a/requirements/mypy.txt
+++ b/requirements/mypy.txt
@@ -1,3 +1,4 @@
 mypy==0.971; python_version <= '3.6'
 mypy==1.4.1; python_version >= '3.7' and python_version < '3.8'
-mypy==1.14.1; python_version >= '3.8'
+mypy==1.14.1; python_version >= '3.8' and python_version < '3.9'
+mypy==1.15.0; python_version >= '3.9'
diff --git a/requirements/pep8-check.txt b/requirements/pep8-check.txt
index b7ac419..f920579 100644
--- a/requirements/pep8-check.txt
+++ b/requirements/pep8-check.txt
@@ -1,3 +1,3 @@
-flake8==7.1.1
+flake8==7.1.2
 flake8-unused-arguments==0.0.13
 flake8-use-fstring==1.4
diff --git a/requirements/py-docs.txt b/requirements/py-docs.txt
index 189eee1..9ba431c 100644
--- a/requirements/py-docs.txt
+++ b/requirements/py-docs.txt
@@ -1,3 +1,3 @@
 docutils==0.21.2
 pygments==2.19.1
-beautifulsoup4==4.13.0
+beautifulsoup4==4.13.3
diff --git a/requirements/typos.txt b/requirements/typos.txt
index fd0d5b4..3d968de 100644
--- a/requirements/typos.txt
+++ b/requirements/typos.txt
@@ -1,1 +1,1 @@
-typos==1.29.5
+typos==1.29.7


Test patch:
diff --git a/tests/completion_e2e/test_completion_e2e.py b/tests/completion_e2e/test_completion_e2e.py
index 61c94e2..cb969d7 100644
--- a/tests/completion_e2e/test_completion_e2e.py
+++ b/tests/completion_e2e/test_completion_e2e.py
@@ -75,7 +75,7 @@ test_cases: Dict[str, str] = {
     "git machete github retarget-pr -b ":
         "develop master",
     "git machete github update-pr-descriptions -":
-        "--all --debug -h --help --mine --related -v --verbose",
+        "--all --by --debug -h --help --mine --related -v --verbose",
     "git machete gitlab ":
         "anno-mrs checkout-mrs create-mr restack-mr retarget-mr update-mr-descriptions",
     "git machete gitlab anno-mrs -":
@@ -91,7 +91,7 @@ test_cases: Dict[str, str] = {
     "git machete gitlab retarget-mr -b ":
         "develop master",
     "git machete gitlab update-mr-descriptions -":
-        "--all --debug -h --help --mine --related -v --verbose",
+        "--all --by --debug -h --help --mine --related -v --verbose",
     "git machete g ":
         "down first last next prev root up",
     "git machete go ":
diff --git a/tests/test_github.py b/tests/test_github.py
index 4b99249..92a3f36 100644
--- a/tests/test_github.py
+++ b/tests/test_github.py
@@ -354,18 +354,20 @@ class TestGitHub(BaseTest):
         assert_failure(["github", "create-pr", "--ignore-if-missing"],
                        "--ignore-if-missing option is only valid with retarget-pr subcommand.")
         assert_failure(["github", "checkout-prs", "--all", "--mine"],
-                       "checkout-prs subcommand must take exactly one of the following options: --all, --by=..., --mine, pr-number(s)")
+                       "checkout-prs subcommand must take exactly one "
+                       "of the following options: --all, --by=..., --mine, pr-number(s)")
         assert_failure(["github", "checkout-prs", "--title=foo"],
                        "--title option is only valid with create-pr subcommand.")
         assert_failure(["github", "restack-pr", "--with-urls"],
                        "--with-urls option is only valid with anno-prs subcommand.")
         assert_failure(["github", "restack-pr", "--yes"],
                        "--yes option is only valid with create-pr subcommand.")
-        assert_failure(["github", "update-pr-descriptions", "--by=other-user"],
-                       "--by option is only valid with checkout-prs subcommand.")
+        assert_failure(["github", "create-pr", "--by=other-user"],
+                       "--by option is only valid with checkout-prs and update-pr-descriptions subcommands.")
         assert_failure(["github", "checkout-prs", "--related"],
                        "--related option is only valid with update-pr-descriptions subcommand.")
         assert_failure(["github", "update-pr-descriptions", "--all", "--related"],
-                       "update-pr-descriptions subcommand must take exactly one of the following options: --all, --mine, --related")
+                       "update-pr-descriptions subcommand must take exactly one "
+                       "of the following options: --all, --by=..., --mine, --related")
         assert_failure(["github", "update-pr-descriptions", "--update-related-descriptions"],
                        "--update-related-descriptions option is only valid with create-pr, restack-pr and retarget-pr subcommands.")
diff --git a/tests/test_github_update_pr_descriptions.py b/tests/test_github_update_pr_descriptions.py
index a68e720..3e2aafa 100644
--- a/tests/test_github_update_pr_descriptions.py
+++ b/tests/test_github_update_pr_descriptions.py
@@ -23,7 +23,7 @@ class TestGitHubUpdatePRDescriptions(BaseTest):
         return [
             mock_pr_json(head='chore/redundant_checks', base='restrict_access', number=18),
             mock_pr_json(head='restrict_access', base='allow-ownership-link', number=17, user='github_user'),
-            mock_pr_json(head='allow-ownership-link', base='bugfix/feature', number=12),
+            mock_pr_json(head='allow-ownership-link', base='bugfix/feature', number=12, user='other_user'),
             mock_pr_json(head='bugfix/feature', base='enhance/feature', number=6),
             mock_pr_json(head='enhance/add_user', base='develop', number=19),
             mock_pr_json(head='testing/add_user', base='bugfix/add_user', number=22),
@@ -111,6 +111,14 @@ class TestGitHubUpdatePRDescriptions(BaseTest):
             """
         )
 
+        assert_success(
+            ['github', 'update-pr-descriptions', '--by=other_user'],
+            """
+            Checking for open GitHub PRs... OK
+            Description of PR #12 (allow-ownership-link -> bugfix/feature) has been updated
+            """
+        )
+
         assert_success(
             ['github', 'update-pr-descriptions', '--related'],
             """
@@ -193,8 +201,10 @@ class TestGitHubUpdatePRDescriptions(BaseTest):
     def test_github_update_pr_descriptions_misc_failures_and_warns(self, mocker: MockerFixture) -> None:
         self.patch_symbol(mocker, 'git_machete.code_hosting.OrganizationAndRepository.from_url', mock_from_url)
         self.patch_symbol(mocker, 'urllib.request.urlopen', mock_urlopen(MockGitHubAPIState.with_prs()))
-
         self.patch_symbol(mocker, 'git_machete.github.GitHubToken.for_domain', mock_github_token_for_domain_none)
+
+        create_repo_with_remote()
+
         assert_success(
             ["github", "update-pr-descriptions", "--all"],
             """
diff --git a/tests/test_gitlab.py b/tests/test_gitlab.py
index 9e51b87..509e16e 100644
--- a/tests/test_gitlab.py
+++ b/tests/test_gitlab.py
@@ -305,18 +305,20 @@ class TestGitLab(BaseTest):
         assert_failure(["gitlab", "create-mr", "--ignore-if-missing"],
                        "--ignore-if-missing option is only valid with retarget-mr subcommand.")
         assert_failure(["gitlab", "checkout-mrs", "--all", "--mine"],
-                       "checkout-mrs subcommand must take exactly one of the following options: --all, --by=..., --mine, mr-number(s)")
+                       "checkout-mrs subcommand must take exactly one "
+                       "of the following options: --all, --by=..., --mine, mr-number(s)")
         assert_failure(["gitlab", "checkout-mrs", "--title=foo"],
                        "--title option is only valid with create-mr subcommand.")
         assert_failure(["gitlab", "restack-mr", "--with-urls"],
                        "--with-urls option is only valid with anno-mrs subcommand.")
         assert_failure(["gitlab", "restack-mr", "--yes"],
                        "--yes option is only valid with create-mr subcommand.")
-        assert_failure(["gitlab", "update-mr-descriptions", "--by=other-user"],
-                       "--by option is only valid with checkout-mrs subcommand.")
+        assert_failure(["gitlab", "create-mr", "--by=other-user"],
+                       "--by option is only valid with checkout-mrs and update-mr-descriptions subcommands.")
         assert_failure(["gitlab", "checkout-mrs", "--related"],
                        "--related option is only valid with update-mr-descriptions subcommand.")
         assert_failure(["gitlab", "update-mr-descriptions", "--all", "--related"],
-                       "update-mr-descriptions subcommand must take exactly one of the following options: --all, --mine, --related")
+                       "update-mr-descriptions subcommand must take exactly one "
+                       "of the following options: --all, --by=..., --mine, --related")
         assert_failure(["gitlab", "update-mr-descriptions", "--update-related-descriptions"],
                        "--update-related-descriptions option is only valid with create-mr, restack-mr and retarget-mr subcommands.")
diff --git a/tests/test_gitlab_update_mr_descriptions.py b/tests/test_gitlab_update_mr_descriptions.py
index 6e08f29..8448c14 100644
--- a/tests/test_gitlab_update_mr_descriptions.py
+++ b/tests/test_gitlab_update_mr_descriptions.py
@@ -23,7 +23,7 @@ class TestGitLabUpdateMRDescriptions(BaseTest):
         return [
             mock_mr_json(head='chore/redundant_checks', base='restrict_access', number=18),
             mock_mr_json(head='restrict_access', base='allow-ownership-link', number=17, user='gitlab_user'),
-            mock_mr_json(head='allow-ownership-link', base='bugfix/feature', number=12),
+            mock_mr_json(head='allow-ownership-link', base='bugfix/feature', number=12, user='other_user'),
             mock_mr_json(head='bugfix/feature', base='enhance/feature', number=6),
             mock_mr_json(head='enhance/add_user', base='develop', number=19),
             mock_mr_json(head='testing/add_user', base='bugfix/add_user', number=22),
@@ -111,6 +111,14 @@ class TestGitLabUpdateMRDescriptions(BaseTest):
             """
         )
 
+        assert_success(
+            ['gitlab', 'update-mr-descriptions', '--by=other_user'],
+            """
+            Checking for open GitLab MRs... OK
+            Description of MR !12 (allow-ownership-link -> bugfix/feature) has been updated
+            """
+        )
+
         assert_success(
             ['gitlab', 'update-mr-descriptions', '--related'],
             """
@@ -193,9 +201,10 @@ class TestGitLabUpdateMRDescriptions(BaseTest):
     def test_gitlab_update_mr_descriptions_misc_failures_and_warns(self, mocker: MockerFixture) -> None:
         self.patch_symbol(mocker, 'git_machete.code_hosting.OrganizationAndRepository.from_url', mock_from_url)
         self.patch_symbol(mocker, 'urllib.request.urlopen', mock_urlopen(MockGitLabAPIState.with_mrs()))
+        self.patch_symbol(mocker, 'git_machete.gitlab.GitLabToken.for_domain', mock_gitlab_token_for_domain_none)
 
         create_repo_with_remote()
-        self.patch_symbol(mocker, 'git_machete.gitlab.GitLabToken.for_domain', mock_gitlab_token_for_domain_none)
+
         assert_success(
             ["gitlab", "update-mr-descriptions", "--all"],
             """