4

次の作業コピー構造があると仮定しましょう:

.
├── adm
└── etc

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

ここで、次の方法でサブプロジェクトを追加したとしgit subtreeます。

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)

このプロジェクトにしばらく取り組んでいないと仮定すると、サブプロジェクトのルートを特定するにはどうすればよいでしょうか? たとえば、「サブツリー化」した場所と正しいリモートを特定するにはどうすればよいでしょうか。または、「サブツリー化」したことをどのように識別しますか?

4

1 に答える 1

2

サブツリーが追加されたコミットを検出する 1 つの方法は、2 つの親が同じツリーに属していないマージ コミットを探すことです。つまり、これらの 2 つのコミットが履歴内の以前のコミットを共有していません。

Git リポジトリのルートから実行している bash でそのようなものを検出する方法のスクリプト例:

#!/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
于 2013-04-15T05:48:32.303 に答える