App-KGB
view release on metacpan or search on metacpan
lib/App/KGB/Client/Git.pm view on Meta::CPAN
$updated_heads{$branch} = 1;
if ( $old =~ /^0+$/ ) {
push @new_branches, $branch;
$new_branches{$branch} = 1;
}
else {
push @updated, "$new", "^$old";
push @old_revs, $old;
push @updated_branches, $branch;
$branch_updates{$branch} = [ $old => $new ];
}
}
my @existing_branches;
my @old_branches;
my @lines
= $self->_git->command( 'branch', '-v', '--no-abbrev' );
for my $l (@lines) {
$l =~ s/^[ *]+//;
my ( $ref, $sha, $ignore ) = split( ' ', $l );
$branch_head{$ref} = $sha;
$branch_tips{$sha}{$ref} = 1;
$ref_branch{$sha} //= $ref;
push @existing_branches, $ref unless $new_branches{$ref};
push @old_branches, $ref
unless $new_branches{$ref}
or $branch_updates{$ref};
}
warn "existing branches: @existing_branches" if 0;
warn "old branches: @old_branches" if 0;
my @commits;
my %reported;
if (@updated) {
push @params, map( "^$_", @old_branches );
warn "# git rev-list @params @updated" if 0;
my @lines = $self->_git->command( 'rev-list', @params, @updated);
do { warn $_ for @lines } if 0;
if ( $self->squash_threshold
and scalar(@lines) > $self->squash_threshold )
{
for my $branch (@updated_branches) {
my ($old,$new) = @{ $branch_updates{$branch} };
my $stat = $self->_git->command( 'diff', '--shortstat',
"$old..$new" );
my @commit_lines
= $self->_git->command( 'rev-list', '--topo-order', $new,
"^$old" );
push @commits,
$self->format_message(
$self->squash_msg_template,
branch => $branch,
commit_id => substr( $new, 0, 7 ),
author_login => $ENV{USER},
author_name => $self->_get_full_user_name,
log => sprintf(
'%d commits pushed, %s',
scalar(@commit_lines), $self->format_git_stat($stat),
),
);
warn "# $commits[-1]" if 0;
$branch_has_commits{$branch} = 1;
}
}
else {
my @refs;
for (@lines) {
my ( $ref, @parents ) = split(/\s+/);
push @refs, $ref;
if ( @parents and not $ref_branch{ $parents[0] } ) {
$ref_branch{ $parents[0] } = $ref_branch{$ref}
or confess
"Ref $ref with parent $parents[0] is of unknown branch";
warn
"# $parents[0] determined to be on branch $ref_branch{$ref}"
if 0;
}
}
warn "# revisions to describe: " . join( ' ', @refs ) if 0;
for my $ref (@refs) {
if ( $reported{$ref} ) {
warn "$ref already reported" if 0;
next;
}
my $cmt = App::KGB::Commit->new( $self->_describe_ref($ref) );
warn "# putting $ref on $ref_branch{$ref}" if 0;
$cmt->branch( $ref_branch{$ref} );
unshift @commits, $cmt;
$reported{$ref} = 1;
$branch_has_commits{ $ref_branch{$ref} } = 1;
}
}
# see if some updated branch was without any reported commits
# if this case put a fast-forward notification
if ( $self->enable_branch_ff_notification ) {
for ( @updated_branches ) {
next if $branch_has_commits{$_};
push @commits,
App::KGB::Commit->new(
{ branch => $_,
id => substr( $branch_updates{$_}[1], 0, 7 ),
author => $ENV{USER},
author_name => $self->_get_full_user_name,
log => 'fast forward',
}
);
}
}
}
# walk the branch until it is exhausted or a revision with multiple
# children (branch point) is reached
lib/App/KGB/Client/Git.pm view on Meta::CPAN
next;
}
my $pipe = $self->_git->command_output_pipe( 'rev-list',
'--children', $rev );
my $in = <$pipe>;
$self->_git->command_close_pipe($pipe);
my @children;
if ($in) {
chomp($in);
warn "# Children of $rev: @children" if 0;
@children = split(/\s+/, $in);
shift @children;
}
# a branch point is:
# * a commit with more than one child
# * a tip of another branch
if (@children > 1
or ( exists $branch_tips{$rev}
and not exists $branch_tips{$rev}{$b} )
)
{
unshift @br_commits,
App::KGB::Commit->new(
{ log => "Branch '$b' created",
id => substr( $rev, 0, 7 ),
branch => $b,
}
);
$branch_point = $rev;
warn "$b branched at $rev" if 0;
last;
}
if ($parent) {
$ref_branch{$parent} //= $ref_branch{$rev};
$ref_parent{$rev} = $parent;
}
my $cmt = App::KGB::Commit->new( $self->_describe_ref($rev) );
warn "# putting $rev on $ref_branch{$rev}" if 0;
$cmt->branch( $ref_branch{$rev} );
unshift @br_commits, $cmt;
$reported{$rev} = 1;
}
if ( not $branch_point and $last_rev and $ref_parent{$last_rev} )
{
$branch_point = $ref_parent{$last_rev};
warn "$b branched at $branch_point" if 0 and $branch_point;
}
if ( $self->squash_threshold
and scalar(@br_commits) > $self->squash_threshold )
{
my $log = sprintf( 'New branch with %d commits pushed',
scalar(@br_commits) );
if ($branch_point) {
$log .= ', '
. $self->format_git_stat(
$self->_git->command(
'diff', '--shortstat', "$branch_point..$b"
)
);
$log .= " since ";
$log .= "$ref_branch{$branch_point}/"
if $ref_branch{$branch_point};
$log .= substr( $branch_point, 0, 7 );
}
push @commits,
$self->format_message(
$self->squash_msg_template,
branch => $b,
author_login => $ENV{USER},
author_name => $self->_get_full_user_name,
log => $log,
commit_id => substr( $branch_head{$b}, 0, 7 ),
);
}
else {
push @commits, @br_commits;
push @commits,
App::KGB::Commit->new(
{ id => substr( $branch_head{$b}, 0, 7 ),
log => "branch created",
branch => $b,
changes => [],
}
) unless @br_commits;
}
}
}
warn '# ' . scalar(@commits) . ' commits queued' if 0;
push @{ $self->_commits }, @commits;
}
sub _process_changeset_simple {
my ( $self, $old_rev, $new_rev, $refname ) = @_;
$_ = $self->_git->command_oneline( 'rev-parse', $_ )
for ( $old_rev, $new_rev );
# see what kind of commit is this
my $ref_update_type;
if ( $old_rev =~ /^0+$/ ) {
# 0000000 -> 1234567
$ref_update_type = 'create';
}
elsif ( $new_rev =~ /^0+$/ ) {
# 7654321 -> 0000000
$ref_update_type = 'delete';
}
else {
# 2345678 -> 3456789
$ref_update_type = 'update';
( run in 2.127 seconds using v1.01-cache-2.11-cpan-5a3173703d6 )