2

I'm finding myself in the situation where a client has provided us with a computer that I can use to VPN into their network in order to access their SVN repo. But we can't all be doing our development on that computer so we exported "our branch" and then imported it into our own SVN repo. Since the client doesn't really care about our day-to-day work we are planning to simply drop in large changesets at convenient times. This would all work, I'm sure of that.

Lately I have been wondering if there's any easy way of getting changesets (i.e. diff + message) out of our SVN, and then replay that into the client's SVN. Similar to what git format-patch and git am allows.

From looking at svn log --diff it looks like it would be possible, but I'd have to whip up some script to separate the output into a patch (to be applied using svn patch) and a commit message (to be supplied to svn commit -F). I'm hoping there's a solution that doesn't require me writing such a script though ;)

3 Answers 3

3
  1. LAST_MOVED is last moved commit. at the beginning it's 0, later it will increase.

  2. get list of commits:

    svn log -q -r $LAST_MOVED:HEAD | grep -o ^r[0-9]*

    this will produce something like

    r10
    r12
    r16
    r22

  3. for each REVISION you need to get diff:

    svn diff -c $REVISION > $REVISION.diff

    and commit message:

    svn log -c $REVISION | tail -n -2 | head -n -1 > $REVISION.txt

    you will have:

    r10.diff
    r10.txt

    r12.diff
    r12.txt

    r16.diff
    r16.txt

    r22.diff
    r22.txt

  4. get those files to target machine,

  5. run svn update

  6. for each r*.diff and r*.txt files run:

    • patch -p0 -i r{number}.diff

    • svn commit -a -m --file r{number}.txt

There is a problem that svn does not diff binary data, so any binary data won't be transferred using this method. For each binary file you will get:

Index: path/to/file/something.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

You should detect this string in diff files and for those files you can use external diff command described in https://stackoverflow.com/a/2255846/146745

3
  • Thanks, that's very clear. The limitation around binary files is a bit troublesome since the developers setting up the project decided to check in quite a few binary files, i.e. configuration is performed in Excel. Also, are there no drawbacks to using patch over svn patch?
    – Magnus
    Mar 22, 2014 at 6:44
  • 1) patch and svn patch should do same magic. 2) to get binary diff you can use git - take a look at this stackoverflow.com/questions/2234820/…
    – andrej
    Mar 22, 2014 at 17:25
  • Use svn diff --force to handle binary files. svn patch will automatically run svn add and svn rm on new and deleted files. Jul 23, 2018 at 18:10
1

I guess @andrej his answer worked when you have commit messages not exceeding one line of text. Now it leaves you with an empty commit message:

$ svn log -c r80 test/ | tail -n 2 | head -n 1

$

Note: I assume your version of svn log supported the options presented.

A better way is to grep the revisions from some path within your svn root and use svn log instead. The regex is adjusted not to match a single r in case you have a commit message starting with it.

The following commands create patches from revisions that affect the directory dir:

$ dir=test/
$ svn log "${dir}" | grep -oE '^r[0-9]+' \
        | while read -r rev; do
                svn log --diff -c ${rev} "${dir}" > "${rev}-${dir/\/*/}.patch";
        done

The command to patch r80-test.patch:

$ patch -p 0 < r80-test.patch

Tested with svn version 1.9.5.

0

deprecated, see my other answer

  1. change files
  2. run svn add *
  3. run svn diff > file.diff
  4. copy file.diff to client's pc
  5. on the client pc run svn update
  6. run patch -p0 -i file.diff
  7. run svn commit -a
  8. enjoy!
1
  • That won't work very well since we have a whole set of changes in "our SVN" that we want to bring over to "their SVN". The question is whether that can easily be done keeping the individual commits.
    – Magnus
    Mar 21, 2014 at 8:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .