Skip to content

Instantly share code, notes, and snippets.

@jwhitley
Last active January 14, 2024 17:59
Show Gist options
  • Save jwhitley/bea6a8cc9e59151a468a12aac80ccf13 to your computer and use it in GitHub Desktop.
Save jwhitley/bea6a8cc9e59151a468a12aac80ccf13 to your computer and use it in GitHub Desktop.
Shell script that replicates lazygit repo_paths_test.go scenarios
#!/bin/zsh
startPath=`pwd`
setupTmpdir() {
relTmpDir=`mktemp -d /tmp/lazygitRepoPath.XXXXXX`
TMPDIR=`realpath "$relTmpDir"`
cd $TMPDIR
}
cleanupTmpdir() {
cd "$startPath"
rm -rf $TMPDIR
}
grp() {
git rev-parse --path-format=absolute $*
}
# outputs a report of the intended RepoPaths
# for the current scenario. This is
# a git + shell reimplementation of GetRepoPaths()
reportRepoPaths() {
[[ -n "$GIT_DIR" ]] && echo "GIT_DIR: $GIT_DIR"
echo "currentPath:" "\"`pwd`\","
worktreePath=`grp --show-toplevel`
echo "worktreePath:" "\"$worktreePath\","
worktreeGitDirPath=`grp --git-dir`
echo "worktreeGitDirPath:" "\"$worktreeGitDirPath\","
# If we're in a submodule, superprojectWorkingTree will be non-empty;
# return the worktree path as the repoPath. Otherwise we're in a
# normal repo or a worktree so return the parent of the git common
# dir (repoGitDirPath)
superprojectWorkingTree=`grp --show-superproject-working-tree`
commonGitDir=`grp --git-common-dir`
if [[ -n "$superprojectWorkingTree" ]]; then
repoPath="$worktreePath"
else
repoPath=`dirname $commonGitDir`
fi
echo "repoPath:" "\"$repoPath\","
echo "repoGitDirPath:" "\"$commonGitDir\","
echo "repoName:" "\"`basename $repoPath`\","
}
exitIfDebug() {
[[ -z "$DEBUG" ]] && return 0
echo "skipping cleanup. repos can be inspected in:" "$TMPDIR"
exit 0
}
runScenario() {
[[ -n "$RUN" && "$RUN" != "$1" ]] && return 0
echo "--- running: $1"
setupTmpdir
# run the scenario
eval "$1"
# report the paths
reportRepoPaths | sed "s:$TMPDIR:/path/to:"
unset GIT_DIR
exitIfDebug $1
cleanupTmpdir
}
addStuff() {
echo "foo" > foo.txt
git add foo.txt >& /dev/null
git commit -m "adding foo" >& /dev/null
echo "bar" > bar.txt
git add bar.txt >& /dev/null
git commit -m "adding bar" >& /dev/null
}
addOtherStuff() {
echo "baz" > baz.txt
git add baz.txt >& /dev/null
git commit -m "adding baz" >& /dev/null
echo "kar" > kar.txt
git add kar.txt >& /dev/null
git commit -m "adding kar" >& /dev/null
}
addDeepPath() {
mkdir -p a/b/c
echo "all the way down" > a/b/c/deep.txt
git add a/b/c/deep.txt >& /dev/null
git commit -m "adding deep" >& /dev/null
}
# single, normal git repo
typicalCase() {
git init repo >& /dev/null
cd repo
addStuff
}
# single worktree
worktreeCase() {
git init repo >& /dev/null
cd repo
addStuff
git worktree add ../worktree1 >& /dev/null
cd ../worktree1
}
worktreeSubdirCase() {
git init repo >& /dev/null
cd repo
addDeepPath
git worktree add ../worktree1 >& /dev/null
cd ../worktree1/a/b/c
}
# This case builds up a "fake" bare repo as constructed by
# some git-based homedir versioning tools like vcsh. This
# structure is used to work with many overlaid but non-
# intersecting repos onto one worktree root path.
fakeBareRepoCase() {
git init repo >& /dev/null
cd repo
addDeepPath
cd ..
export GIT_DIR=`pwd`/bareRepo.git
git init --shared=false >& /dev/null
export V_BASE=`pwd`
git config core.bare false >& /dev/null
git config core.worktree "$(cd "$GIT_DIR" && GIT_WORK_TREE=$V_BASE git rev-parse --show-cdup)" >& /dev/null
git remote add origin `pwd`/repo >& /dev/null
git checkout -b main >& /dev/null
git config branch.main.remote origin >& /dev/null
git config branch.main.merge refs/heads/main >& /dev/null
git fetch origin main >& /dev/null
git -c merge.ff=true merge origin/main >& /dev/null
cd a/b/c
}
submoduleCase() {
git init repo >& /dev/null
cd repo
addStuff
cd ..
git init dependency >& /dev/null
cd dependency
addDeepPath
cd ../repo
# the git config (-c) parameter below is required
# to let git create a file-protocol/path submodule
git -c protocol.file.allow=always submodule add ../dependency my/submodule1 >& /dev/null
git commit -m "add dependency as submodule1" >& /dev/null
cd my/submodule1
}
linkedSubmoduleCase() {
git init repo >& /dev/null
cd repo
addStuff
cd ..
git init dependency >& /dev/null
cd dependency
addDeepPath
cd ../repo
# the git config (-c) parameter below is required
# to let git create a file-protocol/path submodule
git -c protocol.file.allow=always submodule add ../dependency my/submodule1 >& /dev/null
git commit -m "add dependency as submodule1" >& /dev/null
ln -s `realpath my/submodule1` linkedSubmodule
cd linkedSubmodule
}
doubleLinkedSubmoduleCase(){
caseRoot=`pwd`
git init repo >& /dev/null
cd $caseRoot/repo
addStuff
cd $caseRoot
git init innerSubmodule >& /dev/null
cd innerSubmodule
addDeepPath
cd $caseRoot
git init outerSubmodule >& /dev/null
cd outerSubmodule
addOtherStuff
git -c protocol.file.allow=always submodule add ../innerSubmodule >& /dev/null
git commit -m "add dependency as innerSubmodule" >& /dev/null
cd $caseRoot/repo
# the git config (-c) parameter below is required
# to let git create a file-protocol/path submodule
git -c protocol.file.allow=always submodule add ../outerSubmodule >& /dev/null
git commit -m "add dependency as outerSubmodule" >& /dev/null
cd outerSubmodule
git -c protocol.file.allow=always submodule update --init --recursive >& /dev/null
cd $caseRoot
ln -s repo/outerSubmodule/innerSubmodule/a/b/c cLink
cd cLink
}
if [[ -n "$1" ]]; then
RUN="$1"
fi
runScenario typicalCase
runScenario worktreeCase
runScenario worktreeSubdirCase
runScenario submoduleCase
runScenario fakeBareRepoCase
runScenario linkedSubmoduleCase
runScenario doubleLinkedSubmoduleCase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment