[PATCH] translate bad characters in refnames during git-svn fetch

Subsystems: the rest

DORMANTno replies

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

[PATCH] translate bad characters in refnames during git-svn fetch

From: martin f krafft <hidden>
Date: 2016-06-15 22:43:21

Hi,

I am trying to track/convert the Debian pkg-mdadm repository with
git-svn:

  svn://svn.debian.org/svn/pkg-mdadm/mdadm/trunk

My problem is that the fetching fails:

  fatal: refs/remotes/tags/2.6.1-1~exp.1: cannot lock the ref
  update-ref -m r311 refs/remotes/tags/2.6.1-1~exp.1
  c6e351ea25dc90714048e33693099595c2d5dab8: command returned error:
  128

This is because the ~ character is an invalid character for
a refname (it's used to specify the nth parent).

So I figured that the best way to deal with this is to introduce
a conversion filter to git-svn, but I cannot figure out where it has
to go. My perl is rusty and even after an hour now with the code,
I could not find the right spot.

The following patch works, but I can't really explain why. Moreover,
it does not change the STDERR output, so you'll still get stuff like 

  r340 = 0dc5693471af9dfdb712c1342071ba1040af8963
  (tags/2.6.1-1~exp.3)

which makes me think that it's translating the refname too late.
However, the end result looks sane.

Comments welcome,
m

---
git-check-ref-format(1) documents which characters may be contained in
a refname. Since Subversion has different rules, an import can result in
problems, such as:

  fatal: refs/remotes/tags/2.6.1-1~exp.1: cannot lock the ref
  update-ref -m r311 refs/remotes/tags/2.6.1-1~exp.1
  c6e351ea25dc90714048e33693099595c2d5dab8: command returned error: 128

This patch translates bad characters to valid substitutes to enable imports of
tags/branches/whatever using characters that git does not allow in refnames.

Signed-off-by: martin f. krafft <redacted>
---
 git-svn.perl |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 299b40f..de43697 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1239,7 +1239,29 @@ sub new {
 	$self;
 }
 
-sub refname { "refs/remotes/$_[0]->{ref_id}" }
+sub refname {
+	my ($refname) = $_[0]->{ref_id};
+	## transform the refname as per rules in git-check-ref-format(1):
+	# no slash-separated omponent can begin with a dot .
+	# /.* becomes /,*
+	$refname =~ s|/\.|/,|g;
+	# It cannot have two consecutive dots .. anywhere
+	# .. becomes ,,
+	$refname =~ s|\.\.|,,|g;
+	# It cannot have ASCII control character space, tilde ~, caret ^,
+	# colon :, question-mark ?, asterisk *, or open bracket[ anywhere
+	# <space> becomes _
+	# ~ becomes =
+	# ^ becomes @
+	# : becomes %
+	# ? becomes $
+	# * becomes +
+	# [ becomes (
+	$refname =~ y| ~^:?*[|_=@%\$+(|;
+	# It cannot end with a slash /
+	$refname =~ s|/$||g;
+	"refs/remotes/$refname";
+}
 
 sub svm_uuid {
 	my ($self) = @_;
-- 
1.5.3.rc1.27.ga5e40


-- 
martin;              (greetings from the heart of the sun.)
  \____ echo mailto: !#^."<*>"|tr "<*> mailto:" net@madduck
 
spamtraps: madduck.bogus@madduck.net
 
"a warm bed in a house sounds a mite better
 than eating a hot dog on a stick
 with an old geezer traveling on a lawn mower."
                                -- alvin straight (the straight story)

Re: [PATCH] translate bad characters in refnames during git-svn fetch

From: Eric Wong <hidden>
Date: 2016-06-15 22:43:21

martin f krafft [off-list ref] wrote:
Hi,

I am trying to track/convert the Debian pkg-mdadm repository with
git-svn:

  svn://svn.debian.org/svn/pkg-mdadm/mdadm/trunk

My problem is that the fetching fails:

  fatal: refs/remotes/tags/2.6.1-1~exp.1: cannot lock the ref
  update-ref -m r311 refs/remotes/tags/2.6.1-1~exp.1
  c6e351ea25dc90714048e33693099595c2d5dab8: command returned error:
  128

This is because the ~ character is an invalid character for
a refname (it's used to specify the nth parent).

So I figured that the best way to deal with this is to introduce
a conversion filter to git-svn, but I cannot figure out where it has
to go. My perl is rusty and even after an hour now with the code,
I could not find the right spot.

The following patch works, but I can't really explain why. Moreover,
it does not change the STDERR output, so you'll still get stuff like 

  r340 = 0dc5693471af9dfdb712c1342071ba1040af8963
  (tags/2.6.1-1~exp.3)

which makes me think that it's translating the refname too late.
However, the end result looks sane.

Comments welcome,
The major issue with this is that it doesn't handle odd cases
where a refname is sanitized into something
(say "1234~2" sanitizes to "1234=2"), and then another branch
is created named "1234=2".

git-svn should at least keep track of what it got sanitized to, to
avoid clobbering branches.

I started working on this a while back but haven't gotten around
to revisiting it:
http://thread.gmane.org/gmane.comp.version-control.git/45651
quoted hunk
---
git-check-ref-format(1) documents which characters may be contained in
a refname. Since Subversion has different rules, an import can result in
problems, such as:

  fatal: refs/remotes/tags/2.6.1-1~exp.1: cannot lock the ref
  update-ref -m r311 refs/remotes/tags/2.6.1-1~exp.1
  c6e351ea25dc90714048e33693099595c2d5dab8: command returned error: 128

This patch translates bad characters to valid substitutes to enable imports of
tags/branches/whatever using characters that git does not allow in refnames.

Signed-off-by: martin f. krafft <redacted>
---
 git-svn.perl |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 299b40f..de43697 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1239,7 +1239,29 @@ sub new {
 	$self;
 }
 
-sub refname { "refs/remotes/$_[0]->{ref_id}" }
+sub refname {
+	my ($refname) = $_[0]->{ref_id};
+	## transform the refname as per rules in git-check-ref-format(1):
+	# no slash-separated omponent can begin with a dot .
+	# /.* becomes /,*
+	$refname =~ s|/\.|/,|g;
+	# It cannot have two consecutive dots .. anywhere
+	# .. becomes ,,
+	$refname =~ s|\.\.|,,|g;
+	# It cannot have ASCII control character space, tilde ~, caret ^,
+	# colon :, question-mark ?, asterisk *, or open bracket[ anywhere
+	# <space> becomes _
+	# ~ becomes =
+	# ^ becomes @
+	# : becomes %
+	# ? becomes $
+	# * becomes +
+	# [ becomes (
+	$refname =~ y| ~^:?*[|_=@%\$+(|;
+	# It cannot end with a slash /
+	$refname =~ s|/$||g;
+	"refs/remotes/$refname";
+}
 
 sub svm_uuid {
 	my ($self) = @_;
-- 
-- 
Eric Wong

Re: [PATCH] translate bad characters in refnames during git-svn fetch

From: Jan Hudec <hidden>
Date: 2016-06-15 22:43:21

On Sun, Jul 15, 2007 at 20:30:50 -0700, Eric Wong wrote:
The major issue with this is that it doesn't handle odd cases
where a refname is sanitized into something
(say "1234~2" sanitizes to "1234=2"), and then another branch
is created named "1234=2".

git-svn should at least keep track of what it got sanitized to, to
avoid clobbering branches.

I started working on this a while back but haven't gotten around
to revisiting it:
http://thread.gmane.org/gmane.comp.version-control.git/45651
I believe % is safe, right? So what if git-svn just url-escaped stuff in the
branch name it does not like. Of course % would be included in the list of
characters it does not like. Eg. 1234~2 would escape to 1234%7E2 and if the
user ever head 1234%7E2 in svn, it would simply escape too, to 1234%257E2.

Space is rather common, but that's why there is the + rule in url-encoding --
"foo bar" escapes to "foo+bar" and "foo+bar" escapes to "foo%2Bbar". Or you
could use something else to escape space. I can only think of "=", "_" is too
common to have it escaped and anything else would conflict with either git or
shell.

-- 
						 Jan 'Bulb' Hudec [off-list ref]
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help