获取最终分支列表(这是最终提示)

时间:2013-02-02 15:16:27

标签: git tree branch hierarchy git-branch

如何获得仅作为最终分支(不是任何其他提交的父级)的分支列表 - 换句话说,分支是提交树的提示(最终节点)。 我期待git branch命令中的--final或--tips这样的选项,但只有--merged, - no-merged和--contains选项。

5 个答案:

答案 0 :(得分:3)

如果你得到所有引用的列表,你可以列出所有不是另一个引用的父类的引用:

refs=`git show-ref -s`
git log --oneline --decorate $refs --not `echo "$refs" | sed 's/$/^/'`

这可以过滤掉所有父提交。

答案 1 :(得分:3)

git show -s --oneline --decorate $(
        git show-branch --independent -a
)

git show -s --format=%d $(
        git show-branch --independent -a
)

或许sed来品尝。要打破每行的所有重新命名并删除分组标点符号

git show -s --format=%d $(git show-branch --independent -a) \
| sed 's/,/\n/g; s/[ ()]//g'

答案 2 :(得分:3)

已经有一些有用的答案,但没有给出要求:列表或分支(对我而言,这意味着分支名称,而不是提交ID)。

获取提示分支名称列表

{
        echo "** Below is list of tip branches a.k.a. final nodes."
        echo "** These aren't reachable from any other branches."
        echo "** Removing them is potentially DANGEROUS: it would make some commit unreachable."
        TIPS=$( git rev-list --branches --children | grep -v ' ' | sort )
        { while read branchname commitid message
                do grep $commitid < <(echo $TIPS) -q && echo $branchname
                done
        } < <(git branch -v --no-abbrev | sed 's/\*//' )
        echo "** end of list"
}

结果如下所示:

** Below is list of tip branches a.k.a. final nodes.
** These aren't reachable from any other branches.
** Removing them is potentially DANGEROUS: it would make some commit unreachable.
feature-workingonit
dev
** end of list

获取非提示分支名称列表

整理时,您可能希望看到非尖端分支。这是获取它们列表的一种方法。唯一的变化是&&成为||

{
        echo "** Below is list of non-tip branches a.k.a. inner nodes."
        echo "** These are reachable from other branches."
        echo "** If you remove them, all commits would stay reachable, but be careful anyway."
        TIPS=$( git rev-list --branches --children | grep -v ' ' | sort )
        { while read branchname commitid message
                do grep $commitid < <(echo $TIPS) -q || echo $branchname
                done
        } < <(git branch -v --no-abbrev | sed 's/\*//' )
        echo "** end of list"
}

结果如下所示:

** Below is list of non-tip branches a.k.a. inner nodes.
** These are reachable from other branches.
** If you remove them, all commits would stay reachable, but be careful anyway.
feature-alreadymerged
master
** end of list

获取具有提交ID和消息

的非提示分支名称列表

您可以根据需要进行装饰,例如通过更改:

echo $branchname

echo -e "$branchname\t$commitid\t$message"

结果如下:

** Below is list of non-tip branches a.k.a. inner nodes.
** These are reachable from other branches.
** If you remove them, all commits would stay reachable, but be careful anyway.
feature-alreadymerged   426ac5186841876163970afdcc5774d46641abc4    Cool feature foo, ref task #1234
master  39148238924687239872eea425c0e837fafdcfd9    Some commit
** end of list

然后,您可以在自己喜欢的工具中查看这些分支,看看删除它们是否有意义。

答案 3 :(得分:2)

由于分支只是在工作目录中处于活动状态时添加新提交时移动的标签 - 所有分支都是“按照定义”树的叶节点。

但我认为你要求那些与另一个分支的叶子提交没有共同祖先的分支。您想要CE,而不是ABD

-A-o-B-o-C
      \
       D-o-E

如果是这种情况,则可以找到不共享另一个分支的叶子提交的共同祖先的所有分支的列表。例如,DE共享D当前叶提交的共同祖先。

这可能是通过脚本完成的,但我不知道为所有分支执行它的git命令。但git过去让我感到惊讶,因为它可以通过其(有时是模糊的)命令参数的组合来完成。


在你的评论之后我做了更多的思考,我想我更好地理解为什么你的要求不可能(或可能有用)作为一个命令。这是因为git merge --squash <branch>之类的命令不会创建合并提交。创建的提交只是另一个常规提交 - 不包含任何说明来自另一个分支的提交。

例如,从:

开始
-A-o-B-o-C
      \
       D-o-E

并且HEAD位于Cgit merge --squash E命令会将E中包含的所有更改都准备好提交到索引中。一旦提交,树将看起来像

-A-o-B-o-o-C    <== notice branch `C` has moved forward one commit
      \
       D-o-E

C处的提交现在包含来自D-o-E的所有更改,但没有说明它来自哪里。现在可能不需要D-o-E,但只有项目的知识可以告诉你。

了解你想要做的事情将是一个手动过程;我确实想到了一些可以帮助您确定是否可以删除分支的命令。

这个git log命令只生成一个装饰的提交图(分支,标签和HEAD)。

git log --all --graph --oneline --simplify-by-decoration --decorate

运行此选项将为您提供一个视觉效果,使您可以快速查看“终点”分支的位置。提示:添加>> <filename>.txt将图表转储到可以用铅笔标记的文本文件中。

此外,一旦您确定了要保留的“终点”分支,请运行以下命令以查看<branch>的分支的祖先列表。这是将完全合并(使用合并提交)的分支列入<branch>

git branch --merged <branch>

这可能不是你想要的 - 但正如我上面所解释的那样,我认为这不可能。希望这些命令会有所帮助。

答案 4 :(得分:0)

我想你想要一份branch pointers的清单。这基本上是对分支末尾的提交的引用列表。这些通常称为masterHEAD,但可以是任何分支名称。

例如

git branch -a