Copybara compared
Copybara requires one repository to be authoritative. In the common workflow where that source of truth is an internal monorepo, a public pull request is imported and submitted there. For example, XLA's Copybara notes explain that the original pull request is closed rather than marked as merged, while a separate commit is applied publicly.
With git-splice, the monorepo can pull the contributor's branch for its
own tests without publishing anything. The maintainers then merge the pull
request in the public repository, and the monorepo pulls the resulting
main. This page shows that workflow; it doesn't run Copybara.
The setup: https://git.example.com/lib.git, a public library with 30
commits, and a monorepo with an app. How these pages run.
The monorepo has the library as a splice:
$ git splice clone https://git.example.com/lib.git vendor/lib
=== vendor/lib: fetching https://git.example.com/lib.git
ok vendor/lib: cloned bafd496 from main
An external contributionโ
A contributor opens a pull request in the public library, from a
contribution branch:
$ git clone -q https://git.example.com/lib.git ../contributor && git -C ../contributor switch -q -c contribution && echo "external contribution" >>../contributor/src/parse.txt && git -C ../contributor commit -q -a -m "external contribution" && git -C ../contributor push -q origin contribution
Test it in the monorepoโ
On a monorepo branch of the same name, pull brings the contribution in,
to test it together with the app:
$ git switch -q -c contribution && git splice pull vendor/lib
ok vendor/lib fetched
ok vendor/lib: pulled 4085e21
$ tail -n 1 vendor/lib/src/parse.txt
external contribution
Nothing is published: the public main is unchanged, and the monorepo's
main doesn't have the contribution.
$ git -C "$COMPARISON/upstream/lib.git" log --format=%s -1 main
lib commit 30
$ git show main:vendor/lib/src/parse.txt | tail -n 1
line 30
Merge it in publicโ
The maintainers merge the pull request in the public library, where the contributor sees it as merged:
$ git -C ../contributor switch -q main && git -C ../contributor merge -q --no-ff contribution -m "Merge external contribution" && git -C ../contributor push -q origin main
$ git -C "$COMPARISON/upstream/lib.git" log --graph --format=%s -4 main
* Merge external contribution
|\
| * external contribution
|/
* lib commit 30
* lib commit 29
The monorepo's main pulls the merge result:
$ git switch -q main && git splice pull vendor/lib
ok vendor/lib fetched (main moved bafd496..c174d0d)
ok vendor/lib: pulled c174d0d
$ git log -1 --format=%s && tail -n 1 vendor/lib/src/parse.txt
splice: pull vendor/lib from main at c174d0d
external contribution