2010-02-05 9 views
8

¿Cómo puedo obtener una lista de las ramas que son descendientes de primer nivel del HEAD actual?Mostrar todas las ramas de descendientes de primer nivel usando Git

puedo obtener una lista de todo el árbol con:

git log --graph --abbrev-commit --pretty=decorate --branches 

que da

* 2eff4a7... (refs/heads/issue-8351) Added a factory factory factory. 
* 2e387aa... Refactored all of the factory factories. 
| * b3fad52... (refs/heads/issue-8354) Moved the baz out of the constructor. 
|/ 
| * f4cf3fe... (refs/heads/experimental) quuz looking good 
| * 1d276b9... Risky fix to replace the quux with the quuz. 
| * d6b0222... (refs/heads/issue-7559) Fixed the quux in the foo. 
|/ 
| * 3f4cfff... (refs/heads/dev) wip 
|/ 
* 76f493f... (refs/heads/master) SVN 30192 

pero me gustaría que acaba de obtener una lista simple de los hijos del primer nivel de la rama actual, como en este ejemplo para master:

dev 
issue-7559 
issue-8354 
issue-8351 

y si yo estaba en la rama issue-7559 Solo vería:

experimental 

¿Qué debo hacer al respecto?

+0

¿A qué se refieren exactamente por descendientes de primer nivel? ¿Qué rama y criterio darían la lista de 4 ramas que das? –

+0

Disculpe, ese ejemplo fue para 'maestro'. Estoy buscando obtener una lista de sucursales que no tienen otro encabezado entre ellas y el padre. – mskfisher

+0

Suena un poco complicado. Podría intentar usar bucles '' git-for-each' anidados para probar si la base de fusión para cualquier otra rama y la rama que se está probando es distinta de la rama actual. Sin embargo, parece bastante arbitrario querer. ¿Hay un problema mayor que estás tratando de resolver? –

Respuesta

3

Puede hacerlo de la siguiente manera.

En primer lugar el preámbulo de costumbre:

#! /usr/bin/perl 

use warnings; 
use strict; 

Uso git for-each-ref para recoger el SHA-1 y el nombre de cada ref:

sub refs { 
    open my $fh, "-|", "git", "for-each-ref", 
          "--format=%(objectname)\t%(refname:short)" 
    or die "$0: failed to run git for-each-ref"; 

    my %ref2sha; 
    while (<$fh>) { 
    chomp; 
    my($sha,$ref) = split /\t/; 
    $ref2sha{$ref} = $sha; 
    } 

    \%ref2sha; 
} 

Si una confirmación es un hijo de HEAD, el conjunto de confirmaciones accesible desde HEAD excluyendo todo lo accesible desde la confirmación en cuestión es el conjunto vacío. Podemos verificar esta relación con git rev-list.

sub is_child { 
    my($ref) = @_; 

    # git rev-list ^dev master 
    my $refs = `git rev-list ^$ref HEAD -- 2>&1`; 
    die "$0: git rev-list-failed.\n$refs" if $?; 

    $refs !~ /\S/; 
} 

Para cada referencia que es un descendiente de HEAD pero no equivalente a HEAD, se analiza la trayectoria de HEAD a que la referencia usando git log. Si la ruta contiene la punta de otra rama, la referencia no puede ser un hijo de primer nivel.

Todos los sobrevivientes de este guantelete son niños de primer nivel.

chomp(my $head = `git rev-parse HEAD 2>&1`); 
die "$0: git rev-parse failed.\n$head" if $?; 

my $ref2sha = refs; 
my %headsha = reverse %$ref2sha; 

REF: 
foreach my $ref (keys %$ref2sha) { 
    my $refsha = $ref2sha->{$ref}; 

    next if $refsha eq $head || !is_child $ref; 

    my @log = `git log --pretty=format:%H ..$ref 2>&1`; 
    die "$0: git log failed.\[email protected]" if $?; 
    for (@log) { 
    chomp; 
    next if $_ eq $refsha; 
    next REF if exists $headsha{$_}; 
    } 

    print $ref, "\n"; 
} 
+0

Tenía la esperanza de evitar escribir código para lograr esto, y me has ayudado a lograr eso. :) – mskfisher

+0

@mskfisher Me alegra que sea beneficioso. ¡Disfrutar! –

Cuestiones relacionadas