2010-02-05 2 views
8

현재 HEAD의 첫 번째 레벨 자손 인 브랜치 목록을 얻으려면 어떻게해야합니까?Git을 사용하여 모든 1 레벨 자손 브랜치를 표시

* 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 

을 제공하지만 난 단지의 첫 번째 수준의 아이들의 일반 목록을 좀하고 싶습니다

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

:

내가 가지고있는 전체 트리의 목록을 얻을 수 있습니다 master이 예와 같이 현재 지점 :

dev 
issue-7559 
issue-8354 
issue-8351 

나는 지점에 있었다면만 볼 수 있습니다 :

experimental 

어떻게하면됩니까?

+0

1 등급 자손이란 정확히 무엇을 의미합니까? 어떤 지점과 기준으로 네 지점의 목록을 줄까요? –

+0

죄송합니다. 그 예는'master'입니다. 그 (것)들과 부모 사이 다른 머리가없는 분지의 명부를 얻기 위하여 나는보고있다. – mskfisher

+0

조금 까다롭게 들립니다. 중첩 된'git-for-each' 루프를 사용하여 다른 브랜치와 테스트중인 브랜치에 대한 병합베이스가 현재 브랜치 이외의 다른 것인지 여부를 테스트 할 수 있습니다. 그래도 원하는 것은 상당히 임의적 인 것 같습니다. 당신이 해결하려고하는 더 큰 문제가 있습니까? –

답변

3

다음과 같이 할 수 있습니다.

먼저 일반적인 프리앰블 :

#! /usr/bin/perl 

use warnings; 
use strict; 

사용 git for-each-ref 각 심판의 SHA-1와 이름을 수집합니다 :

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; 
} 

HEAD의 자식 커밋 경우, 커밋의 집합을 HEAD에서 도달 할 수있는 것은 해당 커밋에서 도달 할 수있는 모든 것을 제외하고 빈 집합입니다. 이 관계를 git rev-list으로 확인할 수 있습니다. HEAD하지만 동일하지 HEAD의 자손 각 타이밍에서

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/; 
} 

, 우리 git log를 사용하는 기준에 HEAD의 경로를 조사한다. 경로에 다른 분기의 끝이 포함되어 있으면 ref는 첫 번째 수준의 자식이 될 수 없습니다.

이 결투의 모든 생존자는 1 급 어린이입니다.

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

나는이 일을 성취하기 위해 코드를 쓰지 않기를 바랬는데 그 일을 도와 주었다. :) – mskfisher

+0

@mskfisher 나는 그것이 기쁘다. 즐겨! –

관련 문제