Commit dfc23192 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add the git-supertree-mv subcommand

parent 5170422e
Loading
Loading
Loading
Loading
+67 −2
Original line number Diff line number Diff line
@@ -62,6 +62,12 @@ $SCRIPT add [--from SOURCE] BRANCH[:PATH]
  matching branch does not exist it is created from
  SOURCE (default: base 'HEAD').

$SCRIPT mv [--branch] NAME NEW-NAME
  Move a worktree to a new path.

  --branch  Create a new branch with the name NEW-NAME and check it out in the
            moved worktree.

$SCRIPT rm [--branch] NAME
  Remove a worktree named NAME.

@@ -225,6 +231,18 @@ gitlink()
	realpath --relative-to=${REL-$(dirname $1)} $2
} > $1

readlink()
{
	local link=$(<$1)
	if [[ -v PREFIX ]]; then
		if [[ ${link%%:*} != ${PREFIX} ]]; then
			die "Wrong type of link: '$link' is not a $PREFIX link"
		fi
		link=${link#${PREFIX}: }
	fi
	realpath --relative-to="$PWD" "$(dirname "$1")/$link"
}


action_init()
{
@@ -377,6 +395,53 @@ action_add()
	new_worktree "$BRANCH_PATH" "$BRANCH_NAME"
}

action_mv()
{
	local NAME NEW_NAME CREATE
	while [[ $# -gt 0 ]]; do
		case $1 in
			--branch) CREATE=yes ;;
			*) case '' in
				${NAME-}) NAME=$1 ;;
				${NEW_NAME-}) NEW_NAME=$1 ;;
				*) arg_error "Unknown argument: $1" ;;
			esac ;;
		esac
		shift
	done

	if ! [[ -v NAME ]]; then
		arg_error "A source worktree name is required"
	fi
	if ! [[ -v NEW_NAME ]]; then
		arg_error "A target worktree name is required"
	fi

	if ! is_subdirectory "$NAME"; then
		arg_error "The first argument must be a worktree name"
	fi
	if [[ -e "$NEW_NAME" ]]; then
		arg_error "$NEW_NAME already exists"
	fi

	local WT_GIT="$NEW_NAME/.git"
	local WT_REPO=".git/worktrees/$NEW_NAME"

	mkdir -p $(dirname "$WT_REPO")
	mv $(PREFIX=gitdir readlink "$NAME/.git") "$WT_REPO"

	mkdir -p $(dirname "$NEW_NAME")
	mv "$NAME" "$NEW_NAME"

	PREFIX=gitdir gitlink $WT_GIT $WT_REPO
	REL=.git gitlink "$WT_REPO/gitdir" "$WT_GIT"
	gitlink "$WT_REPO/commondir" .git

	if [[ -v CREATE ]]; then
		git checkout -b $NEW_NAME
	fi
}

action_rm()
{
	local BRANCH DELETE
@@ -416,11 +481,11 @@ action_rm()
while [ $# -gt 0 ]; do
	case $1 in
		-h|--help) help ;;
		init|clone|convert|add|rm) COMMAND=$1 ;;
		init|clone|convert|add|mv|rm) COMMAND=$1 ;;
		*) break ;;
	esac
	shift
done

[[ -v COMMAND ]] || arg_error "'init', 'clone' or 'convert' is required"
[[ -v COMMAND ]] || arg_error "'init', 'clone', 'convert', 'add', 'mv' or 'rm' is required"
action_$COMMAND "$@"
+8 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ _git-supertree()
				'clone:Clone a new git repo with support for the supertree layout.'
				'convert:Convert a vanilla repo to a supertree layout.'
				'add:Add a worktree to the supertree.'
				'mv:Move a worktree to a new path.'
				'rm:Remove a worktree.'
			)
			_describe -t commands 'git supertree' subcommands
@@ -81,6 +82,13 @@ _git-supertree()
						':BRANCH:__git_supertree_branch_spec' \
					;;

				(mv)
					_arguments \
						'--branch[Create a new branch as well as the working tree]' \
						':path:_directories' \
						':newpath:_directories' \
					;;

				(rm)
					_arguments \
						'--rm-branch[Delete the branch as well as the working tree]' \