git – 如何找出一个工作副本包含一个子树?

让我们假设我们有以下工作副本结构:

.
├── adm
└── etc

$git remote -v
origin  git@github.com:xxx/my.git (fetch)
origin  git@github.com:xxx/my.git (push)

现在,让我们假设我们已经通过git子树添加了一个子项目:

git remote add extlip git@github.com:yyy/ExtLib.git
git subtree add -P tech -m "added extlib as a sub-project" extlib/master

这样

.
├── adm
├── etc
└── tech

$git remote -v
origin  git@github.com:xxx/my.git (fetch)
origin  git@github.com:xxx/my.git (push)
extlip  git@github.com:yyy/ExtLib.git (fetch)
extlip  git@github.com:yyy/ExtLib.git (push)

现在假设你暂时没有在这个项目上工作,你如何识别子项目的根?比如说,你如何识别“子树化”的位置以及哪一个是正确的遥控器?或者,你如何确定你“完全”了?

最佳答案 检测添加子树的提交的一种方法是查找合并提交,其中两个父项不属于同一个树,或者换句话说,这两个提交不共享其历史记录中的任何先前提交.

一个示例脚本,介绍如何在bash中从git存储库的根目录运行它:

#!/bin/bash

# To separate the rev-list by newlines
IFS=$'\n'

# This rev list will return the hash and the parents, separated by spaces,
# of any merge commit found in the history of HEAD
for hashes in $(git rev-list --merges --parents HEAD); do

    # To split the commits by space
    IFS=$' '
    hashList=($hashes)

    # Merge base will find the most recent commit shared by all the
    # given commits, output dumped just to not clutter
    git merge-base ${hashList[1]} ${hashList[2]} > /dev/null

    # We care only if such commit did not exist, which means each parent is
    # in its own separate tree
    if [[ $? != 0 ]]; then
        echo "Subtree merge: ${hashList[0]}"
    fi
done
unset IFS
点赞