{"thread":{"id":"14142","subject":"[PATCH 1/2] fix update-hook-example to work with packed tag references","startedAt":"2008-06-25T08:26:55Z","lastAt":"2008-06-25T23:14:31Z","messageCount":4,"participants":["Dmitry Potapov","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"81092","messageId":"1214382416-6687-1-git-send-email-dpotapov@gmail.com","threadId":"14142","inReplyTo":null,"subject":"[PATCH 1/2] fix update-hook-example to work with packed tag references","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-06-25T08:26:55Z","receivedAt":"2008-06-25T08:26:55Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"The update-hook-example used 'test -f' to check the tag present, which\ndoes not work if the checked reference is packed. This check has been\nchanged to use 'git rev-parse $tag' instead.\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\n Documentation/howto/update-hook-example.txt |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt\nindex 88765b5..a8d3bae 100644\n--- a/Documentation/howto/update-hook-example.txt\n+++ b/Documentation/howto/update-hook-example.txt\n@@ -68,7 +68,7 @@ function info {\n # - Branches should only be fast-forwarded.\n case \"$1\" in\n   refs/tags/*)\n-    [ -f \"$GIT_DIR/$1\" ] &&\n+    git rev-parse --verify -q \"$1\" &&\n     deny >/dev/null \"You can't overwrite an existing tag\"\n     ;;\n   refs/heads/*)\n-- \n1.5.6\n"},{"id":"81093","messageId":"1214382416-6687-2-git-send-email-dpotapov@gmail.com","threadId":"14142","inReplyTo":"1214382416-6687-1-git-send-email-dpotapov@gmail.com","subject":"[PATCH 2/2] update-hook-example: optionally allow non-fast-forward","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-06-25T08:26:56Z","receivedAt":"2008-06-25T08:26:56Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"Sometimes it is desirable to have non-fast-forward branches in a\nshared repository. A typical example of that is the 'pu' branch.\nThis patch extends the format of allowed-users and allow-groups\nfiles by using the '+' sign at the beginning as the mark that\nnon-fast-forward pushes are permitted to the branch.\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\n Documentation/howto/update-hook-example.txt |   20 ++++++++++++--------\n 1 files changed, 12 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt\nindex a8d3bae..e1e2889 100644\n--- a/Documentation/howto/update-hook-example.txt\n+++ b/Documentation/howto/update-hook-example.txt\n@@ -65,7 +65,7 @@ function info {\n \n # Implement generic branch and tag policies.\n # - Tags should not be updated once created.\n-# - Branches should only be fast-forwarded.\n+# - Branches should only be fast-forwarded unless their pattern starts with '+'\n case \"$1\" in\n   refs/tags/*)\n     git rev-parse --verify -q \"$1\" &&\n@@ -80,7 +80,7 @@ case \"$1\" in\n       mb=$(git-merge-base \"$2\" \"$3\")\n       case \"$mb,$2\" in\n         \"$2,$mb\") info \"Update is fast-forward\" ;;\n-        *)        deny >/dev/null  \"This is not a fast-forward update.\" ;;\n+        *)        noff=y; info \"This is not a fast-forward update.\";;\n       esac\n     fi\n     ;;\n@@ -98,8 +98,9 @@ info \"The user is: '$username'\"\n if [ -f \"$allowed_users_file\" ]; then\n   rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |\n     while read head_pattern user_patterns; do\n-      matchlen=$(expr \"$1\" : \"$head_pattern\")\n-      if [ \"$matchlen\" == \"${#1}\" ]; then\n+      matchlen=$(expr \"$1\" : \"${head_pattern#+}\")\n+      allow_noff=$(expr substr \"$head_pattern\" 1 1)\n+      if [ \"$matchlen\" = \"${#1}\" -a \\( -z \"$noff\" -o \"$allow_noff\" = '+' \\) ]; then\n         info \"Found matching head pattern: '$head_pattern'\"\n         for user_pattern in $user_patterns; do\n           info \"Checking user: '$username' against pattern: '$user_pattern'\"\n@@ -127,8 +128,9 @@ info \"'$groups'\"\n if [ -f \"$allowed_groups_file\" ]; then\n   rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |\n     while read head_pattern group_patterns; do\n-      matchlen=$(expr \"$1\" : \"$head_pattern\")\n-      if [ \"$matchlen\" == \"${#1}\" ]; then\n+      matchlen=$(expr \"$1\" : \"${head_pattern#+}\")\n+      allow_noff=$(expr substr \"$head_pattern\" 1 1)\n+      if [ \"$matchlen\" = \"${#1}\" -a \\( -z \"$noff\" -o \"$allow_noff\" = '+' \\) ]; then\n         info \"Found matching head pattern: '$head_pattern'\"\n         for group_pattern in $group_patterns; do\n           for groupname in $groups; do\n@@ -159,6 +161,7 @@ allowed-groups, to describe which heads can be pushed into by\n whom.  The format of each file would look like this:\n \n         refs/heads/master\tjunio\n+        +refs/heads/pu\t\tjunio\n         refs/heads/cogito$\tpasky\n         refs/heads/bw/.*\tlinus\n         refs/heads/tmp/.*\t.*\n@@ -166,7 +169,8 @@ whom.  The format of each file would look like this:\n \n With this, Linus can push or create \"bw/penguin\" or \"bw/zebra\"\n or \"bw/panda\" branches, Pasky can do only \"cogito\", and JC can\n-do master branch and make versioned tags.  And anybody can do\n-tmp/blah branches.\n+do master and pu branches and make versioned tags.  And anybody\n+can do tmp/blah branches. The '+' sign at the pu record means\n+that JC can make non-fast-forward pushes on it.\n \n ------------\n-- \n1.5.6\n"},{"id":"81173","messageId":"7vtzfhz3fb.fsf@gitster.siamese.dyndns.org","threadId":"14142","inReplyTo":"1214382416-6687-2-git-send-email-dpotapov@gmail.com","subject":"Re: [PATCH 2/2] update-hook-example: optionally allow non-fast-forward","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-25T20:04:56Z","receivedAt":"2008-06-25T20:04:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dmitry Potapov <dpotapov@gmail.com> writes:\n\n> Sometimes it is desirable to have non-fast-forward branches in a\n> shared repository. A typical example of that is the 'pu' branch.\n> This patch extends the format of allowed-users and allow-groups\n> files by using the '+' sign at the beginning as the mark that\n> non-fast-forward pushes are permitted to the branch.\n\nThanks.  1/2 queued for 'maint' (as it was an obvious fix) to be included\nin 1.5.6.1, but not this one that is a feature enhancement even though it\nis in docs.\n\n> Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>\n\n>    rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |\n>      while read head_pattern user_patterns; do\n> -      matchlen=$(expr \"$1\" : \"$head_pattern\")\n> -      if [ \"$matchlen\" == \"${#1}\" ]; then\n> +      matchlen=$(expr \"$1\" : \"${head_pattern#+}\")\n> +      allow_noff=$(expr substr \"$head_pattern\" 1 1)\n> +      if [ \"$matchlen\" = \"${#1}\" -a \\( -z \"$noff\" -o \"$allow_noff\" = '+' \\) ]; then\n\n\"expr substr\"?  Please don't.\n\n    cf. http://www.opengroup.org/onlinepubs/000095399/utilities/expr.html\n\nI'd probably write this part like so:\n\n\t... pipe ... |\n\twhile read heads users\n        do\n        \t# does this rule apply to us?\n        \thead_pattern=${heads#+}\n                matchlen=$(expr \"$1\" : \"$head_pattern\")\n                test \"$matchlen\" = ${#1} || continue\n\n                # if non-ff, $heads must be with the '+' prefix\n                test -n \"$noff\" &&\n                test \"z$head_pattern\" = \"z$heads\" && continue\n\n                ... Ok this is good.\n"},{"id":"81207","messageId":"20080625231431.GD5737@dpotapov.dyndns.org","threadId":"14142","inReplyTo":"7vtzfhz3fb.fsf@gitster.siamese.dyndns.org","subject":"[PATCH v2] update-hook-example: optionally allow non-fast-forward","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-06-25T23:14:31Z","receivedAt":"2008-06-25T23:14:31Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"Sometimes it is desirable to have non-fast-forward branches in a\nshared repository. A typical example of that is the 'pu' branch.\nThis patch extends the format of allowed-users and allow-groups\nfiles by using the '+' sign at the beginning as the mark that\nnon-fast-forward pushes are permitted to the branch.\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\n\nOn Wed, Jun 25, 2008 at 01:04:56PM -0700, Junio C Hamano wrote:\n> \n> I'd probably write this part like so:\n<snip>\n\nThank you for advice. I have corrected the patch.\n\n Documentation/howto/update-hook-example.txt |   75 ++++++++++++++++-----------\n 1 files changed, 45 insertions(+), 30 deletions(-)\n\ndiff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt\nindex a8d3bae..7f430a0 100644\n--- a/Documentation/howto/update-hook-example.txt\n+++ b/Documentation/howto/update-hook-example.txt\n@@ -65,7 +65,7 @@ function info {\n \n # Implement generic branch and tag policies.\n # - Tags should not be updated once created.\n-# - Branches should only be fast-forwarded.\n+# - Branches should only be fast-forwarded unless their pattern starts with '+'\n case \"$1\" in\n   refs/tags/*)\n     git rev-parse --verify -q \"$1\" &&\n@@ -80,7 +80,7 @@ case \"$1\" in\n       mb=$(git-merge-base \"$2\" \"$3\")\n       case \"$mb,$2\" in\n         \"$2,$mb\") info \"Update is fast-forward\" ;;\n-        *)        deny >/dev/null  \"This is not a fast-forward update.\" ;;\n+        *)        noff=y; info \"This is not a fast-forward update.\";;\n       esac\n     fi\n     ;;\n@@ -97,19 +97,25 @@ info \"The user is: '$username'\"\n \n if [ -f \"$allowed_users_file\" ]; then\n   rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |\n-    while read head_pattern user_patterns; do\n-      matchlen=$(expr \"$1\" : \"$head_pattern\")\n-      if [ \"$matchlen\" == \"${#1}\" ]; then\n-        info \"Found matching head pattern: '$head_pattern'\"\n-        for user_pattern in $user_patterns; do\n-          info \"Checking user: '$username' against pattern: '$user_pattern'\"\n-          matchlen=$(expr \"$username\" : \"$user_pattern\")\n-          if [ \"$matchlen\" == \"${#username}\" ]; then\n-            grant \"Allowing user: '$username' with pattern: '$user_pattern'\"\n-          fi\n-        done\n-        deny \"The user is not in the access list for this branch\"\n-      fi\n+    while read heads user_patterns; do\n+      #  does this rule apply to us?\n+      head_pattern=${heads#+}\n+      matchlen=$(expr \"$1\" : \"${head_pattern#+}\")\n+      test \"$matchlen\" = ${#1} || continue\n+\n+      # if non-ff, $heads must be with the '+' prefix\n+      test -n \"$noff\" &&\n+      test \"$head_pattern\" = \"$heads\" && continue\n+\n+      info \"Found matching head pattern: '$head_pattern'\"\n+      for user_pattern in $user_patterns; do\n+        info \"Checking user: '$username' against pattern: '$user_pattern'\"\n+        matchlen=$(expr \"$username\" : \"$user_pattern\")\n+        if [ \"$matchlen\" == \"${#username}\" ]; then\n+          grant \"Allowing user: '$username' with pattern: '$user_pattern'\"\n+        fi\n+      done\n+      deny \"The user is not in the access list for this branch\"\n     done\n   )\n   case \"$rc\" in\n@@ -127,20 +133,27 @@ info \"'$groups'\"\n if [ -f \"$allowed_groups_file\" ]; then\n   rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |\n     while read head_pattern group_patterns; do\n-      matchlen=$(expr \"$1\" : \"$head_pattern\")\n-      if [ \"$matchlen\" == \"${#1}\" ]; then\n-        info \"Found matching head pattern: '$head_pattern'\"\n-        for group_pattern in $group_patterns; do\n-          for groupname in $groups; do\n-            info \"Checking group: '$groupname' against pattern: '$group_pattern'\"\n-            matchlen=$(expr \"$groupname\" : \"$group_pattern\")\n-            if [ \"$matchlen\" == \"${#groupname}\" ]; then\n-              grant \"Allowing group: '$groupname' with pattern: '$group_pattern'\"\n-            fi\n-          done\n+\n+      #  does this rule apply to us?\n+      head_pattern=${heads#+}\n+      matchlen=$(expr \"$1\" : \"${head_pattern#+}\")\n+      test \"$matchlen\" = ${#1} || continue\n+\n+      # if non-ff, $heads must be with the '+' prefix\n+      test -n \"$noff\" &&\n+      test \"$head_pattern\" = \"$heads\" && continue\n+\n+      info \"Found matching head pattern: '$head_pattern'\"\n+      for group_pattern in $group_patterns; do\n+        for groupname in $groups; do\n+          info \"Checking group: '$groupname' against pattern: '$group_pattern'\"\n+          matchlen=$(expr \"$groupname\" : \"$group_pattern\")\n+          if [ \"$matchlen\" == \"${#groupname}\" ]; then\n+            grant \"Allowing group: '$groupname' with pattern: '$group_pattern'\"\n+          fi\n         done\n-        deny \"None of the user's groups are in the access list for this branch\"\n-      fi\n+      done\n+      deny \"None of the user's groups are in the access list for this branch\"\n     done\n   )\n   case \"$rc\" in\n@@ -159,6 +172,7 @@ allowed-groups, to describe which heads can be pushed into by\n whom.  The format of each file would look like this:\n \n         refs/heads/master\tjunio\n+        +refs/heads/pu\t\tjunio\n         refs/heads/cogito$\tpasky\n         refs/heads/bw/.*\tlinus\n         refs/heads/tmp/.*\t.*\n@@ -166,7 +180,8 @@ whom.  The format of each file would look like this:\n \n With this, Linus can push or create \"bw/penguin\" or \"bw/zebra\"\n or \"bw/panda\" branches, Pasky can do only \"cogito\", and JC can\n-do master branch and make versioned tags.  And anybody can do\n-tmp/blah branches.\n+do master and pu branches and make versioned tags.  And anybody\n+can do tmp/blah branches. The '+' sign at the pu record means\n+that JC can make non-fast-forward pushes on it.\n \n ------------\n-- \n1.5.6\n"}]}