(Hmmpth, forgot signoff...)

To whom it may interest, added some CC.

2014/1/5 Francesco Pretto <cez...@gmail.com>:
> At the current state, the following use-case is not supported very
> well in git:
> - a maintainer adds a submodule, checking out a specific branch of
> the repository. He doesn't track the upstream submodule revision sha1;
> - a developer checkout the repository branch decided by the maintainer.
> Subsequent "merge" or "rebase" update operations don't detach the HEAD.
>
> To ease the above use-case this patch:
> - introduces a "submodule.<module>.attached" property that, when set
>   to "true", ensures that the "update" operation will result in
>   the HEAD attached to a branch;
> - introduces "--attach|--dettach" switches to the submodule "update"
>   command: they attach/detach the HEAD, overriding
>   "submodule.<module>.attached" property value;
> - introduces "--attached-update" switch to the "add" operation. It:
>     * sets "submodule.<module>.attached" to true;
>     * sets "submodule.<module>.ignore" to all.
>
> Using the '--attach' switch or operating in a repository with
> 'submodule.<name>.attached' set to 'true' during "update" will:
> - checkout a branch with an attached HEAD if the repository was just
> cloned;
> - perform a fast-forward only merge of changes if it's a 'checkout'
> update operation;
> - reattach the HEAD prior performing a 'merge', 'rebase' or '!command'
> update operation if the HEAD was found detached. Orphaned commits
> will also be merged back in the branch.
>
> '--attach' or 'submodule.<name>.attached' set to true also implies '--remote'.
>
> Using  the '--detach' switch or operating in a repository with
> 'submodule.<name>.attached' set to 'false' during "update" will:
> - checkout a detached HEAD if the repository was just cloned;
> - detach the HEAD prior performing a 'merge', 'rebase' or '!command'
> update operation if the HEAD was found attached.
>
> 'submodule.<name>.attached' works similarly to 'submodule.<name>.update'
> property: git copies the values found in ".gitmodules" in ".git/config" when
> performing an "init" command. "update" looks for values in ".git/config"
> only.
>
> '--attach' and '--detach' switches override an opposite behaviour
> of 'submodule.<name>.attached' properties.
>
> The patch is strongly additive and doesn't break any submodule specific
> test. It also adds some tests specific to the added feature.
> ---
>  Documentation/git-submodule.txt    |  48 +++++--
>  Documentation/gitmodules.txt       |  10 +-
>  git-submodule.sh                   | 154 +++++++++++++++++++--
>  t/t7410-submodule-attached-head.sh | 268 
> +++++++++++++++++++++++++++++++++++++
>  4 files changed, 457 insertions(+), 23 deletions(-)
>  create mode 100755 t/t7410-submodule-attached-head.sh
>
> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index bfef8a0..b97eefb 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -10,13 +10,14 @@ SYNOPSIS
>  --------
>  [verse]
>  'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>]
> -             [--reference <repository>] [--depth <depth>] [--] <repository> 
> [<path>]
> +             [--reference <repository>] [--attached-update] [--depth <depth>]
> +             [--] <repository> [<path>]
>  'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
>  'git submodule' [--quiet] init [--] [<path>...]
>  'git submodule' [--quiet] deinit [-f|--force] [--] <path>...
>  'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]
> -             [-f|--force] [--rebase] [--reference <repository>] [--depth 
> <depth>]
> -             [--merge] [--recursive] [--] [<path>...]
> +             [-f|--force] [--rebase] [--reference <repository>] [--attach | 
> --detach]
> +             [--depth <depth>] [--merge] [--recursive] [--] [<path>...]
>  'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) 
> <n>]
>               [commit] [--] [<path>...]
>  'git submodule' [--quiet] foreach [--recursive] <command>
> @@ -107,6 +108,9 @@ is the superproject and submodule repositories will be 
> kept
>  together in the same relative location, and only the
>  superproject's URL needs to be provided: git-submodule will correctly
>  locate the submodule using the relative URL in .gitmodules.
> ++
> +If `--attached-update` is specified, the property `submodule.<name>.attached`
> +will be set to `true` and `submodule.<name>.ignore` will be set to `all`.
>
>  status::
>         Show the status of the submodules. This will print the SHA-1 of the
> @@ -156,12 +160,15 @@ it contains local modifications.
>  update::
>         Update the registered submodules, i.e. clone missing submodules and
>         checkout the commit specified in the index of the containing 
> repository.
> -       This will make the submodules HEAD be detached unless `--rebase` or
> -       `--merge` is specified or the key `submodule.$name.update` is set to
> -       `rebase`, `merge` or `none`. `none` can be overridden by specifying
> -       `--checkout`. Setting the key `submodule.$name.update` to `!command`
> -       will cause `command` to be run. `command` can be any arbitrary shell
> -       command that takes a single argument, namely the sha1 to update to.
> +       This will make the submodules HEAD be detached unless `--attach` is
> +       specified or `submodule.$name.attached` is set to `true`. The last 
> setting
> +       can always be overridden specifying `--detach`. Update mode can be
> +       selected specifying `--checkout`, `--rebase` or `--merge` switches
> +       or setting the key `submodule.$name.update` to `checkout`, `rebase`,
> +       `merge` or `none`. `none` will cause the submodule to be skipped 
> during
> +       the update. Setting the key `submodule.$name.update` to `!command` 
> will
> +       cause `command` to be run. `command` can be any arbitrary shell 
> command
> +       that takes a single argument, namely the sha1 to update to.
>  +
>  If the submodule is not yet initialized, and you just want to use the
>  setting as stored in .gitmodules, you can automatically initialize the
> @@ -270,6 +277,23 @@ OPTIONS
>         be overridden by setting the `submodule.<name>.branch` option in
>         either `.gitmodules` or `.git/config` (with `.git/config` taking
>         precedence).
> +
> +--attached-update::
> +       This option is only valid for the add command. Causes the add command
> +       also to set the property `submodule.<name>.attached` to `true` and
> +       the property `submodule.<name>.ignore` to `all`.
> +
> +--attach::
> +       This option is only valid for the update commands. Causes the result
> +       of an update operation to be an attached HEAD. In the update 
> operation,
> +       the branch named by 'submodule.<name>.branch' is checked out as the 
> new
> +       HEAD of the submodule repository. If 'submodule.<name>.branch' is not
> +       set, the 'master' branch is checked out as the new HEAD of the
> +       submodule. Note: `--attach` also implies `--remote`.
> +
> +--detach::
> +       This option is only valid for the update command. Forces the result
> +       of the update operation to be a detached HEAD in the submodule.
>  +
>  This works for any of the supported update procedures (`--checkout`,
>  `--rebase`, etc.).  The only change is the source of the target SHA-1.
> @@ -290,8 +314,7 @@ SHA-1.  If you don't want to fetch, you should use 
> `submodule update
>  --merge::
>         This option is only valid for the update command.
>         Merge the commit recorded in the superproject into the current branch
> -       of the submodule. If this option is given, the submodule's HEAD will
> -       not be detached. If a merge failure prevents this process, you will
> +       of the submodule. If a merge failure prevents this process, you will
>         have to resolve the resulting conflicts within the submodule with the
>         usual conflict resolution tools.
>         If the key `submodule.$name.update` is set to `merge`, this option is
> @@ -300,8 +323,7 @@ SHA-1.  If you don't want to fetch, you should use 
> `submodule update
>  --rebase::
>         This option is only valid for the update command.
>         Rebase the current branch onto the commit recorded in the
> -       superproject. If this option is given, the submodule's HEAD will not
> -       be detached. If a merge failure prevents this process, you will have
> +       superproject. If a merge failure prevents this process, you will have
>         to resolve these failures with linkgit:git-rebase[1].
>         If the key `submodule.$name.update` is set to `rebase`, this option is
>         implicit.
> diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
> index f7be93f..9c436db 100644
> --- a/Documentation/gitmodules.txt
> +++ b/Documentation/gitmodules.txt
> @@ -38,7 +38,8 @@ submodule.<name>.url::
>  submodule.<name>.update::
>         Defines what to do when the submodule is updated by the superproject.
>         If 'checkout' (the default), the new commit specified in the
> -       superproject will be checked out in the submodule on a detached HEAD.
> +       superproject (or branch, with '--attach') will be checked out in
> +       the submodule.
>         If 'rebase', the current branch of the submodule will be rebased onto
>         the commit specified in the superproject. If 'merge', the commit
>         specified in the superproject will be merged into the current branch
> @@ -54,6 +55,13 @@ submodule.<name>.branch::
>         If the option is not specified, it defaults to 'master'.  See the
>         `--remote` documentation in linkgit:git-submodule[1] for details.
>
> +submodule.<name>.attached::
> +       Determine if the update operation will produce a detached HEAD or not.
> +       Valid values are `true` or `false`. If the property is set to `true`
> +       and `submodule.<name>.branch` is not set, the branch `master` will
> +       be checked out. If `submodule.<name>.branch` is set the branch
> +       specified will be checked out instead.
> +
>  submodule.<name>.fetchRecurseSubmodules::
>         This option can be used to control recursive fetching of this
>         submodule. If this option is also present in the submodules entry in
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 1d041a7..bc6df2b 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -5,11 +5,11 @@
>  # Copyright (c) 2007 Lars Hjemli
>
>  dashless=$(basename "$0" | sed -e 's/-/ /')
> -USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference 
> <repository>] [--] <repository> [<path>]
> +USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference 
> <repository>] [--attached-update] [--] <repository> [<path>]
>     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] init [--] [<path>...]
>     or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
> -   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] 
> [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] 
> [--] [<path>...]
> +   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] 
> [-f|--force] [--rebase] [--reference <repository>] [--attach | --detach] 
> [--merge] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] 
> [commit] [--] [<path>...]
>     or: $dashless [--quiet] foreach [--recursive] <command>
>     or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
> @@ -36,6 +36,9 @@ update=
>  prefix=
>  custom_name=
>  depth=
> +attach=
> +detach=
> +attached_update=
>
>  # The function takes at most 2 arguments. The first argument is the
>  # URL that navigates to the submodule origin repo. When relative, this URL
> @@ -352,6 +355,9 @@ cmd_add()
>                         custom_name=$2
>                         shift
>                         ;;
> +               --attached-update)
> +                       attached_update=yes
> +                       ;;
>                 --depth)
>                         case "$2" in '') usage ;; esac
>                         depth="--depth=$2"
> @@ -491,6 +497,12 @@ Use -f if you really want to add it." >&2
>         then
>                 git config -f .gitmodules submodule."$sm_name".branch 
> "$branch"
>         fi &&
> +       if test -n "$attached_update"
> +       then
> +               # We'll stay stick to the HEAD, no need to track revision sha1
> +               git config -f .gitmodules submodule."$sm_name".attached "true"
> +               git config -f .gitmodules submodule."$sm_name".ignore "all"
> +       fi &&
>         git add --force .gitmodules ||
>         die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
>  }
> @@ -632,6 +644,22 @@ cmd_init()
>                         git config submodule."$name".update "$upd" ||
>                         die "$(eval_gettext "Failed to register update mode 
> for submodule path '\$displaypath'")"
>                 fi
> +
> +               # Copy "attached" setting when it is not set yet
> +               if attached="$(git config -f .gitmodules 
> submodule."$name".attached)" &&
> +                  test -n "$attached" &&
> +                  test -z "$(git config submodule."$name".attached)"
> +               then
> +                       case "$attached" in
> +                       true | false)
> +                               ;; # Valid attach flag values
> +                       *)
> +                               echo >&2 "warning: invalid attach flag value 
> for submodule '$name'"
> +                               ;;
> +                       esac
> +                       git config submodule."$name".attached "$attached" ||
> +                       die "$(eval_gettext "Failed to register attach option 
> for submodule path '\$displaypath'")"
> +               fi
>         done
>  }
>
> @@ -750,6 +778,14 @@ cmd_update()
>                 --reference=*)
>                         reference="$1"
>                         ;;
> +               --attach)
> +                       if test -n "$detach" ; then usage ; fi
> +                       attach=1
> +                       ;;
> +               --detach)
> +                       if test -n "$attach" ; then usage ; fi
> +                       detach=1
> +                       ;;
>                 -m|--merge)
>                         update="merge"
>                         ;;
> @@ -800,6 +836,28 @@ cmd_update()
>                 name=$(module_name "$sm_path") || exit
>                 url=$(git config submodule."$name".url)
>                 branch=$(get_submodule_config "$name" branch master)
> +               attach_module=
> +               detach_module=
> +               if test -n "$attach" -o -n "$detach"
> +               then
> +                       attach_module=$attach
> +                       detach_module=$detach
> +               else
> +                       attached=$(git config submodule."$name".attached)
> +                       case "$attached" in
> +                       '')
> +                               ;; # Unset attach flag
> +                       true)
> +                               attach_module=1
> +                               ;;
> +                       false)
> +                               detach_module=1
> +                               ;;
> +                       *)
> +                               echo >&2 "warning: invalid attach flag value 
> for submodule '$name'"
> +                               ;;
> +                       esac
> +               fi
>                 if ! test -z "$update"
>                 then
>                         update_module=$update
> @@ -848,7 +906,16 @@ Maybe you want to use 'update --init'?")"
>                         die "$(eval_gettext "Unable to find current revision 
> in submodule path '\$displaypath'")"
>                 fi
>
> -               if test -n "$remote"
> +               head_rev_ref=$(clear_local_git_env; cd "$sm_path" && git 
> rev-parse --abbrev-ref HEAD) ||
> +               die "$(eval_gettext "Unable to determine revision ref in 
> submodule path '\$sm_path'")"
> +               head_detached=
> +               if test "$head_rev_ref" = "HEAD"
> +               then
> +                       # Determine if the HEAD is detached
> +                       head_detached="true"
> +               fi
> +
> +               if test -n "$remote" -o -n "$attach_module"
>                 then
>                         if test -z "$nofetch"
>                         then
> @@ -862,7 +929,8 @@ Maybe you want to use 'update --init'?")"
>                         die "$(eval_gettext "Unable to find current 
> ${remote_name}/${branch} revision in submodule path '\$sm_path'")"
>                 fi
>
> -               if test "$subsha1" != "$sha1" -o -n "$force"
> +               if test "$subsha1" != "$sha1" || test -n "$attach_module" -a 
> -n "$head_detached" ||
> +                       test -n "$detach_module" -a -z "$head_detached" || 
> test -n "$force"
>                 then
>                         subforce=$force
>                         # If we don't already have a -f flag and the 
> submodule has never been checked out
> @@ -882,40 +950,108 @@ Maybe you want to use 'update --init'?")"
>                         fi
>
>                         # Is this something we just cloned?
> +                       just_cloned=
>                         case ";$cloned_modules;" in
>                         *";$name;"*)
>                                 # then there is no local change to integrate
> -                               update_module= ;;
> +                               update_module="checkout"
> +                               just_cloned=yes
> +                               ;;
>                         esac
>
> +                       if test -z "$update_module"
> +                       then
> +                               # Fallback to checkout
> +                               update_module="checkout"
> +                       fi
> +
> +                       command_attach=:
> +                       suffix_attach=
> +                       if test "$update_module" != "checkout"
> +                       then
> +                               if test -n "$attach_module" -a -n 
> "$head_detached"
> +                               then
> +                                       # We need to reattach to the branch
> +                                       command_attach="git checkout 
> $subforce -q"
> +                                       suffix_attach=$branch
> +                               elif test -n "$detach_module" -a -z 
> "$head_detached"
> +                               then
> +                                       # We need to detach from the branch
> +                                       command_attach="git checkout 
> $subforce -q"
> +                                       suffix_attach=$sha1
> +                               fi
> +                       fi
> +
> +                       command_pre=:
> +                       suffix_pre=
> +                       command_post=:
> +                       suffix_pre=
> +                       suffix=
>                         must_die_on_failure=
> +                       custom_update=
>                         case "$update_module" in
>                         rebase)
>                                 command="git rebase"
> +                               suffix=$sha1
>                                 die_msg="$(eval_gettext "Unable to rebase 
> '\$sha1' in submodule path '\$displaypath'")"
>                                 say_msg="$(eval_gettext "Submodule path 
> '\$displaypath': rebased into '\$sha1'")"
>                                 must_die_on_failure=yes
> +                               if test -n "$attach_module" -a -n 
> "$head_detached" && test "$subsha1" != "$sha1"
> +                               then
> +                                       # After the rebase, we merge orphaned 
> commits in the branch
> +                                       command_post="git merge"
> +                                       suffix_post=$subsha1
> +                               fi
>                                 ;;
>                         merge)
> +                               if test -n "$attach_module" -a -n 
> "$head_detached" && test "$subsha1" != "$sha1"
> +                               then
> +                                       # Prior the rebase, we merge orphaned 
> commits in in the branch
> +                                       command_pre="git merge"
> +                                       suffix_pre=$subsha1
> +                               fi
>                                 command="git merge"
> +                               suffix=$sha1
>                                 die_msg="$(eval_gettext "Unable to merge 
> '\$sha1' in submodule path '\$displaypath'")"
>                                 say_msg="$(eval_gettext "Submodule path 
> '\$displaypath': merged in '\$sha1'")"
>                                 must_die_on_failure=yes
>                                 ;;
> +                       checkout)
> +                               if test -n "$attach_module"
> +                               then
> +                                       command="git checkout $subforce -q"
> +                                       suffix=$branch
> +                                       die_msg="$(eval_gettext "Unable to 
> checkout banch '\$branch' in submodule path '\$displaypath'")"
> +                                       say_msg="$(eval_gettext "Submodule 
> path '\$displaypath': checked out branch '\$branch'")"
> +                                       if test -z "$just_cloned" -a && test 
> "$subsha1" != "$sha1"
> +                                       then
> +                                               # Perform a fast-forward only 
> merge of the origin
> +                                               command_post="git merge 
> $subforce --ff-only"
> +                                               suffix_post="origin/$branch"
> +                                       fi
> +                               else
> +                                       command="git checkout $subforce -q"
> +                                       suffix=$sha1
> +                                       die_msg="$(eval_gettext "Unable to 
> checkout '\$sha1' in submodule path '\$displaypath'")"
> +                                       say_msg="$(eval_gettext "Submodule 
> path '\$displaypath': checked out '\$sha1'")"
> +                               fi
> +                               ;;
>                         !*)
>                                 command="${update_module#!}"
> +                               suffix=$sha1
>                                 die_msg="$(eval_gettext "Execution of 
> '\$command \$sha1' failed in submodule  path '\$prefix\$sm_path'")"
>                                 say_msg="$(eval_gettext "Submodule path 
> '\$prefix\$sm_path': '\$command \$sha1'")"
>                                 must_die_on_failure=yes
> +                               custom_update=yes
>                                 ;;
>                         *)
> -                               command="git checkout $subforce -q"
> -                               die_msg="$(eval_gettext "Unable to checkout 
> '\$sha1' in submodule path '\$displaypath'")"
> -                               say_msg="$(eval_gettext "Submodule path 
> '\$displaypath': checked out '\$sha1'")"
> +                               # Valid user configurable update modes are 
> already filtered above
> +                               die "$(eval_gettext "Unexpected update mode 
> in the current flow")"
>                                 ;;
>                         esac
>
> -                       if (clear_local_git_env; cd "$sm_path" && $command 
> "$sha1")
> +                       if (clear_local_git_env; cd "$sm_path" && 
> $command_attach "$suffix_attach" &&
> +                               $command_pre "$suffix_pre" && $command 
> "$suffix" && $command_post "$suffix_pro")
>                         then
>                                 say "$say_msg"
>                         elif test -n "$must_die_on_failure"
> diff --git a/t/t7410-submodule-attached-head.sh 
> b/t/t7410-submodule-attached-head.sh
> new file mode 100755
> index 0000000..04b3018
> --- /dev/null
> +++ b/t/t7410-submodule-attached-head.sh
> @@ -0,0 +1,268 @@
> +#!/bin/sh
> +#
> +# Copyright (c) 2014 Francesco Pretto
> +#
> +
> +test_description='Support for submodules with attached head
> +
> +This test verifies the sanity of the add and update git submodule commands 
> with
> +or without the --attached-update, --attach, --detach switches or the
> +submoudule.<module>.attach property set
> +'
> +
> +TEST_NO_CREATE_REPO=true
> +. ./test-lib.sh
> +
> +submodurl1=$(pwd -P)/repo1
> +submodurl2=$(pwd -P)/repo2
> +repourl=$(pwd -P)/repo
> +
> +test_expect_success 'setup - create repository "repo1" to be used as 
> submodule' '
> +       mkdir repo1 &&
> +       (
> +               cd repo1 &&
> +               git init &&
> +               git config receive.denyCurrentBranch ignore &&
> +               echo a >a &&
> +               git add a &&
> +               git commit -m "repo1 commit 1"
> +       )
> +'
> +
> +test_expect_success 'setup - reate repository "repo2" to be used as 
> submodule' '
> +       mkdir repo2 &&
> +       (
> +               cd repo2 &&
> +               git init &&
> +               git config receive.denyCurrentBranch ignore &&
> +               echo a >a &&
> +               git add a &&
> +               git commit -m "repo2 commit 1"
> +       )
> +'
> +
> +test_expect_success 'setup - create repository "repo" to be added with 
> sumodules' '
> +       mkdir repo &&
> +       (
> +               cd repo &&
> +               git init &&
> +               git config receive.denyCurrentBranch ignore &&
> +               echo a >a &&
> +               git add a &&
> +               git commit -m "repo commit 1"
> +       )
> +'
> +
> +test_expect_success 'setup - clone repository "repo" in "repoclone"' '
> +       git clone "$repourl" repoclone
> +'
> +
> +test_expect_success 'setup - add "mod1" as regular submodule of "repo"' '
> +       (
> +               cd repo &&
> +               git submodule add "$submodurl1" submod1
> +       )
> +'
> +
> +test_expect_success 'setup - add "mod2" as update attached HEAD submodule of 
> "repo"' '
> +       (
> +               cd repo &&
> +               git submodule add --attached-update "$submodurl2" submod2
> +       )
> +'
> +
> +test_expect_success 'setup - commit submodules in repo' '
> +       (
> +               cd repo &&
> +               git add . &&
> +               git commit -m "Added submodules"
> +       )
> +'
> +
> +test_expect_success 'init submodules in cloned repo' '
> +       (
> +               cd repoclone &&
> +               git pull &&
> +               git submodule init
> +       )
> +'
> +
> +test_expect_success 'update submodules in cloned repo' '
> +       (
> +               cd repoclone &&
> +               git submodule update
> +       )
> +'
> +
> +test_expect_success 'assert submod1 HEAD is detached in cloned repo' '
> +       (
> +               cd repoclone/submod1 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" = "HEAD"
> +       )
> +'
> +
> +test_expect_success 'assert submod2 HEAD is attached in cloned repo' '
> +       (
> +               cd repoclone/submod2 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" != "HEAD"
> +       )
> +'
> +
> +test_expect_success 'update submodules with --attach in cloned repo' '
> +       (
> +               cd repoclone &&
> +               git submodule update --attach
> +       )
> +'
> +
> +test_expect_success 'assert submod1 HEAD is attached in cloned repo' '
> +       (
> +               cd repoclone/submod1 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" != "HEAD"
> +       )
> +'
> +
> +test_expect_success 'update submodules with --detach in cloned repo' '
> +       (
> +               cd repoclone &&
> +               git submodule update --detach
> +       )
> +'
> +
> +test_expect_success 'assert submod1 HEAD is detached in cloned repo' '
> +       (
> +               cd repoclone/submod1 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" = "HEAD"
> +       )
> +'
> +
> +test_expect_success 'assert submod2 HEAD is detached in cloned repo' '
> +       (
> +               cd repoclone/submod2 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" = "HEAD"
> +       )
> +'
> +
> +test_expect_success 'update submodules in cloned repo (will restore HEAD 
> states)' '
> +       (
> +               cd repoclone &&
> +               git submodule update
> +       )
> +'
> +
> +test_expect_success 'assert submod1 HEAD is detached in cloned repo' '
> +       (
> +               cd repoclone/submod1 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" = "HEAD"
> +       )
> +'
> +
> +test_expect_success 'assert submod2 HEAD is attached in cloned repo' '
> +       (
> +               cd repoclone/submod2 &&
> +               test "$(git rev-parse --abbrev-ref HEAD)" != "HEAD"
> +       )
> +'
> +
> +test_expect_success 'setup - add update operation to submodules' '
> +       (
> +               cd repo &&
> +               git config  -f .gitmodules submodule.submod1.update merge &&
> +               git config  -f .gitmodules submodule.submod2.update rebase &&
> +               git add . &&
> +               git commit -m "updated submodules"
> +       )
> +'
> +
> +test_expect_success 'setup - update cloned repo and reinitialize submodules' 
> '
> +       (
> +               cd repoclone &&
> +               git pull &&
> +               git submodule init
> +       )
> +'
> +
> +test_expect_success 'add some content to repo2' '
> +       (
> +               cd repo2 &&
> +               echo b >b &&
> +               git add b &&
> +               git commit -m "repo2 commit 2"
> +       )
> +'
> +
> +test_expect_success 'update sumodules in cloned repo and verify that submod2 
> matches repo2' '
> +       (
> +               cd repoclone &&
> +               git submodule update &&
> +               test -e submod2/b
> +       )
> +'
> +
> +test_expect_success 'prepend some content to repo1/a' '
> +       (
> +               cd repo1 &&
> +               echo -e "b\na" >a &&
> +               git add a &&
> +               git commit -m "repo1 commit 2"
> +       )
> +'
> +
> +test_expect_success 'append some content in repoclone/submod1 and commit' '
> +       (
> +               cd repoclone/submod1 &&
> +               echo c >>a &&
> +               git add a &&
> +               git commit -m "submod1 commit 1"
> +       )
> +'
> +
> +test_expect_success 'update repoclone submodules with --attach' '
> +       (
> +               cd repoclone &&
> +               git submodule update --attach
> +       )
> +'
> +
> +test_expect_success 'verify repoclone submod1 merge with reattached orphaned 
> commits was correct' '
> +       (
> +               cd repoclone/submod1 &&
> +               test "$(<a)" = "$'b\na\nc'"
> +       )
> +'
> +
> +test_expect_success 'setup - set operation checkout to submodule sumod1 in 
> repo' '
> +       (
> +               cd repo &&
> +               git config  -f .gitmodules submodule.submod1.update checkout 
> &&
> +               git add . &&
> +               git commit -m "updated submodules"
> +       )
> +'
> +
> +test_expect_success 'setup - update cloned repo and reinitialize submodules' 
> '
> +       (
> +               cd repoclone &&
> +               git pull &&
> +               git submodule init
> +       )
> +'
> +
> +test_expect_success 'add some content to repo1' '
> +       (
> +               cd repo1 &&
> +               echo b >b &&
> +               git add b &&
> +               git commit -m "repo1 commit 3"
> +       )
> +'
> +
> +test_expect_success 'update submodule submod2 (merge ff-only) and verify it 
> matches repo2' '
> +       (
> +               cd repoclone &&
> +               git submodule update &&
> +               test -e submod2/b
> +       )
> +'
> +
> +test_done
> --
> 1.8.5.2.230.g032cd47.dirty
>
--
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