--- /dev/null
+#!/bin/sh
+
+set -e
+
+# Only one vcsh instance at a time can have the work dir fully populated.
+LOCKDIR=/run/lock/vcsh
+
+# Kill the parent process because vcsh does not catch the hook exit value.
+# See: https://github.com/RichiH/vcsh/issues/251
+mkdir "$LOCKDIR" 2>/dev/null || { echo "An instance of vcsh already entered a repository." 1>&2; kill -- -$PPID;}
+
+# Lock on the parent pid because the hooks are launched as children of vcsh.
+echo $PPID > "$LOCKDIR/pid"
+
+# git read-tree manual page says this is the proper way to fully repopulate
+# the working directory
+git config core.sparseCheckout true
+rm -f "$GIT_DIR/info/sparse-checkout"
+echo "/*" > "$GIT_DIR/info/sparse-checkout"
+git read-tree -mu HEAD
+git config core.sparseCheckout false
--- /dev/null
+#!/bin/sh
+
+set -e
+
+# Only the same instance of vcsh that had the work dir fully populated is
+# allowed to repopulate it sparsely.
+LOCKDIR=/run/lock/vcsh
+LOCKPID=$(cat "$LOCKDIR/pid")
+# Use the parent pid because the hooks are launched as children of vcsh.
+[ "$LOCKPID" = $PPID ] || { echo "Repository entered from another vcsh instance. Aborting." 1>&2; exit 1; }
+
+: "${XDG_CONFIG_HOME:="$HOME/.config"}"
+. "$XDG_CONFIG_HOME/vcsh/hooks-available/sparse-checkout.sh"
+git read-tree -mu HEAD
+
+# Unlock the work dir.
+rm -rf "$LOCKDIR"
--- /dev/null
+#!/bin/sh
+
+: "${XDG_CONFIG_HOME:="$HOME/.config"}"
+
+git config core.sparseCheckout true
+rm -f "$GIT_DIR/info/sparse-checkout"
+ln -s "$XDG_CONFIG_HOME/vcsh/sparse-checkout" "$GIT_DIR/info/sparse-checkout"
--- /dev/null
+#!/bin/sh
+
+git submodule sync --recursive
+git submodule update --init --recursive
--- /dev/null
+../hooks-available/submodule-update.sh
\ No newline at end of file
--- /dev/null
+../hooks-available/populate-sparsely.sh
\ No newline at end of file
--- /dev/null
+../hooks-available/submodule-update.sh
\ No newline at end of file
--- /dev/null
+../hooks-available/populate-fully.sh
\ No newline at end of file
--- /dev/null
+../hooks-available/sparse-checkout.sh
\ No newline at end of file
--- /dev/null
+/*
+!/.gitattributes
+!/.gitignore
+!/.gitmodules
+!/LICENSE*
+!/README*
--- /dev/null
+*
+!/.config
+!/.config/vcsh
+!/.config/vcsh/hooks-available
+!/.config/vcsh/hooks-available/populate-fully.sh
+!/.config/vcsh/hooks-available/populate-sparsely.sh
+!/.config/vcsh/hooks-available/sparse-checkout.sh
+!/.config/vcsh/hooks-available/submodule-update.sh
+!/.config/vcsh/hooks-enabled
+!/.config/vcsh/hooks-enabled/post-clone.00-submodule-init
+!/.config/vcsh/hooks-enabled/post-enter.00-populate-sparsely
+!/.config/vcsh/hooks-enabled/post-pull.00-submodule-init
+!/.config/vcsh/hooks-enabled/pre-enter.00-populate-fully
+!/.config/vcsh/hooks-enabled/pre-upgrade.00-sparse-checkout
+!/.config/vcsh/sparse-checkout
+!/.gitignore
+!/README
--- /dev/null
+vcsh configuration to handle collisions of files common to distinct vcsh
+repositories using the sparse-checkout functionality of git.
+
+The patterns for the colliding files are in .config/vcsh/sparse-checkout and
+a pre-upgrade hook is used to make vcsh repositories use it.
+
+Many git commands (e.g. git-merge, git-checkout) will automatically use the
+information in $GIT_DIR/info/sparse-checkout when dealing with files in the
+git work directory, so generally a calling git-read-tree explicitly is not
+needed.
+
+However when the content of $GIT_DIR/info/sparse-checkout changes it is
+necessary to call "git read-tree -mu HEAD" to update the content of the
+working directory.