Re: git-svn can lose changes silently
From: Seth Falcon <hidden>
Date: 2016-08-11 20:18:19
Subsystem:
the rest · Maintainer:
Linus Torvalds
Possibly related (same subject, not in this thread)
- 2016-08-11 · git-svn can lose changes silently · Steven Grimm <hidden>
Steven Grimm [off-list ref] writes:
git-svn is happy to overwrite changes in the svn repository with no warnings. Didn't seem to be known behavior when I mentioned it in #git, so here's an example, starting completely from scratch to make it easier to reproduce. I'm using git-svn 1.4.3 and svn 1.2.3 on OS X.
I can reproduce your example and also see the same thing when accessing an svn repository via https [I've never used the local file:// mode and was leary of it].
It is probably not a feature that you can lose changes without knowing about it! Even if I'd run git-svn fetch before that commit, it still wouldn't help if the svn version of the file changed between the time I ran fetch and the time I ran dcommit, totally possible with a busy svn repository. Opinions? Suggestions on fixing it? Do other people agree this is a bug?
I think this is a pretty big deal -- at least in terms of user expectation. The man page for 'git-svn commit' warns that upstream changes will be lost. But in suggesting to use 'git-svn dcommit' instead, one might expect (hope?) this overwritting upstream changes to not occur. I'm embarassed to admit that I've been using git-svn for a few weeks now and didn't test out these details. Here is a patch that I think improves matters a bit:
diff --git a/git-svn.perl b/git-svn.perl
index 4a56f18..daa1764 100755
--- a/git-svn.perl
+++ b/git-svn.perl@@ -830,6 +830,17 @@ sub commit_diff { ($repo, $SVN_PATH) = repo_path_split($SVN_URL); $SVN_LOG ||= libsvn_connect($repo); $SVN ||= libsvn_connect($repo); + + my ($r_last, $cmt_last) = svn_grab_base_rev(); + my $fetched = fetch(); + if ($r_last != $fetched->{revision}) { + print STDERR "There are new revisions that were fetched ", + "and need to be merged (or acknowledged) ", + "before committing.\n", + "last rev: $r_last\n", + " current: $fetched->{revision}\n"; + exit 1; + } my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : (); my $ed = SVN::Git::Editor->new({ r => $SVN->get_latest_revnum, ra => $SVN_LOG, c => $tb,
But for a possibly busy svn repository, the only real solution is one that uses the svn libs in a way that behaves like the svn client in terms of atomicity.