2010-02-05 37 views
8

Làm cách nào để có danh sách các nhánh là con cháu cấp một của HEAD hiện tại?Hiển thị tất cả các nhánh hậu duệ cấp 1 sử dụng Git

tôi có thể có được một danh sách toàn bộ cây với:

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

mang đến cho

* 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 

nhưng tôi muốn chỉ nhận được một danh sách đơn giản của những đứa trẻ đầu tiên cấp của nhánh hiện tại, như ví dụ này cho master:

dev 
issue-7559 
issue-8354 
issue-8351 

và nếu tôi ở chi nhánh issue-7559 Tôi chỉ thấy:

experimental 

Làm cách nào để tôi thực hiện việc này?

+0

Chính xác bạn có ý nghĩa gì với con cháu cấp một? Chi nhánh và tiêu chí nào sẽ đưa ra danh sách 4 chi nhánh mà bạn cung cấp? –

+0

Xin lỗi, ví dụ đó là dành cho "master". Tôi đang tìm kiếm danh sách các chi nhánh không có đầu khác giữa họ và cha mẹ. – mskfisher

+0

Nghe có vẻ hơi phức tạp. Bạn có thể thử sử dụng các vòng lặp 'git-for-each' lồng nhau để kiểm tra xem cơ sở hợp nhất cho bất kỳ nhánh nào khác và nhánh đang được thử nghiệm là bất kỳ thứ gì khác với nhánh hiện tại. Nghe có vẻ khá là tùy ý khi muốn. Có vấn đề lớn hơn mà bạn đang cố giải quyết không? –

Trả lời

3

Bạn có thể thực hiện như sau.

Đầu tiên là lời mở đầu thông thường:

#! /usr/bin/perl 

use warnings; 
use strict; 

Sử dụng git for-each-ref để thu thập các SHA-1 và đặt tên cho mỗi 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; 
} 

Nếu một cam kết là một đứa trẻ của HEAD, tập các cam kết có thể truy cập từ HEAD trừ mọi thứ có thể truy cập từ cam kết được đề cập là bộ trống. Chúng tôi có thể kiểm tra mối quan hệ này với 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/; 
} 

Đối với mỗi ref đó là một hậu duệ của HEAD nhưng nó không tương đương với HEAD, chúng tôi kiểm tra đường đi từ HEAD để tham khảo rằng việc sử dụng git log. Nếu đường dẫn chứa đầu của nhánh khác, ref không thể là con đầu tiên.

Tất cả những người sống sót của găng tay này là trẻ em cấp một.

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

Tôi đã hy vọng để tránh viết mã để thực hiện điều này, và bạn đã giúp tôi thực hiện điều đó. :) – mskfisher

+0

@mskfisher Tôi rất vui vì nó có lợi. Thưởng thức! –

Các vấn đề liên quan