如何获得当前HEAD的第一级后代的分支列表?
我可以得到整个树的列表:
git log --graph --abbrev-commit --pretty=decorate --branches
这使
* 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
但是我想获得当前分支的第一级子级的简单列表,就像master的这个例子一样:
dev issue-7559 issue-8354 issue-8351
如果我在分支机构问题-7559,我只会看到:
experimental
我怎么能这样做?
解决方法
你可以这样做.
首先是通常的序言:
#! /usr/bin/perl use warnings; use strict;
使用git for-each-ref
收集每个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
检查这种关系.
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/; }
对于作为HEAD后代但不等同于HEAD的每个ref,我们使用git log
检查从HEAD到该引用的路径.如果路径包含另一个分支的尖端,则ref不能是第一级子节点.
这个手套的所有幸存者都是一级儿童.
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.\n@log" if $?; for (@log) { chomp; next if $_ eq $refsha; next REF if exists $headsha{$_}; } print $ref,"\n"; }