From: "Eddy Petrișor" <eddy.petrisor@gmail.com>
To: git@vger.kernel.org
Cc: Eddy Petrisor <eddy@epetrisor.dsd.ro>
Subject: [PATCH] First crude implementation of git-svn-externals
Date: Fri, 29 Aug 2008 03:02:58 +0300 [thread overview]
Message-ID: <1219968179-14156-2-git-send-email-eddy.petrisor@gmail.com> (raw)
In-Reply-To: <1219968179-14156-1-git-send-email-eddy.petrisor@gmail.com>
From: Eddy Petrisor <eddy@epetrisor.dsd.ro>
Current functionality:
- fetches all the externals of an already svn-fetched repo
- support for svn:externals refresh
- if the location of the external has changed, the current working
copy will be placed aside and a new directory will be created
instead
- if the remote URI is the same (maybe a verison bump, there will
be a 'git svn rebase'
- remove support (useful for testing purposes or clean restarts)
- avoid zombie externals at all costs - in some repos empty
svn:externals might exist; svn ignores such externals, so git should
do the same
TODO:
- take into account the revision of an external, if it exists
- do not do deep svn cloning, to avoid legthy operations, just pull HEAD
- add shallow copies to git svn repos (one revision should be enough
for most externals)
- use submodules for externals
---
.gitignore | 1 +
Makefile | 1 +
git-svn-externals.sh | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+), 0 deletions(-)
create mode 100755 git-svn-externals.sh
diff --git a/.gitignore b/.gitignore
index bbaf9de..cd2c47d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,6 +123,7 @@ git-status
git-stripspace
git-submodule
git-svn
+git-svn-externals
git-symbolic-ref
git-tag
git-tar-tree
diff --git a/Makefile b/Makefile
index bf400e6..b130244 100644
--- a/Makefile
+++ b/Makefile
@@ -265,6 +265,7 @@ SCRIPT_SH += git-sh-setup.sh
SCRIPT_SH += git-stash.sh
SCRIPT_SH += git-submodule.sh
SCRIPT_SH += git-web--browse.sh
+SCRIPT_SH += git-svn-externals.sh
SCRIPT_PERL += git-add--interactive.perl
SCRIPT_PERL += git-archimport.perl
diff --git a/git-svn-externals.sh b/git-svn-externals.sh
new file mode 100755
index 0000000..38b7af6
--- /dev/null
+++ b/git-svn-externals.sh
@@ -0,0 +1,158 @@
+#!/bin/sh
+
+set -e
+
+GIT_SVN_LAST_DIR="$(pwd)"
+trap "cd '$GIT_SVN_LAST_DIR'" INT EXIT KILL
+
+
+USAGE='[help|init|refresh|show]'
+
+LONG_USAGE='git svn externals help
+ print this long help message.
+git svn externals init [<pathspec>...]
+ pull all externals according to current repo state.
+git svn externals refresh [<pathspec>...]
+ removes current externals and repulls them.
+'
+
+
+SUBDIRECTORY_OK=Sometimes
+OPTIONS_SPEC=
+. git-sh-setup
+cd_to_toplevel
+# this should never fail
+require_work_tree
+
+
+GIT_SVN_TOP_DIR="$(pwd)"
+
+svn_revision_to_numrevision ()
+#$1 - repository URI
+#$2 - the revision to be transformed
+{
+ local REVSPEC
+ [ "$2" ] && REVSPEC="-r $2" || REVSPEC=''
+ [ "$1" ] || die "Internal error: no repository given in svn_revision_to_numrevision"
+ LANG=C svn info "$1" "$REVSPEC" | grep 'Revision' | cut -f 2 -d ':' | sed 's#^\ \ *##g'
+}
+
+prune_inital_slashes ()
+{
+ echo "$1" | sed 's#^//*##g'
+}
+
+git_svn_externals_remove ()
+{
+ local LASTDIR="$(pwd)"
+ cd_to_toplevel && TOPLEVELDIR="$(pwd)"
+ git svn show-externals | grep -vE '^(#.*|)$' | while read EXT_DIR REV EXT_SRC ; do
+ if [ -z "$REV" ] ; then
+ echo "Skipping illegal external '$EXT_DIR' which has no value" >&2
+ continue
+ fi
+ EXT_DIR="$(prune_inital_slashes "$EXT_DIR")"
+
+ if [ -z "$EXT_SRC" ] ; then
+ EXT_SRC="$REV"
+ REV="-rHEAD"
+ fi
+ REV=${REV#-r}
+
+ echo "Removing local copy for external '$EXT_DIR' ( $EXT_SRC@$REV )"
+ rm -fr "$EXT_DIR"
+ done
+
+ cd "$LASTDIR"
+}
+
+git_svn_init_dir_repo ()
+# assumes is ran from the parent dir of the repo
+# $1 EXT_DIR
+# $2 EXT_SRC
+# $3 REV
+{
+ local LASTDIR="$(pwd)"
+
+ mkdir -p "$1"
+ cd "$1"
+ git svn init "$2"
+ git svn fetch
+
+ cd "$LASTDIR"
+}
+
+git_svn_externals_refresh_external ()
+#$1 directory where the external is locally
+#$2 remote url
+#$3 revision at which the external is pinned at
+{
+ local LASTDIR="$GIT_SVN_TOP_DIR"
+
+ local EXT_SRC="$2"
+ local EXT_DIR="$1"
+
+ if cd "$EXT_DIR" 2>/dev/null; then
+ local OLDDIREXISTS=yes
+ local OLD_EXT_SRC=$(git config --get svn-remote.svn.url)
+ local OLD_EXT_REV=$(git config --get svn-remote.svn.revision || svn_revision_to_numrevision $OLD_EXT_SRC HEAD)
+ cd -
+ else
+ local OLDDIREXISTS=no
+ local OLD_EXT_SRC="${EXT_SRC}"
+ local OLD_EXT_REV=$(svn_revision_to_numrevision $EXT_SRC HEAD)
+ fi
+
+ if [ "$OLD_EXT_SRC" != "$EXT_SRC" ] ; then
+ echo "External URI definition changed. Moving away the old repo and pulling a new one."
+ cd "$LASTDIR"
+ local SUBDIR="$(basename "$EXT_DIR")"
+ local DIRNAME="$(dirname "$EXT_DIR")"
+ NEWDIR="$(mktemp -p "$DIRNAME" "$SUBDIR.obsolete.XXXXXX")" && rm -f "$NEWDIR"
+ mv "$EXT_DIR" "$NEWDIR"
+ echo " Old copy moved to '$NEWDIR'."
+ git_svn_init_dir_repo "$EXT_DIR" "$EXT_SRC" "$REV"
+ elif [ "$OLDDIREXISTS" = "no" ] ; then
+ git_svn_init_dir_repo "$EXT_DIR" "$EXT_SRC" "$REV"
+ else
+ cd "$EXT_DIR"
+ git svn rebase
+ fi
+
+ cd "$LASTDIR"
+ return 0
+}
+
+git_svn_externals_refresh ()
+{
+ git svn show-externals | grep -vE '^(#.*|)$' | while read EXT_DIR REV EXT_SRC ; do
+ if [ -z "$REV" ] ; then
+ echo "Skipping illegal external '$EXT_DIR' which has no value" >&2
+ continue
+ fi
+ EXT_DIR="$(prune_inital_slashes "$EXT_DIR")"
+
+ if [ -z "$EXT_SRC" ] ; then
+ EXT_SRC="$REV"
+ REV="-rHEAD"
+ fi
+ REV=${REV#-r}
+
+ echo "Refreshing local copy for external '$EXT_DIR' ( $EXT_SRC@$REV )"
+ cd "$GIT_SVN_TOP_DIR"
+ git_svn_externals_refresh_external "$EXT_DIR" "$EXT_SRC" "$REV"
+ done
+
+ cd "$GIT_SVN_TOP_DIR"
+}
+
+
+case $1 in
+ --remove)
+ git_svn_externals_remove
+ ;;
+ -r|--refresh|*)
+ git_svn_externals_refresh
+ ;;
+esac
+
--
1.5.6.3
next prev parent reply other threads:[~2008-08-29 0:04 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-29 0:02 [PATCH 0/3] git-svn-externals PoC (in a sh script) Eddy Petrișor
2008-08-29 0:02 ` [PATCH] git svn: should not display zombie externals Eddy Petrișor
2008-08-29 0:02 ` Eddy Petrișor [this message]
2008-08-29 0:02 ` [PATCH] added a test frame for git-svn-externals.sh Eddy Petrișor
2008-08-29 0:16 ` [PATCH 0/3] git-svn-externals PoC (in a sh script) Eddy Petrișor
2008-08-29 9:29 ` Eric Wong
2008-09-01 6:20 ` RFH: git-svn and submodules Eric Wong
2008-09-10 13:56 ` [PATCH 0/3] git-svn-externals PoC (in a sh script) Eddy Petrișor
2008-09-10 13:59 ` Eddy Petrișor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1219968179-14156-2-git-send-email-eddy.petrisor@gmail.com \
--to=eddy.petrisor@gmail.com \
--cc=eddy@epetrisor.dsd.ro \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).