Skip to content

a few useful features #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,30 @@ Options

- Alexander Artemenko <[email protected]>

* ``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 <[email protected]>
9 changes: 5 additions & 4 deletions git-svn-check-unpushed
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
258 changes: 163 additions & 95 deletions git-svn-clone-externals
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Loading