| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 | #!/bin/bash
#
# Take first subdir (or a subdir specified in a file) and consider
# it a git repo dir.  Get its origin, exchange the last bit for
# other project name and clone the other repo
#
# This is useful if you have a local dir where you store repos
# for various projects from a common namespace that differ only
# in last part of the remote URI.  Now all you need to do to
# clone new one is "git sibling aproject".  The script will
# do the rest for you including sniffing the URI.
#
# The script simply takes the first subdir.  In case this is not
# OK for you (e.g. the dir id likely to be empty or contain
# come "non-compliant" repos, you can specify path to the
# other "template" repo in .gittum-sibling file.
#
# Hint: regarding the "template" repo, you can easily create
# a "fake" repo that would sit elsewhere, e.g.:
#     $ mkdir .some/hidden/dir
#     $ cd .some/hidden/dir
#     $ git init
#     $ git remote add origin ssh://our_server/projects/FAKE
## funz
#
die() {
    echo "$@" 1>&2
    exit 1
}
usage() {
    echo "usage: git $(basename "$0") [-v] [-s SIBLING] [-r REMOTE] PROJECT"
    exit 0
}
rewrite_uri () {
    local remote=$1
    local to=$2
    # create a new remote URI based on current one
    git remote -v \
        | grep "^$remote" \
        | grep "(fetch)$" \
        | cut -f 2 \
        | cut -d" " -f 1 \
        | perl -pe "s|[^/]+$|$to|;"
}
think() {
    $verbose && echo "$@"
}
## initz
#
sibling_conf=".gittum-sibling"
verbose=false
sibling=$(find -maxdepth 1 -type d -name "[^.]*" | sort | head -1)
test -f $sibling_conf && sibling=$(cat $sibling_conf)
remote_name="origin"
while true; do case $1 in
    -r|--remote-name)   remote_name=$2; shift 2 ;;
    -s|--sibling)       sibling=$2;     shift 2 ;;
    -v|--verbose)       verbose=true;   shift   ;;
    -*)                                 usage   ;;
    "")                                 break   ;;
    *)                  project=$1;     shift   ;;
esac done
test -n "$project" || usage
test -n "$sibling" || die "could not find older sibling"
test -d "$sibling" || die "sibling does not exist: $sibling"
## body
#
pushd "$sibling" >/dev/null
new_remote=$(rewrite_uri "$remote_name" "$project")
popd >/dev/null
test -n "$new_remote" || die "no such remote at sibling: $new_remote at $sibling"
think \'git clone $new_remote\'
git clone "$new_remote"
 |