如何使用git(或gitk)获取/列表/查看提交的所有后代?

时间:2011-12-11 02:57:12

标签: git parent commit gitk descendant

如果您使用gitk --all,则可以从所有分支机构查看您的仓库的所有提交。除了给定提交的后代之外,我想要类似的东西。

4 个答案:

答案 0 :(得分:12)

我认为这可能会做你想要的。所有分支中的所有提交,其中A为祖先:

gitk --all --ancestry-path A..

答案 1 :(得分:4)

简而言之:

git log --all BRANCH~1..

详细说明,使用示例:这是我刚创建的存储库的完整树:

$ git log --graph --oneline --decorate --all
* e3972be (HEAD, a) a-6
* 2707d79 a-5
* cdea9a7 a-4
| * 65b716e (c) c-5
| * ebe2a0e c-4
|/  
| * 2ed9abe (b) b-4
|/  
* ace558e (master) 3
* 20db61f 2
* 3923af1 1

除了--all,另一件事显而易见:master - > HEAD

$ git log --graph --oneline --decorate master..
* e3972be (HEAD, a) a-6
* 2707d79 a-5
* cdea9a7 a-4

所以我尝试将它们组合起来,几乎让我得到了我们想要的东西:

$ git log --graph --oneline --decorate --all master..
* e3972be (HEAD, a) a-6
* 2707d79 a-5
* cdea9a7 a-4
* 65b716e (c) c-5
* ebe2a0e c-4
* 2ed9abe (b) b-4

但不幸的是,这并没有显示分支之间的关系,因为我们要求的分支被省略了。所以我们必须使用来自master的父级的日志,如下所示:

$ git log --graph --oneline --decorate --all master~1..
* e3972be (HEAD, a) a-6
* 2707d79 a-5
* cdea9a7 a-4
| * 65b716e (c) c-5
| * ebe2a0e c-4
|/  
| * 2ed9abe (b) b-4
|/  
* ace558e (master) 3

钽哒! (我不知道这在过去根本不起作用,但以防万一:我在git 1.7.1版本上)

编辑2017-11-17 - 感谢STW实际上显示了这个问题:独立的树木会搞砸了。完全独立于master的提交将包含在此输出中。从上面的repo副本开始,这是我的上一个命令输出的内容:

$ git checkout --orphan z
Switched to a new branch 'z'
$ git commit --allow-empty -m'z-1'
[z (root-commit) bc0c0bb] z-1
$ git commit --allow-empty -m'z-2'
[z 1183713] z-2

$ git log --graph --oneline --decorate --all master~1..
* 1183713 (HEAD -> z) z-2
* bc0c0bb z-1
* 6069f73 (a) a-6
* 654d106 a-5
* a218c59 a-4
| * 338432a (c) c-5
| * 2115318 c-4
|/  
| * 43a34dc (b) b-4
|/  
* ce05471 (master) 3

作为孤儿创建的z分支与master没有共同的历史记录,因此应排除z-1z-2,但不是。--ancestry-pathz。这就是$ git log --graph --oneline --decorate --all --ancestry-path master~1.. * 6069f73 (a) a-6 * 654d106 a-5 * a218c59 a-4 | * 338432a (c) c-5 | * 2115318 c-4 |/ | * 43a34dc (b) b-4 |/ * ce05471 (master) 3 的用途,我现在得到了。包括它将排除分支--ancestry-path

master

为了完整性,即使它已经有$ git log --graph --oneline --decorate --all --ancestry-path master.. * 6069f73 (a) a-6 * 654d106 a-5 * a218c59 a-4 * 338432a (c) c-5 * 2115318 c-4 * 43a34dc (b) b-4 ,当前的最佳答案也没有正确显示分支关系,因为它排除了{{1}}本身的提交:

{{1}}

答案 2 :(得分:2)

提交只知道它的父级(因此一直都是这样),但对其子级/后代没有任何线索。你必须使用像A..B这样的符号来找到它。

例如,如果您想在给定的提交A之后找到当前分支中的提交,您可以执行以下操作:

git rev-list A..

答案 3 :(得分:0)

我能够使用 bash/git 为所有分支执行此操作。

这列出了后代提交(和给定的根):

git_list_all_descendant_hashes() {
    COMMIT=$1
    if [[ ${#COMMIT} -lt 40 ]]; then # short commit hash, need full hash
        COMMIT=`git rev-parse ${COMMIT}`
    fi

    declare -A ALL_HASHES

    while IFS= read -r string; do
        IFS=' ' read -r -a array <<< $string
        key=${array[0]}
        value=${array[@]:1}
        ALL_HASHES[${key}]=$value
    done <<< $(git rev-list --children --all)

    declare -A HASHES # subset of ALL_HASHES that are descendants

    HASHES[${COMMIT}]=1

    added_hashes=1
    while [[ ${added_hashes} -gt 0 ]]; do
        added_hashes=0
        # this loop is inefficient, as it will iterate over all collected hashes each time a hash is found to have new children
        for hash in ${!HASHES[@]}; do
            for child_hash in ${ALL_HASHES[${hash}]}; do
                if [[ ! -v HASHES[$child_hash] ]]; then
                    added_hashes=1
                    HASHES[${child_hash}]=1
                fi
            done
        done
    done

    for hash in ${!HASHES[@]}; do
        echo ${hash}
    done
}

您可以通过以下方式调用它:

git_descendants() {
    # the --short flag is a hack that'll return an error code if no argument is given, but git_list_all_descendant_hashes actually needs to turn it into a full hash
    COMMIT=`git rev-parse --short $1 2>/dev/null || git rev-parse HEAD`
    git log --graph --oneline --decorate ^${COMMIT}^@ $(git_list_all_descendant_hashes ${COMMIT})
}

如果后代有多个父母(即来自合并提交),它也会显示其非根祖先。这是我很高兴的事情,所以我没有费心去弄清楚如何摆脱它。