OSS/000755 000766 000024 00000000000 12654350565 012006 5ustar00crisestaff000000 000000 OSS/.git/000755 000766 000024 00000000000 12654350565 012647 5ustar00crisestaff000000 000000 OSS/lib/000755 000766 000024 00000000000 12654350565 012554 5ustar00crisestaff000000 000000 OSS/Makefile.PL000644 000766 000024 00000001224 12654350565 013757 0ustar00crisestaff000000 000000 use 5.008; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'Ali::OSS', VERSION_FROM => 'lib/OSS.pm', # finds $VERSION PREREQ_PM => { 'Encode' =>0, 'utf8' =>0, 'Digest::HMAC_SHA1' => 0, 'MIME::Base64' =>0, 'LWP::UserAgent'=>0, 'POSIX' =>0, 'Carp' => 0, 'Http::Date'=>0, 'HTTP::Headers'=>0, 'XML::Simple'=>0, }, ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/OSS.pm', # retrieve abstract from module AUTHOR => 'Crisewang ') : ()), ); OSS/README.pod000644 000766 000024 00000001270 12654350565 013447 0ustar00crisestaff000000 000000 =encoding utf-8 =head1 NAME OSS - 阿里云对象存储oss管理接口 =head1 SYNOPSIS #!/usr/bin/evn perl use warnings; use strict; use OSS; my $ali_access_key_id = ''; my $ali_secret_access_key = ''; my $oss = OSS->new( { $ali_access_key_id => $ali_access_key_id, $ali_secret_access_key => $ali_secret_access_key, } ); my $buckets = $oss->buckets; my $bucket_name = 'mytest'; #创建bucket my $bucket = $oss->add_bucket({bucket =>$bucket_name}) or die $oss->err . ": " . $oss->errstr; =head1 DESCRIPTION OSS 提供操作oss存储接口 =head1 AUTHOR Crisewng OSS/t/000755 000766 000024 00000000000 12654350565 012251 5ustar00crisestaff000000 000000 OSS/t/.DS_Store000644 000766 000024 00000014004 12654350565 013733 0ustar00crisestaff000000 000000 Bud1ompile 00_compile.t~Ilocblob(  @ @ @ @ EDSDB ` @ @ @OSS/t/00_compile.t000644 000766 000024 00000000075 12654350565 014367 0ustar00crisestaff000000 000000 use strict; use Test::More tests => 1; BEGIN { use_ok 'OSS' }OSS/t/00_compile.t~000644 000766 000024 00000000103 12654350565 014555 0ustar00crisestaff000000 000000 use strict; use Test::More tests => 1; BEGIN { use_ok 'OSS::File' }OSS/lib/OSS/000755 000766 000024 00000000000 12654350565 013220 5ustar00crisestaff000000 000000 OSS/lib/OSS.pm000644 000766 000024 00000024231 12654350565 013560 0ustar00crisestaff000000 000000 package OSS; use strict; use warnings; use OSS::Bucket; use Carp; use HTTP::Date; use Digest::HMAC_SHA1; use MIME::Base64 qw(encode_base64); use base qw(Class::Accessor::Fast); use HTTP::Headers; use LWP::UserAgent::Determined; use XML::Simple; use URI::Escape qw(uri_escape_utf8); my $ALI_HEADER_PREFIX ='x-oss'; __PACKAGE__->mk_accessors( qw(ali_access_key_id ali_secret_access_key host secure timeout ua err errstr) ); our $VERSION = '0.11'; my $KEEP_ALIVE_CACHESIZE = 10; sub new { my $class = shift; my $self = $class->SUPER::new(@_); die "No ali_access_key_id" unless $self->ali_access_key_id; die "No ali_secret_access_key" unless $self->ali_secret_access_key; $self->secure(0) if not defined $self->secure; $self->timeout(30) if not defined $self->timeout; $self->host('oss-cn-hangzhou.aliyuncs.com') if not defined $self->host; my $ua; $ua = LWP::UserAgent->new( keep_alive => $KEEP_ALIVE_CACHESIZE, requests_redirectable => [qw(GET HEAD DELETE PUT)], ); $ua->timeout($self->timeout); $ua->env_proxy; $self->ua($ua); return $self; } sub buckets { my $self = shift; my $r = $self->_send_request('GET', '', {}); return undef unless $r; my $owner_id = $r->{Owner}{ID}; my $owner_displayname = $r->{Owner}{DisplayName}; my @buckets; if (ref $r->{Buckets}) { my $buckets = $r->{Buckets}{Bucket}; $buckets = [$buckets] unless ref $buckets eq 'ARRAY'; foreach my $node (@$buckets) { push @buckets, OSS::Bucket->new( { bucket => $node->{Name}, creation_date => $node->{CreationDate}, account => $self, } ); } } return { owner_id => $owner_id, owner_displayname => $owner_displayname, buckets => \@buckets, }; }; sub list_bucket { my ($self, $conf) = @_; my $bucket = delete $conf->{bucket}; croak 'must specify bucket' unless $bucket; $conf ||= {}; my $path = $bucket . "/"; if (%$conf) { $path .= "?" .join('&', map {$_ . "=" . $self->_urlencode($conf->{$_}) } keys %$conf ); } my $r = $self->_send_request('GET', $path, {}); return undef unless $r && !$self->_remember_errors($r); my $return = { bucket => $r->{Name}, prefix => $r->{Prefix}, marker => $r->{Marker}, next_marker => $r->{NextMarker}, max_keys => $r->{MaxKeys}, is_truncated => ( scalar $r->{IsTruncated} eq 'true' ? 1 : 0 ), }; my @keys; for my $node (@{$r->{Contents}}) { my $etag = $node->{ETag}; $etag =~ s{(^"|"$)}{}g if defined $etag; push @keys,{ key => $node->{Key}, last_modified => $node->{LastModified}, etag => $etag, size => $node->{Size}, storage_class => $node->{StorageClass}, owner_id => $node->{Owner}{ID}, owner_displayname => $node->{Owner}{DisplayName}, }; } $return->{keys} = \@keys; if ($conf->{delimiter}) { my @common_prefixes; my $strip_delim = qr/$conf->{delimiter}$/; foreach my $node ($r->{CommonPrefixes}) { my $prefix = $r->{Prefix}; $prefix =~ s/$strip_delim//; push @common_prefixes, $prefix; } $return->{common_prefixes} = \@common_prefixes; } return $return; } sub add_bucket { my ($self, $conf) = @_; my $bucket = $conf->{bucket}; croak 'must specify bucket' unless $bucket; #验证bucket访问权限 if ($conf->{acl_short}) { $self->_validate_acl_short($conf->{acl_short}); } my $header_ref = ($conf->{acl_short}) ? {'x-oss-acl' => $conf->{acl_short}} : {}; #指定bucket所在的数据中文 默认是oss-cn-hangzhou my $data = ''; if (defined $conf->{location_constraint}) { $data = "" . $conf->{location_constraint} . ""; } return 0 unless $self->_send_request_expect_nothing('PUT', "$bucket/", $header_ref, $data); return $self->bucket($bucket); } sub delete_bucket { my ($self, $conf) = @_; my $bucket; if (eval { $conf->isa("OSS::Bucket"); }) { $bucket = $conf->bucket; } else { $bucket = $conf->{bucket}; } croak 'must specify bucket' unless $bucket; return $self->_send_request_expect_nothing('DELETE', $bucket . "/", {}); } sub bucket { my ($self, $bucketname) = @_; return OSS::Bucket->new({bucket => $bucketname, account => $self}); } sub _send_request_expect_nothing { my $self = shift; my $request = $self->_make_request(@_); my $response = $self->_do_http($request); my $content = $response->content; return 1 if $response->code =~ /^2\d\d$/; # anything else is a failure, and we save the parsed result $self->_remember_errors($response->content); return 0; } sub _send_request { my $self = shift; my $request; $request = $self->_make_request(@_); my $response = $self->_do_http($request); my $content = $response->content; return $content unless $response->content_type eq 'application/xml'; return unless $content; return $self->_xpc_of_content($content); } # returns 1 if errors were found sub _remember_errors { my ($self, $src) = @_; unless (ref $src || $src =~ m/^[[:space:]]*err($code); $self->errstr($src); return 1; } my $r = ref $src ? $src : $self->_xpc_of_content($src); if ($r->{Error}) { $self->err($r->{Error}{Code}); $self->errstr($r->{Error}{Message}); return 1; } return 0; } sub _make_request { my ($self, $method, $path, $headers) = @_; croak 'must specify method' unless $method; croak 'must specify path' unless defined $path; $headers ||= {}; my $http_headers = $self->_merge_meta($headers); $self->_add_auth_header($http_headers, $method, $path) unless exists $headers->{Authorization}; my $protocol = $self->secure ? 'https' : 'http'; my $host = $self->host; my $url = "$protocol://$host/$path"; my $request = HTTP::Request->new($method, $url, $http_headers); return $request; } sub _xpc_of_content { return XMLin($_[1], 'SuppressEmpty' => '', 'ForceArray' => ['Contents']); } sub _add_auth_header { my ($self, $headers, $method, $path) = @_; my $ali_access_key_id = $self->ali_access_key_id; my $ali_secret_access_key = $self->ali_secret_access_key; if (not $headers->header('Date')) { $headers->header(Date => time2str(time)); } my $canonical_string = $self->_canonical_string($method, $path, $headers); my $encoded_canonical = $self->_encode($ali_secret_access_key, $canonical_string); $headers->header( Authorization => "OSS $ali_access_key_id:$encoded_canonical"); } sub _encode { my ($self, $ali_secret_access_key, $str, $urlencode) = @_; my $hmac = Digest::HMAC_SHA1->new($ali_secret_access_key); $hmac->add($str); my $b64 = encode_base64($hmac->digest); return $b64; } sub _do_http { my ($self, $request, $filename) = @_; # convenient time to reset any error conditions $self->err(undef); $self->errstr(undef); return $self->ua->request($request, $filename); } sub _canonical_string { my ($self, $method, $path, $headers) = @_; my %interesting_headers = (); while (my ($key, $value) = each %$headers) { my $lk = lc $key; if ( $lk eq 'content-md5' or $lk eq 'content-type' or $lk eq 'date') { $interesting_headers{$key} = $self->_trim($value); } } $interesting_headers{'content-type'} ||= ''; $interesting_headers{'content-md5'} ||= ''; my $buf = "$method\n"; foreach my $key (sort keys %interesting_headers) { if ($key =~/^$ALI_HEADER_PREFIX/) { my $k = lc($key); $buf .= "$key:$interesting_headers{$key}\n"; } else { $buf .="$interesting_headers{$key}\n"; } } $path =~ /^([^?]*)/; $buf .= "/$1"; return $buf; } sub _validate_acl_short { my ($self, $policy_name) = @_; if (!grep({$policy_name eq $_} qw(private public-read public-read-write ))) { croak "$policy_name is not a supported canned access policy"; } } sub _trim { my ($self, $value) = @_; $value =~ s/^\s+//; $value =~ s/\s+$//; return $value; } sub _merge_meta { my ($self, $headers) = @_; $headers ||= {}; my $http_header = HTTP::Headers->new; while ( my ($k, $v) = each %$headers ) { $http_header->header($k => $v); } return $http_header; } sub _urlencode { my ($self, $unencoded) = @_; return uri_escape_utf8($unencoded, '^A-Za-z0-9_-'); } 1; __END__ =head1 NAME OSS - 阿里云对象存储oss管理接口 =head1 SYNOPSIS #!/usr/bin/evn perl use warnings; use strict; use OSS; my $ali_access_key_id = ''; my $ali_secret_access_key = ''; my $oss = OSS->new( { $ali_access_key_id => $ali_access_key_id, $ali_secret_access_key => $ali_secret_access_key, } ); my $buckets = $oss->buckets; my $bucket_name = 'mytest'; #创建bucket my $bucket = $oss->add_bucket({bucket =>$bucket_name}) or die $oss->err . ": " . $oss->errstr; =head1 DESCRIPTION OSS 提供操作oss存储接口 =head1 AUTHOR Crisewng OSS/lib/OSS/Bucket.pm000644 000766 000024 00000000620 12654350565 014771 0ustar00crisestaff000000 000000 package OSS::Bucket; use strict; use warnings; use Carp; use File::stat; use IO::File; use base qw(Class::Accessor::Fast); __PACKAGE__->mk_accessors(qw(bucket creation_date account)); sub new { my $class = shift; my $self = $class->SUPER::new(@_); croak "no bucket" unless $self->bucket; croak "no account" unless $self->account; return $self; } 1; OSS/.git/branches/000755 000766 000024 00000000000 12654350563 014432 5ustar00crisestaff000000 000000 OSS/.git/config000644 000766 000024 00000000461 12654350565 014040 0ustar00crisestaff000000 000000 [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = https://github.com/crisewng/OSS.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master OSS/.git/description000644 000766 000024 00000000111 12654350563 015104 0ustar00crisestaff000000 000000 Unnamed repository; edit this file 'description' to name the repository. OSS/.git/HEAD000644 000766 000024 00000000027 12654350565 013272 0ustar00crisestaff000000 000000 ref: refs/heads/master OSS/.git/hooks/000755 000766 000024 00000000000 12654350563 013770 5ustar00crisestaff000000 000000 OSS/.git/index000644 000766 000024 00000001120 12654350565 013673 0ustar00crisestaff000000 000000 DIRCVuVuc}i[ >uoC8{ Makefile.PLVuVuc~V2O$ 4yaG README.podVuVuc(ǼǣjI~%ElI lib/OSS.pmVuVuc$ܬd "Ulib/OSS/Bucket.pmVuVucIzMv t/.DS_StoreVuVuc=OfI &Æzg ot/00_compile.tVuVucCۋTVu}!5@t/00_compile.t~`,4 %@OSS/.git/info/000755 000766 000024 00000000000 12654350563 013600 5ustar00crisestaff000000 000000 OSS/.git/logs/000755 000766 000024 00000000000 12654350565 013613 5ustar00crisestaff000000 000000 OSS/.git/objects/000755 000766 000024 00000000000 12654350565 014300 5ustar00crisestaff000000 000000 OSS/.git/packed-refs000644 000766 000024 00000000153 12654350565 014755 0ustar00crisestaff000000 000000 # pack-refs with: peeled fully-peeled 06f7835ea0bd73d22e6a182606454aad0f109908 refs/remotes/origin/master OSS/.git/refs/000755 000766 000024 00000000000 12654350565 013606 5ustar00crisestaff000000 000000 OSS/.git/refs/heads/000755 000766 000024 00000000000 12654350565 014672 5ustar00crisestaff000000 000000 OSS/.git/refs/remotes/000755 000766 000024 00000000000 12654350565 015264 5ustar00crisestaff000000 000000 OSS/.git/refs/tags/000755 000766 000024 00000000000 12654350563 014542 5ustar00crisestaff000000 000000 OSS/.git/refs/remotes/origin/000755 000766 000024 00000000000 12654350565 016553 5ustar00crisestaff000000 000000 OSS/.git/refs/remotes/origin/HEAD000644 000766 000024 00000000040 12654350565 017171 0ustar00crisestaff000000 000000 ref: refs/remotes/origin/master OSS/.git/refs/heads/master000644 000766 000024 00000000051 12654350565 016104 0ustar00crisestaff000000 000000 06f7835ea0bd73d22e6a182606454aad0f109908 OSS/.git/objects/02/000755 000766 000024 00000000000 12654350565 014521 5ustar00crisestaff000000 000000 OSS/.git/objects/03/000755 000766 000024 00000000000 12654350565 014522 5ustar00crisestaff000000 000000 OSS/.git/objects/06/000755 000766 000024 00000000000 12654350565 014525 5ustar00crisestaff000000 000000 OSS/.git/objects/0b/000755 000766 000024 00000000000 12654350565 014601 5ustar00crisestaff000000 000000 OSS/.git/objects/19/000755 000766 000024 00000000000 12654350565 014531 5ustar00crisestaff000000 000000 OSS/.git/objects/1a/000755 000766 000024 00000000000 12654350565 014601 5ustar00crisestaff000000 000000 OSS/.git/objects/1e/000755 000766 000024 00000000000 12654350565 014605 5ustar00crisestaff000000 000000 OSS/.git/objects/20/000755 000766 000024 00000000000 12654350565 014521 5ustar00crisestaff000000 000000 OSS/.git/objects/21/000755 000766 000024 00000000000 12654350565 014522 5ustar00crisestaff000000 000000 OSS/.git/objects/24/000755 000766 000024 00000000000 12654350565 014525 5ustar00crisestaff000000 000000 OSS/.git/objects/2b/000755 000766 000024 00000000000 12654350565 014603 5ustar00crisestaff000000 000000 OSS/.git/objects/35/000755 000766 000024 00000000000 12654350565 014527 5ustar00crisestaff000000 000000 OSS/.git/objects/40/000755 000766 000024 00000000000 12654350565 014523 5ustar00crisestaff000000 000000 OSS/.git/objects/44/000755 000766 000024 00000000000 12654350565 014527 5ustar00crisestaff000000 000000 OSS/.git/objects/49/000755 000766 000024 00000000000 12654350565 014534 5ustar00crisestaff000000 000000 OSS/.git/objects/4a/000755 000766 000024 00000000000 12654350565 014604 5ustar00crisestaff000000 000000 OSS/.git/objects/4f/000755 000766 000024 00000000000 12654350565 014611 5ustar00crisestaff000000 000000 OSS/.git/objects/66/000755 000766 000024 00000000000 12654350565 014533 5ustar00crisestaff000000 000000 OSS/.git/objects/69/000755 000766 000024 00000000000 12654350565 014536 5ustar00crisestaff000000 000000 OSS/.git/objects/6f/000755 000766 000024 00000000000 12654350565 014613 5ustar00crisestaff000000 000000 OSS/.git/objects/79/000755 000766 000024 00000000000 12654350565 014537 5ustar00crisestaff000000 000000 OSS/.git/objects/80/000755 000766 000024 00000000000 12654350565 014527 5ustar00crisestaff000000 000000 OSS/.git/objects/83/000755 000766 000024 00000000000 12654350565 014532 5ustar00crisestaff000000 000000 OSS/.git/objects/8f/000755 000766 000024 00000000000 12654350565 014615 5ustar00crisestaff000000 000000 OSS/.git/objects/92/000755 000766 000024 00000000000 12654350565 014532 5ustar00crisestaff000000 000000 OSS/.git/objects/93/000755 000766 000024 00000000000 12654350565 014533 5ustar00crisestaff000000 000000 OSS/.git/objects/94/000755 000766 000024 00000000000 12654350565 014534 5ustar00crisestaff000000 000000 OSS/.git/objects/98/000755 000766 000024 00000000000 12654350565 014540 5ustar00crisestaff000000 000000 OSS/.git/objects/9a/000755 000766 000024 00000000000 12654350565 014611 5ustar00crisestaff000000 000000 OSS/.git/objects/9b/000755 000766 000024 00000000000 12654350565 014612 5ustar00crisestaff000000 000000 OSS/.git/objects/a0/000755 000766 000024 00000000000 12654350565 014600 5ustar00crisestaff000000 000000 OSS/.git/objects/a3/000755 000766 000024 00000000000 12654350565 014603 5ustar00crisestaff000000 000000 OSS/.git/objects/ae/000755 000766 000024 00000000000 12654350565 014665 5ustar00crisestaff000000 000000 OSS/.git/objects/b9/000755 000766 000024 00000000000 12654350565 014612 5ustar00crisestaff000000 000000 OSS/.git/objects/be/000755 000766 000024 00000000000 12654350565 014666 5ustar00crisestaff000000 000000 OSS/.git/objects/bf/000755 000766 000024 00000000000 12654350565 014667 5ustar00crisestaff000000 000000 OSS/.git/objects/c1/000755 000766 000024 00000000000 12654350565 014603 5ustar00crisestaff000000 000000 OSS/.git/objects/c7/000755 000766 000024 00000000000 12654350565 014611 5ustar00crisestaff000000 000000 OSS/.git/objects/c8/000755 000766 000024 00000000000 12654350565 014612 5ustar00crisestaff000000 000000 OSS/.git/objects/d7/000755 000766 000024 00000000000 12654350565 014612 5ustar00crisestaff000000 000000 OSS/.git/objects/d8/000755 000766 000024 00000000000 12654350565 014613 5ustar00crisestaff000000 000000 OSS/.git/objects/db/000755 000766 000024 00000000000 12654350565 014665 5ustar00crisestaff000000 000000 OSS/.git/objects/ea/000755 000766 000024 00000000000 12654350565 014665 5ustar00crisestaff000000 000000 OSS/.git/objects/f9/000755 000766 000024 00000000000 12654350565 014616 5ustar00crisestaff000000 000000 OSS/.git/objects/fa/000755 000766 000024 00000000000 12654350565 014666 5ustar00crisestaff000000 000000 OSS/.git/objects/fc/000755 000766 000024 00000000000 12654350565 014670 5ustar00crisestaff000000 000000 OSS/.git/objects/fd/000755 000766 000024 00000000000 12654350565 014671 5ustar00crisestaff000000 000000 OSS/.git/objects/ff/000755 000766 000024 00000000000 12654350565 014673 5ustar00crisestaff000000 000000 OSS/.git/objects/info/000755 000766 000024 00000000000 12654350563 015231 5ustar00crisestaff000000 000000 OSS/.git/objects/pack/000755 000766 000024 00000000000 12654350563 015214 5ustar00crisestaff000000 000000 OSS/.git/objects/ff/1c5525e204717b46abcd48d086e99a3e8378ed000444 000766 000024 00000000353 12654350565 021762 0ustar00crisestaff000000 000000 xKOR025cPVz>{>[OW=YOcNfqIRirvjY-Ϧ|y/+H-QMNuI+UPSSrtf^qIbNӎOw?t]ŭ\ũ {r+TlA]rĜ[; uxqjrQj 4XBVbR$D];ζR)z L_lk..|tOSS/.git/objects/fd/70f519f55d17f776cfbeadda8602ddb80ae1ae000444 000766 000024 00000000470 12654350565 022405 0ustar00crisestaff000000 000000 xW=kAI, i,- A,L(ZhU~WyAP.64 y3wعm7̦sis|0aonMF ory9`wQ~^[x_ګ- < P*@{a`z*@v>&w~t<@ cK5 FQ R+F9%jr墾3;kPwGxh TRۘ?WEQ*bhI[{g/|f{ ccL=)򊍱^`/G0]hTq)OSS/.git/objects/fc/3a783e7783f4b1119676b4382b8b2362261923000444 000766 000024 00000000060 12654350565 021306 0ustar00crisestaff000000 000000 xKOR06cH.,Nu)NٺEz9ɉ9z&&UOSS/.git/objects/fc/49c47aca164d90cae87606b8c4cf0380ccf40d000444 000766 000024 00000000471 12654350565 022157 0ustar00crisestaff000000 000000 xW=O@ iJRGPx0 CYl9< zߝc7uvMY-/.Rd f,/ưf#eD0ܣ'ɣ0>`s9V3 Y7VT P*{`z*@}(0Ga>K5F(G戡QxɼGɚOT va ?, PN775^){t8o`oX+>Wl5rĽ? ABwOSS/.git/objects/fa/8e4ad0b5f94040e26f9661986592520d470c58000444 000766 000024 00000003655 12654350565 021471 0ustar00crisestaff000000 000000 xXmSFg~ō6C>($ 6-!!YRNwvO:[ʤ`c/4MF7oΞԥewʒ|~*JZg]Z~ua)Y|se ˆh aYz,dY^e4$PT}'(jv-3| +I&cΒe˕ΎCv'wbϹe< ﳗ~˛ d%Jw4 ӄW XJ)#%+kC,\+)d)u(RGvVbzvΓǻ~??ώd ++;#A="Cr)ӹeOޞg(tq"u !cٴ:K!bӎ]g zxtK!ǹOFZ-,D,]op`?mB{58 ceE]Zcª΢q/G!Y?@bS HY VZi?&5XC敁qdTWsܗ@ȋ?%E $q<5c+CES6(T~pxt (<|M=NʊJ\nbɕ`upfiZyYgo (!ˤ¤mӇ7~8:X#8)4\e\A|@;aOiE@+](:qhT3r }`!HlQ^ϗj-ư3;=UO3ϕ A sI\4H-#lwE:7|( ] )UgA Ħ 19(ZyU٤[7# ?3(ڊMCg=`bE;ހ Gy_O% Jex#jQɲ3m.y5|ؑHYWHMU09 yP )aQIQ1_ &ש3 q_DA>5Z\֙.aH Z#1,j4x<βƖ_(sLN2/#w">isXyj-jp1*h㵔Z Tg9cqu@fq{7iyz󅼞\%tXCTEGy:x&W:£O`mNP:L'j*tH&!Mt`j4AR^PjͬUQe [mq83ap{ . @|/j`c3s^*3BZp)JVzD+z3mM1';[Y<ٶG6`uwFv z avÈDeU,ϠlhV`{m#tS۳bO (jvL@ld};i9vF= h wH:i90_v.xC\c,\*+~xDWp$P4y´ogʀ;R`<`LV@cY $\@rJ ojB8{6TOrc&Y*%e60Tig;w f0\˪-?|R ܆i Rȥ74C8EU3.pneו4HS!\ ɰǴgm%=Fz" {kluvU*@b〉!sq}6 .RpUvzm{L>tشh=ƐB1pcXzvjG7㡵)LA;W0I7u0NL>]~?U']v>fR\Mԇ`-519mَP2ɇ#QЬzvj3@C#׾:t)f[1j1ZEp3 {O7#Jsְ-#OSS/.git/objects/f9/208b872545c39f55e03e49634ef9f33352f97f000444 000766 000024 00000000252 12654350565 021504 0ustar00crisestaff000000 000000 xM 0]iDt7&-Ԉ׷ %穂6nWW oy4c$ϘLM1٨i^e{cRZ:GG] }h8QV|/gJ> 9 {F{U6̜r9B-FiJOSS/.git/objects/ea/7a6f821bc7adebb394b92033f110c3a6d49344000444 000766 000024 00000000221 12654350565 021775 0ustar00crisestaff000000 000000 x+)JMU046e040031QMNMI aȔ~nԃK79[UwJB:047_%I-S51$+7ݎfLfrg?<89#_(ʡ,rR9SOSS/.git/objects/db/8b54fc56d3fb75df7df321d5048bba91354091000444 000766 000024 00000000116 12654350565 022020 0ustar00crisestaff000000 000000 xKOR03g(-NU(.)L.CRK|RJb[;Ck.'WwO?jlu`++̜TuZOSS/.git/objects/d8/3e4c5bdc74b280f861e5f184f3a4e270f54801000444 000766 000024 00000000227 12654350565 021666 0ustar00crisestaff000000 000000 x[ 0)/)$ԂmJx}+x,sCo"bX,2! D\;2$-7Y1J_<`m"f% hIWצom~{~tx?8LV!{]Uf[eCOSS/.git/objects/d7/42df121906ae18b695fc7f403afb0da4907ec5000444 000766 000024 00000000230 12654350565 022011 0ustar00crisestaff000000 000000 xK 0@]dҙ4 $I-SbۅpxV:`|]<  ES5)Q!Y+T<dGĜ,aqSBeX ;*ǽu%R8V/0{QvwBΰBCKOSS/.git/objects/c8/775e6f27d70b40a579f06c935aa571c103e6c7000444 000766 000024 00000000220 12654350565 021603 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:0 U}RXDž+ޚBNf=Ą˷ߗ9oKt$D.N r'K\3C7"OSS/.git/objects/c7/bc0295c7a38e6a497e25a1451908f36c85ee49000444 000766 000024 00000007360 12654350565 021631 0ustar00crisestaff000000 000000 xZmsg,FQ m؉'ۡ쬥k{kiW]vMigM~`0ih0-&6ɿs9w_MTty~/>sCw_/FVQzݘ %VQPZƚ/{:[%gj{WWV; F{Qj=욅:[Qj]EAjF0ґ~nF:lkuÁ￶zþxs}D]wh؍B3F8W;κyi5P=nQT}8kW/w88t\5 d9'Sn̆:Xayj{b5rCH`ʫՂ^0?HW:5qKW;+ot2hhWHK ]x{]tOa7:pkW@p=O(ʊjeU#W j,?Kc3@LGjFoOAzzb 9 bs4)80VIȏ*" ]NF~7 պ*IL4rE>DT\7!-z;:ZX, ^on5m!p_l* yܹ쨵ƥ@$Nh 'O ;0 Or5 a8dwM2aks&jCX7߃BFZZTϫ*O]|DFmaƝ!l8A$hwO|wC怗y:v>WD wH-dhR;4$`c"L8eX KJVzu¤^j{`XӪvJDQtmeN1g}(zmLFny_ :&x(Yȏ>ć"'7I' Jd8,)I2є"X_0:l b88۲t2{uD{㓁&"q PU#:흈6$J|s(x EͲlS<-fe |Z ? gS.g=~kLȉCH~zE<+Ѧş(*y Ɲ!tY5곱$+dTl%?FM2E}()Mw_ ͷT4*Y'>#IDՖs|Qac@= :m'"$y{G 5l^!?ǔi*: l ,p<%oTȌ~7H@).xUK\8APlg(X[Pq)PWвpr܁Д8t "*MM}1gXH$v1ݬdi&|mOq$gzo M9dй |71.-)a>C}nr1}kZ"歲t2שבzdٯ 2@$u&Ê4bЋZ93/|,twP;qbx&vζ̷3YַZT-b#Ɠa5;xLR畝#7<qv籞<":*PGC$8q4n}s">UK=?|s\xyno U#<G'C+lsVeF,4D-0DAŲcT!3Ϟ=vD ()9 <OuRs {1R,8MC[l쬙'OVXdI1-)a',Fx"?rdlgӘfD1r!sHDt n@3)YjC|]EXzCh9iw׳04 u¸ F F6&y~&(&Jr:׌LSH/71'Lx2)=Q9CLw:>,Z zޘyFYpjޚ}߁MÝ4]h/{0- HiȜB= wqsLl4!~nd֭;&34zЄٛ/M6Ft6d(paݡ3k8jG!.kU΍Unפ(tp*BpAoDX$R(m 8Ad؎mo_Xuk\C(-[,`ZPlqʾɒ{YȜ:V2)cgbt~+ʦ@k,JB K; 8f5'(l+)#_iPzW SXpڍ7] xN &%|w:חTZ jT.<ק?>>۽ӟ|/??_NSk+SQ6w=jCD鍬12F2cZ̙N@]!<|KX= CeH"pa։X.PIΜ&1rX̙f<rK|F*\'1U18q23wO?$ D-Ά,&k >ytn%AXZ_Y+iKg?ISԾyzz>B}+߮p/FoJ-JFOSS/.git/objects/c1/002465a57f5a7ff5f3d89d09e0b5366e6f26e8000444 000766 000024 00000007437 12654350565 021714 0ustar00crisestaff000000 000000 xZ{sE FQN+b'$C^Jcg-]ۋ]Jlh%3-Z0th;}<ƚ?u7; #Z F?S_jth>|׍fsQn ;ݎ!}HsC:au9v\zЩ#f+j}nz6AK0꭫#ܡ)GQ3zE{s>[u\5NA~gU;^GѓHCgJ V VW0_6EPnZ8r⸚Q{!`uҁí#2h`QژRxth[Hwz}vᡓS&p@pO(ʊj%ZU W2N?Ic@LG{kFoIA:zb 9 b=4)80VIȏ "+J0+v*5ULP 9h|ϒC [uUtFs53[P?>PwPcw iE!NɇN1."qYk8_>J_pa3bU2Q&lM|NDmHwѬZݪߍ2 ÁH-̸\\uH[6yMX8A Í#E=2|WcE sPpGTCHfq5ICY o g ֆ%WS~BZ BW KyZUZ"Y?Vu8̩1_>ыdyj ^;7YyYsh8 HE|(rpD{JJ@m$Viʮ nL4W, gm1^;b[SeH=ӸÎd H\]Uހn{K,&l8'FAnBEܣJ,SL{fT@)R{ j9DMʹW~7i;5z>/ky[S>~wwqo_~76 p WuF<;_t77?Q'͍@aߟ|m>m};Bc![l}e] 9z?_| 4z$*onoƛxv G1#, G\ޗ7x'ʵg{1Rĭ?!7ol]yc{l}"֬*^!g$D~m6GIuƺ?WXon޼ T;^bOCmʭg0`aFY[_>DRδ1;bOKl%:M EC4 R'<<;>$&i 1wA<+DȹierEuQL@GCEg R` Jk6[dN8Qb>c<0S(PұL)VNiwY2ŧTQ=_zT 7T&3A0W{B c" _xyCFa+tdȟcJ*ȕ9^ X,AiL^4mj!=S!3H "qKfi>$q ɅCLPCOD^Cbz(8yh J.Jipw "?6*7lY:Y9k,2/S&'wTlsm:)~L'9Ĵ[Ҭg."6d*~46L1w+}!H2S"G~[, )}#bYP2Lvp>6F'pV⸏I$Rn"Xe-hc}36po-USϏmTc/wW{\spD'∼J,[=wI,O֐H(I sAdMrfK\bj &ȝ܂gŲʗ x|@Hؽx`ۂGʎ%eB%Wc.=*)TPA9*9DŽ ڿgg\;Z2bfkɒ4+bRkFx"?rdl;ѰjE!Q/>ڨ1QQ;S, *tۊ8hv8*iR_{G08 wBG F F*A$nP$^UJ$t^ohN`;/vRzrևh0>DU=n c~jx\ϭq 4miA~;Zl7̩#n(4FQp,FW>VyY)ChC`qA6muԅy) /u4M(}Q ߥ uOs47EOHOSS/.git/objects/bf/b90ed0f5580cfbfcce798d2276530750044fdf000444 000766 000024 00000000221 12654350565 022103 0ustar00crisestaff000000 000000 x+)JMU046e040031QMNMI aȔ~nԃK79[UwJB:047_%I-S51$}n/y];1L,D焍mB % OxvqrhGPXC?Y*8OSS/.git/objects/be/f0dba68ceb7d91561657741df990b1862f1296000444 000766 000024 00000000116 12654350565 021677 0ustar00crisestaff000000 000000 x+)JMU03a040031Q+e8i}Yu ]%9>紾41{Uyww2[ OSS/.git/objects/b9/c5edaec4b54063c8c172e162a1682e82bf3f3e000444 000766 000024 00000000175 12654350565 022077 0ustar00crisestaff000000 000000 x+)JMU044a042=\?Vv_6 N+bݭ&lh``fb\_XetwuPEN٩`TI=a{*ߜ &>WZs!|S0=OSS/.git/objects/ae/a93e1bf058dfa1c946d35c7f1845fa7c6de8a1000444 000766 000024 00000000220 12654350565 022241 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:08d9zTr(d&1HM|-^rSxfCdKЎ|+~$UK3OSS/.git/objects/a3/8cbcd11f40161377b6a80f18ff8e699eb45b59000444 000766 000024 00000000161 12654350565 021753 0ustar00crisestaff000000 000000 x+)JMU040d040031Qs ./JehJg{!13PEz 0M=/˳Nu$w&@TuG:$8X0ia^~{;I*pOSS/.git/objects/a0/05bd24d6bb5cef5edd9a0ea638ddbf852b0170000444 000766 000024 00000000130 12654350565 022270 0ustar00crisestaff000000 000000 x+)JMU07a040031Qs ./Je[Ukjc:"\;kRfO޳7炉ϕ\4"YOSS/.git/objects/9b/5dfc2d683f5d8294ab2a28b2cb468dcc3dbd37000444 000766 000024 00000000220 12654350565 022237 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:08d9zTr(d&1(-bkܰ4/ {4/9gB6M;g;Lw{3otipgRhq0JAxZ2K>FZ׼xƔ?ֽTH'iql VCճSGyfBkk/Izh${{^ ОchGzo r T`kևOj%I֒>}4p躝DYf$'>w_ѓDb8JRYULu*cG`RŪp{gZ7WVpȅݵpgCĶ$;P>UK /ǰCD>NP1w;O {=uP@ƃƊi ZUY8ATXu /XpF)8fhPz Uׇ]W8ϝwysrfa"P}:ex< G(ڪ'me9v#l=zBĉ.YV XR`i."ȫP=z{ $ :vqb| 8:;8< !C_.1d$RBpc-C`Hjť3ڋ,8rťRPǔ bN!-\^l_!cb?Hf-&+`c;lس b:8СPnI.9>G̑ A %{0 fQA9 S wޱ#r}KULEbG5gorfXMUAk;j/P,"96v[ҩK ߤtAu~2y+c;O& Tmb̐Lf~t` 'DF8|g/O9솳xdf !s}7-הQ3A;l Ltbn݋ıv[kܧ~"EMsmQ #--A]y 6ZY.shFxJ}hKR#/B[poڹKN/,P+ۮyݩ 1/S]Cd+M`f["$Apޑ\LJN=t1p,9T57{qIh7c-z[UUȐZX=\ѩIHQtxB?a@!aI d:IH.?V͍50o`՛ &O4˧ӲEI nnY>T3-X5J &cLNW`cTf2ꭂ-k@"79H.PZ9Me'z44ܽ'Jq.HKfE`QĂkFiƩ`4y}*l qxzp/lj+@ء̒qa vd+IOSS/.git/objects/8f/bc288fb143e87cfc126495d8c92062b527f36b000444 000766 000024 00000000306 12654350565 021701 0ustar00crisestaff000000 000000 xJ1=)r"$ݝAgffY<ފu]u9=͡jgԒR'fҪքw".Kdu6-SbA=itҀչyғw"=@)67q 9x/XnWu;}׉"Q@*9} `4"svvcT[OSS/.git/objects/83/56ef3299b74f24e90b3479fbb46195a48547cd000444 000766 000024 00000000636 12654350565 021563 0ustar00crisestaff000000 000000 xuRO0ܿ #^[$H"ax𴌭"L;$pT0^HB5Ũ /l1h/{}}]Ԝ, n|a,drH uz>\O/}ۄmDy  ka>Y'8Y1$:5/_'6TlQa29AM E4D3"AF8@yZ FS"jD<+vX qe0gnbk& EZԵ}0v\c4StqWYpzC~1+9;鲭(1 @ ݸ/_HmC| |F7N$vyS*A :kZQKh)oOSS/.git/objects/80/6a130a6706e3f080688a815ef3f8cc5837481d000444 000766 000024 00000001030 12654350565 021445 0ustar00crisestaff000000 000000 xWn1n"@"E()mq "bQ+DQeWҲF( 3@< VD+YxƎ?G3uIȧA kMj'=%5i95ɿ]c! dKw-ЕBOFbdW{紾41G߮;!I 3wOSS/.git/objects/6f/184a36f3d6ac8baaada315093988f634ad920b000444 000766 000024 00000000161 12654350565 022014 0ustar00crisestaff000000 000000 x+)JMU040d040031Qs ./JehJg{!13PEz .h9BGY;#M @aѷluH>qa v|+OSS/.git/objects/6f/d11391dda2ec35961f4333996da55e8ca15fe3000444 000766 000024 00000000221 12654350565 021743 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:0 U}RXDž+ޚBNfä %^.7g-apxóC;*ɒ(W:OSS/.git/objects/69/185befc30a3e9995c1fd756fb24338067b8919000444 000766 000024 00000000664 12654350565 021564 0ustar00crisestaff000000 000000 xuR_k0k)RP!` EYӺuڗږycWVҗ w#NR`il>X:};KEi^r FtT jft rxh^?#XkK"%i :ɵa̜س{xYn [rJ8&S[E&- lE0יӁf%ȋsNW"CbI[_s>ݯ=,37LۇaKNt Z2lx8p5ͻ-Z72Gͱ$GT1ؒ.P F#poNH63P܌騰-7q保%젴d\ *%.?`֒+X]Ԇuq]TRQ('3Y:o6༫OSS/.git/objects/66/f7a460a1322e19daa0c9bc87d2db6ed15deffd000444 000766 000024 00000000221 12654350565 022306 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:0L^8/k6sfwN'6^_(d&1HM|-^rSxfCdKЎ|+~$UL7fOSS/.git/objects/4f/03b266db499f0c26c3867a9e670bb1fa6ffbc4000444 000766 000024 00000000110 12654350565 022077 0ustar00crisestaff000000 000000 xKOR03d(-NU(.)L.CRK|RJb[;Ck.'WwO?jlu`uZOSS/.git/objects/4a/df7ee32ddf6901400db177725d8bd2b1c533d3000444 000766 000024 00000000255 12654350565 022007 0ustar00crisestaff000000 000000 xͪ0F])$3iQ>4]rou8p48tS2za UN[L]%WsuYe:KE dnZOJOSS/.git/objects/49/44eefcd9145a10816ef99dd054f14d9ab98f59000444 000766 000024 00000007442 12654350565 022004 0ustar00crisestaff000000 000000 xZ{sE )JUb'$CdRYKk{;F @IJfZ+P0$v$-߅ڊWBs!mxiY{s=W mAyxџu抽䨣{z(p>o-{`zG֧ː?Vؑg%'Sq~<{hv5c-/6ݶð^j60zq;t@:o g :xEsFش]/p-GzhSYS39\COj1:65 ˪NvV,[D cnZq,I4'J-e?GEn{ wTHSCG Uڳ{|2O6,TÚ>ؘ?L {Wc /n].y:EǼ^?q1W|rU8kEXYQ@*U$RGiCc6\yOEKzsG,R g*" \BdT^u.,ݰZk~TQ4 zȇ($9D%]Wk9'̏]1^aViFB!'inoc'WN3."qIc8_Jh;guu-c]ƪa31nqIEё (h9䰻tʕKPK/³!8 R%/=']&N~2namyv|,|$F|b@2͍+b"1`Ap |hRYU- akYzHժ|IKD^- P: ^ &R#$Q;r}jeJQYyPd#C1K@Nj9Vi.'nbT4%W, CS&?FؖCYgdz[ X$QA~`"WWTӣuxd"K kN&%-SUVeYc*/ĶVjK;tZ/Z ' x7(k&PhaQBŜ$-d-_~Q=0N, ՠAX.&4/[֟_پ[D\ıuֵ7.vW>|oo;y祭V@ >xdy(O8bnB X]xWAa_ym=g5'/@w?ؼu^ 3x?ؼ[/^L1i6os헶"7?w f~G_߹[>ƿ4c%77o]ںr_5ZQRd[7.2xucpTg/g/zžw]:nU(C1}*v8H$D(`b+G&F>)& }L?I;3YxvR.|:HtĎAQOj&FY{IzcqVrMOslBBKb.0->5 I8ϋm*~"dJq#'n~k t[CCqQ>Z :;v!1 M,g1!/K@wXКL:`3fx_-о'R撖dߖAdav\'t'ױ$9${,F[H,8Ê,bC7}`L; *,UV<OA!'Ȟ?vt31?s#>naŌ]DuQh>0 7fK7A8bGH9( G@<X0 z2~1eVip& 5;iN/!P;^`ZnȜ\=c sif %C|i_gYv7QMظqnmһㄱfK-Spn-T7ڭcYUpcx[D5 I* A &pvD_paP ,cU)si xTs3gM?yn %i9LsI.bd~,LE5™կlS-҆ІLlmtMqƊStϓB1šߪ4=ᙩ3vxVcPTOSS/.git/objects/44/403755655437bf582904c70605dc4fac1a637e000444 000766 000024 00000000354 12654350565 021364 0ustar00crisestaff000000 000000 xKOR025gPVz>{>[OW=YOcNfqIRirvjY-Ϧ|y/+H-QMNuI+UPSSrtf^qIbNӎOw?t]ŭ\\ũ r+TlA]rĜ[; uxqjrQj 4XBVbR$D];R)z Lglk.. uOSS/.git/objects/40/e5fff0e6d19355886f125679d4c2f904611e78000444 000766 000024 00000000165 12654350565 021475 0ustar00crisestaff000000 000000 x+)JMU04`040031Qs ./JeyꔘS/v9p /TA|r~nAfN^ ?۞yUK+,nw ~gū,ݻ&:Lǰ3#OSS/.git/objects/35/76c1b5ba6fdadcda49d3a0c553023088f6488c000444 000766 000024 00000000066 12654350565 022016 0ustar00crisestaff000000 000000 x+)JMU06g040031Qp*MN-+eP&e=Zs.\iͅPUOSS/.git/objects/2b/1d2f64fe1b424812628ade82850d1c94781c64000444 000766 000024 00000000243 12654350565 021517 0ustar00crisestaff000000 000000 xM 0. g(7/V0j5M000<<=mjd'Nmb S5VDƤ.UK\1!a+5XuN`Wq/y>S/?9cs i1B:WwX=0@';R/ NGOSS/.git/objects/24/dcac649b90b78caa0e85fb09a091e722acd055000444 000766 000024 00000000377 12654350565 022073 0ustar00crisestaff000000 000000 xmAK0=W eCaO)kYE紾41Ӳ[wߺsLOSS/.git/objects/1a/947bf083492b84fcc89f21b46f674a1e940c9b000444 000766 000024 00000000161 12654350565 021676 0ustar00crisestaff000000 000000 x+)JMU040d040031Qs ./JehJg{!13PEz .l(ZIA<&@TuG:$8X0ia^~{;_ *OSS/.git/objects/19/562c4f0b0456ff5e34eba9c0b912db0ce22614000444 000766 000024 00000000262 12654350565 021720 0ustar00crisestaff000000 000000 xK 1D] 3o"IwG1"xzUՃG4sE`M0D"v,GZC:h,yjZtSrɤ v*v0%cwLh{o lZUZVXnRtM$Ռ1TOSS/.git/objects/0b/0a0d93c80ffff145c54c48394ff5f2f73edc46000444 000766 000024 00000000237 12654350565 022113 0ustar00crisestaff000000 000000 xA 0= elDvwS{h1RmޖentjUՒԍbB%DNeyPյYYHrRyd$G`wor_in>f?;ޖu29*ɢ dIOSS/.git/objects/0b/6e6471c13407fcbd28cdd1dc6422fae7e1d62c000444 000766 000024 00000000247 12654350565 022145 0ustar00crisestaff000000 000000 xAj0E)f0I\E/d%BHN_#ty E(5 fOsaA׾MO-]hm020ǡMmy+ox<SU JOSS/.git/objects/06/f7835ea0bd73d22e6a182606454aad0f109908000444 000766 000024 00000000242 12654350565 021505 0ustar00crisestaff000000 000000 xA 0E] %3q&ZhZo6pEzg@d[ Gc k'+>^ "Ζf"(ܙQ,).#ח|E_~t[_&骁:"GXQuyE 0rd8EOSS/.git/objects/03/81e978e4f4cc4eae8c247bbdc0ffd19d25d274000444 000766 000024 00000000220 12654350565 022163 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:0 U}RXDž+ޚBNfCkkW],id$nl ]ڑ/VyOD 8a7:OSS/.git/objects/03/8dad87e42d5c907e3f8d2bd0c9add484b0c246000444 000766 000024 00000000203 12654350565 022074 0ustar00crisestaff000000 000000 xA 0E]LLD4Y4Rσ/94ЩU6:6.Z 8&+ 1ů Muwu;]#|7 czth Dun ~"=OSS/.git/objects/02/54f67d5d1af3d334a039fb9201d8d95cfae3fb000444 000766 000024 00000000220 12654350565 022066 0ustar00crisestaff000000 000000 x+)JMU046a040031QMNMI aȔ~nԃK79[UwJB:0 U}RXDž+ޚBNfԔ͞-NWܒ%7g6D.N r'K\9C7+OSS/.git/logs/HEAD000644 000766 000024 00000000261 12654350565 014236 0ustar00crisestaff000000 000000 0000000000000000000000000000000000000000 06f7835ea0bd73d22e6a182606454aad0f109908 Crisewng 1454494069 +0800 clone: from https://github.com/crisewng/OSS.git OSS/.git/logs/refs/000755 000766 000024 00000000000 12654350565 014552 5ustar00crisestaff000000 000000 OSS/.git/logs/refs/heads/000755 000766 000024 00000000000 12654350565 015636 5ustar00crisestaff000000 000000 OSS/.git/logs/refs/remotes/000755 000766 000024 00000000000 12654350565 016230 5ustar00crisestaff000000 000000 OSS/.git/logs/refs/remotes/origin/000755 000766 000024 00000000000 12654350565 017517 5ustar00crisestaff000000 000000 OSS/.git/logs/refs/remotes/origin/HEAD000644 000766 000024 00000000261 12654350565 020142 0ustar00crisestaff000000 000000 0000000000000000000000000000000000000000 06f7835ea0bd73d22e6a182606454aad0f109908 Crisewng 1454494069 +0800 clone: from https://github.com/crisewng/OSS.git OSS/.git/logs/refs/heads/master000644 000766 000024 00000000261 12654350565 017053 0ustar00crisestaff000000 000000 0000000000000000000000000000000000000000 06f7835ea0bd73d22e6a182606454aad0f109908 Crisewng 1454494069 +0800 clone: from https://github.com/crisewng/OSS.git OSS/.git/info/exclude000644 000766 000024 00000000360 12654350563 015153 0ustar00crisestaff000000 000000 # git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ OSS/.git/hooks/applypatch-msg.sample000755 000766 000024 00000000736 12654350563 020135 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to check the commit log message taken by # applypatch from an e-mail message. # # The hook should exit with non-zero status after issuing an # appropriate message if it wants to stop the commit. The hook is # allowed to edit the commit message file. # # To enable this hook, rename this file to "applypatch-msg". . git-sh-setup commitmsg="$(git rev-parse --git-path hooks/commit-msg)" test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} : OSS/.git/hooks/commit-msg.sample000755 000766 000024 00000001600 12654350563 017247 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to check the commit log message. # Called by "git commit" with one argument, the name of the file # that has the commit message. The hook should exit with non-zero # status after issuing an appropriate message if it wants to stop the # commit. The hook is allowed to edit the commit message file. # # To enable this hook, rename this file to "commit-msg". # Uncomment the below to add a Signed-off-by line to the message. # Doing this in a hook is a bad idea in general, but the prepare-commit-msg # hook is more suited to it. # # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" # This example catches duplicate Signed-off-by lines. test "" = "$(grep '^Signed-off-by: ' "$1" | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { echo >&2 Duplicate Signed-off-by lines. exit 1 } OSS/.git/hooks/post-update.sample000755 000766 000024 00000000275 12654350563 017447 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to prepare a packed repository for use over # dumb transports. # # To enable this hook, rename this file to "post-update". exec git update-server-info OSS/.git/hooks/pre-applypatch.sample000755 000766 000024 00000000650 12654350563 020130 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to verify what is about to be committed # by applypatch from an e-mail message. # # The hook should exit with non-zero status after issuing an # appropriate message if it wants to stop the commit. # # To enable this hook, rename this file to "pre-applypatch". . git-sh-setup precommit="$(git rev-parse --git-path hooks/pre-commit)" test -x "$precommit" && exec "$precommit" ${1+"$@"} : OSS/.git/hooks/pre-commit.sample000755 000766 000024 00000003152 12654350563 017253 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to verify what is about to be committed. # Called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if # it wants to stop the commit. # # To enable this hook, rename this file to "pre-commit". if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # If you want to allow non-ASCII filenames set this variable to true. allownonascii=$(git config --bool hooks.allownonascii) # Redirect output to stderr. exec 1>&2 # Cross platform projects tend to avoid non-ASCII filenames; prevent # them from being added to the repository. We exploit the fact that the # printable range starts at the space character and ends with tilde. if [ "$allownonascii" != "true" ] && # Note that the use of brackets around a tr range is ok here, (it's # even required, for portability to Solaris 10's /usr/bin/tr), since # the square bracket bytes happen to fall in the designated range. test $(git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 then cat <<\EOF Error: Attempt to add a non-ASCII file name. This can cause problems if you want to work with people on other platforms. To be portable it is advisable to rename the file. If you know what you are doing you can disable this check using: git config hooks.allownonascii true EOF exit 1 fi # If there are whitespace errors, print the offending file names and fail. exec git diff-index --check --cached $against -- OSS/.git/hooks/pre-push.sample000755 000766 000024 00000002504 12654350563 016742 0ustar00crisestaff000000 000000 #!/bin/sh # An example hook script to verify what is about to be pushed. Called by "git # push" after it has checked the remote status, but before anything has been # pushed. If this script exits with a non-zero status nothing will be pushed. # # This hook is called with the following parameters: # # $1 -- Name of the remote to which the push is being done # $2 -- URL to which the push is being done # # If pushing without using a named remote those arguments will be equal. # # Information about the commits which are being pushed is supplied as lines to # the standard input in the form: # # # # This sample shows how to prevent push of commits where the log message starts # with "WIP" (work in progress). remote="$1" url="$2" z40=0000000000000000000000000000000000000000 while read local_ref local_sha remote_ref remote_sha do if [ "$local_sha" = $z40 ] then # Handle delete : else if [ "$remote_sha" = $z40 ] then # New branch, examine all commits range="$local_sha" else # Update to existing branch, examine new commits range="$remote_sha..$local_sha" fi # Check for WIP commit commit=`git rev-list -n 1 --grep '^WIP' "$range"` if [ -n "$commit" ] then echo >&2 "Found WIP commit in $local_ref, not pushing" exit 1 fi fi done exit 0 OSS/.git/hooks/pre-rebase.sample000755 000766 000024 00000011527 12654350563 017231 0ustar00crisestaff000000 000000 #!/bin/sh # # Copyright (c) 2006, 2008 Junio C Hamano # # The "pre-rebase" hook is run just before "git rebase" starts doing # its job, and can prevent the command from running by exiting with # non-zero status. # # The hook is called with the following parameters: # # $1 -- the upstream the series was forked from. # $2 -- the branch being rebased (or empty when rebasing the current branch). # # This sample shows how to prevent topic branches that are already # merged to 'next' branch from getting rebased, because allowing it # would result in rebasing already published history. publish=next basebranch="$1" if test "$#" = 2 then topic="refs/heads/$2" else topic=`git symbolic-ref HEAD` || exit 0 ;# we do not interrupt rebasing detached HEAD fi case "$topic" in refs/heads/??/*) ;; *) exit 0 ;# we do not interrupt others. ;; esac # Now we are dealing with a topic branch being rebased # on top of master. Is it OK to rebase it? # Does the topic really exist? git show-ref -q "$topic" || { echo >&2 "No such branch $topic" exit 1 } # Is topic fully merged to master? not_in_master=`git rev-list --pretty=oneline ^master "$topic"` if test -z "$not_in_master" then echo >&2 "$topic is fully merged to master; better remove it." exit 1 ;# we could allow it, but there is no point. fi # Is topic ever merged to next? If so you should not be rebasing it. only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` only_next_2=`git rev-list ^master ${publish} | sort` if test "$only_next_1" = "$only_next_2" then not_in_topic=`git rev-list "^$topic" master` if test -z "$not_in_topic" then echo >&2 "$topic is already up-to-date with master" exit 1 ;# we could allow it, but there is no point. else exit 0 fi else not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` /usr/bin/perl -e ' my $topic = $ARGV[0]; my $msg = "* $topic has commits already merged to public branch:\n"; my (%not_in_next) = map { /^([0-9a-f]+) /; ($1 => 1); } split(/\n/, $ARGV[1]); for my $elem (map { /^([0-9a-f]+) (.*)$/; [$1 => $2]; } split(/\n/, $ARGV[2])) { if (!exists $not_in_next{$elem->[0]}) { if ($msg) { print STDERR $msg; undef $msg; } print STDERR " $elem->[1]\n"; } } ' "$topic" "$not_in_next" "$not_in_master" exit 1 fi exit 0 ################################################################ This sample hook safeguards topic branches that have been published from being rewound. The workflow assumed here is: * Once a topic branch forks from "master", "master" is never merged into it again (either directly or indirectly). * Once a topic branch is fully cooked and merged into "master", it is deleted. If you need to build on top of it to correct earlier mistakes, a new topic branch is created by forking at the tip of the "master". This is not strictly necessary, but it makes it easier to keep your history simple. * Whenever you need to test or publish your changes to topic branches, merge them into "next" branch. The script, being an example, hardcodes the publish branch name to be "next", but it is trivial to make it configurable via $GIT_DIR/config mechanism. With this workflow, you would want to know: (1) ... if a topic branch has ever been merged to "next". Young topic branches can have stupid mistakes you would rather clean up before publishing, and things that have not been merged into other branches can be easily rebased without affecting other people. But once it is published, you would not want to rewind it. (2) ... if a topic branch has been fully merged to "master". Then you can delete it. More importantly, you should not build on top of it -- other people may already want to change things related to the topic as patches against your "master", so if you need further changes, it is better to fork the topic (perhaps with the same name) afresh from the tip of "master". Let's look at this example: o---o---o---o---o---o---o---o---o---o "next" / / / / / a---a---b A / / / / / / / / c---c---c---c B / / / / \ / / / / b---b C \ / / / / / \ / ---o---o---o---o---o---o---o---o---o---o---o "master" A, B and C are topic branches. * A has one fix since it was merged up to "next". * B has finished. It has been fully merged up to "master" and "next", and is ready to be deleted. * C has not merged to "next" at all. We would want to allow C to be rebased, refuse A, and encourage B to be deleted. To compute (1): git rev-list ^master ^topic next git rev-list ^master next if these match, topic has not merged in next at all. To compute (2): git rev-list master..topic if this is empty, it is fully merged to "master". OSS/.git/hooks/prepare-commit-msg.sample000755 000766 000024 00000002327 12654350563 020712 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to prepare the commit log message. # Called by "git commit" with the name of the file that has the # commit message, followed by the description of the commit # message's source. The hook's purpose is to edit the commit # message file. If the hook fails with a non-zero status, # the commit is aborted. # # To enable this hook, rename this file to "prepare-commit-msg". # This hook includes three examples. The first comments out the # "Conflicts:" part of a merge commit. # # The second includes the output of "git diff --name-status -r" # into the message, just before the "git status" output. It is # commented because it doesn't cope with --amend or with squashed # commits. # # The third example adds a Signed-off-by line to the message, that can # still be edited. This is rarely a good idea. case "$2,$3" in merge,) /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; # ,|template,) # /usr/bin/perl -i.bak -pe ' # print "\n" . `git diff --cached --name-status -r` # if /^#/ && $first++ == 0' "$1" ;; *) ;; esac # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" OSS/.git/hooks/update.sample000755 000766 000024 00000007033 12654350563 016463 0ustar00crisestaff000000 000000 #!/bin/sh # # An example hook script to blocks unannotated tags from entering. # Called by "git receive-pack" with arguments: refname sha1-old sha1-new # # To enable this hook, rename this file to "update". # # Config # ------ # hooks.allowunannotated # This boolean sets whether unannotated tags will be allowed into the # repository. By default they won't be. # hooks.allowdeletetag # This boolean sets whether deleting tags will be allowed in the # repository. By default they won't be. # hooks.allowmodifytag # This boolean sets whether a tag may be modified after creation. By default # it won't be. # hooks.allowdeletebranch # This boolean sets whether deleting branches will be allowed in the # repository. By default they won't be. # hooks.denycreatebranch # This boolean sets whether remotely creating branches will be denied # in the repository. By default this is allowed. # # --- Command line refname="$1" oldrev="$2" newrev="$3" # --- Safety check if [ -z "$GIT_DIR" ]; then echo "Don't run this script from the command line." >&2 echo " (if you want, you could supply GIT_DIR then run" >&2 echo " $0 )" >&2 exit 1 fi if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then echo "usage: $0 " >&2 exit 1 fi # --- Config allowunannotated=$(git config --bool hooks.allowunannotated) allowdeletebranch=$(git config --bool hooks.allowdeletebranch) denycreatebranch=$(git config --bool hooks.denycreatebranch) allowdeletetag=$(git config --bool hooks.allowdeletetag) allowmodifytag=$(git config --bool hooks.allowmodifytag) # check for no description projectdesc=$(sed -e '1q' "$GIT_DIR/description") case "$projectdesc" in "Unnamed repository"* | "") echo "*** Project description file hasn't been set" >&2 exit 1 ;; esac # --- Check types # if $newrev is 0000...0000, it's a commit to delete a ref. zero="0000000000000000000000000000000000000000" if [ "$newrev" = "$zero" ]; then newrev_type=delete else newrev_type=$(git cat-file -t $newrev) fi case "$refname","$newrev_type" in refs/tags/*,commit) # un-annotated tag short_refname=${refname##refs/tags/} if [ "$allowunannotated" != "true" ]; then echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 exit 1 fi ;; refs/tags/*,delete) # delete tag if [ "$allowdeletetag" != "true" ]; then echo "*** Deleting a tag is not allowed in this repository" >&2 exit 1 fi ;; refs/tags/*,tag) # annotated tag if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 then echo "*** Tag '$refname' already exists." >&2 echo "*** Modifying a tag is not allowed in this repository." >&2 exit 1 fi ;; refs/heads/*,commit) # branch if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then echo "*** Creating a branch is not allowed in this repository" >&2 exit 1 fi ;; refs/heads/*,delete) # delete branch if [ "$allowdeletebranch" != "true" ]; then echo "*** Deleting a branch is not allowed in this repository" >&2 exit 1 fi ;; refs/remotes/*,commit) # tracking branch ;; refs/remotes/*,delete) # delete tracking branch if [ "$allowdeletebranch" != "true" ]; then echo "*** Deleting a tracking branch is not allowed in this repository" >&2 exit 1 fi ;; *) # Anything else (is there anything else?) echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 exit 1 ;; esac # --- Finished exit 0