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) endif endfunction
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/validation_exceptions_by_period_table.tt M conf/log/log.conf A lib/Pips3/C/Reports/Imports/Validation/ObjectsByPeriod.pm M lib/Pips3/Report/Query/Validation.pm
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.
Re:why and the command you're looking for
Ovid on 2008-05-02T13:42:16
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!
Re:why and the command you're looking for
jplindstrom on 2008-05-02T16:33:43
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.Re:why and the command you're looking for
Aristotle on 2008-05-03T00:50:24
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
browser.:-) Re:why and the command you're looking for
jplindstrom on 2008-05-03T13:39:46
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.
Re:Branch names
Smylers on 2008-05-02T16:34:12
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 - '
endif
startinsert!Re:Branch names
mpeters on 2008-05-02T16:43:30
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 - '
endif
startinsert!
endfunctionRe:Branch names
Smylers on 2008-05-02T16:56:01
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:
.vim/ftplugin/svn.vim
is run (because you have filetype plug-ins enabled), which in your case defines a function.svn.vim
has just defined.svn-commit.tmp
.If in step 1 you just run the commands immediately in svn.vim
rather than defining a function then you can get rid of step 2 entirely. And the check in step 3 is unnecessary, since svn.vim
only runs at all if the filename matches.
So this can be refactored quite a bit. Also:
fnamemodify()
can do the filename manipulation.startinsert!
but with the exclamation mark conveniently puts the cursor at the end of the line, which is more robust than having to track how many lines and characters you've inserted.Putting all that together, I think you can just have the following in.vim/ftplugin/svn.vim
:
let parent_dir = fnamemodify(getcwd(), ':t')
if parent_dir != 'trunk'
execute '1s//Branch: ' . parent_dir . '\r\r - '
endif
startinsert!
However, neither your nor my version actually seems to do the right thing! It seems that svn commit
changes to the directory of the file being committed, which messes up getcwd()
for commits in subdirectories. So it looks like parsing svn info
will be needed, unfortunately.