git statusgit loggit diffgit show-refgit name-revgit ls-remote$ cd ~/git/My-Project $ git tag v0.6 v0.6.1 v0.6.2 v0.6.3 v0.6.4 v0.6.5
my $git = Git::Repository->new(
work_tree => "$ENV{HOME}/git/My-Project",
);
my @tags = $git->run( "tag" );
# ("v0.6", "v0.6.1", "v0.6.2", "v0.6.3",
# "v0.6.4", "v0.6.5")
$ cd ~/git/My-Project $ git log --oneline -n3 b23123a Release v0.6.12 6762cba do not try to fetch items that don't exist d045083 errors from the server must extend ServerError
my $git = Git::Repository->new(
work_tree => "$ENV{HOME}/git/My-Project",
);
my %commits = map { split /\s+/, $_, 2 }
$git->run( log => '--oneline-', '-n3' );
# (
# b23123a => "Release v0.6.12",
# 6762cba => "do not try to fetch items ...",
# d045083 => "errors from the server ...",
# )
my $git = Git::Repository->new( work_tree => '.' );
my @tags = $git->run( 'tag' );
# Make sure each v-tag is in the update.xml file
for my $tag ( grep { /^v/ } @tags ) {
# Get the information from git
$git->run( checkout => $tag );
my @log = $git->run( log => '-n1' );
my $info = parse_git_log( @log );
# ... build and add to update.xml
}
# Restore ourselves to master
$git->run( checkout => 'master' );
commit 88ecb78596865b6c1303816dc9051e8c62463993 Author: Doug BellDate: Tue Sep 18 22:28:51 2012 -0500 Release v0.6.5 Changes: * Add: Schema changes to support new item and anim development * Add: Loading images. Scenes can specify an image to show while they are being loaded. A default image can be set in the World dialog. * Fix: Some of the loading problems in the client are fixed
sub parse_git_log {
my @lines = @_;
my $info = { }; my $in_msg = 0;
for my $line ( @lines ) {
# First empty line starts the commit message
if ( $line =~ /^\s*$/ ) {
$in_msg = 1;
}
elsif ( $in_msg ) {
$info->{description} .= $line . "\n";
}
# Extract the date
elsif ( $line =~ /^Date:\s+(.+)\s*$/ ) {
my $parser = DateTime::Format::Strptime->new(
pattern => '%a %b %d %T %Y %z',
);
my $dt = $parser->parse_datetime( $1 );
$info->{date} = $dt->strftime('%F');
}
}
return $info;
}
git submodule add <repo>$ mkdir release && cd release $ git init Initialized empty Git repository in /Users/doug/release/.git/ $ git submodule add ~/storyteller Cloning into 'storyteller' done. $ git submodule add ~/swfconduit Cloning into 'swfconduit' done. $ ls storyteller swfconduit
git submodule lists the submodules and their commitgit ls-remote lists all the branches for a remote$ git submodule 4abfbe96d4e7ba5821eb1adb99bb5856c3e0422e storyteller (v0.6.13) ef95f4294f4dc7554be523bd6cbd573c8c0ae594 swfconduit (v1.0.0)
sub git_submodule {
my ( $git ) = @_;
my %submodules;
for $line ( $git->run( 'submodule' ) ) {
# <status><SHA1 hash> <submodule> (ref name)
$line =~ m{^.(\S+)\s(\S+)};
$submodules{ $2 } = $1;
}
return %submodules;
}
$ cd storyteller $ git ls-remote origin b72ea4150cf59957dd9d2a847c3cb7b695b68e7b HEAD 4abfbe96d4e7ba5821eb1adb99bb5856c3e0422e refs/heads/master f9d19573a65a1eb8c4caa6d6aaab00cafc7ce047 refs/heads/prop_iso_view 4abfbe96d4e7ba5821eb1adb99bb5856c3e0422e refs/remotes/origin/HEAD 4abfbe96d4e7ba5821eb1adb99bb5856c3e0422e refs/remotes/origin/master a91fd98facea44769481f0256057dd47a2e2f934 refs/stash efeade8251c5f46b58196624d21b110ac6dc9db0 refs/tags/v0.5.0 b72ea4150cf59957dd9d2a847c3cb7b695b68e7b refs/tags/v0.6 08060acac4dc32b2577be0523b527187681aa851 refs/tags/v0.6.1
sub git_ls_remote {
my ( $git ) = @_;
my %refs;
my @lines = $git->run( 'ls-remote', 'origin' );
for my $line ( @lines ) {
# <SHA1 hash> <symbolic ref>
my ( $ref_id, $ref_name ) = split $line;
$refs{ $ref_name } = $ref_id;
}
return %refs;
}
use feature qw( say );
my $git = Git::Repository->new( work_tree => '.' );
my %submod_refs = git_submodule( $git );
for my $submod ( keys %submod_refs ) {
my $subgit = Git::Repository->new(
work_tree => $submod,
);
my %remote = git_ls_remote( $subgit );
if ( $submod_refs{ $submod }
ne $remote{'refs/heads/master'} )
{
say "$submod out of date";
}
}
$ cd storyteller $ git checkout refs/remote/origin/master Note: checking out 'refs/remote/origin/master'. # ... some noise about 'detached HEAD' HEAD is now at 4abfbe9... Release v0.6.13 $ cd .. $ git commit storyteller -m'updated storyteller' [master 8bae1c3] update storyteller 1 file changed, 1 insertion(+)
my $git = Git::Repository->new( work_tree => '.' );
my %submod_refs = git_submodule( $git );
for my $submod ( keys %submod_refs ) {
my $subgit = Git::Repository->new(
work_tree => $submod,
);
$subgit->run(
checkout => 'refs/remotes/origin/master',
);
}
$git->run( 'commit' => '-m' => 'Update submodules' );
$git->run( 'push', 'origin', 'master' );
my $release_version = 'v1.00';
my $git = Git::Repository->new( work_tree => '.' );
my %submod_refs = git_submodule( $git );
for my $submod ( keys %submod_refs ) {
my $subgit = Git::Repository->new(
work_tree => $submod,
);
my %remote = git_ls_remote( $subgit );
if ( $submod_refs{ $submod }
ne $remote{'refs/heads/master'} )
{
$subgit->run(
checkout => 'refs/remotes/origin/master',
);
}
$subgit->run( tag => $release_version );
$subgit->run( push => '--tags', 'origin' );
}
$git->run(
'commit' => '-m' => "Release $release_version"
);
$git->run( 'push' => 'origin', 'master' );
# Create release branch
$git->run( 'branch' => $release_version );
$git->run(
'push' => 'origin',
"$release_version:$release_version"
);
Slides are licensed under a CC-BY-SA 3.0 license.
Code is licensed under the Artistic License or GNU GPL v1.0 or later (the same terms as Perl itself).