Ir para o conteúdo

Software livre Brasil

 Voltar a Blog
Tela cheia

A better svn diff

6 de Outubro de 2010, 0:00 , por Software Livre Brasil - | Ninguém está seguindo este artigo ainda.
Visualizado 4238 vezes

Since I started using git, every time I need to use Subversion again I suffer. The output of `git diff` is so nice compared to the one produced `svn diff` that it hurts. I've alredy been struggling with that previously.

Now I think I've achieved the perfect solution to make `svn diff` behave just like `git diff`. I've documented it in this post hoping to help other poor souls like me who still have to use Subversion now and then.

Step 1: install colordiff. It's installed on Debian, so the installation required me no effort at all.

Step2 (optional): configure colordiff to use your preferred set of colors. My ~/.colordiffrc contains the following, to match the same colors used by default by `git diff`:


Step 3: create a script to be called by Subversion when running `svn diff`. In my case, I called it svn-diff and stored it in ~/bin (which is in my $PATH), but you can put it in /usr/local/bin or any other directory that is in your $PATH. The contents of ~/bin/svn-diff is the following:


 colordiff -u -L "${3}" -L "${5}" "${6}" "${7}"


After creating the script, you need to make it executable:

$ chmod +x ~/bin/svn-diff

Step 4: tell Subversion to use your script instead of plain diff on `svn diff`. To do that, locate the "helpers" section in your Subversion configuration file (~/.subversion/config), and set the diff-cmd setting to the name you gave to your custom script (svn-diff in my case):

diff-cmd = svn-diff

There is only one thing missing with regard to `git diff`: the nice pager behaviour. Git invokes that system pager in a way that less will receives the options "-FRSX". These options make less exit imediately if the output fits in one terminal screen and output the ANSI sequences (and thus colors) generated by colordiff in raw format, among other things. I couldn't find a way to emulate this: since `svn diff` will call our custom  diff command once for each changed file, we can't call the pager inside svn-diff. A comprimise is doing `svn diff | less -FRSX` , or setting the LESS environment variable to 'FRSX' and doing simply `svn diff | less`.

That's it! Now you can almost forget you are using Subversion (until you need to do some merging).

Tags deste artigo: git subversion colordiff less english

44 comentários

  • 049e519d4f9e81e2c1cfb9460c38cf82?only path=false&size=50&d=404Rene Wagner(usuário não autenticado)
    15 de Abril de 2011, 6:58

    git-style pager behavior

    Hi Antonio,

    thanks for documenting this. I've been meaning to implement the pager behavior but I wasn't aware of less already doing the majority of the work. I created a simple wrapper script in ~/bin and made sure ~/bin comes first in $PATH:

    $ cat ~/bin/svn

    /usr/bin/svn $@ | less -FRSX

    $ tail -n1 .bashrc
    export PATH=${HOME}/bin:${PATH}

    This gets rid of much of the pain with svn :) Now I just need to replicate 'git show' with svn...



  • 049e519d4f9e81e2c1cfb9460c38cf82?only path=false&size=50&d=404Rene Wagner(usuário não autenticado)
    15 de Abril de 2011, 7:25

    git show

    Revised wrapper script implementing 'svn show':


    MYLESS="less -FRSX"

    case $1 in
    (${SVN} log -c $2 | grep -v -- '------'; echo; ${SVN} diff -c $2) | ${MYLESS}
    ${SVN} $@ | ${MYLESS}

  • 1f71e0e53aa9a0ca76452567ae122410?only path=false&size=50&d=404Daniel Fancsali(usuário não autenticado)
    27 de Julho de 2011, 12:30

    Why write a script?

    Why do you write a separate script? Simply set the diff-cmd variable in svn config to colordiff, and voila', it works like a charm...

  • Ffe7c41864e239bf8c93fb994ca4a6a7?only path=false&size=50&d=404Rene Wagner(usuário não autenticado)
    2 de Novembro de 2011, 10:58

    Updated Script

    The script I posted above is slightly buggy. Here's a corrected version:


    MYLESS="less -FRSX"

    case $1 in
    (${SVN} log -c $2 | grep -v -- '------'; echo; ${SVN} diff -c $2) | ${MYLESS}
    ${SVN} "$@" | ${MYLESS}
    ${SVN} "$@"