subwrap 0.3.12 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ProjectInfo.rb +4 -4
- data/Readme +29 -2
- data/bin/subwrap +6 -4
- data/bin/svn +2 -5
- data/lib/subwrap.rb +3 -5
- data/lib/subwrap/pager.rb +29 -0
- data/lib/subwrap/subversion.rb +23 -4
- data/lib/subwrap/subversion_extensions.rb +30 -12
- data/lib/subwrap/svn_command.rb +338 -70
- data/test/svn_command_test.rb +1 -1
- data/test/test_helper.rb +2 -2
- metadata +5 -13
data/ProjectInfo.rb
CHANGED
@@ -5,7 +5,7 @@ module Project
|
|
5
5
|
PrettyName = "Subwrap: Enhanced Subversion Command"
|
6
6
|
Name = "subwrap"
|
7
7
|
RubyForgeName = "subwrap"
|
8
|
-
Version = "0.
|
8
|
+
Version = "0.4.0"
|
9
9
|
Specification = Gem::Specification.new do |s|
|
10
10
|
s.name = Project::Name
|
11
11
|
s.summary = "A nifty wrapper command for Subversion's command-line svn client"
|
@@ -19,7 +19,7 @@ module Project
|
|
19
19
|
s.rubyforge_project = Project::Name
|
20
20
|
s.platform = Gem::Platform::RUBY
|
21
21
|
s.add_dependency("colored")
|
22
|
-
s.add_dependency("escape")
|
22
|
+
#s.add_dependency("escape")
|
23
23
|
s.add_dependency("facets")
|
24
24
|
s.add_dependency("quality_extensions")
|
25
25
|
s.add_dependency("rscm")
|
@@ -27,8 +27,8 @@ module Project
|
|
27
27
|
---------------------------------------------------------------------------------------------------
|
28
28
|
You should now be able to run the subwrap command.
|
29
29
|
|
30
|
-
IMPORTANT: If you want to replace the normal svn command with subwrap, please run
|
31
|
-
_subwrap_post_install or check the Readme to find out how to manually add it to your path.
|
30
|
+
IMPORTANT: If you want to replace the normal svn command with subwrap, please run
|
31
|
+
sudo `which _subwrap_post_install` or check the Readme to find out how to manually add it to your path.
|
32
32
|
|
33
33
|
Also, it is recommended that you install the termios gem so that you don't have to press enter
|
34
34
|
after selecting an option from the menu, but it will work without it.
|
data/Readme
CHANGED
@@ -3,8 +3,9 @@ link:include/subwrap.jpg
|
|
3
3
|
|
4
4
|
[<b>Home page</b>:] http://subwrap.rubyforge.org/
|
5
5
|
[<b>Project site</b>:] http://rubyforge.org/projects/subwrap
|
6
|
+
[<b>Suggestions?</b>:] http://subwrap.uservoice.com
|
6
7
|
[<b>Gem install</b>:] <tt>gem install subwrap</tt>
|
7
|
-
[<b>Author</b>:] Tyler Rick
|
8
|
+
[<b>Author</b>:] Tyler Rick (<rubyforge.org|tylerrick.com>)
|
8
9
|
[<b>Copyright</b>:] 2007 QualitySmith, Inc.
|
9
10
|
[<b>License</b>:] {GNU General Public License}[http://www.gnu.org/copyleft/gpl.html]
|
10
11
|
|
@@ -12,6 +13,12 @@ link:include/subwrap.jpg
|
|
12
13
|
|
13
14
|
This is a replacement <b><tt>svn</tt> command-line client</b> meant to be used instead of the standard +svn+ command. (Actually, it's a _wrapper_, not a strict replacement, because it still uses <tt>/usr/bin/svn</tt> to do all the dirty work.)
|
14
15
|
|
16
|
+
== Who is it for?
|
17
|
+
|
18
|
+
Anyone who feels like the standard svn command is missing some features and wants a slightly more powerful command-line svn tool...
|
19
|
+
|
20
|
+
Anyone who wants to hack/extend the svn command but is afraid to/too lazy to mess with the actual C source code...
|
21
|
+
|
15
22
|
== Installation
|
16
23
|
|
17
24
|
=== Dependencies
|
@@ -407,6 +414,22 @@ But... as with most things written in Ruby, it's all more about *productivity* t
|
|
407
414
|
|
408
415
|
==To do
|
409
416
|
|
417
|
+
Drop dependency on colordiff and use a native ruby colorizer that works on top of standard diff output. That may be necessary to support following change:
|
418
|
+
|
419
|
+
Make it do these by default:
|
420
|
+
-x [--extensions] arg : Default: '-u'. When Subversion is invoking an
|
421
|
+
external diff program, ARG is simply passed along
|
422
|
+
to the program. But when Subversion is using its
|
423
|
+
default internal diff implementation, or when
|
424
|
+
Subversion is displaying blame annotations, ARG
|
425
|
+
could be any of the following:
|
426
|
+
-b (--ignore-space-change):
|
427
|
+
Ignore changes in the amount of white space.
|
428
|
+
-w (--ignore-all-space):
|
429
|
+
Ignore all white space.
|
430
|
+
--ignore-eol-style:
|
431
|
+
Ignore changes in EOL style
|
432
|
+
|
410
433
|
Calling "Extensions.anything" is stupid. Can't we just merge/extend/include the methods from Extensions into the Subversion module itself?
|
411
434
|
|
412
435
|
Say you just did `svn mv base-suffix base-new_suffix`. Now say you want to commit that move without committing anything else in that dir.
|
@@ -432,7 +455,7 @@ After you save/edit/set an svn:externals, it should try to automatically pretty
|
|
432
455
|
my_info = YAML::load(svn(:info, File.join(dir, '..')))
|
433
456
|
my_revision = YAML::load(svn(:info, my_info['URL']))['Revision']
|
434
457
|
|
435
|
-
|
458
|
+
Get everything that was on http://wiki.qualitysmith.com/subwrap
|
436
459
|
|
437
460
|
===Ideas from TortoiseSvn
|
438
461
|
|
@@ -455,3 +478,7 @@ Word ideas to possibly incorporate:
|
|
455
478
|
* more
|
456
479
|
|
457
480
|
* 'subwrap'? Short for "Subversion wrapper". Also, a play on the words sub and wrap -- both of which are also food items.
|
481
|
+
|
482
|
+
==Contact me!
|
483
|
+
|
484
|
+
If you have any comments, suggestions, or patches, I would love to hear them! You'd be surprised how open I am to considering small or even massive changes to this project.
|
data/bin/subwrap
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
|
-
gem 'facets', '>=
|
5
|
-
require 'facets/kernel/load'
|
6
|
-
|
3
|
+
#require 'rubygems'
|
4
|
+
#gem 'facets', '>=2.4.1'
|
5
|
+
#require 'facets/kernel/load'
|
6
|
+
|
7
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
require 'subwrap/svn_command.rb'
|
7
9
|
Subversion::SvnCommand.execute
|
data/bin/svn
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require '
|
4
|
-
gem 'facets', '>=1.8.20'
|
5
|
-
require 'facets/kernel/load'
|
6
|
-
require_local '../lib/subwrap/svn_command.rb'
|
2
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'subwrap/svn_command'
|
7
4
|
Subversion::SvnCommand.execute
|
data/lib/subwrap.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
# This is the auto-require
|
2
|
-
|
3
|
-
|
4
|
-
require 'facets/kernel/load'
|
5
|
-
require_local 'subwrap/subversion'
|
1
|
+
# This is the auto-require, which I suppose never gets used any more thanks to RubyGems' annoying change
|
2
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__)))
|
3
|
+
require 'subwrap/subversion'
|
6
4
|
Subversion
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
|
2
|
+
|
3
|
+
def run_pager
|
4
|
+
return if PLATFORM =~ /win32/
|
5
|
+
return unless STDOUT.tty?
|
6
|
+
|
7
|
+
read, write = IO.pipe
|
8
|
+
|
9
|
+
unless Kernel.fork # Child process
|
10
|
+
STDOUT.reopen(write)
|
11
|
+
STDERR.reopen(write) if STDERR.tty?
|
12
|
+
read.close
|
13
|
+
write.close
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
# Parent process, become pager
|
18
|
+
STDIN.reopen(read)
|
19
|
+
read.close
|
20
|
+
write.close
|
21
|
+
|
22
|
+
ENV['LESS'] = 'FSRX' # Don't page if the input is short enough
|
23
|
+
|
24
|
+
Kernel.select [STDIN] # Wait until we have input before we start the pager
|
25
|
+
pager = ENV['PAGER'] || 'less'
|
26
|
+
exec pager rescue exec "/bin/sh", "-c", pager
|
27
|
+
end
|
28
|
+
|
29
|
+
|
data/lib/subwrap/subversion.rb
CHANGED
@@ -8,9 +8,10 @@ require 'rexml/xpath'
|
|
8
8
|
require 'rubygems'
|
9
9
|
|
10
10
|
gem 'facets'
|
11
|
+
require 'facets/kernel/silence'
|
11
12
|
silence_warnings do
|
12
|
-
require 'facets/kernel/silence'
|
13
13
|
require 'facets/kernel/load'
|
14
|
+
require 'facets/kernel/in'
|
14
15
|
require 'facets/enumerable/uniq_by'
|
15
16
|
require 'facets/fileutils/which'
|
16
17
|
require 'facets/fileutils/whereis'
|
@@ -18,6 +19,7 @@ end
|
|
18
19
|
|
19
20
|
gem 'quality_extensions'
|
20
21
|
require 'quality_extensions/module/initializer'
|
22
|
+
require 'quality_extensions/enumerable/map_with_index'
|
21
23
|
require 'quality_extensions/kernel/windows_platform'
|
22
24
|
|
23
25
|
|
@@ -212,7 +214,24 @@ module Subversion
|
|
212
214
|
# Returns the modifications to the working directory or URL specified in +args+.
|
213
215
|
def self.diff(*args)
|
214
216
|
args = ['./'] if args.empty?
|
215
|
-
execute("diff #{"--diff-cmd colordiff" if color?} #{args.join ' '}")
|
217
|
+
diff = execute("diff #{"--diff-cmd colordiff" if color?} #{args.join ' '}")
|
218
|
+
|
219
|
+
# Fix annoyance: You can't seem to do a diff on a file that was *added*. If you do -r 1:2 for a file that was *added* in 2, it will say it can't find the repository location for that file in r1.
|
220
|
+
if diff =~ /Unable to find repository location for '.*' in revision/ and @allow_diffs_for_added_files != false
|
221
|
+
args.map!(&:to_s)
|
222
|
+
args.map_with_index! do |arg, i|
|
223
|
+
if args[i-1].in? ['--revision', '-r']
|
224
|
+
arg.gsub(/\d+:/, '')
|
225
|
+
elsif arg.in? ['--change', '-c']
|
226
|
+
arg.gsub(/-c|--change/, '-r')
|
227
|
+
else
|
228
|
+
arg
|
229
|
+
end
|
230
|
+
end
|
231
|
+
diff = execute("cat #{args.join ' '}") #.enum(:each_line).map(&:chomp).map(&:green).join("\n")
|
232
|
+
end
|
233
|
+
|
234
|
+
diff
|
216
235
|
end
|
217
236
|
# Parses the output from diff and returns an array of Diff objects.
|
218
237
|
def self.diffs(*args)
|
@@ -323,8 +342,8 @@ module Subversion
|
|
323
342
|
#@rscm = ::RSCM::Subversion.new
|
324
343
|
#@rscm.revisions
|
325
344
|
|
326
|
-
|
327
|
-
log_output = Subversion.log(*
|
345
|
+
args = (['-v'] + args)
|
346
|
+
log_output = Subversion.log(*args)
|
328
347
|
parser = ::RSCM::SubversionLogParser.new(io = StringIO.new(log_output), url = 'http://ignore.me.com')
|
329
348
|
revisions = parser.parse_revisions
|
330
349
|
revisions
|
@@ -8,6 +8,7 @@ require 'facets/class_extension'
|
|
8
8
|
|
9
9
|
require 'subwrap/svn_command'
|
10
10
|
|
11
|
+
# :todo: move to quality_extensions
|
11
12
|
class Array
|
12
13
|
def to_regexp_char_class
|
13
14
|
"[#{join('')}]"
|
@@ -57,8 +58,8 @@ class String
|
|
57
58
|
end
|
58
59
|
def colorize_svn_diff
|
59
60
|
if Subversion.color
|
60
|
-
self.gsub(/^(Index: )(.*)$/) { $2.ljust(100).black_on_white}.
|
61
|
-
gsub(/^=+\n/, '')
|
61
|
+
self.gsub(/^(Index: )(.*)$/) { $2.ljust(100).black_on_white}. #
|
62
|
+
gsub(/^=+\n/, '') # Get rid of the boring ========= lines
|
62
63
|
else
|
63
64
|
self
|
64
65
|
end
|
@@ -77,26 +78,43 @@ module Subversion
|
|
77
78
|
|
78
79
|
class_extension do # These are actually class methods, but we have to do it this way so that the Subversion.extend(Subversion::Extensions) will also add these class methods to Subversion.
|
79
80
|
|
80
|
-
def status_lines_filter(input)
|
81
|
+
def status_lines_filter(input, options)
|
82
|
+
uninteresting_status_flags = []
|
83
|
+
if options[:only_statuses].nonempty?
|
84
|
+
uninteresting_status_flags = Interesting_status_flags - options[:only_statuses]
|
85
|
+
end
|
86
|
+
uninteresting_status_flags += Uninteresting_status_flags
|
87
|
+
|
81
88
|
input = (input || "").reject { |line|
|
82
89
|
line =~ /^$/ # Blank lines
|
83
90
|
}.reject { |line|
|
84
|
-
line =~
|
91
|
+
line =~ /^ ?#{uninteresting_status_flags.to_regexp_char_class}/
|
85
92
|
}.join
|
86
93
|
|
94
|
+
#-------------------------------------------------------------------------------------------
|
87
95
|
before_externals, *externals = input.split(/^Performing status on external item at.*$/)
|
88
96
|
|
89
97
|
before_externals ||= ''
|
90
|
-
|
98
|
+
if before_externals != ""
|
99
|
+
if options[:files_only]
|
100
|
+
before_externals = before_externals.strip.
|
101
|
+
gsub(/^ ?#{Status_flags.to_regexp_char_class} */, '') \
|
102
|
+
+ "\n"
|
103
|
+
else
|
104
|
+
before_externals = before_externals.strip.colorize_svn_status_lines + "\n"
|
105
|
+
end
|
106
|
+
end
|
91
107
|
|
92
108
|
externals = externals.join.strip
|
93
|
-
externals
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
109
|
+
if externals != ""
|
110
|
+
externals =
|
111
|
+
'_'*40 + ' externals '.underline + '_'*40 + "\n" +
|
112
|
+
externals.reject { |line|
|
113
|
+
line =~ /^Performing status on external item at/
|
114
|
+
}.reject { |line|
|
115
|
+
line =~ /^$/ # Blank lines
|
116
|
+
}.join.strip.colorize_svn_status_lines + "\n"
|
117
|
+
end
|
100
118
|
|
101
119
|
before_externals +
|
102
120
|
externals
|
data/lib/subwrap/svn_command.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rubygems'
|
|
4
4
|
|
5
5
|
require 'facets'
|
6
6
|
#gem 'facets', '>=1.8.51'
|
7
|
-
#require 'facets/more/command' # Not until
|
7
|
+
#require 'facets/more/command' # Not until Facets includes my changes
|
8
8
|
#require 'facets/kernel/load'
|
9
9
|
#require 'facets/kernel/with' # returning
|
10
10
|
#require 'facets/enumerable/every'
|
@@ -29,14 +29,15 @@ require 'quality_extensions/module/attribute_accessors'
|
|
29
29
|
require 'English'
|
30
30
|
require 'pp'
|
31
31
|
require 'stringio'
|
32
|
+
require 'subwrap/pager'
|
32
33
|
|
33
34
|
gem 'colored'
|
34
35
|
require 'colored' # Lets us do "a".white.bold instead of "\033[1ma\033[0m"
|
35
36
|
|
36
37
|
silence_warnings do
|
37
38
|
require_local '../../ProjectInfo'
|
38
|
-
|
39
|
-
|
39
|
+
require 'subwrap/subversion'
|
40
|
+
require 'subwrap/subversion_extensions'
|
40
41
|
end
|
41
42
|
|
42
43
|
begin
|
@@ -54,6 +55,9 @@ begin
|
|
54
55
|
at_exit { Termios.tcsetattr(STDIN, 0, save_terminal_attributes) }
|
55
56
|
rescue RuntimeError => exception # Necessary for automated testing.
|
56
57
|
if exception.message =~ /can't get terminal parameters/
|
58
|
+
# :todo: Can we detect if they are piping/redirecting stdout? Don't show warning if they are simply piping stdout.
|
59
|
+
# On the other hand, when ELSE do we expect to not find a terminal? Is this message *ever* helpful?
|
60
|
+
# Only testing? Then maybe the tests should set an environment variable or *something* to communicate that they want non-interactive mode.
|
57
61
|
puts 'Warning: Terminal not found.'
|
58
62
|
$interactive = false
|
59
63
|
else
|
@@ -74,8 +78,10 @@ module Kernel
|
|
74
78
|
end
|
75
79
|
end
|
76
80
|
|
81
|
+
# :todo: move to quality_extensions
|
77
82
|
class Object
|
78
83
|
def nonnil?; !nil?; end
|
84
|
+
def nonempty?; !empty?; end
|
79
85
|
end
|
80
86
|
|
81
87
|
class IO
|
@@ -303,7 +309,7 @@ module Subversion
|
|
303
309
|
#puts "add #{args.inspect}"
|
304
310
|
svn :exec, 'add', *args
|
305
311
|
end
|
306
|
-
|
312
|
+
|
307
313
|
#-----------------------------------------------------------------------------------------------------------------------------
|
308
314
|
module Commit
|
309
315
|
Console::Command.pass_through({
|
@@ -470,7 +476,8 @@ module Subversion
|
|
470
476
|
#-----------------------------------------------------------------------------------------------------------------------------
|
471
477
|
module Diff
|
472
478
|
Console::Command.pass_through({
|
473
|
-
[:_r, :__revision] => 1,
|
479
|
+
[:_r, :__revision] => 1,
|
480
|
+
[:_c, :__change] => 1,
|
474
481
|
[:__old] => 1,
|
475
482
|
[:__new] => 0,
|
476
483
|
#[:_N, :__non_recursive] => 0,
|
@@ -570,7 +577,7 @@ End
|
|
570
577
|
#-----------------------------------------------------------------------------------------------------------------------------
|
571
578
|
module Log
|
572
579
|
Console::Command.pass_through({
|
573
|
-
[:_r, :__revision] => 1,
|
580
|
+
[:_r, :__revision] => 1,
|
574
581
|
[:_q, :__quiet] => 0,
|
575
582
|
[:_v, :__verbose] => 0,
|
576
583
|
[:__targets] => 1,
|
@@ -632,7 +639,7 @@ End
|
|
632
639
|
#-----------------------------------------------------------------------------------------------------------------------------
|
633
640
|
module Move
|
634
641
|
Console::Command.pass_through({
|
635
|
-
[:_r, :__revision] => 1,
|
642
|
+
[:_r, :__revision] => 1,
|
636
643
|
[:_q, :__quiet] => 0,
|
637
644
|
[:__force] => 0,
|
638
645
|
}.
|
@@ -703,7 +710,7 @@ End
|
|
703
710
|
#-----------------------------------------------------------------------------------------------------------------------------
|
704
711
|
module Copy
|
705
712
|
Console::Command.pass_through({
|
706
|
-
[:_r, :__revision] => 1,
|
713
|
+
[:_r, :__revision] => 1,
|
707
714
|
[:_q, :__quiet] => 0,
|
708
715
|
[:__force] => 0,
|
709
716
|
}.
|
@@ -752,6 +759,15 @@ End
|
|
752
759
|
|
753
760
|
#-----------------------------------------------------------------------------------------------------------------------------
|
754
761
|
module Status
|
762
|
+
# Has no effect :( :
|
763
|
+
def initialize
|
764
|
+
@only_statuses = []
|
765
|
+
end
|
766
|
+
# So we'll do this instead:
|
767
|
+
def self.extended(klass)
|
768
|
+
klass.instance_variable_set(:@only_statuses, [])
|
769
|
+
end
|
770
|
+
|
755
771
|
Console::Command.pass_through({
|
756
772
|
[:_u, :__show_updates] => 0,
|
757
773
|
[:_v, :__verbose] => 0,
|
@@ -763,15 +779,41 @@ End
|
|
763
779
|
[:__ignore_externals] => 0,
|
764
780
|
}.merge(SvnCommand::C_standard_remote_command_options), self
|
765
781
|
)
|
782
|
+
def __modified
|
783
|
+
@only_statuses << 'M'
|
784
|
+
end
|
785
|
+
alias_method :_M, :__modified
|
786
|
+
|
787
|
+
def __added
|
788
|
+
@only_statuses << 'A'
|
789
|
+
end
|
790
|
+
alias_method :_A, :__added
|
791
|
+
|
792
|
+
#document :__files_only do
|
793
|
+
"Only list filenames, not statuses"
|
794
|
+
"(also currently lists directories with property changes -- not sure if it should or not)"
|
795
|
+
"Useful if you want to pipe a list of files to xargs, for instance."
|
796
|
+
"Examples:"
|
797
|
+
"subwrap st -M -A --files-only | xargs svn diff"
|
798
|
+
"for f in `subwrap st -M -A --files-only` ; do diff $f new_path/$f ; done"
|
799
|
+
"for f in `subwrap st -M -A --files-only` ; do cp $f new_path/$f ; done"
|
800
|
+
#end
|
801
|
+
def __files_only
|
802
|
+
@files_only = true
|
803
|
+
end
|
804
|
+
alias_method :__files, :__files_only
|
766
805
|
end
|
767
806
|
def status(*args)
|
768
|
-
|
807
|
+
options = {}
|
808
|
+
options[:only_statuses] = @only_statuses
|
809
|
+
options[:files_only] = @files_only
|
810
|
+
print Subversion.status_lines_filter( Subversion.status(*(prepare_args(args))), options )
|
769
811
|
end
|
770
812
|
|
771
813
|
#-----------------------------------------------------------------------------------------------------------------------------
|
772
814
|
module Update
|
773
815
|
Console::Command.pass_through({
|
774
|
-
[:_r, :__revision] => 1,
|
816
|
+
[:_r, :__revision] => 1,
|
775
817
|
[:_N, :__non_recursive] => 0,
|
776
818
|
[:_q, :__quiet] => 0,
|
777
819
|
[:__diff3_cmd] => 1,
|
@@ -1128,6 +1170,56 @@ End
|
|
1128
1170
|
end
|
1129
1171
|
|
1130
1172
|
|
1173
|
+
|
1174
|
+
|
1175
|
+
#-----------------------------------------------------------------------------------------------------------------------------
|
1176
|
+
# It seems that if a file has been modified, it doesn't matter if you svn:ignore it -- it *still* shows up in svn st/diff and
|
1177
|
+
# *still* will be committed if you commit the directory that contains it. That is bad.
|
1178
|
+
#
|
1179
|
+
# http://svn.haxx.se/users/archive-2006-11/0055.shtml
|
1180
|
+
# > Is there a way to mark a file as local changes only so that
|
1181
|
+
# > this file's changes will not be comitted?
|
1182
|
+
# No. The standard solution is to check in a template with a different filename and have your users copy it to the real
|
1183
|
+
# filename which is not under version control and on the ignore list.
|
1184
|
+
#
|
1185
|
+
# http://svnbook.red-bean.com/en/1.2/svn.advanced.props.html#svn.advanced.props.special.ignore
|
1186
|
+
# http://svnbook.red-bean.com/en/1.2/svn.advanced.html#svn.advanced.confarea.opts.config (global-ignores)
|
1187
|
+
#
|
1188
|
+
# In short, it looks like svn:ignore can ONLY be used to make svn ignore unversioned files. It doesn't work at all with versioned
|
1189
|
+
# files.
|
1190
|
+
#
|
1191
|
+
# But that's not an acceptable solution for some of us! Sometimes there are things in under version control that we want to make local changes to
|
1192
|
+
# without committing them and we can't just force all users of the repository to rename this file to whatever.dist...
|
1193
|
+
# At least not yet ... not without discussing it, etc. first. So in the meantime, we need something like this...
|
1194
|
+
#
|
1195
|
+
# So subwrap provides a higher-level mechanism for ignoring local changes to versioned files.
|
1196
|
+
#
|
1197
|
+
# We DON'T want to store local-ignores in an svn property, because then the property itself could accidentally get committed.
|
1198
|
+
#
|
1199
|
+
# But we need to store locally-ignored files SOMEWHERE persistent (in a file) ... how about in the .svn dir where svn keeps its
|
1200
|
+
# metadata? (Being careful, of course, not to conflict with any of its files/conventions.)
|
1201
|
+
|
1202
|
+
# To do:
|
1203
|
+
# Have every command that needs to read ./.svn/local_ignores
|
1204
|
+
# Commands that need to respect local ignores:
|
1205
|
+
# status
|
1206
|
+
# diff
|
1207
|
+
# commit!!
|
1208
|
+
# Since built-in svn commit doesn't let you say "commit this directory except for these files in it"...
|
1209
|
+
# Modify commit so that instead of passing dir name directly to svn, pass dir name with --non-recursive (to commit prop changes)
|
1210
|
+
# and calculate a list of all files to commit within the directory and pass the filenames too...
|
1211
|
+
# but reject from the file list everything listed in dir/.svn/local_ignores (for every subfolder too!)
|
1212
|
+
# Add an --except option to commit, which will do the same thing, but with user-supplied list
|
1213
|
+
|
1214
|
+
module LocalIgnore
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
def local_ignore
|
1218
|
+
#...
|
1219
|
+
end
|
1220
|
+
alias_method :dont_commit, :local_ignore
|
1221
|
+
alias_method :pretend_isnt_versioned, :local_ignore
|
1222
|
+
|
1131
1223
|
#-----------------------------------------------------------------------------------------------------------------------------
|
1132
1224
|
|
1133
1225
|
def ignore(file)
|
@@ -1143,13 +1235,15 @@ End
|
|
1143
1235
|
svn :system, "propedit svn:ignore #{directory}"
|
1144
1236
|
end
|
1145
1237
|
|
1238
|
+
|
1146
1239
|
#-----------------------------------------------------------------------------------------------------------------------------
|
1147
1240
|
# Commit message retrieving/editing
|
1148
1241
|
|
1149
1242
|
module GetMessage
|
1150
|
-
def
|
1243
|
+
def __revision(revision)
|
1151
1244
|
@revision = revision
|
1152
1245
|
end
|
1246
|
+
alias_method :_r, :__revision
|
1153
1247
|
end
|
1154
1248
|
def get_message()
|
1155
1249
|
#svn propget --revprop svn:log -r2325
|
@@ -1164,9 +1258,11 @@ End
|
|
1164
1258
|
end
|
1165
1259
|
|
1166
1260
|
module SetMessage
|
1167
|
-
def
|
1261
|
+
def __revision(revision)
|
1168
1262
|
@revision = revision
|
1169
1263
|
end
|
1264
|
+
alias_method :_r, :__revision
|
1265
|
+
|
1170
1266
|
def __file(filename)
|
1171
1267
|
@filename = filename
|
1172
1268
|
end
|
@@ -1191,9 +1287,10 @@ End
|
|
1191
1287
|
|
1192
1288
|
# Lets you edit it with your default editor
|
1193
1289
|
module EditRevisionProperty
|
1194
|
-
def
|
1290
|
+
def __revision(revision)
|
1195
1291
|
@revision = revision
|
1196
1292
|
end
|
1293
|
+
alias_method :_r, :__revision
|
1197
1294
|
end
|
1198
1295
|
def edit_revision_property(property_name, directory = './')
|
1199
1296
|
args = ['propedit', '--revprop', property_name, directory]
|
@@ -1239,11 +1336,12 @@ End
|
|
1239
1336
|
# Cause a working copy to cease being a working copy
|
1240
1337
|
def delete_svn(directory = './')
|
1241
1338
|
puts "If you continue, all of the following directories/files will be deleted:"
|
1242
|
-
system("find #{directory} -name .svn | xargs -n1 echo")
|
1339
|
+
system("find #{directory} -name .svn -type d | xargs -n1 echo")
|
1243
1340
|
response = confirm("Do you wish to continue?")
|
1244
1341
|
puts
|
1342
|
+
|
1245
1343
|
if response == 'y'
|
1246
|
-
system("find #{directory} -name .svn | xargs -n1 rm -r")
|
1344
|
+
system("find #{directory} -name .svn -type d | xargs -n1 rm -r")
|
1247
1345
|
end
|
1248
1346
|
end
|
1249
1347
|
|
@@ -1263,16 +1361,126 @@ End
|
|
1263
1361
|
end
|
1264
1362
|
|
1265
1363
|
#-----------------------------------------------------------------------------------------------------------------------------
|
1364
|
+
# This is designed to be a convenient replacement to the svn update command for those who wish to not only see a *list* of
|
1365
|
+
# which files were updated as the update occurs but also wish to see *what changed* for each of those files.
|
1366
|
+
# So this command will effectively do a diff on each updated file and show you what has changed (= "what's new").
|
1367
|
+
module WhatsNew
|
1368
|
+
end
|
1369
|
+
def whats_new
|
1370
|
+
SvnCommand.execute("revisions --whats-new --non-interactive")
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
#-----------------------------------------------------------------------------------------------------------------------------
|
1374
|
+
# :todo: Pre-fetch svn diff in the background (fork the process) so you don't have to wait, in interactive mode.
|
1375
|
+
# :todo: When calling this command on a single file,
|
1376
|
+
# * default to not showing all that annoying list of files (-v) but yes to automatically showing diffs.
|
1377
|
+
# * currently defaults to showingly only changes to this file, but should be option for View this changeset to show the full changeset
|
1378
|
+
# :todo: add number aliases (1) for view changeset, etc. so you can use numpad exclusively
|
1379
|
+
# :todo: rename interactive mode to different name, s.a. browse_revisions
|
1380
|
+
# Add --grep option to non-interactively search all changesets returned for a pattern.
|
1266
1381
|
module Revisions
|
1382
|
+
# We will pass all of these options through to 'svn log'
|
1383
|
+
Console::Command.pass_through({
|
1384
|
+
[:_q, :__quiet] => 0,
|
1385
|
+
[:_v, :__verbose] => 0,
|
1386
|
+
[:__targets] => 1,
|
1387
|
+
[:__stop_on_copy] => 0,
|
1388
|
+
[:__incremental] => 0,
|
1389
|
+
[:__xml] => 0,
|
1390
|
+
[:__limit] => 1,
|
1391
|
+
}.merge(SvnCommand::C_standard_remote_command_options), self
|
1392
|
+
)
|
1393
|
+
|
1394
|
+
#-------------------------------------------------------------------------
|
1395
|
+
def documentation
|
1396
|
+
"Examples:
|
1397
|
+
> subwrap revisions --limit 5 -r {2008-06-10}:head .
|
1398
|
+
"
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
#-------------------------------------------------------------------------
|
1402
|
+
def __revision(revisions)
|
1403
|
+
@revisions = revisions
|
1404
|
+
end
|
1405
|
+
alias_method :_r, :__revision
|
1406
|
+
|
1407
|
+
#-------------------------------------------------------------------------
|
1408
|
+
# :todo: Problem: I often forget to run this *before* doing an svn update. But as soon as I do an update, base is updated and now there is *nothing* new since last update.
|
1409
|
+
# Possible solution: Keep a log of updates (at least all updates that use this wrapper) and let you go back to any previous update as your starting point if you've updated very recently and want to go back farther than that.
|
1410
|
+
# (Or maybe .svn has a record of the previous update time somewhere that we can pick up?)
|
1411
|
+
# Also, as soon as you do an svn revisions, it detects that it's out of date and forces an update, making it so that you can't repeat the command and get the same results.
|
1412
|
+
#
|
1413
|
+
def __since_last_update
|
1414
|
+
@revisions = '%base%:head'
|
1415
|
+
@newest_first_default = false
|
1416
|
+
end
|
1417
|
+
alias_method :__from_base, :__since_last_update
|
1418
|
+
alias_method :__since_base, :__since_last_update
|
1419
|
+
alias_method :__new, :__since_last_update
|
1420
|
+
alias_method :__whats_new, :__since_last_update
|
1421
|
+
|
1422
|
+
#-------------------------------------------------------------------------
|
1423
|
+
# revision can be revision number or date.
|
1424
|
+
# :todo: allow 'yesterday', etc. or absolute time
|
1425
|
+
# Use chronic?
|
1426
|
+
# :todo:
|
1427
|
+
def __from(revision)
|
1428
|
+
@revisions = "#{revision}:head"
|
1429
|
+
@newest_first_default = false
|
1430
|
+
end
|
1431
|
+
alias_method :__since, :__from
|
1432
|
+
|
1433
|
+
def __back_to(revision)
|
1434
|
+
@revisions = "#{revision}:head"
|
1435
|
+
@newest_first_default = true
|
1436
|
+
end
|
1437
|
+
|
1438
|
+
#-------------------------------------------------------------------------
|
1439
|
+
# Show diffs automatically for each revision without the user having to press v
|
1440
|
+
def __show_diffs
|
1441
|
+
@show_diffs = true
|
1442
|
+
end
|
1443
|
+
alias_method :__auto_diffs, :__show_diffs
|
1444
|
+
|
1445
|
+
#-------------------------------------------------------------------------
|
1446
|
+
def __show_file_list; @show_file_list = true; end
|
1447
|
+
def __no_file_list; @show_file_list = false; end
|
1448
|
+
|
1449
|
+
#-------------------------------------------------------------------------
|
1450
|
+
def __fetch_all_diffs_up_front
|
1451
|
+
# :todo:
|
1452
|
+
# So that when you're actually stepping through revisions, viewing a diff is instantaneous...
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
#-------------------------------------------------------------------------
|
1267
1456
|
# Start at earlier revision and go forwards rather than starting at the latest revision
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1457
|
+
def __oldest_first
|
1458
|
+
@newest_first = false
|
1459
|
+
end
|
1460
|
+
alias_method :__forward, :__oldest_first
|
1461
|
+
alias_method :__forwards, :__oldest_first
|
1462
|
+
alias_method :__chronological, :__oldest_first
|
1463
|
+
|
1464
|
+
def __newest_first
|
1465
|
+
@newest_first = true
|
1271
1466
|
end
|
1272
|
-
|
1273
|
-
|
1467
|
+
alias_method :__reverse, :__newest_first
|
1468
|
+
alias_method :__backwards, :__newest_first
|
1469
|
+
|
1470
|
+
#-------------------------------------------------------------------------
|
1471
|
+
# Automatically fetch and print all diffs, pipe to a pager.
|
1472
|
+
# Great for catching up on what's new, skimming through recent commits.
|
1473
|
+
# (Whereas intercative mode is better for investigating, searching for the right commit that corresponds to some change you noticed, etc.)
|
1474
|
+
def __non_interactive
|
1475
|
+
@interactive = false
|
1274
1476
|
end
|
1477
|
+
alias_method :__ni, :__non_interactive
|
1275
1478
|
|
1479
|
+
def __interactive
|
1480
|
+
@interactive = true
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
#-------------------------------------------------------------------------
|
1276
1484
|
# Only show revisions that are in need of a code review
|
1277
1485
|
# :todo:
|
1278
1486
|
def __unreviewed_only
|
@@ -1288,28 +1496,61 @@ End
|
|
1288
1496
|
@author_filter = author
|
1289
1497
|
end
|
1290
1498
|
end
|
1499
|
+
# :todo: what if they pass in *2* filenames?
|
1291
1500
|
def revisions(directory = './')
|
1292
1501
|
puts "Getting list of revisions for '#{directory.white.bold}' ..."
|
1293
1502
|
|
1503
|
+
#-----------------------------
|
1294
1504
|
head = Subversion.latest_revision
|
1295
1505
|
revision_of_directory = Subversion.latest_revision_for_path(directory)
|
1296
1506
|
|
1297
|
-
# It's possible for a working copy to get "out of date" (even if you were the last committer!), in which case svn log will
|
1507
|
+
# It's possible for a working copy to get "out of date" (even if you were the last committer! at least, each *directory* seems to have a different concept of base rev), in which case svn log will
|
1298
1508
|
# only list revisions up to that revision (actually looks like it only goes up to and including Last Changed Rev: 2838,
|
1299
1509
|
# not Revision: 2839, as reported by svn info...)
|
1300
1510
|
if revision_of_directory and head and revision_of_directory < head
|
1301
1511
|
puts "The working copy '#{directory.white.bold}' appears to be out-of-date (#{revision_of_directory}) with respect to the head revision (#{head}). Updating..."
|
1302
1512
|
Subversion.update(directory)
|
1303
1513
|
end
|
1514
|
+
#-----------------------------
|
1515
|
+
|
1516
|
+
args = [directory]
|
1517
|
+
#@revisions ||= '1:head' # this was messing with --limit 5, making it start at 1 instead of most recent
|
1518
|
+
if @revisions
|
1519
|
+
@revisions.gsub! /%base%/, revision_of_directory
|
1520
|
+
args.concat ['-r', @revisions]
|
1521
|
+
end
|
1522
|
+
|
1523
|
+
@newest_first_default.nil? ? @newest_first_default = false : nil
|
1524
|
+
@newest_first.nil? ? @newest_first = @newest_first_default : nil
|
1525
|
+
|
1526
|
+
@show_diffs ||= true if !@interactive
|
1527
|
+
@show_diffs_default ||= false
|
1528
|
+
@show_diffs ||= @show_diffs_default
|
1304
1529
|
|
1305
|
-
|
1530
|
+
if @show_file_list.nil?
|
1531
|
+
if directory != './' # They specified a (non-default) directory/file
|
1532
|
+
@show_file_list = false
|
1533
|
+
else
|
1534
|
+
@show_file_list = true
|
1535
|
+
end
|
1536
|
+
end
|
1306
1537
|
|
1307
|
-
|
1308
|
-
|
1538
|
+
run_pager if !@interactive
|
1539
|
+
|
1540
|
+
#-----------------------------
|
1541
|
+
#pp prepare_args(args)
|
1542
|
+
revisions = Subversion.revisions(*prepare_args(args))
|
1543
|
+
|
1544
|
+
#puts "@newest_first=#{@newest_first}"
|
1545
|
+
puts "#{revisions.length.to_s.bold} revisions found. Starting with #{(@newest_first ? 'most recent' : 'oldest').green.bold} revision and #{@newest_first ? 'going backward in time' :'going forward in time' }..."
|
1546
|
+
revisions.instance_variable_get(:@revisions).reverse! if @newest_first
|
1309
1547
|
revision_ids = revisions.map(&:identifier)
|
1310
1548
|
|
1549
|
+
#-----------------------------------------------------------------------
|
1550
|
+
# The main loop through the array of revisions
|
1311
1551
|
target_rev = nil # revision_ids.first
|
1312
|
-
|
1552
|
+
show_revision = true
|
1553
|
+
|
1313
1554
|
revisions.each do |revision|
|
1314
1555
|
rev = revision.identifier
|
1315
1556
|
other_rev = rev-1
|
@@ -1321,42 +1562,76 @@ End
|
|
1321
1562
|
end
|
1322
1563
|
end
|
1323
1564
|
|
1324
|
-
|
1325
|
-
|
1565
|
+
#-----------------------------------------------------------------------
|
1566
|
+
show_diffs = proc {
|
1567
|
+
revs_to_compare = [other_rev, rev]
|
1568
|
+
#puts "\n"*10
|
1569
|
+
puts
|
1326
1570
|
puts((' '*100).green.underline)
|
1571
|
+
print "Diffing #{revs_to_compare.min}:#{revs_to_compare.max}... ".bold
|
1572
|
+
puts
|
1573
|
+
#Subversion.repository_root
|
1574
|
+
#Subversion.print_commands! do
|
1575
|
+
SvnCommand.execute("diff #{directory} --ignore-externals -r #{revs_to_compare.min}:#{revs_to_compare.max}")
|
1576
|
+
#end
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
#-----------------------------------------------------------------------
|
1580
|
+
# Display the revision (number, date, description, files changed)
|
1581
|
+
if show_revision
|
1582
|
+
|
1583
|
+
#puts((' '*100).green.underline)
|
1584
|
+
puts
|
1585
|
+
puts((' '*100).on_green)
|
1586
|
+
|
1327
1587
|
puts "#{revisions.length - revision_ids.index(rev)}. ".green.bold +
|
1328
1588
|
"r#{rev}".magenta.bold + (rev == head ? ' (head)'.bold : '') +
|
1329
1589
|
" | #{revision.developer} | #{revision.time.strftime('%Y-%m-%d %H:%M:%S')}".magenta.bold
|
1330
1590
|
puts revision.message
|
1331
1591
|
puts
|
1332
1592
|
#pp revision
|
1333
|
-
|
1334
|
-
|
1335
|
-
' ' +
|
1336
|
-
|
1593
|
+
if @show_file_list
|
1594
|
+
puts revision.map {|a|
|
1595
|
+
(a.status ? a.status[0..0].colorize_svn_status_code : ' ') + # This check is necessary because RSCM doesn't recognize several Subversion status flags, including 'R', and status will return nil in these cases.
|
1596
|
+
' ' + a.path
|
1597
|
+
}.join("\n")
|
1598
|
+
end
|
1337
1599
|
else
|
1338
|
-
|
1600
|
+
show_revision = true
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
#-----------------------------------------------------------------------
|
1604
|
+
if @show_diffs
|
1605
|
+
show_diffs.call
|
1339
1606
|
end
|
1340
1607
|
|
1608
|
+
#-----------------------------------------------------------------------
|
1341
1609
|
# Display the menu
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1610
|
+
if @interactive
|
1611
|
+
print(
|
1612
|
+
"r#{rev}".magenta.on_blue.bold + ': ' +
|
1613
|
+
'View this changeset'.menu_item(:cyan) + ', ' +
|
1614
|
+
'Diff against specific revision'.menu_item(:cyan, 'D') + ', ' +
|
1615
|
+
'Grep the changeset'.menu_item(:cyan, 'G') + ', ' +
|
1616
|
+
'List or '.menu_item(:magenta, 'L') + '' +
|
1617
|
+
'Edit revision properties'.menu_item(:magenta, 'E') + ', ' +
|
1618
|
+
'svn Cat all files'.menu_item(:cyan, 'C') + ', ' +
|
1619
|
+
'grep the cat'.menu_item(:cyan, 'a') + ', ' + "\n " +
|
1620
|
+
'mark as Reviewed'.menu_item(:green, 'R') + ', ' +
|
1621
|
+
'edit log Message'.menu_item(:yellow, 'M') + ', ' +
|
1622
|
+
'or ' + 'browse using ' + 'Up/Down/Space/Enter'.white.bold + ' keys > '
|
1623
|
+
)
|
1624
|
+
end
|
1355
1625
|
|
1626
|
+
#-----------------------------------------------------------------------
|
1356
1627
|
# Get response from user and then act on it
|
1357
1628
|
begin # rescue
|
1358
|
-
|
1359
|
-
|
1629
|
+
if @interactive
|
1630
|
+
response = ""
|
1631
|
+
response = $stdin.getch.downcase
|
1632
|
+
else
|
1633
|
+
response = "\n"
|
1634
|
+
end
|
1360
1635
|
|
1361
1636
|
# Escape sequence such as the up arrow key ("\e[A")
|
1362
1637
|
if response == "\e"
|
@@ -1374,17 +1649,9 @@ End
|
|
1374
1649
|
end
|
1375
1650
|
|
1376
1651
|
case response
|
1377
|
-
when 'v' # View this changeset
|
1378
|
-
|
1379
|
-
|
1380
|
-
puts((' '*100).green.underline)
|
1381
|
-
print "Diffing #{revs_to_compare.min}:#{revs_to_compare.max}... ".bold
|
1382
|
-
puts
|
1383
|
-
#Subversion.repository_root
|
1384
|
-
Subversion.print_commands! do
|
1385
|
-
SvnCommand.execute("diff #{directory} --ignore-externals -r #{revs_to_compare.min}:#{revs_to_compare.max}")
|
1386
|
-
end
|
1387
|
-
show_revision_again = false
|
1652
|
+
when '1', 'v' # View this changeset
|
1653
|
+
show_diffs.call
|
1654
|
+
show_revision = false # only show the menu
|
1388
1655
|
|
1389
1656
|
when 'g' # Grep the changeset
|
1390
1657
|
# :todo; make it accept regexpes like /like.*this/im so you can make it case insensitive or multi-line
|
@@ -1395,9 +1662,9 @@ End
|
|
1395
1662
|
puts((' '*100).green.underline)
|
1396
1663
|
puts "Searching `svn diff #{directory} -r #{revs_to_compare.min}:#{revs_to_compare.max}` for #{search_pattern.to_s}... ".bold
|
1397
1664
|
diffs = nil
|
1398
|
-
Subversion.print_commands! do
|
1665
|
+
#Subversion.print_commands! do
|
1399
1666
|
diffs = Subversion.diffs(directory, '-r', "#{revs_to_compare.min}:#{revs_to_compare.max}")
|
1400
|
-
end
|
1667
|
+
#end
|
1401
1668
|
|
1402
1669
|
hits = 0
|
1403
1670
|
diffs.each do |filename, diff|
|
@@ -1415,7 +1682,7 @@ End
|
|
1415
1682
|
if hits == 0
|
1416
1683
|
puts "Search term not found!".red.bold
|
1417
1684
|
end
|
1418
|
-
|
1685
|
+
show_revision = false
|
1419
1686
|
|
1420
1687
|
when 'a' # Grep the cat
|
1421
1688
|
puts
|
@@ -1437,13 +1704,13 @@ End
|
|
1437
1704
|
else
|
1438
1705
|
puts "Search term not found!".red.bold
|
1439
1706
|
end
|
1440
|
-
|
1707
|
+
show_revision = false
|
1441
1708
|
|
1442
1709
|
|
1443
1710
|
when 'l' # List revision properties
|
1444
1711
|
puts
|
1445
1712
|
puts Subversion::printable_revision_properties(rev)
|
1446
|
-
|
1713
|
+
show_revision = false
|
1447
1714
|
|
1448
1715
|
when 'e' # Edit revision property
|
1449
1716
|
puts
|
@@ -1459,14 +1726,14 @@ End
|
|
1459
1726
|
end
|
1460
1727
|
end
|
1461
1728
|
|
1462
|
-
|
1729
|
+
show_revision = false
|
1463
1730
|
|
1464
1731
|
when 'c' # Cat all files from revision
|
1465
1732
|
puts
|
1466
1733
|
Subversion.print_commands! do
|
1467
1734
|
puts Subversion.cat(directory, '-r', rev)
|
1468
1735
|
end
|
1469
|
-
|
1736
|
+
show_revision = true
|
1470
1737
|
|
1471
1738
|
when 'r' # Mark as reviewed
|
1472
1739
|
puts
|
@@ -1479,14 +1746,14 @@ End
|
|
1479
1746
|
puts svn(:capture, "propset code:reviewed '#{your_name}' --revprop -r #{rev}", :prepare_args => false)
|
1480
1747
|
# :todo: Maybe *append* to code:reviewed (,-delimited) rather than overwriting it?, in case there is a policy of requiring 2 reviewers or something
|
1481
1748
|
end
|
1482
|
-
|
1749
|
+
show_revision = false
|
1483
1750
|
|
1484
1751
|
when 'm' # Edit log message
|
1485
1752
|
puts
|
1486
1753
|
Subversion.print_commands! do
|
1487
1754
|
SvnCommand.execute("edit_message -r #{rev}")
|
1488
1755
|
end
|
1489
|
-
|
1756
|
+
show_revision = false
|
1490
1757
|
|
1491
1758
|
when "\e[A" # Up
|
1492
1759
|
i = revision_ids.index(rev)
|
@@ -1495,16 +1762,17 @@ End
|
|
1495
1762
|
retry
|
1496
1763
|
|
1497
1764
|
|
1498
|
-
when /\n|\e\[B/ # Enter or Down
|
1765
|
+
when /\n|\e\[B| / # Enter or Down or Space
|
1499
1766
|
# Skip / Do nothing with this file
|
1500
1767
|
puts " Next..."
|
1768
|
+
#show_revision = false #?
|
1501
1769
|
next
|
1502
1770
|
|
1503
1771
|
else
|
1504
1772
|
# Invalid option. Do nothing.
|
1505
1773
|
#puts response.inspect
|
1506
1774
|
puts
|
1507
|
-
|
1775
|
+
show_revision = false
|
1508
1776
|
|
1509
1777
|
end # case response
|
1510
1778
|
|
@@ -1560,7 +1828,7 @@ End
|
|
1560
1828
|
end
|
1561
1829
|
|
1562
1830
|
# Removes nil elements, converts to strings, and adds any pass-through args that may have been provided.
|
1563
|
-
def prepare_args(args)
|
1831
|
+
def prepare_args(args=[])
|
1564
1832
|
args.compact! # nil elements spell trouble
|
1565
1833
|
args.map!(&:to_s) # shell_escape doesn't like Fixnums either
|
1566
1834
|
@passthrough_options + args.shell_escape
|
data/test/svn_command_test.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -3,13 +3,13 @@ require 'rubygems'
|
|
3
3
|
require 'facets/kernel/load'
|
4
4
|
gem 'mocha'
|
5
5
|
require 'stubba'
|
6
|
-
$LOAD_PATH << File.dirname(__FILE__)
|
6
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
7
|
|
8
8
|
gem 'test_extensions'
|
9
9
|
require 'test_extensions'
|
10
10
|
gem 'quality_extensions'
|
11
11
|
|
12
|
-
|
12
|
+
require 'subwrap/subversion'
|
13
13
|
if $mock_subversion
|
14
14
|
module Subversion
|
15
15
|
def self.executable
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: subwrap
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2008-06-
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2008-06-19 00:00:00 -07:00
|
8
8
|
summary: A nifty wrapper command for Subversion's command-line svn client
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,8 +29,8 @@ post_install_message: |
|
|
29
29
|
---------------------------------------------------------------------------------------------------
|
30
30
|
You should now be able to run the subwrap command.
|
31
31
|
|
32
|
-
IMPORTANT: If you want to replace the normal svn command with subwrap, please run
|
33
|
-
_subwrap_post_install or check the Readme to find out how to manually add it to your path.
|
32
|
+
IMPORTANT: If you want to replace the normal svn command with subwrap, please run
|
33
|
+
sudo `which _subwrap_post_install` or check the Readme to find out how to manually add it to your path.
|
34
34
|
|
35
35
|
Also, it is recommended that you install the termios gem so that you don't have to press enter
|
36
36
|
after selecting an option from the menu, but it will work without it.
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/subwrap/subversion_extensions.rb
|
43
43
|
- lib/subwrap/subversion.rb
|
44
44
|
- lib/subwrap/svn_command.rb
|
45
|
+
- lib/subwrap/pager.rb
|
45
46
|
- lib/subwrap.rb
|
46
47
|
- test/subversion_extensions_test.rb
|
47
48
|
- test/svn_command_test.rb
|
@@ -85,15 +86,6 @@ dependencies:
|
|
85
86
|
- !ruby/object:Gem::Version
|
86
87
|
version: 0.0.0
|
87
88
|
version:
|
88
|
-
- !ruby/object:Gem::Dependency
|
89
|
-
name: escape
|
90
|
-
version_requirement:
|
91
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
92
|
-
requirements:
|
93
|
-
- - ">"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: 0.0.0
|
96
|
-
version:
|
97
89
|
- !ruby/object:Gem::Dependency
|
98
90
|
name: facets
|
99
91
|
version_requirement:
|