diff --git a/README.txt b/README.txt index 2578b06..f691daf 100644 --- a/README.txt +++ b/README.txt @@ -80,3 +80,30 @@ Options - Alexander Artemenko +* ``git-svn-clone-externals`` + * -i git-ignore-file : For some reason, I need to add some ignore to + the root repository and to each svn:externals project. the git-ignore-file + format is just like a .gitignore file format. Its content will be added to + .git/info/exclude for each repository. + * -l : use symlinks in .git_externals/ for each svn:externals repository. + The default is off, which means it does not create symlinks, but direct + folder in the main repository. Everything should just work the same with + modified scripts from this 'freebsd' branch. + * Recursive svn:externals clone: + RootRepo/ + + ExtRepo1/ (svn:externals in RootRepo/) + | + ExtRepo11/ (svn:externals in ExtRepo1/) + ... + +* ``git-svn-excludes-update`` + * -i git-ignore-file : this options is required for this script. For each + exclude pattern option in the file, the script will check if it exists in + .git/info/exclude. The script check each svn:externals recursively. + git-ignore-file sample : + $ cat git-ignore-file + *.o + *.a + *~ + # end-of-file + +- Guillaume Bibaut diff --git a/git-svn-check-unpushed b/git-svn-check-unpushed index 8d6ddb8..e794090 100755 --- a/git-svn-check-unpushed +++ b/git-svn-check-unpushed @@ -22,10 +22,11 @@ def list_references(): HEAD_ref = None refs = {} for item in references.split('\n'): - sha1, name = item.split() - if name == 'HEAD': - HEAD_ref = sha1 - refs[sha1] = name + if len(item) != 0: + sha1, name = item.split() + if name == 'HEAD': + HEAD_ref = sha1 + refs[sha1] = name return HEAD_ref, refs diff --git a/git-svn-clone-externals b/git-svn-clone-externals index d6896f8..7265981 100755 --- a/git-svn-clone-externals +++ b/git-svn-clone-externals @@ -5,88 +5,98 @@ set -e toplevel_directory="$(git rev-parse --show-cdup)" [ -n "$toplevel_directory" ] && { echo "please run from the toplevel directory"; exit 1; } +gitignore_file="" +use_symlinks=0 function call() { - cmd="$@" - echo "$cmd" - eval "$cmd" - return "$?" + cmd="$@" + echo "$cmd" + eval "$cmd" + return "$?" } function do_clone() { - test -d .git_externals || return 1 - module=`echo $remote_url|sed 's,\(.*\)\(/trunk\|/branch.*\|/tag.*\),\1,'` - branch=`echo $remote_url|sed 's,\(.*\)\(/trunk\|/branch.*\|/tag.*\),\2,'|sed 's,^/,,'` - if [[ $branch = $remote_url ]]; then - branch="" - fi - ( - cd .git_externals - if [ -d "$local_directory" ]; then - ( - cd "$local_directory" - call git svn fetch --all - ) - else - tags="tags" - brch="branches" - branchpath=$(echo $branch|cut -f1 -d/) - echo $tags|grep $branchpath >/dev/null 2>&1 && tags=$branchpath - echo $brch|grep $branchpath >/dev/null 2>&1 && brch=$branchpath - - if [ "$module" = "$remote_url" ]; then - # URL does not contains any trunk, branches or tags part, so we dont need - # additional options for git-svn - call git svn clone "$revision" "$module" "$local_directory" - else - call git svn clone "$revision" "$module" -T trunk -b $brch -t $tags "$local_directory" - fi - - fi - ( - branch="$(echo ${branch}|sed 's,/$,,')" - if [ -n "$branch" ]; then - cd "$local_directory" - call git reset --hard $branch - fi - ) - ) + if [ $use_symlinks -ne 0 ]; then + test -d .git_externals || return 1 + fi + revision="$1" + remote_url="$2" + local_directory="$3" + module=`echo $remote_url | sed 's,\(.*\)\(/trunk\|/branch.*\|/tag.*\),\1,'` + branch=`echo $remote_url | sed 's,\(.*\)\(/trunk\|/branch.*\|/tag.*\),\2,' | sed 's,^/,,'` + if [[ $branch = $remote_url ]]; then + branch="" + fi + ( + if [ $use_symlinks -ne 0 ]; then + cd .git_externals + fi + if [ -d "$local_directory" ]; then + ( + cd "$local_directory" + call git svn fetch --all + ) + else + tags="tags" + brch="branches" + branchpath=$(echo $branch | cut -f1 -d/) + echo $tags | grep $branchpath >/dev/null 2>&1 && tags=$branchpath + echo $brch | grep $branchpath >/dev/null 2>&1 && brch=$branchpath + + if [ "$module" = "$remote_url" ]; then + # URL does not contains any trunk, branches or tags part, so we dont need + # additional options for git-svn + call git svn clone "$revision" "$module" "$local_directory" + else + call git svn clone "$revision" "$module" -T trunk -b $brch -t $tags "$local_directory" + fi + + fi + ( + branch="$(echo ${branch} | sed 's,/$,,')" + if [ -n "$branch" ]; then + cd "$local_directory" + call git reset --hard $branch + fi + ) + ) } function do_link() { - dir="$1" - base="$(dirname $dir)" - ( - mkdir -p "$base" - cd $base - rel=$(git rev-parse --show-cdup) - ln -sf ${rel}.git_externals/"$dir" - ) + dir="$1" + base="$(dirname $dir)" + ( + mkdir -p "$base" + cd $base + rel=$(git rev-parse --show-cdup) + ln -sf ${rel}.git_externals/"$dir" + ) } function do_excludes() { - dir="$1" - git_excludes_path=.git/info/exclude - if ! grep -q '^.git_externals$' "$git_excludes_path" - then - echo .git_externals >> "$git_excludes_path" - fi - - if ! grep -q '^'"$dir"'$' "$git_excludes_path" - then - echo "$dir" >> "$git_excludes_path" - fi + dir="$1" + git_excludes_path=.git/info/exclude + if [ $use_symlinks -ne 0 ]; then + if ! grep -q '^.git_externals$' "$git_excludes_path" + then + echo .git_externals >> "$git_excludes_path" + fi + fi + if ! grep -q '^'"$dir"'$' "$git_excludes_path" + then + echo "$dir" >> "$git_excludes_path" + fi } function is_excluded() { local result=0 if [ -f .git_externals_exclude ] ; then - matches=`grep -v "^#" .git_externals_exclude|grep "^/$1$"|wc -l` + matches=`grep -v "^#" .git_externals_exclude | grep "^/$1$"|wc -l` if [ $matches -gt 0 ] ; then local result=1 fi @@ -96,42 +106,100 @@ function is_excluded() } -git svn show-externals|grep -vE '#|^$'| \ - sed 's/\(-r\)[ ]*\([0-9]\{1,\}\)/\1\2/'|while read -a words -do - [ -z "${words[*]}" ] && continue - - local_directory="$(echo ${words[0]}|sed 's,^/,,')" - revision="" - remote_url="${words[1]}" - - check_excluded=$(is_excluded $local_directory) - - if [ $check_excluded -eq 0 ] ; then - if [ -n "${words[2]}" ]; then - revision="${words[1]}" - remote_url="${words[2]}" - fi - - if [ -n "$USE_SSH" ]; then - echo "Rewriting url to use SVN+SSH." - shopt -s extglob - remote_url="${remote_url/+(http|https)/svn+ssh}" - fi - - [ -z "${remote_url}" ] && continue - - export local_directory revision remote_url +function do_clone_externals() +{ + git svn show-externals | grep -vE '#|^$' | \ + sed 's/\(-r\)[ ]*\([0-9]\{1,\}\)/\1\2/' | \ + while read -a words + do + [ -z "${words[*]}" ] && continue + + local_directory="$(echo ${words[0]} | sed 's,^/,,')" + revision="" + remote_url="${words[1]}" + + check_excluded=$(is_excluded $local_directory) + + if [ $check_excluded -eq 0 ] ; then + if [ -n "${words[2]}" ]; then + revision="${words[1]}" + remote_url="${words[2]}" + fi + + if [ -n "$USE_SSH" ]; then + echo "Rewriting url to use SVN+SSH." + shopt -s extglob + remote_url="${remote_url/#(http|https)/svn+ssh}" + fi + + [ -z "${remote_url}" ] && continue + + echo "$local_directory -> $remote_url" + + dir=`dirname $local_directory` + if [ $use_symlinks -ne 0 ]; then + [ -d ".git_externals/$dir" ] || mkdir -p ".git_externals/$dir" + fi + + do_clone "$revision" "$remote_url" "$local_directory" || exit + if [ $use_symlinks -ne 0 ]; then + do_link "$local_directory" + fi + do_excludes "$local_directory" + + #recurse svn:externals + pushd $local_directory 1>/dev/null 2>/dev/null + do_clone_externals + popd 1>/dev/null 2>/dev/null + fi + + done + + if [ -n "$gitignore_file" ]; then + cat $gitignore_file | while read excopt; do + if ! grep -q "^${excopt}" .git/info/exclude; then + echo " adding \"${excopt}\" exclude pattern" + cat >> .git/info/exclude << EOF +${excopt} +EOF + fi + done + fi +} - echo "$local_directory -> $remote_url" +function usage() +{ + echo "Usage: `basename $0` [-i git-ignore-file] [-l]" + echo " -i git-ignore-file : git-ignore-file must exist. $0 will add its content to exclude informations" + echo " -l : use symlinks to svn:externals repositories (default: off)" + exit 2 +} - dir=`dirname $local_directory` - [ -d ".git_externals/$dir" ] || mkdir -p ".git_externals/$dir" +# Main + +while getopts "li:" _a; do + case $_a in + i) + _ignorefile="$OPTARG" + ;; + l) + use_symlinks=1 + ;; + \?) + usage + ;; + esac +done - do_clone "$revision" "$remote_url" "$local_directory" || exit - do_link "$local_directory" - do_excludes "$local_directory" +if [ -n "$_ignorefile" -a ! -f "$_ignorefile" ]; then + usage +fi +if [ -n "$_ignorefile" ]; then + _ignorefile=`realpath -q $_ignorefile` + if [ $? -ne 0 ]; then + usage fi +fi +gitignore_file="$_ignorefile" -done - +do_clone_externals diff --git a/git-svn-excludes-update b/git-svn-excludes-update new file mode 100755 index 0000000..4ed0893 --- /dev/null +++ b/git-svn-excludes-update @@ -0,0 +1,88 @@ +#!/bin/bash + +set -e + +toplevel_directory="$(git rev-parse --show-cdup)" +[ -n "$toplevel_directory" ] && { echo "please run from the toplevel directory"; exit 1; } + +gitignore_file="" + +function is_excluded() +{ + local result=0 + if [ -f .git_externals_exclude ] ; then + matches=`grep -v "^#" .git_externals_exclude | grep "^/$1$"|wc -l` + if [ $matches -gt 0 ] ; then + local result=1 + fi + fi + echo $result + return +} + + +function do_excludes_update() +{ + _root="$1" + git svn show-externals | grep -vE '#|^$' | \ + sed 's/\(-r\)[ ]*\([0-9]\{1,\}\)/\1\2/' | \ + while read -a words; do + [ -z "${words[*]}" ] && continue + + local_directory="$(echo ${words[0]} | sed 's,^/,,')" + [ -z "$local_directory" ] && continue + + check_excluded=$(is_excluded $local_directory) + if [ $check_excluded -eq 0 ] ; then + #recurse svn:externals + pushd $local_directory 2>&1 >/dev/null + do_excludes_update $_root + popd 2>&1 >/dev/null + fi + + done + + _pwd=`pwd` + _pwd="${_pwd/${_root}/}" + echo ".${_pwd}" + cat $gitignore_file | while read excopt; do + if ! grep -q "^${excopt}" .git/info/exclude; then + echo " adding \"${excopt}\" exclude pattern" + cat >> .git/info/exclude << EOF +${excopt} +EOF + fi + done +} + +function usage() +{ + echo "Usage: `basename $0` -i git-ignore-file" + echo " -i git-ignore-file : git-ignore-file must exist. $0 will add its content to exclude informations" + exit 2 +} + +# Main + +while getopts "i:" _a; do + case $_a in + i) + _ignorefile="$OPTARG" + ;; + \?) + usage + ;; + esac +done + +if [ -z "$_ignorefile" -o ! -f "$_ignorefile" ]; then + usage +fi +_ignorefile=`realpath -q $_ignorefile` +if [ $? -ne 0 ]; then + usage +fi +gitignore_file="$_ignorefile" + +_root=`pwd` +do_excludes_update $_root diff --git a/git-svn-externals-check b/git-svn-externals-check index fddc313..014a322 100755 --- a/git-svn-externals-check +++ b/git-svn-externals-check @@ -1,19 +1,28 @@ #!/bin/bash -for dir in *; do + +toplevel_directory="$(git rev-parse --show-cdup)" +[ -n "$toplevel_directory" ] && { echo "please run from the toplevel directory"; exit 1; } + +find . -type d -name .git -mindepth 2 | while read gitdir; do + dir=$(dirname "$gitdir") if [ -d $dir ]; then - cd $dir - STATUS=$(git status) - UNPUSHED=$(git-svn-check-unpushed) - if [ $(echo $STATUS|grep -c "clean") -lt 1 -o \ - $(echo $UNPUSHED|grep -c "No unpushed") -lt 1 ]; then - echo '>>>>>>>>>>>>>>>>' $dir '<<<<<<<<<<<<<<<<' - git status - git-svn-check-unpushed - echo '----------------------------------------' - else - echo $dir 'is clean' - fi - cd .. - fi + pushd $dir 1>/dev/null 2>/dev/null + STATUS=$(git status) + UNPUSHED=$(git-svn-check-unpushed) + if [ $(echo $STATUS|grep -c "clean") -lt 1 -o \ + $(echo $UNPUSHED|grep -c "No unpushed") -lt 1 ]; then + echo '>>>>>>>>>>>>>>>>' $dir '<<<<<<<<<<<<<<<<' + cat >&1 << EOF +$STATUS +EOF + cat >&1 << EOF +$UNPUSHED +EOF + echo '----------------------------------------' + else + echo $dir 'is clean' + fi + popd 1>/dev/null 2>/dev/null + fi done diff --git a/git-svn-externals-update b/git-svn-externals-update index 4313b29..571ff00 100755 --- a/git-svn-externals-update +++ b/git-svn-externals-update @@ -3,13 +3,13 @@ toplevel_directory="$(git rev-parse --show-cdup)" [ -n "$toplevel_directory" ] && { echo "please run from the toplevel directory"; exit 1; } -find .git_externals -type d -name .git | while read gitdir; do - dir=$(dirname "$gitdir") +find . -type d -name .git -mindepth 2 | while read gitdir; do + dir=$(dirname "$gitdir") if [ -d $dir ]; then - pushd $dir - echo $dir - git svn fetch - git svn rebase - popd + pushd $dir 1>/dev/null 2>/dev/null + echo $dir + git svn fetch + git svn rebase + popd 1>/dev/null 2>/dev/null fi done