显示所有Git的一级子分支。

8

我该如何获取当前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

如果我在分支issue-7559上,我只能看到:

experimental

我该如何处理这个问题呢?

你所说的“一级后代”具体是什么意思?哪个分支和标准会给出你提供的4个分支列表? - CB Bailey
抱歉,那个示例是针对“主分支”的。 我想获取一个列表,其中列出了没有其他头部位于它们和父级之间的分支。 - mskfisher
听起来有点棘手。你可以尝试使用嵌套的git-for-each循环来测试任何其他分支和正在测试的分支的合并基是否与当前分支不同。虽然这听起来相当随意,但你是不是想解决一个更大的问题呢? - CB Bailey
是的,这是任意的 - 我正在探索按层次组织分支的可能性。我还想用只有分支末端的简化拓扑视图来展示图形,但我找不到一个好的方法让 git log 压缩提交。 - mskfisher
1
@mskfisher:针对上个问题,请尝试使用“--simplify-by-decoration”。 - Jakub Narębski
1个回答

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检查这种关系。
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的引用,我们使用git log检查从HEAD到该引用的路径。如果该路径包含另一个分支的末尾,则该引用不能是一级子级。

所有通过此筛选的引用都是一级子级。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接