{"thread":{"id":"2086","subject":"[PATCH] Add findtags - reworked","startedAt":"2005-10-13T08:56:50Z","lastAt":"2005-10-13T08:56:50Z","messageCount":1,"participants":["Martin Langhoff"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"10060","messageId":"11291938104157-git-send-email-martin@catalyst.net.nz","threadId":"2086","inReplyTo":null,"subject":"[PATCH] Add findtags - reworked","fromName":"Martin Langhoff","fromEmail":"martin@catalyst.net.nz","sentAt":"2005-10-13T08:56:50Z","receivedAt":"2005-10-13T08:56:50Z","isPatch":true,"sender":{"key":"martin@laptop.org","avatar":null},"body":"A short perl script that will walk the tag refs, tag objects, and even commit\nobjects in its quest to figure out whether the given SHA1 (for a commit or\ntree) was ever tagged.\n\nThis version is reworked incorporating sanity, feature and style fixes from\nJunio.\n\nUsage: git-findtags.perl [ -t ] <commit-or-tree-sha1>\n\nSigned-off-by: Martin Langhoff <martin@catalyst.net.nz>\n\n\n---\n\n Makefile          |    3 +-\n git-findtags.perl |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 96 insertions(+), 1 deletions(-)\n create mode 100755 git-findtags.perl\n\napplies-to: ef9b5c2cb61cf509adf2f5ef37fa1db517291f48\n342d4cd1c66d8e58e1ba2221366c9237f9197b03\ndiff --git a/Makefile b/Makefile\nindex 8697d52..a5d9cd4 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -93,7 +93,8 @@ SCRIPT_SH = \\\n \n SCRIPT_PERL = \\\n \tgit-archimport.perl git-cvsimport.perl git-relink.perl \\\n-\tgit-rename.perl git-shortlog.perl git-fmt-merge-msg.perl\n+\tgit-rename.perl git-shortlog.perl git-fmt-merge-msg.perl \\\n+\tgit-findtags.perl\n \n SCRIPT_PYTHON = \\\n \tgit-merge-recursive.py\ndiff --git a/git-findtags.perl b/git-findtags.perl\nnew file mode 100755\nindex 0000000..745affe\n--- /dev/null\n+++ b/git-findtags.perl\n@@ -0,0 +1,94 @@\n+#!/usr/bin/perl -w\n+#\n+# Copyright (c) 2005 Martin Langhoff\n+#\n+# Walk the tags and find if they match a commit\n+# expects a SHA1 of a commit. Option -t enables \n+# searching trees too.\n+#\n+\n+use strict;\n+use File::Basename;\n+use File::Find;\n+use Getopt::Std;\n+\n+my $git_dir = $ENV{GIT_DIR} || '.git';\n+$git_dir =~ s|/$||; # chomp trailing slash\n+\n+# options\n+our $opt_t;\n+getopts(\"t\") || usage();\n+\n+my @tagfiles   = `find $git_dir/refs/tags -follow -type f`; # haystack\n+my $target = shift @ARGV;                     # needle\n+unless ($target) {\n+    usage();\n+}\n+\n+# drive the processing from the find hook\n+# slower, safer (?) than the find utility\n+find( { wanted   => \\&process,\n+\tno_chdir => 1,\n+\tfollow   => 1,\n+      }, \"$git_dir/refs/tags\");\n+\n+\n+sub process {\n+    my ($dev,$ino,$mode,$nlink,$uid,$gid);\n+\n+    # process only regular files\n+    unless ((($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _) {\n+\treturn 1; # ignored anyway\n+    }\n+\n+    my $tagfile = $_;\n+    chomp $tagfile;\n+    my $tagname = substr($tagfile, length($git_dir.'/refs/tags/'));\n+\n+    my $tagid = quickread($tagfile);\n+    chomp $tagid;\n+\n+    # is it just a soft tag?\n+    if ($tagid eq $target) {\n+\tprint \"$tagname\\n\";\n+\treturn 1; # done with this tag\n+    }\n+\n+    # grab the first 2 lines (the whole tag could be large)\n+    my $tagobj = `git-cat-file tag $tagid | head -n2 `;\n+    if ($tagobj =~  m/^type commit$/m) { # only deal with commits\n+\n+\tif ($tagobj =~ m/^object $target$/m) { # match on the commit\n+\t    print \"$tagname\\n\";\n+\n+\t} elsif ( $opt_t &&                      # follow the commit\n+\t\t $tagobj =~ m/^object (\\S+)$/m) { # and try to match trees\n+\t    my $commitid = $1;\n+\t    my $commitobj = `git-cat-file commit $commitid | head -n1`;\n+\t    chomp $commitobj;\n+\t    $commitobj =~ m/^tree (\\S+)$/;\n+\t    my $treeid = $1;\n+\t    if ($target eq $treeid) {\n+\t\tprint \"$tagname\\n\";\n+\t    }\n+\t}\n+    }\n+}\n+\n+sub quickread {\n+    my $file = shift;\n+    local $/; # undef: slurp mode\n+    open FILE, \"<$file\"\n+\tor die \"Cannot open $file : $!\";\n+    my $content = <FILE>;\n+    close FILE;\n+    return $content;\n+}\n+\n+sub usage {\n+\tprint STDERR <<END;\n+Usage: ${\\basename $0}     # find tags for a commit or tree\n+       [ -t ] <commit-or-tree-sha1>\n+END\n+\texit(1);\n+}\n---\n0.99.8.GIT\n"}]}