Scenario: a recursive pull, a conflict in an update
Updating a splice from its upstream sounds like a fast-forward: the
upstream has new commits, and the splice takes them. That holds for a
splice with nothing of its own. Once the monorepo has changed the
splice too, an update is a merge of two lines of work, as git pull is
in a clone with local commits, and it can conflict like one.
Here, d/ has nothing of its own, and vendor/a/ has the monorepo's
commit m1, on the same lines a's upstream changed in a2.
Output
setup.bash builds this state:
$ build_scenario scenario_recursive_pull
$ git clone -q https://git.example.com/d.git ../d-work &&
> echo "d upstream" >>../d-work/file.txt &&
> git -C ../d-work commit -q -am "d2: d upstream" &&
> git -C ../d-work push -q origin main
$ git clone -q https://git.example.com/a.git ../a-work &&
> echo "a upstream" >>../a-work/file.txt &&
> git -C ../a-work commit -q -am "a2: a upstream" &&
> git -C ../a-work push -q origin main
$ echo "a in the monorepo" >>vendor/a/file.txt &&
> git commit -q -am "m1: a in the monorepo"
A fast-forward
d/ takes d2, and that's all:
$ git splice pull vendor/a/d
ok vendor/a/d fetched (main moved 2c64d15..36c850e)
ok vendor/a/d: pulled 36c850e
d2 is d/'s synced commit now, and vendor/a/, which contains d/,
gets the copy of that pull, pd', on top of its own:
A merge
vendor/a/'s head isn't its synced commit a1 any more: its history
has the copies of m1 and of the pull of d/, pd', on top. a2
merges into it, from a1, the base, and m1 and a2 changed the same
line of file.txt:
$ git splice pull vendor/a
ok vendor/a fetched (main moved 764d9c4..4936f17)
ok vendor/a/b fetched
ok vendor/a/b/c fetched
ok vendor/a/d fetched
Auto-merging vendor/a/file.txt
CONFLICT (content): Merge conflict in vendor/a/file.txt
!! vendor/a: conflict -- resolve it, then 'git commit' (or 'git cherry-pick --abort' to give up)
!! vendor/a: pull failed
!! Failed: vendor/a
[1]
$ git diff vendor/a/file.txt
diff --cc vendor/a/file.txt
index b63060e,106bfed..0000000
--- a/vendor/a/file.txt
+++ b/vendor/a/file.txt
@@@ -1,2 -1,2 +1,6 @@@
a seed
++<<<<<<< HEAD
+a in the monorepo
++=======
+ a upstream
++>>>>>>> 21988c5 (splice: pull vendor/a from main at 4936f17)
Resolved, the merge is a commit like any other. vendor/a/ is at
a2 now, with its own commits on top, and d/ at d2, with none:
$ printf 'a seed\na in the monorepo\na upstream\n' >vendor/a/file.txt &&
> git add vendor/a/file.txt &&
> git commit -q --no-edit
A splice's head can also differ from its synced commit by what its
parent's upstream changed in its folder: in
the recursive pull, b's upstream's change to c/ meets
c's upstream's in the same way.