threads / patch / 8647

patch, 3 partsAccept root <tree-ish> in 'git-svn commit-diff'

Subject: [PATCH 1/3] Accept root <tree-ish> in 'git-svn commit-diff'

## tl;dr

3 messages between Jun 19, 2007 and Jun 19, 2007. Diffs are folded; open one to read it.

replies: 2people: 1as markdown or json

Sergey Yanovich· Jun 19, 2007, 06:54 UTC · lore

Experiments with Subversion (my version is 1.4.2) show that it is not necessary to call 'svn import' before the first commit. Contrarily to the Subversion documentation, first commit may be done even when Subversion repository is at revision 0.

This allow export the whole git branch to a Subversion repo using only 'git-svn commit-diff'. Before this patch, however, 'git-svn' had no means to operate on root commits.

Signed-off-by: Sergey Yanovich <ynvich@gmail.com>
---
 git-svn.perl |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
Show changes to git-svn.perl +8 −1
diff --git a/git-svn.perl b/git-svn.perl
index 50128d7..8ad291b 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -2572,7 +2572,12 @@ sub generate_diff {
 	}
 	push @diff_tree, '--find-copies-harder' if $_find_copies_harder;
 	push @diff_tree, "-l$_rename_limit" if defined $_rename_limit;
-	push @diff_tree, $tree_a, $tree_b;
+	if ($tree_a eq '0000000000000000000000000000000000000000') {
+		push @diff_tree, '--root';
+	} else {
+		push @diff_tree, $tree_a;
+	}
+	push @diff_tree, $tree_b;
 	my ($diff_fh, $ctx) = command_output_pipe(@diff_tree);
 	local $/ = "\0";
 	my $state = 'meta';
@@ -2606,6 +2611,8 @@ sub generate_diff {
 			}
 			$x->{file_b} = $_;
 			$state = 'meta';
+		} elsif ($state eq 'meta' && $_ eq $tree_b &&
+			$tree_a eq '0000000000000000000000000000000000000000') {
 		} else {
 			croak "Error parsing $_\n";
 		}
-- 
1.5.2.1
Sergey Yanovich· Jun 19, 2007, 06:54 UTC · re: Sergey Yanovich · lore

[PATCH 2/3] 'git-svndump'

A git tool to keep a subversion mirror

git-svndump is essentially a wrapper around 'git-svn commit-diff'. It will work only when it is the sole method of committing to the Subversion repository.

It is designed to export a linear git branch. However, thanks to the way 'git' handles source code, 'git-svndump' seems to work in other conditions. For example, when branches are switched or merged.

git-svndump provides a solution when you need to export your source code in Subversion format (who would need this with git :), but do not want to have all the shackles that 'git-svn init' puts on your repository.

Signed-off-by: Sergey Yanovich <ynvich@gmail.com>
---
 Documentation/git-svndump.txt |   97 ++++++++++++++++++++++++++++++++++++++++
 Makefile                      |    1 +
 git-svndump-init.sh           |   85 +++++++++++++++++++++++++++++++++++
 git-svndump-sync.sh           |   98 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 281 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/git-svndump.txt
 create mode 100755 git-svndump-init.sh
 create mode 100755 git-svndump-sync.sh
Show changes to 4 files +281 −0

Documentation/git-svndump.txt, Makefile, git-svndump-init.sh, git-svndump-sync.sh

