splitsh-lite replaces the subtree split
Git built-in command to make
splitting a monolithic repository to read-only standalone repositories
easy and fast.
When starting a project, do you store all the code in one repository? Or are you creating many standalone repositories?
Both strategies work well and both have drawbacks as well. splitsh helps use both strategies by providing tools that automatically synchronize a monolithic repository to standalone repositories in real-time.
splitsh-lite is a sub-project that provides a faster implementation of the
git subtree split
command, which helps create standalone repositories for one
or more sub-directories of a main repository.
If you want to learn more about monorepo vs manyrepos, watch this 4-minute lightning talk I gave at dotScale (or read the slides)... or watch the longer version from DrupalCon. "The Monorepo - Storing your source code has never been so much fun" is also a great resource.
Note If you currently have multiple repositories that you want to merge into a monorepo, use the tomono tool.
First, you need to install libgit2
, preferably using your package manager of
choice.
If you get libgit2
version 1.5
, you're all set and jump to the compilation
step below. If not, you first need to change the git2go
version used in the
code. Using the table on the
libgit2 repository,
figure out which version of the git2go
you need based on the liggit2
library
you installed. Let's say you need version v31
:
sed -i -e 's/v34/v31/g' go.mod splitter/*.go
go mod tidy
Then, compile splitsh-lite
:
go build -o splitsh-lite github.com/splitsh/lite
If everything goes fine, a splitsh-lite
binary should be available in the
current directory.
If you get errors about an incompatible libgit2
library, try exporting the
needed flags, e.g.
export LDFLAGS="-L/opt/homebrew/opt/libgit2@1.5/lib"
export CPPFLAGS="-I/opt/homebrew/opt/libgit2@1.5/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/libgit2@1.5/lib/pkgconfig"
before running go build
.
If you want to integrate splitsh with Git, install it like this (and use it via
git splitsh
):
cp splitsh-lite "$(git --exec-path)"/git-splitsh
Let's say you want to split the lib/
directory of a repository to its own
branch; from the "master" Git repository (bare or clone), run:
splitsh-lite --prefix=lib/
The sha1 of the split is displayed at the end of the execution:
SHA1=`splitsh-lite --prefix=lib/`
The sha1 can be used to create a branch or to push the commits to a new repository.
Automatically create a branch for the split by passing a branch name
via the --target
option:
splitsh-lite --prefix=lib/ --target=heads/branch-name
If new commits are made to the repository, update the split by running the same
command again. Updates are much faster as splitsh-lite keeps a cache of
already split commits. Caching is possible as splitsh-lite guarantees that
two splits of the same code always results in the same history and the same
sha1
s for each commit.
By default, splitsh-lite splits the currently checked out branch but you can
split a different branch by passing it explicitly via the --origin
flag
(mandatory when splitting a bare repository):
splitsh-lite --prefix=lib/ --origin=origin/master
You don't even need to run the command from the Git repository directory if you
pass the --path
option:
splitsh-lite --prefix=lib/ --origin=origin/1.0 --path=/path/to/repo
Available options:
-
--prefix
is the prefix of the directory to split; the value can be one of the following:-
from
: the origin directory to split; -
from:to
: move the split content to a sub-directory on the target; -
from:to:exclude
: exclude a directory from the originfrom
directory (usefrom:to:exclude1:exclude2:...
to exclude more than one directory).
Split several directories by passing multiple
--prefix
flags; -
-
--path
is the path of the repository to split (current directory by default); -
--origin
is the Git reference for the origin (can be any Git reference likeHEAD
,heads/xxx
,tags/xxx
,origin/xxx
, or anyrefs/xxx
); -
--target
creates a reference for the tip of the split (can be any Git reference likeheads/xxx
,tags/xxx
,origin/xxx
, or anyrefs/xxx
); -
--progress
displays a progress bar; -
--scratch
flushes the cache (useful when a branch is force pushed or in case of a cache corruption).
Migrating from git subtree split
to splith-lite
is easy as both tools
generate the same sha1
s.
However, note that older versions of git subtree split
used broken
algorithms, and so generated different sha1
s than the latest version. You can
simulate those version via the --git
flag. Use <1.8.2
or <2.8.0
depending
on which version of git subtree split
you want to simulate.