Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 158 lines (138 sloc) 5.24 KB
#!/usr/bin/env ruby
################################################################################
# #
# File: vcsdiff #
# ++++++++++++++++++++++++++++++ #
# Copyright (C) 2012 + Author: Foivos S. Zakkak + #
# + Website: foivos.zakkak.net + #
# + Email: foivos@zakkak.net + #
# ++++++++++++++++++++++++++++++ #
# #
# Based on the script svnvimdiff, written by #
# Geoff Buchan <geoffrey.buchan@gmail.com> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
require 'optparse'
require 'fileutils'
options = {}
option_parser = OptionParser.new do |opts|
opts.banner = %'Usage: #{opts.program_name} [OPTIONS] -- [DIFF OPTIONS]'
opts.separator ''
opts.separator 'Options'
options[:files] = Array.new
opts.on('-f','--file FILE[,FILE]',Array,'Define the file/files you want to diff',
'(you can use it more than once',
'or seperate the filenames with commas)',
'If not specified vcsdiff diffs all files in the directory') do |f|
options[:files]+=f
end
avail_sys = %w[svn hg git]
opts.on('-s','--system NAME',avail_sys,
'Define the version control system you are using',
"(#{avail_sys.join(',')})",
"if not given, #{opts.program_name} tries to automatically detect it"
) do |s|
options[:sys]=s
end
avail_diff = %w[vimdiff kompare]
options[:diff]="vimdiff"
opts.on('-t','--tool NAME',avail_diff,
'Define the prefered diff visualization tool',
"(#{avail_diff.join(',')})",
'defaults to vimdiff') do |t|
options[:diff]=t
end
options[:verbose]=false
opts.on('-v','--verbose',
'Enable verbose printing') do
options[:verbose]=true
end
opts.separator ''
opts.separator 'Diff options:'
opts.separator 'All diff options are passed to svn/git/hg diff'
opts.separator ''
opts.separator 'Common options:'
opts.on_tail('-h','--help','Show this message') do
puts option_parser
exit 0;
end
end
begin
option_parser.parse!(ARGV)
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
puts option_parser
exit 1;
end
if not options[:sys]
# Check if it is a svn repository
%x[svn info 2> /dev/null]
if ($?.success?)
options[:sys]="svn"
end
end
if not options[:sys]
# Check if it is a git repository
%x[git status 2> /dev/null]
if ($?.success?)
options[:sys]="git"
end
end
if not options[:sys]
# Check if it is a svn repository
%x[hg status 2> /dev/null]
if ($?.success?)
options[:sys]="hg"
end
end
if options[:verbose]
puts 'Auto-detected ' + options[:sys] + ' version control'
end
# if the user didn't specify any arguments go through each file in the directory
if options[:files].length == 0
if options[:sys].eql? "git"
modified=%x[#{options[:sys]} status 2> /dev/null | grep modified | awk '{print $3}']
else
modified=%x[#{options[:sys]} status 2> /dev/null | grep -e "^[MU]" | awk '{print $2}']
end
modified.split(%r[\n]).each do |f|
options[:files].push(f) if File.file?(f)
end
end
if options[:verbose]
puts 'Files that are going to be diffed:'
options[:files].each do |f|
puts " " + f
end
end
patch="/tmp/svnkomp_747_patch"
remote=""
options[:files].each do |f|
remote="/tmp/"+f
dir=File.dirname(remote)
FileUtils.mkdir_p(dir) unless File.exists?(dir)
%x[cp #{f} #{remote}]
%x[#{options[:sys]} diff #{ARGV.join(" ")} #{f} > #{patch}]
if !($?.success?)
puts %'Error: #{options[:sys]} diff #{ARGV.join(" ")} #{f} > #{patch} failed'
exit 1;
end
%x[patch -R -p0 #{remote} #{patch}]
%x[#{options[:diff]} #{f} #{remote} < `tty` > `tty`]
File.delete(remote)
end
at_exit do
%x[rm -rf #{remote} #{patch}]
end