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:

  1. git checkout -b versioned-release-svn remotes/versioned-release
  2. git svn branch new-versioned-release -m "Preparing for merge of XXX"
  3. git checkout -b new-versioned-release-svn remotes/new-versioned-release
  4. git cherry-pick ... for every 1🍒, 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:

  1. Assuming I was back to before git svn dcommit: How do I get my local branch dcommit to its planned destination?
  2. 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…

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top