Jens Lehmann <jens.lehm...@web.de> writes:

> With "git submodule init" the user is able to tell git he cares about one
> or more submodules and wants to have it populated on the next call to "git
> submodule update". But currently there is no easy way he could tell git he
> does not care about a submodule anymore and wants to get rid of his local
> work tree (except he knows a lot about submodule internals and removes the
> "submodule.$name.url" setting from .git/config himself).
>
> Help those users by providing a 'deinit' command. This removes the url
> setting from .git/config either for the given submodule(s) or for all
> those which have been initialized if none were given. Complain only when
> for a submodule given on the command line the url setting can't be found
> in .git/config.
>
> Add tests and link the man pages of "git submodule deinit" and "git rm" to
> assist the user in deciding whether removing or unregistering the submodule
> is the right thing to do for him.
>
> Signed-off-by: Jens Lehmann <jens.lehm...@web.de>
> ---

I fully agree with your analysis on the reason why the "url" element
is special and has to be copied to $GIT_DIR/config, but when you
deinit (or uninit) a submodule to say you are no longer interested
in it and do not want it populated in the context of the
superproject, I am not sure if removing only submodule.$name.url (so
that when you later decide to "init" it again, you will keep the
values for submodule.$name.update and other things from the previous
life) is the sane thing to do, or it is better to remove
submodule.$name.* altogether as if an earlier "init" has never
happened.  Would it be worth analyzing the pros-and-cons here?

> Am 01.12.2012 16:56, schrieb Jens Lehmann:
>> Am 01.12.2012 00:52, schrieb Phil Hord:
>>> If I never 'submodule init' a submodule, it does not get visited by
>>> 'git submodule foreach', among others.  I think some people use this
>>> behavior explicitly.
>>>
>>> On the other hand, I've also notice that a submodule which I have
>>> removed does not get de-inited later one.  It causes my 'git submodule
>>> foreach' to emit errors.  :-(
>> 
>> I'm currently hacking on "git submodule deinit" which removes the 'url'
>> setting from git/config. This should do the trick for you, right?
>
> And here we go ...
>
>
>  Documentation/git-rm.txt        |  4 ++++
>  Documentation/git-submodule.txt | 11 +++++++++
>  git-submodule.sh                | 50 
> ++++++++++++++++++++++++++++++++++++++++-
>  t/t7400-submodule-basic.sh      | 11 +++++++++
>  4 files changed, 75 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
> index 262436b..ec42bf5 100644
> --- a/Documentation/git-rm.txt
> +++ b/Documentation/git-rm.txt
> @@ -149,6 +149,10 @@ files that aren't ignored are present in the submodules 
> work tree.
>  Ignored files are deemed expendable and won't stop a submodule's work
>  tree from being removed.
>
> +If you only want to remove the local checkout of a submodule from your
> +work tree without committing that use `git submodule deinit` instead
> +(see linkgit:git-submodule[1]).
> +
>  EXAMPLES
>  --------
>  `git rm Documentation/\*.txt`::
> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index b1de3ba..fba77f6 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -13,6 +13,7 @@ SYNOPSIS
>             [--reference <repository>] [--] <repository> [<path>]
>  'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
>  'git submodule' [--quiet] init [--] [<path>...]
> +'git submodule' [--quiet] deinit [--] [<path>...]
>  'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
>             [--reference <repository>] [--merge] [--recursive] [--] 
> [<path>...]
>  'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) 
> <n>]
> @@ -134,6 +135,16 @@ init::
>       the explicit 'init' step if you do not intend to customize
>       any submodule locations.
>
> +deinit::
> +     Unregister the submodules, i.e. remove the `submodule.$name.url`
> +     setting from .git/config. Further calls to `git submodule update`,
> +     `git submodule foreach` and `git submodule sync` will skip any
> +     unregistered submodules until they are initialized again, so use
> +     this command if you don't want to have a local checkout of the
> +     submodule in your work tree anymore. If you really want to remove
> +     a submodule from the repository and commit that use
> +     linkgit:git-rm[1] instead.
> +
>  update::
>       Update the registered submodules, i.e. clone missing submodules and
>       checkout the commit specified in the index of the containing repository.
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 2365149..4059a2e 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -8,6 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
>  USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference 
> <repository>] [--] <repository> [<path>]
>     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] init [--] [<path>...]
> +   or: $dashless [--quiet] deinit [--] [<path>...]
>     or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] 
> [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] 
> [commit] [--] [<path>...]
>     or: $dashless [--quiet] foreach [--recursive] <command>
> @@ -516,6 +517,53 @@ cmd_init()
>  }
>
>  #
> +# Unregister submodules from .git/config
> +#
> +# $@ = requested paths (default to all)
> +#
> +cmd_deinit()
> +{
> +     # parse $args after "submodule ... init".
> +     while test $# -ne 0
> +     do
> +             case "$1" in
> +             -q|--quiet)
> +                     GIT_QUIET=1
> +                     ;;
> +             --)
> +                     shift
> +                     break
> +                     ;;
> +             -*)
> +                     usage
> +                     ;;
> +             *)
> +                     break
> +                     ;;
> +             esac
> +             shift
> +     done
> +
> +     module_list "$@" |
> +     while read mode sha1 stage sm_path
> +     do
> +             die_if_unmatched "$mode"
> +             name=$(module_name "$sm_path") || exit
> +             url=$(git config submodule."$name".url)
> +             if test -z "$url"
> +             then
> +                     # Only mention uninitialized submodules when its
> +                     # path have been specified
> +                     test "$#" != "0" &&
> +                     say "$(eval_gettext "No url found for submodule path 
> '\$sm_path' in .git/config")"
> +                     continue
> +             fi
> +             git config --unset submodule."$name".url &&
> +             say "$(eval_gettext "Submodule '\$name' (\$url) unregistered")"
> +     done
> +}
> +
> +#
>  # Update each submodule path to correct revision, using clone and checkout 
> as needed
>  #
>  # $@ = requested paths (default to all)
> @@ -1108,7 +1156,7 @@ cmd_sync()
>  while test $# != 0 && test -z "$command"
>  do
>       case "$1" in
> -     add | foreach | init | update | status | summary | sync)
> +     add | foreach | init | deinit | update | status | summary | sync)
>               command=$1
>               ;;
>       -q|--quiet)
> diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
> index de7d453..803bda7 100755
> --- a/t/t7400-submodule-basic.sh
> +++ b/t/t7400-submodule-basic.sh
> @@ -756,4 +756,15 @@ test_expect_success 'submodule add with an existing name 
> fails unless forced' '
>       )
>  '
>
> +test_expect_success 'submodule deinit should unregister submodule url from 
> .git/config' '
> +     url=$(git config submodule.example.url) &&
> +     git submodule deinit &&
> +     test -z "$(git config submodule.example.url)"
> +'
> +
> +test_expect_success 'submodule deinit complains only when explicitly used on 
> an uninitialized submodule' '
> +     git submodule deinit &&
> +     test_must_fail git submodule deinit example
> +'
> +
>  test_done
--
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