Re: When someone creates a new worktree by copying an existing one
From: Tao Klerks <hidden>
Date: 2023-06-01 08:35:17
On Wed, May 31, 2023 at 8:59 PM Tao Klerks [off-list ref] wrote:
I think I can implement something reasonably effective with a pair of hooks (pre-commit and post-checkout look like good candidates), but I'm weirded out that something like this should need to be "custom".
FWIW, here's what that code has ended up looking like, in
post-checkout and pre-commit:
########################################################################
# WORKTREE GIT FILE PATH TO REPO WORKTREE GITDIR FILE PATH CONSISTENCY #
########################################################################
# (this code is duplicated across pre-commit and post-checkout)
WORKTREE_GIT_FILE_PATH="$PWD/.git"
GITDIR_PREFIX="gitdir: "
# Only run worktree consistency checks if it's a worktree - if .git is a file
if [[ -f "$WORKTREE_GIT_FILE_PATH" ]]; then
WORKTREE_GIT_FILE_CONTENT=$(head -n 1 "$WORKTREE_GIT_FILE_PATH")
WORKTREE_METADATA_FOLDER_PATH=${WORKTREE_GIT_FILE_CONTENT#"$GITDIR_PREFIX"}
WORKTREE_GITDIR_FILE_PATH="$WORKTREE_METADATA_FOLDER_PATH/gitdir"
# if the gitdir file doesn't exist, git will complain loudly, no
need to interfere.
if [[ -f "$WORKTREE_GITDIR_FILE_PATH" ]]; then
WORKTREE_GITDIR_PATH=$(head -n 1 "$WORKTREE_GITDIR_FILE_PATH")
# if the gitdir value doesn't match this worktree's git file path,
we have a problem.
if ! [[ "$WORKTREE_GIT_FILE_PATH" -ef "$WORKTREE_GITDIR_PATH" ]]; then
>&2 echo ""
>&2 echo "******************************************************************************"
>&2 echo "* WARNING: It looks like this worktree has moved or
been copied incorrectly! *"
>&2 echo "******************************************************************************"
>&2 echo ""
>&2 echo "The git repo expects this worktree to be at:
$(realpath "$(dirname "$WORKTREE_GITDIR_PATH")")"
>&2 echo ""
>&2 echo "However, it is at: $(realpath "$(dirname
"$WORKTREE_GIT_FILE_PATH")")"
>&2 echo ""
>&2 echo "If you copied an existing worktree to create this one,
then the two worktrees"
>&2 echo "will be badly 'linked', with changes in one affecting
the other. To resolve this,"
>&2 echo "please delete one of the two, and run 'git worktree
repair' in the remaining one."
>&2 echo "You can then properly create a new worktree using 'git
worktree add'. You"
>&2 echo "should delete whichever worktree doesn't contain
uncommitted changes you"
>&2 echo "want to keep, of course."
>&2 echo ""
>&2 echo "If you simply moved/renamed this worktree, then run
'git worktree repair' to"
>&2 echo "make the git repo and worktree 'match up' again, and
resolve this warning."
>&2 echo ""
>&2 echo "******************************************************************************"
>&2 echo ""
# in post-checkout this exit code won't change git's behavior,
but git still "echoes" it to
# the calling program, so it's still a useful signal that
something went wrong - which is
# warranted under the circumstances.
exit 1
fi
fi
fi