diff --git a/Documentation/git-svndump.txt b/Documentation/git-svndump.txt
new file mode 100644
index 0000000..11e7e79
--- /dev/null
+++ b/Documentation/git-svndump.txt
@@ -0,0 +1,97 @@
+git-svndump(1)
+==========
+
+NAME
+----
+git-svndump - Exporting from git to a single Subversion branch
+
+SYNOPSIS
+--------
+'git-svndump' <command> [options] [arguments]
+
+DESCRIPTION
+-----------
+git-svndump is essentially a wrapper around 'git-svn commit-diff'. It
+will work only when it is the sole method of committing to the
+Subversion repository.
+
+It is designed to export a linear git branch. However, thanks to the way
+'git' handles source code, 'git-svndump' seems to work in other
+conditions. For example, when branches are switched or merged.
+
+git-svndump provides a solution when you need to export your source code
+in Subversion format (who would need this with git :), but do not want
+to have all the shackles that 'git-svn init' puts on your repository.
+
+COMMANDS
+--------
+--
+
+'init'::
+	Initialize an existing git repository with additional
+	metadata directories for git-svndump.  The Subversion URL
+	must be specified as the first non-optional command-line
+	argument. 'git' tree-ish that correspond to the HEAD of
+	that Subversion URL may be specified as the second optional
+	command-line argument.
+
+-f;;
+	git-svndump normally declines to reinitialize the same git
+	repository. With the '-f' option that behavior is overridden.
+
+'sync'::
+	Commit git revisions to the Subversion repository. If a git
+	<tree-ish> is specified as an optional command-line argument,
+	than all commits between the last 'sync' and that <tree-ish> are
+	send. If the argument is omitted, the HEAD of the active branch
+	is used.
+
+--
+
+BASIC EXAMPLE
+--------------
+
+Contributing to a Subversion repository:
+
+------------------------------------------------------------------------
+# Create your git repository, do some work and commit your  changes
+# You are working on a computer A (git.foo.org)
+# Prepare your git repository for export (you are in the top dir)
+	git-svndump-init -A .auth http://svn.foo.org/project
+# Commit the whole branch:
+	git-svndump-sync
+# Now you go a different computer B
+# Clone a git repo:
+	git clone git.foo.org:/path/to/project.git
+# Enter the newly cloned directory:
+	cd project
+# Immediately prepare the new repository for export
+	git-svndump-init -A .auth http://svn.foo.org/project HEAD
+# Do some work and commit both locally and to A:
+	git commit ...
+	git push
+# Commit the new work:
+	git-svndump-sync
+# Now you return to the computer A
+# Reinit your repository for export!
+	git-svndump-init -f -A .auth http://svn.foo.org/project HEAD
+------------------------------------------------------------------------
+
+BUGS
+----
+
+The HEAD of the Subversion repository is not tracked. If your
+git-svndump repository goes out-of-sync with the Subversion mirror,
+the latter will most probably be corrupted.
+
+SEE ALSO
+--------
+gitlink:git-svn[1]
+
+Author
+------
+Written by Sergey Yanovich <ynvich@gmail.com>.
+
+Documentation
+-------------
+Written by Sergey Yanovich <ynvich@gmail.com>.
diff --git a/Makefile b/Makefile
index c09dfaf..ecf2803 100644
--- a/Makefile
+++ b/Makefile
@@ -211,6 +211,7 @@ SCRIPT_SH = \
 	git-am.sh \
 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
 	git-merge-resolve.sh git-merge-ours.sh \
+	git-svndump-init.sh git-svndump-sync.sh \
 	git-lost-found.sh git-quiltimport.sh git-submodule.sh
 
 SCRIPT_PERL = \
