Dealing with external dependency repositories

Cloning contrib/ansible into ndslabs-deploy-tools

Source: http://stackoverflow.com/questions/23937436/add-subdirectory-of-remote-repo-with-git-subtree

Initial clone from contrib/ansible

# Do this the first time:
$ git remote add -f -t master --no-tags k8contrib https://github.com/kubernetes/contrib
 
# The next line is optional. Without it, the upstream commits get
# squashed; with it they will be included in your local history.
$ git merge -s ours --no-commit k8contrib/master
 
# Link to the "ansible" subdirectory in kubernetes contrib repository
# The trailing slash is important here!
$ git read-tree --prefix=FILES.deploy-tools/usr/local/lib/ndslabs/ansible/roles/kubernetes/ -u k8contrib/master:contrib/ansible
 
$ git commit

Pull from contrib/ansible

# In future, you can merge in additional changes as follows:
# The next line is optional. Without it, the upstream commits get
# squashed; with it they will be included in your local history.
$ git merge -s ours --no-commit k8contrib/master
 
# Replace the SHA1 below with the commit hash that you most recently
# merged in using this technique (i.e. the most recent commit on
# k8contrib/master at the time).
$ git diff --color=never d169004f6e66ad446c9a856cfbff80c7cfc931bf:contrib/ansible k8contrib/master:contrib/ansible | git apply -3 --directory=FILES.deploy-tools/usr/local/lib/ndslabs/ansible/roles/kubernetes/
 
# Now fix any conflicts if you'd modified FILES.deploy-tools/usr/local/lib/ndslabs/ansible/roles/kubernetes.
$ git commit

A Bash script to make it easier

git-merge-subpath
git-merge-subpath() {
    local SQUASH
    if [[ $1 == "--squash" ]]; then
        SQUASH=1
        shift
    fi
    if (( $# != 3 )); then
        local PARAMS="[--squash] SOURCE_COMMIT SOURCE_PREFIX DEST_PREFIX"
        echo "USAGE: ${FUNCNAME[0]} $PARAMS"
        return 1
    fi

    # Friendly parameter names; strip any trailing slashes from prefixes.
    local SOURCE_COMMIT="$1" SOURCE_PREFIX="${2%/}" DEST_PREFIX="${3%/}"

    local SOURCE_SHA1
    SOURCE_SHA1=$(git rev-parse --verify "$SOURCE_COMMIT^{commit}") || return 1

    local OLD_SHA1
    local GIT_ROOT=$(git rev-parse --show-toplevel)
    if [[ -n "$(ls -A "$GIT_ROOT/$DEST_PREFIX" 2> /dev/null)" ]]; then
        # OLD_SHA1 will remain empty if there is no match.
        local RE="^${FUNCNAME[0]}: [0-9a-f]{40} $SOURCE_PREFIX $DEST_PREFIX\$"
        OLD_SHA1=$(git log -1 --format=%b -E --grep="$RE" \
                   | grep --color=never -E "$RE" | tail -1 | awk '{print $2}')
    fi

    local OLD_TREEISH
    if [[ -n $OLD_SHA1 ]]; then
        OLD_TREEISH="$OLD_SHA1:$SOURCE_PREFIX"
    else
        # This is the first time git-merge-subpath is run, so diff against the
        # empty commit instead of the last commit created by git-merge-subpath.
        OLD_TREEISH=$(git hash-object -t tree /dev/null)
    fi &&

    if [[ -z $SQUASH ]]; then
        git merge -s ours --no-commit "$SOURCE_COMMIT"

Initial Clone (w/ script)

# Do this the first time:
$ git remote add -f -t master --no-tags k8contrib https://github.com/kubernetes/contrib.git
$ git-merge-subpath k8contrib/master contrib/ansible FILES.deploy-tools/usr/local/lib/ndslabs/ansible/roles/kubernetes/

Pull from contrib/ansible (w/ script)

# In future, you can merge in additional changes as follows:
$ git fetch k8contrib
$ git-merge-subpath k8contrib/master contrib/ansible FILES.deploy-tools/usr/local/lib/ndslabs/ansible/roles/kubernetes/
 
# Now fix any conflicts if you'd modified FILES.deploy-tools/usr/local/lib/ndslabs/ansible/roles/kubernetes.
$ git commit
  • No labels