@@ -13,7 +13,7 @@ require 'shellwords'
1313require 'json'
1414
1515class HackorumPatch
16- VERSION = '1.1 .0'
16+ VERSION = '1.2 .0'
1717
1818 def initialize ( argv )
1919 @options = { }
@@ -96,6 +96,10 @@ class HackorumPatch
9696
9797 private
9898
99+ def verbose_log ( msg )
100+ puts msg if @options [ :verbose ]
101+ end
102+
99103 def parse_options! ( argv )
100104 @option_parser = OptionParser . new do |opts |
101105 opts . banner = "Usage: hackorum-patch <topic_id|archive.tar.gz> [<branch_name>] [OPTIONS]"
@@ -129,6 +133,10 @@ class HackorumPatch
129133 @options [ :server ] = url
130134 end
131135
136+ opts . on ( "--verbose" , "Print detailed base commit detection info" ) do
137+ @options [ :verbose ] = true
138+ end
139+
132140 opts . on ( "-h" , "--help" , "Show this help" ) do
133141 puts opts
134142 exit
@@ -434,10 +442,18 @@ class HackorumPatch
434442 file_info = { } # path => before_hash
435443 all_patch_files . each do |patch_file |
436444 content = File . read ( patch_file )
445+ verbose_log " Scanning #{ File . basename ( patch_file ) } for file hashes..."
437446 # Format: diff --git a/path b/path followed by index abc123..def456
438447 content . scan ( /^diff --git a\/ (.+?) b\/ \1 \n (?:.*?\n )*?index ([0-9a-f]+)\. \. ([0-9a-f]+)/m ) do |path , before_hash , after_hash |
439- next if before_hash =~ /^0+$/ # Skip new files
440- next if file_info . key? ( path ) # Only use first occurrence
448+ if before_hash =~ /^0+$/
449+ verbose_log " #{ path } : new file (skipped)"
450+ next
451+ end
452+ if file_info . key? ( path )
453+ verbose_log " #{ path } : already recorded (skipped duplicate)"
454+ next
455+ end
456+ verbose_log " #{ path } : before=#{ before_hash } "
441457 file_info [ path ] = before_hash
442458 end
443459 end
@@ -448,15 +464,30 @@ class HackorumPatch
448464 end
449465
450466 puts " Found #{ file_info . size } modified files across #{ all_patch_files . size } patches"
467+ if @options [ :verbose ]
468+ verbose_log " Files and their expected 'before' hashes:"
469+ file_info . each do |path , hash |
470+ verbose_log " #{ path } : #{ hash } "
471+ end
472+ end
451473
452474 default_branch = detect_default_branch_head
453475
454476 # Check if the "before" hashes match what's at the default branch HEAD
455477 # This confirms HEAD is the correct base
456478 default_head = `git rev-parse #{ default_branch } 2>/dev/null` . strip
479+ verbose_log " Checking against #{ default_branch } HEAD (#{ default_head [ 0 ..11 ] } ...):"
457480 all_match = file_info . all? do |path , before_hash |
458481 current_hash = `git rev-parse #{ default_head } :#{ path } 2>/dev/null` . strip
459- current_hash == before_hash || current_hash . start_with? ( before_hash ) || before_hash . start_with? ( current_hash )
482+ matches = current_hash == before_hash || current_hash . start_with? ( before_hash ) || before_hash . start_with? ( current_hash )
483+ if @options [ :verbose ]
484+ status = matches ? "MATCH" : "MISMATCH"
485+ verbose_log " #{ path } :"
486+ verbose_log " patch: #{ before_hash } "
487+ verbose_log " HEAD: #{ current_hash . empty? ? '(not found)' : current_hash } "
488+ verbose_log " result: #{ status } "
489+ end
490+ matches
460491 end
461492
462493 if all_match
@@ -471,25 +502,37 @@ class HackorumPatch
471502
472503 # Find commits on the default branch that touched these files
473504 paths = file_info . keys . map { |p | Shellwords . escape ( p ) } . join ( " " )
505+ verbose_log " Searching commits that touched: #{ file_info . keys . join ( ', ' ) } "
474506 commits = `git log #{ default_branch } --pretty=format:%H -n 50 -- #{ paths } 2>/dev/null` . strip . split ( "\n " )
507+ verbose_log " Found #{ commits . size } candidate commits to check"
475508
476- commits . each do |commit |
509+ commits . each_with_index do |commit , idx |
477510 next if commit . empty?
478511
512+ verbose_log " Checking commit #{ idx + 1 } /#{ commits . size } : #{ commit [ 0 ..11 ] } ..."
513+ mismatch_details = [ ]
479514 matches = file_info . all? do |path , before_hash |
480515 blob_hash = `git rev-parse #{ commit } :#{ path } 2>/dev/null` . strip
481- blob_hash == before_hash || blob_hash . start_with? ( before_hash ) || before_hash . start_with? ( blob_hash )
516+ result = blob_hash == before_hash || blob_hash . start_with? ( before_hash ) || before_hash . start_with? ( blob_hash )
517+ unless result
518+ mismatch_details << " #{ path } : patch=#{ before_hash } , commit=#{ blob_hash . empty? ? '(not found)' : blob_hash } "
519+ end
520+ result
482521 end
483522
484523 if matches
485524 puts " Found matching commit: #{ commit [ 0 ..11 ] } ..."
486525 puts "[OK] Base commit: #{ commit } "
487526 puts ""
488527 return commit
528+ else
529+ verbose_log " No match. Mismatches:"
530+ mismatch_details . each { |d | verbose_log d }
489531 end
490532 end
491533
492534 puts " Could not find matching commit in history"
535+ verbose_log " Falling back to default branch HEAD"
493536 detect_default_branch_head
494537 end
495538
0 commit comments