{"thread":{"id":"35584","subject":"[PATCH/RFC] Introduce git submodule add|update --attach","startedAt":"2013-12-30T01:49:44Z","lastAt":"2014-01-27T01:59:59Z","messageCount":102,"participants":["Francesco Pretto","Phil Hord","Junio C Hamano","W. Trevor King","Heiko Voigt","Jens Lehmann","John Keeping","Philip Oakley","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"232503","messageId":"1388368184-18418-1-git-send-email-ceztko@gmail.com","threadId":"35584","inReplyTo":null,"subject":"[PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2013-12-30T01:49:44Z","receivedAt":"2013-12-30T01:49:44Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"Hello everybody,\n\nby default \"git submodule\" performs its add or update operations on a detached\nHEAD. This works well when using an existing full-fledged/indipendent project as\nthe submodule, as there's less frequent need to update it or commit back\nchanges. When the submodule is actually a large portion of shareable code\nbetween  different projects, and the superproject needs to track very closely\nthe evolution of the submodule (or the other way around), I feel more confortable\nto reattach the HEAD of the submodule with an existing branch. This can be as\nsimple as having a superproject \"project1\" in branch \"master\" with a submodule\n\"common\" attached to the branch \"master-project1\" or, in a more development\nworkflow, \"project1\" in branch \"featureA\" with the same submodule \"common\"\nattached to a similarly named branch \"featureA\". Doing this in git requires me\nthe following:\n\n# Maintainer\n$ git submodule add --branch \"master-project1\" <repository> common\n$ git commit -m \"Added submodule\"\n$ git config -f .gitmodules submodule.common.ignore all\n$ git push\n$ cd <path>\n$ git checkout \"master-project1\"\n\n# Developer\n$ git pull\n$ git submodule init\n$ git submodule update --remote\n$ cd <path>\n$ branch=\"$(git config -f ..\\.gitmodules submodule.common.branch)\"; git checkout $branch\n\nWhile the burden for the repository maitainer/administrator is acceptable, in\nthe developer point of view there are two problems:\n1) Checking out an attached HEAD of a specified branch as when using \"--remote\"\nis not really simple as it could be and could require lauching of scrips or\nreading some repository specific documentation. Also in Windows platform the\nsyntax for inline shell evaluation of commands is less known between users;\n2) There's no way to store a similar default behaviour in the repository except\nby using scripts. Also recently submodule.<modulename>.update custom !commands\nin no more supported when stored in .gitmodules [1].\n\nThe attached patch tries to solve these problems by introducing an \"--attach\"\nswitch to the \"add\" and \"update\" submodule commands and a \"--detach\" switch just\nfor the \"update\" command. It also add the support for an 'submodule.<name>.attach'\nproperty when updating. Using the \"--attach\" switch when adding a submodule does:\n- create the submodule checking out an attached HEAD;\n- set the 'submodule.<name>.attach' property to 'true';\n- set the 'submodule.<name>.ignore' property to 'all' (this is useful as\nattaching to the branch doesn't require tracking of revision sha1).\n\nThe rationale of setting 'attach' and 'ignore' properties when adding a\nsubmodule with the \"--attach\" switch is to give a convenient default behaviour.\nNo other properties are set: the repository responsible will still be required\nto configure a different 'submodule.<name>.update' behaviour separetely, if he\nwants that.\n\nWhen updating, using the '--attach' switch or operating in a repository with\n'submodule.<name>.attach' set to 'true' will:\n- checkout a branch with an attached HEAD if the repository was just cloned;\n- perform a fast-forward only merge of changes if it's a 'checkout' update,\nkeeping the HEAD attached;\n- reattach the HEAD prior performing a 'merge', 'rebase' or '!command' update\noperation if the HEAD was found detached.\n\n'--attach' or 'submodule.<name>.attach' set to true also implies '--remote', as\nit's needed the origin HEAD sha1 to verify the current HEAD state.\n\nA '--detach' switch is also available. Using the '--detach' switch or\noperating in a repository with 'submodule.<name>.attach' set to 'false' during\nupdate will:\n- checkout a detached HEAD if the repository was just cloned (same behaviour as\nbefore);\n- detach the HEAD prior performing a 'merge', 'rebase' or '!command' update\noperation if the HEAD was found attached.\n\n'submodule.<name>.attach' works the same way as 'submodule.<name>.update'\nproperty: git copies the values found in \".gitmodules\" in \".git/config\" when\nperforming an \"init\" command. \"update\" looks for the values in \".git/config\"\nonly.\n\n'--attach' and '--detach' switches override an opposite behaviour of 'submodule.<name>.attach'\nproperties.\n\nThe patch is small (touches only git-submodule.sh) and 100% additive with\nrespect to currently documented behaviour: when using \"add\" and \"update\"\ncommands without the introduced switches and properties, git shall operate as\nbefore. As a bonus (but this was done to ease conditionals and keep the code\nclean) it also clarifies and validates the content of 'submodule.<name>.update'\nduring 'update' command, warning the user if it's not one of the supported\nvalues 'checkout', 'merge', 'rebase' and 'none'. Please note that 'checkout'\nupdate command was documented in upstream \"Documentation/gitmodules.txt\" [2] as\na valid 'submodule.<name>.update' value and code in upstream \"git-submodule.sh\"\nimplicitly assumes it as recognized value. \"Documentation/git-submodule.txt\"\ndoesn't mention it properly and I guess this is the reason why it wasn't\nconsidered for the validation in [1] patch.\n\nUsing this patch, the previous workflow becomes:\n\n# Maintainer\n$ git submodule add --branch \"master-project1\" --attach <repository> <path>\n$ git commit -m \"Added submodule\"\n$ git push\n\n# Developer\n$ git pull\n$ git submodule init\n$ git submodule update\n\nIs there interest in supporting this workflow and seeing this patch applied?\n\nThanks,\nFrancesco\n\n[1] http://marc.info/?l=git&m=138610752125816&w=2\n[2] Documentation/gitmodules.txt: \"If 'checkout' (the default)...\"\n\nSigned-off-by: Francesco Pretto <ceztko@gmail.com>\n---\n Documentation/git-submodule.txt |  37 ++++++---\n Documentation/gitmodules.txt    |  11 ++-\n git-submodule.sh                | 172 +++++++++++++++++++++++++++++++++++++---\n 3 files changed, 197 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex bfef8a0..452376d 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -10,13 +10,14 @@ SYNOPSIS\n --------\n [verse]\n 'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>]\n-\t      [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]\n+\t      [--reference <repository>] [--attach] [--depth <depth>]\n+\t      [--] <repository> [<path>]\n 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]\n 'git submodule' [--quiet] init [--] [<path>...]\n 'git submodule' [--quiet] deinit [-f|--force] [--] <path>...\n 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]\n-\t      [-f|--force] [--rebase] [--reference <repository>] [--depth <depth>]\n-\t      [--merge] [--recursive] [--] [<path>...]\n+\t      [-f|--force] [--rebase] [--reference <repository>] [--attach | --detach]\n+\t      [--depth <depth>] [--merge] [--recursive] [--] [<path>...]\n 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]\n \t      [commit] [--] [<path>...]\n 'git submodule' [--quiet] foreach [--recursive] <command>\n@@ -107,6 +108,10 @@ is the superproject and submodule repositories will be kept\n together in the same relative location, and only the\n superproject's URL needs to be provided: git-submodule will correctly\n locate the submodule using the relative URL in .gitmodules.\n++\n+If `--attach` is specified, the submodule will be registered to be\n+checked out with an an attached HEAD. Also `submodule.<name>.attach` will\n+be set to `true` and `submodule.<name>.ignore` will be set to `all`.\n \n status::\n \tShow the status of the submodules. This will print the SHA-1 of the\n@@ -156,12 +161,15 @@ it contains local modifications.\n update::\n \tUpdate the registered submodules, i.e. clone missing submodules and\n \tcheckout the commit specified in the index of the containing repository.\n-\tThis will make the submodules HEAD be detached unless `--rebase` or\n-\t`--merge` is specified or the key `submodule.$name.update` is set to\n-\t`rebase`, `merge` or `none`. `none` can be overridden by specifying\n-\t`--checkout`. Setting the key `submodule.$name.update` to `!command`\n-\twill cause `command` to be run. `command` can be any arbitrary shell\n-\tcommand that takes a single argument, namely the sha1 to update to.\n+\tThis will make the submodules HEAD be detached unless `--attach` is\n+\tspecified or `submodule.$name.attach` is set to `true`. The last setting\n+\tcan always be overridden specifying `--detach`. Update mode can be\n+\tselected specifying `--checkout`, `--rebase` or `--merge` switches\n+\tor setting the key `submodule.$name.update` to `checkout`, `rebase`,\n+\t`merge` or `none`. `none` will cause the submodule to be skipped during\n+\tthe update. Setting the key `submodule.$name.update` to `!command` will\n+\tcause `command` to be run. `command` can be any arbitrary shell command\n+\tthat takes a single argument, namely the sha1 to update to.\n +\n If the submodule is not yet initialized, and you just want to use the\n setting as stored in .gitmodules, you can automatically initialize the\n@@ -270,6 +278,17 @@ OPTIONS\n \tbe overridden by setting the `submodule.<name>.branch` option in\n \teither `.gitmodules` or `.git/config` (with `.git/config` taking\n \tprecedence).\n+\n+--attach::\n+\tThis option is only valid for the add and update commands. Cause the\n+\tresult of an add or update operation to be an attached HEAD. In the\n+\tupdate command , if `submodule.<name>.branch` is not set, it will\n+\tdefault to `master`. Note: for the update command `--attach` also\n+\timplies `--remote`.\n+\n+--detach::\n+\tThis option is only valid for the update command. Cause the result\n+\tof the update operation to be forcedly a detached HEAD.\n +\n This works for any of the supported update procedures (`--checkout`,\n `--rebase`, etc.).  The only change is the source of the target SHA-1.\ndiff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\nindex f7be93f..e6c3360 100644\n--- a/Documentation/gitmodules.txt\n+++ b/Documentation/gitmodules.txt\n@@ -37,8 +37,10 @@ submodule.<name>.url::\n \n submodule.<name>.update::\n \tDefines what to do when the submodule is updated by the superproject.\n-\tIf 'checkout' (the default), the new commit specified in the\n-\tsuperproject will be checked out in the submodule on a detached HEAD.\n+\tIf 'checkout' (the default), the new commit (or the branch, when using\n+\tthe '--attach' switch or the 'submodule.<name>.attach' property is set\n+\tto 'true' during an update operation) specified in the superproject will\n+\tbe checked out in the submodule.\n \tIf 'rebase', the current branch of the submodule will be rebased onto\n \tthe commit specified in the superproject. If 'merge', the commit\n \tspecified in the superproject will be merged into the current branch\n@@ -54,6 +56,11 @@ submodule.<name>.branch::\n \tIf the option is not specified, it defaults to 'master'.  See the\n \t`--remote` documentation in linkgit:git-submodule[1] for details.\n \n+submodule.<name>.attach::\n+\tDetermine if the update operation will produce a detached HEAD or not.\n+\tValid values are `true` or `false`. If the property is set to `true`\n+\tand `submodule.<name>.branch`, it will default to `master`\n+\n submodule.<name>.fetchRecurseSubmodules::\n \tThis option can be used to control recursive fetching of this\n \tsubmodule. If this option is also present in the submodules entry in\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 2677f2e..3951fa2 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -5,11 +5,11 @@\n # Copyright (c) 2007 Lars Hjemli\n \n dashless=$(basename \"$0\" | sed -e 's/-/ /')\n-USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]\n+USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--attach] [--] <repository> [<path>]\n    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]\n    or: $dashless [--quiet] init [--] [<path>...]\n    or: $dashless [--quiet] deinit [-f|--force] [--] <path>...\n-   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]\n+   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--attach | --detach] [--merge] [--recursive] [--] [<path>...]\n    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]\n    or: $dashless [--quiet] foreach [--recursive] <command>\n    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]\"\n@@ -36,6 +36,7 @@ update=\n prefix=\n custom_name=\n depth=\n+attach=\n \n # The function takes at most 2 arguments. The first argument is the\n # URL that navigates to the submodule origin repo. When relative, this URL\n@@ -352,6 +353,9 @@ cmd_add()\n \t\t\tcustom_name=$2\n \t\t\tshift\n \t\t\t;;\n+\t\t--attach)\n+\t\t\tattach=\"true\"\n+\t\t\t;;\n \t\t--depth)\n \t\t\tcase \"$2\" in '') usage ;; esac\n \t\t\tdepth=\"--depth=$2\"\n@@ -475,8 +479,17 @@ Use -f if you really want to add it.\" >&2\n \t\t\tcd \"$sm_path\" &&\n \t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n \t\t\tcase \"$branch\" in\n-\t\t\t'') git checkout -f -q ;;\n-\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n+\t\t\t'')\n+\t\t\t\tgit checkout -f -q\n+\t\t\t\t;;\n+\t\t\t?*)\n+\t\t\t\tif test -n \"$attach\"\n+\t\t\t\tthen\n+\t\t\t\t\tgit checkout -f -q \"$branch\"\n+\t\t\t\telse\n+\t\t\t\t\tgit checkout -f -q -B \"$branch\" \"origin/$branch\"\n+\t\t\t\tfi\n+\t\t\t\t;;\n \t\t\tesac\n \t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n \tfi\n@@ -491,6 +504,12 @@ Use -f if you really want to add it.\" >&2\n \tthen\n \t\tgit config -f .gitmodules submodule.\"$sm_name\".branch \"$branch\"\n \tfi &&\n+\tif test -n \"$attach\"\n+\tthen\n+\t\t# We'll stay stick to the HEAD, no need to track revision sha1\n+\t\tgit config -f .gitmodules submodule.\"$sm_name\".attach \"true\"\n+\t\tgit config -f .gitmodules submodule.\"$sm_name\".ignore \"all\"\n+\tfi &&\n \tgit add --force .gitmodules ||\n \tdie \"$(eval_gettext \"Failed to register submodule '\\$sm_path'\")\"\n }\n@@ -622,7 +641,7 @@ cmd_init()\n \t\t   test -z \"$(git config submodule.\"$name\".update)\"\n \t\tthen\n \t\t\tcase \"$upd\" in\n-\t\t\trebase | merge | none)\n+\t\t\tcheckout | rebase | merge | none)\n \t\t\t\t;; # known modes of updating\n \t\t\t*)\n \t\t\t\techo >&2 \"warning: unknown update mode '$upd' suggested for submodule '$name'\"\n@@ -632,6 +651,23 @@ cmd_init()\n \t\t\tgit config submodule.\"$name\".update \"$upd\" ||\n \t\t\tdie \"$(eval_gettext \"Failed to register update mode for submodule path '\\$displaypath'\")\"\n \t\tfi\n+\n+\t\t# Copy \"attach\" setting when it is not set yet\n+\t\tif attached=\"$(git config -f .gitmodules submodule.\"$name\".attach)\" &&\n+\t\t   test -n \"$attached\" &&\n+\t\t   test -z \"$(git config submodule.\"$name\".attach)\"\n+\t\tthen\n+\t\t\tcase \"$attached\" in\n+\t\t\ttrue | false)\n+\t\t\t\t;; # Valid attach flag values\n+\t\t\t*)\n+\t\t\t\techo >&2 \"warning: invalid attach flag value for submodule '$name'\"\n+\t\t\t\tupd=none\n+\t\t\t\t;;\n+\t\t\tesac\n+\t\t\tgit config submodule.\"$name\".attach \"$attached\" ||\n+\t\t\tdie \"$(eval_gettext \"Failed to register attached option for submodule path '\\$displaypath'\")\"\n+\t\tfi\n \tdone\n }\n \n@@ -750,6 +786,14 @@ cmd_update()\n \t\t--reference=*)\n \t\t\treference=\"$1\"\n \t\t\t;;\n+\t\t--attach)\n+\t\t\tif test \"$attach\" = \"false\" ; then usage ; fi\n+\t\t\tattach=\"true\"\n+\t\t\t;;\n+\t\t--detach)\n+\t\t\tif test \"$attach\" = \"true\" ; then usage ; fi\n+\t\t\tattach=\"false\"\n+\t\t\t;;\n \t\t-m|--merge)\n \t\t\tupdate=\"merge\"\n \t\t\t;;\n@@ -800,11 +844,44 @@ cmd_update()\n \t\tname=$(module_name \"$sm_path\") || exit\n \t\turl=$(git config submodule.\"$name\".url)\n \t\tbranch=$(get_submodule_config \"$name\" branch master)\n+\t\tif test -n \"$attach\"\n+\t\tthen\n+\t\t\tattach_module=$attach\n+\t\telse\n+\t\t\tattach_module=$(git config submodule.\"$name\".attach)\n+\t\t\tcase \"$attach_module\" in\n+\t\t\t'')\n+\t\t\t\t;; # Unset attach flag\n+\t\t\ttrue|false)\n+\t\t\t\t;; # Valid attach flag values\n+\t\t\t*)\n+\t\t\t\techo >&2 \"warning: invalid attach flag value for submodule '$name'\"\n+\t\t\t\tattach_module=\n+\t\t\t\t;;\n+\t\t\tesac\n+\t\tfi\n+\t\tif test \"$attach_module\" = \"false\"\n+\t\tthen\n+\t\t\t# Normalize attach 'false' flag value\n+\t\t\tattach_module=\n+\t\tfi\n \t\tif ! test -z \"$update\"\n \t\tthen\n \t\t\tupdate_module=$update\n \t\telse\n \t\t\tupdate_module=$(git config submodule.\"$name\".update)\n+\t\t\tcase \"$update_module\" in\n+\t\t\t'')\n+\t\t\t\t;; # Unset update mode\n+\t\t\tcheckout | rebase | merge | none)\n+\t\t\t\t;; # Known update modes\n+\t\t\t!*)\n+\t\t\t\t;; # Custom update command\n+\t\t\t*)\n+\t\t\t\tupdate_module=\n+\t\t\t\techo >&2 \"warning: invalid update mode for submodule '$name'\"\n+\t\t\t\t;;\n+\t\t\tesac\n \t\tfi\n \n \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n@@ -836,7 +913,7 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tdie \"$(eval_gettext \"Unable to find current revision in submodule path '\\$displaypath'\")\"\n \t\tfi\n \n-\t\tif test -n \"$remote\"\n+\t\tif test -n \"$remote\" -o -n \"$attach_module\"\n \t\tthen\n \t\t\tif test -z \"$nofetch\"\n \t\t\tthen\n@@ -850,7 +927,16 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tdie \"$(eval_gettext \"Unable to find current ${remote_name}/${branch} revision in submodule path '\\$sm_path'\")\"\n \t\tfi\n \n-\t\tif test \"$subsha1\" != \"$sha1\" -o -n \"$force\"\n+\t\thead_rev_ref=$(clear_local_git_env; cd \"$sm_path\" && git rev-parse --abbrev-ref HEAD) ||\n+\t\tdie \"$(eval_gettext \"Unable to determine revision ref in submodule path '\\$sm_path'\")\"\n+\t\tif test \"$head_rev_ref\" = \"HEAD\"\n+\t\tthen\n+\t\t\t# Determine if the HEAD is detached\n+\t\t\thead_detached=\"true\"\n+\t\tfi\n+\n+\t\tif test \"$subsha1\" != \"$sha1\" || test -n \"$attach_module\" -a -n \"$head_detached\" ||\n+\t\t\ttest -z \"$attach_module\" -a -z \"$head_detached\" || test -n \"$force\"\n \t\tthen\n \t\t\tsubforce=$force\n \t\t\t# If we don't already have a -f flag and the submodule has never been checked out\n@@ -870,40 +956,102 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tfi\n \n \t\t\t# Is this something we just cloned?\n+\t\t\tjust_cloned=\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module= ;;\n+\t\t\t\tupdate_module=\"checkout\"\n+\t\t\t\tjust_cloned=yes\n+\t\t\t\t;;\n \t\t\tesac\n \n+\t\t\tif test -z \"$update_module\"\n+\t\t\tthen\n+\t\t\t\t# Fallback to checkout\n+\t\t\t\tupdate_module=\"checkout\"\n+\t\t\tfi\n+\t\t\t\n+\t\t\tcommand_pre=:\n+\t\t\tsuffix_pre=\n+\t\t\tif test \"$update_module\" = \"checkout\"\n+\t\t\tthen\n+\t\t\t\tif test -n \"$attach_module\" -a -z \"$just_cloned\"\n+\t\t\t\tthen\n+\t\t\t\t\t# We need to attach to the HEAD/switch the branch prior\n+\t\t\t\t\t# performing any fast-forward update\n+\t\t\t\t\tcommand_pre=\"git checkout $subforce -q\"\n+\t\t\t\t\tsuffix_pre=$branch\n+\t\t\t\tfi\n+\t\t\telse\n+\t\t\t\tif test -n \"$attach_module\" -a -n \"$head_detached\"\n+\t\t\t\tthen\n+\t\t\t\t\t# We need to reattach to the head\n+\t\t\t\t\tcommand_pre=\"git checkout $subforce -q\"\n+\t\t\t\t\tsuffix_pre=$branch\n+\t\t\t\telif test -z \"$attach_module\" -a -z \"$head_detached\"\n+\t\t\t\tthen\n+\t\t\t\t\t# We need to detach from the head\n+\t\t\t\t\tcommand_pre=\"git checkout $subforce -q\"\n+\t\t\t\t\tsuffix_pre=$sha1\n+\t\t\t\tfi\n+\t\t\tfi\n+\n \t\t\tmust_die_on_failure=\n+\t\t\tcustom_update=\n+\t\t\tsuffix=\n \t\t\tcase \"$update_module\" in\n \t\t\trebase)\n \t\t\t\tcommand=\"git rebase\"\n+\t\t\t\tsuffix=$sha1\n \t\t\t\tdie_msg=\"$(eval_gettext \"Unable to rebase '\\$sha1' in submodule path '\\$displaypath'\")\"\n \t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': rebased into '\\$sha1'\")\"\n \t\t\t\tmust_die_on_failure=yes\n \t\t\t\t;;\n \t\t\tmerge)\n \t\t\t\tcommand=\"git merge\"\n+\t\t\t\tsuffix=$sha1\n \t\t\t\tdie_msg=\"$(eval_gettext \"Unable to merge '\\$sha1' in submodule path '\\$displaypath'\")\"\n \t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': merged in '\\$sha1'\")\"\n \t\t\t\tmust_die_on_failure=yes\n \t\t\t\t;;\n+\t\t\tcheckout)\n+\t\t\t\tif test -n \"$attach_module\"\n+\t\t\t\tthen\n+\t\t\t\t\tif test -n \"$just_cloned\"\n+\t\t\t\t\tthen\n+\t\t\t\t\t\tcommand=\"git checkout $subforce -q\"\n+\t\t\t\t\t\tsuffix=$branch\n+\t\t\t\t\telse\n+\t\t\t\t\t\t# Perform a fast-forward only merge of the origin\n+\t\t\t\t\t\tcommand=\"git merge $subforce --ff-only\"\n+\t\t\t\t\t\tsuffix=\"origin/$branch\"\n+\t\t\t\t\tfi\n+\t\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout banch '\\$branch' in submodule path '\\$displaypath'\")\"\n+\t\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out branch '\\$branch'\")\"\n+\t\t\t\telse\n+\t\t\t\t\tcommand=\"git checkout $subforce -q\"\n+\t\t\t\t\tsuffix=$sha1\n+\t\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n+\t\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n+\t\t\t\tfi\n+\t\t\t\t;;\n \t\t\t!*)\n \t\t\t\tcommand=\"${update_module#!}\"\n+\t\t\t\tsuffix=$sha1\n \t\t\t\tdie_msg=\"$(eval_gettext \"Execution of '\\$command \\$sha1' failed in submodule  path '\\$prefix\\$sm_path'\")\"\n \t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$prefix\\$sm_path': '\\$command \\$sha1'\")\"\n \t\t\t\tmust_die_on_failure=yes\n+\t\t\t\tcustom_update=yes\n \t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tcommand=\"git checkout $subforce -q\"\n-\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n-\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n+\t\t\t\t# Valid user configurable update modes are already filtered above\n+\t\t\t\tdie \"$(eval_gettext \"Unexpected update mode in the current flow\")\"\n \t\t\t\t;;\n \t\t\tesac\n \n-\t\t\tif (clear_local_git_env; cd \"$sm_path\" && $command \"$sha1\")\n+\t\t\tif (clear_local_git_env; cd \"$sm_path\" &&\n+\t\t\t\t$command_pre \"$suffix_pre\" &&\n+\t\t\t\t$command \"$suffix\")\n \t\t\tthen\n \t\t\t\tsay \"$say_msg\"\n \t\t\telif test -n \"$must_die_on_failure\"\n-- \n1.8.5.2.227.g53f3478.dirty\n"},{"id":"232547","messageId":"CABURp0pQHw7qvG_tq8oK=6DBOUoYy=Rb5othV+zBpNonuv=PLw@mail.gmail.com","threadId":"35584","inReplyTo":"1388368184-18418-1-git-send-email-ceztko@gmail.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2013-12-31T20:05:54Z","receivedAt":"2013-12-31T20:05:54Z","isPatch":true,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Sun, Dec 29, 2013 at 8:49 PM, Francesco Pretto <ceztko@gmail.com> wrote:\n>\n> by default \"git submodule\" performs its add or update operations on a detached\n> HEAD. This works well when using an existing full-fledged/indipendent project as\n> the submodule, as there's less frequent need to update it or commit back\n> changes. When the submodule is actually a large portion of shareable code\n> between  different projects, and the superproject needs to track very closely\n> the evolution of the submodule (or the other way around), I feel more confortable\n> to reattach the HEAD of the submodule with an existing branch. This can be as\n> simple as having a superproject \"project1\" in branch \"master\" with a submodule\n> \"common\" attached to the branch \"master-project1\" or, in a more development\n> workflow, \"project1\" in branch \"featureA\" with the same submodule \"common\"\n> attached to a similarly named branch \"featureA\". Doing this in git requires me\n> the following:\n>\n> # Maintainer\n> $ git submodule add --branch \"master-project1\" <repository> common\n> $ git commit -m \"Added submodule\"\n> $ git config -f .gitmodules submodule.common.ignore all\n> $ git push\n> $ cd <path>\n> $ git checkout \"master-project1\"\n>\n> # Developer\n> $ git pull\n> $ git submodule init\n> $ git submodule update --remote\n> $ cd <path>\n> $ branch=\"$(git config -f ..\\.gitmodules submodule.common.branch)\"; git checkout $branch\n>\n> While the burden for the repository maitainer/administrator is acceptable, in\n> the developer point of view there are two problems:\n> 1) Checking out an attached HEAD of a specified branch as when using \"--remote\"\n> is not really simple as it could be and could require lauching of scrips or\n> reading some repository specific documentation. Also in Windows platform the\n> syntax for inline shell evaluation of commands is less known between users;\n> 2) There's no way to store a similar default behaviour in the repository except\n> by using scripts. Also recently submodule.<modulename>.update custom !commands\n> in no more supported when stored in .gitmodules [1].\n>\n> The attached patch tries to solve these problems by introducing an \"--attach\"\n> switch to the \"add\" and \"update\" submodule commands and a \"--detach\" switch just\n> for the \"update\" command. It also add the support for an 'submodule.<name>.attach'\n> property when updating. Using the \"--attach\" switch when adding a submodule does:\n> - create the submodule checking out an attached HEAD;\n> - set the 'submodule.<name>.attach' property to 'true';\n> - set the 'submodule.<name>.ignore' property to 'all' (this is useful as\n> attaching to the branch doesn't require tracking of revision sha1).\n>\n> The rationale of setting 'attach' and 'ignore' properties when adding a\n> submodule with the \"--attach\" switch is to give a convenient default behaviour.\n> No other properties are set: the repository responsible will still be required\n> to configure a different 'submodule.<name>.update' behaviour separetely, if he\n> wants that.\n>\n> When updating, using the '--attach' switch or operating in a repository with\n> 'submodule.<name>.attach' set to 'true' will:\n> - checkout a branch with an attached HEAD if the repository was just cloned;\n> - perform a fast-forward only merge of changes if it's a 'checkout' update,\n> keeping the HEAD attached;\n> - reattach the HEAD prior performing a 'merge', 'rebase' or '!command' update\n> operation if the HEAD was found detached.\n\nI need to understand this \"reattach the HEAD\" case better. Can you\ngive some examples of the expected behavior when merge, rebase or\n!command is encountered?\n\n\n> '--attach' or 'submodule.<name>.attach' set to true also implies '--remote', as\n> it's needed the origin HEAD sha1 to verify the current HEAD state.\n>\n> A '--detach' switch is also available. Using the '--detach' switch or\n> operating in a repository with 'submodule.<name>.attach' set to 'false' during\n> update will:\n> - checkout a detached HEAD if the repository was just cloned (same behaviour as\n> before);\n> - detach the HEAD prior performing a 'merge', 'rebase' or '!command' update\n> operation if the HEAD was found attached.\n>\n> 'submodule.<name>.attach' works the same way as 'submodule.<name>.update'\n> property: git copies the values found in \".gitmodules\" in \".git/config\" when\n> performing an \"init\" command. \"update\" looks for the values in \".git/config\"\n> only.\n>\n> '--attach' and '--detach' switches override an opposite behaviour of 'submodule.<name>.attach'\n> properties.\n>\n> The patch is small (touches only git-submodule.sh) and 100% additive with\n> respect to currently documented behaviour: when using \"add\" and \"update\"\n> commands without the introduced switches and properties, git shall operate as\n> before. As a bonus (but this was done to ease conditionals and keep the code\n> clean) it also clarifies and validates the content of 'submodule.<name>.update'\n> during 'update' command, warning the user if it's not one of the supported\n> values 'checkout', 'merge', 'rebase' and 'none'. Please note that 'checkout'\n> update command was documented in upstream \"Documentation/gitmodules.txt\" [2] as\n> a valid 'submodule.<name>.update' value and code in upstream \"git-submodule.sh\"\n> implicitly assumes it as recognized value. \"Documentation/git-submodule.txt\"\n> doesn't mention it properly and I guess this is the reason why it wasn't\n> considered for the validation in [1] patch.\n>\n> Using this patch, the previous workflow becomes:\n>\n> # Maintainer\n> $ git submodule add --branch \"master-project1\" --attach <repository> <path>\n> $ git commit -m \"Added submodule\"\n> $ git push\n>\n> # Developer\n> $ git pull\n> $ git submodule init\n> $ git submodule update\n>\n> Is there interest in supporting this workflow and seeing this patch applied?\n>\n> Thanks,\n> Francesco\n>\n> [1] http://marc.info/?l=git&m=138610752125816&w=2\n> [2] Documentation/gitmodules.txt: \"If 'checkout' (the default)...\"\n>\n> Signed-off-by: Francesco Pretto <ceztko@gmail.com>\n> ---\n>  Documentation/git-submodule.txt |  37 ++++++---\n>  Documentation/gitmodules.txt    |  11 ++-\n>  git-submodule.sh                | 172 +++++++++++++++++++++++++++++++++++++---\n>  3 files changed, 197 insertions(+), 23 deletions(-)\n>\n> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\n> index bfef8a0..452376d 100644\n> --- a/Documentation/git-submodule.txt\n> +++ b/Documentation/git-submodule.txt\n> @@ -10,13 +10,14 @@ SYNOPSIS\n>  --------\n>  [verse]\n>  'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>]\n> -             [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]\n> +             [--reference <repository>] [--attach] [--depth <depth>]\n> +             [--] <repository> [<path>]\n>  'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]\n>  'git submodule' [--quiet] init [--] [<path>...]\n>  'git submodule' [--quiet] deinit [-f|--force] [--] <path>...\n>  'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]\n> -             [-f|--force] [--rebase] [--reference <repository>] [--depth <depth>]\n> -             [--merge] [--recursive] [--] [<path>...]\n> +             [-f|--force] [--rebase] [--reference <repository>] [--attach | --detach]\n> +             [--depth <depth>] [--merge] [--recursive] [--] [<path>...]\n>  'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]\n>               [commit] [--] [<path>...]\n>  'git submodule' [--quiet] foreach [--recursive] <command>\n> @@ -107,6 +108,10 @@ is the superproject and submodule repositories will be kept\n>  together in the same relative location, and only the\n>  superproject's URL needs to be provided: git-submodule will correctly\n>  locate the submodule using the relative URL in .gitmodules.\n> ++\n> +If `--attach` is specified, the submodule will be registered to be\n> +checked out with an an attached HEAD. Also `submodule.<name>.attach` will\n> +be set to `true` and `submodule.<name>.ignore` will be set to `all`.\n>\n>  status::\n>         Show the status of the submodules. This will print the SHA-1 of the\n> @@ -156,12 +161,15 @@ it contains local modifications.\n>  update::\n>         Update the registered submodules, i.e. clone missing submodules and\n>         checkout the commit specified in the index of the containing repository.\n> -       This will make the submodules HEAD be detached unless `--rebase` or\n> -       `--merge` is specified or the key `submodule.$name.update` is set to\n> -       `rebase`, `merge` or `none`. `none` can be overridden by specifying\n> -       `--checkout`. Setting the key `submodule.$name.update` to `!command`\n> -       will cause `command` to be run. `command` can be any arbitrary shell\n> -       command that takes a single argument, namely the sha1 to update to.\n> +       This will make the submodules HEAD be detached unless `--attach` is\n> +       specified or `submodule.$name.attach` is set to `true`. The last setting\n> +       can always be overridden specifying `--detach`. Update mode can be\n> +       selected specifying `--checkout`, `--rebase` or `--merge` switches\n> +       or setting the key `submodule.$name.update` to `checkout`, `rebase`,\n> +       `merge` or `none`. `none` will cause the submodule to be skipped during\n> +       the update. Setting the key `submodule.$name.update` to `!command` will\n> +       cause `command` to be run. `command` can be any arbitrary shell command\n> +       that takes a single argument, namely the sha1 to update to.\n>  +\n>  If the submodule is not yet initialized, and you just want to use the\n>  setting as stored in .gitmodules, you can automatically initialize the\n> @@ -270,6 +278,17 @@ OPTIONS\n>         be overridden by setting the `submodule.<name>.branch` option in\n>         either `.gitmodules` or `.git/config` (with `.git/config` taking\n>         precedence).\n> +\n> +--attach::\n> +       This option is only valid for the add and update commands. Cause the\n\nGrammar: 'Causes the result'\n\n> +       result of an add or update operation to be an attached HEAD. In the\n> +       update command , if `submodule.<name>.branch` is not set, it will\n\ntypo: space before comma.\n\nAlso, the pronoun \"it\" here is unclear to me.  Does this convey the\ncorrect meaning?\n\n   In the update operation, the branch named by 'submodule.<name>.branch' is\n   checked out as the new HEAD of the submodule repository. If\n   'submodule.<name>.branch' is not set, the 'master' branch is\nchecked out as the\n   new HEAD of the submodule.\n\n> +       default to `master`. Note: for the update command `--attach` also\n> +       implies `--remote`.\n> +\n> +--detach::\n> +       This option is only valid for the update command. Cause the result\n\n Grammar: 'Causes the result'\n\n> +       of the update operation to be forcedly a detached HEAD.\n\n\"Forcedly\" is a bit strong, maybe, slightly misplaced, and not a word,\nbesides.   How's this, instead:\n\n   Forces the result of the update operation to be a detached HEAD in\nthe submodule.\n\n>  +\n>  This works for any of the supported update procedures (`--checkout`,\n>  `--rebase`, etc.).  The only change is the source of the target SHA-1.\n> diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\n> index f7be93f..e6c3360 100644\n> --- a/Documentation/gitmodules.txt\n> +++ b/Documentation/gitmodules.txt\n> @@ -37,8 +37,10 @@ submodule.<name>.url::\n>\n>  submodule.<name>.update::\n>         Defines what to do when the submodule is updated by the superproject.\n> -       If 'checkout' (the default), the new commit specified in the\n> -       superproject will be checked out in the submodule on a detached HEAD.\n> +       If 'checkout' (the default), the new commit (or the branch, when using\n> +       the '--attach' switch or the 'submodule.<name>.attach' property is set\n> +       to 'true' during an update operation) specified in the superproject will\n> +       be checked out in the submodule.\n\nIMHO, this wording is overcomplicated by this change.  How about:\n\n       If 'checkout' (the default), the new commit specified in the superproject\n       (or branch, with '--attach') will be checked out in the submodule.\n\n>         If 'rebase', the current branch of the submodule will be rebased onto\n>         the commit specified in the superproject. If 'merge', the commit\n>         specified in the superproject will be merged into the current branch\n\nDoes the 'merge', 'rebase' and '!command' description need to be\nupdated, too?  Here and above it seems to still suggest the old\nbehavior is kept when --attach is used.\n\n\n> @@ -54,6 +56,11 @@ submodule.<name>.branch::\n>         If the option is not specified, it defaults to 'master'.  See the\n>         `--remote` documentation in linkgit:git-submodule[1] for details.\n>\n> +submodule.<name>.attach::\n> +       Determine if the update operation will produce a detached HEAD or not.\n> +       Valid values are `true` or `false`. If the property is set to `true`\n> +       and `submodule.<name>.branch`, it will default to `master`\n\nI think you mean \"...and 'submodule.<name>.branch' is not set, it\nwill...\", right?\n\nSome explanation of what happens when it _is_ set would be useful\nhere, too, I think.  But maybe I do not understand the nuances yet.\n\n> +\n>  submodule.<name>.fetchRecurseSubmodules::\n>         This option can be used to control recursive fetching of this\n>         submodule. If this option is also present in the submodules entry in\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 2677f2e..3951fa2 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -5,11 +5,11 @@\n>  # Copyright (c) 2007 Lars Hjemli\n>\n>  dashless=$(basename \"$0\" | sed -e 's/-/ /')\n> -USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]\n> +USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--attach] [--] <repository> [<path>]\n>     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]\n>     or: $dashless [--quiet] init [--] [<path>...]\n>     or: $dashless [--quiet] deinit [-f|--force] [--] <path>...\n> -   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]\n> +   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--attach | --detach] [--merge] [--recursive] [--] [<path>...]\n>     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]\n>     or: $dashless [--quiet] foreach [--recursive] <command>\n>     or: $dashless [--quiet] sync [--recursive] [--] [<path>...]\"\n> @@ -36,6 +36,7 @@ update=\n>  prefix=\n>  custom_name=\n>  depth=\n> +attach=\n>\n>  # The function takes at most 2 arguments. The first argument is the\n>  # URL that navigates to the submodule origin repo. When relative, this URL\n> @@ -352,6 +353,9 @@ cmd_add()\n>                         custom_name=$2\n>                         shift\n>                         ;;\n> +               --attach)\n> +                       attach=\"true\"\n> +                       ;;\n>                 --depth)\n>                         case \"$2\" in '') usage ;; esac\n>                         depth=\"--depth=$2\"\n> @@ -475,8 +479,17 @@ Use -f if you really want to add it.\" >&2\n>                         cd \"$sm_path\" &&\n>                         # ash fails to wordsplit ${branch:+-b \"$branch\"...}\n>                         case \"$branch\" in\n> -                       '') git checkout -f -q ;;\n> -                       ?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> +                       '')\n> +                               git checkout -f -q\n> +                               ;;\n\nIs this whitespace change intentional and necessary?\n\n> +                       ?*)\n> +                               if test -n \"$attach\"\n> +                               then\n> +                                       git checkout -f -q \"$branch\"\n> +                               else\n> +                                       git checkout -f -q -B \"$branch\" \"origin/$branch\"\n> +                               fi\n> +                               ;;\n>                         esac\n>                 ) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n>         fi\n> @@ -491,6 +504,12 @@ Use -f if you really want to add it.\" >&2\n>         then\n>                 git config -f .gitmodules submodule.\"$sm_name\".branch \"$branch\"\n>         fi &&\n> +       if test -n \"$attach\"\n> +       then\n> +               # We'll stay stick to the HEAD, no need to track revision sha1\n> +               git config -f .gitmodules submodule.\"$sm_name\".attach \"true\"\n> +               git config -f .gitmodules submodule.\"$sm_name\".ignore \"all\"\n> +       fi &&\n>         git add --force .gitmodules ||\n>         die \"$(eval_gettext \"Failed to register submodule '\\$sm_path'\")\"\n>  }\n> @@ -622,7 +641,7 @@ cmd_init()\n>                    test -z \"$(git config submodule.\"$name\".update)\"\n>                 then\n>                         case \"$upd\" in\n> -                       rebase | merge | none)\n> +                       checkout | rebase | merge | none)\n\nThis belongs in a commit of its own.\n\n>                                 ;; # known modes of updating\n>                         *)\n>                                 echo >&2 \"warning: unknown update mode '$upd' suggested for submodule '$name'\"\n> @@ -632,6 +651,23 @@ cmd_init()\n>                         git config submodule.\"$name\".update \"$upd\" ||\n>                         die \"$(eval_gettext \"Failed to register update mode for submodule path '\\$displaypath'\")\"\n>                 fi\n> +\n> +               # Copy \"attach\" setting when it is not set yet\n> +               if attached=\"$(git config -f .gitmodules submodule.\"$name\".attach)\" &&\n> +                  test -n \"$attached\" &&\n> +                  test -z \"$(git config submodule.\"$name\".attach)\"\n> +               then\n> +                       case \"$attached\" in\n> +                       true | false)\n> +                               ;; # Valid attach flag values\n> +                       *)\n> +                               echo >&2 \"warning: invalid attach flag value for submodule '$name'\"\n> +                               upd=none\n> +                               ;;\n> +                       esac\n> +                       git config submodule.\"$name\".attach \"$attached\" ||\n> +                       die \"$(eval_gettext \"Failed to register attached option for submodule path '\\$displaypath'\")\"\n> +               fi\n>         done\n>  }\n>\n> @@ -750,6 +786,14 @@ cmd_update()\n>                 --reference=*)\n>                         reference=\"$1\"\n>                         ;;\n> +               --attach)\n> +                       if test \"$attach\" = \"false\" ; then usage ; fi\n> +                       attach=\"true\"\n> +                       ;;\n> +               --detach)\n> +                       if test \"$attach\" = \"true\" ; then usage ; fi\n> +                       attach=\"false\"\n> +                       ;;\n>                 -m|--merge)\n>                         update=\"merge\"\n>                         ;;\n> @@ -800,11 +844,44 @@ cmd_update()\n>                 name=$(module_name \"$sm_path\") || exit\n>                 url=$(git config submodule.\"$name\".url)\n>                 branch=$(get_submodule_config \"$name\" branch master)\n> +               if test -n \"$attach\"\n> +               then\n> +                       attach_module=$attach\n> +               else\n> +                       attach_module=$(git config submodule.\"$name\".attach)\n> +                       case \"$attach_module\" in\n> +                       '')\n> +                               ;; # Unset attach flag\n> +                       true|false)\n> +                               ;; # Valid attach flag values\n> +                       *)\n> +                               echo >&2 \"warning: invalid attach flag value for submodule '$name'\"\n> +                               attach_module=\n> +                               ;;\n> +                       esac\n> +               fi\n> +               if test \"$attach_module\" = \"false\"\n> +               then\n> +                       # Normalize attach 'false' flag value\n> +                       attach_module=\n> +               fi\n>                 if ! test -z \"$update\"\n>                 then\n>                         update_module=$update\n>                 else\n>                         update_module=$(git config submodule.\"$name\".update)\n> +                       case \"$update_module\" in\n> +                       '')\n> +                               ;; # Unset update mode\n> +                       checkout | rebase | merge | none)\n> +                               ;; # Known update modes\n> +                       !*)\n> +                               ;; # Custom update command\n> +                       *)\n> +                               update_module=\n> +                               echo >&2 \"warning: invalid update mode for submodule '$name'\"\n> +                               ;;\n> +                       esac\n\nProbably belongs to the same \"other\" commit mentioned before.\n\n>                 fi\n>\n>                 displaypath=$(relative_path \"$prefix$sm_path\")\n> @@ -836,7 +913,7 @@ Maybe you want to use 'update --init'?\")\"\n>                         die \"$(eval_gettext \"Unable to find current revision in submodule path '\\$displaypath'\")\"\n>                 fi\n>\n> -               if test -n \"$remote\"\n> +               if test -n \"$remote\" -o -n \"$attach_module\"\n>                 then\n>                         if test -z \"$nofetch\"\n>                         then\n> @@ -850,7 +927,16 @@ Maybe you want to use 'update --init'?\")\"\n>                         die \"$(eval_gettext \"Unable to find current ${remote_name}/${branch} revision in submodule path '\\$sm_path'\")\"\n>                 fi\n>\n> -               if test \"$subsha1\" != \"$sha1\" -o -n \"$force\"\n> +               head_rev_ref=$(clear_local_git_env; cd \"$sm_path\" && git rev-parse --abbrev-ref HEAD) ||\n> +               die \"$(eval_gettext \"Unable to determine revision ref in submodule path '\\$sm_path'\")\"\n> +               if test \"$head_rev_ref\" = \"HEAD\"\n> +               then\n> +                       # Determine if the HEAD is detached\n> +                       head_detached=\"true\"\n> +               fi\n> +\n> +               if test \"$subsha1\" != \"$sha1\" || test -n \"$attach_module\" -a -n \"$head_detached\" ||\n> +                       test -z \"$attach_module\" -a -z \"$head_detached\" || test -n \"$force\"\n>                 then\n>                         subforce=$force\n>                         # If we don't already have a -f flag and the submodule has never been checked out\n> @@ -870,40 +956,102 @@ Maybe you want to use 'update --init'?\")\"\n>                         fi\n>\n>                         # Is this something we just cloned?\n> +                       just_cloned=\n>                         case \";$cloned_modules;\" in\n>                         *\";$name;\"*)\n>                                 # then there is no local change to integrate\n> -                               update_module= ;;\n> +                               update_module=\"checkout\"\n> +                               just_cloned=yes\n> +                               ;;\n>                         esac\n>\n> +                       if test -z \"$update_module\"\n> +                       then\n> +                               # Fallback to checkout\n> +                               update_module=\"checkout\"\n> +                       fi\n> +\n> +                       command_pre=:\n> +                       suffix_pre=\n> +                       if test \"$update_module\" = \"checkout\"\n> +                       then\n> +                               if test -n \"$attach_module\" -a -z \"$just_cloned\"\n> +                               then\n> +                                       # We need to attach to the HEAD/switch the branch prior\n> +                                       # performing any fast-forward update\n> +                                       command_pre=\"git checkout $subforce -q\"\n> +                                       suffix_pre=$branch\n> +                               fi\n> +                       else\n> +                               if test -n \"$attach_module\" -a -n \"$head_detached\"\n> +                               then\n> +                                       # We need to reattach to the head\n> +                                       command_pre=\"git checkout $subforce -q\"\n> +                                       suffix_pre=$branch\n> +                               elif test -z \"$attach_module\" -a -z \"$head_detached\"\n> +                               then\n> +                                       # We need to detach from the head\n> +                                       command_pre=\"git checkout $subforce -q\"\n> +                                       suffix_pre=$sha1\n> +                               fi\n> +                       fi\n> +\n>                         must_die_on_failure=\n> +                       custom_update=\n> +                       suffix=\n>                         case \"$update_module\" in\n>                         rebase)\n>                                 command=\"git rebase\"\n> +                               suffix=$sha1\n>                                 die_msg=\"$(eval_gettext \"Unable to rebase '\\$sha1' in submodule path '\\$displaypath'\")\"\n>                                 say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': rebased into '\\$sha1'\")\"\n>                                 must_die_on_failure=yes\n>                                 ;;\n>                         merge)\n>                                 command=\"git merge\"\n> +                               suffix=$sha1\n>                                 die_msg=\"$(eval_gettext \"Unable to merge '\\$sha1' in submodule path '\\$displaypath'\")\"\n>                                 say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': merged in '\\$sha1'\")\"\n>                                 must_die_on_failure=yes\n>                                 ;;\n> +                       checkout)\n> +                               if test -n \"$attach_module\"\n> +                               then\n> +                                       if test -n \"$just_cloned\"\n> +                                       then\n> +                                               command=\"git checkout $subforce -q\"\n> +                                               suffix=$branch\n> +                                       else\n> +                                               # Perform a fast-forward only merge of the origin\n> +                                               command=\"git merge $subforce --ff-only\"\n> +                                               suffix=\"origin/$branch\"\n> +                                       fi\n> +                                       die_msg=\"$(eval_gettext \"Unable to checkout banch '\\$branch' in submodule path '\\$displaypath'\")\"\n> +                                       say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out branch '\\$branch'\")\"\n> +                               else\n> +                                       command=\"git checkout $subforce -q\"\n> +                                       suffix=$sha1\n> +                                       die_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n> +                                       say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n> +                               fi\n> +                               ;;\n>                         !*)\n>                                 command=\"${update_module#!}\"\n> +                               suffix=$sha1\n>                                 die_msg=\"$(eval_gettext \"Execution of '\\$command \\$sha1' failed in submodule  path '\\$prefix\\$sm_path'\")\"\n>                                 say_msg=\"$(eval_gettext \"Submodule path '\\$prefix\\$sm_path': '\\$command \\$sha1'\")\"\n>                                 must_die_on_failure=yes\n> +                               custom_update=yes\n>                                 ;;\n>                         *)\n> -                               command=\"git checkout $subforce -q\"\n> -                               die_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n> -                               say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n> +                               # Valid user configurable update modes are already filtered above\n> +                               die \"$(eval_gettext \"Unexpected update mode in the current flow\")\"\n>                                 ;;\n>                         esac\n>\n> -                       if (clear_local_git_env; cd \"$sm_path\" && $command \"$sha1\")\n> +                       if (clear_local_git_env; cd \"$sm_path\" &&\n> +                               $command_pre \"$suffix_pre\" &&\n> +                               $command \"$suffix\")\n>                         then\n>                                 say \"$say_msg\"\n>                         elif test -n \"$must_die_on_failure\"\n\nI didn't have time to parse out all these conditional completion\ncommands in this review, but the feature seems sane to me, as I\nunderstand it.\n\nPhil\n"},{"id":"232568","messageId":"CALas-igDaweib14zaLJk3m1zmBWk=14oA7h_e7G82vpxmBjiOg@mail.gmail.com","threadId":"35584","inReplyTo":"CABURp0pQHw7qvG_tq8oK=6DBOUoYy=Rb5othV+zBpNonuv=PLw@mail.gmail.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-02T18:48:30Z","receivedAt":"2014-01-02T18:48:30Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"Thanks for the comments, my replies below. Before, a couple of general\nquestions:\n- I'm also writing some tests, should I commit them together with the\nfeature patch?\n- to determine the attached/detached state I did this:\n\nhead_detached=\nif test \"$(rev-parse --abbrev-ref HEAD)\" = \"HEAD\"\nthen\n    head_detached=\"true\"\nfi\n\nIs this correct?\n\n2013/12/31 Phil Hord <phil.hord@gmail.com>\n>\n> On Sun, Dec 29, 2013 at 8:49 PM, Francesco Pretto <ceztko@gmail.com> wrote:\n>  [...]\n> >\n> > When updating, using the '--attach' switch or operating in a repository with\n> > 'submodule.<name>.attach' set to 'true' will:\n> > - checkout a branch with an attached HEAD if the repository was just cloned;\n> > - perform a fast-forward only merge of changes if it's a 'checkout' update,\n> > keeping the HEAD attached;\n> > - reattach the HEAD prior performing a 'merge', 'rebase' or '!command' update\n> > operation if the HEAD was found detached.\n>\n> I need to understand this \"reattach the HEAD\" case better. Can you\n> give some examples of the expected behavior when merge, rebase or\n> !command is encountered?\n>\n\nThanks for pointing this out, actually my patch was a bit lacking at\nthis. Reattaching the HEAD prior to merge, rebase or \"!command\" would\nhave caused just a *silent* \"git checkout \"<branch>\", possibly leaving\norphaned commits forgotten.\n\nMy plans for the patch are now to implement this safer and, IMO,\nintuitive behavior: let set say we have a submodule \"mod\" with the\nHEAD detached at orphaned commit <orphaned-sha1>. Let say\n\"origin/<branch>\" is at commit <origin-sha1>. Let say I set\n\"submodule.mod.attach\" to \"true\" or I run \"git submodule update\" with\nthe \"--attach\" switch. The expected behavior for submodule \"mod\" would\nbe (pseudocode):\n\ngit checkout <branch>\nif \"merge\" and \"head_detached\" then\n    git merge <orphaned-sha1>\ncase:\n    \"merge\":\n        git merge <origin-sha1>\n    \"rebase\":\n        git rebase <origin-sha1>\n    \"!<command>\":\n        <command> <origin-sha1>\nif \"rebase\" and \"head_detached\" then\n   git merge <orphaned-sha1>\n\nSo, in both \"merge|rebase\" cases we merge back orphaned commits with a\n\"git merge\", but the effect will be a merge or a rebase depending of\nthe ordering of the main \"update\" operation. We can't assume a merge\nor rebase operation in the case of !command so we let the\nresponsibility of merging back orphaned commits to the user.\n\nSounds good?\n\n>\n> > +\n> > +--attach::\n> > +       This option is only valid for the add and update commands. Cause the\n>\n> Grammar: 'Causes the result'\n>\n\nOk.\n\n>\n> > +       result of an add or update operation to be an attached HEAD. In the\n> > +       update command , if `submodule.<name>.branch` is not set, it will\n>\n> typo: space before comma.\n>\n\nOk.\n\n>\n> Also, the pronoun \"it\" here is unclear to me.  Does this convey the\n> correct meaning?\n>\n>    In the update operation, the branch named by 'submodule.<name>.branch' is\n>    checked out as the new HEAD of the submodule repository. If\n>    'submodule.<name>.branch' is not set, the 'master' branch is\n> checked out as the\n>    new HEAD of the submodule.\n>\n\nSounds good to me.\n\n>\n> > +       default to `master`. Note: for the update command `--attach` also\n> > +       implies `--remote`.\n> > +\n> > +--detach::\n> > +       This option is only valid for the update command. Cause the result\n>\n>  Grammar: 'Causes the result'\n>\n\nOk.\n\n>\n> > +       of the update operation to be forcedly a detached HEAD.\n>\n> \"Forcedly\" is a bit strong, maybe, slightly misplaced, and not a word,\n> besides.   How's this, instead:\n>\n>    Forces the result of the update operation to be a detached HEAD in\n> the submodule.\n\n\nSounds good to me.\n\n>\n> >  submodule.<name>.update::\n> >         Defines what to do when the submodule is updated by the superproject.\n> > -       If 'checkout' (the default), the new commit specified in the\n> > -       superproject will be checked out in the submodule on a detached HEAD.\n> > +       If 'checkout' (the default), the new commit (or the branch, when using\n> > +       the '--attach' switch or the 'submodule.<name>.attach' property is set\n> > +       to 'true' during an update operation) specified in the superproject will\n> > +       be checked out in the submodule.\n>\n> IMHO, this wording is overcomplicated by this change.  How about:\n>\n>        If 'checkout' (the default), the new commit specified in the superproject\n>        (or branch, with '--attach') will be checked out in the submodule.\n>\n\nSounds good to me.\n\n>\n> >         If 'rebase', the current branch of the submodule will be rebased onto\n> >         the commit specified in the superproject. If 'merge', the commit\n> >         specified in the superproject will be merged into the current branch\n>\n> Does the 'merge', 'rebase' and '!command' description need to be\n> updated, too?  Here and above it seems to still suggest the old\n> behavior is kept when --attach is used.\n>\n\nYou are right, I'll improve those. Also I think the documentation was\na bit innacurate because, with the current git features state, it's\npossible merge changes keeping the HEAD detached, and that's what\nhappen.\n\n\n>\n> > @@ -54,6 +56,11 @@ submodule.<name>.branch::\n> >         If the option is not specified, it defaults to 'master'.  See the\n> >         `--remote` documentation in linkgit:git-submodule[1] for details.\n> >\n> > +submodule.<name>.attach::\n> > +       Determine if the update operation will produce a detached HEAD or not.\n> > +       Valid values are `true` or `false`. If the property is set to `true`\n> > +       and `submodule.<name>.branch`, it will default to `master`\n>\n> I think you mean \"...and 'submodule.<name>.branch' is not set, it\n> will...\", right?\n\n\nCorrect. I'll fix it.\n\n>\n> Some explanation of what happens when it _is_ set would be useful\n> here, too, I think.  But maybe I do not understand the nuances yet.\n>\n\nI think you're right. I'll improve it.\n\n>\n> > @@ -475,8 +479,17 @@ Use -f if you really want to add it.\" >&2\n> >                         cd \"$sm_path\" &&\n> >                         # ash fails to wordsplit ${branch:+-b \"$branch\"...}\n> >                         case \"$branch\" in\n> > -                       '') git checkout -f -q ;;\n> > -                       ?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> > +                       '')\n> > +                               git checkout -f -q\n> > +                               ;;\n>\n> Is this whitespace change intentional and necessary?\n>\n\nIt's unnecessary but it was intentional. In the file there are mixed\nindentation styles for cases but when there are multiple statements\nclauses the more frequent style is to span single statement clauses to\nmulti-line too. I touched the clause below to become muti-statenent so\nhere we are. Please tell me if it's more correct to not touch that\nline.\n\n\n>\n> >  }\n> > @@ -622,7 +641,7 @@ cmd_init()\n> >                    test -z \"$(git config submodule.\"$name\".update)\"\n> >                 then\n> >                         case \"$upd\" in\n> > -                       rebase | merge | none)\n> > +                       checkout | rebase | merge | none)\n>\n> This belongs in a commit of its own.\n>\n\nAgreed. I'll do it.\n\n>\n> >                                 ;; # known modes of updating\n> >                         *)\n> >                                 echo >&2 \"warning: unknown update mode '$upd' suggested for submodule '$name'\"\n> > @@ -632,6 +651,23 @@ cmd_init()\n> >                         git config submodule.\"$name\".update \"$upd\" ||\n> >                         die \"$(eval_gettext \"Failed to register update mode for submodule path '\\$displaypath'\")\"\n> >                 fi\n> > +\n> > +               # Copy \"attach\" setting when it is not set yet\n> > +               if attached=\"$(git config -f .gitmodules submodule.\"$name\".attach)\" &&\n> > +                  test -n \"$attached\" &&\n> > +                  test -z \"$(git config submodule.\"$name\".attach)\"\n> > +               then\n> > +                       case \"$attached\" in\n> > +                       true | false)\n> > +                               ;; # Valid attach flag values\n> > +                       *)\n> > +                               echo >&2 \"warning: invalid attach flag value for submodule '$name'\"\n> > +                               upd=none\n> > +                               ;;\n> > +                       esac\n> > +                       git config submodule.\"$name\".attach \"$attached\" ||\n> > +                       die \"$(eval_gettext \"Failed to register attached option for submodule path '\\$displaypath'\")\"\n> > +               fi\n> >         done\n> >  }\n> >\n> > @@ -750,6 +786,14 @@ cmd_update()\n> >                 --reference=*)\n> >                         reference=\"$1\"\n> >                         ;;\n> > +               --attach)\n> > +                       if test \"$attach\" = \"false\" ; then usage ; fi\n> > +                       attach=\"true\"\n> > +                       ;;\n> > +               --detach)\n> > +                       if test \"$attach\" = \"true\" ; then usage ; fi\n> > +                       attach=\"false\"\n> > +                       ;;\n> >                 -m|--merge)\n> >                         update=\"merge\"\n> >                         ;;\n> > @@ -800,11 +844,44 @@ cmd_update()\n> >                 name=$(module_name \"$sm_path\") || exit\n> >                 url=$(git config submodule.\"$name\".url)\n> >                 branch=$(get_submodule_config \"$name\" branch master)\n> > +               if test -n \"$attach\"\n> > +               then\n> > +                       attach_module=$attach\n> > +               else\n> > +                       attach_module=$(git config submodule.\"$name\".attach)\n> > +                       case \"$attach_module\" in\n> > +                       '')\n> > +                               ;; # Unset attach flag\n> > +                       true|false)\n> > +                               ;; # Valid attach flag values\n> > +                       *)\n> > +                               echo >&2 \"warning: invalid attach flag value for submodule '$name'\"\n> > +                               attach_module=\n> > +                               ;;\n> > +                       esac\n> > +               fi\n> > +               if test \"$attach_module\" = \"false\"\n> > +               then\n> > +                       # Normalize attach 'false' flag value\n> > +                       attach_module=\n> > +               fi\n> >                 if ! test -z \"$update\"\n> >                 then\n> >                         update_module=$update\n> >                 else\n> >                         update_module=$(git config submodule.\"$name\".update)\n> > +                       case \"$update_module\" in\n> > +                       '')\n> > +                               ;; # Unset update mode\n> > +                       checkout | rebase | merge | none)\n> > +                               ;; # Known update modes\n> > +                       !*)\n> > +                               ;; # Custom update command\n> > +                       *)\n> > +                               update_module=\n> > +                               echo >&2 \"warning: invalid update mode for submodule '$name'\"\n> > +                               ;;\n> > +                       esac\n>\n> Probably belongs to the same \"other\" commit mentioned before.\n>\n\nAgreed. Please confirm that you meant only the\nsubmodule.\"$module\".update part here as you quoted also a lof of code\nthat does belongs to the main \"--attach\" functionality.\n\n>\n> I didn't have time to parse out all these conditional completion\n> commands in this review, but the feature seems sane to me, as I\n> understand it.\n>\n\nGood. After a response I should be able to produce an improved patch.\n\nThanks,\nFrancesco\n"},{"id":"232573","messageId":"xmqqppoap2qb.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"1388368184-18418-1-git-send-email-ceztko@gmail.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-02T20:07:08Z","receivedAt":"2014-01-02T20:07:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Francesco Pretto <ceztko@gmail.com> writes:\n\n> by default \"git submodule\" performs its add or update operations on a detached\n> HEAD. This works well when using an existing full-fledged/indipendent project as\n> the submodule, as there's less frequent need to update it or commit back\n> changes. When the submodule is actually a large portion of shareable code\n> between  different projects, and the superproject needs to track very closely\n> the evolution of the submodule (or the other way around), I feel more confortable\n> to reattach the HEAD of the submodule with an existing branch.\n\nI may be missing some fundamental assumption in your mind when you\ndid this change, but in a workflow where somebody wants submodule\ncheckout to be on branches (as opposed to detached), wouldn't it\nmake more sense not to detach in the first place, rather than\nintroducing yet another option to \"re-attach\"?  The documentation of\n\"submodule update\" seems to say that its \"merge\" and \"rebase\" modes\ndo not detach in the first place (and it alludes to \"--checkout\" but\nit is unclear what it does purely from the documentation, as \"git\nsubmodule --help\" does not even list it as one of the options).\n\nAnd if there is a good reason why detaching to update and then\n(perhaps after verifying the result or cleaning it up?  I dunno what\nthe expected use case is, so I am purely guessing) attaching the\nresult to a specific branch in separate steps, does it make sense to\ngive \"--attach\" option to \"update\" in the first place?  That makes\nthe whole thing into a single step, not giving the user a chance to\ndo anything in between, which I am guessing is the whole point of\nyour not using the existing \"do not detach, work on a branch\" modes.\n\nPuzzled...\n"},{"id":"232597","messageId":"CALas-ihAkUGOZsmWRHN7fG+5D0OnpWmSNtrMH2mwNm51gcYdRw@mail.gmail.com","threadId":"35584","inReplyTo":"xmqqppoap2qb.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-02T23:42:35Z","receivedAt":"2014-01-02T23:42:35Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/2 Junio C Hamano <gitster@pobox.com>:\n> Francesco Pretto <ceztko@gmail.com> writes:\n>\n>> by default \"git submodule\" performs its add or update operations on a detached\n>> HEAD. This works well when using an existing full-fledged/indipendent project as\n>> the submodule, as there's less frequent need to update it or commit back\n>> changes. When the submodule is actually a large portion of shareable code\n>> between  different projects, and the superproject needs to track very closely\n>> the evolution of the submodule (or the other way around), I feel more confortable\n>> to reattach the HEAD of the submodule with an existing branch.\n>\n> I may be missing some fundamental assumption in your mind when you\n> did this change, but in a workflow where somebody wants submodule\n> checkout to be on branches (as opposed to detached), wouldn't it\n> make more sense not to detach in the first place, rather than\n> introducing yet another option to \"re-attach\"?  The documentation of\n> \"submodule update\" seems to say that its \"merge\" and \"rebase\" modes\n> do not detach in the first place (and it alludes to \"--checkout\" but\n> it is unclear what it does purely from the documentation, as \"git\n> submodule --help\" does not even list it as one of the options).\n>\n\nThanks for commenting: because of more checking I just spotted some\nunuseful code in my patch in cmd_add() function. In short: it seems to\nme \"git submodule update\" doesn't allow to work with attached an HEAD\n(unless it is *manually* attached, as I regularly do). My feeling is\nthe documentation of \"merge\", \"rebase\" update commands is inaccurate\nand doesn't really reflect what happen when adding a submodule with\n\"add\" or cloning it for the first time with \"update\". You can look at\nthe following conditionals in the current code in git-submodule.sh:\n\n## cmd_add()\ncase \"$branch\" in\n'') git checkout -f -q ;;\n?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\nesac\n\n## cmd_update()\n# Is this something we just cloned?\ncase \";$cloned_modules;\" in\n    *\";$name;\"*)\n    # then there is no local change to integrate\n    update_module= ;;\nesac\n\nThis means that the \"add\" command will always checkout an *attached*\nHEAD but at the first clone of a different user the checkout will\nresolve in \"git checkout <sha1>\", always producing a *detached* HEAD\nand resulting in inconsistent HEAD state between who added the\nsubmodule with \"add\" and who cloned it with \"update\". Subsequent\n\"merge\" or \"rebase\" operations won't change this fact, the HEAD will\nremain detached. The following test case confirms this, unless I did\nsomething wrong:\n\n-----------------------------------------------------------------\nparentdir=$(pwd -P)\nsubmodurl1=$(pwd -P)/repo1\nsubmodurl2=$(pwd -P)/repo2\nrepourl=$(pwd -P)/repo\n\n# Create repo to be added with submodules\ncd $parentdir\nmkdir repo\ncd repo\ngit init\ngit config receive.denyCurrentBranch ignore\necho a >a\ngit add a\ngit commit -m \"repo commit 1\"\n\n# Create repo repo1 to be used as submodule\ncd $parentdir\nmkdir repo1\ncd repo1\ngit init\ngit config receive.denyCurrentBranch ignore\necho a >a\ngit add a\ngit commit -m \"repo1 commit 1\"\n\n# Create repo repo2 to be used as submodule\ncd $parentdir\nmkdir repo2\ncd repo2\ngit init\ngit config receive.denyCurrentBranch ignore\necho a >a\ngit add a\ngit commit -m \"repo2 commit 1\"\n\n# Clone repo to test \"git submodule update\"\ncd $parentdir\ngit clone \"$repourl\" repoclone\n\n#\n## Adding submodule with update \"rebase\", not specifying a <branch>\n#\n\ncd $parentdir/repo\ngit submodule add \"$submodurl1\" submod1\ngit config -f .gitmodules submodule.submod1.ignore all\ngit config -f .gitmodules submodule.submod1.update rebase\ngit commit -m \"Added submodule\"\n###### repo/submod1 has an attached HEAD ######\n\ncd $parentdir/repoclone\ngit pull\ngit submodule init\ngit submodule update\n###### repoclone/submod1 has a detached HEAD --> note the inconsistency ######\n\n#\n## Adding submodule with update \"rebase\", specifying a <branch>\n#\ncd $parentdir/repo\ngit submodule add --branch master \"$submodurl2\" submod2\ngit config -f .gitmodules submodule.submod2.ignore all\ngit config -f .gitmodules submodule.submod2.update rebase\ngit add .\ngit commit -m \"Added submodule\"\n###### repo/submod2 has a attached HEAD ######\n\ncd $parentdir/repoclone\ngit pull\ngit submodule init\ngit submodule update --remote\n###### repoclone/submod2 has a detached HEAD --> note the inconsistency ######\n\n#\n## Adding something to submod2 and test update \"rebase\" on repoclone\n#\n\ncd $parentdir/repo1\necho b >b\ngit add b\ngit commit -m \"repo1 commit 2\"\n\ncd $parentdir/repoclone\ngit submodule update --remote\n###### repoclone/submod1 has still a detached HEAD ######\n-----------------------------------------------------------------\n\n\n> And if there is a good reason why detaching to update and then\n> (perhaps after verifying the result or cleaning it up?  I dunno what\n> the expected use case is, so I am purely guessing) attaching the\n> result to a specific branch in separate steps, does it make sense to\n> give \"--attach\" option to \"update\" in the first place?  That makes\n> the whole thing into a single step, not giving the user a chance to\n> do anything in between, which I am guessing is the whole point of\n> your not using the existing \"do not detach, work on a branch\" modes.\n>\n\n1) The \"--attach\" option in the \"add\" git submodule command is my\ncontribution to have the \"attached\" behavior by default for cloning\nusers, because it's not possible to obtain it by just setting the\nupdate command to \"merge\" or \"rebase\";\n2) The \"--attach\" and \"--detach\" switches for the \"update\" command are\nneeded just to override in the command line the setting of\n\"submodule.<module>.attach\" (or its absence of value). Of course not\nmany users will need to use these switche. The others will just use\nthe provided \"submodule.<module>.attach\" value and issue \"git update\"\n(or \"git init\", when needed to update properties).\n\nConcluding, my point is that at the current state submodules in git\nseem to be flawed because of the inconsistent HEAD state between \"add\"\nand \"update\" users. With my patch applied the attached HEAD behavior\nwould be fully supported. At some point \"git submodule add\" (without\nthe \"--attached\" switch) could be also modified to produce a detached\nHEAD by default, removing any remaining inconsistency.\n"},{"id":"232602","messageId":"CALas-ij4b-y0=6wa+VnEmnyq9a0c3ACQ+yOgESBeXOy32mm_MQ@mail.gmail.com","threadId":"35584","inReplyTo":"CALas-ihAkUGOZsmWRHN7fG+5D0OnpWmSNtrMH2mwNm51gcYdRw@mail.gmail.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-03T00:26:44Z","receivedAt":"2014-01-03T00:26:44Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/3 Francesco Pretto <ceztko@gmail.com>:\n> Concluding, my point is that at the current state submodules in git\n> seem to be flawed because of the inconsistent HEAD state between \"add\"\n> and \"update\" users. With my patch applied the attached HEAD behavior\n> would be fully supported. At some point \"git submodule add\" (without\n> the \"--attached\" switch) could be also modified to produce a detached\n> HEAD by default, removing any remaining inconsistency.\n>\n\nAlso consider that ultimately my desired behavior for submodules is\nthe following:\n1) I'd like cloning users to have an attached HEAD by default when\ndoing \"git submodule update\";\n2) when using an attached HEAD, I'd like \"git submodule update\" to\nalso imply \"--remote\".\n\nAn alternative approach would be, for example, make \"git submodule\nupdate\" honor the current documentation about the behavior of \"merge\"\nand \"rebase\" update operations, if confirmed to be wrong, really\nkeeping the HEAD attached. That would be a breaking change, but at\nleast it would reflect currently documented behavior. I prefer my\noriginal approach, because it adds more feasibility and it's not\nbreaking in the short time, but I'm open to that and other solutions.\n\nPlease let me know, what do you think about it.\n\nThank you,\nFrancesco\n"},{"id":"232614","messageId":"CALas-iiF7Og8qjWoYeop3GofG_kR7w5DDcNkA1y3eQhu1Srxkw@mail.gmail.com","threadId":"35584","inReplyTo":"CALas-ihAkUGOZsmWRHN7fG+5D0OnpWmSNtrMH2mwNm51gcYdRw@mail.gmail.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-03T08:49:01Z","receivedAt":"2014-01-03T08:49:01Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/3 Francesco Pretto <ceztko@gmail.com>:\n> Concluding, my point is that at the current state submodules in git\n> seem to be flawed because of the inconsistent HEAD state between \"add\"\n> and \"update\" users. With my patch applied the attached HEAD behavior\n> would be fully supported. At some point \"git submodule add\" (without\n> the \"--attached\" switch) could be also modified to produce a detached\n> HEAD by default, removing any remaining inconsistency.\n\nJunio, please let me amend this affirmation as it's inaccurate.\nAccording to the current *upstream* features this should the supported\nuse case for submodules:\n- there's a maintainer \"add\" user that adds the submodule. He will\nneed to track the upstream submodule revision sha1, so he will clone\nthe repository with an *attached* HEAD;\n- there's a developer \"update\" use that just clone the submodule\nrepository and track the sha1 decided by the maintainer \"add\" user. He\nwon't need to track upstream submodule revision sha1 so cloning the\nrepository with a *detached* HEAD. Subsequent \"merge\" or \"rebase\"\nupdate operations will keep the HEAD detached.\n\nWe should *not* modify/break this default workflow in any way.\n\nThe current documentation seems to be misleading when saying that\n\"This [the update command] will make the submodules HEAD be detached\n**unless** --rebase or --merge is specified\", as it seems to imply\nthat the update operation will result in a repository with the HEAD\nattached. The repository will be indeed updated merging changes, but\nthe HEAD will stay detached.\n\nNow, the use case I would like git to support is this:\n- there's a maintainer \"add\" user that adds the submodule. He won't\ntrack the upstream submodule revision sha1, so\n\"submodule.<module>.ignore\" will be set to \"all\". He will still clone\nthe repository with an *attached* HEAD;\n- there's a developer \"update\" user. He will clone the submodule\nrepository with an *attached* HEAD. Subsequent \"merge\" or \"rebase\"\nupdate operations will keep the HEAD attached.\n\nTo fully support this workflow in my patch I want to:\n- introduce a \"submodule.<module>.attach\" property so \"update\" users\nwill clone the submodule repository with an attached HEAD;\n- introduce \"--attach|--dettach\" switches to \"update\" commmant to\neventually override \"submodule.<module>.attach\" property value in the\ncommand line;\n- introduce \"--attach\" (but better rename it to \"--keep-attached\" or\nsomething else) switch to the \"add\" operation. This \"--keep-attached\"\nwill:\n    * set \"submodule.<module>.attach\" to true;\n    * set \"submodule.<module>.ignore\" to all.\n\nBeing the workflow complementary, and the behavior fully optional, I\nthink the proposed feature should be solid. Give me some time to\nproduce an improved patch and let see if I can convince you.\n\nRegards,\nFrancesco\n"},{"id":"232623","messageId":"dad947caba9e1c49d691ffccc868cfdce7d04e82.1388772192.git.wking@tremily.us","threadId":"35584","inReplyTo":"CALas-iiF7Og8qjWoYeop3GofG_kR7w5DDcNkA1y3eQhu1Srxkw@mail.gmail.com","subject":"[PATCH] submodule: Respect reqested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-03T18:06:11Z","receivedAt":"2014-01-03T18:06:11Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"From: \"W. Trevor King\" <wking@tremily.us>\n\nThe previous code only checked out the requested branch in cmd_add.\nThis commit moves the branch-checkout logic into module_clone, where\nit can be shared by cmd_add and cmd_update.  I also update the initial\ncheckout command to use 'rebase' to preserve branches setup during\nmodule_clone.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n\nOn Fri, Jan 03, 2014 at 09:49:01AM +0100, Francesco Pretto wrote:\n> - there's a developer \"update\" user. He will clone the submodule\n> repository with an *attached* HEAD. Subsequent \"merge\" or \"rebase\"\n> update operations will keep the HEAD attached.\n\n'merge' and 'rebase' updates don't change the HEAD attachment.\nBranches stay branches and detached HEADs stay detached.  If you've\nmoved away from the 'checkout' update mechanism, the only thing you\nstill need is a way to get an initial checkout on a branch.  This\nshould do it (I can add tests if folks like the general approach).\n\n git-submodule.sh | 30 +++++++++++++++++-------------\n 1 file changed, 17 insertions(+), 13 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 2979197..e2e5a6c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -253,6 +253,7 @@ module_clone()\n \turl=$3\n \treference=\"$4\"\n \tdepth=\"$5\"\n+\tbranch=\"$6\"\n \tquiet=\n \tif test -n \"$GIT_QUIET\"\n \tthen\n@@ -306,7 +307,14 @@ module_clone()\n \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n \n \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n-\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n+\t(\n+\t\tclear_local_git_env\n+\t\tcd \"$sm_path\" &&\n+\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n+\t\tif test -n \"$branch\"; then\n+\t\t\tgit checkout -f -q -B \"$branch\" \"origin/$branch\" && echo \"checked out $branch\"\n+\t\tfi\n+\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n }\n \n isnumber()\n@@ -469,16 +477,7 @@ Use -f if you really want to add it.\" >&2\n \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n \t\t\tfi\n \t\tfi\n-\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n-\t\t(\n-\t\t\tclear_local_git_env\n-\t\t\tcd \"$sm_path\" &&\n-\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n-\t\t\tcase \"$branch\" in\n-\t\t\t'') git checkout -f -q ;;\n-\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n-\t\t\tesac\n-\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n+\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$branch\" || exit\n \tfi\n \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n \n@@ -815,7 +814,7 @@ Maybe you want to use 'update --init'?\")\"\n \n \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n \t\tthen\n-\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n+\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$branch\" || exit\n \t\t\tcloned_modules=\"$cloned_modules;$name\"\n \t\t\tsubsha1=\n \t\telse\n@@ -861,7 +860,12 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module= ;;\n+\t\t\t\tif test -n \"$branch\"; then\n+\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n+\t\t\t\telse\n+\t\t\t\t\tupdate_module=\n+\t\t\t\tfi\n+\t\t\t\t;;\n \t\t\tesac\n \n \t\t\tmust_die_on_failure=\n-- \n1.8.5.2.gaa5d535.dirty\n"},{"id":"232649","messageId":"20140104220915.GA5697@book-mint","threadId":"35584","inReplyTo":"dad947caba9e1c49d691ffccc868cfdce7d04e82.1388772192.git.wking@tremily.us","subject":"Re: [PATCH] submodule: Respect reqested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-04T22:09:15Z","receivedAt":"2014-01-04T22:09:15Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Hi,\n\nOn Fri, Jan 03, 2014 at 10:06:11AM -0800, W. Trevor King wrote:\n> From: \"W. Trevor King\" <wking@tremily.us>\n> \n> The previous code only checked out the requested branch in cmd_add.\n> This commit moves the branch-checkout logic into module_clone, where\n> it can be shared by cmd_add and cmd_update.  I also update the initial\n> checkout command to use 'rebase' to preserve branches setup during\n> module_clone.\n> \n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n> \n> On Fri, Jan 03, 2014 at 09:49:01AM +0100, Francesco Pretto wrote:\n> > - there's a developer \"update\" user. He will clone the submodule\n> > repository with an *attached* HEAD. Subsequent \"merge\" or \"rebase\"\n> > update operations will keep the HEAD attached.\n> \n> 'merge' and 'rebase' updates don't change the HEAD attachment.\n> Branches stay branches and detached HEADs stay detached.  If you've\n> moved away from the 'checkout' update mechanism, the only thing you\n> still need is a way to get an initial checkout on a branch.  This\n> should do it (I can add tests if folks like the general approach).\n> \n>  git-submodule.sh | 30 +++++++++++++++++-------------\n>  1 file changed, 17 insertions(+), 13 deletions(-)\n> \n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 2979197..e2e5a6c 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -253,6 +253,7 @@ module_clone()\n>  \turl=$3\n>  \treference=\"$4\"\n>  \tdepth=\"$5\"\n> +\tbranch=\"$6\"\n>  \tquiet=\n>  \tif test -n \"$GIT_QUIET\"\n>  \tthen\n> @@ -306,7 +307,14 @@ module_clone()\n>  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n>  \n>  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n\nWhy should this line be removed? Is it not needed for correct\nworktree <-> repo linking of submodules?\n\n> +\t(\n> +\t\tclear_local_git_env\n> +\t\tcd \"$sm_path\" &&\n> +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> +\t\tif test -n \"$branch\"; then\n> +\t\t\tgit checkout -f -q -B \"$branch\" \"origin/$branch\" && echo \"checked out $branch\"\n> +\t\tfi\n> +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n>  }\n>  \n>  isnumber()\n> @@ -469,16 +477,7 @@ Use -f if you really want to add it.\" >&2\n>  \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n>  \t\t\tfi\n>  \t\tfi\n> -\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n> -\t\t(\n> -\t\t\tclear_local_git_env\n> -\t\t\tcd \"$sm_path\" &&\n> -\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n> -\t\t\tcase \"$branch\" in\n> -\t\t\t'') git checkout -f -q ;;\n> -\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> -\t\t\tesac\n> -\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n> +\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$branch\" || exit\n>  \tfi\n>  \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n>  \n> @@ -815,7 +814,7 @@ Maybe you want to use 'update --init'?\")\"\n>  \n>  \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n>  \t\tthen\n> -\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n> +\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$branch\" || exit\n>  \t\t\tcloned_modules=\"$cloned_modules;$name\"\n>  \t\t\tsubsha1=\n>  \t\telse\n> @@ -861,7 +860,12 @@ Maybe you want to use 'update --init'?\")\"\n>  \t\t\tcase \";$cloned_modules;\" in\n>  \t\t\t*\";$name;\"*)\n>  \t\t\t\t# then there is no local change to integrate\n> -\t\t\t\tupdate_module= ;;\n> +\t\t\t\tif test -n \"$branch\"; then\n> +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n\nDoes that not put the user in danger of loosing changes?\n\nI am wondering if we should maybe take a little different approach:\n\nIf submodule.<name>.branch is configured:\n\n\tgit submodule update\n\nwill checkout the configured branch instead of the sha1? Maybe something like\nthis (untested):\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 2677f2e..eca519a 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -903,7 +903,13 @@ Maybe you want to use 'update --init'?\")\"\n                                ;;\n                        esac\n \n-                       if (clear_local_git_env; cd \"$sm_path\" && $command \"$sha1\")\n+                       revision=\"$sha1\"\n+                       if test -n \"$branch\"\n+                       then\n+                               revision=\"$branch\"\n+                       fi\n+\n+                       if (clear_local_git_env; cd \"$sm_path\" && $command \"$revision\")\n                        then\n                                say \"$say_msg\"\n                        elif test -n \"$must_die_on_failure\"\n\n\nThen we do not need to write a command configuration into the local repository\nconfiguration. If I understand the OP intention correctly, that should solve the\nuse-case.\n\nCheers Heiko\n"},{"id":"232652","messageId":"20140104225401.GA3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140104220915.GA5697@book-mint","subject":"Re: [PATCH] submodule: Respect reqested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-04T22:54:01Z","receivedAt":"2014-01-04T22:54:01Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sat, Jan 04, 2014 at 11:09:15PM +0100, Heiko Voigt wrote:\n> On Fri, Jan 03, 2014 at 10:06:11AM -0800, W. Trevor King wrote:\n> > @@ -306,7 +307,14 @@ module_clone()\n> >  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n> >  \n> >  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> > -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> \n> Why should this line be removed? Is it not needed for correct\n> worktree <-> repo linking of submodules?\n> \n> > +\t(\n> > +\t\tclear_local_git_env\n> > +\t\tcd \"$sm_path\" &&\n> > +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> > +\t\tif test -n \"$branch\"; then\n> > +\t\t\tgit checkout -f -q -B \"$branch\" \"origin/$branch\" && echo \"checked out $branch\"\n> > +\t\tfi\n> > +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n> >  }\n\nIt's not removed, just merged with the branch manipulation that also\nhappens in a clean local environment in $sm_path.  Spawning two\nsequential subshells with the same setup seemed like overkill.\n\n> > @@ -861,7 +860,12 @@ Maybe you want to use 'update --init'?\")\"\n> >  \t\t\tcase \";$cloned_modules;\" in\n> >  \t\t\t*\";$name;\"*)\n> >  \t\t\t\t# then there is no local change to integrate\n> > -\t\t\t\tupdate_module= ;;\n> > +\t\t\t\tif test -n \"$branch\"; then\n> > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> \n> Does that not put the user in danger of loosing changes?\n\nNo, because this is only happens for just-cloned modules.  The user\nhasn't had time to make local changes yet.\n\n> If submodule.<name>.branch is configured:\n> \n> \tgit submodule update\n> \n> will checkout the configured branch instead of the sha1?\n\nThe use case described by Francesco, a submodule maintainer Alice sets\nup the submodule, which downstream developer Bob want to checkout to a\nbranch.  I think that matching the exact commit specified by Alice in\nBob's checkout is important, even if the upstream developer Charlie\nhas advanced the referenced branch in the meantime.  Shifting the\nreferenced submodule commit should be an explicit decision made by\nAlice, not a clone-time accident for Bob.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232654","messageId":"20140105003922.GA21772@sandbox-ub","threadId":"35584","inReplyTo":"20140104225401.GA3156@odin.tremily.us","subject":"Re: Re: [PATCH] submodule: Respect reqested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-05T00:39:22Z","receivedAt":"2014-01-05T00:39:22Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Sat, Jan 04, 2014 at 02:54:01PM -0800, W. Trevor King wrote:\n> On Sat, Jan 04, 2014 at 11:09:15PM +0100, Heiko Voigt wrote:\n> > On Fri, Jan 03, 2014 at 10:06:11AM -0800, W. Trevor King wrote:\n> > > @@ -306,7 +307,14 @@ module_clone()\n> > >  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n> > >  \n> > >  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> > > -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> > \n> > Why should this line be removed? Is it not needed for correct\n> > worktree <-> repo linking of submodules?\n> > \n> > > +\t(\n> > > +\t\tclear_local_git_env\n> > > +\t\tcd \"$sm_path\" &&\n> > > +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> > > +\t\tif test -n \"$branch\"; then\n> > > +\t\t\tgit checkout -f -q -B \"$branch\" \"origin/$branch\" && echo \"checked out $branch\"\n> > > +\t\tfi\n> > > +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n> > >  }\n> \n> It's not removed, just merged with the branch manipulation that also\n> happens in a clean local environment in $sm_path.  Spawning two\n> sequential subshells with the same setup seemed like overkill.\n\nAh ok, thanks. For some reason I overlooked that.\n\n> > > @@ -861,7 +860,12 @@ Maybe you want to use 'update --init'?\")\"\n> > >  \t\t\tcase \";$cloned_modules;\" in\n> > >  \t\t\t*\";$name;\"*)\n> > >  \t\t\t\t# then there is no local change to integrate\n> > > -\t\t\t\tupdate_module= ;;\n> > > +\t\t\t\tif test -n \"$branch\"; then\n> > > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> > \n> > Does that not put the user in danger of loosing changes?\n> \n> No, because this is only happens for just-cloned modules.  The user\n> hasn't had time to make local changes yet.\n\nAh ok I see. But why the reset then? Doesn't the earlier git checkout in your\npatch take care of checking out the branch and thus update to the right\nrevision?\n\n> > If submodule.<name>.branch is configured:\n> > \n> > \tgit submodule update\n> > \n> > will checkout the configured branch instead of the sha1?\n> \n> The use case described by Francesco, a submodule maintainer Alice sets\n> up the submodule, which downstream developer Bob want to checkout to a\n> branch.  I think that matching the exact commit specified by Alice in\n> Bob's checkout is important, even if the upstream developer Charlie\n> has advanced the referenced branch in the meantime.  Shifting the\n> referenced submodule commit should be an explicit decision made by\n> Alice, not a clone-time accident for Bob.\n\nBut from what I understand of this part of Francesco's use-case description:\n\n> # Developer\n> $ git pull\n> $ git submodule init\n> $ git submodule update --remote\n> $ cd <path>\n> $ branch=\"$(git config -f ..\\.gitmodules submodule.common.branch)\"; git checkout $branch\n\nIs that he wants to allow the developer to switch to following a branch instead\nof an exact sha1 while some extension in the common module is still under\ndevelopment. That makes it easier to develop in parallel in the submodule and\nthe superproject because you do not need to update the sha1 all the time.\n\nE.g. its likely that changes have to be reviewed and cleaned up in the\nsubmodule first until they can be merged to the master branch there. During\nthis time the developer follows the branch.\nOnce the submodule review is finished the superproject branch can switch back\nto the exact model again (because the submodule will not change anymore) and\nfinish its implementation there.\n\nMatching the exact commit and checking out the branch only if it points to that\nexact commit does not really help the developer in this use-case. But I am only\nguessing from my experience with development of features in submodule.\n\nCheers Heiko\n"},{"id":"232655","messageId":"20140105010859.GD3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140105003922.GA21772@sandbox-ub","subject":"Re: [PATCH] submodule: Respect reqested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-05T01:08:59Z","receivedAt":"2014-01-05T01:08:59Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 01:39:22AM +0100, Heiko Voigt wrote:\n> On Sat, Jan 04, 2014 at 02:54:01PM -0800, W. Trevor King wrote:\n> > On Sat, Jan 04, 2014 at 11:09:15PM +0100, Heiko Voigt wrote:\n> > > On Fri, Jan 03, 2014 at 10:06:11AM -0800, W. Trevor King wrote:\n> > > > @@ -861,7 +860,12 @@ Maybe you want to use 'update --init'?\")\"\n> > > >  \t\t\tcase \";$cloned_modules;\" in\n> > > >  \t\t\t*\";$name;\"*)\n> > > >  \t\t\t\t# then there is no local change to integrate\n> > > > -\t\t\t\tupdate_module= ;;\n> > > > +\t\t\t\tif test -n \"$branch\"; then\n> > > > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> > > \n> > > Does that not put the user in danger of loosing changes?\n> > \n> > No, because this is only happens for just-cloned modules.  The user\n> > hasn't had time to make local changes yet.\n> \n> Ah ok I see. But why the reset then? Doesn't the earlier git\n> checkout in your patch take care of checking out the branch and thus\n> update to the right revision?\n\nThe reset avoids a detached HEAD.  With an empty $update_module, the\nfollowing case block will setup:\n\n  command=\"git checkout $subforce -q\"\n\nwhich is later called with:\n\n  $command \"$sha1\"\n\nThat's going to give you a detached HEAD.  The new code sets up:\n\n  command=\"git reset --hard -q\"\n\nwhich will keep you on the branch checked out in module_clone().\n\n> > > If submodule.<name>.branch is configured:\n> > > \n> > > \tgit submodule update\n> > > \n> > > will checkout the configured branch instead of the sha1?\n> > \n> > The use case described by Francesco, a submodule maintainer Alice\n> > sets up the submodule, which downstream developer Bob want to\n> > checkout to a branch.  I think that matching the exact commit\n> > specified by Alice in Bob's checkout is important, even if the\n> > upstream developer Charlie has advanced the referenced branch in\n> > the meantime.  Shifting the referenced submodule commit should be\n> > an explicit decision made by Alice, not a clone-time accident for\n> > Bob.\n> \n> But from what I understand of this part of Francesco's use-case\n> description:\n> \n> > # Developer\n> > $ git pull\n> > $ git submodule init\n> > $ git submodule update --remote\n> > $ cd <path>\n> > $ branch=\"$(git config -f ..\\.gitmodules submodule.common.branch)\"; git checkout $branch\n> \n> Is that he wants to allow the developer to switch to following a\n> branch instead of an exact sha1 while some extension in the common\n> module is still under development. That makes it easier to develop\n> in parallel in the submodule and the superproject because you do not\n> need to update the sha1 all the time.\n\nI'll wait for Francesco to clarify his use case.  All my patch does is\nreplace the manual:\n\n  $ cd <path>\n  $ branch=\"$(git config -f ..\\.gitmodules submodule.common.branch)\"; git checkout $branch\n\nwith an automatic (on update):\n\n  $ branch=\"$(git config -f .gitmodules submodule.${name}.branch)\";\n  $ cd \"$path\"\n  $ git checkout -f -q -B \"$branch\" \"origin/$branch\"\n  $ git reset --hard -q \"$sha\"\n\nwhen submodule.<name>.branch is configured.  Whether that last bit is\ndesirable or not is debatable.  If you *do* want to float the\nsubmodule past the commit blessed by Alice, it's easy to add a manual:\n\n  $ git submodule update --remote --rebase \"$path\"\n\nIf we drop the trailing reset (to float the checkout), it's harder to\nrewind to the commit blessed by Alice, because distinguising between:\n\na) locally added stuff that we want to merge/rebase onto Alice's $sha,\n   and\nb) advancements from the automatic float that we *don't* want to\n   merge/rebase onto Alice's $sha.\n\nis difficult/impossible.  If you use the --checkout strategy (there\nare no local commits), you can use:\n\n  $ git submodule update --checkout \"$path\"\n\nbut you'd still need to update the branch references to point to the\nthat particular commit.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232659","messageId":"CALas-ii90x07Kbxzy_siBJV_RHPkvBw7spFBD9vi6o43mU1k6g@mail.gmail.com","threadId":"35584","inReplyTo":"dad947caba9e1c49d691ffccc868cfdce7d04e82.1388772192.git.wking@tremily.us","subject":"Re: [PATCH] submodule: Respect reqested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-05T03:53:12Z","receivedAt":"2014-01-05T03:53:12Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"Thanks for adding your contribute. My comments below:\n\n2014/1/3 W. Trevor King <wking@tremily.us>:\n>\n> The previous code only checked out the requested branch in cmd_add.\n> This commit moves the branch-checkout logic into module_clone, where\n> it can be shared by cmd_add and cmd_update.  I also update the initial\n> checkout command to use 'rebase' to preserve branches setup during\n> module_clone.\n> [...]\n> @@ -306,7 +307,14 @@ module_clone()\n>         echo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n>\n>         rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> -       (clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> +       (\n> +               clear_local_git_env\n> +               cd \"$sm_path\" &&\n> +               GIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> +               if test -n \"$branch\"; then\n> +                       git checkout -f -q -B \"$branch\" \"origin/$branch\" && echo \"checked out $branch\"\n> +               fi\n> +       ) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n>  }\n\nIf I understand it correctly, looking at your intervention in\nmodule_clone and cmd_update, when \"submodule.<module>.branch\" is set\nduring \"update\" the resulting first clone will always be a branch\ncheckout (cause $branch is filled with \"branch\" property). I believe\nthis will break a lot of tests, as the the documentation says that in\nthis configuration the HEAD should be detached. Also it could break\nsome users that rely on the current behavior.\n"},{"id":"232669","messageId":"d0de817dfc687fd943349c9d3e1d410161a0f01e.1388938473.git.wking@tremily.us","threadId":"35584","inReplyTo":"CALas-ii90x07Kbxzy_siBJV_RHPkvBw7spFBD9vi6o43mU1k6g@mail.gmail.com","subject":"[RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-05T16:17:00Z","receivedAt":"2014-01-05T16:17:00Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"From: \"W. Trevor King\" <wking@tremily.us>\n\nThe previous code only checked out the requested branch in cmd_add.\nThis commit moves the branch-checkout logic into module_clone, where\nit can be shared by cmd_add and cmd_update.  I also update the initial\ncheckout command to use 'rebase' to preserve branches setup during\nmodule_clone.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\nChanges since v1:\n* Fix a 'reqested' -> 'requested' typo in the subject/summary.\n* Restore a post-clone 'git checkout -f -q' for the empty-branch case\n  in module_clone().\n* Distinguish between $branch (which defaults to 'master') and a new\n  $config_branch (which defaults to empty) in cmd_update\n\nAfter these fixes, all the existing submodule tests pass.  If we want\nto merge this, we'd still want new tests that demonstrate the new\nfunctionality.\n\nOn Sun, Jan 05, 2014 at 04:53:12AM +0100, Francesco Pretto wrote:\n> If I understand it correctly, looking at your intervention in\n> module_clone and cmd_update, when \"submodule.<module>.branch\" is set\n> during \"update\" the resulting first clone will always be a branch\n> checkout (cause $branch is filled with \"branch\" property).\n\nThat's correct.\n\n> I believe this will break a lot of tests,\n\nThanks for prompting me to run the tests.  This v2 now passes all of\nthe current submodule tests, and the functionality actually matches my\nearlier descriptions of it ;).\n\n> as the the documentation says that in this configuration the HEAD\n> should be detached.\n\nThe current Documentation/git-submodule.txt has:\n\n  update::\n    Update the registered submodules, i.e. clone missing submodules\n    and checkout the commit specified in the index of the containing\n    repository.  This will make the submodules HEAD be detached unless\n    `--rebase` or `--merge` is specified or the key\n    `submodule.$name.update` is set to `rebase`, `merge` or `none`.\n\nIt's not clear if this refers to the initial-clone update, future\npost-clone updates, or both.  Ideally, the behavior should be the\nsame, but in the initial-clone case we don't have an existing\nchecked-out branch to work with.\n\n> Also it could break some users that rely on the current behavior.\n\nThe current code always has a detached HEAD after an initial-clone\nupdate, regardless of submodule.<name>.update, which doesn't match\nthose docs either.  Adding a check to only checkout\nsubmodule.<name>.branch if submodule.<name>.update was 'rebase',\n'merge', or 'none' would be easy, but I don't think that makes much\nsense.  I can't see any reason for folks who specify\nsubmodule.<name>.branch to prefer a detached HEAD over a local branch\nmatching the remote branch's name.  If they prefer checkout updates,\nthe first such update will return them to a detached HEAD.  If they\nprefer merge/rebase updates, future updates will keep them on the same\nbranch.  All my commit does is setup that initial branch for folks who\nget the submodule via 'update', in the same way it's currently setup\nfor folks who get the submodule via 'add'.\n\nCheers,\nTrevor\n\n git-submodule.sh | 34 ++++++++++++++++++++--------------\n 1 file changed, 20 insertions(+), 14 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 2979197..167d4fa 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -253,6 +253,7 @@ module_clone()\n \turl=$3\n \treference=\"$4\"\n \tdepth=\"$5\"\n+\tbranch=\"$6\"\n \tquiet=\n \tif test -n \"$GIT_QUIET\"\n \tthen\n@@ -306,7 +307,15 @@ module_clone()\n \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n \n \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n-\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n+\t(\n+\t\tclear_local_git_env\n+\t\tcd \"$sm_path\" &&\n+\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n+\t\tcase \"$branch\" in\n+\t\t'') git checkout -f -q ;;\n+\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n+\t\tesac\n+\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n }\n \n isnumber()\n@@ -469,16 +478,7 @@ Use -f if you really want to add it.\" >&2\n \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n \t\t\tfi\n \t\tfi\n-\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n-\t\t(\n-\t\t\tclear_local_git_env\n-\t\t\tcd \"$sm_path\" &&\n-\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n-\t\t\tcase \"$branch\" in\n-\t\t\t'') git checkout -f -q ;;\n-\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n-\t\t\tesac\n-\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n+\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$branch\" || exit\n \tfi\n \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n \n@@ -787,7 +787,8 @@ cmd_update()\n \t\tfi\n \t\tname=$(module_name \"$sm_path\") || exit\n \t\turl=$(git config submodule.\"$name\".url)\n-\t\tbranch=$(get_submodule_config \"$name\" branch master)\n+\t\tconfig_branch=$(get_submodule_config \"$name\" branch)\n+\t\tbranch=\"${config_branch:-master}\"\n \t\tif ! test -z \"$update\"\n \t\tthen\n \t\t\tupdate_module=$update\n@@ -815,7 +816,7 @@ Maybe you want to use 'update --init'?\")\"\n \n \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n \t\tthen\n-\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n+\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$config_branch\" || exit\n \t\t\tcloned_modules=\"$cloned_modules;$name\"\n \t\t\tsubsha1=\n \t\telse\n@@ -861,7 +862,12 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module= ;;\n+\t\t\t\tif test -n \"$config_branch\"; then\n+\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n+\t\t\t\telse\n+\t\t\t\t\tupdate_module=\n+\t\t\t\tfi\n+\t\t\t\t;;\n \t\t\tesac\n \n \t\t\tmust_die_on_failure=\n-- \n1.8.4.100.gd81c160.dirty\n"},{"id":"232670","messageId":"20140105194850.GA2994@book.hvoigt.net","threadId":"35584","inReplyTo":"d0de817dfc687fd943349c9d3e1d410161a0f01e.1388938473.git.wking@tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-05T19:48:50Z","receivedAt":"2014-01-05T19:48:50Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Sun, Jan 05, 2014 at 08:17:00AM -0800, W. Trevor King wrote:\n> From: \"W. Trevor King\" <wking@tremily.us>\n> \n> The previous code only checked out the requested branch in cmd_add.\n> This commit moves the branch-checkout logic into module_clone, where\n> it can be shared by cmd_add and cmd_update.  I also update the initial\n> checkout command to use 'rebase' to preserve branches setup during\n> module_clone.\n> \n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n> Changes since v1:\n> * Fix a 'reqested' -> 'requested' typo in the subject/summary.\n> * Restore a post-clone 'git checkout -f -q' for the empty-branch case\n>   in module_clone().\n> * Distinguish between $branch (which defaults to 'master') and a new\n>   $config_branch (which defaults to empty) in cmd_update\n> \n> After these fixes, all the existing submodule tests pass.  If we want\n> to merge this, we'd still want new tests that demonstrate the new\n> functionality.\n\nI think this patch is going in the right direction. Making add() and\nupdate() do the same is the right thing to do.\n\nI would still like a complete description of Francesco's use case\nthough. Francesco: Could you give us a short description about what\nexactly is your use-case? And please ignore all technical details how we\nare going to implement this. I would like to know how, in an ideal\nworld, you would expect git to behave. Do you really only care about\n\n\tgit submodule add\n\nand the *initial*\n\n\tgit submodule update\n\n?\n\nWhat happens if a developer already has the submodule and wants to work\non a feature?\n\n> On Sun, Jan 05, 2014 at 04:53:12AM +0100, Francesco Pretto wrote:\n> > If I understand it correctly, looking at your intervention in\n> > module_clone and cmd_update, when \"submodule.<module>.branch\" is set\n> > during \"update\" the resulting first clone will always be a branch\n> > checkout (cause $branch is filled with \"branch\" property).\n> \n> That's correct.\n> \n> > I believe this will break a lot of tests,\n> \n> Thanks for prompting me to run the tests.  This v2 now passes all of\n> the current submodule tests, and the functionality actually matches my\n> earlier descriptions of it ;).\n> \n> > as the the documentation says that in this configuration the HEAD\n> > should be detached.\n> \n> The current Documentation/git-submodule.txt has:\n> \n>   update::\n>     Update the registered submodules, i.e. clone missing submodules\n>     and checkout the commit specified in the index of the containing\n>     repository.  This will make the submodules HEAD be detached unless\n>     `--rebase` or `--merge` is specified or the key\n>     `submodule.$name.update` is set to `rebase`, `merge` or `none`.\n> \n> It's not clear if this refers to the initial-clone update, future\n> post-clone updates, or both.  Ideally, the behavior should be the\n> same, but in the initial-clone case we don't have an existing\n> checked-out branch to work with.\n\nI do not think that its actually important to end up with a detached\nHEAD. The documentation just states it because in most cases there is no\nother option. But I do not think anything will break if a branch points\nto the exact sha1 we would checkout and we checkout the branch instead.\n\n> > Also it could break some users that rely on the current behavior.\n> \n> The current code always has a detached HEAD after an initial-clone\n> update, regardless of submodule.<name>.update, which doesn't match\n> those docs either.  Adding a check to only checkout\n> submodule.<name>.branch if submodule.<name>.update was 'rebase',\n> 'merge', or 'none' would be easy, but I don't think that makes much\n> sense.  I can't see any reason for folks who specify\n> submodule.<name>.branch to prefer a detached HEAD over a local branch\n> matching the remote branch's name.  If they prefer checkout updates,\n> the first such update will return them to a detached HEAD.  If they\n> prefer merge/rebase updates, future updates will keep them on the same\n> branch.  All my commit does is setup that initial branch for folks who\n> get the submodule via 'update', in the same way it's currently setup\n> for folks who get the submodule via 'add'.\n\nI like your goal of putting this logic into one place. But a few things\nstill could be improved IMO.\n\n>  git-submodule.sh | 34 ++++++++++++++++++++--------------\n>  1 file changed, 20 insertions(+), 14 deletions(-)\n> \n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 2979197..167d4fa 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -253,6 +253,7 @@ module_clone()\n>  \turl=$3\n>  \treference=\"$4\"\n>  \tdepth=\"$5\"\n> +\tbranch=\"$6\"\n>  \tquiet=\n>  \tif test -n \"$GIT_QUIET\"\n>  \tthen\n> @@ -306,7 +307,15 @@ module_clone()\n>  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n>  \n>  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> +\t(\n> +\t\tclear_local_git_env\n> +\t\tcd \"$sm_path\" &&\n> +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> +\t\tcase \"$branch\" in\n> +\t\t'') git checkout -f -q ;;\n> +\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> +\t\tesac\n> +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n>  }\n>  \n>  isnumber()\n> @@ -469,16 +478,7 @@ Use -f if you really want to add it.\" >&2\n>  \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n>  \t\t\tfi\n>  \t\tfi\n> -\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n> -\t\t(\n> -\t\t\tclear_local_git_env\n> -\t\t\tcd \"$sm_path\" &&\n> -\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n> -\t\t\tcase \"$branch\" in\n> -\t\t\t'') git checkout -f -q ;;\n> -\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> -\t\t\tesac\n> -\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n> +\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$branch\" || exit\n>  \tfi\n>  \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n>  \n> @@ -787,7 +787,8 @@ cmd_update()\n>  \t\tfi\n>  \t\tname=$(module_name \"$sm_path\") || exit\n>  \t\turl=$(git config submodule.\"$name\".url)\n> -\t\tbranch=$(get_submodule_config \"$name\" branch master)\n> +\t\tconfig_branch=$(get_submodule_config \"$name\" branch)\n> +\t\tbranch=\"${config_branch:-master}\"\n>  \t\tif ! test -z \"$update\"\n>  \t\tthen\n>  \t\t\tupdate_module=$update\n> @@ -815,7 +816,7 @@ Maybe you want to use 'update --init'?\")\"\n>  \n>  \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n>  \t\tthen\n> -\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n> +\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$config_branch\" || exit\n\nIn the simple case (update=checkout, no branch specified) with the new\ncheckout branch stuff in module_clone() this code here ends up calling\ncheckout twice.  First for master and then here later with the sha1.\nThis feels a little bit double. I would prefer if we skip the checkout\nin module_clone() if its not necessary.\n\nHow about we move the whole \"what to checkout\"-decision into one place\ninstead of having it in update() and moving it from add() into\nmodule_clone() ?\n\nPreviously there was not much in add() regarding checkout but since it\nseems to grow (and now parts need to be shared between add() and\nupdate()). I would like it if we could move that code into one central\nlocation.\n\n>  \t\t\tcloned_modules=\"$cloned_modules;$name\"\n>  \t\t\tsubsha1=\n>  \t\telse\n> @@ -861,7 +862,12 @@ Maybe you want to use 'update --init'?\")\"\n>  \t\t\tcase \";$cloned_modules;\" in\n>  \t\t\t*\";$name;\"*)\n>  \t\t\t\t# then there is no local change to integrate\n> -\t\t\t\tupdate_module= ;;\n> +\t\t\t\tif test -n \"$config_branch\"; then\n> +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n\nIf we get here the checkout has already been done. Shouldn't this rather\nspecify a noop. I.E. like\n\n\tupdate_module=\"!true\"\n\n?\n\nCheers Heiko\n"},{"id":"232675","messageId":"20140105212458.GG3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140105194850.GA2994@book.hvoigt.net","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-05T21:24:58Z","receivedAt":"2014-01-05T21:24:58Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 08:48:50PM +0100, Heiko Voigt wrote:\n> On Sun, Jan 05, 2014 at 08:17:00AM -0800, W. Trevor King wrote:\n> > It's not clear if this refers to the initial-clone update, future\n> > post-clone updates, or both.  Ideally, the behavior should be the\n> > same, but in the initial-clone case we don't have an existing\n> > checked-out branch to work with.\n> \n> I do not think that its actually important to end up with a detached\n> HEAD. The documentation just states it because in most cases there\n> is no other option. But I do not think anything will break if a\n> branch points to the exact sha1 we would checkout and we checkout\n> the branch instead.\n\nThere's no \"if the remote-tracking branch points to the exact sha1\"\nlogic in my patch.  If submodule.<name>.branch is set, it *always*\ncreates a new local branch of that name pointing to the exact sha1.\nIf submodule.<name>.branch is not set, we still create a detached-HEAD\ncheckout of the exact sha1.  Thinking through this more, perhaps the\nlogic should be:\n\n* If submodule.<name>.update (defaulting to checkout) is checkout,\n  create a detached HEAD.\n* Otherwise, create a new branch submodule.<name>.branch (defaulting\n  to master).\n\nThe motivation is that if submodule.<name>.update is checkout, the\nuser is unlikely to be developing locally in the submodule, as\nsubsequent updates would clobber their local commits.  Having a\ndetached HEAD is a helpful \"don't develop here\" reminder ;).  If\nsubmodule.<name>.update is set, the user is likely to be developing\nlocally, and will probably want a local branch already checked out to\nfacilitate that.\n\n> > -\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n> > +\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$config_branch\" || exit\n> \n> In the simple case (update=checkout, no branch specified) with the\n> new checkout branch stuff in module_clone() this code here ends up\n> calling checkout twice.  First for master and then here later with\n> the sha1.  This feels a little bit double.\n\nThere is no guarantee that the remote master and the exact sha1 point\nat the same commit.  Ideally we'd just clone the exact sha1 in this\ncase.\n\n> I would prefer if we skip the checkout in module_clone() if its not\n> necessary.\n\nWhen I tried to drop the '' case here:\n\n> > @@ -306,7 +307,15 @@ module_clone()\n> >  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n> >  \n> >  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> > -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> > +\t(\n> > +\t\tclear_local_git_env\n> > +\t\tcd \"$sm_path\" &&\n> > +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> > +\t\tcase \"$branch\" in\n> > +\t\t'') git checkout -f -q ;;\n> > +\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> > +\t\tesac\n> > +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n> >  }\n\nI got test-suite errors that I didn't get to the bottom of.  However…\n\n> How about we move the whole \"what to checkout\"-decision into one place\n> instead of having it in update() and moving it from add() into\n> module_clone() ?\n\n…this sounds like a good idea to me.  However, it would be a more\nintrusive change, and there may be conflicts with Francesco's proposed\nattach/detach functionality.  I'll wait until we have a clearer idea\nof where that is headed before I attempt a more complete\nconsolidation.\n\n> > -\t\t\t\tupdate_module= ;;\n> > +\t\t\t\tif test -n \"$config_branch\"; then\n> > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> \n> If we get here the checkout has already been done. Shouldn't this\n> rather specify a noop. I.E. like\n> \n> \tupdate_module=\"!true\"\n\nWe are on a local branch at this point, but not neccessarily pointing\nat the gitlinked sha1.  The reset here ensures that the new local\nbranch does indeed point at the gitlinked sha1.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232676","messageId":"CALas-ijwb+20dArOGCnZJSqEwU8+ufUpOEktUJ2hAOW_BLpgxw@mail.gmail.com","threadId":"35584","inReplyTo":"d0de817dfc687fd943349c9d3e1d410161a0f01e.1388938473.git.wking@tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-05T21:27:19Z","receivedAt":"2014-01-05T21:27:19Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/5 W. Trevor King <wking@tremily.us>:\n> On Sun, Jan 05, 2014 at 04:53:12AM +0100, Francesco Pretto wrote:\n>> Also it could break some users that rely on the current behavior.\n>\n> The current code always has a detached HEAD after an initial-clone\n> update, regardless of submodule.<name>.update, which doesn't match\n> those docs either.\n\nI perfectly agree with you that the documentation is a bit\ncontradictory with regard to \"update\" command and detached HEAD.\nThat's why it's so hard to add a feature and keep the same spirit of\nthose that coded submodules at first. Also, I think that submodules\ndidn't get much feedback with regards to these pitfalls because many\npeople try to setup them, they see that \"update\" detaches the HEAD and\nthey think \"hmmm, maybe submodules are not what I was looking for\".\n\n> Adding a check to only checkout\n> submodule.<name>.branch if submodule.<name>.update was 'rebase',\n> 'merge', or 'none' would be easy, but I don't think that makes much\n> sense.  I can't see any reason for folks who specify\n> submodule.<name>.branch to prefer a detached HEAD over a local branch\n> matching the remote branch's name.\n\nI think the reason is that it still matches the original use case of\nsubmodules devs:\n- the maintainer decides the specific commit developers should have;\n- developers checkout that commit and don't pull (you can't do \"git\npull\" in a detached HEAD);\n- they optionally get the upstream commit from the specified\n\"submodule.<name>.branch\" with \"--remote\". They are still in a\ndetached HEAD and can't do \"git pull\".\n\nMaybe who coded submodules at first was thinking that the best way to\ncontribute to a project is to checkout that repository, and not work\nin the submodule. As said, this works well when the submodule\nrepository is a full project, and not a bunch of shared code.\n\n> If they prefer checkout updates,\n> the first such update will return them to a detached HEAD.  If they\n> prefer merge/rebase updates, future updates will keep them on the same\n> branch.  All my commit does is setup that initial branch for folks who\n> get the submodule via 'update', in the same way it's currently setup\n> for folks who get the submodule via 'add'.\n>\n\nMy patch is in the same spirit but wants to obtain the same by being\n100% additive and by not altering existing behavior in any way. Also\nit covers:\n- an \"autoremote\" behavior when the user wants an attached HEAD: with\nyour patch \"--remote\" is still needed to really update the branch with\n\"git submodule update\":\n- voluntary reattach/detach the HEAD with command line;\n- ff-only merge of changes in the case of \"checkout\" in an attached\nHEAD (doing \"git checkout <branch>\" is not enough);\n- reattach of the HEAD with orphaned commits.\n\nUnfortunately our patches are already a bit colliding. I'll wait for\nother comments from git maintainers and let see. Anyway, I'm happy\nbecause things are moving: after this debate git submodules will be\nbetter for sure.\n\nCheers,\nFrancesco\n"},{"id":"232678","messageId":"20140105214752.GH3156@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-ijwb+20dArOGCnZJSqEwU8+ufUpOEktUJ2hAOW_BLpgxw@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-05T21:47:52Z","receivedAt":"2014-01-05T21:47:52Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 10:27:19PM +0100, Francesco Pretto wrote:\n> 2014/1/5 W. Trevor King:\n> > Adding a check to only checkout submodule.<name>.branch if\n> > submodule.<name>.update was 'rebase', 'merge', or 'none' would be\n> > easy, but I don't think that makes much sense.  I can't see any\n> > reason for folks who specify submodule.<name>.branch to prefer a\n> > detached HEAD over a local branch matching the remote branch's\n> > name.\n> \n> I think the reason is that it still matches the original use case of\n> submodules devs:\n> - the maintainer decides the specific commit developers should have;\n> - developers checkout that commit and don't pull (you can't do \"git\n> pull\" in a detached HEAD);\n> - they optionally get the upstream commit from the specified\n> \"submodule.<name>.branch\" with \"--remote\". They are still in a\n> detached HEAD and can't do \"git pull\".\n> \n> Maybe who coded submodules at first was thinking that the best way to\n> contribute to a project is to checkout that repository, and not work\n> in the submodule. As said, this works well when the submodule\n> repository is a full project, and not a bunch of shared code.\n\nYou're saying that the detached HEAD is a feature because it breaks\npull?  And developers can't be trusted/trained to just not pull\nreflexively?  I'm not buying that ;).  Although I was sad to see\njc/pull-training-wheel dropped and have that discussion stall out [1].\n\n> > If they prefer checkout updates, the first such update will return\n> > them to a detached HEAD.  If they prefer merge/rebase updates,\n> > future updates will keep them on the same branch.  All my commit\n> > does is setup that initial branch for folks who get the submodule\n> > via 'update', in the same way it's currently setup for folks who\n> > get the submodule via 'add'.\n> \n> My patch is in the same spirit but wants to obtain the same by being\n> 100% additive and by not altering existing behavior in any way.\n\nMy v2 patch doesn't break the current test suite.  I'd be surprised if\na change in such peripheral existing behavior as the post clone-update\nbranch actually break any user code, but I'd be happy to see links\nthat prove me wrong.\n\n> Also it covers:\n> - an \"autoremote\" behavior when the user wants an attached HEAD:\n> with your patch \"--remote\" is still needed to really update the\n> branch with \"git submodule update\":\n> - voluntary reattach/detach the HEAD with command line;\n> - ff-only merge of changes in the case of \"checkout\" in an attached\n> HEAD (doing \"git checkout <branch>\" is not enough);\n> - reattach of the HEAD with orphaned commits.\n\nPersonally, I don't think autoremote updates are worth the additional\nUI complication (hence my alternative patch ;), but I'm open to\ndiscussion on this point.  Can you make a case for why and explicit\n--remote update is burdensome?\n\nI'm also not entirely clear on the problems avoided or workflows\nenhanced via the last two entries.  Could you sketch an example\nworkflow that makes that more obvious?\n\n> Unfortunately our patches are already a bit colliding. I'll wait for\n> other comments from git maintainers and let see. Anyway, I'm happy\n> because things are moving: after this debate git submodules will be\n> better for sure.\n\n+1.  I floated my patch as a proof-of-concept for my side of this\ndebate, but I'm pretty happy with the current setup, so it's hard for\nme to imagine submodules getting worse as a result of this ;).\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/236372\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232679","messageId":"20140105220124.GI3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140105214752.GH3156@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-05T22:01:24Z","receivedAt":"2014-01-05T22:01:24Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 01:47:52PM -0800, W. Trevor King wrote:\n> On Sun, Jan 05, 2014 at 10:27:19PM +0100, Francesco Pretto wrote:\n> > 2014/1/5 W. Trevor King:\n> > Also it covers:\n> > - an \"autoremote\" behavior when the user wants an attached HEAD:\n> > with your patch \"--remote\" is still needed to really update the\n> > branch with \"git submodule update\":\n> > - voluntary reattach/detach the HEAD with command line;\n> > - ff-only merge of changes in the case of \"checkout\" in an attached\n> > HEAD (doing \"git checkout <branch>\" is not enough);\n> > - reattach of the HEAD with orphaned commits.\n> \n> Personally, I don't think autoremote updates are worth the additional\n> UI complication (hence my alternative patch ;), but I'm open to\n> discussion on this point.  Can you make a case for why and explicit\n> --remote update is burdensome?\n> \n> I'm also not entirely clear on the problems avoided or workflows\n> enhanced via the last two entries.  Could you sketch an example\n> workflow that makes that more obvious?\n\nFor example, your original patch [1] claimed a reduction from:\n\n  # Maintainer\n  $ git submodule add --branch \"master-project1\" <repository> common\n  $ git commit -m \"Added submodule\"\n  $ git config -f .gitmodules submodule.common.ignore all\n  $ git push\n  $ cd <path>\n  $ git checkout \"master-project1\"\n\nto:\n\n  # Maintainer\n  $ git submodule add --branch \"master-project1\" --attach <repository> <path>\n  $ git commit -m \"Added submodule\"\n  $ git push\n\nMy patch does not effect this maintainer flow at all, but I'm pretty\nsure the initial checkout is already automatic:\n\n  $ git --version\n  git version 1.8.3.2\n  $ cd b/\n  $ git init\n  Initialized empty Git repository in /tmp/b/.git/\n  $ git submodule add --branch master ../a\n  Cloning into 'a'...\n  done.\n  Checking connectivity... done\n  $ cd a/\n  $ git branch\n  * master\n\nYou also claimed a reduction from:\n\n  # Developer\n  $ git pull\n  $ git submodule init\n  $ git submodule update --remote\n  $ cd <path>\n  $ branch=\"$(git config -f ..\\.gitmodules submodule.common.branch)\"; git checkout $branch\n\nto:\n\n  # Developer\n  $ git pull\n  $ git submodule init\n  $ git submodule update\n\nMy patch should cover the developer reduction (auto branch checkout on\nthe initial cloning update) without confusing the situation with\nautofloated updates.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/239799\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232680","messageId":"20140105225733.GB4660@book.hvoigt.net","threadId":"35584","inReplyTo":"20140105212458.GG3156@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-05T22:57:33Z","receivedAt":"2014-01-05T22:57:33Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Sun, Jan 05, 2014 at 01:24:58PM -0800, W. Trevor King wrote:\n> On Sun, Jan 05, 2014 at 08:48:50PM +0100, Heiko Voigt wrote:\n> > On Sun, Jan 05, 2014 at 08:17:00AM -0800, W. Trevor King wrote:\n> > > It's not clear if this refers to the initial-clone update, future\n> > > post-clone updates, or both.  Ideally, the behavior should be the\n> > > same, but in the initial-clone case we don't have an existing\n> > > checked-out branch to work with.\n> > \n> > I do not think that its actually important to end up with a detached\n> > HEAD. The documentation just states it because in most cases there\n> > is no other option. But I do not think anything will break if a\n> > branch points to the exact sha1 we would checkout and we checkout\n> > the branch instead.\n> \n> There's no \"if the remote-tracking branch points to the exact sha1\"\n> logic in my patch.\n\nI know I was more referring to the discussion whether detached HEAD for\nsubmodules is important or not.\n\n> If submodule.<name>.branch is set, it *always*\n> creates a new local branch of that name pointing to the exact sha1.\n> If submodule.<name>.branch is not set, we still create a detached-HEAD\n> checkout of the exact sha1.\n\nThanks for this clarification. Since the usual usage with --remote is\nwith a remote-tracking branch, I confused this here. I am not sure\nwhether blindly creating a local branch from the recorded sha1 is the\nright thing to do. In what situations would that be helpful?\n\nAt $dayjob we usually use feature branches for our work. So if someone\nwants to work in a submodule you simply create a branch at the current\nsha1 which you then send out for review.\n\nThe reason why one would set a branch option here is to share the\nsuperproject branch with colleagues. He can make sure they can always\nfetch and checkout the submodule even though the branch there is still\nunder cleanup and thus will be rebased often. The commit referenced by\nsha1 would not be available to a developer fetching after a rebase.\n\n> Thinking through this more, perhaps the\n> logic should be:\n> \n> * If submodule.<name>.update (defaulting to checkout) is checkout,\n>   create a detached HEAD.\n> * Otherwise, create a new branch submodule.<name>.branch (defaulting\n>   to master).\n\nWhy not trigger the attached state with the submodule.<name>.branch\nconfiguration option? If there is a local branch available use that, if\nnot the tracking branch (as it is currently). Then a developer can start\nworking on the branch with:\n\n\tcd submodule; git checkout -t origin/<branchname>\n\nassuming that submodule update learns some more support for this.\n\n> The motivation is that if submodule.<name>.update is checkout, the\n> user is unlikely to be developing locally in the submodule, as\n> subsequent updates would clobber their local commits.  Having a\n> detached HEAD is a helpful \"don't develop here\" reminder ;).  If\n> submodule.<name>.update is set, the user is likely to be developing\n> locally, and will probably want a local branch already checked out to\n> facilitate that.\n> \n> > > -\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n> > > +\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$config_branch\" || exit\n> > \n> > In the simple case (update=checkout, no branch specified) with the\n> > new checkout branch stuff in module_clone() this code here ends up\n> > calling checkout twice.  First for master and then here later with\n> > the sha1.  This feels a little bit double.\n> \n> There is no guarantee that the remote master and the exact sha1 point\n> at the same commit.  Ideally we'd just clone the exact sha1 in this\n> case.\n> \n> > I would prefer if we skip the checkout in module_clone() if its not\n> > necessary.\n> \n> When I tried to drop the '' case here:\n> \n> > > @@ -306,7 +307,15 @@ module_clone()\n> > >  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n> > >  \n> > >  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> > > -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> > > +\t(\n> > > +\t\tclear_local_git_env\n> > > +\t\tcd \"$sm_path\" &&\n> > > +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> > > +\t\tcase \"$branch\" in\n> > > +\t\t'') git checkout -f -q ;;\n> > > +\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> > > +\t\tesac\n> > > +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n> > >  }\n> \n> I got test-suite errors that I didn't get to the bottom of.  However…\n> \n> > How about we move the whole \"what to checkout\"-decision into one place\n> > instead of having it in update() and moving it from add() into\n> > module_clone() ?\n> \n> …this sounds like a good idea to me.  However, it would be a more\n> intrusive change, and there may be conflicts with Francesco's proposed\n> attach/detach functionality.  I'll wait until we have a clearer idea\n> of where that is headed before I attempt a more complete\n> consolidation.\n\nI agree, that would be good.\n\n> > > -\t\t\t\tupdate_module= ;;\n> > > +\t\t\t\tif test -n \"$config_branch\"; then\n> > > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> > \n> > If we get here the checkout has already been done. Shouldn't this\n> > rather specify a noop. I.E. like\n> > \n> > \tupdate_module=\"!true\"\n> \n> We are on a local branch at this point, but not neccessarily pointing\n> at the gitlinked sha1.  The reset here ensures that the new local\n> branch does indeed point at the gitlinked sha1.\n\nBut isn't this a fresh clone? Why should the branch point at anything\nelse?\n\nCheers Heiko\n"},{"id":"232682","messageId":"20140105233943.GJ3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140105225733.GB4660@book.hvoigt.net","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-05T23:39:43Z","receivedAt":"2014-01-05T23:39:43Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 11:57:33PM +0100, Heiko Voigt wrote:\n> On Sun, Jan 05, 2014 at 01:24:58PM -0800, W. Trevor King wrote:\n> > If submodule.<name>.branch is set, it *always* creates a new local\n> > branch of that name pointing to the exact sha1.  If\n> > submodule.<name>.branch is not set, we still create a\n> > detached-HEAD checkout of the exact sha1.\n> \n> Thanks for this clarification. Since the usual usage with --remote\n> is with a remote-tracking branch, I confused this here. I am not\n> sure whether blindly creating a local branch from the recorded sha1\n> is the right thing to do. In what situations would that be helpful?\n\nIn any situation where your going to develop the submodule locally,\nyou're going to want a branch to develop in.  Starting local-submodule\ndevelopers off on a branch seems useful, even if we can only use\nsubmodule.<name>.branch to guess at their preferred local branch name.\nSometimes (often?) the guess will be right.  However, A detached HEAD\nwill never be right for local development, so being right sometimes is\nstill an improvement ;).\n\n> At $dayjob we usually use feature branches for our work. So if\n> someone wants to work in a submodule you simply create a branch at\n> the current sha1 which you then send out for review.\n\nI'm all for named feature branches for development, and in this case\nsubmodule.<name>.branch is likely to be the wrong choice.  However,\nit's still safer to develop in that branch and then rename the branch\nto match your feature than it would be to develop your fix with a\ndetached HEAD.  If your developers have enough discipline to always\ncheckout their feature branch before starting development, my patch\nwon't affect them.  However, I know a number of folks who go into\nfight-or-flight mode when they have a detached HEAD :p.\n\n> The reason why one would set a branch option here is to share the\n> superproject branch with colleagues. He can make sure they can\n> always fetch and checkout the submodule even though the branch there\n> is still under cleanup and thus will be rebased often. The commit\n> referenced by sha1 would not be available to a developer fetching\n> after a rebase.\n\nYeah, floating gitlinks are something else.  I'd be happy to have that\nfunctionality (gitlinks pointing to references) should be built into\ngitlinks themselves, not added as an additional layer in the submodule\nscript.  This \"gitlinked sha1 rebased out of existence\" scenario is\nthe first I've heard where I think gitlinked references would be\nuseful.\n\n> > Thinking through this more, perhaps the logic should be:\n> > \n> > * If submodule.<name>.update (defaulting to checkout) is checkout,\n> >   create a detached HEAD.\n> > * Otherwise, create a new branch submodule.<name>.branch\n> >   (defaulting to master).\n> \n> Why not trigger the attached state with the submodule.<name>.branch\n> configuration option? If there is a local branch available use that,\n> if not the tracking branch (as it is currently). Then a developer\n> can start working on the branch with:\n> \n> \tcd submodule; git checkout -t origin/<branchname>\n> \n> assuming that submodule update learns some more support for this.\n\nIsn't that already what 'git update --remote <submodule>' already\ndoes?\n\n> > > > -\t\t\t\tupdate_module= ;;\n> > > > +\t\t\t\tif test -n \"$config_branch\"; then\n> > > > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> > > \n> > > If we get here the checkout has already been done. Shouldn't\n> > > this rather specify a noop. I.E. like\n> > > \n> > > \tupdate_module=\"!true\"\n> > \n> > We are on a local branch at this point, but not neccessarily\n> > pointing at the gitlinked sha1.  The reset here ensures that the\n> > new local branch does indeed point at the gitlinked sha1.\n> \n> But isn't this a fresh clone? Why should the branch point at\n> anything else?\n\nWe don't pass $sha1 to module_clone().  Before my patch, we don't even\npass $branch to module_clone().  That means that module_clone() will\nonly checkout the gitlinked sha1 when the upstream HEAD (or $branch\nwith my patch) happens to point to the gitlinked sha1.  For example,\nif Alice adds Charie's repo as a submodule (gitlinking his current\nmaster d2dbd39), then Charlie pushes a new commit d0de817 to his\nmaster, and then Bob clones Alice's superproject.  Post-clone,\nCharlie's submodule will have checked out Charlie's new d0de817, and\nwe need update's additional:\n\n  git reset --hard -q d2dbd39\n\nto rewind to Alice's gitlinked sha1.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232686","messageId":"20140106003314.GL3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140105233943.GJ3156@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-06T00:33:14Z","receivedAt":"2014-01-06T00:33:14Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 03:39:43PM -0800, W. Trevor King wrote:\n> On Sun, Jan 05, 2014 at 11:57:33PM +0100, Heiko Voigt wrote:\n> > The reason why one would set a branch option here is to share the\n> > superproject branch with colleagues. He can make sure they can\n> > always fetch and checkout the submodule even though the branch there\n> > is still under cleanup and thus will be rebased often. The commit\n> > referenced by sha1 would not be available to a developer fetching\n> > after a rebase.\n> \n> Yeah, floating gitlinks are something else.  I'd be happy to have\n> that functionality (gitlinks pointing to references) be built into\n> gitlinks themselves, not added as an additional layer in the\n> submodule script.  This \"gitlinked sha1 rebased out of existence\"\n> scenario is the first I've heard where I think gitlinked references\n> would be useful.\n\nOn the other hand, if the subproject has such a rebase, a superproject\ndev can hop into an existing checkout, update around the rebase, add a\nsuperproject commit with the fixed sha1, and push that for other\nsuperproject devs.  The only people who would need *automatic* rebase\nrecovery would be superproject devs update-cloning the subproject.\nThat's a small enough cross-section that I don't think it deserves the\nambiguity of gitlink-to-reference.  In that case, all you really need\nis a way to force a recovery gitlink (i.e. add a 'commit' object to\nthe tree by hand).\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232687","messageId":"20140106011255.GM3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140106003314.GL3156@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-06T01:12:56Z","receivedAt":"2014-01-06T01:12:56Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 05, 2014 at 04:33:14PM -0800, W. Trevor King wrote:\n> The only people who would need *automatic* rebase recovery would be\n> superproject devs update-cloning the subproject.  That's a small\n> enough cross-section that I don't think it deserves the ambiguity of\n> gitlink-to-reference.  In that case, all you really need is a way to\n> force a recovery gitlink (i.e. add a 'commit' object to the tree by\n> hand).\n\nActually, you recovering by hand is a lot easier.  Setup a\nrebased-away gitlink target:\n\n  mkdir subproject &&\n  (\n    cd subproject &&\n    git init\n    echo 'Subproject' > README &&\n    git add README &&\n    git commit -m 'Subproject v1' &&\n    echo 'Changes' >> README &&\n    git commit -am 'Subproject v2'\n  ) &&\n  mkdir superproject &&\n  (\n    cd superproject &&\n    git init\n    git submodule add ../subproject &&\n    git commit -m 'Superproject v1'\n  ) &&\n  (\n    cd subproject &&\n    git reset --hard HEAD^ &&\n    git reflog expire --expire=now --all &&\n    git gc --aggressive --prune=now\n  )\n\nThen a recursive clone of the superproject dies:\n\n  $ git clone --recursive superproject super2\n  Cloning into 'super2'...\n  done.\n  Submodule 'subproject' (/tmp/x/subproject) registered for path 'subproject'\n  Cloning into 'subproject'...\n  done.\n  fatal: reference is not a tree: f589144d16282d1a80d17a9032c6f1d332e38dd0\n  Unable to checkout 'f589144d16282d1a80d17a9032c6f1d332e38dd0' in submodule path 'subproject'\n\nBut you still have the submodule checkout (up until the $sha1 setup):\n\n  $ cd super2\n  $ git diff\n  diff --git a/subproject b/subproject\n  index f589144..82d4553 160000\n  --- a/subproject\n  +++ b/subproject\n  @@ -1 +1 @@\n  -Subproject commit f589144d16282d1a80d17a9032c6f1d332e38dd0\n  +Subproject commit 82d4553fe437ae014f22bbc87a082c6d19e5d9f9-dirty\n\nAnd you can automatically update to match the upstream remote:\n\n  $ git submodule update --remote --force\n  Submodule path 'subproject': checked out '82d4553fe437ae014f22bbc87a082c6d19e5d9f9'\n  $ git diff\n  diff --git a/subproject b/subproject\n  index f589144..82d4553 160000\n  --- a/subproject\n  +++ b/subproject\n  @@ -1 +1 @@\n  -Subproject commit f589144d16282d1a80d17a9032c6f1d332e38dd0\n  +Subproject commit 82d4553fe437ae014f22bbc87a082c6d19e5d9f9\n\nWhen explicitly updating to the superproject or subproject's\n(--remote) new tip is so easy, I don't see a need for floating the\ngitlinks themselves.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232714","messageId":"20140106144708.GC27265@t2784.greatnet.de","threadId":"35584","inReplyTo":"CALas-ijwb+20dArOGCnZJSqEwU8+ufUpOEktUJ2hAOW_BLpgxw@mail.gmail.com","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-06T14:47:08Z","receivedAt":"2014-01-06T14:47:08Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Sun, Jan 05, 2014 at 10:27:19PM +0100, Francesco Pretto wrote:\n> 2014/1/5 W. Trevor King <wking@tremily.us>:\n> > On Sun, Jan 05, 2014 at 04:53:12AM +0100, Francesco Pretto wrote:\n> >> Also it could break some users that rely on the current behavior.\n> >\n> > The current code always has a detached HEAD after an initial-clone\n> > update, regardless of submodule.<name>.update, which doesn't match\n> > those docs either.\n> \n> I perfectly agree with you that the documentation is a bit\n> contradictory with regard to \"update\" command and detached HEAD.\n> That's why it's so hard to add a feature and keep the same spirit of\n> those that coded submodules at first. Also, I think that submodules\n> didn't get much feedback with regards to these pitfalls because many\n> people try to setup them, they see that \"update\" detaches the HEAD and\n> they think \"hmmm, maybe submodules are not what I was looking for\".\n\nI am not so sure about that. Why should detached HEAD make you think\nlike that? For us at $dayjob we have a pre-commit hook that denies you\nto commit on a detached HEAD and asks you to create a branch first.\n\nYou then work on that branch and send it out for review. If the reviewer\nis happy he merges it into a stable branch (master most times) of the\nsubmodule. Only revisions that are on a stable branch in a submodule are\nallowed to be linked in a superprojects branch that should be merged.\n\nBefore the submodule's branch gets merged we usually track the\ndevelopment branches sha1 of the submodule in the superproject. For\ncleanup in the submodule I currently use fixup! commits most times so\nthe referenced sha1 is not lost. In the very end when everyone is happy\nwith the submodule change I rebase, change the referenced sha1 in the\nsuperproject and send the final branch out for review another time.\n\n> > Adding a check to only checkout\n> > submodule.<name>.branch if submodule.<name>.update was 'rebase',\n> > 'merge', or 'none' would be easy, but I don't think that makes much\n> > sense.  I can't see any reason for folks who specify\n> > submodule.<name>.branch to prefer a detached HEAD over a local branch\n> > matching the remote branch's name.\n> \n> I think the reason is that it still matches the original use case of\n> submodules devs:\n> - the maintainer decides the specific commit developers should have;\n\nNope. We usually do not have a maintainer. We use a review based\nworkflow. Everyone is allowed to review. If you develop you need to send\nyou changes to a reviewer first who then merges when he is ok with it.\n\n> - developers checkout that commit and don't pull (you can't do \"git\n> pull\" in a detached HEAD);\n\nExactly. We consider pull evil ;-) Seriously: To update we only do fast\nforward merges of local stable branches. Only reviewers or maintainers\nare allowed to merge and push into stable branches. Direct commits to\nstable branches are forbidden.\n\nTo review we have a shortcut to update the stable branch in git gui\nfor which the code can be found on my github[1].\n\n> - they optionally get the upstream commit from the specified\n> \"submodule.<name>.branch\" with \"--remote\". They are still in a\n> detached HEAD and can't do \"git pull\".\n\nYes, why would you do a git pull in a submodule? Don't you want to do\nsomething like\n\n\tgit checkout -t -b dev/my-topic origin/master\n\nto start your development?\n\n> Maybe who coded submodules at first was thinking that the best way to\n> contribute to a project is to checkout that repository, and not work\n> in the submodule. As said, this works well when the submodule\n> repository is a full project, and not a bunch of shared code.\n\nWhy not work in the submodule? See explanation above.\n\nCheers Heiko\n\n\n[1] https://github.com/hvoigt/git/commits/hv/gui-improvements\n"},{"id":"232719","messageId":"20140106154739.GD27265@t2784.greatnet.de","threadId":"35584","inReplyTo":"20140105233943.GJ3156@odin.tremily.us","subject":"Re: Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-06T15:47:39Z","receivedAt":"2014-01-06T15:47:39Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Sun, Jan 05, 2014 at 03:39:43PM -0800, W. Trevor King wrote:\n> On Sun, Jan 05, 2014 at 11:57:33PM +0100, Heiko Voigt wrote:\n> > On Sun, Jan 05, 2014 at 01:24:58PM -0800, W. Trevor King wrote:\n> > > If submodule.<name>.branch is set, it *always* creates a new local\n> > > branch of that name pointing to the exact sha1.  If\n> > > submodule.<name>.branch is not set, we still create a\n> > > detached-HEAD checkout of the exact sha1.\n> > \n> > Thanks for this clarification. Since the usual usage with --remote\n> > is with a remote-tracking branch, I confused this here. I am not\n> > sure whether blindly creating a local branch from the recorded sha1\n> > is the right thing to do. In what situations would that be helpful?\n> \n> In any situation where your going to develop the submodule locally,\n> you're going to want a branch to develop in.  Starting local-submodule\n> developers off on a branch seems useful, even if we can only use\n> submodule.<name>.branch to guess at their preferred local branch name.\n> Sometimes (often?) the guess will be right.  However, A detached HEAD\n> will never be right for local development, so being right sometimes is\n> still an improvement ;).\n\nStarting developers at a local submodule branch makes sense. But lets\nthink further. What happens after the initial update? Most times the\nsubmodule will already be initialized and cloned. Then developers will\nstill get a detached HEAD even with your local branch feature.\n\nIf there are no changes on it should we advance the local branch\nsomehow on update? If it does not exist anymore should we recreate it?\n\n> > At $dayjob we usually use feature branches for our work. So if\n> > someone wants to work in a submodule you simply create a branch at\n> > the current sha1 which you then send out for review.\n> \n> I'm all for named feature branches for development, and in this case\n> submodule.<name>.branch is likely to be the wrong choice.  However,\n> it's still safer to develop in that branch and then rename the branch\n> to match your feature than it would be to develop your fix with a\n> detached HEAD.  If your developers have enough discipline to always\n> checkout their feature branch before starting development, my patch\n> won't affect them.  However, I know a number of folks who go into\n> fight-or-flight mode when they have a detached HEAD :p.\n\nI agree having an initial branch makes it less likely to loose committed\nchanges. Thats good. Also starting on some local branch name and then\nrenaming the branch sounds quite practical. Then we could recreate the\ndefault local branch on update (like described above).\n\n> > The reason why one would set a branch option here is to share the\n> > superproject branch with colleagues. He can make sure they can\n> > always fetch and checkout the submodule even though the branch there\n> > is still under cleanup and thus will be rebased often. The commit\n> > referenced by sha1 would not be available to a developer fetching\n> > after a rebase.\n> \n> Yeah, floating gitlinks are something else.  I'd be happy to have that\n> functionality (gitlinks pointing to references) should be built into\n> gitlinks themselves, not added as an additional layer in the submodule\n> script.  This \"gitlinked sha1 rebased out of existence\" scenario is\n> the first I've heard where I think gitlinked references would be\n> useful.\n\nYeah I have been thinking about this for quite a while now, but have not\nyet found the time to really think it through and come up with a good\nsolution that does not put you in danger of unprecise revisions. The\nonly solution I can think of is a similar approach as\nsubmodule.<name>.branch gives us now but possibly enabled by some\noption (i.e.: submodule.<name>.remote = true).\nThis way you always get the current tip of development but still see the\ndifferences (which you can choose to commit) in git status.\n\n> > > Thinking through this more, perhaps the logic should be:\n> > > \n> > > * If submodule.<name>.update (defaulting to checkout) is checkout,\n> > >   create a detached HEAD.\n> > > * Otherwise, create a new branch submodule.<name>.branch\n> > >   (defaulting to master).\n> > \n> > Why not trigger the attached state with the submodule.<name>.branch\n> > configuration option? If there is a local branch available use that,\n> > if not the tracking branch (as it is currently). Then a developer\n> > can start working on the branch with:\n> > \n> > \tcd submodule; git checkout -t origin/<branchname>\n> > \n> > assuming that submodule update learns some more support for this.\n> \n> Isn't that already what 'git update --remote <submodule>' already\n> does?\n\nDoes it? As far as I understood (not using the branch option yet) it\nonly does\n\n\tgit checkout origin/<branchname>\n\nso there is no local branch created that tracks the remote branch (-t).\nWhat I was thinking is that when submodule.<name>.branch is set a\n\n\tgit submodule update\n\nwill:\n\n1. if no local branch with that name exists:\n\n   checkout the remote/<branch>\n\n2. If a local branch with that name exists:\n\n   checkout the local branch and possibly advance it according to its\n   setting.\n\nThinking further: Maybe submodule.<name>.update = pull could denote that\na user wants to have a branch ready for work in a submodule. submodule\nupdate will then\n\n1. if no local branch with that name exists:\n\n   - automatically create the branch based on the referenced sha1\n   - set up that its tracking remote/<branch>\n   - issue a git pull in the submodule\n\n2. if a local branch with that name exists:\n\n   - issue a git pull in the submodule\n\nThe superproject will still show if there are any changes in the\nsubmodule (i.e. the sha1 does not match anymore). Even though the user\ncan disable it with submodule.<name>.ignore=all I would advise against\nit.\n\n> > > > > -\t\t\t\tupdate_module= ;;\n> > > > > +\t\t\t\tif test -n \"$config_branch\"; then\n> > > > > +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> > > > \n> > > > If we get here the checkout has already been done. Shouldn't\n> > > > this rather specify a noop. I.E. like\n> > > > \n> > > > \tupdate_module=\"!true\"\n> > > \n> > > We are on a local branch at this point, but not neccessarily\n> > > pointing at the gitlinked sha1.  The reset here ensures that the\n> > > new local branch does indeed point at the gitlinked sha1.\n> > \n> > But isn't this a fresh clone? Why should the branch point at\n> > anything else?\n> \n> We don't pass $sha1 to module_clone().  Before my patch, we don't even\n> pass $branch to module_clone().  That means that module_clone() will\n> only checkout the gitlinked sha1 when the upstream HEAD (or $branch\n> with my patch) happens to point to the gitlinked sha1.  For example,\n> if Alice adds Charie's repo as a submodule (gitlinking his current\n> master d2dbd39), then Charlie pushes a new commit d0de817 to his\n> master, and then Bob clones Alice's superproject.  Post-clone,\n> Charlie's submodule will have checked out Charlie's new d0de817, and\n> we need update's additional:\n> \n>   git reset --hard -q d2dbd39\n> \n> to rewind to Alice's gitlinked sha1.\n\nAh yeah, sorry I was confusing this with the checkout of remote/<branch>\nhere again. Since I have done that twice already maybe we should be\ncareful about not confusing users with this as well...\n\nAfter wrapping my head around the fact that you want to simply create a\nlocal branch on the referenced sha1 (and hopefully remembering it) I\nstill would like to think a little more about it and let it settle a\nbit.\n\nCheers Heiko\n"},{"id":"232722","messageId":"20140106160202.GE27265@t2784.greatnet.de","threadId":"35584","inReplyTo":"20140106011255.GM3156@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-06T16:02:03Z","receivedAt":"2014-01-06T16:02:03Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Sun, Jan 05, 2014 at 05:12:56PM -0800, W. Trevor King wrote:\n> On Sun, Jan 05, 2014 at 04:33:14PM -0800, W. Trevor King wrote:\n> > The only people who would need *automatic* rebase recovery would be\n> > superproject devs update-cloning the subproject.  That's a small\n> > enough cross-section that I don't think it deserves the ambiguity of\n> > gitlink-to-reference.  In that case, all you really need is a way to\n> > force a recovery gitlink (i.e. add a 'commit' object to the tree by\n> > hand).\n> \n> Actually, you recovering by hand is a lot easier.  Setup a\n> rebased-away gitlink target:\n> \n>   mkdir subproject &&\n>   (\n>     cd subproject &&\n>     git init\n>     echo 'Subproject' > README &&\n>     git add README &&\n>     git commit -m 'Subproject v1' &&\n>     echo 'Changes' >> README &&\n>     git commit -am 'Subproject v2'\n>   ) &&\n>   mkdir superproject &&\n>   (\n>     cd superproject &&\n>     git init\n>     git submodule add ../subproject &&\n>     git commit -m 'Superproject v1'\n>   ) &&\n>   (\n>     cd subproject &&\n>     git reset --hard HEAD^ &&\n>     git reflog expire --expire=now --all &&\n>     git gc --aggressive --prune=now\n>   )\n> \n> Then a recursive clone of the superproject dies:\n> \n>   $ git clone --recursive superproject super2\n>   Cloning into 'super2'...\n>   done.\n>   Submodule 'subproject' (/tmp/x/subproject) registered for path 'subproject'\n>   Cloning into 'subproject'...\n>   done.\n>   fatal: reference is not a tree: f589144d16282d1a80d17a9032c6f1d332e38dd0\n>   Unable to checkout 'f589144d16282d1a80d17a9032c6f1d332e38dd0' in submodule path 'subproject'\n> \n> But you still have the submodule checkout (up until the $sha1 setup):\n> \n>   $ cd super2\n>   $ git diff\n>   diff --git a/subproject b/subproject\n>   index f589144..82d4553 160000\n>   --- a/subproject\n>   +++ b/subproject\n>   @@ -1 +1 @@\n>   -Subproject commit f589144d16282d1a80d17a9032c6f1d332e38dd0\n>   +Subproject commit 82d4553fe437ae014f22bbc87a082c6d19e5d9f9-dirty\n> \n> And you can automatically update to match the upstream remote:\n> \n>   $ git submodule update --remote --force\n>   Submodule path 'subproject': checked out '82d4553fe437ae014f22bbc87a082c6d19e5d9f9'\n>   $ git diff\n>   diff --git a/subproject b/subproject\n>   index f589144..82d4553 160000\n>   --- a/subproject\n>   +++ b/subproject\n>   @@ -1 +1 @@\n>   -Subproject commit f589144d16282d1a80d17a9032c6f1d332e38dd0\n>   +Subproject commit 82d4553fe437ae014f22bbc87a082c6d19e5d9f9\n> \n> When explicitly updating to the superproject or subproject's\n> (--remote) new tip is so easy, I don't see a need for floating the\n> gitlinks themselves.\n\nI agree. If we were to support this more easily we could add a\nconfiguration option so you can omit the --remote (i.e.:\nsubmodule.<name>.remote=true, as I also suggested in the other email).\n\nThat way the developer checking out a branch in flight does not even\nneed to know whether (and which) submodules sha1s are still in flight\nand temporarily set this configuration in the branches .gitmodules file.\n\nMaybe that could actually be the attach operation Francesco is\nsuggesting:\n\n\tgit submodule attach [--pull] <submodule path> <branchname>\n\nwill attach the specified submodule to a branch. That means it changes\nthe .gitmodule file accordingly and stages it. With the --pull switch\none can specify whether a local branch tracking the remote branch should\nbe automatically created. Names and the command format are just a\nsuggestion here.\n\nThat way we can support the\n\n\tfork superproject needing submodule changes and send submodule\n\tchanges upstream first.\n\nworkflow. What do you think?\n\nCheers Heiko\n"},{"id":"232727","messageId":"xmqqtxdhjbgp.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"20140106144708.GC27265@t2784.greatnet.de","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-06T16:56:22Z","receivedAt":"2014-01-06T16:56:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Heiko Voigt <hvoigt@hvoigt.net> writes:\n\n> On Sun, Jan 05, 2014 at 10:27:19PM +0100, Francesco Pretto wrote:\n>> 2014/1/5 W. Trevor King <wking@tremily.us>:\n>> > On Sun, Jan 05, 2014 at 04:53:12AM +0100, Francesco Pretto wrote:\n>> >> Also it could break some users that rely on the current behavior.\n>> >\n>> > The current code always has a detached HEAD after an initial-clone\n>> > update, regardless of submodule.<name>.update, which doesn't match\n>> > those docs either.\n>> \n>> I perfectly agree with you that the documentation is a bit\n>> contradictory with regard to \"update\" command and detached HEAD.\n>> That's why it's so hard to add a feature and keep the same spirit of\n>> those that coded submodules at first. Also, I think that submodules\n>> didn't get much feedback with regards to these pitfalls because many\n>> people try to setup them, they see that \"update\" detaches the HEAD and\n>> they think \"hmmm, maybe submodules are not what I was looking for\".\n>\n> I am not so sure about that. Why should detached HEAD make you think\n> like that? For us at $dayjob we have a pre-commit hook that denies you\n> to commit on a detached HEAD and asks you to create a branch first.\n\nPerception is irrational ;-)\n\nWe long-timers think detached is a perfect starting point for both\nusers of submodule who merely want to use the specified commit and\ndevelopers who want to work on the submodule to match the need of\nthe superproject.  The former do not have to do anything, and the\nlatter will have to chdir to the submodule working tree and create a\nbranch (or update the branch with rebase or pull on top of the\nspecified commit) as the first thing before doing anything.\n\nNot everybody is a long-timer, but the saving grace is that nobody\nstays a newcomer.\n\nBUT.\n\n>> - developers checkout that commit and don't pull (you can't do \"git\n>> pull\" in a detached HEAD);\n>\n> Exactly. We consider pull evil ;-) Seriously: To update we only do fast\n> forward merges of local stable branches. \n> ...\n> Yes, why would you do a git pull in a submodule? Don't you want to do\n> something like\n>\n> \tgit checkout -t -b dev/my-topic origin/master\n>\n> to start your development?\n\nAs long as origin/master contains the commit specified by the\nsuperproject, that would work, but it may be a good thing to use a\nmode of submodule.*.update that does not have to drop the user into\na detached state in the first place.  I somehow thought that was\nwhat rebase (or merge) was about, that is, starting from the state\nwhere a branch is checked out in the submodule working tree, an\nupdate in the superproject would cause that branch checked out in\nthe submodule brought up to date with respect to the commit\nspecified in the superproject tree.  If that is not how it is\nsupposed to work, please correct me---and we may have to add another\nmode that does so (or even make rebase/merge do so as a bugfix).\n\nAnd wouldn't it make it unnecessary to have a new \"re-attach\" option\nif such a mode that never have to detach is used?\n"},{"id":"232734","messageId":"20140106172230.GT3156@odin.tremily.us","threadId":"35584","inReplyTo":"20140106154739.GD27265@t2784.greatnet.de","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-06T17:22:30Z","receivedAt":"2014-01-06T17:22:30Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Mon, Jan 06, 2014 at 04:47:39PM +0100, Heiko Voigt wrote:\n> On Sun, Jan 05, 2014 at 03:39:43PM -0800, W. Trevor King wrote:\n> > On Sun, Jan 05, 2014 at 11:57:33PM +0100, Heiko Voigt wrote:\n> > > On Sun, Jan 05, 2014 at 01:24:58PM -0800, W. Trevor King wrote:\n> > > > Thinking through this more, perhaps the logic should be:\n> > > > \n> > > > * If submodule.<name>.update (defaulting to checkout) is checkout,\n> > > >   create a detached HEAD.\n> > > > * Otherwise, create a new branch submodule.<name>.branch\n> > > >   (defaulting to master).\n> > > \n> > > Why not trigger the attached state with the\n> > > submodule.<name>.branch configuration option? If there is a\n> > > local branch available use that, if not the tracking branch (as\n> > > it is currently). Then a developer can start working on the\n> > > branch with:\n> > > \n> > > \tcd submodule; git checkout -t origin/<branchname>\n> > > \n> > > assuming that submodule update learns some more support for this.\n> > \n> > Isn't that already what 'git update --remote <submodule>' already\n> > does?\n> \n> Does it? As far as I understood (not using the branch option yet) it\n> only does\n> \n> \tgit checkout origin/<branchname>\n> \n> so there is no local branch created that tracks the remote branch (-t).\n\nThat's right.  Anyone who wants to do local development in a submodule\nshould probably not be using checkout updates, hence my proposal above\nto base local-branch creation on submodule.<name>.update.\n\n> What I was thinking is that when submodule.<name>.branch is set a\n> \n> \tgit submodule update\n> \n> will:\n> \n> 1. if no local branch with that name exists:\n> \n>    checkout the remote/<branch>\n> \n> 2. If a local branch with that name exists:\n> \n>    checkout the local branch and possibly advance it according to\n>    its setting.\n\nThis sounds too complicated to me ;).\n\n> Thinking further: Maybe submodule.<name>.update = pull could denote\n> that a user wants to have a branch ready for work in a submodule.\n\nThis sounds like my quoted realization above.  We both even preface\nthe idea with \"thinking\" ;).  However, I think merge, rebase,\n!command, and all other non-checkout update schemes are already\nsignals that the developer is interested in local developent (and\ntherefore wants a branch), without the need to add an aditional 'pull'\n(and then how to distinguish between rebase/merge?).\n\n> submodule update will then\n> \n> 1. if no local branch with that name exists:\n> \n>    - automatically create the branch based on the referenced sha1\n>    - set up that its tracking remote/<branch>\n\nWith my patch this happens with the initial clone-update (as of v2,\nonly when submodule.<name>.branch is set.  In a hypothetical v3, only\nwhen submodule.<name>.update is not checkout).  I'm not sure we want\nto do this if the user switches to non-checkout updates after the\ninitial cloning update though.  They may actually have work in that\ndetached HEAD that we'd be clobbering.\n\n>    - issue a git pull in the submodule\n\nI think that updating using the gitlinked sha1 (a local update) and\nupdating using the upstream origin/$branch (a --remote update) should\nalways be two distinct events.  Combining them in a single operation\njust complicates the situation.\n\n> 2. if a local branch with that name exists:\n> \n>    - issue a git pull in the submodule\n\nThat's what we already have with submodule.<name>.update as 'merge'.\nThe merged object is either the gitlinked sha1 (a local update) or a\nre-fetched upstream branch tip (a --remote update).\n\n> > > > We are on a local branch at this point, but not neccessarily\n> > > > pointing at the gitlinked sha1.  The reset here ensures that\n> > > > the new local branch does indeed point at the gitlinked sha1.\n> > > \n> > > But isn't this a fresh clone? Why should the branch point at\n> > > anything else?\n> > \n> > We don't pass $sha1 to module_clone().  Before my patch, we don't\n> > even pass $branch to module_clone().  That means that\n> > module_clone() will only checkout the gitlinked sha1 when the\n> > upstream HEAD (or $branch with my patch) happens to point to the\n> > gitlinked sha1.  For example, if Alice adds Charie's repo as a\n> > submodule (gitlinking his current master d2dbd39), then Charlie\n> > pushes a new commit d0de817 to his master, and then Bob clones\n> > Alice's superproject.  Post-clone, Charlie's submodule will have\n> > checked out Charlie's new d0de817, and we need update's\n> > additional:\n> > \n> >   git reset --hard -q d2dbd39\n> > \n> > to rewind to Alice's gitlinked sha1.\n> \n> Ah yeah, sorry I was confusing this with the checkout of\n> remote/<branch> here again. Since I have done that twice already\n> maybe we should be careful about not confusing users with this as\n> well...\n>\n> After wrapping my head around the fact that you want to simply create a\n> local branch on the referenced sha1 (and hopefully remembering it) I\n> still would like to think a little more about it and let it settle a\n> bit.\n\nThe way I keep this straight is:\n\n1. Submodules are links to Git commits (that's how they're stored in\n   the index).\n2. There are two places to look if you want to update the linked\n   commit:\n   a. The superproject's tree (a local updates).\n   b. The remote subproject's current submodule.<name>.branch tip (a\n      --remote update).\n3. There are a number of ways to integrate external updates with your\n   local submodule development.\n   a. checkout: blow away local development\n   b. merge: merge the update into the local branch\n   c. rebase: rebase the local branch onto the update\n   d. !command: do something fancier\n\nWe currently have easy config and command-line switches to select\nbetween 2.a and 2.b, which for me makes extending 1 to support\nfloating branches unnecessary.  Note that we're always updating to a\nreferenced sha1, and there are only two places we can look to find\nthat sha1.\n\nWe also have easy config and command-line switches to select between\n3.a, 3.b, 3.c, and 3.d.\n\nOne thing that's a bit fuzzy is the definition of \"local development\".\nWe're currently treating it as \"any commits leading up to HEAD that\nare not in the update source\", which works well until upstream starts\nrebasing (or rolling back to an earlier release, etc.).  It's hard for\nGit to handle that sort of thing automatically, for all the usual\n\"recovering from upstream rebase\" reasons [1].  I'm fine if we leave\nit up to users to resolve this sort of situation by hand.  Folks with\nlocal work should know what was local, and folks without local work\ncan use a checkout update.\n\nWe're also not doing a great job of setting people up for local\ndevelopment, but that's tricky if they may already have local work.\nMy \"start them on a branch\" patch is not saving anyone a lot of work,\nbut it's a step in that direction.  Doing anything after the initial\ncloning update is going to be much harder, because there's not much\nthat would be unabmiguously helpful.  After all, the current submodule\nimplementation supports my workflows pretty well.\n\nCheers,\nTrevor\n\n[1]: See \"RECOVERING FROM UPSTREAM REBASE\" in git-rebase(1).\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232736","messageId":"20140106173708.GU3156@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqtxdhjbgp.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-06T17:37:08Z","receivedAt":"2014-01-06T17:37:08Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Mon, Jan 06, 2014 at 08:56:22AM -0800, Junio C Hamano wrote:\n> Heiko Voigt <hvoigt@hvoigt.net> writes:\n> > Yes, why would you do a git pull in a submodule? Don't you want to do\n> > something like\n> >\n> > \tgit checkout -t -b dev/my-topic origin/master\n> >\n> > to start your development?\n> \n> As long as origin/master contains the commit specified by the\n> superproject, that would work, but it may be a good thing to use a\n> mode of submodule.*.update that does not have to drop the user into\n> a detached state in the first place.  I somehow thought that was\n> what rebase (or merge) was about, that is, starting from the state\n> where a branch is checked out in the submodule working tree, an\n> update in the superproject would cause that branch checked out in\n> the submodule brought up to date with respect to the commit\n> specified in the superproject tree.\n\nThat is my understanding as well.  In fact, I don't think the\ndetached-HEAD-vs-branch distinction is important here, you can still\nrebase your detached HEAD onto the superproject's referenced commit\n(or origin/$branch with --remote).  This will also work for merge, and\nshould work for well-crafted !commands.\n\n> And wouldn't it make it unnecessary to have a new \"re-attach\" option\n> if such a mode that never have to detach is used?\n\nI think so, but we currently don't have a \"never detached\" route for\nfolks that are cloning submodules via update (instead of via\n'submodule add').  Currently, new clone-updates will always leave you\nwith a detached HEAD (unless you have branch-creation in your update\n!command).  My patch aims to close this detached-HEAD gap, for folks\nwe expect will be doing local development, by creating an initial\nbranch at clone-update time.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232768","messageId":"xmqqsit0hk3f.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"20140106173708.GU3156@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-06T21:32:52Z","receivedAt":"2014-01-06T21:32:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n>> And wouldn't it make it unnecessary to have a new \"re-attach\" option\n>> if such a mode that never have to detach is used?\n>\n> I think so, but we currently don't have a \"never detached\" route for\n> folks that are cloning submodules via update (instead of via\n> 'submodule add').  Currently, new clone-updates will always leave you\n> with a detached HEAD (unless you have branch-creation in your update\n> !command).  My patch aims to close this detached-HEAD gap, for folks\n> we expect will be doing local development, by creating an initial\n> branch at clone-update time.\n\nI am not a submodule expert so I may be missing some other gaps, but\nwhat your change does sounds sensible to me.\n"},{"id":"232781","messageId":"CALas-ijXQFcUHWk-jJrLifqsMHAKo6NNKya+jR6RJGGDXY76hg@mail.gmail.com","threadId":"35584","inReplyTo":"20140106160202.GE27265@t2784.greatnet.de","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-06T23:10:24Z","receivedAt":"2014-01-06T23:10:24Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/6 Heiko Voigt <hvoigt@hvoigt.net>:\n>\n> I agree. If we were to support this more easily we could add a\n> configuration option so you can omit the --remote (i.e.:\n> submodule.<name>.remote=true, as I also suggested in the other email).\n>\n> That way the developer checking out a branch in flight does not even\n> need to know whether (and which) submodules sha1s are still in flight\n> and temporarily set this configuration in the branches .gitmodules file.\n>\n\n\"submodule.<name>.remote\" can be useful but can be added later to aid\nthe current use case.\n\nTo not break the existing behavior what it's really needed here, IMO,\nis a \"submodule.<name>.attached\" property that says two things:\n- at the first clone on \"git submodule update\" stay attached to\n\"submodule.<name>.branch\";\n- implies \"--remote\", as it's the only thing that makes sense when the\nsubmodules are attached.\n\nMy patch at the current unreleased state does exactly this.\n\n> Maybe that could actually be the attach operation Francesco is\n> suggesting:\n>\n>         git submodule attach [--pull] <submodule path> <branchname>\n>\n> will attach the specified submodule to a branch. That means it changes\n> the .gitmodule file accordingly and stages it. With the --pull switch\n> one can specify whether a local branch tracking the remote branch should\n> be automatically created. Names and the command format are just a\n> suggestion here.\n>\n> That way we can support the\n>\n>         fork superproject needing submodule changes and send submodule\n>         changes upstream first.\n>\n\nMy patch didn't do this, as the maintainer can do these things quite\neasily[1] (maintainer is \"cooler\" with respect to other devs :) ), but\nI think it could be good to also have this feature.\n\nThe feature I think that are still needed and you don't mention are:\n- an \"--attached\" switch for the \"add\" command when the maintainer\ncreate the submodule the first time (DONE in patch);\n- a easy way to attach|detach the submodule locally by developer. This should:\n    * fix the head state (DONE in patch);\n    * fix the local .git/config \"submodule.<name>.attached\" property\naccordingly (DONE in patch, unreleased).\n\nI do the latest in the \"update\" command but it seems bad to touch\n.git/config in the \"update\" command...\n\nMaybe we should have a \"git submodule head\" command that does all\nthese things: --attach (for the maintainer), --attach|--detach (for\nthe developer).\n\n[1]\n$ ( cd submodule && git branch newbranch && git push -u origin HEAD)\n$ git config -f .gitmodules submodule.newbranch.branch newbranch\n$ git config -f .gitmodules submodule.newbranch.attached true\n$ git add . && git commit -m \"Forked superproject\" && git push\n"},{"id":"232785","messageId":"CALas-ijNgaTQr77DZw3acypgaJHpDFVnGdq97ECM4zu+CPma0w@mail.gmail.com","threadId":"35584","inReplyTo":"CALas-ijXQFcUHWk-jJrLifqsMHAKo6NNKya+jR6RJGGDXY76hg@mail.gmail.com","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-06T23:32:47Z","receivedAt":"2014-01-06T23:32:47Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/7 Francesco Pretto <ceztko@gmail.com>:\n> To not break the existing behavior what it's really needed here, IMO,\n> is a \"submodule.<name>.attached\" property that says two things:\n> - at the first clone on \"git submodule update\" stay attached to\n> \"submodule.<name>.branch\";\n> - implies \"--remote\", as it's the only thing that makes sense when the\n> submodules are attached.\n>\n\nUnless you decide to go with the proposed approach of Trevor, where\n\"submodule.<name>.branch\" set means attached (if it's not changed:\nthis thread is quite hard to follow...). To this end, Junio could sync\nwith more \"long-timers\" (Heiko?) submodule users/devs to understand if\nthis breaks too much or not.\n"},{"id":"232792","messageId":"CALas-iiuq1GPk4h=2L6eR1CUqacxZ8mTteu1NgBE_NR4Bo0P9Q@mail.gmail.com","threadId":"35584","inReplyTo":"xmqqtxdhjbgp.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-07T00:55:23Z","receivedAt":"2014-01-07T00:55:23Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/6 Junio C Hamano <gitster@pobox.com>:\n>\n> As long as origin/master contains the commit specified by the\n> superproject, that would work, but it may be a good thing to use a\n> mode of submodule.*.update that does not have to drop the user into\n> a detached state in the first place.  I somehow thought that was\n> what rebase (or merge) was about, that is, starting from the state\n> where a branch is checked out in the submodule working tree, an\n> update in the superproject would cause that branch checked out in\n> the submodule brought up to date with respect to the commit\n> specified in the superproject tree.  If that is not how it is\n> supposed to work, please correct me---and we may have to add another\n> mode that does so (or even make rebase/merge do so as a bugfix).\n>\n\nI think the mode you are referring to is actually my\n\"submodule.<name>.attached\" property. As I said to Heiko, the\n\"submodule.<name>.attached\" property says two things:\n- at the first clone on \"git submodule update\" stay attached to\n\"submodule.<name>.branch\";\n- implies \"--remote\", as it's the only thing that makes sense when the\nsubmodules are attached.\n\n> And wouldn't it make it unnecessary to have a new \"re-attach\" option\n> if such a mode that never have to detach is used?\n\nI think the reattach|detach option are still needed (it is debatable\nif we should have something like \"git submodule head\" command or we\ncan keep them in \"git submodule update\") because the user may want to\ndo so and doing it requires things should be really atomic:\n    * fix the head state;\n    * set the local .git/config \"submodule.<name>.attached\" property.\n\nThe \"--attach\" switch also can add a great bonus: it can reintegrate\norphaned commits when reattaching and having a \"update\" mode with\n\"merge\" or \"rebase\". This is already in my patch.\n"},{"id":"232823","messageId":"xmqqlhyrek02.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"d0de817dfc687fd943349c9d3e1d410161a0f01e.1388938473.git.wking@tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-07T18:15:25Z","receivedAt":"2014-01-07T18:15:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> From: \"W. Trevor King\" <wking@tremily.us>\n>\n> The previous code only checked out the requested branch in cmd_add.\n> This commit moves the branch-checkout logic into module_clone, where\n> it can be shared by cmd_add and cmd_update.  I also update the initial\n> checkout command to use 'rebase' to preserve branches setup during\n> module_clone.\n\nI want to see the log message explain the motivation behind it\n(i.e. instead of stopping after saying \"We used to do X, now we do\nY\", but also explain why we consider that Y is better than X).  Here\nis my attempt.\n\n    submodule: respect requested branch on all clones\n\n    The previous code only checked out the requested branch in cmd_add\n    but not in cmd_update; this left the user on a detached HEAD after\n    an update initially cloned, and subsequent updates using rebase or\n    merge mode will kept the HEAD detached, unless the user moved to the\n    desired branch himself.\n\n    Move the branch-checkout logic into module_clone, where it can be\n    shared by cmd_add and cmd_update.  Also update the initial checkout\n    command to use 'rebase' to preserve branches setup during\n    module_clone.  This way, unless the user explicitly asks to work on\n    a detached HEAD, subsequent updates all happen on the specified\n    branch, which matches the end-user expectation much better.\n\n    Signed-off-by: W. Trevor King <wking@tremily.us>\n    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n\nPlease correct me if I misunderstood the intention.\n\nHaving writing all the above and then looking at the patch again, it\nis not immediately obvious to me where you use \"rebase\" when doing\nthe initial checkout, though.\n\n> The current Documentation/git-submodule.txt has:\n>\n>   update::\n>     Update the registered submodules, i.e. clone missing submodules\n>     and checkout the commit specified in the index of the containing\n>     repository.  This will make the submodules HEAD be detached unless\n>     `--rebase` or `--merge` is specified or the key\n>     `submodule.$name.update` is set to `rebase`, `merge` or `none`.\n\nSide note but doesn't Francesco's \"'checkout' is a valid update mode\"\nneed to update this part of the documentation as well?\n\n\n>  git-submodule.sh | 34 ++++++++++++++++++++--------------\n>  1 file changed, 20 insertions(+), 14 deletions(-)\n>\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 2979197..167d4fa 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -253,6 +253,7 @@ module_clone()\n>  \turl=$3\n>  \treference=\"$4\"\n>  \tdepth=\"$5\"\n> +\tbranch=\"$6\"\n>  \tquiet=\n>  \tif test -n \"$GIT_QUIET\"\n>  \tthen\n> @@ -306,7 +307,15 @@ module_clone()\n>  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n>  \n>  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> +\t(\n> +\t\tclear_local_git_env\n> +\t\tcd \"$sm_path\" &&\n> +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> +\t\tcase \"$branch\" in\n> +\t\t'') git checkout -f -q ;;\n> +\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> +\t\tesac\n> +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n>  }\n>  \n>  isnumber()\n> @@ -469,16 +478,7 @@ Use -f if you really want to add it.\" >&2\n>  \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n>  \t\t\tfi\n>  \t\tfi\n> -\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n> -\t\t(\n> -\t\t\tclear_local_git_env\n> -\t\t\tcd \"$sm_path\" &&\n> -\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n> -\t\t\tcase \"$branch\" in\n> -\t\t\t'') git checkout -f -q ;;\n> -\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> -\t\t\tesac\n> -\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n> +\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$branch\" || exit\n>  \tfi\n>  \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n>  \n> @@ -787,7 +787,8 @@ cmd_update()\n>  \t\tfi\n>  \t\tname=$(module_name \"$sm_path\") || exit\n>  \t\turl=$(git config submodule.\"$name\".url)\n> -\t\tbranch=$(get_submodule_config \"$name\" branch master)\n> +\t\tconfig_branch=$(get_submodule_config \"$name\" branch)\n> +\t\tbranch=\"${config_branch:-master}\"\n>  \t\tif ! test -z \"$update\"\n>  \t\tthen\n>  \t\t\tupdate_module=$update\n> @@ -815,7 +816,7 @@ Maybe you want to use 'update --init'?\")\"\n>  \n>  \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n>  \t\tthen\n> -\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n> +\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$config_branch\" || exit\n>  \t\t\tcloned_modules=\"$cloned_modules;$name\"\n>  \t\t\tsubsha1=\n>  \t\telse\n> @@ -861,7 +862,12 @@ Maybe you want to use 'update --init'?\")\"\n>  \t\t\tcase \";$cloned_modules;\" in\n>  \t\t\t*\";$name;\"*)\n>  \t\t\t\t# then there is no local change to integrate\n> -\t\t\t\tupdate_module= ;;\n> +\t\t\t\tif test -n \"$config_branch\"; then\n> +\t\t\t\t\tupdate_module=\"!git reset --hard -q\"\n> +\t\t\t\telse\n> +\t\t\t\t\tupdate_module=\n> +\t\t\t\tfi\n> +\t\t\t\t;;\n>  \t\t\tesac\n>  \n>  \t\t\tmust_die_on_failure=\n"},{"id":"232825","messageId":"xmqqd2k3ejfr.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"CALas-ijNgaTQr77DZw3acypgaJHpDFVnGdq97ECM4zu+CPma0w@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-07T18:27:36Z","receivedAt":"2014-01-07T18:27:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Francesco Pretto <ceztko@gmail.com> writes:\n\n> 2014/1/7 Francesco Pretto <ceztko@gmail.com>:\n>> To not break the existing behavior what it's really needed here, IMO,\n>> is a \"submodule.<name>.attached\" property that says two things:\n>> - at the first clone on \"git submodule update\" stay attached to\n>> \"submodule.<name>.branch\";\n>> - implies \"--remote\", as it's the only thing that makes sense when the\n>> submodules are attached.\n>>\n>\n> Unless you decide to go with the proposed approach of Trevor, where\n> \"submodule.<name>.branch\" set means attached (if it's not changed:\n> this thread is quite hard to follow...). To this end, Junio could sync\n> with more \"long-timers\" (Heiko?) submodule users/devs to understand if\n> this breaks too much or not.\n\nIt is not immediately obvious to me why anybody who specifies the\nsubmodule.*.branch variable to say \"I want _that_ branch\" not to\nwant to be on that branch but in a detached state, so from that\nperspective, submodule.*.attach feels superfluous.\n\nBut I'd mostly defer the design discussion to Heiko (and Jens), WTK\nand you.\n"},{"id":"232827","messageId":"20140107184659.GF11060@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqlhyrek02.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-07T18:47:00Z","receivedAt":"2014-01-07T18:47:00Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 07, 2014 at 10:15:25AM -0800, Junio C Hamano wrote:\n>     submodule: respect requested branch on all clones\n> \n>     The previous code only checked out the requested branch in cmd_add\n>     but not in cmd_update; this left the user on a detached HEAD after\n>     an update initially cloned, and subsequent updates using rebase or\n>     merge mode will kept the HEAD detached, unless the user moved to the\n>     desired branch himself.\n> \n>     Move the branch-checkout logic into module_clone, where it can be\n>     shared by cmd_add and cmd_update.  Also update the initial checkout\n>     command to use 'rebase' to preserve branches setup during\n>     module_clone.  This way, unless the user explicitly asks to work on\n>     a detached HEAD, subsequent updates all happen on the specified\n>     branch, which matches the end-user expectation much better.\n\nThis looks reasonable to me, but there are still changes I'd like to\nmake for a v3 (e.g. using submodule.<name>.update to trigger local\nbranch checkout).  However, I'm currently leaning towards a new 'git\nsubmodule checkout' command with explicit preferred local submodule\nbranches (see [1]).  Maybe this should all wait until Jens rolls out\nhis update implementation [2]?\n\n> Having writing all the above and then looking at the patch again, it\n> is not immediately obvious to me where you use \"rebase\" when doing\n> the initial checkout, though.\n\nIt's used to shift the local branch reference from from the\n(arbitrary) cloned remote branch tip to the explicit submodule $sha1.\nOtherwise the default method for that operation is a HEAD-detaching\n'checkout'. I tried to explain it here [3].\n\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> > The current Documentation/git-submodule.txt has:\n> >\n> >   update::\n> >     Update the registered submodules, i.e. clone missing submodules\n> >     and checkout the commit specified in the index of the containing\n> >     repository.  This will make the submodules HEAD be detached unless\n> >     `--rebase` or `--merge` is specified or the key\n> >     `submodule.$name.update` is set to `rebase`, `merge` or `none`.\n> \n> Side note but doesn't Francesco's \"'checkout' is a valid update mode\"\n> need to update this part of the documentation as well?\n\nThat would be nice.  I don't think his patch changes the docs, and I\ndon't know if mentioning the --checkout option belongs in that patch\nas well, or in a separate fixup ;).\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240097\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240117\n[3]: http://article.gmane.org/gmane.comp.version-control.git/239953\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232830","messageId":"CALas-ihPmJSf9eH0P7Vf28pB4zN_dsa_2=fe+_moZgiP0C3UTA@mail.gmail.com","threadId":"35584","inReplyTo":"xmqqd2k3ejfr.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-07T19:19:49Z","receivedAt":"2014-01-07T19:19:49Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/7 Junio C Hamano <gitster@pobox.com>:\n>> Unless you decide to go with the proposed approach of Trevor, where\n>> \"submodule.<name>.branch\" set means attached (if it's not changed:\n>> this thread is quite hard to follow...). To this end, Junio could sync\n>> with more \"long-timers\" (Heiko?) submodule users/devs to understand if\n>> this breaks too much or not.\n>\n> It is not immediately obvious to me why anybody who specifies the\n> submodule.*.branch variable to say \"I want _that_ branch\" not to\n> want to be on that branch but in a detached state, so from that\n> perspective, submodule.*.attach feels superfluous.\n>\n\nJunio, for what it concerns me I fully support this patch as, IMO, it\nmakes cleaner the role of the property \"submodule.<name>.branch\".\nBecause with my original proposal I decided to go non-breaking Heiko\nand Jens could also take position on this because this patch will\nrepresent a small behavior break.\n\nAlso, and important feature should be added together with this patch:\na way to go \"--remote\" by default on an attached HEAD. This can be\ndone at least in two ways:\n- explicit, non breaking way: add a \"submodule.<name>.remote\"\nproperty. When set to \"true\" it implies \"--remote\" when doing \"git\nsubmodule update\", both on attached and detached HEAD;\n- implicit, breaking way: assume \"--remote\" when doing \"git submodule\nupdate\" on an attached HEAD. I am quite sure this will break a couple\nof submodule tests (I already tried it), probably for marginal\nreasons.\n\nI think this is needed because it makes little sense to having an\nattached HEAD and \"git submodule update\" does nothing.\n\nThank you,\nFrancesco\n"},{"id":"232831","messageId":"xmqqtxdfd2dj.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"20140107184659.GF11060@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-07T19:21:28Z","receivedAt":"2014-01-07T19:21:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> On Tue, Jan 07, 2014 at 10:15:25AM -0800, Junio C Hamano wrote:\n>>     submodule: respect requested branch on all clones\n>> \n>>     The previous code only checked out the requested branch in cmd_add\n>>     but not in cmd_update; this left the user on a detached HEAD after\n>>     an update initially cloned, and subsequent updates using rebase or\n>>     merge mode will kept the HEAD detached, unless the user moved to the\n>>     desired branch himself.\n>> \n>>     Move the branch-checkout logic into module_clone, where it can be\n>>     shared by cmd_add and cmd_update.  Also update the initial checkout\n>>     command to use 'rebase' to preserve branches setup during\n>>     module_clone.  This way, unless the user explicitly asks to work on\n>>     a detached HEAD, subsequent updates all happen on the specified\n>>     branch, which matches the end-user expectation much better.\n>\n> This looks reasonable to me, but there are still changes I'd like to\n> make for a v3 (e.g. using submodule.<name>.update to trigger local\n> branch checkout).  However, I'm currently leaning towards a new 'git\n> submodule checkout' command with explicit preferred local submodule\n> branches (see [1]).  Maybe this should all wait until Jens rolls out\n> his update implementation [2]?\n\nSounds good.  I'll backburner this one, then.\n\n>> Having writing all the above and then looking at the patch again, it\n>> is not immediately obvious to me where you use \"rebase\" when doing\n>> the initial checkout, though.\n>\n> It's used to shift the local branch reference from from the\n> (arbitrary) cloned remote branch tip to the explicit submodule $sha1.\n\nThe objective is not what I was questioning. In the patch I see\n\n\tgit checkout -f -q -B \"$branch\" \"origin/$branch\"\n\nused in the module_clone (which I think makes sense), and then\ncmd_update uses \"git reset --hard -q\" to make sure that the working\ntree matches the commit $sha1 obtained from the superproject's\ngitlink (which may make $branch diverged from origin/$branch, but\nstill I think it makes sense).\n\nBut there is no 'rebase' I can see in the codepath, which was what I\nwas puzzled about.\n"},{"id":"232837","messageId":"20140107194503.GA26583@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-ihPmJSf9eH0P7Vf28pB4zN_dsa_2=fe+_moZgiP0C3UTA@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-07T19:45:03Z","receivedAt":"2014-01-07T19:45:03Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 07, 2014 at 08:19:49PM +0100, Francesco Pretto wrote:\n> 2014/1/7 Junio C Hamano <gitster@pobox.com>:\n> > It is not immediately obvious to me why anybody who specifies the\n> > submodule.*.branch variable to say \"I want _that_ branch\" not to\n> > want to be on that branch but in a detached state, so from that\n> > perspective, submodule.*.attach feels superfluous.\n> \n> Junio, for what it concerns me I fully support this patch as, IMO, it\n> makes cleaner the role of the property \"submodule.<name>.branch\".\n\nNo, submodule.<name>.branch is the name of the remote-tracking branch\nfor 'update --remote'.  In this patch, I'm using it as a hint for the\npreferred local branch name [1], which I now think was a bad idea.\nAfter [2], I think that we should just define the preferred local\nbranch name explicitly (submodule.<name>.local-branch?).\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/239980\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240097\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232839","messageId":"CALas-ihLbODY6idQizsvH-U6OFRnC6e5=WRB6gkJ7SpBJ3VskQ@mail.gmail.com","threadId":"35584","inReplyTo":"20140107194503.GA26583@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-07T19:48:08Z","receivedAt":"2014-01-07T19:48:08Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/7 W. Trevor King <wking@tremily.us>:\n>> Junio, for what it concerns me I fully support this patch as, IMO, it\n>> makes cleaner the role of the property \"submodule.<name>.branch\".\n>\n> No.\n\nTrevor, maybe it was not clear. But I wanted to say:\n\n\" I fully support *Trevor's* patch...\" :)\n"},{"id":"232840","messageId":"20140107195042.GH11060@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqtxdfd2dj.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-07T19:50:42Z","receivedAt":"2014-01-07T19:50:42Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 07, 2014 at 11:21:28AM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> > On Tue, Jan 07, 2014 at 10:15:25AM -0800, Junio C Hamano wrote:\n> >> Having writing all the above and then looking at the patch again, it\n> >> is not immediately obvious to me where you use \"rebase\" when doing\n> >> the initial checkout, though.\n> >\n> > It's used to shift the local branch reference from from the\n> > (arbitrary) cloned remote branch tip to the explicit submodule $sha1.\n> \n> The objective is not what I was questioning. In the patch I see\n> \n> \tgit checkout -f -q -B \"$branch\" \"origin/$branch\"\n> \n> used in the module_clone (which I think makes sense), and then\n> cmd_update uses \"git reset --hard -q\" to make sure that the working\n> tree matches the commit $sha1 obtained from the superproject's\n> gitlink (which may make $branch diverged from origin/$branch, but\n> still I think it makes sense).\n> \n> But there is no 'rebase' I can see in the codepath, which was what I\n> was puzzled about.\n\nAh, thanks.  s/rebase/reset/ in the commit message ;).\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232841","messageId":"CALas-ihyPTt60F_cVM8_D07rkN+gtaD9HdWcPvfx-soN4bFrgg@mail.gmail.com","threadId":"35584","inReplyTo":"CALas-ihPmJSf9eH0P7Vf28pB4zN_dsa_2=fe+_moZgiP0C3UTA@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-07T19:52:07Z","receivedAt":"2014-01-07T19:52:07Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/7 Francesco Pretto <ceztko@gmail.com>:\n> 2014/1/7 Junio C Hamano <gitster@pobox.com>:\n>> It is not immediately obvious to me why anybody who specifies the\n>> submodule.*.branch variable to say \"I want _that_ branch\" not to\n>> want to be on that branch but in a detached state, so from that\n>> perspective, submodule.*.attach feels superfluous.\n>>\n>\n> Junio, for what it concerns me I fully support *this* patch as,\n\nWhere \"this\" patch is Trevor's one, don't get me wrong... :)\n"},{"id":"232878","messageId":"20140107223858.GB10782@sandbox-ub","threadId":"35584","inReplyTo":"20140107194503.GA26583@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-07T22:38:58Z","receivedAt":"2014-01-07T22:38:58Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nHi,\n\nhere my current thoughts in a kind of summary email.\n\nOn Tue, Jan 07, 2014 at 11:45:03AM -0800, W. Trevor King wrote:\n> On Tue, Jan 07, 2014 at 08:19:49PM +0100, Francesco Pretto wrote:\n> > 2014/1/7 Junio C Hamano <gitster@pobox.com>:\n> > > It is not immediately obvious to me why anybody who specifies the\n> > > submodule.*.branch variable to say \"I want _that_ branch\" not to\n> > > want to be on that branch but in a detached state, so from that\n> > > perspective, submodule.*.attach feels superfluous.\n> > \n> > Junio, for what it concerns me I fully support this patch as, IMO, it\n> > makes cleaner the role of the property \"submodule.<name>.branch\".\n> \n> No, submodule.<name>.branch is the name of the remote-tracking branch\n> for 'update --remote'.  In this patch, I'm using it as a hint for the\n> preferred local branch name [1], which I now think was a bad idea.\n> After [2], I think that we should just define the preferred local\n> branch name explicitly (submodule.<name>.local-branch?).\n\nI am not so sure about that. Having an extra value adds more\nconfiguration burden to the user and it also does not help to understand\nhow this feature is supposed to be used.\n\nEven though I was confused in the first place by the remote/local branch\nswitch for this option, after thinking a little bit more about it I\nthink it makes perfect sense to use the branch option as a hint for the\nlocal branch.\n\nLet me explain by an example. Suppose we have the following setup:\n\n1. Fast-forward situation\n\n    superproject      submodule\n\n master PA--------------->A master\n                          |\n                          B origin/master\n\nLets say superproject has submodule.submodule.branch=master and\nsubmodule.submodule.update=merge.\n\nDoing the initial update which clones results in the submodules master\nbranch being set to the sha1 registered in the superproject.\n\nNow an update to the newest master in submodule is straightforward:\n\n$ git submodule update --remote\n\n2. Direct work situation\n\nThe developer start with the same setup as in situation 1 but now\ndirectly starts to work in the submodule and creates commit C.\n\n    superproject      submodule\n\n master PA--------------->A\n                          |\\\n            origin/master B C master\n\n$ git submodule update --remote\n$ git commit -a -m \"update submodule\"\n\ngets him this:\n\n    superproject      submodule\n\n        PA--------------->A\n         |                |\\\n         |  origin/master B C\n         |                |/\n master PB--------------->D master\n\nWhere now both the submodule and the superproject can be directly\npushed. If origin/master in the submodule is tracked by master this is\nactually one command\n\n$ git push --recurse-submodules=on-demand\n\nSo with your (Trevors) patch and reusing submodule.<name>.branch using\nthis kind of direct work in submodules is made easy. And wasn't that\nwhat people always requested? ;-) Well, at least if you do not use\nfeature branches this makes it easy. But I think that is a good start\nmake the simple things easy first. Then we can later discuss the more\ncomplicated ones. It seems to me that is also the case David wants for\nhis emacs/CEDET workflow: Make it easy for the superproject developers\nto directly push out trivial fixes to the submodule.\n\nAnd it also seems to me that is want Francesco wants.\n\nOne thing is missing though (and I think thats where Francesco came\nfrom): What if the developer already has a detached HEAD in the\nsubmodule?\n\nHow does he attach to a branch? For this we need something similar to\nFrancescos attach/detach or Trevors submodule checkout with Junio's checkout\nHEAD~0 from here[1].\n\nI am still undecided how we should call it. Because of my\n\nIdea for feature branch support\n- -------------------------------\n\nFor the branch attaching feature I would also like something that can actually\nmodify .git/config and for me more importantly .gitmodules.\n\nSo e.g. if I want to work on a longer lived feature branch in a submodule which\nI need in a feature branch in the superproject I would do something like this:\n\n$ git submodule checkout --gitmodules --merge -b hv/my-cool-feature\n\nWhich should create a local feature branch hv/my-cool-feature in the submodule,\ncheckout that branch and modify .gitmodules (because of --gitmodules) to have\nsubmodule.<name>.update=merge, submodule.<name>.branch=hv/my-cool-feature and\nstage that to the index.\n\nThis is a temporary setting so everyone who is working together can update\ntheir branches easily. Once finished (with the prove that the big feature in\nthe superproject works) everyone can go and polish the submodule branches,\nget their changes accepted there first, and then the update/branch setting\nlocal for this branch will be dropped. In this workflow these settings never\nenter a stable branch but are still very useful to transport this information\nwhile developing.\n\nJust an idea of a future extension we should keep in mind when designing the\ncommand to attach to a branch. But maybe the command to configure this should\nbe completely independent from checkout. I.e.:\n\ngit submodule checkout - syncs to a possible update/branch\ngit submodule attach   - creates a submodule branch and configures\n\t\t\t update/branch in .git/config or .gitmodules\ngit submodule detach?  - reverse attach\n\nor maybe --attach and --detach in this scenario could be options to checkout?\n\nStill unsure...\n\nCheers Heiko\n\n[1] http://article.gmane.org/gmane.comp.version-control.git/240097\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.14 (GNU/Linux)\n\niEYEARECAAYFAlLMggIACgkQjLR3Aoip+rpoMACgpn4XzDD4CvD+HCi8coIlwueP\ngQUAn1v1BSJ+k8IJT7S/hwtojT+sUmgP\n=GGTX\n-----END PGP SIGNATURE-----\n"},{"id":"232889","messageId":"CALas-ihk6cVfosQ+Ov4QKUcfzvbXrYSonQvsN8Ay1+GTq_Ae-w@mail.gmail.com","threadId":"35584","inReplyTo":"20140107223858.GB10782@sandbox-ub","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-08T00:17:49Z","receivedAt":"2014-01-08T00:17:49Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/7 Heiko Voigt <hvoigt@hvoigt.net>:\n> One thing is missing though (and I think thats where Francesco came\n> from): What if the developer already has a detached HEAD in the\n> submodule?\n>\n> How does he attach to a branch? For this we need something similar to\n> Francescos attach/detach or Trevors submodule checkout with Junio's checkout\n> HEAD~0 from here[1].\n>\n> I am still undecided how we should call it. Because of my\n>\n> Idea for feature branch support\n> - -------------------------------\n>\n> For the branch attaching feature I would also like something that can actually\n> modify .git/config and for me more importantly .gitmodules.\n>\n> So e.g. if I want to work on a longer lived feature branch in a submodule which\n> I need in a feature branch in the superproject I would do something like this:\n>\n> $ git submodule checkout --gitmodules --merge -b hv/my-cool-feature\n>\n\nI said in another thread I said to Junio am not pursuing\n--attach|--detach anymore, but seeing that now everybody seem to be\nexcited about attached HEAD here we are...\n\nHeiko, it's all day I think this syntax: it supports your above \"git\nsubmodule checkout\" and more. Take attention at the feature branch\npart!\n\nNOTE: the following seems to me compatible with Trevor's\n\"submodule.<module>.branch means attached\" patch.\n\ngit submodule head\n================\n\nThe full syntax is the sum of the following ones:\ngit submodule head [-b <branch>] [--attach] [--] [<path>...]\ngit submodule head [-b <branch>] [--attach] --index [--] [<path>...]\ngit submodule head --reset [--] [<path>...]\ngit submodule head --reset --index [--] [<path>...]\n\n(NOTE: --index should be the same as Heiko's above --gitmodules, it\nmeans -> touch .gitmodules)\n\nAll the switches combinations follow, explained:\n\n# Attach the submodule HEAD to <branch>.\n# Also set \".git/config\" 'submodule.<module>.branch' to <branch>\n$ git submodule head -b <branch> --attach <module>\n\n# Attach the submodule HEAD to 'submodule.<module>.branch'.\n# If it does not exists defaults to <remote>/master\n$ git submodule head --attach <module>\n\n# Unset  \".git/config\" 'submodule.<module>.branch'\n# Also attach or detach the HEAD according to what is in \".gitmodules\":\n# with Trevor's patch 'submodule.<module>.branch' set means attached,\n# unset means detached\n$ git submodule head --reset <module>\n\nNOTE: feature branch part!\n\n# Set \".gitmodules\" 'submodule.<module>.branch' to <branch>\n$ git submodule head -b <branch> --attach --index <module>\n\n# Unset \".gitmodules\" 'submodule.<module>.branch'\n$ git submodule head --reset --index <module>\n---------------------------------------------------------------------\n\nAlso note that a --detach switch is not needed with Trevor's patch. To\nresync to a dettached HEAD workflow, when 'submodule.<module>.branch'\nis unset in \".gitmodule\", --reset (without --index) should be enough.\n\nWhat do you think? Better?\n\nThank you,\nFrancesco\n"},{"id":"232890","messageId":"20140108010504.GE26583@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-ihk6cVfosQ+Ov4QKUcfzvbXrYSonQvsN8Ay1+GTq_Ae-w@mail.gmail.com","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-08T01:05:04Z","receivedAt":"2014-01-08T01:05:04Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Wed, Jan 08, 2014 at 01:17:49AM +0100, Francesco Pretto wrote:\n> # Attach the submodule HEAD to <branch>.\n> # Also set \".git/config\" 'submodule.<module>.branch' to <branch>\n> $ git submodule head -b <branch> --attach <module>\n\nI prefer submodule.<name>.local-branch for the submodule's local\nbranch name.  I also prefer 'checkout' to 'head', because 'checkout'\nalready exists in non-submodule Git for switching between local\nbranches.\n\n> # Attach the submodule HEAD to 'submodule.<module>.branch'.\n> # If it does not exists defaults to <remote>/master\n> $ git submodule head --attach <module>\n\nDefaulting to the configured local branch is fine, but I think it\nshould default to 'master' if no local branch is configured.  This\nshould not have anything to do with remote-tracking branches (that's\nwhat 'submodule update' already handles).  I don't understand why\nremote-tracking-branch integration keeps getting mixed up with\nlocal-branch checkout.\n\n> # Unset  \".git/config\" 'submodule.<module>.branch'\n> # Also attach or detach the HEAD according to what is in \".gitmodules\":\n> # with Trevor's patch 'submodule.<module>.branch' set means attached,\n> # unset means detached\n> $ git submodule head --reset <module>\n\nTo me this reads “always detach HEAD” (because it unsets\nsubmodule.<name>.branch, and submodule.<name>.branch unset means\ndetached).  Note that I've moved away from “submodule.<name>.branch\nset means attached” towards “we should set per-superproject-branch\nsubmodule.<name>.local-branch explicitly” [1].\n\n> NOTE: feature branch part!\n> \n> # Set \".gitmodules\" 'submodule.<module>.branch' to <branch>\n> $ git submodule head -b <branch> --attach --index <module>\n> \n> # Unset \".gitmodules\" 'submodule.<module>.branch'\n> $ git submodule head --reset --index <module>\n> ---------------------------------------------------------------------\n\nThese are just manipulating .gitmodules.  I think we also need\nper-superproject-branch configs under the superproject's .git/ for\ndeveloper overrides.\n\n> What do you think? Better?\n\nI don't think so.  To elaborate the idea I sketched out here [2], say\nyou want:\n\n  Superproject branch  Submodule branch  Upstream branch\n  ===================  ================  ===============\n  master               master            master\n  super-feature        master            master\n  my-feature           my-feature        master\n  other-feature        other-feature     other-feature\n\nThat's only going to work with per-superproject-branch configs for\nboth the local and remote branches.  Using the same name for both\nlocal and remote branches does not work.\n\nLet me motivate each of the combinations in the above table:\n\n* master, master, master: The stable trunk.\n* super-feature, master, master: A superproject feature that works\n  with the stock submodule.\n* my-feature, my-feature, master: A superproject feature that needs an\n  improved submodule, but wants to integrate upstream master changes\n  during development.\n* other-feature, other-feature, other-feature: A superproject feature\n  that needs an improved submodule, and wants to integrate\n  other-feature changes that are also being developed upstream.\n\nThe deal-breaker for recycling submodule.<name>.branch to also mean\nthe local branch name is the {my-feature, my-feature, master} case.\nDo we want to force submodule developers to always match the upstream\nname of the feature branch they'd like to integrate with?  What if\nthere is no upstream my-feature branch (and the superproject developer\npushes submodule branches upstream via email)?  Making the local\nbranch name independently configurable avoids these issues with a\nminimal increase in complexity.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240177\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240180\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232891","messageId":"CALas-ihovRi755a0LKLqn4h4P0Y8tPkJjZew91kKzDTiZb9rGA@mail.gmail.com","threadId":"35584","inReplyTo":"20140108010504.GE26583@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-08T02:12:44Z","receivedAt":"2014-01-08T02:12:44Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/8 W. Trevor King <wking@tremily.us>:\n> Note that I've moved away from “submodule.<name>.branch\n> set means attached” towards “we should set per-superproject-branch\n> submodule.<name>.local-branch explicitly” [1].\n>\n\nHonestly, I'm having an hard time to follow this thread. Also, you\ndidn't update the patch. If you were endorsed by someone (Junio,\nHeiko, ...) for the \"submodule.<name>.local-branch\" feature please\nshow me where.\n\nI somehow understand the point of the\n\"submodule.<name>.local-branch\" property, but I can't \"see\" the the\nworkflow. Please, show me some hypothetical scripting example with as\nmuch complete as possible workflow (creation, developer update,\nmantainers creates feature branch, developer update, developer attach\nto another branch). Also, consider I proposed to support the attached\nHEAD path to reduce complexity and support a simpler use case for\ngit submodules. I would be disappointed if the complexity is reduced in a\nway and augmented in another.\n\n> On Wed, Jan 08, 2014 at 01:17:49AM +0100, Francesco Pretto wrote:\n>> # Attach the submodule HEAD to <branch>.\n>> # Also set \".git/config\" 'submodule.<module>.branch' to <branch>\n>> $ git submodule head -b <branch> --attach <module>\n> [...]\n> I also prefer 'checkout' to 'head', because 'checkout'\n> already exists in non-submodule Git for switching between local\n> branches.\n>\n\nI can agree with similarity to other git commands, but 'checkout' does\nnot give me the idea of something that writes to \".git/config\" or\n\".gitmodules\".\n\n>> # Attach the submodule HEAD to 'submodule.<module>.branch'.\n>> # If it does not exists defaults to <remote>/master\n>> $ git submodule head --attach <module>\n>\n> Defaulting to the configured local branch is fine, but I think it\n> should default to 'master' if no local branch is configured.  This\n> should not have anything to do with remote-tracking branches (that's\n> what 'submodule update' already handles).  I don't understand why\n> remote-tracking-branch integration keeps getting mixed up with\n> local-branch checkout.\n>\n\nYep, it should default to \"master\", my fault.\n\n>> # Unset  \".git/config\" 'submodule.<module>.branch'\n>> # Also attach or detach the HEAD according to what is in \".gitmodules\":\n>> # with Trevor's patch 'submodule.<module>.branch' set means attached,\n>> # unset means detached\n>> $ git submodule head --reset <module>\n>\n> To me this reads “always detach HEAD” (because it unsets\n> submodule.<name>.branch, and submodule.<name>.branch unset means\n> detached).\n\nI disagree: this would remove only the value in \".git/config\". If the\nvalue is till present in \".gitmodules\", as I wrote above, the behavior\nof what is in the index should be respected as for the other\nproperties. Also it gives a nice meaning to a switch like --reset :\nreturn to how it was before.\n\n>> NOTE: feature branch part!\n>>\n>> # Set \".gitmodules\" 'submodule.<module>.branch' to <branch>\n>> $ git submodule head -b <branch> --attach --index <module>\n>>\n>> # Unset \".gitmodules\" 'submodule.<module>.branch'\n>> $ git submodule head --reset --index <module>\n>> ---------------------------------------------------------------------\n>\n> These are just manipulating .gitmodules.  I think we also need\n> per-superproject-branch configs under the superproject's .git/ for\n> developer overrides.\n>\n\nI disagree: in my idea the --index switch is a maintainer only command\nto modify the behavior of the developers and touch only indexed files\n(.gitmodules, or create a new submodule branch). It expressly don't\ntouch .git/config.\n"},{"id":"232928","messageId":"CALas-iheQ4Rfxvty5guEieVwa8SffRnhRdHkNXUKwmuHRXD2Xg@mail.gmail.com","threadId":"35584","inReplyTo":"20140108010504.GE26583@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-08T23:07:56Z","receivedAt":"2014-01-08T23:07:56Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/8 W. Trevor King <wking@tremily.us>:\n> To elaborate the idea I sketched out here [2], say\n> you want:\n>\n>   Superproject branch  Submodule branch  Upstream branch\n>   ===================  ================  ===============\n>   master               master            master\n>   super-feature        master            master\n>   my-feature           my-feature        master\n>   other-feature        other-feature     other-feature\n>\n> That's only going to work with per-superproject-branch configs for\n> both the local and remote branches.  Using the same name for both\n> local and remote branches does not work.\n>\n\nAfter long thoughts, I think your idea about a local branch with a\ndifferently named remote branch looks interesting but I would be\nextremely cautious to add a ' submodule.<name>.local-branch' now. Do\nwe have a similar mechanism on regular repository clones? We can clone\nand switch to a branch other than \"master\" by default, but can we also\nhave a different remote by default? If we don't have it, we shouldn't\nadd it first on submodules, as there's the chance the feature never\nget coupled on  the regular clones.\n\nAlso, I think you fear too much that this can't be added also later.\n\nI think you should pursue your initial proposal of \"--branch means\nattached\" to get it upstream first. It's alone, IMO, a great\nimprovement on submodules.\n"},{"id":"232930","messageId":"CALas-iiX1=LAJQ_LsayhxB2zQTYVd5jxpVvOLOpdgHBW10ci1A@mail.gmail.com","threadId":"35584","inReplyTo":"20140108010504.GE26583@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-08T23:54:54Z","receivedAt":"2014-01-08T23:54:54Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/8 W. Trevor King <wking@tremily.us>:\n> I also prefer 'checkout' to 'head', because 'checkout'\n> already exists in non-submodule Git for switching between local\n> branches.\n>\n\nReasons I would loosely support 'git submodule checkout'\n--------------------------------------------------------------------------------\n1)  It's true that 'git submodule checkout' would also often run 'git checkout'.\n\nReasons, as an user, I seriously would *not* like 'git submodule checkout'\n-----------------------------------------------------------------------------------------------------\n1) 'git submodule checkout' would also touch '.git/config' and\n'.gitmodules', and I don't like much the idea of a 'checkout' command\ntouching config files. It looks dirty.\n2) Having 'git checkout', 'git checkout --recurse-submodules' and\nfinally 'git submodule checkout' is too much for me.\n\nAlso, in my proposal, 'git submodule [tobedecided] --attach' would\nalso merge orphaned commits by default, and 'checkout' is not about\nmerge.\n\nReasons I would fervently support 'git submodule head'\n----------------------------------------------------------------------------\n1) It tells immediately that this command is about HEAD of the\nsubmodule, and will take care of it. Newcomers would loveit if they\ndon't like their HEAD state;\n2) \"head\" is unspecific enough to admit it can also touch\n'.git/config' and '.gitmodules'.\n\nSaid this, it seems Heiko[1] proposed a similar syntax and the only\ndifference was about names, not behavior of the command to be added\n(if we eventually take this path, ofc).\n\n> On Wed, Jan 08, 2014 at 01:17:49AM +0100, Francesco Pretto wrote:\n>> # Attach the submodule HEAD to <branch>.\n>> # Also set \".git/config\" 'submodule.<module>.branch' to <branch>\n>> $ git submodule head -b <branch> --attach <module>\n>\n> I prefer submodule.<name>.local-branch for the submodule's local\n> branch name.\n\nI think this was still part of your original misunderstanding about my\n\"git submodule head\". This command would touch 'branch' property\nanyway because '-b <branch>' would still be the remote branch, even in\nthe case you have a 'local-branch' property (maybe to be coupled here\nwith a --local-branch <local-branch> switch).\n\nGreetings,\nFrancesco\n\n[1] http://marc.info/?l=git&m=138913435216349&w=2\n"},{"id":"232931","messageId":"20140109000338.GM29954@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-iheQ4Rfxvty5guEieVwa8SffRnhRdHkNXUKwmuHRXD2Xg@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-09T00:03:38Z","receivedAt":"2014-01-09T00:03:38Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 09, 2014 at 12:07:56AM +0100, Francesco Pretto wrote:\n> After long thoughts, I think your idea about a local branch with a\n> differently named remote branch looks interesting but I would be\n> extremely cautious to add a ' submodule.<name>.local-branch' now. Do\n> we have a similar mechanism on regular repository clones?\n\nThe default upstream branch is currently configured with\nbranch.<name>.merge.  Earlier [1], I suggested we piggyback on this\nfor the submodule's upstream branches, and only use\nsubmodule.<name>.branch for the initial setup.  That would allow\ndevelopers to configure upstreams on a per-submodule-branch basis.  We\nshould probably fall back to submodule.<name>.branch if the submodule\ndoes not have a branch.<name>.merge configured.\n\nHowever, submodule.<name>.local-branch has nothing to do with remote\nrepositories or tracking branches.  It just selects the preferred\nsubmodule branch for the superproject branch.  This will only work for\nin-tree .gitmodules configs (since the contents are per-branch).  I\ndon't have a good idea for where local overrides would live.  We'd\nwant something like\nbranch.<superproject-branch>.submodule.<submodule-name>.local-branch:\n\n  [branch \"my-feature\"]\n        remote = origin\n        merge = refs/heads/my-feature\n        [submodule \"submod\"]\n            local-branch = \"my-feature\"\n\nand I don't think Git's config supports such nesting.\n\n> We can clone and switch to a branch other than \"master\" by default,\n> but can we also have a different remote by default?\n\nSure, the existing submodule.<name>.url defines the remote repository,\nand the existing submodule.<name>.branch defines the remote branch.\nThe existing code even sets up remote.origin.url and\nbranch.<name>.merge (to the matching refs/heads/<name>) in the the\nsubmodule's config.\n\n> Also, I think you fear too much that this can't be added also later.\n\nWe can add submodule.<name>.local-branch support later, but I see no\nreason not to add it on top of Jens and Jonathan's current submodule\ncheckout work.  With increasingly robust submodule checkout support in\nthe core, I expect the amount of update logic stored in\ngit-submodule.sh will decrease significantly.\n\n> I think you should pursue your initial proposal of \"--branch means\n> attached\" to get it upstream first. It's alone, IMO, a great\n> improvement on submodules.\n\nI can resuscitate that if folks want, but Heiko felt that my initial\nconsolidation didn't go far enough [2].  If it turns out that we're ok\nwith the current level of consolidation, would you be ok with\n\"non-checkout submodule.<name>.update\" as the trigger [3]?  I think\nthat adding a halfway step between the current status and full(ish)\nsubmodule.<name>.local-branch support is just going to confuse people\n;).\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240164\n[2]: http://article.gmane.org/gmane.comp.version-control.git/239968\n[3]: http://article.gmane.org/gmane.comp.version-control.git/239973\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232932","messageId":"20140109002328.GN29954@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-iiX1=LAJQ_LsayhxB2zQTYVd5jxpVvOLOpdgHBW10ci1A@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-09T00:23:28Z","receivedAt":"2014-01-09T00:23:28Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 09, 2014 at 12:54:54AM +0100, Francesco Pretto wrote:\n> 2) Having 'git checkout', 'git checkout --recurse-submodules' and\n> finally 'git submodule checkout' is too much for me.\n\nAgreed.  Since 'git checkout' already exists and 'git checkout\n--recurse-submodules' is close [1,2], I think that means we should\ndrop this and start arguing about adjusting 'git checkout\n--recurse-submodules' to checkout branches as well ;).\n\n> Also, in my proposal, 'git submodule [tobedecided] --attach' would\n> also merge orphaned commits by default, and 'checkout' is not about\n> merge.\n\nAnd that's good.  Bailing with “you have orphaned commits, which you\nshould integrate them with $some_integration_command before checking\nout a different branch” is better than having overlapping\nresponsibilities between the checkout command and the integration\ncommand.\n\nCheers,\nTrevor\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/239695\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240117\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232938","messageId":"CALas-igFQtG1qa2+grMAtZ9mDE-xGuXkDGwGvSXL8_FzPfXBLQ@mail.gmail.com","threadId":"35584","inReplyTo":"20140109000338.GM29954@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-09T01:09:37Z","receivedAt":"2014-01-09T01:09:37Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/9 W. Trevor King <wking@tremily.us>:\n>\n> However, submodule.<name>.local-branch has nothing to do with remote\n> repositories or tracking branches.\n\nMy bad: this means the feature is still not entirely clear to me.\n\n>\n>   [branch \"my-feature\"]\n>         remote = origin\n>         merge = refs/heads/my-feature\n>         [submodule \"submod\"]\n>             local-branch = \"my-feature\"\n>\n> and I don't think Git's config supports such nesting.\n>\n\nAesthetically, It doesn't look very nice.\n\n>\n> I can resuscitate that if folks want, but Heiko felt that my initial\n> consolidation didn't go far enough [2].  If it turns out that we're ok\n> with the current level of consolidation, would you be ok with\n> \"non-checkout submodule.<name>.update\" as the trigger [3]?\n\nFor me it was ok with what you did:\n-------------------------------------------------\nif \"just_cloned\" and \"config_branch\"\nthen\n     !git reset --hard -q\"\nfi\n-------------------------------------------------\n\nSo yes: at the first clone 'checkout' keeps attached HEAD, while\n'merge' and 'rebase' attach to the branch.\nIf it's not the first clone, you should take no action (and your\noriginal patch was ok about this).\n\n>  I think\n> that adding a halfway step between the current status and full(ish)\n> submodule.<name>.local-branch support is just going to confuse people\n\nWell, for now you got some success in confusing me with this \"local-branch\" :)\n\nAt certain point  you may ask maintainers what are the accepted\nfeatures (because all these debates should be about getting, or not\ngetting, endorsement about something) and finalize a patch so people\ncan further review.\n"},{"id":"232939","messageId":"20140109022222.GP29954@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-igFQtG1qa2+grMAtZ9mDE-xGuXkDGwGvSXL8_FzPfXBLQ@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-09T02:22:22Z","receivedAt":"2014-01-09T02:22:22Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 09, 2014 at 02:09:37AM +0100, Francesco Pretto wrote:\n> 2014/1/9 W. Trevor King <wking@tremily.us>:\n> >   [branch \"my-feature\"]\n> >         remote = origin\n> >         merge = refs/heads/my-feature\n> >         [submodule \"submod\"]\n> >             local-branch = \"my-feature\"\n> >\n> > and I don't think Git's config supports such nesting.\n> \n> Aesthetically, It doesn't look very nice.\n\nThe INI syntax does not lend itself to easy nesting, but I'm pretty\nsure some mapping from (<superproject-branch>, <submodule-name>) to\n<submodule-local-branch-name> is what we need for submodule checkouts.\nI'm just not sure where local overides to the per-branch .gitmodules\nshould live.  We could turn it around, and store:\n\n  [superproject \"<superproject-branch>\"]\n      local-branch = \"<submodule-local-branch-name>\"\n\nin .git/modules/<submodule-name>/config, with the UI:\n\n  $ cd submodule\n  $ git config superproject.<superproject-branch>.local-branch = <submodule-branch>\n\nNot beautiful, but maybe a bit more palatable, and already supported\nby Git's current config parser.  That's enough that I can work up a\npatch that will hopefully clarify my position ;).\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232947","messageId":"52CE5E51.4060507@web.de","threadId":"35584","inReplyTo":"CALas-igFQtG1qa2+grMAtZ9mDE-xGuXkDGwGvSXL8_FzPfXBLQ@mail.gmail.com","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-01-09T08:31:13Z","receivedAt":"2014-01-09T08:31:13Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 09.01.2014 02:09, schrieb Francesco Pretto:\n> 2014/1/9 W. Trevor King <wking@tremily.us>:\n>>\n>> However, submodule.<name>.local-branch has nothing to do with remote\n>> repositories or tracking branches.\n> \n> My bad: this means the feature is still not entirely clear to me.\n> \n>>\n>>   [branch \"my-feature\"]\n>>         remote = origin\n>>         merge = refs/heads/my-feature\n>>         [submodule \"submod\"]\n>>             local-branch = \"my-feature\"\n>>\n>> and I don't think Git's config supports such nesting.\n>>\n> \n> Aesthetically, It doesn't look very nice.\n\nAnd I'm not sure we even need that. What's wrong with having the\nbranch setting in the .gitmodules file of the my-feature branch?\nThe only problem I can imagine is accidentally merging that into\na branch where that isn't set, but that could be solved by a merge\nhelper for the .gitmodules file.\n\n>> I can resuscitate that if folks want, but Heiko felt that my initial\n>> consolidation didn't go far enough [2].  If it turns out that we're ok\n>> with the current level of consolidation, would you be ok with\n>> \"non-checkout submodule.<name>.update\" as the trigger [3]?\n> \n> For me it was ok with what you did:\n> -------------------------------------------------\n> if \"just_cloned\" and \"config_branch\"\n> then\n>      !git reset --hard -q\"\n> fi\n> -------------------------------------------------\n> \n> So yes: at the first clone 'checkout' keeps attached HEAD, while\n> 'merge' and 'rebase' attach to the branch.\n\nIt have the impression that attaching the head to the given branch\nfor merge and rebase might be the sensible thing to do, but it\nwould be great to hear from users of merge and rebase if that\nwould break anything for them in their current use cases for these\nsettings.\n\n> If it's not the first clone, you should take no action (and your\n> original patch was ok about this).\n\nI'm not sure this is the right thing to do, after all you\nconfigured git to follow that branch so I'd expect it to be\nupdated later too, no? Otherwise you might end up with an old\nversion of your branch while upstream is a zillion commits\nahead.\n\n>>  I think\n>> that adding a halfway step between the current status and full(ish)\n>> submodule.<name>.local-branch support is just going to confuse people\n> \n> Well, for now you got some success in confusing me with this \"local-branch\" :)\n> \n> At certain point  you may ask maintainers what are the accepted\n> features (because all these debates should be about getting, or not\n> getting, endorsement about something) and finalize a patch so people\n> can further review.\n\nFirst I'd like to see a real consensus about what exactly should\nhappen when a branch is configured to be checked out (and if I\nmissed such a summary in this thread, please point me to it ;-).\nAnd we should contrast that to the exact checkout and floating\nbranch use cases.\n\nSo what should happen on initial clone, later updates, updates\nwhere the local and the remote branch diverged, when superproject\nbranches are merged (with and without conflicts), on a rebase in\nthe superproject and so on.\n\nAfter that we can discuss about how to implement them (even though I\nbelieve we won't need a new submodule command at the end of this\nprocess, simply because if it isn't configurable we cannot teach git\ncheckout and friends to do that automatically for us later).\n\nAnd from reading this discussion I believe we need another value for\nthe ignore option which only ignores changes to the SHA-1 but not to\nwork tree modifications of a submodule work tree relative to its HEAD\n(or make that two: another one which ignores untracked files too and\nonly shows modification of tracked files). Otherwise users of the\nfloating or attached model can easily miss submodule modifications.\n"},{"id":"232955","messageId":"20140109173218.GA8042@odin.tremily.us","threadId":"35584","inReplyTo":"52CE5E51.4060507@web.de","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-09T17:32:18Z","receivedAt":"2014-01-09T17:32:18Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 09, 2014 at 09:31:13AM +0100, Jens Lehmann wrote:\n> Am 09.01.2014 02:09, schrieb Francesco Pretto:\n> > 2014/1/9 W. Trevor King <wking@tremily.us>:\n> >>\n> >> However, submodule.<name>.local-branch has nothing to do with remote\n> >> repositories or tracking branches.\n> > \n> > My bad: this means the feature is still not entirely clear to me.\n> > \n> >>\n> >>   [branch \"my-feature\"]\n> >>         remote = origin\n> >>         merge = refs/heads/my-feature\n> >>         [submodule \"submod\"]\n> >>             local-branch = \"my-feature\"\n> >>\n> >> and I don't think Git's config supports such nesting.\n> >>\n> > \n> > Aesthetically, It doesn't look very nice.\n> \n> And I'm not sure we even need that. What's wrong with having the\n> branch setting in the .gitmodules file of the my-feature branch?\n> The only problem I can imagine is accidentally merging that into\n> a branch where that isn't set, but that could be solved by a merge\n> helper for the .gitmodules file.\n\n.gitmodules is fine so long as the config can live in the versioned\ntree.  Many (all?) .gitmodules settings can be overridden in\n.git/config.  However, the local-branch setting needs to be both\nper-submodule and per-superproject-branch, so .git/config doesn't work\nvery well.  I think it's better to use something like my\n.git/modules/<submodule-name>/config implementation [1] to set this\noverride.\n\nThis lack of per-superproject-branch overrides applies to all of the\nsubmodule.<name>.* settings, but you're unlikely to want an\nout-of-tree override for 'path' or a per-superproject-branch override\nfor 'url', 'ignore', 'update', or 'chRecurseSubmodules'.  Maybe folks\nwould want per-superproject-branch overrides to 'branch', although I'd\nprefer we reuse branch.<name>.merge in the submodule's config for\nthat [2].\n\nOn the other hand, maybe an in-tree .gitmodules is good enough, and\nfolks who want a local override can just edit .gitmodules in their\nlocal branch?  I've never felt the need to override .gitmodules myself\n(for any setting), so feedback from someone who has would be useful.\n\n> >> I can resuscitate that if folks want, but Heiko felt that my initial\n> >> consolidation didn't go far enough [2].  If it turns out that we're ok\n> >> with the current level of consolidation, would you be ok with\n> >> \"non-checkout submodule.<name>.update\" as the trigger [3]?\n> > \n> > For me it was ok with what you did:\n> > -------------------------------------------------\n> > if \"just_cloned\" and \"config_branch\"\n> > then\n> >      !git reset --hard -q\"\n> > fi\n> > -------------------------------------------------\n> > \n> > So yes: at the first clone 'checkout' keeps attached HEAD, while\n> > 'merge' and 'rebase' attach to the branch.\n> \n> It have the impression that attaching the head to the given branch\n> for merge and rebase might be the sensible thing to do, but it\n> would be great to hear from users of merge and rebase if that\n> would break anything for them in their current use cases for these\n> settings.\n\nWhich local branch would you attach to before merging?  I think 'git\nsubmodule update' should always use the current submodule state\n(attached branch or detached HEAD) [3], and we should have a separate\ncall that explicitly checked out the desired submodule branch [4].\n\n> > If it's not the first clone, you should take no action (and your\n> > original patch was ok about this).\n> \n> I'm not sure this is the right thing to do, after all you\n> configured git to follow that branch so I'd expect it to be\n> updated later too, no? Otherwise you might end up with an old\n> version of your branch while upstream is a zillion commits\n> ahead.\n\nNon-clone updates should not change the submodule's *local* branch\n*name*.  They should change the commit that that branch references,\notherwise 'git submodule update' would be a no-op ;).\n\n> First I'd like to see a real consensus about what exactly should\n> happen when a branch is configured to be checked out (and if I\n> missed such a summary in this thread, please point me to it ;-).\n\nI don't think we have a consensus yet.  A stand-alone outline of my\ncurrent position is in my v3 RFC [5], but I don't have any buy-in yet\n;).\n\n> And we should contrast that to the exact checkout and floating\n> branch use cases.\n\nWith my v3 series, there are no more detached HEADs.  Folks using\ncheckout updates get a local master branch.  I do not change any of\nthe exact checkout (superproject gitlinked sha1) vs. floating\n(subproject's remote submodule.<name>.branch via 'update --remote')\nlogic, because that already works well.  The problem is the local\nbranch handling, not the update/integration logic.\n\n> So what should happen on initial clone,\n\nFor 'add', clone the command line URL and create a new branch 'master'\npointing at the commit referenced by the remote's HEAD (or other\nbranch with --branch).\n\nFor 'update', do the same, except use a local-branch setting to\ndetermine the name for the local branch, falling back to 'master' if\nit is not set.\n\n> later updates,\n\nThe same thing that currently happens, with the exception that\ncheckout-style updates should use reset to update the\ncurrently-checked out branch (or detached-HEAD), instead of always\ndetaching the HEAD.\n\n> updates where the local and the remote branch diverged,\n\nThe same thing that currently happens.  For local (non --remote)\nupdates, the integrated branch is the superproject's gitlinked sha1.\nFor --remote updates, the integrated branch is the remote subproject's\nsubmodule.<name>.branch.  We integrate that with the\ncurrently-checked-out local branch (or detached HEAD) using the user's\npreferred submodule.<name>.update strategy.\n\n> when superproject branches are merged (with and without conflicts),\n\nI don't think this currently does anything to the submodule itself,\nand that makes sense to me (use 'submodule update' or my 'submodule\ncheckout' if you want such effects).  We should keep the current logic\nfor updating the gitlinked $sha.  In the case that the\n.gitmodule-configured local-branches disagree, we should give the\nusual conflict warning (and <<<===>>> markup) and let the user resolve\nthe conflict in the usual way.\n\n> on a rebase in the superproject and so on.\n\nSame as the merge case.  Why would configuring a preferred\nlocal-branch that only affects checkout (and the initial clone) have\nanything to do with rebases and merges?\n\n> After that we can discuss about how to implement them (even though I\n> believe we won't need a new submodule command at the end of this\n> process, simply because if it isn't configurable we cannot teach git\n> checkout and friends to do that automatically for us later).\n\nI think it is configurable, and I have an implementation that works\n(modulo bugs) [5].  I think we should teach 'git checkout\n--recurse-submodules' this logic, and then we can drop my 'git\nsubmodule checkout' entirely.\n\n> And from reading this discussion I believe we need another value for\n> the ignore option which only ignores changes to the SHA-1 but not to\n> work tree modifications of a submodule work tree relative to its HEAD\n> (or make that two: another one which ignores untracked files too and\n> only shows modification of tracked files). Otherwise users of the\n> floating or attached model can easily miss submodule modifications.\n\nI am ignore-agnostic ;).  Do whatever you like here.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240251\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240164\n[3]: http://article.gmane.org/gmane.comp.version-control.git/240250\n[4]: http://article.gmane.org/gmane.comp.version-control.git/240249\n[5]: http://article.gmane.org/gmane.comp.version-control.git/240248\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232960","messageId":"52CEF71B.5010201@web.de","threadId":"35584","inReplyTo":"20140109173218.GA8042@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-01-09T19:23:07Z","receivedAt":"2014-01-09T19:23:07Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 09.01.2014 18:32, schrieb W. Trevor King:\n> On Thu, Jan 09, 2014 at 09:31:13AM +0100, Jens Lehmann wrote:\n>> Am 09.01.2014 02:09, schrieb Francesco Pretto:\n>>> 2014/1/9 W. Trevor King <wking@tremily.us>:\n>>>>\n>>>> However, submodule.<name>.local-branch has nothing to do with remote\n>>>> repositories or tracking branches.\n>>>\n>>> My bad: this means the feature is still not entirely clear to me.\n>>>\n>>>>\n>>>>   [branch \"my-feature\"]\n>>>>         remote = origin\n>>>>         merge = refs/heads/my-feature\n>>>>         [submodule \"submod\"]\n>>>>             local-branch = \"my-feature\"\n>>>>\n>>>> and I don't think Git's config supports such nesting.\n>>>>\n>>>\n>>> Aesthetically, It doesn't look very nice.\n>>\n>> And I'm not sure we even need that. What's wrong with having the\n>> branch setting in the .gitmodules file of the my-feature branch?\n>> The only problem I can imagine is accidentally merging that into\n>> a branch where that isn't set, but that could be solved by a merge\n>> helper for the .gitmodules file.\n> \n> .gitmodules is fine so long as the config can live in the versioned\n> tree.  Many (all?) .gitmodules settings can be overridden in\n> .git/config.\n\nWith the exception of path, as that would make no sense at all.\n\n>  However, the local-branch setting needs to be both\n> per-submodule and per-superproject-branch, so .git/config doesn't work\n> very well.  I think it's better to use something like my\n> .git/modules/<submodule-name>/config implementation [1] to set this\n> override.\n\nYes, the local branch should be set in the submodule's .git/config\nto make operations done inside the submodule work seamlessly.\n\n> This lack of per-superproject-branch overrides applies to all of the\n> submodule.<name>.* settings, but you're unlikely to want an\n> out-of-tree override for 'path' or a per-superproject-branch override\n> for 'url', 'ignore', 'update', or 'chRecurseSubmodules'.\n\nUnlikely it is not ;-) We do have people who set update=none in\nthe .git/config of the superproject for submodules they don't have\naccess to (and which is not necessary for their work). And it isn't\na \"per-superproject-branch override\" but a \"per-superproject-branch\ndefault\" which can be overridden in .git/config (except for 'update',\nbut I intend to fix that).\n\n>  Maybe folks\n> would want per-superproject-branch overrides to 'branch', although I'd\n> prefer we reuse branch.<name>.merge in the submodule's config for\n> that [2].\n\nBut that might still have to be synced with what the superproject\nwants. Maybe manually, maybe automatically on checkout. Dunno yet.\n\n> On the other hand, maybe an in-tree .gitmodules is good enough, and\n> folks who want a local override can just edit .gitmodules in their\n> local branch?  I've never felt the need to override .gitmodules myself\n> (for any setting), so feedback from someone who has would be useful.\n\nThat way these changes would propagate to others working on the same\nbranch when pushing, which I believe is a feature.\n\n>>>> I can resuscitate that if folks want, but Heiko felt that my initial\n>>>> consolidation didn't go far enough [2].  If it turns out that we're ok\n>>>> with the current level of consolidation, would you be ok with\n>>>> \"non-checkout submodule.<name>.update\" as the trigger [3]?\n>>>\n>>> For me it was ok with what you did:\n>>> -------------------------------------------------\n>>> if \"just_cloned\" and \"config_branch\"\n>>> then\n>>>      !git reset --hard -q\"\n>>> fi\n>>> -------------------------------------------------\n>>>\n>>> So yes: at the first clone 'checkout' keeps attached HEAD, while\n>>> 'merge' and 'rebase' attach to the branch.\n>>\n>> It have the impression that attaching the head to the given branch\n>> for merge and rebase might be the sensible thing to do, but it\n>> would be great to hear from users of merge and rebase if that\n>> would break anything for them in their current use cases for these\n>> settings.\n> \n> Which local branch would you attach to before merging?  I think 'git\n> submodule update' should always use the current submodule state\n> (attached branch or detached HEAD) [3], and we should have a separate\n> call that explicitly checked out the desired submodule branch [4].\n\nLike we currently do with \"git submodule update --remote\" (where you\nhave to have an explicit command telling git when to advance the\nbranch)? Having a separate call that does something *after* a git\ncommand is exactly the problem I'm trying to fix with recursive\nupdate, so I'm not terribly excited ;-)\n\n>>> If it's not the first clone, you should take no action (and your\n>>> original patch was ok about this).\n>>\n>> I'm not sure this is the right thing to do, after all you\n>> configured git to follow that branch so I'd expect it to be\n>> updated later too, no? Otherwise you might end up with an old\n>> version of your branch while upstream is a zillion commits\n>> ahead.\n> \n> Non-clone updates should not change the submodule's *local* branch\n> *name*.  They should change the commit that that branch references,\n> otherwise 'git submodule update' would be a no-op ;).\n\nOkay, I seem to have misunderstood that. But what happens when the\nbranch setting in .gitmodules changes, shouldn't that be updated?\n\n>> First I'd like to see a real consensus about what exactly should\n>> happen when a branch is configured to be checked out (and if I\n>> missed such a summary in this thread, please point me to it ;-).\n> \n> I don't think we have a consensus yet.  A stand-alone outline of my\n> current position is in my v3 RFC [5], but I don't have any buy-in yet\n> ;).\n\nI'll volunteer to prepare a table explaining the different modes\nin my github wiki. Will scan this thread and your pointers for input\nand will come back soon when I have something ready.\n\n>> And we should contrast that to the exact checkout and floating\n>> branch use cases.\n> \n> With my v3 series, there are no more detached HEADs.  Folks using\n> checkout updates get a local master branch.  I do not change any of\n> the exact checkout (superproject gitlinked sha1) vs. floating\n> (subproject's remote submodule.<name>.branch via 'update --remote')\n> logic, because that already works well.  The problem is the local\n> branch handling, not the update/integration logic.\n\nOk. Maybe we could use the \"<remote>:<local>\" notation to store both\nremote and local branch in a single setting?\n\n>> So what should happen on initial clone,\n> \n> For 'add', clone the command line URL and create a new branch 'master'\n> pointing at the commit referenced by the remote's HEAD (or other\n> branch with --branch).\n> \n> For 'update', do the same, except use a local-branch setting to\n> determine the name for the local branch, falling back to 'master' if\n> it is not set.\n\nGood.\n\n>> later updates,\n> \n> The same thing that currently happens, with the exception that\n> checkout-style updates should use reset to update the\n> currently-checked out branch (or detached-HEAD), instead of always\n> detaching the HEAD.\n\nWon't the user loose any modifications to his local branch here?\n\n>> updates where the local and the remote branch diverged,\n> \n> The same thing that currently happens.  For local (non --remote)\n> updates, the integrated branch is the superproject's gitlinked sha1.\n> For --remote updates, the integrated branch is the remote subproject's\n> submodule.<name>.branch.  We integrate that with the\n> currently-checked-out local branch (or detached HEAD) using the user's\n> preferred submodule.<name>.update strategy.\n\nAnd for checkout I can easily overwrite the upstream branch with\nmy local changes?\n\n>> when superproject branches are merged (with and without conflicts),\n> \n> I don't think this currently does anything to the submodule itself,\n> and that makes sense to me (use 'submodule update' or my 'submodule\n> checkout' if you want such effects).  We should keep the current logic\n> for updating the gitlinked $sha.  In the case that the\n> .gitmodule-configured local-branches disagree, we should give the\n> usual conflict warning (and <<<===>>> markup) and let the user resolve\n> the conflict in the usual way.\n\nFor me it makes lots of sense that in recursive checkout mode the\nmerged submodules are already checked out (if possible) right after\na superproject merge, making another \"submodule update\" unnecessary\n(the whole point of recursive update is to make \"submodule update\"\nobsolete, except for \"--remote\").\n\n>> on a rebase in the superproject and so on.\n> \n> Same as the merge case.  Why would configuring a preferred\n> local-branch that only affects checkout (and the initial clone) have\n> anything to do with rebases and merges?\n\nBecause teaching --recurse-submodules to checkout is only one part,\nin the full recursive update series every work tree manipulating\ncommand (like rebase and merge) will update submodules. So it is\nnot only affecting checkout, but a lot of other commands too.\n\n>> After that we can discuss about how to implement them (even though I\n>> believe we won't need a new submodule command at the end of this\n>> process, simply because if it isn't configurable we cannot teach git\n>> checkout and friends to do that automatically for us later).\n> \n> I think it is configurable, and I have an implementation that works\n> (modulo bugs) [5].  I think we should teach 'git checkout\n> --recurse-submodules' this logic, and then we can drop my 'git\n> submodule checkout' entirely.\n\nOkay, I have no problem with a proof of concept implementation to\nplay around with.\n\n>> And from reading this discussion I believe we need another value for\n>> the ignore option which only ignores changes to the SHA-1 but not to\n>> work tree modifications of a submodule work tree relative to its HEAD\n>> (or make that two: another one which ignores untracked files too and\n>> only shows modification of tracked files). Otherwise users of the\n>> floating or attached model can easily miss submodule modifications.\n> \n> I am ignore-agnostic ;).  Do whatever you like here.\n\nI was hoping someone else would jump in to do that, as I'm rather\nbusy with the recursive checkout topic ;-)\n"},{"id":"232963","messageId":"20140109195522.GT29954@odin.tremily.us","threadId":"35584","inReplyTo":"52CEF71B.5010201@web.de","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-09T19:55:22Z","receivedAt":"2014-01-09T19:55:22Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 09, 2014 at 08:23:07PM +0100, Jens Lehmann wrote:\n> Am 09.01.2014 18:32, schrieb W. Trevor King:\n> >  However, the local-branch setting needs to be both\n> > per-submodule and per-superproject-branch, so .git/config doesn't work\n> > very well.  I think it's better to use something like my\n> > .git/modules/<submodule-name>/config implementation [1] to set this\n> > override.\n> \n> Yes, the local branch should be set in the submodule's .git/config\n> to make operations done inside the submodule work seamlessly.\n\nOnce you're inside the submodule my local-branch setting shouldn't\nmatter, because it just connects superproject branches with submodule\nbranches.  The submodule's config is just a convenient out-of-tree\nplace to store per-submodule overrides.\n\n> > This lack of per-superproject-branch overrides applies to all of the\n> > submodule.<name>.* settings, but you're unlikely to want an\n> > out-of-tree override for 'path' or a per-superproject-branch override\n> > for 'url', 'ignore', 'update', or 'chRecurseSubmodules'.\n> \n> Unlikely it is not ;-) We do have people who set update=none in\n> the .git/config of the superproject for submodules they don't have\n> access to (and which is not necessary for their work).\n\nThat is not a per-superproject-branch override.  local-branch is the\nonly per-submodule config I can think of where I can imagine a sane\nperson actually wanting an out-of-tree per-superproject-branch\noverride.\n\n> And it isn't a \"per-superproject-branch override\" but a\n> \"per-superproject-branch default\" which can be overridden in\n> .git/config (except for 'update', but I intend to fix that).\n\nYou're talking about .gitmodules vs. .git/config here, but for\nlocal-branch, I'm talking about a fallback chain like [1]:\n\n1. superproject.<superproject-branch>.local-branch in the submodule's\n   config (superproject/.git/modules/≤submodule-name>/config).\n2. submodule.<submodule-name>.local-branch in the superproject's\n   config (.git/config).\n3. submodule.<submodule-name>.local-branch in the superproject's\n   .gitmodules file.\n4. default to 'master'\n\nOnly #1 is a new idea.\n\n> > On the other hand, maybe an in-tree .gitmodules is good enough,\n> > and folks who want a local override can just edit .gitmodules in\n> > their local branch?  I've never felt the need to override\n> > .gitmodules myself (for any setting), so feedback from someone who\n> > has would be useful.\n> \n> That way these changes would propagate to others working on the same\n> branch when pushing, which I believe is a feature.\n\nSure.  Unless they don't want to propagate them, at which point they\nuse an out-of-tree override masking the .gitmodules value.  The\nquestion is, would folks want local overrides for local-branch (like\nthey do for submodule.<name>.update), or not?  Since it's easy to do\n[1], I don't see the point of *not* supporting per-superproject-branch\noverrides.\n\n> >> It have the impression that attaching the head to the given\n> >> branch for merge and rebase might be the sensible thing to do,\n> >> but it would be great to hear from users of merge and rebase if\n> >> that would break anything for them in their current use cases for\n> >> these settings.\n> > \n> > Which local branch would you attach to before merging?  I think\n> > 'git submodule update' should always use the current submodule\n> > state (attached branch or detached HEAD) [3], and we should have a\n> > separate call that explicitly checked out the desired submodule\n> > branch [4].\n> \n> Like we currently do with \"git submodule update --remote\" (where you\n> have to have an explicit command telling git when to advance the\n> branch)? Having a separate call that does something *after* a git\n> command is exactly the problem I'm trying to fix with recursive\n> update, so I'm not terribly excited ;-)\n\nI'm all for rolling my 'git submodule checkout' into 'git checkout\n--recurse-submodules' [2].  It was just faster to mock up in shell\nwhile we decide how it should work.\n\n> >>> If it's not the first clone, you should take no action (and your\n> >>> original patch was ok about this).\n> >>\n> >> I'm not sure this is the right thing to do, after all you\n> >> configured git to follow that branch so I'd expect it to be\n> >> updated later too, no? Otherwise you might end up with an old\n> >> version of your branch while upstream is a zillion commits\n> >> ahead.\n> > \n> > Non-clone updates should not change the submodule's *local* branch\n> > *name*.  They should change the commit that that branch references,\n> > otherwise 'git submodule update' would be a no-op ;).\n> \n> Okay, I seem to have misunderstood that. But what happens when the\n> branch setting in .gitmodules changes, shouldn't that be updated?\n\nNot by 'git submodule update'.  If there are no out-of-tree overrides\nand the user calls 'git submodule checkout' with a new local-branch in\n.gitmodules, *that* should checkout a new submodule branch.\n\n> >> First I'd like to see a real consensus about what exactly should\n> >> happen when a branch is configured to be checked out (and if I\n> >> missed such a summary in this thread, please point me to it ;-).\n> > \n> > I don't think we have a consensus yet.  A stand-alone outline of my\n> > current position is in my v3 RFC [5], but I don't have any buy-in yet\n> > ;).\n> \n> I'll volunteer to prepare a table explaining the different modes\n> in my github wiki. Will scan this thread and your pointers for input\n> and will come back soon when I have something ready.\n\nThanks :).\n\n> >> And we should contrast that to the exact checkout and floating\n> >> branch use cases.\n> > \n> > With my v3 series, there are no more detached HEADs.  Folks using\n> > checkout updates get a local master branch.  I do not change any of\n> > the exact checkout (superproject gitlinked sha1) vs. floating\n> > (subproject's remote submodule.<name>.branch via 'update --remote')\n> > logic, because that already works well.  The problem is the local\n> > branch handling, not the update/integration logic.\n> \n> Ok. Maybe we could use the \"<remote>:<local>\" notation to store both\n> remote and local branch in a single setting?\n\nMeh :p.  I'm fine with (remote-)branch and local-branch as separate\nsettings, or a single combined '<remote>:<local>' setting.  However, I\nthink the local branch name is going to be more closely associated\nwith the superproject branch than with the subproject's remote branch,\nand expect folks to want to override the local-branch on a\nper-superproject-branch basis much more often then they'll override\nthe latter.\n\n> >> later updates,\n> > \n> > The same thing that currently happens, with the exception that\n> > checkout-style updates should use reset to update the\n> > currently-checked out branch (or detached-HEAD), instead of always\n> > detaching the HEAD.\n> \n> Won't the user loose any modifications to his local branch here?\n\nThey just called for a checkout-style update, so yes.  If they want to\nkeep local modifications, chose an integration mode that preserves\nlocal changes.\n\n> >> updates where the local and the remote branch diverged,\n> > \n> > The same thing that currently happens.  For local (non --remote)\n> > updates, the integrated branch is the superproject's gitlinked sha1.\n> > For --remote updates, the integrated branch is the remote subproject's\n> > submodule.<name>.branch.  We integrate that with the\n> > currently-checked-out local branch (or detached HEAD) using the user's\n> > preferred submodule.<name>.update strategy.\n> \n> And for checkout I can easily overwrite the upstream branch with\n> my local changes?\n\n?  I don't understand.  How would you overwrite something in the\nupstream repository?  Maybe you meant \"for checkout I can easily\noverwrite the local changes with the upstream branch\", which is what I\nunderstand checkout to do.\n\n> >> when superproject branches are merged (with and without conflicts),\n> > \n> > I don't think this currently does anything to the submodule itself,\n> > and that makes sense to me (use 'submodule update' or my 'submodule\n> > checkout' if you want such effects).  We should keep the current logic\n> > for updating the gitlinked $sha.  In the case that the\n> > .gitmodule-configured local-branches disagree, we should give the\n> > usual conflict warning (and <<<===>>> markup) and let the user resolve\n> > the conflict in the usual way.\n> \n> For me it makes lots of sense that in recursive checkout mode the\n> merged submodules are already checked out (if possible) right after\n> a superproject merge, making another \"submodule update\" unnecessary\n> (the whole point of recursive update is to make \"submodule update\"\n> obsolete, except for \"--remote\").\n\nIf you force the user to have the configured local-branch checked out\nbefore a non-checkout operations with checkout side-effects (as we\ncurrently do for other kinds of dirty trees), I think you'll avoid\nmost (all?) of the branch-clobbering problems.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240251\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240249\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"232968","messageId":"52CF1764.40604@web.de","threadId":"35584","inReplyTo":"20140109195522.GT29954@odin.tremily.us","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-01-09T21:40:52Z","receivedAt":"2014-01-09T21:40:52Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 09.01.2014 20:55, schrieb W. Trevor King:\n> On Thu, Jan 09, 2014 at 08:23:07PM +0100, Jens Lehmann wrote:\n>> Am 09.01.2014 18:32, schrieb W. Trevor King:\n>>>  However, the local-branch setting needs to be both\n>>> per-submodule and per-superproject-branch, so .git/config doesn't work\n>>> very well.  I think it's better to use something like my\n>>> .git/modules/<submodule-name>/config implementation [1] to set this\n>>> override.\n>>\n>> Yes, the local branch should be set in the submodule's .git/config\n>> to make operations done inside the submodule work seamlessly.\n> \n> Once you're inside the submodule my local-branch setting shouldn't\n> matter, because it just connects superproject branches with submodule\n> branches. The submodule's config is just a convenient out-of-tree\n> place to store per-submodule overrides.\n\nNow I get it, you want to be able to override a submodule branch for\nevery superproject branch. I'm not sure I'd add that in the first\niteration though, as it seems to add quite some complexity and I'm\nnot convinced yet users really need it (but I won't object when we\nfind real world use cases for that).\n\n>>> This lack of per-superproject-branch overrides applies to all of the\n>>> submodule.<name>.* settings, but you're unlikely to want an\n>>> out-of-tree override for 'path' or a per-superproject-branch override\n>>> for 'url', 'ignore', 'update', or 'chRecurseSubmodules'.\n>>\n>> Unlikely it is not ;-) We do have people who set update=none in\n>> the .git/config of the superproject for submodules they don't have\n>> access to (and which is not necessary for their work).\n> \n> That is not a per-superproject-branch override.  local-branch is the\n> only per-submodule config I can think of where I can imagine a sane\n> person actually wanting an out-of-tree per-superproject-branch\n> override.\n\nOops, again I managed to miss the per-superproject*-branch* part.\n\n>> And it isn't a \"per-superproject-branch override\" but a\n>> \"per-superproject-branch default\" which can be overridden in\n>> .git/config (except for 'update', but I intend to fix that).\n> \n> You're talking about .gitmodules vs. .git/config here, but for\n> local-branch, I'm talking about a fallback chain like [1]:\n> \n> 1. superproject.<superproject-branch>.local-branch in the submodule's\n>    config (superproject/.git/modules/≤submodule-name>/config).\n> 2. submodule.<submodule-name>.local-branch in the superproject's\n>    config (.git/config).\n> 3. submodule.<submodule-name>.local-branch in the superproject's\n>    .gitmodules file.\n> 4. default to 'master'\n> \n> Only #1 is a new idea.\n\nThanks for the explanation, now I understand what you're aiming at.\n\n>>> On the other hand, maybe an in-tree .gitmodules is good enough,\n>>> and folks who want a local override can just edit .gitmodules in\n>>> their local branch?  I've never felt the need to override\n>>> .gitmodules myself (for any setting), so feedback from someone who\n>>> has would be useful.\n>>\n>> That way these changes would propagate to others working on the same\n>> branch when pushing, which I believe is a feature.\n> \n> Sure.  Unless they don't want to propagate them, at which point they\n> use an out-of-tree override masking the .gitmodules value.  The\n> question is, would folks want local overrides for local-branch (like\n> they do for submodule.<name>.update), or not?  Since it's easy to do\n> [1], I don't see the point of *not* supporting per-superproject-branch\n> overrides.\n\nUnless actual use cases are shown I'd vote for YAGNI here. A new\nconfig option means considerable maintenance burden, no matter how\neasy it is to implement in the first place.\n\n>>>> It have the impression that attaching the head to the given\n>>>> branch for merge and rebase might be the sensible thing to do,\n>>>> but it would be great to hear from users of merge and rebase if\n>>>> that would break anything for them in their current use cases for\n>>>> these settings.\n>>>\n>>> Which local branch would you attach to before merging?  I think\n>>> 'git submodule update' should always use the current submodule\n>>> state (attached branch or detached HEAD) [3], and we should have a\n>>> separate call that explicitly checked out the desired submodule\n>>> branch [4].\n>>\n>> Like we currently do with \"git submodule update --remote\" (where you\n>> have to have an explicit command telling git when to advance the\n>> branch)? Having a separate call that does something *after* a git\n>> command is exactly the problem I'm trying to fix with recursive\n>> update, so I'm not terribly excited ;-)\n> \n> I'm all for rolling my 'git submodule checkout' into 'git checkout\n> --recurse-submodules' [2].  It was just faster to mock up in shell\n> while we decide how it should work.\n\nSure. As I said that's perfectly fine for testing this approach,\nbut we should do that right in \"git checkout\" and friends and not\nadd yet another submodule command.\n\n>>>>> If it's not the first clone, you should take no action (and your\n>>>>> original patch was ok about this).\n>>>>\n>>>> I'm not sure this is the right thing to do, after all you\n>>>> configured git to follow that branch so I'd expect it to be\n>>>> updated later too, no? Otherwise you might end up with an old\n>>>> version of your branch while upstream is a zillion commits\n>>>> ahead.\n>>>\n>>> Non-clone updates should not change the submodule's *local* branch\n>>> *name*.  They should change the commit that that branch references,\n>>> otherwise 'git submodule update' would be a no-op ;).\n>>\n>> Okay, I seem to have misunderstood that. But what happens when the\n>> branch setting in .gitmodules changes, shouldn't that be updated?\n> \n> Not by 'git submodule update'.  If there are no out-of-tree overrides\n> and the user calls 'git submodule checkout' with a new local-branch in\n> .gitmodules, *that* should checkout a new submodule branch.\n\nHmm, but isn't \"submodule sync\" the command that copies changed\nupstream config values (currently only the url) into the local config?\nThen a subsequent \"submodule update\" could do the actual checkout.\n\n>>>> First I'd like to see a real consensus about what exactly should\n>>>> happen when a branch is configured to be checked out (and if I\n>>>> missed such a summary in this thread, please point me to it ;-).\n>>>\n>>> I don't think we have a consensus yet.  A stand-alone outline of my\n>>> current position is in my v3 RFC [5], but I don't have any buy-in yet\n>>> ;).\n>>\n>> I'll volunteer to prepare a table explaining the different modes\n>> in my github wiki. Will scan this thread and your pointers for input\n>> and will come back soon when I have something ready.\n> \n> Thanks :).\n\nA first - rather basic - attempt can be seen at:\n\n   https://github.com/jlehmann/git-submod-enhancements/wiki/Submodule-modes\n\nInput of any kind is very welcome!\n\n>>>> And we should contrast that to the exact checkout and floating\n>>>> branch use cases.\n>>>\n>>> With my v3 series, there are no more detached HEADs.  Folks using\n>>> checkout updates get a local master branch.  I do not change any of\n>>> the exact checkout (superproject gitlinked sha1) vs. floating\n>>> (subproject's remote submodule.<name>.branch via 'update --remote')\n>>> logic, because that already works well.  The problem is the local\n>>> branch handling, not the update/integration logic.\n>>\n>> Ok. Maybe we could use the \"<remote>:<local>\" notation to store both\n>> remote and local branch in a single setting?\n> \n> Meh :p.  I'm fine with (remote-)branch and local-branch as separate\n> settings, or a single combined '<remote>:<local>' setting.  However, I\n> think the local branch name is going to be more closely associated\n> with the superproject branch than with the subproject's remote branch,\n> and expect folks to want to override the local-branch on a\n> per-superproject-branch basis much more often then they'll override\n> the latter.\n\nOkay. This is a detail we can decide later.\n\n>>>> later updates,\n>>>\n>>> The same thing that currently happens, with the exception that\n>>> checkout-style updates should use reset to update the\n>>> currently-checked out branch (or detached-HEAD), instead of always\n>>> detaching the HEAD.\n>>\n>> Won't the user loose any modifications to his local branch here?\n> \n> They just called for a checkout-style update, so yes.  If they want to\n> keep local modifications, chose an integration mode that preserves\n> local changes.\n\nHmm, as current \"submodule updates\" already makes it too easy to\nloose commits, this does not look right to me. I'd prefer to stop\nat that point and tell the user what he can do to solve the conflict.\n\n>>>> updates where the local and the remote branch diverged,\n>>>\n>>> The same thing that currently happens.  For local (non --remote)\n>>> updates, the integrated branch is the superproject's gitlinked sha1.\n>>> For --remote updates, the integrated branch is the remote subproject's\n>>> submodule.<name>.branch.  We integrate that with the\n>>> currently-checked-out local branch (or detached HEAD) using the user's\n>>> preferred submodule.<name>.update strategy.\n>>\n>> And for checkout I can easily overwrite the upstream branch with\n>> my local changes?\n> \n> ?  I don't understand.  How would you overwrite something in the\n> upstream repository?\n\nIf the update doesn't overwrite the user-updated local branch (what\nI assumed it would do to protect his changes) and he pushes that.\n\n> Maybe you meant \"for checkout I can easily\n> overwrite the local changes with the upstream branch\", which is what I\n> understand checkout to do.\n\nBut which I find really unfriendly and would not like to see in a new\nfeature. We should protect the user from loosing any local changes,\nnot simply throw them away. Recursive update makes sure it won't\noverwrite any local modification before it checks out anything and\nwill abort before doing so (unless forced of course).\n\n>>>> when superproject branches are merged (with and without conflicts),\n>>>\n>>> I don't think this currently does anything to the submodule itself,\n>>> and that makes sense to me (use 'submodule update' or my 'submodule\n>>> checkout' if you want such effects).  We should keep the current logic\n>>> for updating the gitlinked $sha.  In the case that the\n>>> .gitmodule-configured local-branches disagree, we should give the\n>>> usual conflict warning (and <<<===>>> markup) and let the user resolve\n>>> the conflict in the usual way.\n>>\n>> For me it makes lots of sense that in recursive checkout mode the\n>> merged submodules are already checked out (if possible) right after\n>> a superproject merge, making another \"submodule update\" unnecessary\n>> (the whole point of recursive update is to make \"submodule update\"\n>> obsolete, except for \"--remote\").\n> \n> If you force the user to have the configured local-branch checked out\n> before a non-checkout operations with checkout side-effects (as we\n> currently do for other kinds of dirty trees), I think you'll avoid\n> most (all?) of the branch-clobbering problems.\n\nI'm thinking that a local branch works in two directions: It should\nmake it easy to follow an upstream branch and also make changes to it\n(and publish those) if necessary. But neither local nor upstream\nchanges take precedence, so the user should either use \"merge\" or\n\"rebase\" as update strategy or be asked to resolve the conflict\nmanually when \"checkout\" is configured and the branches diverged.\nDoes that make sense?\n"},{"id":"232973","messageId":"20140109221840.GW29954@odin.tremily.us","threadId":"35584","inReplyTo":"52CF1764.40604@web.de","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-09T22:18:40Z","receivedAt":"2014-01-09T22:18:40Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 09, 2014 at 10:40:52PM +0100, Jens Lehmann wrote:\n> Am 09.01.2014 20:55, schrieb W. Trevor King:\n> > On Thu, Jan 09, 2014 at 08:23:07PM +0100, Jens Lehmann wrote:\n> >> Am 09.01.2014 18:32, schrieb W. Trevor King:\n> >>>  However, the local-branch setting needs to be both\n> >>> per-submodule and per-superproject-branch, so .git/config doesn't work\n> >>> very well.  I think it's better to use something like my\n> >>> .git/modules/<submodule-name>/config implementation [1] to set this\n> >>> override.\n> >>\n> >> Yes, the local branch should be set in the submodule's .git/config\n> >> to make operations done inside the submodule work seamlessly.\n> > \n> > Once you're inside the submodule my local-branch setting shouldn't\n> > matter, because it just connects superproject branches with submodule\n> > branches. The submodule's config is just a convenient out-of-tree\n> > place to store per-submodule overrides.\n> \n> Now I get it, you want to be able to override a submodule branch for\n> every superproject branch. I'm not sure I'd add that in the first\n> iteration though, as it seems to add quite some complexity and I'm\n> not convinced yet users really need it (but I won't object when we\n> find real world use cases for that).\n\nNot much complexity in the code, it's all in the first patch of my v3\nseries [1].  Adding a new override location doesn't seem that\ncomplicated to me, but I haven't been very successful at getting this\nidea across, so maybe it's weirder than I think ;).  Clearer\nexplanations welcome ;).\n\n> >> And it isn't a \"per-superproject-branch override\" but a\n> >> \"per-superproject-branch default\" which can be overridden in\n> >> .git/config (except for 'update', but I intend to fix that).\n> > \n> > You're talking about .gitmodules vs. .git/config here, but for\n> > local-branch, I'm talking about a fallback chain like [1]:\n> > \n> > 1. superproject.<superproject-branch>.local-branch in the submodule's\n> >    config (superproject/.git/modules/≤submodule-name>/config).\n> > 2. submodule.<submodule-name>.local-branch in the superproject's\n> >    config (.git/config).\n> > 3. submodule.<submodule-name>.local-branch in the superproject's\n> >    .gitmodules file.\n> > 4. default to 'master'\n> > \n> > Only #1 is a new idea.\n> \n> Thanks for the explanation, now I understand what you're aiming at.\n\nFor additional clarity, my whole v3 series is not super long [2]… ;)\n\n> >>> On the other hand, maybe an in-tree .gitmodules is good enough,\n> >>> and folks who want a local override can just edit .gitmodules in\n> >>> their local branch?  I've never felt the need to override\n> >>> .gitmodules myself (for any setting), so feedback from someone\n> >>> who has would be useful.\n> >>\n> >> That way these changes would propagate to others working on the\n> >> same branch when pushing, which I believe is a feature.\n> > \n> > Sure.  Unless they don't want to propagate them, at which point\n> > they use an out-of-tree override masking the .gitmodules value.\n> > The question is, would folks want local overrides for local-branch\n> > (like they do for submodule.<name>.update), or not?  Since it's\n> > easy to do [1], I don't see the point of *not* supporting\n> > per-superproject-branch overrides.\n> \n> Unless actual use cases are shown I'd vote for YAGNI here. A new\n> config option means considerable maintenance burden, no matter how\n> easy it is to implement in the first place.\n\nAutomatically checking out the preferred submodule branch for a given\nsuperproject branch already requires a new config option.  The\nper-superproject-branch out-of-tree override just renames it (from\nsubmodule.<submodule-name>.local-branch to\nsuperproject.<superproject-branch>.local-branch).  So different names\ndepending on superproject-level or submodule-level config, but still\nthe same option.  That doesn't sound like it's adding that much of a\nmaintenance burden.\n\nOn the other hand, I, personally, have no need for out-of-tree\noverrides for *any* submodule-related config, so I'm fine if we drop\nthe submodule-level lookup location ;).\n\n> > I'm all for rolling my 'git submodule checkout' into 'git checkout\n> > --recurse-submodules' [2].  It was just faster to mock up in shell\n> > while we decide how it should work.\n> \n> Sure. As I said that's perfectly fine for testing this approach,\n> but we should do that right in \"git checkout\" and friends and not\n> add yet another submodule command.\n\nThe current C code looked fairly focused on detached HEAD sha1\ncheckouts, which was so far away from what I think should happen that\nI didn't know where to start ;).  If we like the logic layed out in my\nv3 series, I'll take another look at the C series and see if I can\ncome up with something.\n\n> >>>>> If it's not the first clone, you should take no action (and your\n> >>>>> original patch was ok about this).\n> >>>>\n> >>>> I'm not sure this is the right thing to do, after all you\n> >>>> configured git to follow that branch so I'd expect it to be\n> >>>> updated later too, no? Otherwise you might end up with an old\n> >>>> version of your branch while upstream is a zillion commits\n> >>>> ahead.\n> >>>\n> >>> Non-clone updates should not change the submodule's *local* branch\n> >>> *name*.  They should change the commit that that branch references,\n> >>> otherwise 'git submodule update' would be a no-op ;).\n> >>\n> >> Okay, I seem to have misunderstood that. But what happens when the\n> >> branch setting in .gitmodules changes, shouldn't that be updated?\n> > \n> > Not by 'git submodule update'.  If there are no out-of-tree overrides\n> > and the user calls 'git submodule checkout' with a new local-branch in\n> > .gitmodules, *that* should checkout a new submodule branch.\n> \n> Hmm, but isn't \"submodule sync\" the command that copies changed\n> upstream config values (currently only the url) into the local config?\n> Then a subsequent \"submodule update\" could do the actual checkout.\n\n'submodule update' currently only checks out detached HEADs with the\n'checkout' update mode.  I got rid of that in my v3 series, so now all\n'submodule update' does is integrate some branch (the gitlinked sha1\nor the upstream --remote).  It has nothing to do with changing the\nlocally-checked-out branch.\n\n> >>>> later updates,\n> >>>\n> >>> The same thing that currently happens, with the exception that\n> >>> checkout-style updates should use reset to update the\n> >>> currently-checked out branch (or detached-HEAD), instead of\n> >>> always detaching the HEAD.\n> >>\n> >> Won't the user loose any modifications to his local branch here?\n> > \n> > They just called for a checkout-style update, so yes.  If they\n> > want to keep local modifications, chose an integration mode that\n> > preserves local changes.\n> \n> Hmm, as current \"submodule updates\" already makes it too easy to\n> loose commits, this does not look right to me. I'd prefer to stop at\n> that point and tell the user what he can do to solve the conflict.\n\nUsers who are worried about loosing local updates should not be using\na checkout-style updates.  If they are using a checkout-style update,\nand they ask for an update, they're specifically requesting that we\nblow away their local work and checkout/reset to the new sha1.\nSolving update conflicts is the whole point of the non-checkout update\nmodes.\n\n> > Maybe you meant \"for checkout I can easily overwrite the local\n> > changes with the upstream branch\", which is what I understand\n> > checkout to do.\n> \n> But which I find really unfriendly and would not like to see in a\n> new feature. We should protect the user from loosing any local\n> changes, not simply throw them away. Recursive update makes sure it\n> won't overwrite any local modification before it checks out anything\n> and will abort before doing so (unless forced of course).\n\nIf you want to get rid of checkout-mode updates, I'm fine with that.\nHowever, I don't think it supports use-cases like Heiko's (implied) “I\ndon't care what's happening upstream, I never touch that submodule,\njust checkout what the superproject maintainer says should be checked\nout for this branch.  Even if they have been rebasing or whatever”\n[3].\n\n> >>>> when superproject branches are merged (with and without conflicts),\n> >>>\n> >>> I don't think this currently does anything to the submodule itself,\n> >>> and that makes sense to me (use 'submodule update' or my 'submodule\n> >>> checkout' if you want such effects).  We should keep the current logic\n> >>> for updating the gitlinked $sha.  In the case that the\n> >>> .gitmodule-configured local-branches disagree, we should give the\n> >>> usual conflict warning (and <<<===>>> markup) and let the user resolve\n> >>> the conflict in the usual way.\n> >>\n> >> For me it makes lots of sense that in recursive checkout mode the\n> >> merged submodules are already checked out (if possible) right after\n> >> a superproject merge, making another \"submodule update\" unnecessary\n> >> (the whole point of recursive update is to make \"submodule update\"\n> >> obsolete, except for \"--remote\").\n> > \n> > If you force the user to have the configured local-branch checked out\n> > before a non-checkout operations with checkout side-effects (as we\n> > currently do for other kinds of dirty trees), I think you'll avoid\n> > most (all?) of the branch-clobbering problems.\n> \n> I'm thinking that a local branch works in two directions: It should\n> make it easy to follow an upstream branch and also make changes to it\n> (and publish those) if necessary.\n\nThose both sound like “integration with the remote submodule” issues\nto me.  I'm more worried about what happens purely locally as the\ndeveloper checks out different superproject branches and wants the\nsubmodules to follow along automatically (without detaching HEADs).\nOnce we have something that works there, I expect it will be easier to\nadd recursive superproject branch integration cleanly.  For example,\nall of the usual branch-level config options (branch.<name>.*) come\nalong for free.\n\n> But neither local nor upstream changes take precedence, so the user\n> should either use \"merge\" or \"rebase\" as update strategy\n\nThat sounds good to me.\n\n> or be asked to resolve the conflict manually when \"checkout\" is\n> configured and the branches diverged.\n\nI still think that checkout-mode updates should be destructive.  See\nmy paraphrased-version of Heiko's use case above.  How are they going\nto resolve this manually?  Merge or rebase?  Why weren't they using\nthat update mode in the first place?\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240251\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240248\n[3]: http://article.gmane.org/gmane.comp.version-control.git/240013\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233055","messageId":"xmqqd2jv7pr1.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"CALas-igDaweib14zaLJk3m1zmBWk=14oA7h_e7G82vpxmBjiOg@mail.gmail.com","subject":"Re: [PATCH/RFC] Introduce git submodule add|update --attach","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-13T17:31:14Z","receivedAt":"2014-01-13T17:31:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Francesco Pretto <ceztko@gmail.com> writes:\n\n> Thanks for the comments, my replies below. Before, a couple of general\n> questions:\n> - I'm also writing some tests, should I commit them together with the\n> feature patch?\n> - to determine the attached/detached state I did this:\n>\n> head_detached=\n> if test \"$(rev-parse --abbrev-ref HEAD)\" = \"HEAD\"\n> then\n>     head_detached=\"true\"\n> fi\n\nUse \"git symbolic-ref HEAD\" to read off of it.\n"},{"id":"233085","messageId":"20140114102445.GA27915@sandbox-ub","threadId":"35584","inReplyTo":"20140109221840.GW29954@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-14T10:24:45Z","receivedAt":"2014-01-14T10:24:45Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Hi,\n\nOn Thu, Jan 09, 2014 at 02:18:40PM -0800, W. Trevor King wrote:\n> On Thu, Jan 09, 2014 at 10:40:52PM +0100, Jens Lehmann wrote:\n> > Am 09.01.2014 20:55, schrieb W. Trevor King:\n> > > On Thu, Jan 09, 2014 at 08:23:07PM +0100, Jens Lehmann wrote:\n> > >> Am 09.01.2014 18:32, schrieb W. Trevor King:\n> > >>>> later updates,\n> > >>>\n> > >>> The same thing that currently happens, with the exception that\n> > >>> checkout-style updates should use reset to update the\n> > >>> currently-checked out branch (or detached-HEAD), instead of\n> > >>> always detaching the HEAD.\n> > >>\n> > >> Won't the user loose any modifications to his local branch here?\n> > > \n> > > They just called for a checkout-style update, so yes.  If they\n> > > want to keep local modifications, chose an integration mode that\n> > > preserves local changes.\n> > \n> > Hmm, as current \"submodule updates\" already makes it too easy to\n> > loose commits, this does not look right to me. I'd prefer to stop at\n> > that point and tell the user what he can do to solve the conflict.\n> \n> Users who are worried about loosing local updates should not be using\n> a checkout-style updates.  If they are using a checkout-style update,\n> and they ask for an update, they're specifically requesting that we\n> blow away their local work and checkout/reset to the new sha1.\n> Solving update conflicts is the whole point of the non-checkout update\n> modes.\n\nBut checkout is different from reset --hard in that it does not blow\naway local uncommitted changes. Please see below.\n\n> > > Maybe you meant \"for checkout I can easily overwrite the local\n> > > changes with the upstream branch\", which is what I understand\n> > > checkout to do.\n> > \n> > But which I find really unfriendly and would not like to see in a\n> > new feature. We should protect the user from loosing any local\n> > changes, not simply throw them away. Recursive update makes sure it\n> > won't overwrite any local modification before it checks out anything\n> > and will abort before doing so (unless forced of course).\n> \n> If you want to get rid of checkout-mode updates, I'm fine with that.\n> However, I don't think it supports use-cases like Heiko's (implied) “I\n> don't care what's happening upstream, I never touch that submodule,\n> just checkout what the superproject maintainer says should be checked\n> out for this branch.  Even if they have been rebasing or whatever”\n> [3].\n\nI never stated that in that post. Even with the current checkout-mode\nupdates you'll never loose local modifications (without force) that are\nnot committed. I think you have to distinguish between local\nmodifications in the worktree and the ones that are committed.\n\nThe recursive checkout Jens is working on is simply implementing the\ncurrent checkout-mode to the places where the superproject checks out\nits files. That way submodules get checked out when the superproject is\nchecked out. If the submodule does not match the sha1 registered in the\nsuperproject it either stays there (if the checkout would not need to\nupdate the submodule) or (if checkout would need to update) git will not\ndo the checkout and bail out with \"you have local modifications to ... .\n\nI think the whole recursive checkout topic is already complicated enough\nas it is so we should currently not add anything from this discussion to\nit until it is cleaned up and merged. We also need recursive fetch for\nthat which I am planning to work on as soon as we settle this\ndiscussion. I will write another post about how I think we should/can\nproceed.\n\n> > or be asked to resolve the conflict manually when \"checkout\" is\n> > configured and the branches diverged.\n> \n> I still think that checkout-mode updates should be destructive.  See\n> my paraphrased-version of Heiko's use case above.  How are they going\n> to resolve this manually?  Merge or rebase?  Why weren't they using\n> that update mode in the first place?\n\nI strongly disagree. They should only be destructive in the sense that\nanother commit get checked out but never loose local modifications.\n\n> [1]: http://article.gmane.org/gmane.comp.version-control.git/240251\n> [2]: http://article.gmane.org/gmane.comp.version-control.git/240248\n> [3]: http://article.gmane.org/gmane.comp.version-control.git/240013\n\nCheers Heiko\n"},{"id":"233092","messageId":"20140114165709.GH7078@odin.tremily.us","threadId":"35584","inReplyTo":"20140114102445.GA27915@sandbox-ub","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-14T16:57:09Z","receivedAt":"2014-01-14T16:57:09Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 14, 2014 at 11:24:45AM +0100, Heiko Voigt wrote:\n> On Thu, Jan 09, 2014 at 02:18:40PM -0800, W. Trevor King wrote:\n> > Users who are worried about loosing local updates should not be\n> > using a checkout-style updates.  If they are using a\n> > checkout-style update, and they ask for an update, they're\n> > specifically requesting that we blow away their local work and\n> > checkout/reset to the new sha1.  Solving update conflicts is the\n> > whole point of the non-checkout update modes.\n> \n> But checkout is different from reset --hard in that it does not blow\n> away local uncommitted changes. Please see below.\n\nAh, good point.  We should definately die if there are local\nuncommitted changes.\n\n> > On Thu, Jan 09, 2014 at 10:40:52PM +0100, Jens Lehmann wrote:\n> > > Am 09.01.2014 20:55, schrieb W. Trevor King:\n> > > > Maybe you meant \"for checkout I can easily overwrite the local\n> > > > changes with the upstream branch\", which is what I understand\n> > > > checkout to do.\n> > > \n> > > But which I find really unfriendly and would not like to see in\n> > > a new feature. We should protect the user from loosing any local\n> > > changes, not simply throw them away. Recursive update makes sure\n> > > it won't overwrite any local modification before it checks out\n> > > anything and will abort before doing so (unless forced of\n> > > course).\n> > \n> > If you want to get rid of checkout-mode updates, I'm fine with\n> > that.  However, I don't think it supports use-cases like Heiko's\n> > (implied) “I don't care what's happening upstream, I never touch\n> > that submodule, just checkout what the superproject maintainer\n> > says should be checked out for this branch.  Even if they have\n> > been rebasing or whatever” [3].\n> \n> I never stated that in that post.\n\nSorry for misunderstanding.  I think I'm just unclear on your\nworkflow?\n\n> The recursive checkout Jens is working on is simply implementing the\n> current checkout-mode to the places where the superproject checks\n> out its files. That way submodules get checked out when the\n> superproject is checked out. If the submodule does not match the\n> sha1 registered in the superproject it either stays there (if the\n> checkout would not need to update the submodule) or (if checkout\n> would need to update) git will not do the checkout and bail out with\n> \"you have local modifications to ... .\n\nSounds good to me as far as it goes.  I think it misses the “what\nshould we do if the gitlinked hashes are different” case, because the\ncheckout will always leave you with a detached HEAD.\n\n> > > or be asked to resolve the conflict manually when \"checkout\" is\n> > > configured and the branches diverged.\n> > \n> > I still think that checkout-mode updates should be destructive.\n> > See my paraphrased-version of Heiko's use case above.  How are\n> > they going to resolve this manually?  Merge or rebase?  Why\n> > weren't they using that update mode in the first place?\n> \n> I strongly disagree. They should only be destructive in the sense\n> that another commit get checked out but never loose local\n> modifications.\n\nI think the key I'm missing is an example workflow where a developer\nwants to make local submodule changes, but also wants to use\ncheckout-mode updates instead of merge/rebase updates.  Can you sketch\none out for me?\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233104","messageId":"20140114205830.GA838@sandbox-ub","threadId":"35584","inReplyTo":"20140114165709.GH7078@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-14T20:58:30Z","receivedAt":"2014-01-14T20:58:30Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Tue, Jan 14, 2014 at 08:57:09AM -0800, W. Trevor King wrote:\n> > > On Thu, Jan 09, 2014 at 10:40:52PM +0100, Jens Lehmann wrote:\n> > > > Am 09.01.2014 20:55, schrieb W. Trevor King:\n> > > > > Maybe you meant \"for checkout I can easily overwrite the local\n> > > > > changes with the upstream branch\", which is what I understand\n> > > > > checkout to do.\n> > > > \n> > > > But which I find really unfriendly and would not like to see in\n> > > > a new feature. We should protect the user from loosing any local\n> > > > changes, not simply throw them away. Recursive update makes sure\n> > > > it won't overwrite any local modification before it checks out\n> > > > anything and will abort before doing so (unless forced of\n> > > > course).\n> > > \n> > > If you want to get rid of checkout-mode updates, I'm fine with\n> > > that.  However, I don't think it supports use-cases like Heiko's\n> > > (implied) “I don't care what's happening upstream, I never touch\n> > > that submodule, just checkout what the superproject maintainer\n> > > says should be checked out for this branch.  Even if they have\n> > > been rebasing or whatever” [3].\n> > \n> > I never stated that in that post.\n> \n> Sorry for misunderstanding.  I think I'm just unclear on your\n> workflow?\n\nYes probably. We mostly use submodules for shared code and for tracking\nexternal libraries. For the shared code we want to make sure that\nthe changes that come from one project do not break anything in another\nproject that also uses that code so the submodules are maintained and\nreviewed separately and ideally contain tests for the expected\nfunctionality.\n\nA typical workflow where a feature in a project needs some extension or\nchange in a submodule goes like this:\n\n1. The developer does his changes locally implementing everything\n   needed. To commit he creates a local branch in the submodule and in\n   the superproject (most of the times from the current HEAD that is\n   checked out).\n\n2. For convenience I usually commit the resulting commit sha1 of the\n   submodule in the commit that needs the change. That way when I switch\n   to a different branch and back I can simply say: git submodule update\n   and get the correct code everywhere.\n\n3. Once done with the whole feature I first do the review process\n   (adding any missing tests to ensure my change does not break, ...)\n   for the submodule to get the feature branch merged into a stable one.\n   In our superproject only commits sha1 from a stable branch are\n   allowed so the submodule change needs to be reviewed first.\n\n4. Once the change is in a stable branch in the submodule I then update\n   the commit sha1 link in the superproject that needs the change. That\n   is usually done by rebasing the branch in the superproject and\n   registering the new stable branch (typically master).\n\n5. Then I proceed with the review process in the superproject as if it\n   was a normal change without a submodule.\n\nThats our main use case.\n\n> > The recursive checkout Jens is working on is simply implementing the\n> > current checkout-mode to the places where the superproject checks\n> > out its files. That way submodules get checked out when the\n> > superproject is checked out. If the submodule does not match the\n> > sha1 registered in the superproject it either stays there (if the\n> > checkout would not need to update the submodule) or (if checkout\n> > would need to update) git will not do the checkout and bail out with\n> > \"you have local modifications to ... .\n> \n> Sounds good to me as far as it goes.  I think it misses the “what\n> should we do if the gitlinked hashes are different” case, because the\n> checkout will always leave you with a detached HEAD.\n> \n> > > > or be asked to resolve the conflict manually when \"checkout\" is\n> > > > configured and the branches diverged.\n> > > \n> > > I still think that checkout-mode updates should be destructive.\n> > > See my paraphrased-version of Heiko's use case above.  How are\n> > > they going to resolve this manually?  Merge or rebase?  Why\n> > > weren't they using that update mode in the first place?\n> > \n> > I strongly disagree. They should only be destructive in the sense\n> > that another commit get checked out but never loose local\n> > modifications.\n> \n> I think the key I'm missing is an example workflow where a developer\n> wants to make local submodule changes, but also wants to use\n> checkout-mode updates instead of merge/rebase updates.  Can you sketch\n> one out for me?\n\nHow about the use-case I sketched above? Is that what you are searching\nfor? In that use-case we have to update to the new master after a\nsubmodule change was merged. That could be achieved by\n\n\tgit submodule update --remote <submodule>\n\nwith the wanted stable branch configured. But in practise something\nalong the lines of\n\n\t(cd <submodule> && git checkout origin/<stable>)\n\nis usually used and simple enough.\n\nWe have a tool in our git gui configuration that does\n\n\tgit submodule foreach 'git fetch && git checkout origin/master'\n\nwhich can be used by the maintainer before a release to ensure that all\nsubmodules are up-to-date. But in practise it turn out that all\nsubmodules are fairly current since everyone is adding features to the\nquite frequently and thus pulling in the current version automatically.\n\nI hope that draws a clear picture of how we use submodules.\n\nCheers Heiko\n"},{"id":"233105","messageId":"20140114214209.GJ23617@odin.tremily.us","threadId":"35584","inReplyTo":"20140114205830.GA838@sandbox-ub","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-14T21:42:09Z","receivedAt":"2014-01-14T21:42:09Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 14, 2014 at 09:58:30PM +0100, Heiko Voigt wrote:\n> A typical workflow where a feature in a project needs some extension or\n> change in a submodule goes like this:\n> \n> 1. The developer does his changes locally implementing everything\n>    needed. To commit he creates a local branch in the submodule and in\n>    the superproject (most of the times from the current HEAD that is\n>    checked out).\n> \n> 2. For convenience I usually commit the resulting commit sha1 of the\n>    submodule in the commit that needs the change. That way when I switch\n>    to a different branch and back I can simply say: git submodule update\n>    and get the correct code everywhere.\n\nThis checkout functionality is exactly what my\nsubmodule.<name>.localBranch is designed to automate [1].  I think\nthat should be different from integrating local and external changes,\nwhich is what 'git submodule update' is about.  For example, after you\nrun 'git submodule update' here, you'll have your original commit\nchecked out, but you'll be on a detached HEAD instead of your original\nbranch.  If you want to further develop the submodule feature branch,\nyou currently have to cd into the submodule and check the branch out\nby hand.\n\n> How about the use-case I sketched above? Is that what you are searching\n> for? In that use-case we have to update to the new master after a\n> submodule change was merged. That could be achieved by\n> \n> \tgit submodule update --remote <submodule>\n> \n> with the wanted stable branch configured. But in practise something\n> along the lines of\n> \n> \t(cd <submodule> && git checkout origin/<stable>)\n> \n> is usually used and simple enough.\n\nThe “gitlinked commits must be in the subproject's master” rule\nprotects you from blowing stuff away here.  You could use rebase- or\nmerge-style integration as well, assuming the maintainer didn't have\ndirty local work in their submodule.\n\n> We have a tool in our git gui configuration that does\n> \n> \tgit submodule foreach 'git fetch && git checkout origin/master'\n\nI agree that with 'submodule update' seems superfluous.  With proper\nout-of-tree submodule configs specifying remote URLs and upstream\nbranches,\n\n  git submodule foreach 'git fetch && git checkout @{upstream}'\n\n(or merge/rebase/…) should cover this case more generically and with\nless mental overhead.\n\n> I hope that draws a clear picture of how we use submodules.\n\nIt's certainly clearer, thanks :).  I'm not sure where checkout-mode\nis specifically important, though.  In your step-2, it doesn't restore\nyour original branch.  In your “update the superproject's master”\nstep, you aren't even using 'submodule update' :p.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240336\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233106","messageId":"20140114214608.GB838@sandbox-ub","threadId":"35584","inReplyTo":"20140114102445.GA27915@sandbox-ub","subject":"Re: Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-14T21:46:08Z","receivedAt":"2014-01-14T21:46:08Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Hi,\n\nOn Tue, Jan 14, 2014 at 11:24:45AM +0100, Heiko Voigt wrote:\n> I will write another post about how I think we should/can proceed.\n\nand here is my suggestion how we should proceed.\n\nI think there have been many interesting ideas in this thread but IMO\nsome of them tried to achieve a little bit to much and were not clear\nenough. I am a fan of: Keep it as simple as possible, but *no simpler*.\nI think some ideas where going in the \"make it to simple\" direction.\n\nTake my idea for feature branch support from here[1]. After thinking more\nthoroughly it still too many corner cases. E.g. it is way to easy to\naccidentally merge the feature branch configuration into the stable branch. But\nwe want to support the user properly so we need to catch stuff like that.\n\nSubmodules are separate projects. There is a boundary between\nsuperproject and submodule and IMO its there for a good reason. E.g.\ntake the typical \"shared code\" use-case. If A and B are using C\nthen both want to make sure a change from A does not break B's\nexpectations and vice versa. Thats were you usually write unit tests in\nC for: Ensure that the expectations are met. The more users of the code\nthe higher the quality and thus the boundary for bad code should be.\n\nI would like to step back a bit and get back to the original problem at hand:\nFrancescos original use case of an attached head for direct commits on a stable\nbranch in a submodule. How about we finish discussing the exact solution of\nthat first. AFAIK that is already solved with the following:\n\n * Trevor's first patch[2] to create a branch on initial clone of a submodule\n * A possibly a configuration variable for --remote so it can be\n   set as the default update method\n * Combined with submodule.<name>.update=merge/rebase\n\nThat should be all (and IIRC Francesco agreed) needed for that use-case.\n\nLets not implement more than currently is needed. We can revisit the ideas once\nsome other real use-case manifests. Also we (Jens and I) would first like to\nproceed with the recursive checkout / fetch (for which the plan is clear) as\nthe next complicated step.\n\nOnce that is done and people gain some experience with it we can still extend\nfurther.\n\nWhat do you think?\n\nCheers Heiko\n\n[1] http://article.gmane.org/gmane.comp.version-control.git/240178/\n[2] http://article.gmane.org/gmane.comp.version-control.git/239921\n"},{"id":"233108","messageId":"20140114221907.GC838@sandbox-ub","threadId":"35584","inReplyTo":"20140114214209.GJ23617@odin.tremily.us","subject":"Re: Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-14T22:19:07Z","receivedAt":"2014-01-14T22:19:07Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Tue, Jan 14, 2014 at 01:42:09PM -0800, W. Trevor King wrote:\n> On Tue, Jan 14, 2014 at 09:58:30PM +0100, Heiko Voigt wrote:\n> > A typical workflow where a feature in a project needs some extension or\n> > change in a submodule goes like this:\n> > \n> > 1. The developer does his changes locally implementing everything\n> >    needed. To commit he creates a local branch in the submodule and in\n> >    the superproject (most of the times from the current HEAD that is\n> >    checked out).\n> > \n> > 2. For convenience I usually commit the resulting commit sha1 of the\n> >    submodule in the commit that needs the change. That way when I switch\n> >    to a different branch and back I can simply say: git submodule update\n> >    and get the correct code everywhere.\n> \n> This checkout functionality is exactly what my\n> submodule.<name>.localBranch is designed to automate [1].  I think\n> that should be different from integrating local and external changes,\n> which is what 'git submodule update' is about.  For example, after you\n> run 'git submodule update' here, you'll have your original commit\n> checked out, but you'll be on a detached HEAD instead of your original\n> branch.  If you want to further develop the submodule feature branch,\n> you currently have to cd into the submodule and check the branch out\n> by hand.\n\nYes and thats exactly what my idea was about but after further thinking\nam afraid that this is the wrong place. I am not sure but afraid as I\nwrote in the other post that it would be way to dangerous to accidentally\nmerge these changes in. We would need something to prevent this\nconfiguration from ever entering a stable branch.\n\nAnother solution (and completely different approach) would be to have\nsomething that is outside of the tree and actually attached to a\nbranchname. E.g. at the gitmerge last year I though it would be nice to\nhave a place for a description for a branch inside git. In a short\ndiscussion we were envisioning a special ref like the notes trees but\nallowing to attach and describe branches. That place could also be where\nwe could store such a configuration. Once the branchname ceases to exist\nso would the configuration.\n\nI know this is a completely different piece of work so I am not sure\nwhether we want to pursue it at the moment. But at the moment I think\nthis would actually be the correct solution.\n\n> > How about the use-case I sketched above? Is that what you are searching\n> > for? In that use-case we have to update to the new master after a\n> > submodule change was merged. That could be achieved by\n> > \n> > \tgit submodule update --remote <submodule>\n> > \n> > with the wanted stable branch configured. But in practise something\n> > along the lines of\n> > \n> > \t(cd <submodule> && git checkout origin/<stable>)\n> > \n> > is usually used and simple enough.\n> \n> The “gitlinked commits must be in the subproject's master” rule\n> protects you from blowing stuff away here.  You could use rebase- or\n> merge-style integration as well, assuming the maintainer didn't have\n> dirty local work in their submodule.\n\nNo we can't. Developers are not allowed to merge in some submodules.\nThe most central ones have maintainers and only they are allowed to\nmerge into the stable branch. So we need to track exact commits on the\nstable branch, no local merge (except the fast-forward case of course)\nallowed. Thats why the developer does an exact checkout here.\n\n> > We have a tool in our git gui configuration that does\n> > \n> > \tgit submodule foreach 'git fetch && git checkout origin/master'\n> \n> I agree that with 'submodule update' seems superfluous.  With proper\n> out-of-tree submodule configs specifying remote URLs and upstream\n> branches,\n> \n>   git submodule foreach 'git fetch && git checkout @{upstream}'\n> \n> (or merge/rebase/…) should cover this case more generically and with\n> less mental overhead.\n> \n> > I hope that draws a clear picture of how we use submodules.\n> \n> It's certainly clearer, thanks :).  I'm not sure where checkout-mode\n> is specifically important, though.  In your step-2, it doesn't restore\n> your original branch.  In your “update the superproject's master”\n> step, you aren't even using 'submodule update' :p.\n\nAh sorry I though that was clear. The \"others\" are using submodule update ;-)\n\nI mean someone who gets stuff from a stable superproject branch by\neither rebasing their development branch or updating their local copy of\na stable branch (e.g. master) by using\n\n\tgit checkout master\n\tgit pull --ff --ff-only\n\tgit submodule update --init --recursive\n\nThis also prevents the pure \"updaters\" from creating unnecessary merges.\n\nCheers Heiko\n\n> [1]: http://article.gmane.org/gmane.comp.version-control.git/240336\n"},{"id":"233109","messageId":"20140114222231.GA2647@odin.tremily.us","threadId":"35584","inReplyTo":"20140114214608.GB838@sandbox-ub","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-14T22:22:31Z","receivedAt":"2014-01-14T22:22:31Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 14, 2014 at 10:46:08PM +0100, Heiko Voigt wrote:\n> I would like to step back a bit and get back to the original problem\n> at hand: Francescos original use case of an attached head for direct\n> commits on a stable branch in a submodule. How about we finish\n> discussing the exact solution of that first. AFAIK that is already\n> solved with the following:\n> \n>  * Trevor's first patch[2] to create a branch on initial clone of a submodule\n\nv1 broke a bunch of tests.  Are you ok with v2 [1]?  v2 still needs a\nclearer commit message, a test, and a possible transition to\ntriggering on non-checkout submodule.<name>.update instead of\nnon-empty submodule.<name>.branch [2].\n\n> That should be all (and IIRC Francesco agreed) needed for that use-case.\n\nThat was my understanding [3] ;).\n\n> Lets not implement more than currently is needed. We can revisit the\n> ideas once some other real use-case manifests.\n\nI have most of a real use case already.  I have a repository with\nsubmodules in one branch (master) and a subtree version in another\n(assembled) [4].  The *tree* is the same in each case, so I have to\n'git rm -rf .'  to clear the submodules out of master before I can\ncheckout assembled.\n\n  $ git checkout assembled\n  error: The following untracked working tree files would be overwritten by checkout:\n          modular/README.md\n          modular/shell/README.md\n          …\n  $ git rm -rf .\n  $ git checkout assembled\n\nThat leaves some extra stuff removed:\n\n  $ git status\n  On branch assembled\n  Changes to be committed:\n    (use \"git reset HEAD <file>...\" to unstage)\n\n          deleted:    .gitignore\n          deleted:    .mailmap\n          deleted:    CONTRIBUTING.md\n          deleted:    LICENSE.md\n          deleted:    instructor.md\n\nso I need to check that out by hand:\n\n  $ git reset --hard HEAD\n\nNow I can work in the assembled branch.  Going back to master is a bit\nless tedious:\n\n  $ git checkout master\n  $ git submodule update --recursive\n\nLuckily for me, I don't have a third superproject branch where the\nsubmodules are on a different, so the submodule's HEADs are preserved.\nAs I understand it, the new recursive checkout functionality [5] would\ncheckout my submodules with detached HEADs.  The fact that they are\nonly accidentally preserved now is not comforting ;).\n\n> Also we (Jens and I) would first like to proceed with the recursive\n> checkout / fetch (for which the plan is clear) as the next\n> complicated step.\n> \n> Once that is done and people gain some experience with it we can\n> still extend further.\n\nThis is quite reasonable.  Given the need for backwards compatibility,\nI just wanted to make sure my ideal UI was clear before we went\nforward.  There's no need to break fingers twice ;), but if tight\nbinding with localBranch is too big a chunk to bite off now, I'm happy\nto kick that can down the road.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/239967\n[2]: http://article.gmane.org/gmane.comp.version-control.git/239973\n[3]: http://article.gmane.org/gmane.comp.version-control.git/240139\n[4]: (gitweb) http://git.tremily.us/?p=swc-boot-camp.git\n[5]: http://article.gmane.org/gmane.comp.version-control.git/239695\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233110","messageId":"20140114223909.GB2647@odin.tremily.us","threadId":"35584","inReplyTo":"20140114221907.GC838@sandbox-ub","subject":"Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-14T22:39:09Z","receivedAt":"2014-01-14T22:39:09Z","isPatch":false,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Tue, Jan 14, 2014 at 11:19:07PM +0100, Heiko Voigt wrote:\n> On Tue, Jan 14, 2014 at 01:42:09PM -0800, W. Trevor King wrote:\n> > The “gitlinked commits must be in the subproject's master” rule\n> > protects you from blowing stuff away here.  You could use rebase- or\n> > merge-style integration as well, assuming the maintainer didn't have\n> > dirty local work in their submodule.\n> \n> No we can't. Developers are not allowed to merge in some submodules.\n> The most central ones have maintainers and only they are allowed to\n> merge into the stable branch. So we need to track exact commits on the\n> stable branch, no local merge (except the fast-forward case of course)\n> allowed. Thats why the developer does an exact checkout here.\n\nBecause both sides of the merge/rebase are required (by your rule) to\nbe in the subproject's master, you're guaranteed to have a\nfast-forward merge/rebase.\n\n> > > We have a tool in our git gui configuration that does\n> > > \n> > > \tgit submodule foreach 'git fetch && git checkout origin/master'\n> > \n> > I agree that with 'submodule update' seems superfluous.  With proper\n> > out-of-tree submodule configs specifying remote URLs and upstream\n> > branches,\n> > \n> >   git submodule foreach 'git fetch && git checkout @{upstream}'\n> > \n> > (or merge/rebase/…) should cover this case more generically and with\n> > less mental overhead.\n> > \n> > > I hope that draws a clear picture of how we use submodules.\n> > \n> > It's certainly clearer, thanks :).  I'm not sure where checkout-mode\n> > is specifically important, though.  In your step-2, it doesn't restore\n> > your original branch.  In your “update the superproject's master”\n> > step, you aren't even using 'submodule update' :p.\n> \n> Ah sorry I though that was clear. The \"others\" are using submodule update ;-)\n> \n> I mean someone who gets stuff from a stable superproject branch by\n> either rebasing their development branch or updating their local copy of\n> a stable branch (e.g. master) by using\n> \n> \tgit checkout master\n> \tgit pull --ff --ff-only\n> \tgit submodule update --init --recursive\n> \n> This also prevents the pure \"updaters\" from creating unnecessary merges.\n\nRight.  Folks who don't do local development in their submodules can\nget away with checkout-mode updates and their detached HEADs.\nAssuming the upstream superproject only advances the gitlinked commits\nusing fast-forwards, they could equally well use any of the other\nupdate modes, but there is no need for them to make that assumption.\n*This* is the use case that I think the current recursive-checkout\nfacilitates [1].  I don't think it helps folks who are actually doing\nsubmodule development on branches from within their superproject.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/239695\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233111","messageId":"20140114224246.GA13271@book.hvoigt.net","threadId":"35584","inReplyTo":"20140114222231.GA2647@odin.tremily.us","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2014-01-14T22:42:46Z","receivedAt":"2014-01-14T22:42:46Z","isPatch":false,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Tue, Jan 14, 2014 at 02:22:31PM -0800, W. Trevor King wrote:\n> On Tue, Jan 14, 2014 at 10:46:08PM +0100, Heiko Voigt wrote:\n> > I would like to step back a bit and get back to the original problem\n> > at hand: Francescos original use case of an attached head for direct\n> > commits on a stable branch in a submodule. How about we finish\n> > discussing the exact solution of that first. AFAIK that is already\n> > solved with the following:\n> > \n> >  * Trevor's first patch[2] to create a branch on initial clone of a submodule\n> \n> v1 broke a bunch of tests.  Are you ok with v2 [1]?  v2 still needs a\n> clearer commit message, a test, and a possible transition to\n> triggering on non-checkout submodule.<name>.update instead of\n> non-empty submodule.<name>.branch [2].\n\nWill have a look.\n\n> > That should be all (and IIRC Francesco agreed) needed for that use-case.\n> \n> That was my understanding [3] ;).\n\nThanks for the pointer.\n\n> > Lets not implement more than currently is needed. We can revisit the\n> > ideas once some other real use-case manifests.\n> \n> I have most of a real use case already.  I have a repository with\n> submodules in one branch (master) and a subtree version in another\n> (assembled) [4].  The *tree* is the same in each case, so I have to\n> 'git rm -rf .'  to clear the submodules out of master before I can\n> checkout assembled.\n> \n>   $ git checkout assembled\n>   error: The following untracked working tree files would be overwritten by checkout:\n>           modular/README.md\n>           modular/shell/README.md\n>           …\n>   $ git rm -rf .\n>   $ git checkout assembled\n> \n> That leaves some extra stuff removed:\n> \n>   $ git status\n>   On branch assembled\n>   Changes to be committed:\n>     (use \"git reset HEAD <file>...\" to unstage)\n> \n>           deleted:    .gitignore\n>           deleted:    .mailmap\n>           deleted:    CONTRIBUTING.md\n>           deleted:    LICENSE.md\n>           deleted:    instructor.md\n> \n> so I need to check that out by hand:\n> \n>   $ git reset --hard HEAD\n> \n> Now I can work in the assembled branch.  Going back to master is a bit\n> less tedious:\n> \n>   $ git checkout master\n>   $ git submodule update --recursive\n> \n> Luckily for me, I don't have a third superproject branch where the\n> submodules are on a different, so the submodule's HEADs are preserved.\n> As I understand it, the new recursive checkout functionality [5] would\n> checkout my submodules with detached HEADs.  The fact that they are\n> only accidentally preserved now is not comforting ;).\n\nAs it will be opt-in first (you will have to enable it with config\noptions) you can keep your current workflow. Once done with the initial\nimplementation we can discuss and iron out use-cases like yours.\n\n> > Also we (Jens and I) would first like to proceed with the recursive\n> > checkout / fetch (for which the plan is clear) as the next\n> > complicated step.\n> > \n> > Once that is done and people gain some experience with it we can\n> > still extend further.\n> \n> This is quite reasonable.  Given the need for backwards compatibility,\n> I just wanted to make sure my ideal UI was clear before we went\n> forward.  There's no need to break fingers twice ;), but if tight\n> binding with localBranch is too big a chunk to bite off now, I'm happy\n> to kick that can down the road.\n\nYes, that would be good to clearly understand and find out what we\nactually want.\n\nCheers Heiko\n\n> [1]: http://article.gmane.org/gmane.comp.version-control.git/239967\n> [2]: http://article.gmane.org/gmane.comp.version-control.git/239973\n> [3]: http://article.gmane.org/gmane.comp.version-control.git/240139\n> [4]: (gitweb) http://git.tremily.us/?p=swc-boot-camp.git\n> [5]: http://article.gmane.org/gmane.comp.version-control.git/239695\n"},{"id":"233117","messageId":"CALas-ihMfpQHr4nt9WO_att-2FDLvRYzxr-UVhfEsmRzLWafJg@mail.gmail.com","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"Re: Re: [RFC v2] submodule: Respect requested branch on all clones","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-15T00:02:46Z","receivedAt":"2014-01-15T00:02:46Z","isPatch":false,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/14 Heiko Voigt <hvoigt@hvoigt.net>:\n> On Tue, Jan 14, 2014 at 02:22:31PM -0800, W. Trevor King wrote:\n>> On Tue, Jan 14, 2014 at 10:46:08PM +0100, Heiko Voigt wrote:\n>> > I would like to step back a bit and get back to the original problem\n>> > at hand: Francescos original use case of an attached head for direct\n>> > commits on a stable branch in a submodule. How about we finish\n>> > discussing the exact solution of that first. AFAIK that is already\n>> > solved with the following:\n>> >\n>> >  * Trevor's first patch[2] to create a branch on initial clone of a submodule\n> [...]\n>\n>> > That should be all (and IIRC Francesco agreed) needed for that use-case.\n>>\n>> That was my understanding [3] ;).\n>\n>\n\nI've been silent these days but yes: I confirm Trevor's second patch\niteration[1] gives, IMO, a better meaning of the\nsubmodule.<name>.branch property and is perfectly fine for my use\ncase, to the point of stopping pursuing for my non behavior changing\npatch[4] (I still think it deserved some more in depth reviews, though\n;) ).\n\nCheers,\nFrancesco\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/239967\n[2]: http://article.gmane.org/gmane.comp.version-control.git/239973\n[3]: http://article.gmane.org/gmane.comp.version-control.git/240139\n[4]: http://article.gmane.org/gmane.comp.version-control.git/239956\n"},{"id":"233189","messageId":"cover.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 0/6] submodule: Local branch creation in module_clone","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:09:14Z","receivedAt":"2014-01-16T04:09:14Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"Here is the next iteration of cloning-update local branch setup.  This\nversion is based on Francesco's fp/submodule-checkout-mode [1], and\nmoves back towards the weakly-bound v2 approach and away from the\ntightly-bound v3 approach.\n\nThe first patch in this series extends that commit to consolidate ''\nand 'checkout' update_module values.  I wouldn't mind if that gets\nsquashed into Francesco's patch.\n\nThe meat of the series is in the third patch, which changes the v2\nimplementation by triggering attached HEADs based on the update-mode\ninstead of on the existence of a non-empty submodule.<name>.branch\n[2].  There has been pushback from both Heiko [3] and Jens [4] on my\nmapping checkout updaters to “developers not interested in local\nsubmodule development”, but I still think it's the right\ninterpretation.  I'm not clear on Heiko or Jens' current possitions,\nmaybe I've won them over ;).\n\nThe other patches in this series are all new in v4.\n\nThis still does a double checkout (once in module_clone to create a\nlocal branch, and again in cmd_update to point that branch at the\ncorrect commit), which Heiko was not excited about [5].\n\nI'm also not sure if defaulting to $remote_name/$branch in cmd_update\nis appropriate.  cmd_add defaults to using the remote's HEAD, and that\nmakes more sense to me than defaulting to the master branch.  However,\nchanging this logic is probably food for another series.\n\nI still think that this series is only useful as a temporary stop-gap\n[6] until we get something like my v3 [7], so the appropriate\nsubmodule branch is automatically checked out when you change\nsuperproject branches.\n\nCheers,\nTrevor\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240036\n[2]: http://article.gmane.org/gmane.comp.version-control.git/239973\n[3]: http://article.gmane.org/gmane.comp.version-control.git/239978\n[4]: http://article.gmane.org/gmane.comp.version-control.git/240368\n[5]: http://article.gmane.org/gmane.comp.version-control.git/239968\n[6]: http://article.gmane.org/gmane.comp.version-control.git/240232\n[7]: http://article.gmane.org/gmane.comp.version-control.git/240248\n\nW. Trevor King (6):\n  submodule: Make 'checkout' update_module explicit\n  submodule: Document module_clone arguments in comments\n  submodule: Explicit local branch creation in module_clone\n  t7406: Just-cloned checkouts update to the gitlinked hash with 'reset'\n  t7406: Add explicit tests for head attachement after cloning updates\n  Documentation: Describe 'submodule update' modes in detail\n\n Documentation/git-submodule.txt | 36 +++++++++++++-----\n Documentation/gitmodules.txt    |  4 ++\n git-submodule.sh                | 84 +++++++++++++++++++++++++----------------\n t/t7406-submodule-update.sh     | 39 ++++++++++++++++++-\n 4 files changed, 121 insertions(+), 42 deletions(-)\n\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233191","messageId":"43e8f3bfdaffefca9edd7a23574816630690e1e5.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 1/6] submodule: Make 'checkout' update_module explicit","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:10:22Z","receivedAt":"2014-01-16T04:10:22Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"This avoids the current awkwardness of having either '' or 'checkout'\nfor checkout-mode updates, which makes testing for checkout-mode\nupdates (or non-checkout-mode updates) easier.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n git-submodule.sh | 27 +++++++++++----------------\n 1 file changed, 11 insertions(+), 16 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5247f78..5e8776c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -803,17 +803,10 @@ cmd_update()\n \t\t\tupdate_module=$update\n \t\telse\n \t\t\tupdate_module=$(git config submodule.\"$name\".update)\n-\t\t\tcase \"$update_module\" in\n-\t\t\t'')\n-\t\t\t\t;; # Unset update mode\n-\t\t\tcheckout | rebase | merge | none)\n-\t\t\t\t;; # Known update modes\n-\t\t\t!*)\n-\t\t\t\t;; # Custom update command\n-\t\t\t*)\n-\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n-\t\t\t\t;;\n-\t\t\tesac\n+\t\t\tif test -z \"$update_module\"\n+\t\t\tthen\n+\t\t\t\tupdate_module=\"checkout\"\n+\t\t\tfi\n \t\tfi\n \n \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n@@ -882,11 +875,16 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module= ;;\n+\t\t\t\tupdate_module=checkout ;;\n \t\t\tesac\n \n \t\t\tmust_die_on_failure=\n \t\t\tcase \"$update_module\" in\n+\t\t\tcheckout)\n+\t\t\t\tcommand=\"git checkout $subforce -q\"\n+\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n+\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n+\t\t\t\t;;\n \t\t\trebase)\n \t\t\t\tcommand=\"git rebase\"\n \t\t\t\tdie_msg=\"$(eval_gettext \"Unable to rebase '\\$sha1' in submodule path '\\$displaypath'\")\"\n@@ -906,10 +904,7 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\t\tmust_die_on_failure=yes\n \t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tcommand=\"git checkout $subforce -q\"\n-\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n-\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n-\t\t\t\t;;\n+\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n \t\t\tesac\n \n \t\t\tif (clear_local_git_env; cd \"$sm_path\" && $command \"$sha1\")\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233190","messageId":"9d4a3470ef426ea8f93db33ad0e2f11f668a6d26.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 2/6] submodule: Document module_clone arguments in comments","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:10:23Z","receivedAt":"2014-01-16T04:10:23Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"Signed-off-by: W. Trevor King <wking@tremily.us>\n---\n git-submodule.sh | 6 ++++++\n 1 file changed, 6 insertions(+)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5e8776c..68dcbe1 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -241,6 +241,12 @@ module_name()\n #\n # Clone a submodule\n #\n+# $1 = submodule path\n+# $2 = submodule name\n+# $3 = URL to clone\n+# $4 = reference repository to reuse (empty for independent)\n+# $5 = depth argument for shallow clones (empty for deep)\n+#\n # Prior to calling, cmd_update checks that a possibly existing\n # path is not a git repository.\n # Likewise, cmd_add checks that path does not exist at all,\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233195","messageId":"96f9749de94f7e89f4d113f8cde69f2a960bcb88.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 3/6] submodule: Explicit local branch creation in module_clone","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:10:24Z","receivedAt":"2014-01-16T04:10:24Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"The previous code only checked out branches in cmd_add.  This commit\nmoves the branch-checkout logic into module_clone, where it can be\nshared by cmd_add and cmd_update.  I also update the initial checkout\ncommand to use 'reset' to preserve branches setup during module_clone.\n\nWith this change, folks cloning submodules for the first time via:\n\n  $ git submodule update ...\n\nwill get a local branch instead of a detached HEAD, unless they are\nusing the default checkout-mode updates.  This is a change from the\nprevious situation where cmd_update always used checkout-mode logic\n(regardless of the requested update mode) for updates that triggered\nan initial clone, which always resulted in a detached HEAD.\n\nThis commit does not change the logic for updates after the initial\nclone, which will continue to create detached HEADs for checkout-mode\nupdates, and integrate remote work with the local HEAD (detached or\nnot) in other modes.\n\nThe motivation for the change is that developers doing local work\ninside the submodule are likely to select a non-checkout-mode for\nupdates so their local work is integrated with upstream work.\nDevelopers who are not doing local submodule work stick with\ncheckout-mode updates so any apparently local work is blown away\nduring updates.  For example, if upstream rolls back the remote branch\nor gitlinked commit to an earlier version, the checkout-mode developer\nwants their old submodule checkout to be rolled back as well, instead\nof getting a no-op merge/rebase with the rolled-back reference.\n\nBy using the update mode to distinguish submodule developers from\nblack-box submodule consumers, we can setup local branches for the\ndevelopers who will want local branches, and stick with detached HEADs\nfor the developers that don't care.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n git-submodule.sh | 53 ++++++++++++++++++++++++++++++++++++-----------------\n 1 file changed, 36 insertions(+), 17 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 68dcbe1..4a09951 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -246,6 +246,9 @@ module_name()\n # $3 = URL to clone\n # $4 = reference repository to reuse (empty for independent)\n # $5 = depth argument for shallow clones (empty for deep)\n+# $6 = (remote-tracking) starting point for the local branch (empty for HEAD)\n+# $7 = local branch to create (empty for a detached HEAD, unless $6 is\n+#      also empty, in which case the local branch is left unchanged)\n #\n # Prior to calling, cmd_update checks that a possibly existing\n # path is not a git repository.\n@@ -259,6 +262,8 @@ module_clone()\n \turl=$3\n \treference=\"$4\"\n \tdepth=\"$5\"\n+\tstart_point=\"$6\"\n+\tlocal_branch=\"$7\"\n \tquiet=\n \tif test -n \"$GIT_QUIET\"\n \tthen\n@@ -312,7 +317,16 @@ module_clone()\n \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n \n \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n-\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n+\t(\n+\t\tclear_local_git_env\n+\t\tcd \"$sm_path\" &&\n+\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n+\t\t# ash fails to wordsplit ${local_branch:+-B \"$local_branch\"...}\n+\t\tcase \"$local_branch\" in\n+\t\t'') git checkout -f -q ${start_point:+\"$start_point\"} ;;\n+\t\t?*) git checkout -f -q -B \"$local_branch\" ${start_point:+\"$start_point\"} ;;\n+\t\tesac\n+\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n }\n \n isnumber()\n@@ -475,16 +489,14 @@ Use -f if you really want to add it.\" >&2\n \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n \t\t\tfi\n \t\tfi\n-\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n-\t\t(\n-\t\t\tclear_local_git_env\n-\t\t\tcd \"$sm_path\" &&\n-\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n-\t\t\tcase \"$branch\" in\n-\t\t\t'') git checkout -f -q ;;\n-\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n-\t\t\tesac\n-\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n+\t\tif test -n \"$branch\"\n+\t\tthen\n+\t\t\tstart_point=\"origin/$branch\"\n+\t\t\tlocal_branch=\"$branch\"\n+\t\telse\n+\t\t\tstart_point=\"\"\n+\t\tfi\n+\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$start_point\" \"$local_branch\" || exit\n \tfi\n \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n \n@@ -803,7 +815,9 @@ cmd_update()\n \t\tfi\n \t\tname=$(module_name \"$sm_path\") || exit\n \t\turl=$(git config submodule.\"$name\".url)\n-\t\tbranch=$(get_submodule_config \"$name\" branch master)\n+\t\tconfig_branch=$(get_submodule_config \"$name\" branch)\n+\t\tbranch=\"${config_branch:-master}\"\n+\t\tlocal_branch=\"$branch\"\n \t\tif ! test -z \"$update\"\n \t\tthen\n \t\t\tupdate_module=$update\n@@ -817,11 +831,15 @@ cmd_update()\n \n \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n \n-\t\tif test \"$update_module\" = \"none\"\n-\t\tthen\n+\t\tcase \"$update_module\" in\n+\t\tnone)\n \t\t\techo \"Skipping submodule '$displaypath'\"\n \t\t\tcontinue\n-\t\tfi\n+\t\t\t;;\n+\t\tcheckout)\n+\t\t\tlocal_branch=\"\"\n+\t\t\t;;\n+\t\tesac\n \n \t\tif test -z \"$url\"\n \t\tthen\n@@ -835,7 +853,8 @@ Maybe you want to use 'update --init'?\")\"\n \n \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n \t\tthen\n-\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n+\t\t\tstart_point=\"origin/${branch}\"\n+\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$start_point\" \"$local_branch\" || exit\n \t\t\tcloned_modules=\"$cloned_modules;$name\"\n \t\t\tsubsha1=\n \t\telse\n@@ -881,7 +900,7 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module=checkout ;;\n+\t\t\t\tupdate_module='!git reset --hard -q'\n \t\t\tesac\n \n \t\t\tmust_die_on_failure=\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233193","messageId":"09008c79ecc7d4fd92131b4049a25e65db92a30d.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 4/6] t7406: Just-cloned checkouts update to the gitlinked hash with 'reset'","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:10:25Z","receivedAt":"2014-01-16T04:10:25Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"To preserve the local branch, for situations where we're not on a\ndetached HEAD.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n t/t7406-submodule-update.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 0825a92..5aa9591 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -703,7 +703,7 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re\n \tgit clone super_update_r super_update_r2 &&\n \t(cd super_update_r2 &&\n \t git submodule update --init --recursive >actual &&\n-\t test_i18ngrep \"Submodule path .submodule/subsubmodule.: checked out\" actual &&\n+\t test_i18ngrep \"Submodule path .submodule/subsubmodule.: .git reset --hard -q\" actual &&\n \t (cd submodule/subsubmodule &&\n \t  git log > ../../expected\n \t ) &&\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233192","messageId":"b1cc110f1a0b68859af89cf8aed28d8a9eedddb5.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 5/6] t7406: Add explicit tests for head attachement after cloning updates","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:10:26Z","receivedAt":"2014-01-16T04:10:26Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"Test that cloning updates checkout the appropriate local branch for\ntheir update-mode:\n\n* Checkout-mode updates get detached HEADs\n* Everyone else gets a local branch, matching the configured\n  submodule.<name>.branch and defaulting to master.\n\nThe 'initial-setup' tag makes it easy to reset the superproject to a\nknown state, as several earlier tests commit to submodules and commit\nthe changed gitlinks to the superproject, but don't push the new\nsubmodule commits to the upstream subprojects.  This makes it\nimpossible to checkout the current super master, because it references\nsubmodule commits that don't exist in the upstream subprojects.  For a\nspecific example, see the tests that currently generate the\n'two_new_submodule_commits' commits.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n t/t7406-submodule-update.sh | 37 +++++++++++++++++++++++++++++++++++++\n 1 file changed, 37 insertions(+)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 5aa9591..f056c01 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -63,6 +63,9 @@ test_expect_success 'setup a submodule tree' '\n \t git submodule add ../none none &&\n \t test_tick &&\n \t git commit -m \"none\"\n+\t) &&\n+\t(cd super &&\n+\t git tag initial-setup\n \t)\n '\n \n@@ -764,4 +767,38 @@ test_expect_success 'submodule update clone shallow submodule' '\n \t )\n \t)\n '\n+\n+test_expect_success 'submodule update --checkout clones detached HEAD' '\n+\tgit clone super super4 &&\n+\techo \"detached HEAD\" >expected &&\n+\t(cd super4 &&\n+\t git reset --hard initial-setup &&\n+\t git submodule init submodule &&\n+\t git submodule update >> /tmp/log 2>&1 &&\n+\t (cd submodule &&\n+\t  git symbolic-ref HEAD > ../../actual ||\n+\t  echo \"detached HEAD\" > ../../actual\n+\t )\n+\t) &&\n+\ttest_cmp actual expected &&\n+\trm -rf super4\n+'\n+\n+test_expect_success 'submodule update --merge clones attached HEAD' '\n+\tgit clone super super4 &&\n+\techo \"refs/heads/master\" >expected &&\n+\t(cd super4 &&\n+\t git reset --hard initial-setup &&\n+\t git submodule init submodule &&\n+\t git config submodule.submodule.update merge &&\n+\t git submodule update --merge &&\n+\t (cd submodule &&\n+\t  git symbolic-ref HEAD > ../../actual ||\n+\t  echo \"detached HEAD\" > ../../actual\n+\t )\n+\t) &&\n+\ttest_cmp actual expected &&\n+\trm -rf super4\n+'\n+\n test_done\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233194","messageId":"4a8dca477ed5b190767d6a4619c593a83f86f082.1389837412.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140114224246.GA13271@book.hvoigt.net","subject":"[PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T04:10:27Z","receivedAt":"2014-01-16T04:10:27Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"The old documentation did not distinguish between cloning and\nnon-cloning updates and lacked clarity on which operations would lead\nto detached HEADs, and which would not.  The new documentation\naddresses these issues while updating the docs to reflect the changes\nintroduced by this branch's explicit local branch creation in\nmodule_clone.\n\nI also add '--checkout' to the usage summary and group the update-mode\noptions into a single set.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n Documentation/git-submodule.txt | 36 +++++++++++++++++++++++++++---------\n Documentation/gitmodules.txt    |  4 ++++\n 2 files changed, 31 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex bfef8a0..02500b4 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -15,8 +15,8 @@ SYNOPSIS\n 'git submodule' [--quiet] init [--] [<path>...]\n 'git submodule' [--quiet] deinit [-f|--force] [--] <path>...\n 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]\n-\t      [-f|--force] [--rebase] [--reference <repository>] [--depth <depth>]\n-\t      [--merge] [--recursive] [--] [<path>...]\n+\t      [-f|--force] [--rebase|--merge|--checkout] [--reference <repository>]\n+\t      [--depth <depth>] [--recursive] [--] [<path>...]\n 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]\n \t      [commit] [--] [<path>...]\n 'git submodule' [--quiet] foreach [--recursive] <command>\n@@ -155,13 +155,31 @@ it contains local modifications.\n \n update::\n \tUpdate the registered submodules, i.e. clone missing submodules and\n-\tcheckout the commit specified in the index of the containing repository.\n-\tThis will make the submodules HEAD be detached unless `--rebase` or\n-\t`--merge` is specified or the key `submodule.$name.update` is set to\n-\t`rebase`, `merge` or `none`. `none` can be overridden by specifying\n-\t`--checkout`. Setting the key `submodule.$name.update` to `!command`\n-\twill cause `command` to be run. `command` can be any arbitrary shell\n-\tcommand that takes a single argument, namely the sha1 to update to.\n+\tcheckout the commit specified in the index of the containing\n+\trepository.  The update mode defaults to 'checkout', but be\n+\tconfigured with the 'submodule.<name>.update' setting or the\n+\t'--rebase', '--merge', or 'checkout' options.\n++\n+For updates that clone missing submodules, checkout-mode updates will\n+create submodules with detached HEADs; all other modes will create\n+submodules with a local branch named after 'submodule.<path>.branch'.\n++\n+For updates that do not clone missing submodules, the submodule's HEAD\n+is only touched when the remote reference does not match the\n+submodule's HEAD (for none-mode updates, the submodule is never\n+touched).  The remote reference is usually the gitlinked commit from\n+the superproject's tree, but with '--remote' it is the upstream\n+subproject's 'submodule.<name>.branch'.  This remote reference is\n+integrated with the submodule's HEAD using the specified update mode.\n+For checkout-mode updates, that will result in a detached HEAD.  For\n+rebase- and merge-mode updates, the commit referenced by the\n+submodule's HEAD may change, but the symbolic reference will remain\n+unchanged (i.e. checked-out branches will still be checked-out\n+branches, and detached HEADs will still be detached HEADs).  If none\n+of the builtin modes fit your needs, set 'submodule.<name>.update' to\n+'!command' to configure a custom integration command.  'command' can\n+be any arbitrary shell command that takes a single argument, namely\n+the sha1 to update to.\n +\n If the submodule is not yet initialized, and you just want to use the\n setting as stored in .gitmodules, you can automatically initialize the\ndiff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\nindex f7be93f..36e5447 100644\n--- a/Documentation/gitmodules.txt\n+++ b/Documentation/gitmodules.txt\n@@ -53,6 +53,10 @@ submodule.<name>.branch::\n \tA remote branch name for tracking updates in the upstream submodule.\n \tIf the option is not specified, it defaults to 'master'.  See the\n \t`--remote` documentation in linkgit:git-submodule[1] for details.\n++\n+This branch name is also used for the local branch created by\n+non-checkout cloning updates.  See the 'update' documentation in\n+linkgit:git-submodule[1] for details.\n \n submodule.<name>.fetchRecurseSubmodules::\n \tThis option can be used to control recursive fetching of this\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233210","messageId":"xmqqwqhzzrw3.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"43e8f3bfdaffefca9edd7a23574816630690e1e5.1389837412.git.wking@tremily.us","subject":"Re: [PATCH v4 1/6] submodule: Make 'checkout' update_module explicit","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T18:46:36Z","receivedAt":"2014-01-16T18:46:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> This avoids the current awkwardness of having either '' or 'checkout'\n> for checkout-mode updates, which makes testing for checkout-mode\n> updates (or non-checkout-mode updates) easier.\n>\n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n>  git-submodule.sh | 27 +++++++++++----------------\n>  1 file changed, 11 insertions(+), 16 deletions(-)\n>\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 5247f78..5e8776c 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -803,17 +803,10 @@ cmd_update()\n>  \t\t\tupdate_module=$update\n>  \t\telse\n>  \t\t\tupdate_module=$(git config submodule.\"$name\".update)\n> -\t\t\tcase \"$update_module\" in\n> -\t\t\t'')\n> -\t\t\t\t;; # Unset update mode\n> -\t\t\tcheckout | rebase | merge | none)\n> -\t\t\t\t;; # Known update modes\n> -\t\t\t!*)\n> -\t\t\t\t;; # Custom update command\n> -\t\t\t*)\n> -\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n> -\t\t\t\t;;\n> -\t\t\tesac\n> +\t\t\tif test -z \"$update_module\"\n> +\t\t\tthen\n> +\t\t\t\tupdate_module=\"checkout\"\n> +\t\t\tfi\n>  \t\tfi\n\nIs this a good change?\n\nIt removes the code to prevent a broken configuration value from\nslipping through.  The code used to stop early to give the user a\nchance to fix it before actually letting \"submodule update\" to go\ninto the time consuming part, e.g. a call to module_clone, but that\ncode is now lost.\n\n>  \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n> @@ -882,11 +875,16 @@ Maybe you want to use 'update --init'?\")\"\n>  \t\t\tcase \";$cloned_modules;\" in\n>  \t\t\t*\";$name;\"*)\n>  \t\t\t\t# then there is no local change to integrate\n> -\t\t\t\tupdate_module= ;;\n> +\t\t\t\tupdate_module=checkout ;;\n>  \t\t\tesac\n>  \n>  \t\t\tmust_die_on_failure=\n>  \t\t\tcase \"$update_module\" in\n> +\t\t\tcheckout)\n> +\t\t\t\tcommand=\"git checkout $subforce -q\"\n> +\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n> +\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n> +\t\t\t\t;;\n>  ...\n>  \t\t\t*)\n> -\t\t\t\tcommand=\"git checkout $subforce -q\"\n> -\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n> -\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n> -\t\t\t\t;;\n> +\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n>  \t\t\tesac\n\nThese two hunks make sense.  It is clear in the updated code that\n\"checkout\" is what is implemented with that \"git checkout $subforce\n-q\", and not any other random update mode.\n"},{"id":"233211","messageId":"xmqqr487zqfr.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"96f9749de94f7e89f4d113f8cde69f2a960bcb88.1389837412.git.wking@tremily.us","subject":"Re: [PATCH v4 3/6] submodule: Explicit local branch creation in module_clone","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T19:18:00Z","receivedAt":"2014-01-16T19:18:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> The previous code only checked out branches in cmd_add.  This commit\n> moves the branch-checkout logic into module_clone, where it can be\n> shared by cmd_add and cmd_update.  I also update the initial checkout\n> command to use 'reset' to preserve branches setup during module_clone.\n>\n> With this change, folks cloning submodules for the first time via:\n>\n>   $ git submodule update ...\n>\n> will get a local branch instead of a detached HEAD, unless they are\n> using the default checkout-mode updates.  This is a change from the\n> previous situation where cmd_update always used checkout-mode logic\n> (regardless of the requested update mode) for updates that triggered\n> an initial clone, which always resulted in a detached HEAD.\n>\n> This commit does not change the logic for updates after the initial\n> clone, which will continue to create detached HEADs for checkout-mode\n> updates, and integrate remote work with the local HEAD (detached or\n> not) in other modes.\n>\n> The motivation for the change is that developers doing local work\n> inside the submodule are likely to select a non-checkout-mode for\n> updates so their local work is integrated with upstream work.\n> Developers who are not doing local submodule work stick with\n> checkout-mode updates so any apparently local work is blown away\n> during updates.  For example, if upstream rolls back the remote branch\n> or gitlinked commit to an earlier version, the checkout-mode developer\n> wants their old submodule checkout to be rolled back as well, instead\n> of getting a no-op merge/rebase with the rolled-back reference.\n>\n> By using the update mode to distinguish submodule developers from\n> black-box submodule consumers, we can setup local branches for the\n> developers who will want local branches, and stick with detached HEADs\n> for the developers that don't care.\n>\n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n>  git-submodule.sh | 53 ++++++++++++++++++++++++++++++++++++-----------------\n>  1 file changed, 36 insertions(+), 17 deletions(-)\n>\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 68dcbe1..4a09951 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -246,6 +246,9 @@ module_name()\n>  # $3 = URL to clone\n>  # $4 = reference repository to reuse (empty for independent)\n>  # $5 = depth argument for shallow clones (empty for deep)\n> +# $6 = (remote-tracking) starting point for the local branch (empty for HEAD)\n> +# $7 = local branch to create (empty for a detached HEAD, unless $6 is\n> +#      also empty, in which case the local branch is left unchanged)\n>  #\n>  # Prior to calling, cmd_update checks that a possibly existing\n>  # path is not a git repository.\n> @@ -259,6 +262,8 @@ module_clone()\n>  \turl=$3\n>  \treference=\"$4\"\n>  \tdepth=\"$5\"\n> +\tstart_point=\"$6\"\n> +\tlocal_branch=\"$7\"\n>  \tquiet=\n>  \tif test -n \"$GIT_QUIET\"\n>  \tthen\n> @@ -312,7 +317,16 @@ module_clone()\n>  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n>  \n>  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> +\t(\n> +\t\tclear_local_git_env\n> +\t\tcd \"$sm_path\" &&\n> +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> +\t\t# ash fails to wordsplit ${local_branch:+-B \"$local_branch\"...}\n\nInteresting...\n\n> +\t\tcase \"$local_branch\" in\n> +\t\t'') git checkout -f -q ${start_point:+\"$start_point\"} ;;\n> +\t\t?*) git checkout -f -q -B \"$local_branch\" ${start_point:+\"$start_point\"} ;;\n> +\t\tesac\n\nI am wondering if it makes more sense if you did this instead:\n\n\tgit checkout -f -q ${start_point:+\"$start_point\"} &&\n\tif test -n \"$local_branch\"\n        then\n        \tgit checkout -B \"$local_branch\" HEAD\n\tfi\n\nThe optional \"re-attaching to the local_branch\" done with the second\n\"checkout\" would be a non-destructive no-op to the working tree and\nto the index, but it does distinguish between creating the branch\nanew and resetting the existing branch in its output (note that\nthere is no \"-q\" to squelch it).  By doing it this way, when we\nlater teach \"git branch -f\" and \"git checkout -B\" to report more\nabout what commits have been lost by such a resetting, you will get\nthe safety for free if you made the switching with \"-B\" run without\n\"-q\" here.\n\n> +\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n>  }\n>  \n>  isnumber()\n> @@ -475,16 +489,14 @@ Use -f if you really want to add it.\" >&2\n>  \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n>  \t\t\tfi\n>  \t\tfi\n> -\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n> -\t\t(\n> -\t\t\tclear_local_git_env\n> -\t\t\tcd \"$sm_path\" &&\n> -\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n> -\t\t\tcase \"$branch\" in\n> -\t\t\t'') git checkout -f -q ;;\n> -\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> -\t\t\tesac\n> -\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n> +\t\tif test -n \"$branch\"\n> +\t\tthen\n> +\t\t\tstart_point=\"origin/$branch\"\n> +\t\t\tlocal_branch=\"$branch\"\n> +\t\telse\n> +\t\t\tstart_point=\"\"\n> +\t\tfi\n\nI'd feel safer if the \"else\" clause explicitly cleared $local_branch\nby assigning an empty string to it; it would make it a lot clearer\nthat \"when $branch is an empty string here, we do not want to\ntrigger the new codepath to run checkout with \"-B $local_branch\" in\nmodule_clone\" is what you mean.\n\n> +\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$start_point\" \"$local_branch\" || exit\n"},{"id":"233212","messageId":"xmqqmwivzq7n.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"09008c79ecc7d4fd92131b4049a25e65db92a30d.1389837412.git.wking@tremily.us","subject":"Re: [PATCH v4 4/6] t7406: Just-cloned checkouts update to the gitlinked hash with 'reset'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T19:22:52Z","receivedAt":"2014-01-16T19:22:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> To preserve the local branch, for situations where we're not on a\n> detached HEAD.\n>\n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n\nThis should be a part of some other change that actually changes how\nthis \"git submodule update\" checks out the submodule, no?\n\n>  t/t7406-submodule-update.sh | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\n> index 0825a92..5aa9591 100755\n> --- a/t/t7406-submodule-update.sh\n> +++ b/t/t7406-submodule-update.sh\n> @@ -703,7 +703,7 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re\n>  \tgit clone super_update_r super_update_r2 &&\n>  \t(cd super_update_r2 &&\n>  \t git submodule update --init --recursive >actual &&\n> -\t test_i18ngrep \"Submodule path .submodule/subsubmodule.: checked out\" actual &&\n> +\t test_i18ngrep \"Submodule path .submodule/subsubmodule.: .git reset --hard -q\" actual &&\n>  \t (cd submodule/subsubmodule &&\n>  \t  git log > ../../expected\n>  \t ) &&\n"},{"id":"233213","messageId":"20140116192252.GT2647@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqwqhzzrw3.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 1/6] submodule: Make 'checkout' update_module explicit","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T19:22:52Z","receivedAt":"2014-01-16T19:22:52Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 10:46:36AM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> > @@ -803,17 +803,10 @@ cmd_update()\n> >  \t\t\tupdate_module=$update\n> >  \t\telse\n> >  \t\t\tupdate_module=$(git config submodule.\"$name\".update)\n> > -\t\t\tcase \"$update_module\" in\n> > -\t\t\t'')\n> > -\t\t\t\t;; # Unset update mode\n> > -\t\t\tcheckout | rebase | merge | none)\n> > -\t\t\t\t;; # Known update modes\n> > -\t\t\t!*)\n> > -\t\t\t\t;; # Custom update command\n> > -\t\t\t*)\n> > -\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n> > -\t\t\t\t;;\n> > -\t\t\tesac\n> > +\t\t\tif test -z \"$update_module\"\n> > +\t\t\tthen\n> > +\t\t\t\tupdate_module=\"checkout\"\n> > +\t\t\tfi\n> >  \t\tfi\n> \n> Is this a good change?\n> \n> It removes the code to prevent a broken configuration value from\n> slipping through.  The code used to stop early to give the user a\n> chance to fix it before actually letting \"submodule update\" to go\n> into the time consuming part, e.g. a call to module_clone, but that\n> code is now lost.\n\nAvoiding useless clones is probably more important than avoiding\nduplicate \"Invalid update mode\" messages.  I'll reinstate the case\nstatement in v5, but I think it should live outside of the “load from\nconfig” block, in case someone adds the ability to set arbitrary\nupdate modes from the command line (`--update merge`, `--update\n'!command'`, etc.).\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233215","messageId":"20140116192958.GU2647@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqr487zqfr.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 3/6] submodule: Explicit local branch creation in module_clone","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T19:29:58Z","receivedAt":"2014-01-16T19:29:58Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 11:18:00AM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> > @@ -312,7 +317,16 @@ module_clone()\n> >  \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n> >  \n> >  \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n> > -\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n> > +\t(\n> > +\t\tclear_local_git_env\n> > +\t\tcd \"$sm_path\" &&\n> > +\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n> > +\t\t# ash fails to wordsplit ${local_branch:+-B \"$local_branch\"...}\n> \n> Interesting...\n\nThat's copied out of the old cmd_add code ;).  I don't have ash\nintalled to actually confirm the comment.\n\n> > +\t\tcase \"$local_branch\" in\n> > +\t\t'') git checkout -f -q ${start_point:+\"$start_point\"} ;;\n> > +\t\t?*) git checkout -f -q -B \"$local_branch\" ${start_point:+\"$start_point\"} ;;\n> > +\t\tesac\n> \n> I am wondering if it makes more sense if you did this instead:\n> \n> \tgit checkout -f -q ${start_point:+\"$start_point\"} &&\n> \tif test -n \"$local_branch\"\n>         then\n>         \tgit checkout -B \"$local_branch\" HEAD\n> \tfi\n> \n> The optional \"re-attaching to the local_branch\" done with the second\n> \"checkout\" would be a non-destructive no-op to the working tree and\n> to the index, but it does distinguish between creating the branch\n> anew and resetting the existing branch in its output (note that\n> there is no \"-q\" to squelch it).  By doing it this way, when we\n> later teach \"git branch -f\" and \"git checkout -B\" to report more\n> about what commits have been lost by such a resetting, you will get\n> the safety for free if you made the switching with \"-B\" run without\n> \"-q\" here.\n\nThis is immediately post-non-checkout-clone.  There are no local\nbranches to clobber yet.\n\n> > @@ -475,16 +489,14 @@ Use -f if you really want to add it.\" >&2\n> >  \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n> >  \t\t\tfi\n> >  \t\tfi\n> > -\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n> > -\t\t(\n> > -\t\t\tclear_local_git_env\n> > -\t\t\tcd \"$sm_path\" &&\n> > -\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n> > -\t\t\tcase \"$branch\" in\n> > -\t\t\t'') git checkout -f -q ;;\n> > -\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n> > -\t\t\tesac\n> > -\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n> > +\t\tif test -n \"$branch\"\n> > +\t\tthen\n> > +\t\t\tstart_point=\"origin/$branch\"\n> > +\t\t\tlocal_branch=\"$branch\"\n> > +\t\telse\n> > +\t\t\tstart_point=\"\"\n> > +\t\tfi\n> \n> I'd feel safer if the \"else\" clause explicitly cleared $local_branch\n> by assigning an empty string to it; it would make it a lot clearer\n> that \"when $branch is an empty string here, we do not want to\n> trigger the new codepath to run checkout with \"-B $local_branch\" in\n> module_clone\" is what you mean.\n\nOk.  Will add in v5.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233216","messageId":"20140116193212.GV2647@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqmwivzq7n.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 4/6] t7406: Just-cloned checkouts update to the gitlinked hash with 'reset'","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T19:32:12Z","receivedAt":"2014-01-16T19:32:12Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 11:22:52AM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> \n> > To preserve the local branch, for situations where we're not on a\n> > detached HEAD.\n> >\n> > Signed-off-by: W. Trevor King <wking@tremily.us>\n> > ---\n> \n> This should be a part of some other change that actually changes how\n> this \"git submodule update\" checks out the submodule, no?\n\nSure, we can squash both this test fix and the subsequent new test\npatch into patch #3 in v5.  I was just splitting them out because\nbackwards compatibility was a concern, and separate patches makes it\neasy for me to explain why the results changed here without getting\nlost in patch #3's implementation details.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233217","messageId":"xmqqiotjzp8v.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"96f9749de94f7e89f4d113f8cde69f2a960bcb88.1389837412.git.wking@tremily.us","subject":"Re: [PATCH v4 3/6] submodule: Explicit local branch creation in module_clone","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T19:43:44Z","receivedAt":"2014-01-16T19:43:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> @@ -817,11 +831,15 @@ cmd_update()\n>  \n>  \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n>  \n> -\t\tif test \"$update_module\" = \"none\"\n> -\t\tthen\n> +\t\tcase \"$update_module\" in\n> +\t\tnone)\n>  \t\t\techo \"Skipping submodule '$displaypath'\"\n>  \t\t\tcontinue\n> -\t\tfi\n> +\t\t\t;;\n> +\t\tcheckout)\n> +\t\t\tlocal_branch=\"\"\n> +\t\t\t;;\n> +\t\tesac\n\nI wonder if there is a way to avoid detaching (and you may need to\nupdate the coddpath that resets the submodule to the commit\nspecified by the superproject tree) when it is safe to do so.\n\nFor an end user, running \"submodule update\" is similar to running\n\"git pull\" in a project that does not use submodules, expressing \"I\nwant to catch up with the work done by others\".  In a working tree\nwith local changes, we do allow you to run \"git pull\" as long as\nyour local changes do not overlap with the work done by others, and\nthe result of the pull would look as if you did not have any of the\nlocal changes when you ran \"git pull\" and then you did the local\nchanges on top of the state that is up-to-date with their work.\n\nCan't we design \"submodule update --checkout\" to work in a similar\nfashion?  The updated superproject may say it wants $oSHA-1 at a\nsubmodule path P, and also its .gitmodules may say that commit is\nsupposed to be at the tip of branch B=submodule.P.branch in the\nsubmodule repository.  You may locally have advanced that branch in\nyour submodule repository in the meantime to point at $ySHA-1 while\nothers worked in the superproject and the submodule, and the\ndifference $oSHA-1...$ySHA-1 can be considered as the local change\nmade by you from the perspective of the superproject.\n\nWithout thinking things through, if $ySHA-1 matches or is a\ndescendant of $oSHA-1 (assuming that remote-tracking branch\norigin/$B in the submodule does point at $oSHA-1 in either case), it\nshould be safe to do this update.\n\nAnd in a situation where you cannot do the checkout safely, it is\nperfectly fine to say \"the submodules X and Y have local changes;\nyou cannot do 'submodule update' until you upstream them\" and fail\nthe update, just like we fail a 'git pull' saying \"you cannot do\npull until you commit them\", no?\n\nPerhaps that kind of \"'git submodule update' is parallel to 'git\npull' in the project without submodules\" is better done with other\nupdate modes like --rebase or --merge.  If so, how should we explain\nwhat 'submodule update --checkout' is to the end users?  Is it\nsupposed to be like \"git fetch && git checkout origin/master\"?\n"},{"id":"233218","messageId":"CALas-ig4=qKqpopaP163gVdBG39seWH61qqA5Jx0CR6AZkE6ZA@mail.gmail.com","threadId":"35584","inReplyTo":"20140116192252.GT2647@odin.tremily.us","subject":"Re: [PATCH v4 1/6] submodule: Make 'checkout' update_module explicit","fromName":"Francesco Pretto","fromEmail":"ceztko@gmail.com","sentAt":"2014-01-16T20:07:22Z","receivedAt":"2014-01-16T20:07:22Z","isPatch":true,"sender":{"key":"ceztko@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3037449?v=4"},"body":"2014/1/16 W. Trevor King <wking@tremily.us>:\n> Avoiding useless clones is probably more important than avoiding\n> duplicate \"Invalid update mode\" messages.\n\nNo, it's not duplicate code. I'll explain, please follow me:\n\n> @@ -803,17 +803,10 @@ cmd_update()\n>                         update_module=$update\n>                 else\n>                         update_module=$(git config submodule.\"$name\".update)\n> -                       case \"$update_module\" in\n> -                       '')\n> -                               ;; # Unset update mode\n> -                       checkout | rebase | merge | none)\n> -                               ;; # Known update modes\n> -                       !*)\n> -                               ;; # Custom update command\n> -                       *)\n> -                               die \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n> -                               ;;\n> -                       esac\n\nThis is a *validation*. It's done before going more through the code\nand die early.\n\n>                       *)\n> +                             die \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n>\n\nThis should be an *assert* -> it means if you reach this case\nstatement you (programmer) have messed the code something in the code\nbefore. In fact in my original patch I wrote something like \"invalid\nupdate_module at this flow\".\n\nPlease keep both as Junio said.\n\nThanks,\nFrancesco\n"},{"id":"233219","messageId":"20140116201949.GX2647@odin.tremily.us","threadId":"35584","inReplyTo":"CALas-ig4=qKqpopaP163gVdBG39seWH61qqA5Jx0CR6AZkE6ZA@mail.gmail.com","subject":"Re: [PATCH v4 1/6] submodule: Make 'checkout' update_module explicit","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T20:19:49Z","receivedAt":"2014-01-16T20:19:49Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 09:07:22PM +0100, Francesco Pretto wrote:\n> 2014/1/16 W. Trevor King <wking@tremily.us>:\n> > Avoiding useless clones is probably more important than avoiding\n> > duplicate \"Invalid update mode\" messages.\n> \n> No, it's not duplicate code.\n\nI meant “duplicating the \"Invalid update mode\" error message”.  I\nmissed the die-early distinction, but I understand now.  I think its\nnon-DRY to have an early case statement to validate the update_module,\nand a later case statement to use it.  Still, keeping those separate\nstatements in sync shouldn't be too hard ;).\n\n> Please keep both as Junio said.\n\nThat's what I said I'd do in the email you're quoting ;).  Are you ok\nwith the die-early validation checking all update_module settings\ninstead of just checking the loaded-from config branch?\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233220","messageId":"xmqqeh47znin.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"4a8dca477ed5b190767d6a4619c593a83f86f082.1389837412.git.wking@tremily.us","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T20:21:04Z","receivedAt":"2014-01-16T20:21:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> The old documentation did not distinguish between cloning and\n> non-cloning updates and lacked clarity on which operations would lead\n> to detached HEADs, and which would not.  The new documentation\n> addresses these issues while updating the docs to reflect the changes\n> introduced by this branch's explicit local branch creation in\n> module_clone.\n>\n> I also add '--checkout' to the usage summary and group the update-mode\n> options into a single set.\n>\n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n>  Documentation/git-submodule.txt | 36 +++++++++++++++++++++++++++---------\n>  Documentation/gitmodules.txt    |  4 ++++\n>  2 files changed, 31 insertions(+), 9 deletions(-)\n>\n> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\n> index bfef8a0..02500b4 100644\n> --- a/Documentation/git-submodule.txt\n> +++ b/Documentation/git-submodule.txt\n> @@ -15,8 +15,8 @@ SYNOPSIS\n>  'git submodule' [--quiet] init [--] [<path>...]\n>  'git submodule' [--quiet] deinit [-f|--force] [--] <path>...\n>  'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]\n> -\t      [-f|--force] [--rebase] [--reference <repository>] [--depth <depth>]\n> -\t      [--merge] [--recursive] [--] [<path>...]\n> +\t      [-f|--force] [--rebase|--merge|--checkout] [--reference <repository>]\n> +\t      [--depth <depth>] [--recursive] [--] [<path>...]\n>  'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]\n>  \t      [commit] [--] [<path>...]\n>  'git submodule' [--quiet] foreach [--recursive] <command>\n> @@ -155,13 +155,31 @@ it contains local modifications.\n>  \n>  update::\n>  \tUpdate the registered submodules, i.e. clone missing submodules and\n> -\tcheckout the commit specified in the index of the containing repository.\n> -\tThis will make the submodules HEAD be detached unless `--rebase` or\n> -\t`--merge` is specified or the key `submodule.$name.update` is set to\n> -\t`rebase`, `merge` or `none`. `none` can be overridden by specifying\n> -\t`--checkout`. Setting the key `submodule.$name.update` to `!command`\n> -\twill cause `command` to be run. `command` can be any arbitrary shell\n> -\tcommand that takes a single argument, namely the sha1 to update to.\n> +\tcheckout the commit specified in the index of the containing\n> +\trepository.  The update mode defaults to 'checkout', but be\n> +\tconfigured with the 'submodule.<name>.update' setting or the\n> +\t'--rebase', '--merge', or 'checkout' options.\n\nNot '--checkout'?\n\nOther than that, the updated text above is far easier to\nunderstand.  Good job.\n\n> ++\n> +For updates that clone missing submodules, checkout-mode updates will\n> +create submodules with detached HEADs; all other modes will create\n> +submodules with a local branch named after 'submodule.<path>.branch'.\n> ++\n> +For updates that do not clone missing submodules, the submodule's HEAD\n\nThat is, updates that update submodules that are already checked out?\n\n> +is only touched when the remote reference does not match the\n> +submodule's HEAD (for none-mode updates, the submodule is never\n> +touched).  The remote reference is usually the gitlinked commit from\n> +the superproject's tree, but with '--remote' it is the upstream\n> +subproject's 'submodule.<name>.branch'.  This remote reference is\n> +integrated with the submodule's HEAD using the specified update mode.\n\nI think copying some motivation from the log message of 06b1abb5\n(submodule update: add --remote for submodule's upstream changes,\n2012-12-19) would help the readers here.  A naïve expectation from a\ncasual reader of the above would be \"The superproject's tree ought\nto point at the same commit as the tip of the branch used in the\nsubmodule (modulo mirroring delays and somesuch), if the repository\nof the superproject and submodules are maintained properly\", which\nwould lead to \"when would any sane person need to use --remote in\nthe first place???\".\n\nIf I am reading 06b1abb5 correctly, the primary motivation behind\n\"--remote\" seems to be that it is exactly to help the person who\nwants to update superproject to satisify the \"... are maintained\nproperly\" part by fetching the latest in each of the submodules in\nhis superproject in preparation to 'git add .' them.  I still do not\nthink \"--remote\" was a better way than the \"foreach\", but that is a\nseparate topic.\n\nIf the person who works in the superproject does not control the\nprogress of, and/or does not care what development is happening in,\nthe submodules, he can push the superproject tree out without even\nbothering to update the commits in the submodules bound to his\nsuperproject tree, and the consumers of such a superproject could\ncatch up with the advancement of submodule by using --remote\nindividually to bring themselves up to date.  But I do not think\nthat is what you envisioned as the best recommended practice when\nyou wrote 06b1abb5.\n\n> +For checkout-mode updates, that will result in a detached HEAD.  For\n> +rebase- and merge-mode updates, the commit referenced by the\n> +submodule's HEAD may change, but the symbolic reference will remain\n> +unchanged (i.e. checked-out branches will still be checked-out\n> +branches, and detached HEADs will still be detached HEADs).  If none\n> +of the builtin modes fit your needs, set 'submodule.<name>.update' to\n> +'!command' to configure a custom integration command.  'command' can\n> +be any arbitrary shell command that takes a single argument, namely\n> +the sha1 to update to.\n>  +\n>  If the submodule is not yet initialized, and you just want to use the\n>  setting as stored in .gitmodules, you can automatically initialize the\n> diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\n> index f7be93f..36e5447 100644\n> --- a/Documentation/gitmodules.txt\n> +++ b/Documentation/gitmodules.txt\n> @@ -53,6 +53,10 @@ submodule.<name>.branch::\n>  \tA remote branch name for tracking updates in the upstream submodule.\n>  \tIf the option is not specified, it defaults to 'master'.  See the\n>  \t`--remote` documentation in linkgit:git-submodule[1] for details.\n> ++\n> +This branch name is also used for the local branch created by\n> +non-checkout cloning updates.  See the 'update' documentation in\n> +linkgit:git-submodule[1] for details.\n>  \n>  submodule.<name>.fetchRecurseSubmodules::\n>  \tThis option can be used to control recursive fetching of this\n\nOther than the above minor nits, the updated text was very\nreadable.  Thanks.\n"},{"id":"233221","messageId":"xmqqa9evzndg.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"20140116193212.GV2647@odin.tremily.us","subject":"Re: [PATCH v4 4/6] t7406: Just-cloned checkouts update to the gitlinked hash with 'reset'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T20:24:11Z","receivedAt":"2014-01-16T20:24:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n> On Thu, Jan 16, 2014 at 11:22:52AM -0800, Junio C Hamano wrote:\n>> \"W. Trevor King\" <wking@tremily.us> writes:\n>> \n>> > To preserve the local branch, for situations where we're not on a\n>> > detached HEAD.\n>> >\n>> > Signed-off-by: W. Trevor King <wking@tremily.us>\n>> > ---\n>> \n>> This should be a part of some other change that actually changes how\n>> this \"git submodule update\" checks out the submodule, no?\n>\n> Sure, we can squash both this test fix and the subsequent new test\n> patch into patch #3 in v5.  I was just splitting them out because\n> backwards compatibility was a concern, and separate patches makes it\n> easy for me to explain why the results changed here without getting\n> lost in patch #3's implementation details.\n\nOn the contrary, if we had this as part of patch #3, it would have\nhelped reviewing the patch itself, as that would have served as one\nmore clue to illustrate the effect that is externally visible to end\nusers.\n\nBesides, having them separate will break bisection.\n"},{"id":"233222","messageId":"20140116205521.GY2647@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqeh47znin.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T20:55:21Z","receivedAt":"2014-01-16T20:55:21Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 12:21:04PM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> > @@ -155,13 +155,31 @@ it contains local modifications.\n> >  \n> >  update::\n> >  \tUpdate the registered submodules, i.e. clone missing submodules and\n> > -\tcheckout the commit specified in the index of the containing repository.\n> > -\tThis will make the submodules HEAD be detached unless `--rebase` or\n> > -\t`--merge` is specified or the key `submodule.$name.update` is set to\n> > -\t`rebase`, `merge` or `none`. `none` can be overridden by specifying\n> > -\t`--checkout`. Setting the key `submodule.$name.update` to `!command`\n> > -\twill cause `command` to be run. `command` can be any arbitrary shell\n> > -\tcommand that takes a single argument, namely the sha1 to update to.\n> > +\tcheckout the commit specified in the index of the containing\n> > +\trepository.  The update mode defaults to 'checkout', but be\n> > +\tconfigured with the 'submodule.<name>.update' setting or the\n> > +\t'--rebase', '--merge', or 'checkout' options.\n> \n> Not '--checkout'?\n\nOops, will fix in v5.\n\n> > ++\n> > +For updates that clone missing submodules, checkout-mode updates will\n> > +create submodules with detached HEADs; all other modes will create\n> > +submodules with a local branch named after 'submodule.<path>.branch'.\n> > ++\n> > +For updates that do not clone missing submodules, the submodule's HEAD\n> \n> That is, updates that update submodules that are already checked out?\n\nIt's submodules for which $sm_path/.git does not exist.\n\n> > +is only touched when the remote reference does not match the\n> > +submodule's HEAD (for none-mode updates, the submodule is never\n> > +touched).  The remote reference is usually the gitlinked commit from\n> > +the superproject's tree, but with '--remote' it is the upstream\n> > +subproject's 'submodule.<name>.branch'.  This remote reference is\n> > +integrated with the submodule's HEAD using the specified update mode.\n> \n> I think copying some motivation from the log message of 06b1abb5\n> (submodule update: add --remote for submodule's upstream changes,\n> 2012-12-19) would help the readers here.\n\nI think a brief reference to --remote is best here, mentioning that it\nhas something to do with the upstream subproject.  More detail on when\nyou should use --remote should probably go under the docs for --remote\n;).\n\n> A naïve expectation from a casual reader of the above would be \"The\n> superproject's tree ought to point at the same commit as the tip of\n> the branch used in the submodule (modulo mirroring delays and\n> somesuch),\n\nWhat is the branch used in the submodule?  The remote subproject's\ncurrent submodule.<name>.branch?  The local submodule's\nsubmodule.<name>.branch (or localBranch) branch?  The submodule's\ncurrent HEAD?\n\n> if the repository of the superproject and submodules are maintained\n> properly\", which would lead to \"when would any sane person need to\n> use --remote in the first place???\".\n\n--remote is not for sane people (who will probably be pulling from\nwithing the submodule itself).  --remote is for folks who track too\nmany submodules to care about them as individuals, who just want to\nblindly update to whatever the upstream subproject maintainer has in\nsubmodule.<name>.branch.  For example, if you are a distribution with\na hundred submodules tracking all the projects you package, and want\nto bump them all to a their current trunk tip in one fell swoop.\n\n> If I am reading 06b1abb5 correctly, the primary motivation behind\n> \"--remote\" seems to be that it is exactly to help the person who\n> wants to update superproject to satisify the \"... are maintained\n> properly\" part by fetching the latest in each of the submodules in\n> his superproject in preparation to 'git add .' them.  I still do not\n> think \"--remote\" was a better way than the \"foreach\", but that is a\n> separate topic.\n\nI agree now ;), the problems with:\n\n  $ git submodule foreach 'git pull'\n\nare:\n\n1. You may not be on the “right” local branch to begin with, and\n2. You may not have out-of-tree submodule configs setting up the\n   “right” upstream for that branch.\n\n06b1abb did not address the former, and added a new .gitmodules-level\nsubmodule.<name>.branch to help with the latter.  I now think all of\nthis would be easier if we had automatic submodule local-branch\ncheckouts (fixing problem 1) and synchronized out-of-tree submodule\nconfigs (fixing problem 2).  Fixing problem 1 is all you need if you\naren't interested in sharing your out-of-tree configs.\n\nI think 06b1abb was inspired by “we already have a way to integrate\nchanges in the gitlinked commit, we should reuse those to integrate\nother changes”.  In hindsight, changes in the gitlinked commit are\nreally a checkout-time issue, while changes in other places (like the\nremote subproject) are pull-time issues.  Mixing them together was\nmore confusing than it was worth.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233223","messageId":"20140116210222.GG7608@serenity.lan","threadId":"35584","inReplyTo":"20140116205521.GY2647@odin.tremily.us","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2014-01-16T21:02:22Z","receivedAt":"2014-01-16T21:02:22Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Thu, Jan 16, 2014 at 12:55:21PM -0800, W. Trevor King wrote:\n> On Thu, Jan 16, 2014 at 12:21:04PM -0800, Junio C Hamano wrote:\n> > \"W. Trevor King\" <wking@tremily.us> writes:\n> > > @@ -155,13 +155,31 @@ it contains local modifications.\n> > >  \n> > >  update::\n> > >  \tUpdate the registered submodules, i.e. clone missing submodules and\n> > > -\tcheckout the commit specified in the index of the containing repository.\n> > > -\tThis will make the submodules HEAD be detached unless `--rebase` or\n> > > -\t`--merge` is specified or the key `submodule.$name.update` is set to\n> > > -\t`rebase`, `merge` or `none`. `none` can be overridden by specifying\n> > > -\t`--checkout`. Setting the key `submodule.$name.update` to `!command`\n> > > -\twill cause `command` to be run. `command` can be any arbitrary shell\n> > > -\tcommand that takes a single argument, namely the sha1 to update to.\n> > > +\tcheckout the commit specified in the index of the containing\n> > > +\trepository.  The update mode defaults to 'checkout', but be\n> > > +\tconfigured with the 'submodule.<name>.update' setting or the\n> > > +\t'--rebase', '--merge', or 'checkout' options.\n> > \n> > Not '--checkout'?\n> \n> Oops, will fix in v5.\n\nShouldn't this also be `--checkout` (backticks), according to\nCodingGuidelines.  This applies to all this options in this patch I\nthink.\n\n> > > ++\n> > > +For updates that clone missing submodules, checkout-mode updates will\n> > > +create submodules with detached HEADs; all other modes will create\n> > > +submodules with a local branch named after 'submodule.<path>.branch'.\n> > > ++\n> > > +For updates that do not clone missing submodules, the submodule's HEAD\n> > \n> > That is, updates that update submodules that are already checked out?\n> \n> It's submodules for which $sm_path/.git does not exist.\n> \n> > > +is only touched when the remote reference does not match the\n> > > +submodule's HEAD (for none-mode updates, the submodule is never\n> > > +touched).  The remote reference is usually the gitlinked commit from\n> > > +the superproject's tree, but with '--remote' it is the upstream\n> > > +subproject's 'submodule.<name>.branch'.  This remote reference is\n> > > +integrated with the submodule's HEAD using the specified update mode.\n> > \n> > I think copying some motivation from the log message of 06b1abb5\n> > (submodule update: add --remote for submodule's upstream changes,\n> > 2012-12-19) would help the readers here.\n> \n> I think a brief reference to --remote is best here, mentioning that it\n> has something to do with the upstream subproject.  More detail on when\n> you should use --remote should probably go under the docs for --remote\n> ;).\n> \n> > A naïve expectation from a casual reader of the above would be \"The\n> > superproject's tree ought to point at the same commit as the tip of\n> > the branch used in the submodule (modulo mirroring delays and\n> > somesuch),\n> \n> What is the branch used in the submodule?  The remote subproject's\n> current submodule.<name>.branch?  The local submodule's\n> submodule.<name>.branch (or localBranch) branch?  The submodule's\n> current HEAD?\n> \n> > if the repository of the superproject and submodules are maintained\n> > properly\", which would lead to \"when would any sane person need to\n> > use --remote in the first place???\".\n> \n> --remote is not for sane people (who will probably be pulling from\n> withing the submodule itself).  --remote is for folks who track too\n> many submodules to care about them as individuals, who just want to\n> blindly update to whatever the upstream subproject maintainer has in\n> submodule.<name>.branch.  For example, if you are a distribution with\n> a hundred submodules tracking all the projects you package, and want\n> to bump them all to a their current trunk tip in one fell swoop.\n> \n> > If I am reading 06b1abb5 correctly, the primary motivation behind\n> > \"--remote\" seems to be that it is exactly to help the person who\n> > wants to update superproject to satisify the \"... are maintained\n> > properly\" part by fetching the latest in each of the submodules in\n> > his superproject in preparation to 'git add .' them.  I still do not\n> > think \"--remote\" was a better way than the \"foreach\", but that is a\n> > separate topic.\n> \n> I agree now ;), the problems with:\n> \n>   $ git submodule foreach 'git pull'\n> \n> are:\n> \n> 1. You may not be on the “right” local branch to begin with, and\n> 2. You may not have out-of-tree submodule configs setting up the\n>    “right” upstream for that branch.\n> \n> 06b1abb did not address the former, and added a new .gitmodules-level\n> submodule.<name>.branch to help with the latter.  I now think all of\n> this would be easier if we had automatic submodule local-branch\n> checkouts (fixing problem 1) and synchronized out-of-tree submodule\n> configs (fixing problem 2).  Fixing problem 1 is all you need if you\n> aren't interested in sharing your out-of-tree configs.\n> \n> I think 06b1abb was inspired by “we already have a way to integrate\n> changes in the gitlinked commit, we should reuse those to integrate\n> other changes”.  In hindsight, changes in the gitlinked commit are\n> really a checkout-time issue, while changes in other places (like the\n> remote subproject) are pull-time issues.  Mixing them together was\n> more confusing than it was worth.\n> \n> Cheers,\n> Trevor\n> \n> -- \n> This email may be signed or encrypted with GnuPG (http://www.gnupg.org).\n> For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233225","messageId":"20140116211234.GZ2647@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqiotjzp8v.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 3/6] submodule: Explicit local branch creation in module_clone","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T21:12:34Z","receivedAt":"2014-01-16T21:12:34Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 11:43:44AM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> \n> > @@ -817,11 +831,15 @@ cmd_update()\n> >  \n> >  \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n> >  \n> > -\t\tif test \"$update_module\" = \"none\"\n> > -\t\tthen\n> > +\t\tcase \"$update_module\" in\n> > +\t\tnone)\n> >  \t\t\techo \"Skipping submodule '$displaypath'\"\n> >  \t\t\tcontinue\n> > -\t\tfi\n> > +\t\t\t;;\n> > +\t\tcheckout)\n> > +\t\t\tlocal_branch=\"\"\n> > +\t\t\t;;\n> > +\t\tesac\n> \n> I wonder if there is a way to avoid detaching (and you may need to\n> update the coddpath that resets the submodule to the commit\n> specified by the superproject tree) when it is safe to do so.\n>\n> …\n> \n> Perhaps that kind of \"'git submodule update' is parallel to 'git\n> pull' in the project without submodules\" is better done with other\n> update modes like --rebase or --merge.  If so, how should we explain\n> what 'submodule update --checkout' is to the end users?  Is it\n> supposed to be like \"git fetch && git checkout origin/master\"?\n\nIt sounds like you're looking for:\n\n  submodule.<name>.update = !git merge --ff-only\n\nThat's fine for folks who want that sort of advancement, but I think\nthere will also be blind updaters who just want the gitlinked commit,\nand don't care if that blows away local work, because they never work\nlocally in the submodule.  They'll still prefer the current\ncheckout-mode with it's clobbering.\n\nI think the best way to explain this to users is to have 'git\ncheckout' (with an optional '--recurse-submdules' trial period)\ncheckout the gitlinked commit automatically.  Then there is never\nlocal submodule work that is not committed or stashed in the\nsuperproject (or stashed on some out-of-the-way branch in the\nsubmodule).  Currently we have:\n\n  1. Checkout a superproject branch and currently gitlinked submodule.\n  2. Do local work on the submodule.\n  3. Alter the superproject and its gitlinks.\n  4. 'git submodule update' to integrate your work from 2 with the\n     changes from 3 and checkout the appropriate submodule commit.\n\nI think it would make more sense to:\n\n  1. Checkout a superproject branch and currently gitlinked submodule.\n  2. Do local work on the submodule.\n  3. Commit your new gitlink to the superproject (or stash it, or put\n     it on a temporary submodule branch and reset the submodule HEAD\n     to the old value).\n  4. Alter the superproject and its gitlinks, using the existing logic\n     to integrate conflicts.  Automatically checkout the appropriate\n     submodule commit (as the appropriate submodule branch).\n\nThat shifts “dealing with local submodule changes” from an\nintegration-time issue (I just called submodule update, what changes\nare local?) to a pre-checkout-time issue (I've got a dirty submodule\n(it's HEAD is not the gitlinked commit, all of these changes are\nlocal).  I think that's a lot easier to wrap your head around.\n\nThis series is a stop-gap to avoid detached HEADs after cloning,\nnon-checkout updates, while we hash out the real solution ;).\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233227","messageId":"20140116211652.GA2647@odin.tremily.us","threadId":"35584","inReplyTo":"20140116210222.GG7608@serenity.lan","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T21:16:52Z","receivedAt":"2014-01-16T21:16:52Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 09:02:22PM +0000, John Keeping wrote:\n> On Thu, Jan 16, 2014 at 12:55:21PM -0800, W. Trevor King wrote:\n> > On Thu, Jan 16, 2014 at 12:21:04PM -0800, Junio C Hamano wrote:\n> > > Not '--checkout'?\n> > \n> > Oops, will fix in v5.\n> \n> Shouldn't this also be `--checkout` (backticks), according to\n> CodingGuidelines.  This applies to all this options in this patch I\n> think.\n\nI can change that too.  The existing content is inconsistent between\nbackticks and single quotes, but I see no mention of single quotes in\nCodingGuidelines.  Thanks for the reference.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233229","messageId":"xmqqy52fy4km.fsf@gitster.dls.corp.google.com","threadId":"35584","inReplyTo":"20140116205521.GY2647@odin.tremily.us","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-16T21:55:37Z","receivedAt":"2014-01-16T21:55:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"W. Trevor King\" <wking@tremily.us> writes:\n\n>> A naïve expectation from a casual reader of the above would be \"The\n>> superproject's tree ought to point at the same commit as the tip of\n>> the branch used in the submodule (modulo mirroring delays and\n>> somesuch),\n>\n> What is the branch used in the submodule?  The remote subproject's\n> current submodule.<name>.branch?  The local submodule's\n> submodule.<name>.branch (or localBranch) branch?  The submodule's\n> current HEAD?\n\nThey are good questions that such casual readers would have, and\ngiving answers to them in this part of the documentation would be a\ngood way to give them a clear picture of how the command is designed\nto be used.\n"},{"id":"233233","messageId":"777D3478B53C4A3F8B4326A96B3F048E@PhilipOakley","threadId":"35584","inReplyTo":"xmqqeh47znin.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2014-01-16T22:15:59Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Junio C Hamano\" <gitster@pobox.com>\n> \"W. Trevor King\" <wking@tremily.us> writes:\n>\n[...]\n>> @@ -155,13 +155,31 @@ it contains local modifications.\n>>\n>>  update::\n>>  Update the registered submodules, i.e. clone missing submodules and\n>> - checkout the commit specified in the index of the containing \n>> repository.\n>> - This will make the submodules HEAD be detached unless `--rebase` or\n>> - `--merge` is specified or the key `submodule.$name.update` is set \n>> to\n>> - `rebase`, `merge` or `none`. `none` can be overridden by specifying\n>> - `--checkout`. Setting the key `submodule.$name.update` to \n>> `!command`\n>> - will cause `command` to be run. `command` can be any arbitrary \n>> shell\n>> - command that takes a single argument, namely the sha1 to update to.\n>> + checkout the commit specified in the index of the containing\n>> + repository.  The update mode defaults to 'checkout', but be\n\nnit:   s/but be/but can be/  ?\n\n>> + configured with the 'submodule.<name>.update' setting or the\n>> + '--rebase', '--merge', or 'checkout' options.\n>\n[...] \n"},{"id":"233234","messageId":"20140116223519.GB2647@odin.tremily.us","threadId":"35584","inReplyTo":"777D3478B53C4A3F8B4326A96B3F048E@PhilipOakley","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-16T22:35:19Z","receivedAt":"2014-01-16T22:35:19Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 10:18:06PM -0000, Philip Oakley wrote:\n> From: \"Junio C Hamano\" <gitster@pobox.com>\n> > \"W. Trevor King\" <wking@tremily.us> writes:\n> >> + repository.  The update mode defaults to 'checkout', but be\n> \n> nit:   s/but be/but can be/  ?\n\nThanks.  Queuing for v5.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233256","messageId":"20140117023746.GJ7078@odin.tremily.us","threadId":"35584","inReplyTo":"xmqqy52fy4km.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 6/6] Documentation: Describe 'submodule update' modes in detail","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-17T02:37:46Z","receivedAt":"2014-01-17T02:37:46Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 01:55:37PM -0800, Junio C Hamano wrote:\n> \"W. Trevor King\" <wking@tremily.us> writes:\n> > On Thu, Jan 16, 2014 at 12:21:04PM -0800, Junio C Hamano wrote:\n> >> \"W. Trevor King\" <wking@tremily.us> writes:\n> >>> +is only touched when the remote reference does not match the\n> >>> +submodule's HEAD (for none-mode updates, the submodule is never\n> >>> +touched).  The remote reference is usually the gitlinked commit from\n> >>> +the superproject's tree, but with '--remote' it is the upstream\n> >>> +subproject's 'submodule.<name>.branch'.  This remote reference is\n> >>> +integrated with the submodule's HEAD using the specified update mode.\n> >> …\n> >> A naïve expectation from a casual reader of the above would be\n> >> \"The superproject's tree ought to point at the same commit as the\n> >> tip of the branch used in the submodule (modulo mirroring delays\n> >> and somesuch),\n> >\n> > What is the branch used in the submodule?  The remote subproject's\n> > current submodule.<name>.branch?  The local submodule's\n> > submodule.<name>.branch (or localBranch) branch?  The submodule's\n> > current HEAD?\n>\n> They are good questions that such casual readers would have, and\n> giving answers to them in this part of the documentation would be a\n> good way to give them a clear picture of how the command is designed\n> to be used.\n\nHow about:\n\n  Note that the update command only interacts with the submodule's\n  HEAD.  It doesn't care what this head points to.  If the submodule\n  has a branch checked out, HEAD will reference that branch.  If the\n  submodule's HEAD is detached, it will reference a commit.  After\n  following any references, the commit referenced by the submodule's\n  HEAD may resolve to the commit gitlinked by the superproject, or it\n  may not (if you have made local submodule changes, or checked out a\n  different superproject branch).  The update command does not adjust\n  your submodule's HEAD to point at the gitlinked commit before\n  performing any integration.  It just takes your submodle's HEAD,\n  whatever it points to, and integrates the remote reference.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"},{"id":"233794","messageId":"cover.1390768736.git.wking@tremily.us","threadId":"35584","inReplyTo":"20140117023746.GJ7078@odin.tremily.us","subject":"[PATCH v5 0/4] submodule: Local branch creation in module_clone","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-26T20:45:12Z","receivedAt":"2014-01-26T20:45:12Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"Changes since v4:\n\nIn git-submodule.sh:\n\n* Explicitly set an empty $local_branch in cmd_add if $branch is empty\n  [1].\n* Restore die-early checking for invalid $update_module [2].  This\n  check is now outside the load-from-config branch, ensuring we have a\n  valid update_module, regardless of how it was set.\n\nIn Documentation/git-submodule.txt:\n\n* Fix “but be” → “but can be” [3].\n* Fix “checkout” → “--checkout” [4].\n* New text on why you'd use --remote [5] (new commit #4).\n\nIn Documentation/git-submodule.txt and Documentation/gitmodules.txt:\n\n* Use backticks (instead of single quotes) for command line options\n  [6].\n\nI also squashed the implementation, testing fixes, new tests, and\ndocumentation for the new local_branch stuff (v4's #3, #4, #5, and #6)\ninto a single commit (v5's #3) [7].\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240524\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240522\n[3]: http://article.gmane.org/gmane.comp.version-control.git/240543\n[4]: http://article.gmane.org/gmane.comp.version-control.git/240531\n[5]: http://article.gmane.org/gmane.comp.version-control.git/240529\n[6]: http://article.gmane.org/gmane.comp.version-control.git/240536\n[7]: http://article.gmane.org/gmane.comp.version-control.git/240530\n\nW. Trevor King (4):\n  submodule: Make 'checkout' update_module explicit\n  submodule: Document module_clone arguments in comments\n  submodule: Explicit local branch creation in module_clone\n  Documentation: Describe 'submodule update --remote' use case\n\n Documentation/git-submodule.txt | 46 ++++++++++++++++-----\n Documentation/gitmodules.txt    |  4 ++\n git-submodule.sh                | 89 ++++++++++++++++++++++++++---------------\n t/t7406-submodule-update.sh     | 39 +++++++++++++++++-\n 4 files changed, 136 insertions(+), 42 deletions(-)\n\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233796","messageId":"43e8f3bfdaffefca9edd7a23574816630690e1e5.1390768736.git.wking@tremily.us","threadId":"35584","inReplyTo":"cover.1390768736.git.wking@tremily.us","subject":"[PATCH v5 1/4] submodule: Make 'checkout' update_module explicit","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-26T20:45:13Z","receivedAt":"2014-01-26T20:45:13Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"This avoids the current awkwardness of having either '' or 'checkout'\nfor checkout-mode updates, which makes testing for checkout-mode\nupdates (or non-checkout-mode updates) easier.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n git-submodule.sh | 27 +++++++++++----------------\n 1 file changed, 11 insertions(+), 16 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5247f78..5e8776c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -803,17 +803,10 @@ cmd_update()\n \t\t\tupdate_module=$update\n \t\telse\n \t\t\tupdate_module=$(git config submodule.\"$name\".update)\n-\t\t\tcase \"$update_module\" in\n-\t\t\t'')\n-\t\t\t\t;; # Unset update mode\n-\t\t\tcheckout | rebase | merge | none)\n-\t\t\t\t;; # Known update modes\n-\t\t\t!*)\n-\t\t\t\t;; # Custom update command\n-\t\t\t*)\n-\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n-\t\t\t\t;;\n-\t\t\tesac\n+\t\t\tif test -z \"$update_module\"\n+\t\t\tthen\n+\t\t\t\tupdate_module=\"checkout\"\n+\t\t\tfi\n \t\tfi\n \n \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n@@ -882,11 +875,16 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module= ;;\n+\t\t\t\tupdate_module=checkout ;;\n \t\t\tesac\n \n \t\t\tmust_die_on_failure=\n \t\t\tcase \"$update_module\" in\n+\t\t\tcheckout)\n+\t\t\t\tcommand=\"git checkout $subforce -q\"\n+\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n+\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n+\t\t\t\t;;\n \t\t\trebase)\n \t\t\t\tcommand=\"git rebase\"\n \t\t\t\tdie_msg=\"$(eval_gettext \"Unable to rebase '\\$sha1' in submodule path '\\$displaypath'\")\"\n@@ -906,10 +904,7 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\t\tmust_die_on_failure=yes\n \t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tcommand=\"git checkout $subforce -q\"\n-\t\t\t\tdie_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n-\t\t\t\tsay_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n-\t\t\t\t;;\n+\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n \t\t\tesac\n \n \t\t\tif (clear_local_git_env; cd \"$sm_path\" && $command \"$sha1\")\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233795","messageId":"9d4a3470ef426ea8f93db33ad0e2f11f668a6d26.1390768736.git.wking@tremily.us","threadId":"35584","inReplyTo":"cover.1390768736.git.wking@tremily.us","subject":"[PATCH v5 2/4] submodule: Document module_clone arguments in comments","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-26T20:45:14Z","receivedAt":"2014-01-26T20:45:14Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"Signed-off-by: W. Trevor King <wking@tremily.us>\n---\n git-submodule.sh | 6 ++++++\n 1 file changed, 6 insertions(+)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5e8776c..68dcbe1 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -241,6 +241,12 @@ module_name()\n #\n # Clone a submodule\n #\n+# $1 = submodule path\n+# $2 = submodule name\n+# $3 = URL to clone\n+# $4 = reference repository to reuse (empty for independent)\n+# $5 = depth argument for shallow clones (empty for deep)\n+#\n # Prior to calling, cmd_update checks that a possibly existing\n # path is not a git repository.\n # Likewise, cmd_add checks that path does not exist at all,\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233798","messageId":"42bef14770ea71bc96e9a18828e4921d27ee581b.1390768736.git.wking@tremily.us","threadId":"35584","inReplyTo":"cover.1390768736.git.wking@tremily.us","subject":"[PATCH v5 3/4] submodule: Explicit local branch creation in module_clone","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-26T20:45:15Z","receivedAt":"2014-01-26T20:45:15Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"The previous code only checked out branches in cmd_add.  This commit\nmoves the branch-checkout logic into module_clone, where it can be\nshared by cmd_add and cmd_update.  I also update the initial checkout\ncommand to use 'reset' to preserve branches setup during module_clone.\n\nWith this change, folks cloning submodules for the first time via:\n\n  $ git submodule update ...\n\nwill get a local branch instead of a detached HEAD, unless they are\nusing the default checkout-mode updates.  This is a change from the\nprevious situation where cmd_update always used checkout-mode logic\n(regardless of the requested update mode) for updates that triggered\nan initial clone, which always resulted in a detached HEAD.\n\nThis commit does not change the logic for updates after the initial\nclone, which will continue to create detached HEADs for checkout-mode\nupdates, and integrate remote work with the local HEAD (detached or\nnot) in other modes.\n\nThe motivation for the change is that developers doing local work\ninside the submodule are likely to select a non-checkout-mode for\nupdates so their local work is integrated with upstream work.\nDevelopers who are not doing local submodule work stick with\ncheckout-mode updates so any apparently local work is blown away\nduring updates.  For example, if upstream rolls back the remote branch\nor gitlinked commit to an earlier version, the checkout-mode developer\nwants their old submodule checkout to be rolled back as well, instead\nof getting a no-op merge/rebase with the rolled-back reference.\n\nBy using the update mode to distinguish submodule developers from\nblack-box submodule consumers, we can setup local branches for the\ndevelopers who will want local branches, and stick with detached HEADs\nfor the developers that don't care.\n\nTesting\n=======\n\nIn t7406, just-cloned checkouts now update to the gitlinked hash with\n'reset', to preserve the local branch for situations where we're not\non a detached HEAD.\n\nI also added explicit tests to t7406 for HEAD attachement after\ncloning updates, showing that it depends on their update mode:\n\n* Checkout-mode updates get detached HEADs\n* Everyone else gets a local branch, matching the configured\n  submodule.<name>.branch and defaulting to master.\n\nThe 'initial-setup' tag makes it easy to reset the superproject to a\nknown state, as several earlier tests commit to submodules and commit\nthe changed gitlinks to the superproject, but don't push the new\nsubmodule commits to the upstream subprojects.  This makes it\nimpossible to checkout the current super master, because it references\nsubmodule commits that don't exist in the upstream subprojects.  For a\nspecific example, see the tests that currently generate the\n'two_new_submodule_commits' commits.\n\nDocumentation\n=============\n\nI updated the docs to describe the 'submodule update' modes in detail.\nThe old documentation did not distinguish between cloning and\nnon-cloning updates and lacked clarity on which operations would lead\nto detached HEADs, and which would not.  The new documentation\naddresses these issues while updating the docs to reflect the changes\nintroduced by this commit's explicit local branch creation in\nmodule_clone.\n\nI also add '--checkout' to the usage summary and group the update-mode\noptions into a single set.\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n Documentation/git-submodule.txt | 36 ++++++++++++++++++-------\n Documentation/gitmodules.txt    |  4 +++\n git-submodule.sh                | 58 +++++++++++++++++++++++++++++------------\n t/t7406-submodule-update.sh     | 39 ++++++++++++++++++++++++++-\n 4 files changed, 110 insertions(+), 27 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex bfef8a0..2e1c7a2 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -15,8 +15,8 @@ SYNOPSIS\n 'git submodule' [--quiet] init [--] [<path>...]\n 'git submodule' [--quiet] deinit [-f|--force] [--] <path>...\n 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]\n-\t      [-f|--force] [--rebase] [--reference <repository>] [--depth <depth>]\n-\t      [--merge] [--recursive] [--] [<path>...]\n+\t      [-f|--force] [--rebase|--merge|--checkout] [--reference <repository>]\n+\t      [--depth <depth>] [--recursive] [--] [<path>...]\n 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]\n \t      [commit] [--] [<path>...]\n 'git submodule' [--quiet] foreach [--recursive] <command>\n@@ -155,13 +155,31 @@ it contains local modifications.\n \n update::\n \tUpdate the registered submodules, i.e. clone missing submodules and\n-\tcheckout the commit specified in the index of the containing repository.\n-\tThis will make the submodules HEAD be detached unless `--rebase` or\n-\t`--merge` is specified or the key `submodule.$name.update` is set to\n-\t`rebase`, `merge` or `none`. `none` can be overridden by specifying\n-\t`--checkout`. Setting the key `submodule.$name.update` to `!command`\n-\twill cause `command` to be run. `command` can be any arbitrary shell\n-\tcommand that takes a single argument, namely the sha1 to update to.\n+\tcheckout the commit specified in the index of the containing\n+\trepository.  The update mode defaults to `checkout`, but can be\n+\tconfigured with the `submodule.<name>.update` setting or the\n+\t`--rebase`, `--merge`, or `--checkout` options.\n++\n+For updates that clone missing submodules, checkout-mode updates will\n+create submodules with detached HEADs; all other modes will create\n+submodules with a local branch named after `submodule.<path>.branch`.\n++\n+For updates that do not clone missing submodules, the submodule's HEAD\n+is only touched when the remote reference does not match the\n+submodule's HEAD (for none-mode updates, the submodule is never\n+touched).  The remote reference is usually the gitlinked commit from\n+the superproject's tree, but with `--remote` it is the upstream\n+subproject's `submodule.<name>.branch`.  This remote reference is\n+integrated with the submodule's HEAD using the specified update mode.\n+For checkout-mode updates, that will result in a detached HEAD.  For\n+rebase- and merge-mode updates, the commit referenced by the\n+submodule's HEAD may change, but the symbolic reference will remain\n+unchanged (i.e. checked-out branches will still be checked-out\n+branches, and detached HEADs will still be detached HEADs).  If none\n+of the builtin modes fit your needs, set `submodule.<name>.update` to\n+`!command` to configure a custom integration command.  `command` can\n+be any arbitrary shell command that takes a single argument, namely\n+the sha1 to update to.\n +\n If the submodule is not yet initialized, and you just want to use the\n setting as stored in .gitmodules, you can automatically initialize the\ndiff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\nindex f7be93f..385f35d 100644\n--- a/Documentation/gitmodules.txt\n+++ b/Documentation/gitmodules.txt\n@@ -53,6 +53,10 @@ submodule.<name>.branch::\n \tA remote branch name for tracking updates in the upstream submodule.\n \tIf the option is not specified, it defaults to 'master'.  See the\n \t`--remote` documentation in linkgit:git-submodule[1] for details.\n++\n+This branch name is also used for the local branch created by\n+non-checkout cloning updates.  See the `update` documentation in\n+linkgit:git-submodule[1] for details.\n \n submodule.<name>.fetchRecurseSubmodules::\n \tThis option can be used to control recursive fetching of this\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 68dcbe1..626a746 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -246,6 +246,9 @@ module_name()\n # $3 = URL to clone\n # $4 = reference repository to reuse (empty for independent)\n # $5 = depth argument for shallow clones (empty for deep)\n+# $6 = (remote-tracking) starting point for the local branch (empty for HEAD)\n+# $7 = local branch to create (empty for a detached HEAD, unless $6 is\n+#      also empty, in which case the local branch is left unchanged)\n #\n # Prior to calling, cmd_update checks that a possibly existing\n # path is not a git repository.\n@@ -259,6 +262,8 @@ module_clone()\n \turl=$3\n \treference=\"$4\"\n \tdepth=\"$5\"\n+\tstart_point=\"$6\"\n+\tlocal_branch=\"$7\"\n \tquiet=\n \tif test -n \"$GIT_QUIET\"\n \tthen\n@@ -312,7 +317,16 @@ module_clone()\n \techo \"gitdir: $rel/$a\" >\"$sm_path/.git\"\n \n \trel=$(echo $a | sed -e 's|[^/][^/]*|..|g')\n-\t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n+\t(\n+\t\tclear_local_git_env\n+\t\tcd \"$sm_path\" &&\n+\t\tGIT_WORK_TREE=. git config core.worktree \"$rel/$b\" &&\n+\t\t# ash fails to wordsplit ${local_branch:+-B \"$local_branch\"...}\n+\t\tcase \"$local_branch\" in\n+\t\t'') git checkout -f -q ${start_point:+\"$start_point\"} ;;\n+\t\t?*) git checkout -f -q -B \"$local_branch\" ${start_point:+\"$start_point\"} ;;\n+\t\tesac\n+\t) || die \"$(eval_gettext \"Unable to setup cloned submodule '\\$sm_path'\")\"\n }\n \n isnumber()\n@@ -475,16 +489,15 @@ Use -f if you really want to add it.\" >&2\n \t\t\t\techo \"$(eval_gettext \"Reactivating local git directory for submodule '\\$sm_name'.\")\"\n \t\t\tfi\n \t\tfi\n-\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" || exit\n-\t\t(\n-\t\t\tclear_local_git_env\n-\t\t\tcd \"$sm_path\" &&\n-\t\t\t# ash fails to wordsplit ${branch:+-b \"$branch\"...}\n-\t\t\tcase \"$branch\" in\n-\t\t\t'') git checkout -f -q ;;\n-\t\t\t?*) git checkout -f -q -B \"$branch\" \"origin/$branch\" ;;\n-\t\t\tesac\n-\t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n+\t\tif test -n \"$branch\"\n+\t\tthen\n+\t\t\tstart_point=\"origin/$branch\"\n+\t\t\tlocal_branch=\"$branch\"\n+\t\telse\n+\t\t\tstart_point=\"\"\n+\t\t\tlocal_branch=\"\"\n+\t\tfi\n+\t\tmodule_clone \"$sm_path\" \"$sm_name\" \"$realrepo\" \"$reference\" \"$depth\" \"$start_point\" \"$local_branch\" || exit\n \tfi\n \tgit config submodule.\"$sm_name\".url \"$realrepo\"\n \n@@ -803,7 +816,9 @@ cmd_update()\n \t\tfi\n \t\tname=$(module_name \"$sm_path\") || exit\n \t\turl=$(git config submodule.\"$name\".url)\n-\t\tbranch=$(get_submodule_config \"$name\" branch master)\n+\t\tconfig_branch=$(get_submodule_config \"$name\" branch)\n+\t\tbranch=\"${config_branch:-master}\"\n+\t\tlocal_branch=\"$branch\"\n \t\tif ! test -z \"$update\"\n \t\tthen\n \t\t\tupdate_module=$update\n@@ -817,11 +832,19 @@ cmd_update()\n \n \t\tdisplaypath=$(relative_path \"$prefix$sm_path\")\n \n-\t\tif test \"$update_module\" = \"none\"\n-\t\tthen\n+\t\tcase \"$update_module\" in\n+\t\tnone)\n \t\t\techo \"Skipping submodule '$displaypath'\"\n \t\t\tcontinue\n-\t\tfi\n+\t\t\t;;\n+\t\tcheckout)\n+\t\t\tlocal_branch=\"\"\n+\t\t\t;;\n+\t\trebase | merge | !*)\n+\t\t\t;;\n+\t\t*)\n+\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n+\t\tesac\n \n \t\tif test -z \"$url\"\n \t\tthen\n@@ -835,7 +858,8 @@ Maybe you want to use 'update --init'?\")\"\n \n \t\tif ! test -d \"$sm_path\"/.git -o -f \"$sm_path\"/.git\n \t\tthen\n-\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" || exit\n+\t\t\tstart_point=\"origin/${branch}\"\n+\t\t\tmodule_clone \"$sm_path\" \"$name\" \"$url\" \"$reference\" \"$depth\" \"$start_point\" \"$local_branch\" || exit\n \t\t\tcloned_modules=\"$cloned_modules;$name\"\n \t\t\tsubsha1=\n \t\telse\n@@ -881,7 +905,7 @@ Maybe you want to use 'update --init'?\")\"\n \t\t\tcase \";$cloned_modules;\" in\n \t\t\t*\";$name;\"*)\n \t\t\t\t# then there is no local change to integrate\n-\t\t\t\tupdate_module=checkout ;;\n+\t\t\t\tupdate_module='!git reset --hard -q'\n \t\t\tesac\n \n \t\t\tmust_die_on_failure=\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 0825a92..f056c01 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -63,6 +63,9 @@ test_expect_success 'setup a submodule tree' '\n \t git submodule add ../none none &&\n \t test_tick &&\n \t git commit -m \"none\"\n+\t) &&\n+\t(cd super &&\n+\t git tag initial-setup\n \t)\n '\n \n@@ -703,7 +706,7 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re\n \tgit clone super_update_r super_update_r2 &&\n \t(cd super_update_r2 &&\n \t git submodule update --init --recursive >actual &&\n-\t test_i18ngrep \"Submodule path .submodule/subsubmodule.: checked out\" actual &&\n+\t test_i18ngrep \"Submodule path .submodule/subsubmodule.: .git reset --hard -q\" actual &&\n \t (cd submodule/subsubmodule &&\n \t  git log > ../../expected\n \t ) &&\n@@ -764,4 +767,38 @@ test_expect_success 'submodule update clone shallow submodule' '\n \t )\n \t)\n '\n+\n+test_expect_success 'submodule update --checkout clones detached HEAD' '\n+\tgit clone super super4 &&\n+\techo \"detached HEAD\" >expected &&\n+\t(cd super4 &&\n+\t git reset --hard initial-setup &&\n+\t git submodule init submodule &&\n+\t git submodule update >> /tmp/log 2>&1 &&\n+\t (cd submodule &&\n+\t  git symbolic-ref HEAD > ../../actual ||\n+\t  echo \"detached HEAD\" > ../../actual\n+\t )\n+\t) &&\n+\ttest_cmp actual expected &&\n+\trm -rf super4\n+'\n+\n+test_expect_success 'submodule update --merge clones attached HEAD' '\n+\tgit clone super super4 &&\n+\techo \"refs/heads/master\" >expected &&\n+\t(cd super4 &&\n+\t git reset --hard initial-setup &&\n+\t git submodule init submodule &&\n+\t git config submodule.submodule.update merge &&\n+\t git submodule update --merge &&\n+\t (cd submodule &&\n+\t  git symbolic-ref HEAD > ../../actual ||\n+\t  echo \"detached HEAD\" > ../../actual\n+\t )\n+\t) &&\n+\ttest_cmp actual expected &&\n+\trm -rf super4\n+'\n+\n test_done\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233797","messageId":"fff9b46f7d832b74e219075c28db5ebcb0137299.1390768736.git.wking@tremily.us","threadId":"35584","inReplyTo":"cover.1390768736.git.wking@tremily.us","subject":"[PATCH v5 4/4] Documentation: Describe 'submodule update --remote' use case","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-26T20:45:16Z","receivedAt":"2014-01-26T20:45:16Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Thu, Jan 16, 2014 at 12:21:04PM -0800, Junio C Hamano wrote [1]:\n> I think copying some motivation from the log message of 06b1abb5\n> (submodule update: add --remote for submodule's upstream changes,\n> 2012-12-19) would help the readers here.  A naïve expectation from a\n> casual reader of the above would be \"The superproject's tree ought\n> to point at the same commit as the tip of the branch used in the\n> submodule (modulo mirroring delays and somesuch), if the repository\n> of the superproject and submodules are maintained properly\", which\n> would lead to \"when would any sane person need to use --remote in\n> the first place???\".\n\nThere have been other interpretation issues with the --remote option\nas well.  With this commit, I try to make it clear that there is no\nimplicit floating going on; --remote lets you explicitly integrate the\nupstream branch in your current HEAD (just like running 'git pull' in\nthe submodule).  The only distinction with the current 'git pull' is\nthe config location/setting used for the upstream branch, which is\nhopefully clear now.\n\nWith syncing between the out-of-tree submodule config and the in-tree\nsuperproject .gitmodules [2], you wouldn't have to chose between (or\nmanually sync) \"easily distributable .gitmodules settings\" and \"native\nsubmodule pull\", but this patch is my take on the current situation.\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/240529\n[2]: http://article.gmane.org/gmane.comp.version-control.git/240336\n\nSigned-off-by: W. Trevor King <wking@tremily.us>\n---\n Documentation/git-submodule.txt | 10 ++++++++++\n 1 file changed, 10 insertions(+)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 2e1c7a2..21cb59a 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -299,6 +299,16 @@ In order to ensure a current tracking branch state, `update --remote`\n fetches the submodule's remote repository before calculating the\n SHA-1.  If you don't want to fetch, you should use `submodule update\n --remote --no-fetch`.\n++\n+Use this option to integrate changes from the upstream subproject with\n+your submodule's current HEAD.  Alternatively, you can run `git pull`\n+from the submodule, which is equivalent except for the remote branch\n+name: `update --remote` uses the default upstream repository and\n+`submodule.<name>.branch`, while `git pull` uses the submodule's\n+`branch.<name>.merge`.  Prefer `submodule.<name>.branch` if you want\n+to distribute the default upstream branch with the superproject and\n+`branch.<name>.merge` if you want a more native feel while working in\n+the submodule itself.\n \n -N::\n --no-fetch::\n-- \n1.8.5.2.8.g0f6c0d1\n"},{"id":"233807","messageId":"CAPig+cQweMT6g+GLFfAWg=9hcU7EjQ7eMOjYiMDQ4rennJSsXw@mail.gmail.com","threadId":"35584","inReplyTo":"43e8f3bfdaffefca9edd7a23574816630690e1e5.1390768736.git.wking@tremily.us","subject":"Re: [PATCH v5 1/4] submodule: Make 'checkout' update_module explicit","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-01-27T01:32:04Z","receivedAt":"2014-01-27T01:32:04Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, Jan 26, 2014 at 3:45 PM, W. Trevor King <wking@tremily.us> wrote:\n> This avoids the current awkwardness of having either '' or 'checkout'\n> for checkout-mode updates, which makes testing for checkout-mode\n> updates (or non-checkout-mode updates) easier.\n>\n> Signed-off-by: W. Trevor King <wking@tremily.us>\n> ---\n>  git-submodule.sh | 27 +++++++++++----------------\n>  1 file changed, 11 insertions(+), 16 deletions(-)\n>\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 5247f78..5e8776c 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -803,17 +803,10 @@ cmd_update()\n>                         update_module=$update\n>                 else\n>                         update_module=$(git config submodule.\"$name\".update)\n> -                       case \"$update_module\" in\n> -                       '')\n> -                               ;; # Unset update mode\n> -                       checkout | rebase | merge | none)\n> -                               ;; # Known update modes\n> -                       !*)\n> -                               ;; # Custom update command\n> -                       *)\n> -                               die \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n> -                               ;;\n> -                       esac\n> +                       if test -z \"$update_module\"\n> +                       then\n> +                               update_module=\"checkout\"\n\nHere, you (unnecessarily) quote 'checkout'...\n\n> +                       fi\n>                 fi\n>\n>                 displaypath=$(relative_path \"$prefix$sm_path\")\n> @@ -882,11 +875,16 @@ Maybe you want to use 'update --init'?\")\"\n>                         case \";$cloned_modules;\" in\n>                         *\";$name;\"*)\n>                                 # then there is no local change to integrate\n> -                               update_module= ;;\n> +                               update_module=checkout ;;\n\nBut here you use bare (unquoted) 'checkout'. Bare is probably more idiomatic.\n\n>                         esac\n>\n>                         must_die_on_failure=\n>                         case \"$update_module\" in\n> +                       checkout)\n> +                               command=\"git checkout $subforce -q\"\n> +                               die_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n> +                               say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n> +                               ;;\n>                         rebase)\n>                                 command=\"git rebase\"\n>                                 die_msg=\"$(eval_gettext \"Unable to rebase '\\$sha1' in submodule path '\\$displaypath'\")\"\n> @@ -906,10 +904,7 @@ Maybe you want to use 'update --init'?\")\"\n>                                 must_die_on_failure=yes\n>                                 ;;\n>                         *)\n> -                               command=\"git checkout $subforce -q\"\n> -                               die_msg=\"$(eval_gettext \"Unable to checkout '\\$sha1' in submodule path '\\$displaypath'\")\"\n> -                               say_msg=\"$(eval_gettext \"Submodule path '\\$displaypath': checked out '\\$sha1'\")\"\n> -                               ;;\n> +                               die \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n>                         esac\n>\n>                         if (clear_local_git_env; cd \"$sm_path\" && $command \"$sha1\")\n> --\n> 1.8.5.2.8.g0f6c0d1\n"},{"id":"233810","messageId":"20140127015959.GT29063@odin.tremily.us","threadId":"35584","inReplyTo":"CAPig+cQweMT6g+GLFfAWg=9hcU7EjQ7eMOjYiMDQ4rennJSsXw@mail.gmail.com","subject":"Re: [PATCH v5 1/4] submodule: Make 'checkout' update_module explicit","fromName":"W. Trevor King","fromEmail":"wking@tremily.us","sentAt":"2014-01-27T01:59:59Z","receivedAt":"2014-01-27T01:59:59Z","isPatch":true,"sender":{"key":"wking@tremily.us","avatar":"https://avatars.githubusercontent.com/u/209920?v=4"},"body":"On Sun, Jan 26, 2014 at 08:32:04PM -0500, Eric Sunshine wrote:\n> On Sun, Jan 26, 2014 at 3:45 PM, W. Trevor King <wking@tremily.us> wrote:\n> > +                               update_module=\"checkout\"\n> \n> Here, you (unnecessarily) quote 'checkout'...\n> \n> > -                               update_module= ;;\n> > +                               update_module=checkout ;;\n> \n> But here you use bare (unquoted) 'checkout'. Bare is probably more\n> idiomatic.\n\nWhatever you want ;).  Queued for v6.\n\nCheers,\nTrevor\n\n-- \nThis email may be signed or encrypted with GnuPG (http://www.gnupg.org).\nFor more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy\n"}]}