Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

  (email not shown publicly)
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Friday May 02, 2008
04:58 AM

Vim: Automatically Add Branch Names to a Commit

[ #36314 ]

This is for Subversion, but I'm sure you could extend it.

We branch for every feature we add, but I sometimes forget to add branch names to a commit. No longer. Add the following two lines to your .vimrc:

filetype plugin on
au! FileType svn :call AddBranchName()

And create a file named .vim/ftplugin/svn.vim with the following:

function! AddBranchName()
    let cwd  = getcwd()
    let path = split( cwd, '/' )
    let cwd  = path[ len(path) - 1 ]
    if bufname("%") == "svn-commit.tmp" && cwd != 'trunk'
        call append(0, "Branch: " . cwd)
        call append(1, "")
        call append(2, " -  ")

        call cursor(3, 4)

Now, when I type 'svn commit', I see something like the following, with the cursor already positioned where it needs to be:

Branch: errors_on_data_objects_with_drilldown

-  _

--This line, and those below, will be ignored--

M    root/reports/
M    conf/log/log.conf
A    lib/Pips3/C/Reports/Imports/Validation/
M    lib/Pips3/Report/Query/

This makes a few assumptions about your environment, so I would love to get some portability comments. I also wanted to leave the editor in insert mode, but couldn't figure out how to do that. Vim is one of the few tools I use regularly for which Google is almost useless.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • I don't really see the point of putting the name of the branch in the message because its somewhat redundant. If you read the log with -v then you see the paths. Sounds like you want :startinsert.
    • I have to put the branch name in there because it's part of our coding standards. Argue with jplindstrom and others :)

      And yes, startinsert is exactly what I needed. Thanks!

      • Well, I didn't make it up. But I believe it makes it easier to read the SVN Timeline in Trac. That may be the reason.
        • That sort of rule is common in shops stuck on Subversion… since Subversion does so little to actually help with branches (other than making them cheap to create, as if that bought you anything), you need to put a bunch of information in your commit messages manually in order to be able to babysit Subversion later. VCSs that actually have useful merge support, such as any DVCS of your choice, make it unnecessary to do that sort of bookkeeping.

          And if you like browsing Trac, wait to see the gitk browse

          • Yes, we even put revision numbers in merge messages to keep track of what we're doing. Sad, sad, sad.

            The silver lining: we're looking at moving to git. We just need to find a good point in time to take the productivity hit of switching.
  • This seems to get the branch name from the file system and not from svn. I don't always name my checkout directories the same as my branches and I frequently use symlinks to mark which one I'm currently using the most.

    Can your plugin instead use "svn info" to pull the actual branch name? It could pull the URL from "svn info" and then assume that the next path segment after "/branches" (or /branch, etc) is the actual branch name?
    • Can your plugin instead use "svn info" to pull the actual branch name?

      Turns out that's quite straightforward. Here's my version (below) modified to do that:

      let branch = matchstr(system('svn info .'), '\v(branch[^/]*/)@<=[^/]*')
      if branch != ''
        execute '1s//Branch: ' . branch . '\r\r -  '
      • forgive my vi idiocy, but I get this error message when I use that:

        "svn-commit.2.tmp" 4L, 63C
        Error detected while processing function AddBranchName:
        line 3:
        E486: Pattern not found: retired

        Here's my full plugin source:

        function! AddBranchName()
            let branch = matchstr(system('svn info .'), '\v(branch[^/]*/)@<=[^/]*')
            if branch != ''
              execute '1s//Branch: ' . branch . '\r\r -  '

        • I get this error message

          Ooops, my fault! s// repeats the most recent match; I'm guessing you previously searched for retired and that you have something in your Vim config which remembers the search register across sessions.

          Make that s/^/ instead. Sorry about that.

          my full plugin source

          Note you don't need that function definition around it; what I posted was intended to be the complete plug-in. See below for the explanation.

  • Note that you're duplicating the filetype detection there, twice. The standard $VIMRUNTIME/filetype.vim defines an autocommand such that starting to edit a file matching svn-commit*.tmp will trigger a FileType event for svn. As you've got it set up, making a commit causes these steps to run:

    1. .vim/ftplugin/svn.vim is run (because you have filetype plug-ins enabled), which in your case defines a function.
    2. Your autocommand for that filetype runs, which runs the function that svn.vim has just defined.
    3. Your