diff --git a/git-svndump-init.sh b/git-svndump-init.sh
new file mode 100755
index 0000000..4cf61b8
--- /dev/null
+++ b/git-svndump-init.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+usage()
+{
+	cat << EOF
+Usage: git-svndump-init [-f] subversion-url [<commit>]
+  subversion-url -- URL of the subversion repository to which you want
+                    to dump the current git repository
+  <commit>       -- git <commit> that correspond to the latest revision
+                    in the subversion repository
+OPTIONS
+  -f
+  		 do not stop, if the git repository is already initialized.
+EOF
+	exit 1
+}
+
+if test x$GIT_DIR = x ; then
+	if test -d ./.git ; then
+		GIT_DIR=`pwd`/.git
+	fi
+fi
+
+if test ! -d $GIT_DIR ; then
+	usage
+fi
+
+if test x$1 = x ; then
+	usage 
+fi
+
+if test x$1 = x-f; then
+	shift
+	rm -rf $GIT_DIR/svndump
+fi
+
+if test -d $GIT_DIR/svndump ; then
+	echo git-svndump-init: error: This git repository is already initialized
+	exit 1
+fi
+
+mkdir $GIT_DIR/svndump
+if test ! -d $GIT_DIR/svndump ; then
+	echo git-svndump-init: error: Failed to create $GIT_DIR/svndump
+	exit 1
+fi
+
+rev=`svn info $1 >$GIT_DIR/svndump/error.log`
+if test $? -ne 0 ; then
+	echo git-svndump-init: error: While quering $1
+	rm -rf $GIT_DIR/svndump
+	exit 1
+fi
+
+rev=`cat $GIT_DIR/svndump/error.log | sed -ne "/Revision/s/.* //p"`
+rm $GIT_DIR/svndump/error.log
+
+if test x$rev = x ; then
+	echo "git-svndump-init: error: Cannot determine the latest revision"
+	echo "                         at $1"
+	rm -rf $GIT_DIR/svndump
+	exit 1
+fi
+
+if test $rev -eq 0 ; then
+	mkdir -p $GIT_DIR/svndump/import && cd $GIT_DIR/svndump/import &&
+	svn import . $1 -m "Initial import by git-svndump"
+	if test $? -ne 0 ; then
+		echo "git-svndump-init: error: Failed to init $1"
+		rm -rf $GIT_DIR/svndump
+		exit 1
+	fi
+	rmdir $GIT_DIR/svndump/import
+fi
+
+echo "$1" > $GIT_DIR/svndump/url
+
+if test x$2 != x ; then
+	commit=`GIT_DIR=$GIT_DIR git-rev-list --max-count=1 $2`
+	if test $? -ne 0 ; then
+		echo "git-svndump-init: warning: Bad commit $2 ignored"
+	else
+		echo $commit >> $GIT_DIR/svndump/last
+	fi
+fi
diff --git a/git-svndump-sync.sh b/git-svndump-sync.sh
new file mode 100755
index 0000000..602af72
--- /dev/null
+++ b/git-svndump-sync.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+usage()
+{
+	cat << EOF
+Usage: git-svndump-sync [<commit>]
+  <commit>       -- git <commit> that correspond to the latest revision
+                    to be dumped to the subversion repository
+EOF
+	exit 1
+}
+
+if test x$GIT_DIR = x ; then
+	if test -d ./.git ; then
+		GIT_DIR=`pwd`/.git
+	fi
+fi
+
+if test ! -d $GIT_DIR ; then
+	usage
+fi
+
+if test ! -d $GIT_DIR/svndump ; then
+	echo "git-svndump-sync: error: This git repository is not initialized"
+	echo "                         Run git-svndump-init first"
+	exit 1
+fi
+
+if test ! -f $GIT_DIR/svndump/url ; then
+	echo "git-svndump-sync: error: Cannot read url"
+	exit 1
+fi
+
+url=`cat $GIT_DIR/svndump/url`
+rev=`svn info $url >$GIT_DIR/svndump/error.log`
+if test $? -ne 0 ; then
+	echo git-svndump-sync: error: While quering $url
+	rm -rf $GIT_DIR/svndump/error.log
+	exit 1
+fi
+
+rev=`cat $GIT_DIR/svndump/error.log | sed -ne "/Revision/s/.* //p"`
+rm $GIT_DIR/svndump/error.log
+
+if test x$rev = x ; then
+	echo "git-svndump-init: error: Cannot determine the latest revision"
+	echo "                         at $url"
+	exit 1
+fi
+
+if test x$1 = x ; then
+	commit=HEAD
+else
+	commit=`GIT_DIR=$GIT_DIR git-rev-list --max-count=1 $1`
+	if test $? -ne 0 ; then
+		echo "git-svndump-sync: error: Bad commit '$1'"
+		exit 1
+	fi
+fi
+
+start=""
+last=0000000000000000000000000000000000000000
+if test -f $GIT_DIR/svndump/last ; then
+	last=`cat $GIT_DIR/svndump/last`
+	start=^`GIT_DIR=$GIT_DIR git-rev-list --max-count=1 $last`
+	if test $? -ne 0 ; then
+		echo "git-svndump-sync: warning: Ignoring bad commit '$last'"
+		start=""
+		last=0000000000000000000000000000000000000000
+	fi
+fi
+
+while true ; do
+
+list=`GIT_DIR=$GIT_DIR git-rev-list --topo-order $commit $start | tail -n 8`
+
+if test -z "$list" ; then
+	exit 0
+fi
+
+diffs=""
+for c in $list ; do
+	diffs="$c $diffs"
+done
+
+for c in $diffs ; do
+	GIT_DIR=$GIT_DIR git-svn commit-diff -r$rev $last $c $url
+	if test $? -ne 0 ; then
+		exit $?
+	fi
+	echo "$c" > $GIT_DIR/svndump/last
+	last=$c
+	let rev++
+done
+
+start=^$last
+
+done
-- 
1.5.2.1
Sergey Yanovich· Jun 19, 2007, 06:54 UTC · re: Sergey Yanovich · lore

[PATCH 3/3] Fix large-scale exports by 'git-svndump'

This is an empty patch. It is generated only to preserve headers ([PATCH x/y] ...) for two previous patches. May/should be ignored.

Thanks to Johannes Sixt <J.Sixt@eudaptics.com> for comments.
Signed-off-by: Sergey Yanovich <ynvich@gmail.com>
---
 git-svndump-sync.sh |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
Show changes to git-svndump-sync.sh +1 −0
diff --git a/git-svndump-sync.sh b/git-svndump-sync.sh
index 602af72..b3e47f9 100755
--- a/git-svndump-sync.sh
+++ b/git-svndump-sync.sh
@@ -96,3 +96,4 @@ done
 start=^$last
 
 done
+
-- 
1.5.2.1

← back to recent threads