Skip to content

Instantly share code, notes, and snippets.

@mikeslattery
Last active February 25, 2024 20:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikeslattery/48e196a3623608e021e61f6864a3ee74 to your computer and use it in GitHub Desktop.
Save mikeslattery/48e196a3623608e021e61f6864a3ee74 to your computer and use it in GitHub Desktop.
Git Directory Synchronizer
#!/bin/bash
help() { cat<<HELP
git-syncr - git worktree synchronizer
Usage: git syncr <command>
COMMANDS:
create <path> [<branch>]
Create new worktree at <path> forked from current directory.
Set branch name same as basename of path, if not provided.
Stores information about the parent branch in config.
remove <path>
Removes the worktree at <path> and the corresponding branch.
sync [<path>]
Synchronizes repo in path bi-directionally with its parent.
Uses current directory, if none given.
list Alias for "git worktree list"
help This help.
SUGGESTED ALIAS:
git config --global alias.sync 'syncr sync'
HELP
}
set -euo pipefail
pwd="$(pwd)"
thisdir="$(cd "$(dirname "$0")" || exit; pwd)"
this="${thisdir}/$(basename "$0")"
die() {
echo "$* [${BASH_LINENO[0]}]" >&2
exit 1
}
_checkchild() {
path="$1"
branch="$(git -C "$path" rev-parse --abbrev-ref HEAD)"
git -C "$path" config --get "branch.${branch}.parent-branch" > /dev/null || \
die "Not a child sync directory. [${BASH_LINENO[1]}]"
}
# Create new worktree
create() {
path="${1}"
path="$(readlink -f "$path")"
branch="${2:-$(basename "$path")}"
parent_path="$pwd"
parent_branch="$(git rev-parse --abbrev-ref HEAD)"
# Create worktree
git worktree add "$path" -b "$branch"
git config "branch.${branch}.parent-branch" "$parent_branch"
git config "branch.${branch}.parent-path" "$parent_path"
git config "branch.${branch}.path" "$path"
_checkchild "$path"
}
# Remove worktree
remove() {
path="${1}"
branch="$(git -C "$path" rev-parse --abbrev-ref HEAD)"
parent_branch="$(git -C "$path" config --get "branch.${branch}.parent-branch")"
parent_path="$( git -C "$path" config --get "branch.${branch}.parent-path")"
_checkchild "$path"
# Remove tree
git -C "$parent_path" worktree remove "$path"
git -C "$parent_path" branch -D "$branch"
}
list() {
git worktree list "$@"
}
sync() {
path="${1:-$pwd}"
path="$(readlink -f "$path")"
branch="$(git -C "$path" rev-parse --abbrev-ref HEAD)"
parent_branch="$(git -C "$path" config --get "branch.${branch}.parent-branch")"
parent_path="$( git -C "$path" config --get "branch.${branch}.parent-path")"
_checkchild "$path"
# Get latest changes from parent
git -C "$path" rebase "${parent_branch}"
# Push changes to parent
git -C "$parent_path" merge "${branch}" --ff
}
main() {
if [[ "$#" == "0" ]]; then
help
exit 0
fi
"$@"
}
main "$@"
@heijligers
Copy link

Can you explain a little bit more about how to use this?
Especially in aider?
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment