xref: /openbsd-src/gnu/usr.bin/perl/Porting/GitUtils.pm (revision 256a93a44f36679bee503f12e49566c2183f6181)
143003dfeSmillert#!/usr/bin/perl
2*256a93a4Safresh1package GitUtils;
343003dfeSmillertuse strict;
443003dfeSmillertuse warnings;
543003dfeSmillertuse POSIX qw(strftime);
643003dfeSmillert
743003dfeSmillertuse base qw/Exporter/;
843003dfeSmillertour @EXPORT_OK=qw(iso_time_with_dot gen_dot_patch);
943003dfeSmillert
1043003dfeSmillertsub iso_time_with_dot {
1143003dfeSmillert    strftime "%Y-%m-%d.%H:%M:%S",gmtime(shift||time)
1243003dfeSmillert}
1343003dfeSmillert
1443003dfeSmillert# generate the contents of a .patch file for an arbitrary commitish, or for HEAD if none is supplied
1543003dfeSmillert# assumes the CWD is inside of a perl git repository. If the repository is bare then refs/heads/*
1643003dfeSmillert# is used to determine the branch. If the repository is not bare then refs/remotes/origin/* is used
1743003dfeSmillert# to determine the branch. (The assumption being that if its bare then this is running inside of
1843003dfeSmillert# the master git repo - if its not bare then it is a checkout which may not have all the branches)
1943003dfeSmillertsub gen_dot_patch {
2043003dfeSmillert    my $target= shift || 'HEAD';
2143003dfeSmillert    chomp(my ($git_dir, $is_bare, $sha1)=`git rev-parse --git-dir --is-bare-repository $target`);
2243003dfeSmillert    die "Not in a git repository!" if !$git_dir;
2343003dfeSmillert    $is_bare= "" if $is_bare and $is_bare eq 'false';
2443003dfeSmillert
2543003dfeSmillert    # which branches to scan - the order here is important, the first hit we find we use
2643003dfeSmillert    # so if two branches can both reach a ref we want the right one first.
2743003dfeSmillert    my @branches=(
2843003dfeSmillert              'blead',
2943003dfeSmillert              'maint-5.10',
3043003dfeSmillert              'maint-5.8',
3143003dfeSmillert              'maint-5.8-dor',
3243003dfeSmillert              'maint-5.6',
3343003dfeSmillert              'maint-5.005',
3443003dfeSmillert              'maint-5.004',
3543003dfeSmillert              # and more generalized searches...
3643003dfeSmillert              'refs/heads/*',
3743003dfeSmillert              'refs/remotes/*',
3843003dfeSmillert              'refs/*',
3943003dfeSmillert    );
4043003dfeSmillert    my $reftype= $is_bare ? "heads" : "remotes/origin";
4143003dfeSmillert    my $branch;
4243003dfeSmillert    foreach my $name (@branches) {
4343003dfeSmillert        my $refs= $name=~m!^refs/! ? $name : "refs/$reftype/$name";
4443003dfeSmillert        my $cmd= "git name-rev --name-only --refs=$refs $sha1";
4543003dfeSmillert        chomp($branch= `$cmd`);
4643003dfeSmillert        last if $branch ne 'undefined';
4743003dfeSmillert    }
4843003dfeSmillert    for ($branch) {
496fb12b70Safresh1        $_  ||= "error";            # hmm, we did not get /anything/ from name-rev?
5043003dfeSmillert        s!^\Q$reftype\E/!! ||       # strip off the reftype
5143003dfeSmillert        s!^refs/heads/!!   ||       # possible other places it was found
5243003dfeSmillert        s!^refs/remotes/!! ||       # ...
5343003dfeSmillert        s!^refs/!!;                 # might even be a tag or something weirdo...
5443003dfeSmillert        s![~^].*\z!!;               # strip off how far we are from the item
5543003dfeSmillert    }
5643003dfeSmillert    my $tstamp= iso_time_with_dot(`git log -1 --pretty="format:%ct" $sha1`);
5743003dfeSmillert    chomp(my $describe= `git describe $sha1`);
5843003dfeSmillert    join(" ", $branch, $tstamp, $sha1, $describe);
5943003dfeSmillert}
6043003dfeSmillert
6143003dfeSmillert1;
62