From 17e4c715b613ebaad2c43f306db9aae8075f2c92 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Tue, 21 Jan 2014 20:33:35 -0500 Subject: [PATCH 1/7] Fixed RT#90667 --- lib/Git/PurePerl/NewObject.pm | 2 +- lib/Git/PurePerl/Object.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Git/PurePerl/NewObject.pm b/lib/Git/PurePerl/NewObject.pm index 74f6d9b..770474b 100644 --- a/lib/Git/PurePerl/NewObject.pm +++ b/lib/Git/PurePerl/NewObject.pm @@ -4,7 +4,7 @@ use MooseX::StrictConstructor; use Moose::Util::TypeConstraints; use namespace::autoclean; -enum 'ObjectKind' => qw(commit tree blob tag); +enum 'ObjectKind' => [qw(commit tree blob tag)]; has 'kind' => ( is => 'ro', isa => 'ObjectKind', required => 1 ); has 'size' => ( is => 'ro', isa => 'Int', required => 0, lazy_build => 1 ); diff --git a/lib/Git/PurePerl/Object.pm b/lib/Git/PurePerl/Object.pm index 8f561e6..71762f5 100644 --- a/lib/Git/PurePerl/Object.pm +++ b/lib/Git/PurePerl/Object.pm @@ -4,7 +4,7 @@ use MooseX::StrictConstructor; use Moose::Util::TypeConstraints; use namespace::autoclean; -enum 'ObjectKind' => qw(commit tree blob tag); +enum 'ObjectKind' => [qw(commit tree blob tag)]; has 'kind' => ( is => 'ro', isa => 'ObjectKind', required => 1 ); has 'size' => ( is => 'ro', isa => 'Int', required => 1 ); From 29f195bc6a293d3b6a9578a5e09d3312b8fd7c4b Mon Sep 17 00:00:00 2001 From: gregor herrmann Date: Sat, 25 Jan 2014 14:48:17 +0100 Subject: [PATCH 2/7] qw() in list context is an error now Drop this syntax as it's no longer supported[0] in 5.18. Thanks to gregor herrmann for this patch[1]! [0] http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#qw%28...%29_can_no_longer_be_used_as_parentheses [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=711443#10 --- t/00_setup.t | 2 +- t/simple.t | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/t/00_setup.t b/t/00_setup.t index 19de5de..eab79b3 100644 --- a/t/00_setup.t +++ b/t/00_setup.t @@ -4,7 +4,7 @@ use warnings; use Test::More; use Archive::Extract; -foreach my $name qw(test-project test-project-packs test-project-packs2 test-encoding) { +foreach my $name (qw(test-project test-project-packs test-project-packs2 test-encoding)) { next if -d $name; my $ae = Archive::Extract->new( archive => "$name.tgz" ); $ae->extract; diff --git a/t/simple.t b/t/simple.t index 2874dd0..2c0ce45 100644 --- a/t/simple.t +++ b/t/simple.t @@ -7,7 +7,7 @@ use Path::Class; my $checkout_directory = dir('t/checkout'); -foreach my $directory qw(test-project test-project-packs test-project-packs2) +foreach my $directory (qw(test-project test-project-packs test-project-packs2)) { my $git = Git::PurePerl->new( directory => $directory ); like( $git->master_sha1, qr/^[a-z0-9]{40}$/ ); From 810b26e4ccd5f9557eb77f0ab03659aa6a61f867 Mon Sep 17 00:00:00 2001 From: Dan Brook Date: Sat, 25 Jan 2014 14:54:58 +0100 Subject: [PATCH 3/7] Bump version to 0.49 --- lib/Git/PurePerl.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Git/PurePerl.pm b/lib/Git/PurePerl.pm index 6728282..3407bfb 100644 --- a/lib/Git/PurePerl.pm +++ b/lib/Git/PurePerl.pm @@ -37,7 +37,7 @@ use IO::Socket::INET; use Path::Class; use namespace::autoclean; -our $VERSION = '0.48'; +our $VERSION = '0.49'; $VERSION = eval $VERSION; has 'directory' => ( From cbcf705b132eaed50154fe7ceb75836beb3f194d Mon Sep 17 00:00:00 2001 From: Dan Brook Date: Sat, 25 Jan 2014 14:58:54 +0100 Subject: [PATCH 4/7] Include changes from 0.49 in CHANGES I should release more often or automate more. --- CHANGES | 7 +++++++ lib/Git/PurePerl.pm | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 28ea605..aa3ef14 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,12 @@ Revision history for Perl module Git::PurePerl: +0.50 Sat Jan 25 14:58:16 CET 2014 + - Now with the changes from 0.49 in CHANGES. That's it. + +0.49 Sat Jan 25 14:55:42 CET 2014 + - qw() in list context is an error now (gregor herrmann) + - Fixed RT#90667 (Zoffix Znet) + 0.48 Thu Jul 14 22:53:55 BST 2011 - Translation from Digest::SHA1 to Digest::SHA (Jonas Genannt) - A git object can also be of zero size. (Christian Walde) diff --git a/lib/Git/PurePerl.pm b/lib/Git/PurePerl.pm index 3407bfb..03e8639 100644 --- a/lib/Git/PurePerl.pm +++ b/lib/Git/PurePerl.pm @@ -37,7 +37,7 @@ use IO::Socket::INET; use Path::Class; use namespace::autoclean; -our $VERSION = '0.49'; +our $VERSION = '0.50'; $VERSION = eval $VERSION; has 'directory' => ( From bda8730b2dbbb65f780bf301723df424db3d4339 Mon Sep 17 00:00:00 2001 From: Kent Fredric Date: Wed, 30 May 2012 02:08:13 +1200 Subject: [PATCH 5/7] Add a utility library for convenience methods Add tests for utils Update changes --- CHANGES | 2 + lib/Git/PurePerl/Util.pm | 97 +++++++++++++++++++++++++++++++++++++++ t/00_setup.t | 2 +- t/09_util.t | 68 +++++++++++++++++++++++++++ test-util.tgz | Bin 0 -> 12528 bytes 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 lib/Git/PurePerl/Util.pm create mode 100644 t/09_util.t create mode 100644 test-util.tgz diff --git a/CHANGES b/CHANGES index aa3ef14..4737ee4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ Revision history for Perl module Git::PurePerl: + - Add Git::PurePerl::Util with handy current_git_dir() util (Kent Fredric) + 0.50 Sat Jan 25 14:58:16 CET 2014 - Now with the changes from 0.49 in CHANGES. That's it. diff --git a/lib/Git/PurePerl/Util.pm b/lib/Git/PurePerl/Util.pm new file mode 100644 index 0000000..654f5fa --- /dev/null +++ b/lib/Git/PurePerl/Util.pm @@ -0,0 +1,97 @@ +use strict; +use warnings; + +package Git::PurePerl::Util; + +# FILENAME: Util.pm +# CREATED: 29/05/12 21:46:21 by Kent Fredric (kentnl) +# ABSTRACT: Helper tools for Git::PurePerl + +use Sub::Exporter -setup => { + exports => [qw( current_git_dir find_git_dir is_git_dir )], + groups => { default => [qw( current_git_dir )], }, +}; +use Path::Class qw( dir ); + +=head1 SYNOPSIS + + use Git::PurePerl::Util; + use Git::PurePerl; + + my $repo = Git::PurePerl->new( + gitdir => current_git_dir(), + ); + +=cut + +=head1 FUNCTIONS + +=head2 is_git_dir + +Determines if the given C<$dir> has the basic requirements of a Git repository dir. + +( ie: either a checkouts C<.git> folder, or a bare repository ) + + if ( is_git_dir( $dir ) ) { + ... + } + +=cut + +sub is_git_dir { + my ($dir) = @_; + return if not -e $dir->subdir('objects'); + return if not -e $dir->subdir('refs'); + return if not -e $dir->file('HEAD'); + return 1; +} + +=head2 find_git_dir + + my $dir = find_git_dir( $subdir ); + +Finds the closest C<.git> or bare tree that is either at C<$subdir> or somewhere above C<$subdir> + +If C<$subdir> is inside a 'bare' repo, returns the path to that repo. + +If C<$subdir> is inside a checkout, returns the path to the checkouts C<.git> dir. + +If C<$subdir> is not inside a git repo, returns a false value. + +=cut + +sub find_git_dir { + my $start = shift; + + return $start if is_git_dir($start); + + my $repodir = $start->subdir('.git'); + + return $repodir if -e $repodir and is_git_dir($repodir); + + return find_git_dir( $start->parent ) + if $start->parent->absolute ne $start->absolute; + + return undef; +} + +=head2 current_git_dir + +Finds the closest C<.git> or bare tree by walking up parents. + + my $git_dir = current_git_dir(); + +If C<$CWD> is inside a bare repo somewhere, it will return the path to the bare repo root directory. + +If C<$CWD> is inside a git checkout, it will return the path to the C<.git> folder of that checkout. + +If C<$CWD> is not inside any recognisable git repo, will return a false value. + +=cut + +sub current_git_dir { + return find_git_dir( dir('.') ); +} + +1; + diff --git a/t/00_setup.t b/t/00_setup.t index eab79b3..b462b03 100644 --- a/t/00_setup.t +++ b/t/00_setup.t @@ -4,7 +4,7 @@ use warnings; use Test::More; use Archive::Extract; -foreach my $name (qw(test-project test-project-packs test-project-packs2 test-encoding)) { +foreach my $name (qw(test-project test-project-packs test-project-packs2 test-encoding test-util)) { next if -d $name; my $ae = Archive::Extract->new( archive => "$name.tgz" ); $ae->extract; diff --git a/t/09_util.t b/t/09_util.t new file mode 100644 index 0000000..562453f --- /dev/null +++ b/t/09_util.t @@ -0,0 +1,68 @@ +#!perl +use strict; +use warnings; +use Test::More; +use Git::PurePerl; +use Path::Class; + +use Git::PurePerl::Util qw( find_git_dir current_git_dir ); + +foreach my $directory (qw(test-project test-project-packs test-project-packs2)) +{ + my $dir = dir($directory); + my $gd = find_git_dir( dir($directory) ); + + is( + $gd->absolute->stringify, + dir($directory)->subdir('.git')->absolute->stringify, + "Correctly resolves an .git from a repo( $directory )" + ); + +} + +foreach my $directory ( + qw( + test-util/deep + test-util/deep/.git + test-util/deep/stage1 + test-util/deep/stage1/stage2/ + ) + ) +{ + is( + find_git_dir( dir($directory) )->absolute->stringify, + dir('test-util/deep/.git')->absolute->stringify, + "finding .git dirs works at all tree levels ( $directory )" + ); +} + +foreach my $directory ( + qw( + test-util/bare + test-util/bare/info + test-util/bare/objects + test-util/bare/refs + test-util/bare/refs/heads + ) + ) +{ + is( + find_git_dir( dir($directory) )->absolute->stringify, + dir('test-util/bare')->absolute->stringify, + "finding bare dirs works at all tree levels ( $directory )" + ); +} + +use Cwd qw( getcwd ); + +my $old_dir = getcwd; + +chdir "test-util/deep/stage1"; + +is( + current_git_dir()->absolute->stringify, + dir('.')->parent->subdir('.git')->absolute->stringify, + "Can work with CWD" +); + +done_testing; diff --git a/test-util.tgz b/test-util.tgz new file mode 100644 index 0000000000000000000000000000000000000000..2112ed2a0f5d0209bb097196828a3b24b61a1f35 GIT binary patch literal 12528 zcma)?MOU3&ux^2kyF0<%CAe#Ff=h6B32qzr;7)K40fM`GaCZ;x?)yF8z2^^{&T3U- zHJ++bW6mOvMTDB)9#n+_oeQHm&@Ah*%_Nc)luAl|so1kTA2hPI2D}1}VgnvtYBKCE z-F7eMirelsC#O0$bG^N+oUN9`qA_l$X%^I?n=9;O^wl&G;Ywo)U_yc-C=_U<;UuLg zVxp3n)PnUXWh9u2t^>CHoUI;5jD#Lvi0f4K{k$GO`~mP)7n%$9=_>C9j zHw*3q+7#OOmw*AAfcI(MpVz&iy&@-ItP60ZZgt!Pz_G>wF~~FUB1UK#X82%F{fh-C zGSG*+wW$-I0j7=2=|^{XtOs}T1pI|Z&PyUajuG}77^KsdC@i(5GoVJ1oPqM0D>qgx z?tphSJ_BffJ0G-$#ao}Q^*UuthQ$k&eO{;Hb&d~b-z__rAR`m@N8=MPrC2i%Ioo^$ z9yy9QXj)gvM4Rv|AKHE-rhYbN(tdpr)5#?n0Y}c!U5zc0@)7Vf$vY;qw#7MPHV`30 zqp)nBgt6QcK7-1;$Ch%eMt=rneXdoUw*QGliPV-GPL$q<DUE z#yRiozAipSF}_k-reAvEVZe)eNWvlQ>G6ZU^@?*xWhMOKl=8`Rx8ST5&8mIk+}*!+ zUuef!HwOWlhH0X5fRsNJ35CK%;@CrXMU%n`X+-hUevKXocYw|$1k)lDBVp|p$ybQ9 zdW5*Z`txKZ_u%M}z3j+6XbM#d`=C!lk$#nmVMc%IqFMiUtGBU4sHGvRC9l#5T0h)* zk?U=G%6Z&bSo~_T+9daS<#N_}bnA^L{RS+-Ux7QjgzwC8M~utyxXjI3tOV8iY0L51 zFLrr4f16&hI(!?w|9$Bi_Ia`C{=Gzf_b>bP1g#g(P<$ZD6GQ3Nf(E8fn~^Zre+X`EY?t8lZcl&1bJx0k zn|*5M=s>#9D1b5+SI*uzBI4Z-n}=2jc?JdYb%@&u4FrY!-hT-So_AC87xtXBhvoxm zkE$ZDETj3WKg_6F>+ZDTk5TPG|?Hx7vU* z9@S{taKb$Ce3Dl6V%t2l#A>B$OJi+`RfAI_r#vA29j_8Gw z(^dAHL`wCPp^HS}Z&-y0lswk77c^RU-{83YeN>yd!PzsZ5`eBm)ZYneLN0q;0YP-Yu^gq=Nv9rB%r-byiYv5-l`5|n1}c@V5X2qEI6q$sV-QBll>rsay* zU-JjSMFz#gG9+UT5FTN-R63Fa!H^bSAuF5DKRjnvR8jevAo=4@2f&bjDOU|ZuCVU- zPOr%wUrI>x@pT6;Tb%5gghPtub3eT~zj>p?k(M=4*u!w3U)1{`v6NX48Fi0z;|VN3 z9I-GKo%nBTIxG!t^;N$FEc4nalZ8wfW@}hw5Y=xdIcjTL2k}Ig*NM_I`sr_pf9aOW zBygz{12!t>7gECC9x5@8TN+;iR)=%%dIe%qWxKF3bOJDe8GY+kWbIua z{V-E{EEtO}arIMH@f2iG4)k-h{&@14M18)f27;Cdj^Izl()x7)jN*q=pniGvK3A68 zf;-U_uaC$2`U>l@u;$F$Axp%jS$R1YS2rPCT4yWm#V|tz-2!eMsuGJJoMKVlYB9A> zt%=Sg!LJFm6h3oev{Q8Mn*z~HT<>qTQ!!ma9=vD#YPgA6YxdU(6k1=+6znX)GJ{XP z;Gcz{6aSo0AEZOu1x;u-w4_w8keMSZ1Da8jcZvW#K9Ev_P8$@`xS@v3XQ+B>0;RkP z2}B1+UXXlS#o=#0MuW(aXA#rohk!v%R3+v=&_;z$HiXNwvem^BF~@rzq>Ay-i4{>n zW0|WkHjZ(Qvpg>j&^n7QzIE3jqFOU`Jd*et`PmDrFwB3I@@DjA0*o-+lrsfJ zmGM0E7;v^X#ZQoU*FV=D=u+5wFtu!&7#MKzO*WWAanKD>AR)5;nZNSvC$!0lq$(_7 zBDJc=7e^?VK^8=v#fBmk%ga%=uQVUwd2hMH)`W$M9@rA*V4X-JA9gUb80Ffo+tApz7eu_~>(w51oeL5}g1va+S-hX2 zKki09HscqV!wZUL)7G|~Hd4gC)z7o6FekD!1j9Jjf2`R=^v)^0hbR_~cY8@eMG^d6 z)9YKr*vurR)B-k1Cb5DQI3dqoQhKvNdWLG;e-ts9N9`i}$uy@`e@DOs{xs#JxvoH_ zmLg33L7Z@aUX1=b&~OBL86{va+QwD+#`;vgQnFUY*5HN)c`UXEFunw%QUS%G?EEq4iE+of^i_{ldDLu0keiWlgI& z>yIc{R4g*apGYvnFxfH4bJYR4(Qx6kNo>SI-S_x@JkM7 zBLeZ!?A+Y6h&D|tv*+~GEj!B(r=Z-lzj;;SLAlgz*{bH>kK(eg#%*GgZYyG+L3#G3 zNqBS5C-^9Wtn@#}3_ZRRAsLy5clR@K_KzBLPFfW)z8(G?n<^_G9IRwEJFKMI<#WH> zQxIf5gwD!ri=0sFEyKPRlSd(r6)!cYXMT{;ubgK5D%|OP@~;wwASwnXNOQTVFL4ON z$rjY*QHIa(`wO-@pSSYJqpE613C3EEMYRTUGH=^-nXP;V8}_G$DH6l^me9hjPTP=^ zU#@BeD`RxceE!|>>ma?KnHu5k@$IIPz6-KmESly<^D8VuSNfgXS0+$6QAi%q-gLfl z3gJsCAU`Tg+|lzw@**>qoLzLh?jd*#LQ_nJ5v_cRm{q6EQ9A>1P$oX8;~z2>M{6TP z#(J;DhPH(r`S^jPwVfeCoa8wt+1H|5|1g-5@AJ+AHVqQklUkoFTnvJ0F~lu`c_Yj^ zuumkh(3Qoz7YoO3s$t?!zi`AmV0f?2cts(ywQ!(3@QsPfqpr1bb?@$=LlHu`;<>R5 z4(gcVppfFCN;Hp~d>&h*ait}R^%IgL9JHy5&S6hI!d7T4N-m0{s9GVwDZ#sC6a3PL zl@%a+ktO2;hW|I+!aAJ}9igv1hstfKT=HS2ZJGqv6GUv^S}Tw4lg2AD$R@R1{*$D8 zp-5WyQmj#6Zx0qz**-%i2%Vd;ZYt`6@D|!m1HMH{ywe)lc7v<0u}5`oW(%9>YczJc zHWVt$J0gP`NPejnoEen(3YWMmmrT>L3@n&B8h0kVBG4n`TNTZ}T?zHwOQJUhsmHIGb%HoxZo>)Y> zj7rk$meTx@D6-s7*+eULCK06iLMC@q1tBzucCib*mgK*367M5?kfEo3mu}Y z>{@KpjLg)^ZT!RugOc2sOgxh+nB_mAwKLUx=6Z!jt1JW~gr;dC`xgdF7N%}p1Wj1) z3CcFIGl-Gv^A-9Cr#a%1*ctD6sOa~lAHX{zkNpUAaf3QPSkW$0&-{2xRQDLWSu$CD z>u^FvzDMh9)S$a7Jyu~wjf;p__K>do{3ZPwzy}+LR9OV8Z15Kfxng%b_27XR%k*!? z7h{Tg3lD3l^XAx7ivk{mb6JNJn+YUh4XY6F_h~ zKwl*43)d&?8KJK_KE@(5>mM{tUfuLWGn1G{n^{Hh+wzG%Ku0roSC{Z)sWT z@`_Incxt|Q0K_%(*APGQ$1@Z@-o(P+pCKcKjhm<7>I1zh=(F}Rlz6SdB`Ya>Y<~Pf z%F9n~P=s7=m%m*>)e*w*q`A;}BiF$!;xjxb5eU2RUBOBL3B1%?1ZFrW+=|}jYN345 zQcg&)J1ALG%fbn6ZBPluHGBea@1Tkrp=$hLp3`&0Qm4IhhBE=1zbX!rI~shhcd*@& z!b9K7IUmL!`>8^xGyPy`7806&M1^7(Ebz&JO!rPx1Nzo@M*Eo1FD5mJhHf?- z%)Vx$OKs)45J=oP%_d;~3#AU8+*JMwyN1WmT8HVzVum$5U=l(^#%ORmasEgVov3aW z+|L|_PowMLZ>Fc8B1qLdD=tT&5dI`%2>Oh5rPxmFJ^TC4MT2w+yF95-;@E z(?zHvXiYIcf$F795%?>;*q>4i+Gs#~JNs6V`)v}KvW%7$ZG>GG4SMg9jJrI?^@1{l zzQ0~Ai!#RTyd_N~rmyNxPT7L7Z8z!%7_s|VyW8UnSfiR2@^to4#ss-}5Iv|hugg?DYl232O4_9AqgFG*y&Cz&yUBG{UIanAgTS@b;(jFHUY;c_1&#n$y3Cv~sR)&@|DbEo82R1n!E(!)mW)~Kr>}6;H-{Nl7lmm<+Zipy3kbL=XBZxkFwE7nSw1^w;2a)fE3g;pzuMdIhJ^-Ko%z zfe-c!Qfw!ps0lfT{RQ*VfdIwxS^FtCcPy8Hyvxw~+ux7fSMGL#PLVU7!ayvZ7R;Wpw4~V5UFTY-0lZY2P1@2djvQ?raxS0zlw)tH>{PpqQF}ypUp@y@@M|w-E^Fyz zdnlP0#N)x=3FdjAC%Kdflh1u;4?!1@3bCfo*gJ*rIw{j%KFu{5`3MYLdnmz&N*a><>em z1|_dE!$(2QFWc4k?mw2hILWwqI3 z-MO*kSYAJ8wi?I2xJg*=bU_bK;BN&E51{{<`qzBse!a3+vLb*-e{^3}GgW^+-2Bu` z4Zl4@rvXD1gu3_6nB4MqWsQQuk`EP8x5}e9h)Xb?pLlXatgAb5o$;ybe&+>cdHSdD z!!@mNaZGHRbWj!d>grI{$@#fvO{Co2xgF(lmh1v?0qsO9(T<*Gral3Rvm+-KW3+W_ z?7cT>$9c2k74UTRq(!m|pezP&16ft^PhgC4vcZq-uUq5^eHF_26EnI&!nUMn_d_tD zJ$T&znkiP#y56-XX4XTJ=uf&h{W~sEp8VeB3{Q}T(x|quGr)sa`f=_?dhJA1mjs3R zFcapmx|6th$oYJ&;{gqLWaZYOlu;X0eRYoRd*aGI1uAf8UUS`5$6w^DXr~`mH_=;_ zEbb|qu5Hp=(I}Dmxf}QHn?!?38hbm_P$6Jp-WJ6%*urkG(Ew{tl7qFipyUGm&nlhh1rX`Wi!KIp?0LVZg z4-e~}bznGU_xyF-`fju7D|?{(`A#6T+rmrFd+!yHeuTWg4Tz>T;{Z1kQxb@MTQA0y z>3{z}UK|6zn`=%owM-V%I;H=WOPC<5%zSZ+&iG{+Kg}FoG*L_^0Ul6QP1A;Q@nS;Hko&qU*xjk)z0#h z^IiKJg|U}%&$C?5OI<$rkigxwNXSJ~N4D5w^-=yu({xY!_1OEBX7_Ct0mSO8lA7G-uIq##@1-B7 zRv1_cEoBchKR98}6?v&#!0?BZLvG}Z_-_$ZyWY!jQgAZzfzz~D>%*RpIfS?)(WhZ+ zKFmf82Mnmj_dP$@E%{chKR_`WUaC1GToeW-uI4zGV<`{WvC2m3F&PFb{1U-h47o6 zH<2+U+B(qZu*+HW>HN)L`F^_VHMZ9O-Q26^CQl49M*f=59&j<_m22=a+v6M1eb?I~ z#(e|)Ci?@7Y=P|Ku7Pl~(zPofcBt;ZarZbncPoX{U$*^m@5h@5IoD8JQ+y#8eK3|& z?Rxlb9lOoY^A?b?i2y13_S!#p+GYH5MGj1NY+Svc^$&mV`B-UFeIL^ia|Abf-y{L{ zSGJ)W?KS$u*;H8Ff5j<+$ErPXtSN9L%V#i;BiF^t#EA>SIObK#CKHr0QQ?pWURs~J z%IPocEXUnay15&g@9!_Wj<)Vxr`w)3{ETuw3adVer3$I>ZwLb6x!}j@gf0%he|*ODcCUbQk-ff!fF3Y#wEt+xXWg^z577YJO|34sA_H&ujsVL`56Fq3j4Qr5Bt6Pu}~^ zSHtDNk6wy<+dcP%V(%AMkg){OZ2z5DRp9QS)+pEa#xYVm|Dy%teOQa!*XbkTyXr`O z7mzbuS}S7I^BApDgplv}pMK~tejQz7-+oLRaRTqGgCXzsxyI4eS5{ z`1SlKZUp==>%4s*4fx&+Avm?)#O4P8%n8CDOV@9K7qiZg>$#LW46(;h>rYbzTv`5) zmn#_%-Y%d&;|UmO9x+?XngfeI{mos5+&nheSAiQZmh%N4ZXr^&mv3WLgNAhr5Kv^y zVv3xnSof>bofs4Q`~KW#ui7r}ee0!kqjq1j8*6En?}w&8Ip_m-Qu6**E(8ZJ0_wlj zoC5BfGJ5XXrh6`I)&ieVtW~$3l7P2`?ar&R=*Yl5vPiKTeB&Q2&PMx#Nj?5=8SL!| z#(odXV2{Hyg6`)3vbCR(S3gJY%>~J-?Y7+e7fe!fC1D}HOcyVF`-t+v^O%;F#z*Z? z2HeDLrriQJke*(k=ba-F!e6|eu{7NK0H}}20qVAND*zeF25ki2b$=gQUk?21n3&;+ zSU)fP7`X6w5{P;Ohx_xk0v;@XoPpgg95>~o8E)Y9Rr&4mt>l&bTS$w_`!iatiqZz) z`ut)E$;muEYEb=Vo@Lb`q;*_qZPY3FK>+^fd^KKrdQCrltNfvXB^7}3a(3EN3_0?Z zu~B@0Z0z8cs|LOb_0->ed+AG2d{hOt_-eqr`{bQ<0#@~LX#f3b`#NYj(r9mx-8Avt z`umU*AZ9Qz4SOqwpZV{F+*bKU^LtV08Q~Zn+w?>_bAu%r=$<=kPf0*yHuivO1;MAf zOv^1?spgkf%l?bi(L2^Q7$+0Kne><*$ouk^)X1p@F|EIf2UzgGhl@i-pu6NMy($pp z@G1x&uBB2h#k75@gv*&hSzvQXv6mJWQDlx^Pz9z-U}SEA7yxMrJPi6c1|P9TI(Jx} zTym0^xs_B*j7H;MOUT@$I-`CQCmTXXMMf`-y> z;(%*!#JzQ-6OAKk3orlyThSE&`~~D6XNRNG`6mArxxFa;ZxMMR7DwlY@x&DDJvoYl z3NWh#GcXQj)R{oICr5Ayhjjk(yKzLl1!CHMCO`_{L+-%l!4vor6X}X+t4c_aaqC!L ziFxaXZ)KX_}1c`(|ESp9J=>oJhkDFzYCLAnG;Q5+V(Aj5qh%)#bO1%IG! zf&^p!Ut+r#8UO@xm=|&crMadLkDNKF6{@Tfi>hY{E^+MnzKN%68ELy;+g=&XQeD=mYOaqB|( zRi;B{xW)NKncw?eOtqB4FE$*~Xtjw$M>hft!nuN0cCpX9UBPp=!Kx6y&}TU)&=L3w z0*+n+TZP;i??Y!mEECth>VL4IngbcPtw07d>=XD0g8%&ysVcRTdE$F<-L^8|&zT6^ z^w!1Lp2TLF%Y?fvD^(RXsfJ<&@m);ED)EPLOAdscco~@-rn(^d$ON>_i6HK%_tFFY z4^L6+ghs$oY&ZqPk7XtU!g@q^{IvuilLq{2j>`chI)dl_@=(16px*_5H6XA*zHlu| zK|g}iek%CBm7;tV?40d%xxFQ{IW~T`eJc7d_cAl4WV-rtvrQ#pY@BKc%GnwLqd{oE zkc$xk?rD6G%{X0XilvOzUUuGTdY_p~Xuo8IosVY`ovL&@(b;VKUbdN5WtN|yer{>}M8W;5mUO9EkVjf@3a0?=t6NKq-~P%4MolXEWuP51 z-)7B;MZ^_rxz^l!PHW>{0S7}tM&~2pubLyDu2~3 zv8T(fO#X5$zJrI4&((8>izwYs`Ex~T%dFK%8`Ac~y*}^Fn{!OPa?IIqLmXsWCWyL! zH^d9XsyH;aO1|5PzuRIbL8E6oZrWxqF-;KDWmWw)t2dqG5}IT>$WN(&G89+h`1(z9 zkYk!bJLDr0l6%^#rh}7OQE#a~11ff+c+1?2(nGLYqsob1b27?o##2RHx6zIwsB|tD zw3(KN756k%$7H53oq^KS2!&L98`j$7P0vXsPF7P4mvS!^ZIIa(=CW$&M$fc?1}BuwDgcboi^5(0%;^C&STj_*HFEZ zy$VYsCrD*|GG%6x-Cds(Z&&gc!vT6lP=#wfrHOEX-@s!nRdv>qopc(dWQ#ja8g*Gg zQP@n3*F_%wm(N@hr>RqjO;!($rpza9n(<1JX$miAiF2_?fbPv6Ux{W~vas5c<*}63 zB2uo~p96m~vVyzYpSAjwyacAnel2l)j9lfz{r=(CEzM?77xHZGG~v04mEjEEHLKzG zf^7t)|H#{L6sK!~Vl0#0cM-YJDK9t@2PnrZb}YZq9oqx8nS&kSjGtwbAl3yRVkwNz z7d=@@F2I1U3GNG6+8}f`*au|iq8E8&!DF3FD03jMPR-rum^W=rJ)W?>Vkes4z3Trb zW;|uO+`whVPN^_magAC2&mTe7DX|pc{W0%L)n+_OlHmJ&D|Y4FNvBw)O;Q2!ybhYp z)CWrtR6 zD+ojCDnPqe65Aj+S#w{DWyHIiQKF;#3AK7@Wlyx>C&e;UF44)dP_iN$=oeN+lYHCC zvb>gBBa{tF#Xvc`|7kd>h<=J27gom&JgdtQiC_hRU%Y~{W#6(%d8cIytD*g$P}IK| z8yTM`W%>NHtW#au?3v1uM@erw;rqI(V+i>VIu5+x5+wUvA;xLB7O`krjTjbE5Mw`~?7oC~<>E~>R z-EehKLa(}+mEavRUgn0?rZ(L3HALU9>nrb>EZh}i@j-LS-iE+Qj@2N#IAN~Y4(uTQ zsI7;-Bf-h9Evv|6?cJG_v`XJfxW9{M5++ZV_wK@^YjxCdfa4Y{!g$HCW7^{*h40xp zrH)5+4I$q0cj3k}D_jPvJ$*$Kf)M^r^akp6{$jHBP#u(OndfdHCB09UAyzfmHtMx0 z-&U@L&+aqT8H$>WYF)kq!HBMnf zOq@oeT5$(ip7Z$)vzu_%pK88DO(ghVa!`EXhjK#=}Z*7llPzwEyi5>9-(>yYM+ z-=0G0(BfOGyT7p#q?{dRn^SF7h~q!?=%O@JN$VCguRM9i)gcue{;YaX0S-8uVjbT9 zhH))@PF51(zQ=bg)2+OsG!hnebKho-#F%H`f+0h$u_(_qP{TL@4s6H`PodA$e~95h2O^z9|SbQ9Ok&uc>15J zG@2C`9F|@Gz7kqZyo{4*Qk9W3UQdz;7lZ{D#+ALoYfs2t298N5Q2pf39*Wn1WYX(Do1tUWa+r$B@NK9OiY_ z*=tPrIXh9uc0SaLND%*J z$fT%nT=~e?=2K@2-U-{XdXiAQOpB{0p8qVxNwsqB*nok{xJe;zb#T$5! z{CORLVx^znurp&J93GXU9_>2)mewVmC#x+?y9&CT`rscguA`#F@*@@xk6kf|8_k+~hItEsE=JhO>U%K}{*|h|lCI8Gq z&$KD`r?2bw5sTk`GfT!2Ba@g0+ir%ntEOqw(c}{8zJT^FtSXl_m5%B1RPxUWYC?OZ z2aBCi%s0vS-;F$$`xU~%XhXf4y0iMtXKrh){bBt$2y4N{w40n8K6IiMTKnjh&p})9 zYen&Q;dCvBrC~5vk&d500(~o%GIkVjYy21PNh|@OnF%;(*VAi~DX;u&YG%2vZ;+0H zB*+#Oy17XYMJVjH$zM(X)qa%2gdRSV?Gq)MNv+Ll3DO~a0F-LLm)zY7l&wL@X>3s% zq@7Uu(aCw}XNmSZ%Xu2(sp0GKCcIo!NM211(Su;Fa#|hrzjoL2ieqFRJin#B>q^^J zADEudd^6tSF=0qJr7!*{7J>yk_8b#GvkRKQJG@mKz=4vgvd2!Zy6n#u*S=lE&8+_ zVq?V$h4F=WlK()sT*hWoUrVz-J@26+u0&+}Cq!AosanF~ciXAv?8RXvISOCN`Mam% zPv+mK+?i@aGx{e4Q5S2^p~aj_h2QIF0@zs4mxLlabC+H=K3d7&nqkFg@^9~X=<8nMc`~3c;|8&>9|;@qQB78d=V89 zVZBU#Li0ZTM+EAWS^^11d+|MV8MF<8NS|A`<~W@&GrzhKDX{6YS85^yQW+e`^}mY{ z*UR)j=3LSh!#O2QMUz*lq!;vHhUQu=BelFUbHMtN3x{p2O-BbW63Hs|^KckctJ=>a zUH{3hdhA~kOiH0-ZVk{%^sV1H{uat-lBXEr&sUuf zD_Ul|?8gQbI^Af=leF1R^RzQ%j_6ZizmX{{?3B#vJ=iI=JG$K)yi#r@otGMUd{d^I z3`-po*zQ~B9<~YoGvprY=SStwc(?j)_1RMF5oZV+85irbMgLuiHypBz&x z*6#C-7;Xx&0%;^o)+B8-)%b1>C1=LDw*C{(w9!IolA7su&*`*kEs=b(HEo)1+hG{Ki2rKDXY=)!-0xEj1(ZjLx(b17ul zr^>04aT{q5$S@qHAqPV{<&aes`Axk^yAo``pebXScO3<6%=z!hjY`D}LwW1ZYTx8^ zi|@mdi)u&RRU*bt_hI-g_0l`FUbBV<3q-ZaFX!*7?N++TQ+q^pTj_ePx49^1l6jN} zgrGZYRy1C;Ar1@fTiVTF#ABQY5=cl)?d)iEDW9Ca|7W`Vrk>{NjC}a1ZDnRylNC+b z9y+0Sa3!R^R%+5wRUMG22*%U8%9)LOTR2QEjHy;-vJz2eDoKt9QLp^FC&OTyk1K5* z!FflMa?m1kTKc8sJ{3K0uo?4!apOpR4OX=O}Un8ajXMTLYYeQ_UsU-E?>);|+B+*Im&|00f> z$zbwPRU-(gdr{Bd8TVQo*9YG_N4*oV%mmqld54mu{7T+@hk46 z4WHk5M+QX9zLy?smjf@|g;?8Ad<+o!`CEY`mOh7G;%;REvZfpNH_o?#dXNDmYYB1O>u>G9t02S9!YGbT{t&`|#abQIU+ literal 0 HcmV?d00001 From 3c94808166af0f30015c54f2f25c643c3a6aaa33 Mon Sep 17 00:00:00 2001 From: Kent Fredric Date: Thu, 31 May 2012 07:16:44 +1200 Subject: [PATCH 6/7] Add a has_ancestor_sha1 method on Object::Commit. This will hopefully make finding common parents of 2 given refs/tags/branches easier as well as finding if one is the parent of the other, which will be very very useful if anyone ever plans on adding a rebase function to Git::PurePerl Add tests for has_ancestor --- CHANGES | 1 + lib/Git/PurePerl/Object/Commit.pm | 50 +++++++++++++++++++ t/08_has_ancestor.t | 79 +++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 t/08_has_ancestor.t diff --git a/CHANGES b/CHANGES index 4737ee4..70e0abf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ Revision history for Perl module Git::PurePerl: + - Add has_ancestor_sha1 method to Object::Commit (Kent Fredric) - Add Git::PurePerl::Util with handy current_git_dir() util (Kent Fredric) 0.50 Sat Jan 25 14:58:16 CET 2014 diff --git a/lib/Git/PurePerl/Object/Commit.pm b/lib/Git/PurePerl/Object/Commit.pm index 071d17e..983f8f6 100644 --- a/lib/Git/PurePerl/Object/Commit.pm +++ b/lib/Git/PurePerl/Object/Commit.pm @@ -91,5 +91,55 @@ sub parents { return map { $self->git->get_object( $_ ) } @{$self->parent_sha1s}; } +=head2 has_ancestor_sha1 + +Traverses up the parentage of the object graph to find out if the given C appears as an ancestor. + + if ( $commit_object->has_ancestor_sha1( 'deadbeef' x 5 ) ) { + ... + } + +=cut + +sub has_ancestor_sha1 { + my ( $self, $sha1 ) = @_; + + # This may seem redundant, but its not entirely. + # However, its a penalty paid for the branch shortening optimization. + # + # x^, y^ , z^ , y[ y^ , y... ] , z[ z^ , z... ] + # + # Will still be faster than + # + # x^, y[ y^ , y... ] , z[ z^ , z... ] + # + # In the event y is very long. + + return 1 if $self->sha1 eq $sha1; + + # This is a slight optimization of sorts, + # as it means + # x->{ y->{ y' } , z->{ z' } } + # has a check order of: + # x^, y^ , z^ , y[ y^ , ... ], z[ z^, ... ] + # instead of + # x^, y[ y^, y... ], z[ z^, z... ] + # Which will probably make things a bit faster if y is incredibly large + # and you just want to check if a given commit x has a direct ancestor i. + + for my $parent ( @{ $self->parent_sha1s } ) { + return 1 if $parent eq $sha1; + } + + # Depth First. + # TODO perhaps make it breadth first? could be very useful on very long repos + # where the given ancestor might not be in the "first-parent" ancestry line. + # But if somebody wants this feature, they'll have to provide the benchmarks, the code, or both. + + for my $parent ( $self->parents ) { + return 1 if $parent->has_ancestor_sha1( $sha1, ); + } + return; +} __PACKAGE__->meta->make_immutable; diff --git a/t/08_has_ancestor.t b/t/08_has_ancestor.t new file mode 100644 index 0000000..5fe014b --- /dev/null +++ b/t/08_has_ancestor.t @@ -0,0 +1,79 @@ +use strict; +use warnings; + +use Test::More; + +# FILENAME: 08_has_ancestor.t +# CREATED: 31/05/12 07:48:42 by Kent Fredric (kentnl) +# ABSTRACT: Tests for has_ancestor +use strict; +use warnings; +use Test::More; +use Git::PurePerl; +use Path::Class; + +sub shatrim { + return substr( shift, 0, 8 ); +} + +sub repo_ancestor_check { + my ( $repo, $commit, @ancestors ) = @_; + my $git = Git::PurePerl->new( directory => $repo ); + my $commit_obj = $git->get_object($commit); + for my $ancestor (@ancestors) { + my ( $tcommit, $tancestor ) = map { shatrim($_) } $commit, $ancestor; + ok( + $commit_obj->has_ancestor_sha1($ancestor), + "$repo @ $tcommit has ancestor $tancestor" + ); + } +} + +sub repo_ancestor_not_check { + my ( $repo, $commit, @ancestors ) = @_; + my $git = Git::PurePerl->new( directory => $repo ); + my $commit_obj = $git->get_object($commit); + for my $ancestor (@ancestors) { + my ( $tcommit, $tancestor ) = map { shatrim($_) } $commit, $ancestor; + ok( + !$commit_obj->has_ancestor_sha1($ancestor), + "$repo @ $tcommit has no ancestor $tancestor" + ); + } +} + +repo_ancestor_check( + 'test-project' => '0c7b3d23c0f821e58cd20e60d5e63f5ed12ef391' => qw( + a47f812b901251922153bac347a348604a24e372 + d24a32a404ce934cd4f39fd632fc1d43c413f652 + ) +); + +repo_ancestor_check( + 'test-project' => 'a47f812b901251922153bac347a348604a24e372' => qw( + d24a32a404ce934cd4f39fd632fc1d43c413f652 + ) +); + +repo_ancestor_not_check( + 'test-project' => '0c7b3d23c0f821e58cd20e60d5e63f5ed12ef391' => qw( + deadbeefdeadbeefdeadbeefdeadbeefdeadbeef + ) +); + +repo_ancestor_not_check( + 'test-project' => 'a47f812b901251922153bac347a348604a24e372' => qw( + 0c7b3d23c0f821e58cd20e60d5e63f5ed12ef391 + deadbeefdeadbeefdeadbeefdeadbeefdeadbeef + ) +); +repo_ancestor_not_check( + 'test-project' => 'd24a32a404ce934cd4f39fd632fc1d43c413f652' => qw( + 0c7b3d23c0f821e58cd20e60d5e63f5ed12ef391 + deadbeefdeadbeefdeadbeefdeadbeefdeadbeef + a47f812b901251922153bac347a348604a24e372 + ) +); + +done_testing; + From 695f1ba9f3bb423fef5a6836d9e3c15c86ba57d0 Mon Sep 17 00:00:00 2001 From: Kent Fredric Date: Thu, 31 May 2012 07:27:26 +1200 Subject: [PATCH 7/7] Improve documentation on Object::Commit --- CHANGES | 1 + lib/Git/PurePerl/Object/Commit.pm | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 70e0abf..7cabf59 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ Revision history for Perl module Git::PurePerl: + - Add basic documentation for Object::Commit (Kent Fredric) - Add has_ancestor_sha1 method to Object::Commit (Kent Fredric) - Add Git::PurePerl::Util with handy current_git_dir() util (Kent Fredric) diff --git a/lib/Git/PurePerl/Object/Commit.pm b/lib/Git/PurePerl/Object/Commit.pm index 983f8f6..5ff9291 100644 --- a/lib/Git/PurePerl/Object/Commit.pm +++ b/lib/Git/PurePerl/Object/Commit.pm @@ -63,6 +63,13 @@ sub BUILD { $self->comment( decode($encoding, join "\n", @lines) ); } +=head1 METHODS + +=head2 tree + +Returns the L<< C<::Tree>|Git::PurePerl::Object::Tree >> associated with this commit. + +=cut sub tree { my $self = shift; @@ -76,15 +83,33 @@ sub _push_parent_sha1 { push(@{$self->parent_sha1s}, $sha1); } +=head2 parent_sha1 + +Returns the C for the first parent of this this commit. + +=cut + sub parent_sha1 { return shift->parent_sha1s->[0]; } - + +=head2 parent + +Returns the L<< C<::Commit>|Git::PurePerl::Object::Commit >> for this commits first parent. + +=cut + sub parent { my $self = shift; return $self->git->get_object( $self->parent_sha1 ); } +=head2 parents + +Returns L<< C<::Commit>s|Git::PurePerl::Object::Commit >> for all this commits parents. + +=cut + sub parents { my $self = shift;