Subtrees

Merging and Splitting a Subtree

Changes flow both ways. git subtree pull merges a newer library release into the folder, and git subtree push extracts the commits that touched the folder and pushes them to the library as a branch:

Pulling booknest-ui 1.2.0, then sending a local fix back upstreamShell
cd ../booknest-ui
# Edit book-card.css: a sold-out style
git commit -qam "Add a sold-out card style"
git tag -a v1.2.0 -m "booknest-ui 1.2.0" && git push -q --follow-tags
cd ../booknest
git subtree pull -q --prefix=public/vendor/ui ../server/booknest-ui.git v1.2.0 \
  --squash -m "Update booknest-ui to 1.2.0"
# Edit public/vendor/ui/book-card.css: darker price text for contrast
git commit -qam "Darken the card price for contrast"
git subtree push -q --prefix=public/vendor/ui ../server/booknest-ui.git contrast-fix
git push -q
git -C ../booknest-ui fetch -q && git -C ../booknest-ui log --oneline -2 origin/contrast-fix
Output
From ../server/booknest-ui
 * tag               v1.2.0     -> FETCH_HEAD
Merge made by the 'ort' strategy.
 public/vendor/ui/book-card.css | 1 +
 1 file changed, 1 insertion(+)
git push using:  ../server/booknest-ui.git contrast-fix
To ../server/booknest-ui.git
 * [new branch]      d5fbb791dd293774682938460578b56429aeb14c -> contrast-fix
d5fbb79 Darken the card price for contrast
a1397af Add a sold-out card style

The pull was an ordinary ORT merge of a squashed 1.2.0. The push ran git subtree split: it walked BookNest's history, kept the commits that touched public/vendor/ui/, and rewrote them as if that folder were the root. The result, d5fbb79, sits on the library's 1.2.0 commit, ready for its maintainer to merge. Keep subtree changes in their own commits, and note that split walks the whole history each time; --rejoin records a marker so later splits start from there.