"W. Trevor King" <wk...@tremily.us> writes:

> The previous code only checked out branches in cmd_add.  This commit
> moves the branch-checkout logic into module_clone, where it can be
> shared by cmd_add and cmd_update.  I also update the initial checkout
> command to use 'reset' to preserve branches setup during module_clone.
>
> With this change, folks cloning submodules for the first time via:
>
>   $ git submodule update ...
>
> will get a local branch instead of a detached HEAD, unless they are
> using the default checkout-mode updates.  This is a change from the
> previous situation where cmd_update always used checkout-mode logic
> (regardless of the requested update mode) for updates that triggered
> an initial clone, which always resulted in a detached HEAD.
>
> This commit does not change the logic for updates after the initial
> clone, which will continue to create detached HEADs for checkout-mode
> updates, and integrate remote work with the local HEAD (detached or
> not) in other modes.
>
> The motivation for the change is that developers doing local work
> inside the submodule are likely to select a non-checkout-mode for
> updates so their local work is integrated with upstream work.
> Developers who are not doing local submodule work stick with
> checkout-mode updates so any apparently local work is blown away
> during updates.  For example, if upstream rolls back the remote branch
> or gitlinked commit to an earlier version, the checkout-mode developer
> wants their old submodule checkout to be rolled back as well, instead
> of getting a no-op merge/rebase with the rolled-back reference.
>
> By using the update mode to distinguish submodule developers from
> black-box submodule consumers, we can setup local branches for the
> developers who will want local branches, and stick with detached HEADs
> for the developers that don't care.
>
> Signed-off-by: W. Trevor King <wk...@tremily.us>
> ---
>  git-submodule.sh | 53 ++++++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 36 insertions(+), 17 deletions(-)
>
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 68dcbe1..4a09951 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -246,6 +246,9 @@ module_name()
>  # $3 = URL to clone
>  # $4 = reference repository to reuse (empty for independent)
>  # $5 = depth argument for shallow clones (empty for deep)
> +# $6 = (remote-tracking) starting point for the local branch (empty for HEAD)
> +# $7 = local branch to create (empty for a detached HEAD, unless $6 is
> +#      also empty, in which case the local branch is left unchanged)
>  #
>  # Prior to calling, cmd_update checks that a possibly existing
>  # path is not a git repository.
> @@ -259,6 +262,8 @@ module_clone()
>       url=$3
>       reference="$4"
>       depth="$5"
> +     start_point="$6"
> +     local_branch="$7"
>       quiet=
>       if test -n "$GIT_QUIET"
>       then
> @@ -312,7 +317,16 @@ module_clone()
>       echo "gitdir: $rel/$a" >"$sm_path/.git"
>  
>       rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')
> -     (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config 
> core.worktree "$rel/$b")
> +     (
> +             clear_local_git_env
> +             cd "$sm_path" &&
> +             GIT_WORK_TREE=. git config core.worktree "$rel/$b" &&
> +             # ash fails to wordsplit ${local_branch:+-B "$local_branch"...}

Interesting...

> +             case "$local_branch" in
> +             '') git checkout -f -q ${start_point:+"$start_point"} ;;
> +             ?*) git checkout -f -q -B "$local_branch" 
> ${start_point:+"$start_point"} ;;
> +             esac

I am wondering if it makes more sense if you did this instead:

        git checkout -f -q ${start_point:+"$start_point"} &&
        if test -n "$local_branch"
        then
                git checkout -B "$local_branch" HEAD
        fi

The optional "re-attaching to the local_branch" done with the second
"checkout" would be a non-destructive no-op to the working tree and
to the index, but it does distinguish between creating the branch
anew and resetting the existing branch in its output (note that
there is no "-q" to squelch it).  By doing it this way, when we
later teach "git branch -f" and "git checkout -B" to report more
about what commits have been lost by such a resetting, you will get
the safety for free if you made the switching with "-B" run without
"-q" here.

> +     ) || die "$(eval_gettext "Unable to setup cloned submodule 
> '\$sm_path'")"
>  }
>  
>  isnumber()
> @@ -475,16 +489,14 @@ Use -f if you really want to add it." >&2
>                               echo "$(eval_gettext "Reactivating local git 
> directory for submodule '\$sm_name'.")"
>                       fi
>               fi
> -             module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" 
> "$depth" || exit
> -             (
> -                     clear_local_git_env
> -                     cd "$sm_path" &&
> -                     # ash fails to wordsplit ${branch:+-b "$branch"...}
> -                     case "$branch" in
> -                     '') git checkout -f -q ;;
> -                     ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
> -                     esac
> -             ) || die "$(eval_gettext "Unable to checkout submodule 
> '\$sm_path'")"
> +             if test -n "$branch"
> +             then
> +                     start_point="origin/$branch"
> +                     local_branch="$branch"
> +             else
> +                     start_point=""
> +             fi

I'd feel safer if the "else" clause explicitly cleared $local_branch
by assigning an empty string to it; it would make it a lot clearer
that "when $branch is an empty string here, we do not want to
trigger the new codepath to run checkout with "-B $local_branch" in
module_clone" is what you mean.

> +             module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" 
> "$depth" "$start_point" "$local_branch" || exit
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to