In the context of [Alejandro Colomar stepping down as a man-pages maintainer](https://lwn.net/Articles/989215/) :(, [I learned from him](https://lwn.net/Articles/989398/) that
it is possible with `git` to create an email patch set that spans multiple target repositories.
Specifically, he [pointed to a review thread by Jiri Olsa](https://lore.kernel.org/linux-man/CAEf4BzZzE94QUdhWPmrMzRBRLa=nm86Mdm5vow688jKq3HzJeA@mail.gmail.com/T/#t) where this was done, and whose outline takes a similar shape to this (simplified):

* **[PATCH proj v3 0/3]** foobar: Add transmogrifier
  * **[PATCH proj v3 1/3]** foobar: Prepare flux compensator
  * **[PATCH proj v3 2/3]** foobar: Add transmogrifier feature
  * **[PATCH man v3 3/3]** foobar.1: Document transmogrification

Other than in normal review threads, *every mail subject is prefixed with an additional tag here*, to indicate which project it belongs to.

It was not obvious to me how to best achieve it with the existing tools, so I attempted to reconstruct how he had done it, and ended up with the workflow that I will describe below.
[This is not the same workflow that Jiri Olsa has been using](https://lore.kernel.org/all/Zt__OKtOj8AZGy4X@krava/) after all, but it's close, and unusual enough that it's maybe worth documenting here.

## 1. Pull both original repositories in the same local repository

We first make sure that all necessary commits are stored in the same local repository, by pulling in a second remote repository with `git fetch`.

This is unusual, but it is possible.  As a result, your local repository
contains two unrelated commit histories, for instance one for the linux kernel
and one for the man pages:


```pikchr
circlerad = circlerad * 0.4
linewid = linewid * 0.35
dark = papayawhip

define tag {
  line from last circle.n up 40% thin
  //right
  $3
  box $1 ht 0.3*boxht wid $2 fill off thin
  //text at last line.end $1 above
  move to last circle.end
  right
}

fill = off
L: circle
line ; line dotted
line ; circle
tag("linux-base", 75%, left)
fill = dark
line ; circle
line ; circle
tag("linux-feature", 90%, right)

move to 6*circlerad below first circle.w

fill = off
M: circle
line ; line dotted
line; circle
tag("man-base", 70%, left)
fill = dark
line ; circle
tag("man-feature", 85%, right)

d = circlerad
fill = off
BB: box with nw at first circle.nw + (-2*circlerad, 4*circlerad) ht 13*d wid 26*circlerad \
  behind first circle \
  dashed thin \
  radius 0.5*d

line from (BB.e.x, L.y) right 150%;  cylinder "linux" "origin"
line from (BB.e.x, M.y) right 150%;  cylinder "man-pages" "origin"

boxht = 0.7*boxht
line from (BB.w.x, L.y) left 150% <-;  box "linux" "worktree"
line from (BB.w.x, M.y) left 150% <-;  box "man-pages" "worktree"

text at BB.s "local repository" italic below
```

You can simplify your life here a bit by using [git worktrees](https://git-scm.com/docs/git-worktree) -- with these, your can keep doing your Linux work in a separate directory to your man page work, but still keep all of the changes in the same repository.

In the example above, we have prepared two commits in the *linux-feature* branch, based on the *linux-base* branch from upstream, as well as one commit in the *man-feature* branch, based on *man-base*.

### Example

Starting from two repositories `/tmp/git/linux-origin` and `/tmp/git/man-origin`, let's fetch both repositories into the same local repository and create a worktree for each:

```
gnoack:/tmp/git$ git clone /tmp/git/linux-origin linux
Cloning into 'linux'...
done.
gnoack:/tmp/git$ cd linux
gnoack:/tmp/git/linux(main)$ git tag linux-base
gnoack:/tmp/git/linux(main)$ git remote add man-origin /tmp/git/man-origin
gnoack:/tmp/git/linux(main)$ git fetch man-origin
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 12 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (12/12), 948 bytes | 948.00 KiB/s, done.
From /tmp/git/man-origin
 * [new branch]      main       -> man-origin/main
gnoack:/tmp/git/linux(main)$ git worktree add /tmp/git/man man-origin/main
Preparing worktree (detached HEAD efbfa45)
HEAD is now at efbfa45 4
```

We now have a worktree for the man pages at `/tmp/git/man` and one for Linux at `/tmp/git/linux`.

We now prepare the Linux and man page commits on top of these git repositories in the usual way, and make sure that we create branches for the pristine states called `man-base` and `linux-base`, and call our work branches `man-feature` and `linux-feature`.

## 2. Format a patch set that spans two otherwise unrelated branches

Create a giant patch set that spans two branches.
Indicating the desired commit range by using dotted range notation *twice*.

This invocation is compatible with common flags like `-v3` for the patch set version and `--cover-letter`.

We use `--subject-prefix` so that the mail subject is additionally qualified with an abbreviation for the main project.

```
git format-patch -v3 --cover-letter \
   --subject-prefix="PATCH proj"    \
   linux-base..linux-feature        \
   man-base..man-feature
```

Remember from the [*gitrevisions*(7)](https://man.gnoack.org/7/gitrevisions) man page that a *revision range* in Git parlance is a set of commits, which are not necessarily ordered in a single linear chain.  (Somewhat surprisingly, they are also not all connected here, as you would think from reading the man page.)

`git format-patch` includes some additional features for controlling the ordering, but in practice it seems that commits are ordered by date if they are not connected.

## 3. Final hand-editing

Hand-edit the subject prefix in the man page commit's email, so that the man page commit stands out among the others for the reviewers.

And sure enough, after `git send-email`, the mail thread has the expected form (in [`mutt`](http://mutt.org/)):

```
 [PATCH proj v3 0/3] foobar: Add transmogrifier
 ├─>[PATCH proj v3 1/3] foobar: Prepare flux compensator
 ├─>[PATCH proj v3 2/3] foobar: Add transmogrifier feature
 └─>[PATCH man v3 3/3] foobar.1: Document transmogrification
```
