`git svn dcommit` failing on a branch
-
11-06-2021 - |
Domanda
I have been using git-svn
to communicate with my company’s svn repo for a while now without any major headaches.
Today, the “headache”-part changed dramatically:
I’ve been working on master/trunk
pretty exclusively, and needed to merge most (but not all!) of those change-sets into a new svn-branch, that originated from a pre-existing svn-branch.
Basically this:
🍒---💩---💩---💩--1🍒--1🍒---💩--1🍒---💩---💩--1🍒--1🍒--1🍒---💩 master/trunk
\
\
2🍒--2🍒--2🍒--2🍒--2🍒 versioned-release
Should have become this:
🍒---💩---💩---💩--1🍒--1🍒---💩--1🍒---💩---💩--1🍒--1🍒--1🍒---💩 master/trunk
\
\
2🍒--2🍒--2🍒--2🍒--2🍒 versioned-release
\
\
1🍒--1🍒--1🍒--1🍒--1🍒--1🍒 new-versioned-release
Where 💩
are commits that shouldn’t be in the new-versioned-release
, and x🍒
the wanted commits from the respective branches x
.
So I did the following:
git checkout -b versioned-release-svn remotes/versioned-release
git svn branch new-versioned-release -m "Preparing for merge of XXX"
git checkout -b new-versioned-release-svn remotes/new-versioned-release
git cherry-pick ...
for every1🍒
, resolving any conflicts on the way.
Because I wanted to be sure I was really going to target the correct branch on the repo, I then ran git svn dcommit --dry-run
which did not yield any errors or warnings, but told me…
Committing to svn://username@$repo-host/$repo-name/$path/branches/new-versioned-release ...
…followed by a couple of diff-tree
lines.
So I attempted to omit the --dry-run
and half way through the commits ended up with…
Item already exists in filesystem: File already exists: filesystem '/data/subvroot/$repo-name/db', transaction '20856-g3m', path '/$path/branches/new-versioned-release/some-directory' at /usr/libexec/git-core/git-svn line 862
…and a bunch of unstaged changes.
Apart from the obvious — “WTF?!?” and “How do I get out of this mess without losing everything I did?” — I have two questions:
- Assuming I was back to before
git svn dcommit
: How do I get my local branch dcommit to its planned destination? - By now it seems obvious, that this wasn’t the right way to achieve what I wanted…but how should I have done it, instead?
Everything I found for the error-message, that somehow resembled my situation, so far was this other stack overflow question and the proposed solution of “somehow […] to blow away the .git/svn
metadata directory” doesn’t resonate quite that well with me…
Soluzione
Someone just up–voted my old question, so I thought I’d share how I do that nowadays.
It works really quite well.
Assuming the git repository has been created using
git svn clone \
--prefix svn/ \
--stdlayout \
svn://username@$repo-host/$repo-name/$path
$git_repo_name
change into the git repo, and there run
git checkout svn/versioned-release
git svn branch new-versioned-release
This will result in the following history on the SVN server:
🍒---💩---💩---💩--1🍒--1🍒---💩--1🍒---💩---💩--1🍒--1🍒--1🍒---💩 trunk
\
\
2🍒--2🍒--2🍒--2🍒--2🍒 versioned-release
\
\
3⭐️ new-versioned-release
Now I’d run
git checkout svn/new-versioned-release
git checkout -b new-versioned-release
# resulting in the following **local** history:
#
# 🍒---💩---💩---💩--1🍒--1🍒---💩--1🍒---💩---💩--1🍒--1🍒--1🍒---💩 master (tracks 'svn/trunk')
# \
# \
# 2🍒--2🍒--2🍒--2🍒--2🍒--3⭐️ new-versioned-release (tracks 'svn/new-versioned-release')
This is the foundation for achieving what I wanted.
There is one additional commit, because branching in SVN doesn’t work the same way as in Git: creating a branch always means a new revision, (aka commit) and that’s where the 3⭐️
comes from. It doesn’t really matter, but it’s there.
I can now git cherry-pick
all the 1🍒
s, ending up with this local history:
🍒---💩---💩---💩--1🍒--1🍒---💩--1🍒---💩---💩--1🍒--1🍒--1🍒---💩 master (tracks 'svn/trunk')
\
\
2🍒--2🍒--2🍒--2🍒--2🍒--3⭐️--1🍒--1🍒--1🍒--1🍒--1🍒--1🍒 new-versioned-release (tracks 'svn/new-versioned-release')
When I now git svn dcommit
while sitting on new-versioned-release
in git, the history on the SVN server looks like what I wanted to end up with:
🍒---💩---💩---💩--1🍒--1🍒---💩--1🍒---💩---💩--1🍒--1🍒--1🍒---💩 trunk
\
\
2🍒--2🍒--2🍒--2🍒--2🍒 versioned-release
\
\
3⭐️--1🍒--1🍒--1🍒--1🍒--1🍒--1🍒 new-versioned-release
The only difference being that additional 3⭐️
from creating the third SVN branch.