ddsadsa dadsadssda
ddsadsa dadsadssda

Reputation: 23

Copy svn repository to different server and still be able to merge

I have a trunk on server A and would like to copy the whole SVN repository to server B, i.e. create the same trunk there. I then would like to be able to merge changes done on server A in trunk to server B trunk. Is that possible?

I tried with svn export and then import, but then I cannot do any merging. Any ideas?

Upvotes: 0

Views: 277

Answers (1)

Stewart
Stewart

Reputation: 4982

SVN isn't like git. Having seperate repositories doesn't allow you to easily merge one to the other.

Let's say A and B are perfect copies with HEAD pointing to revision 10000. A commit by Fred to repo A, will get a revision number of 10001. Then Sally commits something else to repo B which is also 10001. Getting these repos back in sync with identical revision numbers isn't possible.

What is possible is applying patch files. Let's say Fred's company has made 100 commits in repository A. Fred can 'export' those commits with something like this bash script:

for rev in {1000..10100} do
  svn log -c $rev --diff > $rev.patch
done

Now Fred has 100 patch files which he can zip up and send it to Sally. '

Sally now needs to "merge" those in with:

for patchfile in $(ls *.patch) do
  svn patch $patchfile
  svn ci
done

There will be a lot of manual work in checking all changes.


Maintaining this on a busy project will take lots of work, and is probably not the ideal situation. There is lots of potential for human-error and you will have a hard time tracking which revisions have been merged, which need to be sent, etc. Consider rethinking how/why you are doing this and think about if one of these approaches would suit your needs:

Vendor Branches

My guess is that you are delivering (or receiving) source code from another company. In this case, it might be a good idea to question whether you really need all details of all commits in the duplicated repository. If you consider the source repository as the "vendor", then consider each update of the duplicated repository as "integrating a vendor release". If there are 1000 commits between deliveries, then you can deliver one giant commit representing the new release and do an actual svn merge of that. In fact, to make things easier, just do a periodic svn export to make a simple archive with no revision history.

I do this currently. Here are some instructions I wrote for one of my customers (names changed) to help them setup a repository and prepare for our vendor releases:

First set up the repository:

# Start from an empty repository
# Initialize the repository with tags+branches directories
svn mkdir http://example.com/svn/awesomecode/tags
svn mkdir http://example.com/svn/awesomecode/branches

# Extract the contents of the source file.
tar -xf awesomecode_1.27.tar.xz

# Import the contents of that archive into your repository
svn import \
  awesomecode_1.27 \
  http://example.com/svn/awesomecode/upstream \
  -m "Importing upstream version 1.27"

# Tag the upstream version (optional)
svn copy \
  http://example.com/svn/awesomecode/upstream \
  http://example.com/svn/awesomecode/tags/upstream_1.27 \
  -m "Tagging upstream 1.27"

# Make a trunk to do your work in
svn copy \
  http://example.com/svn/awesomecode/upstream \
  http://example.com/svn/awesomecode/trunk

When we send a source code update, you can update your upstream/vendor branch:

# Checkout the upstream branch of the repository
svn checkout \
  http://example.com/svn/awesomecode/upstream \
  awesomecode

# Replace the old version
rm -rf awesomecode/*
tar -xf awesomecode_1.28.tar.xz \
  --strip-components=1 \
  --directory=awesomecode

# Commit the new version (also delete missing and add unversioned files)
cd awesomecode
svn delete $(svn status | sed -ne '/^!/p' | awk '{print $2}')
svn add $(svn status | sed -ne '/^?/p' | awk '{print $2}')
svn commit -m "Importing upstream version 1.28"

# Tag the new delivery:
svn copy \
  http://example.com/svn/awesomecode/upstream \
  http://example.com/svn/awesomecode/tags/upstream_1.28 \
  -m "Tagging upstream 1.28"

# Merge the delivery into your trunk
svn swtich ^/trunk
svn merge ^/upstream

As our trunks diverge over time, this merge will get much more difficult. To make this easier, consider sending some of your changes to us. We will review patches and add things we agree with to our code base. Minimizing differences is the easiest way to keep upstream merges manageable. Please send one patch file per commit. We need to check every change and a 20,000 line patch file cannot be reviewed. To generate patch files from commits 5-10, do this:

for rev in {5..10} do
  svn log -c $rev --diff > $rev.patch
done

The most authoritative literature on working with vendor branching is SVN book


svn:externals

Another reason you may want to have the same code in two repositories may be that you simply need the same code in two different projects. This is where svn:externals comes in handy. You could maintain the common code in an external repository, and simply have a reference to it in your project. Then, if someone makes a commit to your common code, you can benefit from it on all projects. If your repository is internet-facing, then you can consider having your customer integrate your source-code using svn:externals too.

First make sure your common code is in a repository, independent of any specific project. Next, in your specific project, you'll need use svn propset

svn propset svn:externals 'http://example.com/svn/common-code/trunk common' .

Now you have a directory called common in the root of your tree which contains the HEAD revision of the common-code. You can also peg a specific revision (which I recommend so that you can check out old revisions without them breaking). I like to use a script which periodically checks if my external repository has been updated, then bumps the pegged revision.

For more info, see the svn book, or svn help propset

Mirror

Maybe you want repo B to be a mirror of repo A. If you do that, then repo B should be read-only for normal users, and writable only for the svnsync process.

I have less experience with svnsync but it does exist and it is documented here:

http://svnbook.red-bean.com/en/1.7/svn.ref.svnsync.html

Upvotes: 1

Related Questions