1#!/usr/bin/perl 2# Copyright (C) 2008-2009, Mark Glines. See "LICENSE". 3use strict; 4use warnings; 5 6use App::SVN::Bisect; 7use Getopt::Long qw(:config require_order); 8 9my $min = undef; 10my $max = undef; 11my $back = 0; 12my $verbose = 0; 13my $help = 0; 14my $version = 0; 15 16GetOptions( 17 "min=s" => \$min, 18 "max=s" => \$max, 19 "back" => \$back, 20 "verbose" => \$verbose, 21 "version" => \$version, 22 "help" => \$help, 23); 24 25die("Value \"$min\" invalid for option min (revision expected)\n") 26 if(defined($min) && $min !~ /^r?\d+$/); 27die("Value \"$max\" invalid for option min (revision expected)\n") 28 if(defined($max) && $max !~ /^r?\d+$/); 29 30if($version) { 31 print("This is svn-bisect version ", $App::SVN::Bisect::VERSION, ".\n"); 32 exit(0); 33} 34 35unshift(@ARGV, "help") if $help; 36 37my $action = shift; 38 39my $bisect = App::SVN::Bisect->new( 40 Action => $action, 41 Min => $min, 42 Max => $max, 43 Verbose => $verbose, 44 Back => $back 45); 46$bisect->do_something_intelligent(@ARGV); 47 48 49=head1 NAME 50 51svn-bisect 52 53=head1 SYNOPSIS 54 55 $ svn-bisect --min 25000 --max 26000 start 56 $ svn-bisect bad 57 $ svn-bisect bad 58 $ svn-bisect good 59 [etc etc] 60 $ svn-bisect reset 61 62 63=head1 DESCRIPTION 64 65This tool's purpose is to help you determine which revision of a subversion 66repository contains a change. It does this by employing a binary search. 67It will manage the current revision of your checkout directory, and narrow 68in on the target revision, as you give it clues about the current revision 69such as "before" (this revision is before the one you want) or "after" (this 70revision is after the one you want). 71 72Start a bisect session with the "start" command. Then, walk the binary tree 73by using the "before" and "after" commands. When you are done, the tool will 74tell you the target revision. 75 76The most common usage scenario is finding out which rev a bug was introduced 77in. For this purpose, some command aliases have been added: if the current 78revision contains the bug, you can use the "bad" command (meaning, this 79revision is "after" the change you want to find), otherwise use the "good" 80command (meaning, this revision is "before" the change you want to find). 81 82All commands should be run from within a subversion checkout directory. After 83a "svn-bisect start", all subsequent svn-bisect commands need to be run from 84that same directory. 85 86 87=head1 OPTIONS 88 89Options MUST be specified before subcommands, on the command line. Options 90specified after the subcommand will be passed to the subcommand; this is 91currently only useful for the "run" subcommand. 92 93=over 4 94 95=item --help 96 97Use anywhere. Output a command list, or specific help for the given command. 98 99=item --version 100 101Use anywhere. Tells you my version number. 102 103=item --verbose 104 105Use anywhere. Enable some additional informational output. 106 107=item --min 108 109Use with "start". Specify the beginning revision of the range. 110 111=item --max 112 113Use with "start". Specify the ending revision of the range. 114 115=item --back 116 117Use with "reset". Restores the original repository version. 118 119=back 120 121 122=head1 SUBCOMMANDS 123 124=head2 start 125 126 svn-bisect [--min M] [--max N] start 127 128Start a new bisect session. If --min isn't specified, you can specify it later 129with the "good" command. If --max isn't specified, you can specify it later 130with the "bad" command. 131 132=head2 after 133 134 svn-bisect after [revision] 135 or: svn-bisect bad [revision] 136 137Inform svn-bisect that the specified revision is *after* the change we're 138looking for. If you don't specify a revision number, the current revision of 139the working tree is used. If you are looking for the rev which introduced a bug 140(which is the common case), the alias "bad" might be easier to remember. 141 142=head2 before 143 144 svn-bisect before [revision] 145 or: svn-bisect good [revision] 146 147Inform svn-bisect that the specified revision is *before* the change we're 148looking for. If you don't specify a revision number, the current revision of 149the working tree is used. If you are looking for the rev which introduced a bug 150(which is the common case), the alias "good" might be easier to remember. 151 152=head2 skip 153 154 svn-bisect skip [<rev> [<rev>...]] 155 156Tell svn-bisect to skip the specified revision. If no revision is specified, 157the current version of the working tree is used. Do this if you can't determine 158whether the current revision is bad or good, if, for instance, some other 159issue prevents it from compiling successfully. 160 161You may specify more than one revision, and they will all be skipped. 162 163=head2 unskip 164 165 svn-bisect unskip <rev> [<rev>...] 166 167Tell svn-bisect to no longer skip the specified revision. You must specify 168at least one revision to unskip. If you specify more than one, they will 169all be unskipped. 170 171=head2 run 172 173 svn-bisect run <command> [arguments...] 174 175Runs a command repeatedly to automate the bisection process. 176 177Examples: 178 179 svn-bisect run ./mytest.sh 180 svn-bisect run test ! -f file 181 182We run the command and arguments until a conclusion is reached. The 183command (usually a shell script) tells us about the current revision 184by way of its return code. The following return codes are handled: 185 186 0: This revision is before the change we're looking for 187 1-124, 126-127: This revision includes the change we're looking for 188 125: This revision is untestable and should be skipped 189 any other value: The command failed to run, abort bisection. 190 191In other words, "run" will automatically find the last revision for 192which the given command returns success. (Keep in mind that in the 193shell, "0" means "success".) 194 195The normal caveats apply. In particular, if your script makes any 196changes, don't forget to clean up afterwards. 197 198=head2 reset 199 200 svn-bisect reset 201 202Clean up after a bisect, and return the repository to the revision it was at 203before you started. 204 205=head2 help 206 207 svn-bisect help 208 svn-bisect help start 209 210Gives you some useful descriptions and usage information. 211 212 213=head1 EXAMPLE 214 215...Because, you know, no software documentation is complete without a flashy 216screenshot, these days. 217 218So, lets say you were wondering when the subversion project added the 219"Last Changed Rev:" line to the output of "svn info". Determining the 220existence of this change is a straightforward matter of searching for the 221text string... if a result was found, the current revision is "after", 222otherwise it was "before". So a bisect looks like this: 223 224 $ svn co http://svn.apache.org/repos/asf/subversion/trunk/subversion 225 [snip lots of subversion checkout spam] 226 Checked out revision 980012. 227 228 $ cd subversion 229 230 $ ack --nocolor --nogroup 'Last Changed Rev' 231 svn/info-cmd.c:362: SVN_ERR(svn_cmdline_printf(pool, _("Last Changed Rev: %ld\n"), 232 tests/cmdline/depth_tests.py:2056: 'Last Changed Rev' : '^1$', 233 tests/cmdline/upgrade_tests.py:387: 'Last Changed Rev' : '7' 234 tests/cmdline/upgrade_tests.py:396: 'Last Changed Rev' : '10' 235 236 $ date 237 Wed Jul 28 06:40:03 EDT 2010 238 239 $ svn-bisect --min 0 start 240 $ svn-bisect after 241 Fetching history from r0 to r980012; it may take a while. 242 There are 24349 revs left in the pool. Choosing r862045. 243 244 $ ack --nocolor --nogroup 'Last Changed Rev' 245 svn/info-cmd.c:348: SVN_ERR(svn_cmdline_printf(pool, _("Last Changed Rev: %ld\n"), 246 247 $ svn-bisect after 248 There are 12174 revs left in the pool. Choosing r845633. 249 250 $ ack --nocolor --nogroup 'Last Changed Rev' 251 clients/cmdline/info-cmd.c:153: printf ("Last Changed Rev: %" SVN_REVNUM_T_FMT "\n", entry->cmt_rev); 252 253 $ svn-bisect after 254 There are 6087 revs left in the pool. Choosing r840416. 255 256 $ ack --nocolor --nogroup 'Last Changed Rev' 257 258 $ svn-bisect before 259 There are 3043 revs left in the pool. Choosing r842636. 260 261 # ack --nocolor --nogroup 'Last Changed Rev' 262 clients/cmdline/info-cmd.c:153: printf ("Last Changed Rev: %" SVN_REVNUM_T_FMT "\n", entry->cmt_rev); 263 264 $ svn-bisect after 265 There are 1521 revs left in the pool. Choosing r841463. 266 267 $ ack --nocolor --nogroup 'Last Changed Rev' 268 269 $ svn-bisect before 270 There are 760 revs left in the pool. Choosing r841993. 271 272 $ ack --nocolor --nogroup 'Last Changed Rev' 273 clients/cmdline/info-cmd.c:161: printf ("Last Changed Rev: %" SVN_REVNUM_T_FMT "\n", entry->cmt_rev); 274 275 $ svn-bisect after 276 There are 380 revs left in the pool. Choosing r841730. 277 278 $ ack --nocolor --nogroup 'Last Changed Rev' 279 280 $ svn-bisect before 281 There are 189 revs left in the pool. Choosing r841860. 282 283 $ ack --nocolor --nogroup 'Last Changed Rev' 284 285 $ svn-bisect before 286 There are 94 revs left in the pool. Choosing r841933. 287 288 $ ack --nocolor --nogroup 'Last Changed Rev' 289 clients/cmdline/info-cmd.c:151: printf ("Last Changed Rev: %" SVN_REVNUM_T_FMT "\n", entry->cmt_rev); 290 291 $ svn-bisect after 292 There are 47 revs left in the pool. Choosing r841904. 293 294 $ ack --nocolor --nogroup 'Last Changed Rev' 295 clients/cmdline/info-cmd.c:150: printf ("Last Changed Rev: %ld\n", entry->cmt_rev); 296 297 $ svn-bisect after 298 There are 23 revs left in the pool. Choosing r841880. 299 300 $ ack --nocolor --nogroup 'Last Changed Rev' 301 302 $ svn-bisect before 303 There are 11 revs left in the pool. Choosing r841890. 304 305 $ ack --nocolor --nogroup 'Last Changed Rev' 306 clients/cmdline/info-cmd.c:153: printf ("Last Changed Rev: %ld\n", entry->cmt_rev); 307 308 $ svn-bisect after 309 There are 5 revs left in the pool. Choosing r841883. 310 311 $ ack --nocolor --nogroup 'Last Changed Rev' 312 clients/cmdline/info-cmd.c:153: printf ("Last Changed Rev: %ld\n", entry->cmt_rev); 313 314 $ svn-bisect after 315 There are 2 revs left in the pool. Choosing r841882. 316 317 $ ack --nocolor --nogroup 'Last Changed Rev' 318 319 $ svn-bisect before 320 This is the end of the road! 321 The change occurred in r841883. 322 323 $ svn log -r841883 324 ------------------------------------------------------------------------ 325 r841883 | rooneg | 2002-04-27 15:23:38 -0400 (Sat, 27 Apr 2002) | 30 lines 326 327 As requested by cmpilato in issue #676, add an 'svn info' command, which 328 prints out the contents of the svn_wc_entry_t for a given versioned resource. 329 330 * CHANGES 331 note the addition of the 'svn info' command. 332 333 * subversion/clients/cmdline/cl.h 334 add declaration for svn_cl__info. 335 336 * subversion/clients/cmdline/info-cmd.c 337 new file implementing the info command. 338 339 * subversion/clients/cmdline/main.c 340 hook up the info command. 341 342 * subversion/clients/cmdline/man/svn.1 343 document the info command. 344 345 * subversion/tests/clients/cmdline/getopt_tests_data/svn--help_stdout 346 update for the addition of info command. 347 348 * subversion/tests/clients/cmdline/getopt_tests_data/svn_help_stdout 349 ditto. 350 351 * subversion/tests/clients/cmdline/getopt_tests_data/svn_stderr 352 ditto. 353 354 * tools/dev/bash_completion 355 add 'info' to the tab completion. 356 357 ------------------------------------------------------------------------ 358 359 $ date 360 Wed Jul 28 06:45:27 EDT 2010 361 362So, there it is. In 5 minutes, we've learned that "Last Changed Rev:" has been 363in there since the inception of the "svn info" command itself, back in 2002. 364 365You can also provide a script command to do all of the work for you: 366 367 $ svn-bisect --min 0 --max 980012 start 368 $ svn-bisect run '! grep -r "Last Changed Rev" .' 369 370 371=head1 REQUIREMENTS 372 373This tool requires: 374 375* A computer 376 377* A brain 378 379* An installation of Perl, version 5.8 or above 380 381* The IO::All module, installed from CPAN 382 383* The YAML::Syck module, installed from CPAN 384 385* The "svn" command somewhere in your PATH, executable by the current user 386 387* A svn checkout with some history to bisect. 388 389 390=head1 AUTHOR 391 392 Mark Glines <mark-cpan@glines.org> 393 394 395=head1 REPOSITORY 396 397Browser: L<http://github.com/Infinoid/svn-bisect/> 398Clone: L<git://github.com/Infinoid/svn-bisect.git> 399 400 401=head1 THANKS 402 403* Thanks to the git-bisect author(s), for coming up with a user interface that 404 I actually like. 405 406* Thanks to Will Coleda for inspiring me to actually write and release this. 407 408* Thanks to the Parrot project for having so much random stuff going on as to 409 make a tool like this necessary. 410 411 412=head1 SEE ALSO 413 414App::SVNBinarySearch by Will Coleda: L<http://search.cpan.org/dist/App-SVNBinarySearch/> 415 416 417=head1 COPYRIGHT AND LICENSE 418 419This software is copyright (c) 2008 Mark Glines. 420 421It is distributed under the terms of the Artistic License 2.0. For details, 422see the "LICENSE" file packaged alongside this tool. 423 424=cut 425