使用svn diff结合vimdiff来获取每个修改过的文件的选项卡差异页面

时间:2012-01-31 18:31:02

标签: svn vim diff

是否可以将svn与vim结合使用以获得一系列包含每个文件差异的标签页?这将是svn diff | view -的一个更好的替代方案,但它不会使用线性的差异列表,而是使用vimdiff。

在过去,我找到了一种方法来实现这一点并获得svn diff来为每个编辑的文件打开多个vims,但能够返回并查看旧文件将非常有用。因此,给定一组文件S的元组,我需要一个vim shell命令,它将在不同标签页的S元组的第一个位置打开每个文件,并在元组的第二个位置与相应的文件区分开来在S。

2 个答案:

答案 0 :(得分:6)

您可以通过--diff-cmd命令行开关指定要在Subversion中使用的diff命令,或者在Subversion配置中指定它(对于Unix命令行客户端是$HOME/.subversion/config)。

最重要的是要了解传递给SVN diff命令的参数:

  • 4 th 到最后一个参数 - 左侧的节目标题
  • 3 rd 到最后一个参数 - 右侧的节目标题
  • 2 nd 到上一个参数 - 左侧的临时文件
  • 最后一个参数 - 右侧的临时文件

传递的第一个参数是切换到Subversion diff命令。例如:

  • -u
  • -L

您可以使用此信息创建脚本以查看VIM中的文件。这是一个简单的Perl:

#! /usr/bin/env perl

use strict;
use warnings;

my $diff = "/usr/bin/vimdiff";

my $num_of_params = $#ARGV;

my $file1 = $ARGV[$num_of_params - 1];
my $file2 = $ARGV[$num_of_params];

my $title1 = $ARGV[$num_of_params - 4];
my $title2 = $ARGV[$num_of_params - 3];

my $title = "$title1 - $title2";
$title =~ s/\t/    /g;
$title =~ s/ /\\ /g;

system qq($diff -c "set titlestring=$title" "$file1" "$file2");

您必须确保system命令(如vimdiff)拥有命令行。我尝试在Mac上使用mvim,但在执行mvim命令之前删除了临时文件。

现在,你可以这样做:

$ svn diff --diff-cmd mydiff -rPREV

而且,如果你的脚本在你的PATH中并且是可执行的,它应该可以工作。


感谢ZyX

这是ZyX建议的改进程序。我不得不做出一些改变。我的diff命令在我的机器上实际上是mvim,我需要传入两个参数(-d来表示它是差异,而-f表示不要抛出mvim进入背景)。这意味着传递$DIFF,因为ZyX建议会导致我的system命令认为mvim -d -f是我的命令,并且我收到错误。为了解决这个问题,我将命令存储在一个数组中。我在使用它时也使阵列保持不变。

以下是该计划。更改DIFF以指向您的diff命令(可能是vimdiffgvim -d -fvim -d。如果您使用的是Windows,则完整路径位于{{ 1}},您可以使用C:/Program Files/Vim来摆脱空间。否则,您需要这样做:

C:/Progr~1/Vim

因为您将无法使用use constant DIFF => ('C:/Program Files/Vim/VIM73/gvim', '-f', '-d') 。我们可以说谢谢微软在目录名称中放置一个空格,所有命令都存放在这里没有充分的理由吗?我知道你可以。顺便说一句,如果您的编辑器所在的目录位于qw,则无需指定完整的目录名称。

PATH

答案 1 :(得分:3)

这可以通过几个脚本完成,并利用vim的“服务器”功能。下面的脚本可能会有所改进,例如它假设你想在图形Vim中执行此操作,并且在退出此Vim之前不希望脚本退出。此外,由于使用“diffsplit”,差异默认使用水平分割。

我使用以下两个脚本执行此操作。在要运行diff的目录中执行bash脚本:

#!/bin/bash

export VIM_SERVERNAME="SVN-$RANDOM"

# Start up a vim, graphical, in the foreground, but backgrounded...
vim -g -f --servername "$VIM_SERVERNAME" &
# So we get can it's PID to wait on later
gvim_pid=$!

# Wait for the server to start up enough
sleep 0.5

# Use svn diff to get the right set of files to pass to vimdiff
svn diff --diff-cmd "vim_tab_diff_helper.py" >/dev/null

# Move to the start of the list; remove the first tab which will be the empty
# tab
vim --servername "$VIM_SERVERNAME" --remote-send ":tabfirst<Return>"
vim --servername "$VIM_SERVERNAME" --remote-send ":bd<Return>"

# Wait for the user to exit vim before returning
wait $gvim_pid

帮助脚本“vim_tab_diff_helper.py”如下:

#!/usr/bin/python

import os
import subprocess
import sys

def vim_send(command):
  global vim_server
  subprocess.call(['vim', '--servername', vim_server, '--remote-send',
    command + '<Return>'])

vim_server = os.environ['VIM_SERVERNAME']
svn_orig_file = sys.argv[ len(sys.argv) - 2 ]
modified_file = sys.argv[ len(sys.argv) - 1 ]

vim_send(":tabnew")
vim_send(":e " + svn_orig_file)
vim_send(":diffsplit " + modified_file)