subwrap 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ProjectInfo.rb +3 -3
- data/Readme +16 -2
- data/bin/_subwrap_post_install +0 -0
- data/bin/command_completion_for_subwrap +0 -0
- data/bin/rscm_test +0 -0
- data/bin/subwrap +0 -0
- data/bin/svn +0 -0
- data/lib/subwrap.rb +3 -1
- data/lib/subwrap/subversion.rb +24 -7
- data/lib/subwrap/subversion_extensions.rb +1 -1
- data/lib/subwrap/svn_command.rb +280 -110
- metadata +92 -81
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.5.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"
|
@@ -20,8 +20,8 @@ module Project
|
|
20
20
|
s.platform = Gem::Platform::RUBY
|
21
21
|
s.add_dependency("colored")
|
22
22
|
#s.add_dependency("escape")
|
23
|
-
s.add_dependency("facets")
|
24
|
-
s.add_dependency("quality_extensions")
|
23
|
+
s.add_dependency("facets", '> 2.4.4')
|
24
|
+
s.add_dependency("quality_extensions", '> 1.1.0')
|
25
25
|
s.add_dependency("rscm")
|
26
26
|
s.post_install_message = <<-End
|
27
27
|
---------------------------------------------------------------------------------------------------
|
data/Readme
CHANGED
@@ -102,7 +102,7 @@ New subcommands:
|
|
102
102
|
|
103
103
|
== <tt>svn each_unadded</tt>
|
104
104
|
|
105
|
-
|
105
|
+
This command is useful for keeping your working copies clean -- getting rid of all those accumulated temp files (or *ignoring* or *adding* them if they're something that _all_ users of this repository should be aware of).
|
106
106
|
|
107
107
|
It simply goes through each "unadded" file (each file reporting a status of <tt>?</tt>) reported by <tt>svn status</tt> and asks you what you want to do with them -- *add*, *delete*, or *ignore*.
|
108
108
|
|
@@ -126,7 +126,21 @@ It simply goes through each "unadded" file (each file reporting a status of <tt>
|
|
126
126
|
|
127
127
|
For *files*, it will show a preview of the _contents_ of that file (limited to the first 55 lines); for *directories*, it will show a _directory_ _listing_. By looking at the preview, you should hopefully be able to decide whether you want to _keep_ the file or _junk_ it.
|
128
128
|
|
129
|
-
== <tt>svn
|
129
|
+
== <tt>svn whats_new</tt> (replacement for <tt>svn update</tt>)
|
130
|
+
|
131
|
+
Whereas <tt>svn update</tt> <i>only</i> updates (merges) with the latest changes and shows you which files were updated/etc., <tt>svn whats_new</tt>:
|
132
|
+
* updates (merges) with the latest changes
|
133
|
+
* shows you a summary of which files were updated/added/removed/conflict (:todo:)
|
134
|
+
* shows the commit messages for each change_set [since you last ran this command :todo:]
|
135
|
+
* shows the actual changes (diffs) that were made for every file in the
|
136
|
+
|
137
|
+
It's a lot like <tt>svn browse</tt> (and in fact shares most of the same code with it), except it's <i>non-interactive</i>, so you just run it and then sit back and watch all the pretty output -- which is a good thing, because doing a diff for each changeset can take a long time...
|
138
|
+
|
139
|
+
Tip: When actively working on a project with lots of frequent committers, I like to keep a separate tab open in my terminal where I periodicaly run <tt>svn whats_new</tt>:
|
140
|
+
* to grab the latest changes from everyone else on the team, and
|
141
|
+
* to skim through their changes to see what's changed.
|
142
|
+
|
143
|
+
== <tt>svn browse</tt> (revisions browser)
|
130
144
|
|
131
145
|
Lets you interactively browse through all revisions of a file/directory/repository (one at a time). For each revision, it will ask you what you want to do with it (view the changeset, edit revision properties, etc.).
|
132
146
|
|
data/bin/_subwrap_post_install
CHANGED
File without changes
|
File without changes
|
data/bin/rscm_test
CHANGED
File without changes
|
data/bin/subwrap
CHANGED
File without changes
|
data/bin/svn
CHANGED
File without changes
|
data/lib/subwrap.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# This is the auto-require, which I suppose never gets used any more thanks to RubyGems' annoying change
|
2
|
-
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__))) # This is mainly for development, to make sure the development version is used instead of loading the same file from the installed gem because the gem path happens to be earlier on in the $LOAD_PATH.
|
4
|
+
$LOAD_PATH.uniq!
|
3
5
|
require 'subwrap/subversion'
|
4
6
|
Subversion
|
data/lib/subwrap/subversion.rb
CHANGED
@@ -10,7 +10,7 @@ require 'rubygems'
|
|
10
10
|
gem 'facets'
|
11
11
|
require 'facets/kernel/silence'
|
12
12
|
silence_warnings do
|
13
|
-
require 'facets/kernel/
|
13
|
+
require 'facets/kernel/require_local'
|
14
14
|
require 'facets/kernel/in'
|
15
15
|
require 'facets/enumerable/uniq_by'
|
16
16
|
require 'facets/fileutils/which'
|
@@ -54,6 +54,11 @@ module Subversion
|
|
54
54
|
mattr_accessor :print_commands
|
55
55
|
mguard_method :print_commands!, :@@print_commands
|
56
56
|
|
57
|
+
@@cached_commands = {}
|
58
|
+
@@cached_commands[:latest_revision] = {}
|
59
|
+
|
60
|
+
#-------------------------------------------------------------------------------------------------
|
61
|
+
|
57
62
|
# Adds the given items to the repository. Items may contain wildcards.
|
58
63
|
def self.add(*args)
|
59
64
|
execute "add #{args.join ' '}"
|
@@ -322,18 +327,27 @@ module Subversion
|
|
322
327
|
args = ['./'] if args.empty?
|
323
328
|
execute "log #{args.join(' ')}"
|
324
329
|
end
|
330
|
+
|
325
331
|
# Returns the revision number for head.
|
326
|
-
def self.latest_revision(
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
332
|
+
def self.latest_revision(path = './')
|
333
|
+
(cached = @@cached_commands[:latest_revision][path]) and return cached
|
334
|
+
url = url(path)
|
335
|
+
|
336
|
+
#puts "Fetching latest revision from repository: #{url}"
|
337
|
+
result = latest_revision_for_path(url).to_i
|
338
|
+
@@cached_commands[:latest_revision][path] = result
|
339
|
+
result
|
331
340
|
end
|
341
|
+
|
332
342
|
# Returns the revision number for the working directory(/file?) specified by +path+
|
333
343
|
def self.latest_revision_for_path(path)
|
334
344
|
# The revision returned by svn info seems to be a pretty reliable way to get this. Does anyone know of a better way?
|
335
345
|
matches = info(path).match(/^Revision: (\d+)/)
|
336
|
-
|
346
|
+
if matches
|
347
|
+
matches[1].to_i
|
348
|
+
else
|
349
|
+
raise "Could not extract revision from #{info(path)}"
|
350
|
+
end
|
337
351
|
end
|
338
352
|
|
339
353
|
# Returns an array of RSCM::Revision objects
|
@@ -345,6 +359,7 @@ module Subversion
|
|
345
359
|
args = (['-v'] + args)
|
346
360
|
log_output = Subversion.log(*args)
|
347
361
|
parser = ::RSCM::SubversionLogParser.new(io = StringIO.new(log_output), url = 'http://ignore.me.com')
|
362
|
+
# :todo: svn revisions -r 747 -- chops off line
|
348
363
|
revisions = parser.parse_revisions
|
349
364
|
revisions
|
350
365
|
end
|
@@ -460,7 +475,9 @@ protected
|
|
460
475
|
p command
|
461
476
|
end
|
462
477
|
if Subversion.print_commands
|
478
|
+
#puts '{print'
|
463
479
|
p command
|
480
|
+
#puts '}print'
|
464
481
|
end
|
465
482
|
|
466
483
|
valid_options = [:capture, :exec, :popen]
|
@@ -98,7 +98,7 @@ module Subversion
|
|
98
98
|
if before_externals != ""
|
99
99
|
if options[:files_only]
|
100
100
|
before_externals = before_externals.strip.
|
101
|
-
gsub(/^ ?#{Status_flags.to_regexp_char_class}
|
101
|
+
gsub(/^ ?#{Status_flags.to_regexp_char_class}..... /, '') \
|
102
102
|
+ "\n"
|
103
103
|
else
|
104
104
|
before_externals = before_externals.strip.colorize_svn_status_lines + "\n"
|
data/lib/subwrap/svn_command.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# Tested by: ../../test/svn_command_test.rb
|
2
2
|
|
3
|
+
require File.dirname(__FILE__) + '/../subwrap'
|
4
|
+
|
3
5
|
require 'rubygems'
|
4
6
|
|
5
7
|
require 'facets'
|
6
|
-
#gem 'facets', '>=1.8.51'
|
7
8
|
#require 'facets/more/command' # Not until Facets includes my changes
|
8
9
|
#require 'facets/kernel/load'
|
9
10
|
#require 'facets/kernel/with' # returning
|
@@ -23,6 +24,7 @@ require 'quality_extensions/array/expand_ranges'
|
|
23
24
|
require 'quality_extensions/array/shell_escape'
|
24
25
|
require 'quality_extensions/file_test/binary_file'
|
25
26
|
require 'quality_extensions/console/command'
|
27
|
+
require 'quality_extensions/string/with_knowledge_of_color'
|
26
28
|
require 'quality_extensions/module/attribute_accessors'
|
27
29
|
#require 'quality_extensions/module/class_methods'
|
28
30
|
|
@@ -779,15 +781,14 @@ End
|
|
779
781
|
[:__ignore_externals] => 0,
|
780
782
|
}.merge(SvnCommand::C_standard_remote_command_options), self
|
781
783
|
)
|
782
|
-
def __modified
|
783
|
-
|
784
|
-
end
|
784
|
+
def __modified; @only_statuses << 'M'; end
|
785
|
+
def __added; @only_statuses << 'A'; end
|
786
|
+
def __untracked; @only_statuses << '?'; end
|
787
|
+
def __deleted; @only_statuses << 'D'; end
|
785
788
|
alias_method :_M, :__modified
|
786
|
-
|
787
|
-
def __added
|
788
|
-
@only_statuses << 'A'
|
789
|
-
end
|
790
789
|
alias_method :_A, :__added
|
790
|
+
alias_method :_?, :__untracked
|
791
|
+
alias_method :_D, :__deleted
|
791
792
|
|
792
793
|
#document :__files_only do
|
793
794
|
"Only list filenames, not statuses"
|
@@ -843,6 +844,10 @@ End
|
|
843
844
|
end
|
844
845
|
|
845
846
|
def update(*args)
|
847
|
+
directory = (args[0] ||= './')
|
848
|
+
revision_of_directory = Subversion.latest_revision_for_path(directory)
|
849
|
+
puts "(Note: The working copy '#{directory.white.bold}' was at #{('r' + revision_of_directory.to_s).magenta.bold} before updating...)"
|
850
|
+
|
846
851
|
@passthrough_options << '--ignore-externals' if ignore_externals?
|
847
852
|
Subversion.print_commands! do # Print the commands and options used so they can be reminded that they're using user_preferences['update']['ignore_externals']...
|
848
853
|
puts Subversion.update_lines_filter( Subversion.update(*prepare_args(args)) )
|
@@ -909,6 +914,8 @@ End
|
|
909
914
|
#
|
910
915
|
# Pass in a list of revisions/revision ranges ("134", "134:136", "134-136", and "134-136 139" are all valid)
|
911
916
|
#
|
917
|
+
# :todo: How is this different from whats_new?
|
918
|
+
#
|
912
919
|
module ViewCommits
|
913
920
|
def _r(*revisions)
|
914
921
|
# This is necessary so that the -r option doesn't accidentally eat up an arg that wasn't meant to be a revision (a filename, for instance). The only problem with this is if there's actully a filename that matches these patterns! (But then we could just re-order ars.)
|
@@ -1360,16 +1367,6 @@ End
|
|
1360
1367
|
raise NotImplementedError
|
1361
1368
|
end
|
1362
1369
|
|
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
1370
|
#-----------------------------------------------------------------------------------------------------------------------------
|
1374
1371
|
# :todo: Pre-fetch svn diff in the background (fork the process) so you don't have to wait, in interactive mode.
|
1375
1372
|
# :todo: When calling this command on a single file,
|
@@ -1378,7 +1375,7 @@ End
|
|
1378
1375
|
# :todo: add number aliases (1) for view changeset, etc. so you can use numpad exclusively
|
1379
1376
|
# :todo: rename interactive mode to different name, s.a. browse_revisions
|
1380
1377
|
# Add --grep option to non-interactively search all changesets returned for a pattern.
|
1381
|
-
module
|
1378
|
+
module ShowOrBrowseRevisions
|
1382
1379
|
# We will pass all of these options through to 'svn log'
|
1383
1380
|
Console::Command.pass_through({
|
1384
1381
|
[:_q, :__quiet] => 0,
|
@@ -1387,7 +1384,7 @@ End
|
|
1387
1384
|
[:__stop_on_copy] => 0,
|
1388
1385
|
[:__incremental] => 0,
|
1389
1386
|
[:__xml] => 0,
|
1390
|
-
[:__limit] => 1,
|
1387
|
+
#[:__limit] => 1,
|
1391
1388
|
}.merge(SvnCommand::C_standard_remote_command_options), self
|
1392
1389
|
)
|
1393
1390
|
|
@@ -1405,17 +1402,35 @@ End
|
|
1405
1402
|
alias_method :_r, :__revision
|
1406
1403
|
|
1407
1404
|
#-------------------------------------------------------------------------
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1405
|
+
def __all
|
1406
|
+
@first_revision = '1'
|
1407
|
+
@last_revision = 'head'
|
1408
|
+
@oldest_first_default = false
|
1409
|
+
@limit = false
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
def __limit(limit)
|
1413
|
+
@limit = limit
|
1414
|
+
end
|
1415
|
+
|
1413
1416
|
def __since_last_update
|
1414
|
-
@
|
1415
|
-
@
|
1417
|
+
@first_revision = '%base%'
|
1418
|
+
@last_revision = 'head'
|
1419
|
+
@oldest_first_default = true
|
1416
1420
|
end
|
1417
1421
|
alias_method :__from_base, :__since_last_update
|
1418
1422
|
alias_method :__since_base, :__since_last_update
|
1423
|
+
|
1424
|
+
# :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.
|
1425
|
+
# Possible solution:
|
1426
|
+
# :todo: 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.
|
1427
|
+
# (Or maybe .svn has a record of the previous update time somewhere that we can pick up?)
|
1428
|
+
#
|
1429
|
+
def __whats_new
|
1430
|
+
@first_revision = '%base%'
|
1431
|
+
@last_revision = 'head'
|
1432
|
+
@oldest_first_default = true
|
1433
|
+
end
|
1419
1434
|
alias_method :__new, :__since_last_update
|
1420
1435
|
alias_method :__whats_new, :__since_last_update
|
1421
1436
|
|
@@ -1425,14 +1440,23 @@ End
|
|
1425
1440
|
# Use chronic?
|
1426
1441
|
# :todo:
|
1427
1442
|
def __from(revision)
|
1428
|
-
@
|
1429
|
-
@
|
1443
|
+
@first_revision = revision
|
1444
|
+
@last_revision = 'head'
|
1445
|
+
@oldest_first_default = true
|
1430
1446
|
end
|
1431
1447
|
alias_method :__since, :__from
|
1432
1448
|
|
1433
1449
|
def __back_to(revision)
|
1434
|
-
@
|
1435
|
-
@
|
1450
|
+
@first_revision = revision
|
1451
|
+
@last_revision = 'head'
|
1452
|
+
@oldest_first_default = false
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
# :todo: if they're not at the root of the repo, this may not give them what they want
|
1456
|
+
# they may want the last revisions for a specific file, in which case the latest_revision will likely not be the right revision number
|
1457
|
+
def __last(revision_count)
|
1458
|
+
@first_revision = Subversion.latest_revision - revision_count.to_i + 1
|
1459
|
+
@last_revision = Subversion.latest_revision
|
1436
1460
|
end
|
1437
1461
|
|
1438
1462
|
#-------------------------------------------------------------------------
|
@@ -1455,14 +1479,14 @@ End
|
|
1455
1479
|
#-------------------------------------------------------------------------
|
1456
1480
|
# Start at earlier revision and go forwards rather than starting at the latest revision
|
1457
1481
|
def __oldest_first
|
1458
|
-
@
|
1482
|
+
@oldest_first = true
|
1459
1483
|
end
|
1460
1484
|
alias_method :__forward, :__oldest_first
|
1461
1485
|
alias_method :__forwards, :__oldest_first
|
1462
1486
|
alias_method :__chronological, :__oldest_first
|
1463
1487
|
|
1464
1488
|
def __newest_first
|
1465
|
-
@
|
1489
|
+
@oldest_first = false
|
1466
1490
|
end
|
1467
1491
|
alias_method :__reverse, :__newest_first
|
1468
1492
|
alias_method :__backwards, :__newest_first
|
@@ -1476,6 +1500,10 @@ End
|
|
1476
1500
|
end
|
1477
1501
|
alias_method :__ni, :__non_interactive
|
1478
1502
|
|
1503
|
+
def __paged
|
1504
|
+
@paged = true
|
1505
|
+
end
|
1506
|
+
|
1479
1507
|
def __interactive
|
1480
1508
|
@interactive = true
|
1481
1509
|
end
|
@@ -1497,70 +1525,169 @@ End
|
|
1497
1525
|
end
|
1498
1526
|
end
|
1499
1527
|
# :todo: what if they pass in *2* filenames?
|
1500
|
-
|
1501
|
-
|
1528
|
+
# See also: the implementation of revisions() in /usr/lib/ruby/gems/1.8/gems/rscm-0.5.1/lib/rscm/scm/subversion.rb
|
1529
|
+
|
1530
|
+
module Revisions
|
1531
|
+
def self.extended(base)
|
1532
|
+
base.extend ShowOrBrowseRevisions
|
1533
|
+
end
|
1534
|
+
end
|
1535
|
+
def play_revisions(directory = './')
|
1536
|
+
@interactive = false
|
1537
|
+
show_or_browse_revisions(directory)
|
1538
|
+
end
|
1539
|
+
alias_subcommand :changesets => :revisions
|
1540
|
+
alias_subcommand :show_log => :revisions
|
1541
|
+
alias_subcommand :show_revisions => :revisions
|
1542
|
+
alias_subcommand :show_changesets => :revisions
|
1543
|
+
|
1544
|
+
module Browse
|
1545
|
+
def self.extended(base)
|
1546
|
+
base.extend ShowOrBrowseRevisions
|
1547
|
+
end
|
1548
|
+
end
|
1549
|
+
def browse(directory = './')
|
1550
|
+
@interactive = true
|
1551
|
+
show_or_browse_revisions(directory)
|
1552
|
+
end
|
1553
|
+
alias_subcommand :revisions => :browse
|
1554
|
+
alias_subcommand :browse => :browse
|
1555
|
+
alias_subcommand :browse_log => :browse
|
1556
|
+
alias_subcommand :browse_revisions => :browse
|
1557
|
+
alias_subcommand :browse_changesets => :browse
|
1558
|
+
# Other so-far-rejected name ideas: list_commits, changeset_browser, log_browser, interactive_log
|
1559
|
+
|
1560
|
+
# This is designed to be a convenient replacement to the svn update command for those who wish to not only see a *list* of
|
1561
|
+
# which files were updated as the update occurs but also wish to see *what changed* for each of those files.
|
1562
|
+
# So this command will effectively do a diff on each updated file and show you what has changed (= "what's new").
|
1563
|
+
#
|
1564
|
+
# Should this command run an update or do people want to run this command after an update??
|
1565
|
+
# Nah... an update can be really slow... and they may have just done one...
|
1566
|
+
module WhatsNew
|
1567
|
+
def self.extended(base)
|
1568
|
+
base.extend ShowOrBrowseRevisions
|
1569
|
+
end
|
1570
|
+
end
|
1571
|
+
def whats_new(directory = './')
|
1572
|
+
revision_of_directory = Subversion.latest_revision_for_path(directory)
|
1573
|
+
|
1574
|
+
#__whats_new
|
1575
|
+
# (allow this to be overriden with, for example, a --since option)
|
1576
|
+
@first_revision_default = revision_of_directory.to_s
|
1577
|
+
@last_revision_default = 'head'
|
1578
|
+
@oldest_first_default = true
|
1579
|
+
|
1580
|
+
#puts "Updating..."
|
1581
|
+
#Subversion.update(directory) # silent
|
1582
|
+
#Subversion.execute("update")
|
1502
1583
|
|
1584
|
+
@interactive = false
|
1585
|
+
show_or_browse_revisions(directory)
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
#-------------------------------------------------------------------------
|
1589
|
+
protected
|
1590
|
+
def show_or_browse_revisions(directory = './')
|
1503
1591
|
#-----------------------------
|
1504
1592
|
head = Subversion.latest_revision
|
1505
1593
|
revision_of_directory = Subversion.latest_revision_for_path(directory)
|
1506
1594
|
|
1507
|
-
#
|
1508
|
-
#
|
1509
|
-
#
|
1595
|
+
# By default, if you just do an svn log (which is what we do to get the metadata about each revision), svn will only show revisions up to and Last Changed Rev.
|
1596
|
+
# So if there have been newer revisions since then, it won't show the log messages for them.
|
1597
|
+
# I can't think of a good reason why it shouldn't. I think it's a bug in the svn client.
|
1598
|
+
#
|
1599
|
+
# Also, it's possible for the Last Changed Rev of to be "out of date" even if you were the last committer!
|
1600
|
+
# If you commit file lib/foo.rb, the Last Changed Rev of lib/foo.rb may be 13 but the Last Changed Rev of . will still be 10 until you update '.'.
|
1601
|
+
# In other words each *directory* has a different Last Changed Rev.
|
1602
|
+
#
|
1603
|
+
# Anyway, to work around this bug, we explicitly get the head revision number from the server and pass that as the ending revision number to svn log.
|
1604
|
+
# So in our example, we would pass -r 1:13 to svn log even when doing `svn browse .`, to ensure that we get information for all revisions
|
1605
|
+
# all the way up to head (13).
|
1606
|
+
#
|
1607
|
+
# :todo: do the same for svn log
|
1510
1608
|
if revision_of_directory and head and revision_of_directory < head
|
1511
|
-
puts "The working copy '#{directory.white.bold}' appears to be out-of-date (#{revision_of_directory}) with respect to the head revision (#{head}).
|
1512
|
-
Subversion.update(directory)
|
1609
|
+
puts "The working copy '#{directory.white.bold}' appears to be out-of-date (#{revision_of_directory.to_s.magenta.bold}) with respect to the head revision (#{head.to_s.magenta.bold}). Just so ya know..."
|
1610
|
+
#Subversion.update(directory)
|
1513
1611
|
end
|
1514
1612
|
#-----------------------------
|
1515
1613
|
|
1516
1614
|
args = [directory]
|
1517
|
-
|
1518
|
-
|
1519
|
-
@
|
1520
|
-
|
1615
|
+
|
1616
|
+
unless @revisions
|
1617
|
+
@first_revision_default ||= '1' #'%base%'
|
1618
|
+
@last_revision_default ||= 'head'
|
1619
|
+
|
1620
|
+
@first_revision ||= @first_revision_default
|
1621
|
+
@last_revision ||= @last_revision_default
|
1622
|
+
#@first_revision, @last_revision = @last_revision, @first_revision if @oldest_first
|
1623
|
+
@revisions = "#{@first_revision}:#{@last_revision}"
|
1521
1624
|
end
|
1625
|
+
@revisions.gsub! /%base%/, revision_of_directory.to_s
|
1626
|
+
args.concat ['-r', @revisions]
|
1522
1627
|
|
1523
|
-
@
|
1524
|
-
@
|
1628
|
+
@limit_default = nil #10
|
1629
|
+
@limit = @limit_default if @limit.nil? and @limit_default
|
1630
|
+
args.concat ['--limit', @limit_default.to_s] if @limit
|
1631
|
+
|
1632
|
+
@oldest_first_default = true if @oldest_first_default.nil?
|
1633
|
+
@oldest_first = @oldest_first_default if @oldest_first.nil?
|
1525
1634
|
|
1526
1635
|
@show_diffs ||= true if !@interactive
|
1527
1636
|
@show_diffs_default ||= false
|
1528
1637
|
@show_diffs ||= @show_diffs_default
|
1529
1638
|
|
1530
1639
|
if @show_file_list.nil?
|
1531
|
-
if directory
|
1532
|
-
@show_file_list = false
|
1533
|
-
else
|
1640
|
+
if directory == './' # They are using the default directory
|
1534
1641
|
@show_file_list = true
|
1642
|
+
else
|
1643
|
+
@show_file_list = false
|
1535
1644
|
end
|
1536
1645
|
end
|
1537
1646
|
|
1538
|
-
|
1647
|
+
#puts "@interactive=#{@interactive}"
|
1648
|
+
#puts "@oldest_first=#{@oldest_first}"
|
1649
|
+
#puts "@revisions=#{@revisions}"
|
1650
|
+
#pp prepare_args(args)
|
1539
1651
|
|
1540
1652
|
#-----------------------------
|
1541
|
-
#
|
1542
|
-
|
1653
|
+
puts "Getting revision details for '#{directory.green.bold}', revisions #{@revisions.magenta.bold} #{"(up to #{@limit} of them) " if @limit}(this may take a moment) ..."
|
1654
|
+
#require 'unroller'
|
1655
|
+
#Unroller.trace :dir_match => __FILE__ do
|
1656
|
+
#Subversion.print_commands! do
|
1657
|
+
revisions = Subversion.revisions(*prepare_args(args))
|
1658
|
+
#end
|
1659
|
+
#end
|
1543
1660
|
|
1544
|
-
|
1545
|
-
|
1546
|
-
revisions.
|
1661
|
+
#-----------------------------
|
1662
|
+
run_pager if !@interactive and @paged
|
1663
|
+
puts "#{revisions.length.to_s.bold} revisions found. Starting with #{(@oldest_first ? 'oldest' : 'most recent').white.bold} revision and #{@oldest_first ? 'going forward in time' : 'going backward in time' }..."
|
1664
|
+
#pp revisions.map {|r| [r.identifier, r.time]}
|
1665
|
+
revisions.instance_variable_get(:@revisions).reverse! unless @oldest_first # :todo: or just swap first and last when building @revisions? no, I think there are some cases when that wouldn't work...
|
1547
1666
|
revision_ids = revisions.map(&:identifier)
|
1548
1667
|
|
1549
1668
|
#-----------------------------------------------------------------------
|
1550
1669
|
# The main loop through the array of revisions
|
1551
|
-
|
1670
|
+
#revisions.each do |revision|
|
1671
|
+
i = 0
|
1672
|
+
#target_rev = nil # revision_ids.first
|
1552
1673
|
show_revision = true
|
1674
|
+
show_menu = true
|
1675
|
+
revision = revisions[i]
|
1676
|
+
begin # rescue
|
1677
|
+
loop do
|
1678
|
+
show_revision = false if show_menu == false
|
1553
1679
|
|
1554
|
-
revisions.each do |revision|
|
1555
1680
|
rev = revision.identifier
|
1556
1681
|
other_rev = rev-1
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1682
|
+
counter = revision_ids.index(rev) + 1
|
1683
|
+
|
1684
|
+
#if target_rev
|
1685
|
+
# if rev == target_rev
|
1686
|
+
# target_rev = nil # We have arrived.
|
1687
|
+
# else
|
1688
|
+
# next # Keep going (hopefully in the right direction!)
|
1689
|
+
# end
|
1690
|
+
#end
|
1564
1691
|
|
1565
1692
|
#-----------------------------------------------------------------------
|
1566
1693
|
show_diffs = proc {
|
@@ -1568,7 +1695,7 @@ End
|
|
1568
1695
|
#puts "\n"*10
|
1569
1696
|
puts
|
1570
1697
|
puts((' '*100).green.underline)
|
1571
|
-
print "Diffing #{revs_to_compare.min}:#{revs_to_compare.max}... ".bold
|
1698
|
+
print "Diffing #{revs_to_compare.min.to_s.magenta.bold}:#{revs_to_compare.max.to_s.magenta.bold}... ".bold
|
1572
1699
|
puts
|
1573
1700
|
#Subversion.repository_root
|
1574
1701
|
#Subversion.print_commands! do
|
@@ -1579,14 +1706,15 @@ End
|
|
1579
1706
|
#-----------------------------------------------------------------------
|
1580
1707
|
# Display the revision (number, date, description, files changed)
|
1581
1708
|
if show_revision
|
1582
|
-
|
1583
1709
|
#puts((' '*100).green.underline)
|
1584
1710
|
puts
|
1585
|
-
puts((' '*100).on_green)
|
1711
|
+
#puts((' '*100).on_green)
|
1586
1712
|
|
1587
|
-
puts "#{revisions.length - revision_ids.index(rev)}. ".green.bold +
|
1588
|
-
|
1589
|
-
|
1713
|
+
#puts "#{revisions.length - revision_ids.index(rev)}. ".green.bold +
|
1714
|
+
puts (
|
1715
|
+
"r#{rev}".white.bold.on_green + (rev == head ? ' (head)'.bold.on_green : '') +
|
1716
|
+
" | #{revision.developer} | #{revision.time.strftime('%Y-%m-%d %H:%M:%S')}".white.bold.on_green
|
1717
|
+
).ljust_with_color(100, ' '.on_green)
|
1590
1718
|
puts revision.message
|
1591
1719
|
puts
|
1592
1720
|
#pp revision
|
@@ -1605,32 +1733,28 @@ End
|
|
1605
1733
|
show_diffs.call
|
1606
1734
|
end
|
1607
1735
|
|
1608
|
-
#-----------------------------------------------------------------------
|
1609
|
-
# Display the menu
|
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
|
1625
1736
|
|
1626
1737
|
#-----------------------------------------------------------------------
|
1627
1738
|
# Get response from user and then act on it
|
1628
|
-
|
1739
|
+
go = nil
|
1740
|
+
catch :prev_or_next do
|
1741
|
+
loop do
|
1742
|
+
go = :nowhere
|
1743
|
+
|
1744
|
+
#-----------------------------------------------------------------------
|
1745
|
+
# Display the menu
|
1746
|
+
if @interactive and show_menu
|
1747
|
+
print "r#{rev}".magenta.on_blue.bold + " (#{counter}/#{revisions.length})" + " (#{'?'.bold} for help)" + ' > '
|
1748
|
+
end
|
1749
|
+
|
1750
|
+
#-----------------------------------------------------------------------
|
1629
1751
|
if @interactive
|
1630
1752
|
response = ""
|
1631
1753
|
response = $stdin.getch.downcase
|
1632
1754
|
else
|
1633
|
-
response = "\n"
|
1755
|
+
#response = "\n"
|
1756
|
+
go = :next
|
1757
|
+
throw :prev_or_next
|
1634
1758
|
end
|
1635
1759
|
|
1636
1760
|
# Escape sequence such as the up arrow key ("\e[A")
|
@@ -1649,6 +1773,25 @@ End
|
|
1649
1773
|
end
|
1650
1774
|
|
1651
1775
|
case response
|
1776
|
+
|
1777
|
+
when '?' # Help
|
1778
|
+
show_menu = false
|
1779
|
+
puts
|
1780
|
+
puts(
|
1781
|
+
'View this changeset'.menu_item(:cyan) + ', ' +
|
1782
|
+
'Diff against specific revision'.menu_item(:cyan, 'D') + ', ' +
|
1783
|
+
'Grep the changeset'.menu_item(:cyan, 'G') + ', ' +
|
1784
|
+
'List or '.menu_item(:magenta, 'L') + '' +
|
1785
|
+
'Edit revision properties'.menu_item(:magenta, 'E') + ', ' +
|
1786
|
+
'svn Cat all files'.menu_item(:cyan, 'C') + ', ' +
|
1787
|
+
'grep the cat'.menu_item(:cyan, 'a') + ', ' + "\n " +
|
1788
|
+
'mark as Reviewed'.menu_item(:green, 'R') + ', ' +
|
1789
|
+
'edit log Message'.menu_item(:yellow, 'M') + ', ' +
|
1790
|
+
'browse using ' + 'Up/Down/Left/Right/Space/Enter'.white.bold + ' keys' + ', ' +
|
1791
|
+
'Quit'.menu_item(:magenta)
|
1792
|
+
)
|
1793
|
+
show_revision = false # only show the menu
|
1794
|
+
|
1652
1795
|
when '1', 'v' # View this changeset
|
1653
1796
|
show_diffs.call
|
1654
1797
|
show_revision = false # only show the menu
|
@@ -1755,42 +1898,69 @@ End
|
|
1755
1898
|
end
|
1756
1899
|
show_revision = false
|
1757
1900
|
|
1758
|
-
when "\e[A" # Up
|
1759
|
-
i = revision_ids.index(rev)
|
1760
|
-
target_rev = revision_ids[i - 1]
|
1901
|
+
when "\e[A", "\e\[D" # Previous (Up or Left)
|
1902
|
+
#i = revision_ids.index(rev)
|
1903
|
+
#target_rev = revision_ids[i - 1]
|
1761
1904
|
puts " Previous..."
|
1762
|
-
|
1905
|
+
go = :prev
|
1906
|
+
throw :prev_or_next
|
1907
|
+
#retry
|
1763
1908
|
|
1764
|
-
|
1765
|
-
when /\n|\e\[B| / # Enter or Down or Space
|
1909
|
+
when "\n", "\e\[B", "\e\[C", " " # Next (Enter or Down or Right or Space)
|
1766
1910
|
# Skip / Do nothing with this file
|
1767
1911
|
puts " Next..."
|
1768
|
-
|
1769
|
-
|
1912
|
+
go = :next
|
1913
|
+
throw :prev_or_next
|
1914
|
+
#next
|
1915
|
+
|
1916
|
+
when 'q' # Quit
|
1917
|
+
raise Interrupt, "Quitting"
|
1770
1918
|
|
1771
1919
|
else
|
1772
1920
|
# Invalid option. Do nothing.
|
1773
1921
|
#puts response.inspect
|
1774
1922
|
puts
|
1923
|
+
show_menu = false
|
1775
1924
|
show_revision = false
|
1776
1925
|
|
1777
1926
|
end # case response
|
1778
1927
|
|
1779
|
-
|
1928
|
+
end # loop until they tell us they're ready to move on...
|
1929
|
+
end # catch :prev_or_next
|
1780
1930
|
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1931
|
+
case go
|
1932
|
+
when :prev
|
1933
|
+
if i-1 < 0
|
1934
|
+
show_menu = false
|
1935
|
+
puts "Can't go back -- already at first revision in set!".red
|
1936
|
+
else
|
1937
|
+
show_menu = show_revision = true
|
1938
|
+
i -= 1
|
1939
|
+
end
|
1940
|
+
when :next
|
1941
|
+
if i+1 > revisions.length-1
|
1942
|
+
# We've reached the end
|
1943
|
+
if @interactive
|
1944
|
+
show_menu = false
|
1945
|
+
puts "Can't go forward -- already at last revision in set!".red
|
1946
|
+
else
|
1947
|
+
break
|
1948
|
+
end
|
1949
|
+
else
|
1950
|
+
show_menu = show_revision = true
|
1951
|
+
i += 1
|
1952
|
+
end
|
1953
|
+
end
|
1954
|
+
revision = revisions[i]
|
1955
|
+
|
1956
|
+
end # loop / revisions.each
|
1957
|
+
|
1958
|
+
rescue Interrupt
|
1959
|
+
puts "\nGoodbye!"
|
1960
|
+
return
|
1961
|
+
end # rescue
|
1786
1962
|
end
|
1787
|
-
|
1788
|
-
alias_subcommand :browse => :revisions
|
1789
|
-
alias_subcommand :browse_log => :revisions
|
1790
|
-
alias_subcommand :browse_revisions => :revisions
|
1791
|
-
alias_subcommand :browse_changesets => :revisions
|
1792
|
-
# See also the implementation of revisions() in /usr/lib/ruby/gems/1.8/gems/rscm-0.5.1/lib/rscm/scm/subversion.rb
|
1793
|
-
# Other name ideas: browse, list_commits, changeset_browser, log_browser, interactive_log
|
1963
|
+
public
|
1794
1964
|
|
1795
1965
|
#-----------------------------------------------------------------------------------------------------------------------------
|
1796
1966
|
# Aliases
|
metadata
CHANGED
@@ -1,115 +1,126 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
4
2
|
name: subwrap
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2008-06-19 00:00:00 -07:00
|
8
|
-
summary: A nifty wrapper command for Subversion's command-line svn client
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: rubyforge.org@tylerrick.com
|
12
|
-
homepage: http://subwrap.rubyforge.org/
|
13
|
-
rubyforge_project: subwrap
|
14
|
-
description: This is a wrapper command for Subversion's command-line svn client that adds a few new subcommands.
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: 0.5.0
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message: |
|
29
|
-
---------------------------------------------------------------------------------------------------
|
30
|
-
You should now be able to run the subwrap command.
|
31
|
-
|
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
|
-
|
35
|
-
Also, it is recommended that you install the termios gem so that you don't have to press enter
|
36
|
-
after selecting an option from the menu, but it will work without it.
|
37
|
-
---------------------------------------------------------------------------------------------------
|
38
|
-
|
39
6
|
authors:
|
40
7
|
- Tyler Rick
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
- lib/subwrap/svn_command.rb
|
45
|
-
- lib/subwrap/pager.rb
|
46
|
-
- lib/subwrap.rb
|
47
|
-
- test/subversion_extensions_test.rb
|
48
|
-
- test/svn_command_test.rb
|
49
|
-
- test/subversion_test.rb
|
50
|
-
- test/test_helper.rb
|
51
|
-
- bin/subwrap
|
52
|
-
- bin/rscm_test
|
53
|
-
- bin/command_completion_for_subwrap
|
54
|
-
- bin/svn
|
55
|
-
- bin/_subwrap_post_install
|
56
|
-
- ProjectInfo.rb
|
57
|
-
- Readme
|
58
|
-
test_files:
|
59
|
-
- test/subversion_extensions_test.rb
|
60
|
-
- test/svn_command_test.rb
|
61
|
-
- test/subversion_test.rb
|
62
|
-
- test/test_helper.rb
|
63
|
-
rdoc_options:
|
64
|
-
- --title
|
65
|
-
- subwrap
|
66
|
-
- --main
|
67
|
-
- Readme
|
68
|
-
- --line-numbers
|
69
|
-
extra_rdoc_files:
|
70
|
-
- Readme
|
71
|
-
executables:
|
72
|
-
- command_completion_for_subwrap
|
73
|
-
- _subwrap_post_install
|
74
|
-
- subwrap
|
75
|
-
extensions: []
|
76
|
-
|
77
|
-
requirements: []
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
78
11
|
|
12
|
+
date: 2008-09-17 00:00:00 -07:00
|
13
|
+
default_executable:
|
79
14
|
dependencies:
|
80
15
|
- !ruby/object:Gem::Dependency
|
81
16
|
name: colored
|
17
|
+
type: :runtime
|
82
18
|
version_requirement:
|
83
|
-
version_requirements: !ruby/object:Gem::
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
84
20
|
requirements:
|
85
|
-
- - "
|
21
|
+
- - ">="
|
86
22
|
- !ruby/object:Gem::Version
|
87
|
-
version: 0
|
23
|
+
version: "0"
|
88
24
|
version:
|
89
25
|
- !ruby/object:Gem::Dependency
|
90
26
|
name: facets
|
27
|
+
type: :runtime
|
91
28
|
version_requirement:
|
92
|
-
version_requirements: !ruby/object:Gem::
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
30
|
requirements:
|
94
31
|
- - ">"
|
95
32
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
33
|
+
version: 2.4.4
|
97
34
|
version:
|
98
35
|
- !ruby/object:Gem::Dependency
|
99
36
|
name: quality_extensions
|
37
|
+
type: :runtime
|
100
38
|
version_requirement:
|
101
|
-
version_requirements: !ruby/object:Gem::
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
40
|
requirements:
|
103
41
|
- - ">"
|
104
42
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
43
|
+
version: 1.1.0
|
106
44
|
version:
|
107
45
|
- !ruby/object:Gem::Dependency
|
108
46
|
name: rscm
|
47
|
+
type: :runtime
|
109
48
|
version_requirement:
|
110
|
-
version_requirements: !ruby/object:Gem::
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
50
|
requirements:
|
112
|
-
- - "
|
51
|
+
- - ">="
|
113
52
|
- !ruby/object:Gem::Version
|
114
|
-
version: 0
|
53
|
+
version: "0"
|
115
54
|
version:
|
55
|
+
description: This is a wrapper command for Subversion's command-line svn client that adds a few new subcommands.
|
56
|
+
email: rubyforge.org@tylerrick.com
|
57
|
+
executables:
|
58
|
+
- command_completion_for_subwrap
|
59
|
+
- _subwrap_post_install
|
60
|
+
- subwrap
|
61
|
+
extensions: []
|
62
|
+
|
63
|
+
extra_rdoc_files:
|
64
|
+
- Readme
|
65
|
+
files:
|
66
|
+
- lib/subwrap/subversion_extensions.rb
|
67
|
+
- lib/subwrap/subversion.rb
|
68
|
+
- lib/subwrap/svn_command.rb
|
69
|
+
- lib/subwrap/pager.rb
|
70
|
+
- lib/subwrap.rb
|
71
|
+
- test/subversion_extensions_test.rb
|
72
|
+
- test/svn_command_test.rb
|
73
|
+
- test/subversion_test.rb
|
74
|
+
- test/test_helper.rb
|
75
|
+
- bin/subwrap
|
76
|
+
- bin/rscm_test
|
77
|
+
- bin/command_completion_for_subwrap
|
78
|
+
- bin/svn
|
79
|
+
- bin/_subwrap_post_install
|
80
|
+
- ProjectInfo.rb
|
81
|
+
- Readme
|
82
|
+
has_rdoc: true
|
83
|
+
homepage: http://subwrap.rubyforge.org/
|
84
|
+
post_install_message: |
|
85
|
+
---------------------------------------------------------------------------------------------------
|
86
|
+
You should now be able to run the subwrap command.
|
87
|
+
|
88
|
+
IMPORTANT: If you want to replace the normal svn command with subwrap, please run
|
89
|
+
sudo `which _subwrap_post_install` or check the Readme to find out how to manually add it to your path.
|
90
|
+
|
91
|
+
Also, it is recommended that you install the termios gem so that you don't have to press enter
|
92
|
+
after selecting an option from the menu, but it will work without it.
|
93
|
+
---------------------------------------------------------------------------------------------------
|
94
|
+
|
95
|
+
rdoc_options:
|
96
|
+
- --title
|
97
|
+
- subwrap
|
98
|
+
- --main
|
99
|
+
- Readme
|
100
|
+
- --line-numbers
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: "0"
|
108
|
+
version:
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: "0"
|
114
|
+
version:
|
115
|
+
requirements: []
|
116
|
+
|
117
|
+
rubyforge_project: subwrap
|
118
|
+
rubygems_version: 1.2.0
|
119
|
+
signing_key:
|
120
|
+
specification_version: 2
|
121
|
+
summary: A nifty wrapper command for Subversion's command-line svn client
|
122
|
+
test_files:
|
123
|
+
- test/subversion_extensions_test.rb
|
124
|
+
- test/svn_command_test.rb
|
125
|
+
- test/subversion_test.rb
|
126
|
+
- test/test_helper.rb
|