pull
$ git splice pull -h | check-help preamble
NAME
git-splice-pull - Fetch and splice in upstream changes
SYNOPSIS
git splice pull [--upstream <name>] [--branch <name> [--track]] [--bump | --rebase] [--no-fork-point] [--message-template <template>] [--recursive] (<path>... | --all)
git splice pull [<option>...] -m <message> <path>
Description
$ git splice pull -h | check-help section description
'git splice fetch' followed by 'git splice merge': fetches the splices'
upstreams in parallel, then splices their changes in, as one ordinary
commit per splice.
In the walkthrough's repositories, vendor/pkg-a/ is
already one commit behind. Splice in pkg-b/, then push another commit
to its upstream, so both splices are behind:
$ git splice clone https://git.example.com/pkg-b.git vendor/pkg-b >/dev/null &&
> git clone -q "$WALKTHROUGH/upstream/pkg-b.git" ../pkg-b &&
> echo "pkg-b: add a feature" >>../pkg-b/file.txt &&
> git -C ../pkg-b commit -qam "pkg-b: add a feature" &&
> git -C ../pkg-b push -q
Commands that change the monorepo or an upstream name their splices, or
take --all:
$ git splice pull --all
ok vendor/pkg-a fetched
ok vendor/pkg-b fetched (main moved 9b3cb02..b937c4f)
ok vendor/pkg-a: pulled 703b936
ok vendor/pkg-b: pulled b937c4f
Each splice gets one commit. The monorepo's history stays linear:
$ git log --oneline
6ed2f79 splice: pull vendor/pkg-b from main at b937c4f
dcf70b0 splice: pull vendor/pkg-a from main at 703b936
a73990e splice: clone vendor/pkg-b from main at 9b3cb02
d2867e9 lib-c: first version
3aef6fd splice: clone vendor/pkg-a from main at 9bb866a
ebe3b2b initial commit
Options
$ git splice pull -h | check-help section options
<path>...
The splices to pull, by their folders.
--all
Pulls every splice: each one the monorepo has, as with --recursive.
--upstream <name>
Pulls from this one of the upstreams the splice's .splice names,
instead of its default upstream. A splice without the named
upstream stops the command before it starts. The splices below,
selected or not, are fetched from every upstream they name: names
are only unique within one .splice, and any of them may have the
synced commit the pull moves to.
Merge options
$ git splice pull -h | check-help option merge-options
--branch <name>
Pulls this upstream branch, for this pull only; see 'git splice
merge --help'.
--track
With --branch, also tracks it on the current branch; see 'git splice
merge --help'.
--bump
Also moves the synced commit up to the upstream branch when there's
nothing to pull, e.g. right after a push; see 'git splice merge
--help'.
--rebase
Rebases instead of merging, like 'git pull --rebase'; see 'git
splice merge --help'.
--no-fork-point
Merges a rewritten upstream branch from Git's merge base, not from
where the branch was before the rewrite; see 'git splice merge
--help'.
They work as for merge, after the fetch.
-m
$ git splice pull -h | check-help option -m
Gives the commit this message, for one splice; see 'git splice merge
--help'.
It gives the commit your message instead, e.g. to say why you pull. It
takes one splice: each gets a commit of its own. .splice records the
upstream commit, so nothing needs to stay in the message:
$ echo "pkg-b: fix the feature" >>../pkg-b/file.txt &&
> git -C ../pkg-b commit -qam "pkg-b: fix the feature" &&
> git -C ../pkg-b push -q
$ git splice pull -m "take pkg-b's fix for the release" vendor/pkg-b
ok vendor/pkg-b fetched (main moved b937c4f..e81697a)
ok vendor/pkg-b: pulled e81697a
$ git log -1 --format=%s
take pkg-b's fix for the release
--message-template
$ git splice pull -h | check-help option --message-template
Gives each commit a message made from <template>, also with --all;
see 'git splice merge --help'.
It works as for merge, and unlike
-m, it takes --all:
$ echo "pkg-b: speed up the feature" >>../pkg-b/file.txt &&
> git -C ../pkg-b commit -qam "pkg-b: speed up the feature" &&
> git -C ../pkg-b push -q
$ git splice pull --all --message-template 'chore(deps): {command} {path} to {new}'
ok vendor/pkg-a fetched
ok vendor/pkg-b fetched (main moved e81697a..24c1958)
ok vendor/pkg-a: nothing to pull
ok vendor/pkg-b: pulled 24c1958
$ git log -1 --format=%s
chore(deps): pull vendor/pkg-b to 24c1958
--recursive
$ git splice pull -h | check-help option --recursive
Also pulls every splice below each one given, and any a pull above
adds, and makes one commit of each given splice's pulls, with the
message of its own pull. A conflict stops it: resolve it, commit,
and run it again, which skips the splices already pulled. With
--rebase, the pulls come first, on a detached HEAD at the last
pull, and the branch's own commits since are rebased onto them
once.
For nested splices: each splice is
pulled before the ones below it, which then start from what its
upstream recorded for them. A splice its upstream added is fetched and
pulled in the same run. A run stops at the first conflict, and the next
one goes on from there. When the last run ends, the monorepo gets one
commit per splice given: the message of that splice's own pull, from
--message-template if given, followed by the messages of the pulls
below it. Each splice's history has it on top of its own commits. --all
pulls each splice the monorepo has in the same way
(a recursive pull).
With --rebase, the pulls go at the newest commit that changed a
.splice in the tree, on a detached HEAD, so the branch stays where it
was until they're done. Then the branch's own commits since are rebased
onto their commit once. Rebasing onto each pull would replay the pulls
of the splices above it too
(rebased).
Order
$ git splice pull -h | check-help section order
Also fetches the splices below each, and any its pull brings in:
pulling a splice can move their synced commits. Top-down: a splice is
pulled before the ones below it, and a failed fetch stops the splices
above and below it.
pull also fetches the splices below the ones it pulls, and the ones
its pull brings in, since pulling the splice above can move their synced
commits (nesting). It doesn't pull a
splice it brings in: --recursive does.
Conflicts
$ git splice pull -h | check-help section conflicts
On a conflict, resolve it and run 'git commit' (or 'git cherry-pick
--abort' to give up), then re-run pull for any splices left. With
--rebase, it's 'git rebase --continue' (or 'git rebase --abort'); with
--rebase --recursive, only for the branch's own commits, and 'git
switch <branch>' gives up before.
When both sides changed the same lines, the pull stops at a conflict;
resolve it and git commit (diverged history).
Two developers who pull the same splice at different times get conflicts
in .splice when one merges the other's work. Pull the monorepo before
you pull a splice
(concurrent-pulls).
Read more
$ git splice pull -h | check-help section read-more
- A squash merge of the pull's branch keeps the sync point (squash-merged-pull).
- When
git bisectends at a pull, the upstream commits squashed into it can be tested inside the monorepo, to find the one that broke it (bisect-into-a-pull).