Browse Source

Add findtags - reworked

A short perl script that will walk the tag refs, tag objects, and even commit
objects in its quest to figure out whether the given SHA1 (for a commit or
tree) was ever tagged.

This version is reworked incorporating sanity, feature and style fixes from
Junio.

Usage: git-findtags.perl [ -t ] <commit-or-tree-sha1>

Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
maint
Martin Langhoff 20 years ago committed by Junio C Hamano
parent
commit
8af12741ee
  1. 3
      Makefile
  2. 94
      git-findtags.perl

3
Makefile

@ -93,7 +93,8 @@ SCRIPT_SH = \ @@ -93,7 +93,8 @@ SCRIPT_SH = \

SCRIPT_PERL = \
git-archimport.perl git-cvsimport.perl git-relink.perl \
git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl
git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl \
git-findtags.perl

SCRIPT_PYTHON = \
git-merge-recursive.py

94
git-findtags.perl

@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
#!/usr/bin/perl -w
#
# Copyright (c) 2005 Martin Langhoff
#
# Walk the tags and find if they match a commit
# expects a SHA1 of a commit. Option -t enables
# searching trees too.
#

use strict;
use File::Basename;
use File::Find;
use Getopt::Std;

my $git_dir = $ENV{GIT_DIR} || '.git';
$git_dir =~ s|/$||; # chomp trailing slash

# options
our $opt_t;
getopts("t") || usage();

my @tagfiles = `find $git_dir/refs/tags -follow -type f`; # haystack
my $target = shift @ARGV; # needle
unless ($target) {
usage();
}

# drive the processing from the find hook
# slower, safer (?) than the find utility
find( { wanted => \&process,
no_chdir => 1,
follow => 1,
}, "$git_dir/refs/tags");


sub process {
my ($dev,$ino,$mode,$nlink,$uid,$gid);

# process only regular files
unless ((($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _) {
return 1; # ignored anyway
}

my $tagfile = $_;
chomp $tagfile;
my $tagname = substr($tagfile, length($git_dir.'/refs/tags/'));

my $tagid = quickread($tagfile);
chomp $tagid;

# is it just a soft tag?
if ($tagid eq $target) {
print "$tagname\n";
return 1; # done with this tag
}

# grab the first 2 lines (the whole tag could be large)
my $tagobj = `git-cat-file tag $tagid | head -n2 `;
if ($tagobj =~ m/^type commit$/m) { # only deal with commits

if ($tagobj =~ m/^object $target$/m) { # match on the commit
print "$tagname\n";

} elsif ( $opt_t && # follow the commit
$tagobj =~ m/^object (\S+)$/m) { # and try to match trees
my $commitid = $1;
my $commitobj = `git-cat-file commit $commitid | head -n1`;
chomp $commitobj;
$commitobj =~ m/^tree (\S+)$/;
my $treeid = $1;
if ($target eq $treeid) {
print "$tagname\n";
}
}
}
}

sub quickread {
my $file = shift;
local $/; # undef: slurp mode
open FILE, "<$file"
or die "Cannot open $file : $!";
my $content = <FILE>;
close FILE;
return $content;
}

sub usage {
print STDERR <<END;
Usage: ${\basename $0} # find tags for a commit or tree
[ -t ] <commit-or-tree-sha1>
END
exit(1);
}
Loading…
Cancel
Save