{"thread":{"id":"14244","subject":"[PATCH] better git-submodule status output","startedAt":"2008-07-01T14:57:01Z","lastAt":"2008-07-01T14:57:01Z","messageCount":1,"participants":["Sylvain Joyeux"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"81879","messageId":"20080701145701.GC5852@joyeux","threadId":"14244","inReplyTo":null,"subject":"[PATCH] better git-submodule status output","fromName":"Sylvain Joyeux","fromEmail":"sylvain.joyeux@dfki.de","sentAt":"2008-07-01T14:57:01Z","receivedAt":"2008-07-01T14:57:01Z","isPatch":true,"sender":{"key":"sylvain.joyeux@dfki.de","avatar":null},"body":"This patch makes the output of git-submodule more useful to handle the\nmanagement of a repository using multiple submodules. Namely, it\ndisplays informations about how the current checked out version relates\nto the registered one (i.e. direct parent, direct child, \"just\ndifferent\", registered revision does not exist), and displays if the\nsubmodules contain uncommitted changes.\n\nThis (among other things) allows to do git-submodule update while\nknowing exactly what will happen.\n\nSylvain\n\n\n\n>From 16553a9b210a956b0af961d55a9cf06f1b9b8114 Mon Sep 17 00:00:00 2001\nFrom: Sylvain Joyeux <sylvain.joyeux@dfki.de>\nDate: Tue, 1 Jul 2008 16:01:01 +0200\nSubject: [PATCH] more information in git-submodule status output\n\nThis commit adds more information in the 'status' output of\ngit-submodule. More specifically, it displays different flags if the\nsubmodule and the registered revision are direct parents (> and <,\ndepending on which is the ancestor), if they are not direct parents (+)\nor if the registered revision cannot be found (i.e. if submodule update\nwould fail, '!')\n\nFinally, it shows if the submodule contains uncommitted changes (M flag)\n\nSigned-off-by: Sylvain Joyeux <sylvain.joyeux@dfki.de>\n---\n Documentation/git-submodule.txt |   23 ++++++++++++++++++-----\n git-submodule.sh                |   32 ++++++++++++++++++++++++++++----\n t/t7400-submodule-basic.sh      |   20 +++++++++++++-------\n 3 files changed, 59 insertions(+), 16 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 441ae14..3820002 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -33,10 +33,23 @@ status::\n \tShow the status of the submodules. This will print the SHA-1 of the\n \tcurrently checked out commit for each submodule, along with the\n \tsubmodule path and the output of linkgit:git-describe[1] for the\n-\tSHA-1. Each SHA-1 will be prefixed with `-` if the submodule is not\n-\tinitialized and `+` if the currently checked out submodule commit\n-\tdoes not match the SHA-1 found in the index of the containing\n-\trepository. This command is the default command for git-submodule.\n+\tSHA-1. Each SHA-1 will be prefixed with the following codes:\n+\t* `-` if the submodule is not initialized\n+\t* `<` if the current submodule HEAD is a direct ancestor of the\n+\t    revision registered in the containing repository.  I.e. a `git\n+\t    submodule update` would lead to a fast forward.\n+\t* `>` if the current submodule HEAD is a direct ancestor of the\n+\t    revision registered in the containing repository.\n+\t* `+` if the current submodule HEAD and the revision registered in\n+\t    the containing repository do not match, and there is no direct\n+\t    relationship between the two commits.\n+\t* `!` if the SHA-1 found in the index of the containing repository is\n+\t    not present in the the currently checked out submodule commit,\n+\t    nor be fetched from the associated remote.\n+\t\n+\tAdditionally, a 'M' is displayed if the currently checked out\n+\tsubmodule contains uncommitted changes.\n+\tThis command is the default command for git-submodule.\n \n init::\n \tInitialize the submodules, i.e. register in .git/config each submodule\n@@ -97,7 +110,7 @@ for details.\n \n AUTHOR\n ------\n-Written by Lars Hjemli <hjemli@gmail.com>\n+Written by Lars Hjemli <hjemli@gmail.com> and Sylvain Joyeux <sylvain.joyeux@m4x.org>\n \n GIT\n ---\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 3eb78cc..e2b91f6 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -522,7 +522,11 @@ cmd_summary() {\n #\n # List all submodules, prefixed with:\n #  - submodule not initialized\n-#  + different revision checked out\n+#  > the checked out version is in advance with the current version (fast-forward)\n+#  < the checked out version is late w.r.t the current version (fast-forward)\n+#  + different revisions checked out, no fast-forward relationship\n+#  ! the checked out version does not exist and cannot be fetched\n+#  M submodule contains uncommitted changes\n #\n # If --cached was specified the revision in the index will be printed\n # instead of the currently checked out revision.\n@@ -562,20 +566,40 @@ cmd_status()\n \t\turl=$(git config submodule.\"$name\".url)\n \t\tif test -z \"$url\" || ! test -d \"$path\"/.git -o -f \"$path\"/.git\n \t\tthen\n-\t\t\tsay \"-$sha1 $path\"\n+\t\t\tsay \"-  $sha1 $path\"\n \t\t\tcontinue;\n \t\tfi\n+                unclean=\" \"\n+                if ! ( unset GIT_DIR; cd \"$path\" && git diff --quiet HEAD ); then\n+                    unclean=\"M\"\n+                fi\n \t\tset_name_rev \"$path\" \"$sha1\"\n \t\tif git diff-files --quiet -- \"$path\"\n \t\tthen\n-\t\t\tsay \" $sha1 $path$revname\"\n+\t\t\tsay \" $unclean $sha1 $path$revname\"\n \t\telse\n+                        head=$(unset GIT_DIR; cd \"$path\" && git rev-parse --verify HEAD)\n+                        common=$(unset GIT_DIR; cd \"$path\" && git merge-base HEAD $sha1)\n+                        if test -z \"$common\"; then\n+                            common=$(unset GIT_DIR; cd \"$path\" && git-fetch -q &&\n+                                    git merge-base HEAD $sha1)\n+                        fi\n+                        if test \"$common\" = \"$sha1\"; then\n+                            modflag=\">\"\n+                        elif test \"$common\" = \"$head\"; then\n+                            modflag=\"<\"\n+                        elif test \"$common\" = \"\"; then\n+                            modflag=\"!\"\n+                        else\n+                            modflag=\"+\"\n+                        fi\n+\n \t\t\tif test -z \"$cached\"\n \t\t\tthen\n \t\t\t\tsha1=$(unset GIT_DIR; cd \"$path\" && git rev-parse --verify HEAD)\n \t\t\t\tset_name_rev \"$path\" \"$sha1\"\n \t\t\tfi\n-\t\t\tsay \"+$sha1 $path$revname\"\n+\t\t\tsay \"$modflag$unclean $sha1 $path$revname\"\n \t\tfi\n \tdone\n }\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 6c7b902..ffaa932 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -65,7 +65,7 @@ test_expect_success 'status should only print one line' '\n '\n \n test_expect_success 'status should initially be \"missing\"' '\n-\tgit-submodule status | grep \"^-$rev1\"\n+\tgit-submodule status | grep \"^-  $rev1\"\n '\n \n test_expect_success 'init should register submodule url in .git/config' '\n@@ -130,13 +130,19 @@ test_expect_success 'update should work when path is an empty dir' '\n '\n \n test_expect_success 'status should be \"up-to-date\" after update' '\n-\tgit-submodule status | grep \"^ $rev1\"\n+\tgit-submodule status | grep \"^   $rev1\"\n '\n \n-test_expect_success 'status should be \"modified\" after submodule commit' '\n+test_expect_success 'status should be \"modified\" after submodule change' '\n \tcd init &&\n \techo b >b &&\n-\tgit add b &&\n+        git add b &&\n+        cd .. &&\n+\tgit-submodule status | grep \"^ M $rev1\"\n+'\n+\n+test_expect_success 'status should be \"in advance\" after submodule commit' '\n+\tcd init &&\n \tgit-commit -m \"submodule commit 2\" &&\n \trev2=$(git rev-parse HEAD) &&\n \tcd .. &&\n@@ -145,11 +151,11 @@ test_expect_success 'status should be \"modified\" after submodule commit' '\n \t\techo \"[OOPS] submodule git rev-parse returned nothing\"\n \t\tfalse\n \tfi &&\n-\tgit-submodule status | grep \"^+$rev2\"\n+\tgit-submodule status | grep \"^>  $rev2\"\n '\n \n test_expect_success 'the --cached sha1 should be rev1' '\n-\tgit-submodule --cached status | grep \"^+$rev1\"\n+\tgit-submodule --cached status | grep \"^>  $rev1\"\n '\n \n test_expect_success 'git diff should report the SHA1 of the new submodule commit' '\n@@ -171,7 +177,7 @@ test_expect_success 'update should checkout rev1' '\n '\n \n test_expect_success 'status should be \"up-to-date\" after update' '\n-\tgit-submodule status | grep \"^ $rev1\"\n+\tgit-submodule status | grep \"^   $rev1\"\n '\n \n test_expect_success 'checkout superproject with subproject already present' '\n-- \n1.5.6\n\n"}]}