{"thread":{"id":"53","subject":"git-pasky: gitXnormid.sh overhaul","startedAt":"2005-04-16T16:51:29Z","lastAt":"2005-04-16T16:51:29Z","messageCount":1,"participants":["Rene Scharfe"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"326","messageId":"20050416165129.GA13152@lsrfire.ath.cx","threadId":"53","inReplyTo":null,"subject":"git-pasky: gitXnormid.sh overhaul","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2005-04-16T16:51:29Z","receivedAt":"2005-04-16T16:51:29Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Hello,\n\nI just couldn't stand all the calls to grep and other external tools in\ngitXnormid.sh and started rewriting it in a knee-jerk reaction.\n\nYou said in a private conversation that you don't like to include things\nlike ${var#stuff} to stay \"sh compatible\", while OTOH you favour $(cmd)\nover `cmd`.  Both are POSIX extensions of the classical Bourne Shell\nsyntax (see e.g. http://docs.hp.com/en/B2355-90046/ch15s03.html for a\nfeature comparision between POSIX shell, Bourne Shell and Korn Shells on\nHP-UX).  For reference, The Open Group publishes its IEEE Std 1003.1\nstandard (vulgo: POSIX) on this website:\nhttp://www.opengroup.org/onlinepubs/009695399/toc.htm.  So which shell\ndo you want to target with your git scripts?\n\nThis time I tested the script. :]  It copes with invalid IDs,\nnon-existing valid IDs, abbreviated IDs, an omitted ID, valid IDs, with\ntags and branch names.  I also made sure the script runs with bash, ash,\npdksh, zsh and bash --posix (all on SuSE 9.2).\n\nI changed the way an ID is verified.  The script now tries to find tags\nand branches first by looking for .git/tags/<id> and .git/HEAD.<id> and\nafter that looking inside .git/objects for a match.  That's faster and\nnow I can safely give a branch a name consisting of 40 hex digits. :-)\n\nThe script follows in plain text format, not as a patch.  Your and my\nversion share only very few lines, so this way it's easier to review.\nI'll send you a patch if and when you're ready to apply it, ok?\n\nThanks,\nRene\n\n\n--- 8< ---\n#!/bin/sh\n#\n# Internal: Normalize the given ID to a tree ID.\n# Copyright (c) Petr Baudis, 2005\n#\n# Takes an arbitrary ID as a parameter. -c tells it to give\n# a commit id rather than tree id.\n\nusage() {\n\techo \"Usage: $0 [-c] [tree-id | commit-id | tag | branch]\"\n\texit 2\n}\n\nget_first_word() {\n\tif read one two; then\n\t\techo \"$one\"\n\t\treturn 0\n\tfi\n\treturn 1\n}\n\nexpand_hash() {\n\thashdir=${SHA1_FILE_DIRECTORY:-.git/objects}\n\tfilename=${1#??}\n\tdirname=${1%${filename}}\n\tfirst=true\n\tfor file in \"${hashdir}/${dirname}/${filename}\"*; do\n\t\t[ -f \"$file\" ] || return 1\n\t\tif $first; then\n\t\t\thash=${dirname}${file##*/}\n\t\t\tfirst=false\n\t\telse\n\t\t\treturn 1\n\t\tfi\n\tdone\n\t$first && return 1\n\techo \"$hash\"\n}\n\nget_tree_id() {\n\tcat-file commit \"$1\" | while read tag hash; do\n\t\tif [ \"$tag\" = \"tree\" ]; then\n\t\t\techo \"$hash\"\n\t\t\treturn\n\t\tfi\n\tdone\n}\n\ntype=tree\ncase \"$1\" in\n-c) type=commit; shift;;\n-*) usage;;\nesac\n\nif [ ! \"$1\" ]; then\n\tif [ ! -f \".git/HEAD\" ]; then\n\t\techo \"$0: file .git/HEAD not found\"\n\t\tusage\n\tfi\n\tid=$(get_first_word <\".git/HEAD\")\nelif [ -f \".git/tags/$1\" ]; then\n\tid=$(get_first_word <\".git/tags/$1\")\nelif [ -f \".git/HEAD.$1\" ]; then\n\tid=$(get_first_word <\".git/HEAD.$1\")\nelse\n\tid=$(expand_hash \"$1\")\nfi\nif [ $? != 0 ]; then\n\techo \"$0: invalid ID: $1\" >&2\n\texit 1\nfi\n\nif [ \"$type\" = \"tree\" ]; then\n\ttree_id=$(get_tree_id \"$id\" 2>/dev/null)\n\t[ \"$tree_id\" ] && id=$tree_id\nfi\n\nif [ $(cat-file -t \"$id\") != \"$type\" ]; then\n\techo \"$0: invalid ID: $id\" >&2\n\texit 1\nfi\necho \"$id\"\n"}]}