Skip to content

Commit ecfed3f

Browse files
committed
hackorum-patch now can apply diff files
Sometimes patches are posted as .diff instead of .patch, which requires a different process to apply
1 parent a19b98f commit ecfed3f

2 files changed

Lines changed: 83 additions & 17 deletions

File tree

public/scripts/hackorum-patch

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class HackorumPatch
2222
@temp_dir = nil
2323
@local_archive = nil
2424
@using_local_file = false
25+
@using_diff_mode = false
2526

2627
parse_options!(argv)
2728

@@ -79,7 +80,11 @@ class HackorumPatch
7980
create_branch(base_commit)
8081
end
8182

82-
apply_patches(patch_files)
83+
if @using_diff_mode
84+
apply_diffs(patch_files)
85+
else
86+
apply_patches(patch_files)
87+
end
8388
cleanup_temp_files
8489

8590
print_success_message(use_worktree ? worktree_path : nil)
@@ -350,14 +355,7 @@ class HackorumPatch
350355
end
351356

352357
all_files = Dir.glob(File.join(@temp_dir, "*")).sort
353-
patch_files = all_files.select { |f| f.end_with?(".patch") }
354-
skipped = all_files.size - patch_files.size
355-
msg = "[OK] Downloaded and extracted #{patch_files.size} patches"
356-
msg += " (skipped #{skipped} non-patch files)" if skipped > 0
357-
puts msg
358-
puts ""
359-
360-
patch_files
358+
categorize_and_report_files(all_files)
361359
end
362360

363361
def extract_local_patchset
@@ -379,14 +377,32 @@ class HackorumPatch
379377
end
380378

381379
all_files = Dir.glob(File.join(@temp_dir, "*")).sort
380+
categorize_and_report_files(all_files)
381+
end
382+
383+
def categorize_and_report_files(all_files)
382384
patch_files = all_files.select { |f| f.end_with?(".patch") }
383-
skipped = all_files.size - patch_files.size
384-
msg = "[OK] Extracted #{patch_files.size} patches"
385-
msg += " (skipped #{skipped} non-patch files)" if skipped > 0
385+
diff_files = all_files.select { |f| f.end_with?(".diff") }
386+
skipped = all_files.size - patch_files.size - diff_files.size
387+
388+
if !patch_files.empty? && !diff_files.empty?
389+
raise "Mixed patch and diff files detected. Archives must contain only .patch files OR only .diff files, not both."
390+
end
391+
392+
if patch_files.empty? && diff_files.empty?
393+
raise "No patch or diff files found in archive"
394+
end
395+
396+
@using_diff_mode = !diff_files.empty?
397+
files = @using_diff_mode ? diff_files : patch_files
398+
file_type = @using_diff_mode ? "diffs" : "patches"
399+
400+
msg = "[OK] Extracted #{files.size} #{file_type}"
401+
msg += " (skipped #{skipped} other files)" if skipped > 0
386402
puts msg
387403
puts ""
388404

389-
patch_files
405+
files
390406
end
391407

392408
def detect_base_commit(patch_files_dir)
@@ -397,10 +413,12 @@ class HackorumPatch
397413
end
398414

399415
patch_files = Dir.glob(File.join(patch_files_dir, "*.patch")).sort
400-
return detect_default_branch_head if patch_files.empty?
416+
diff_files = Dir.glob(File.join(patch_files_dir, "*.diff")).sort
417+
all_patch_files = patch_files + diff_files
418+
return detect_default_branch_head if all_patch_files.empty?
401419

402420
# First, check for base-commit line (from git format-patch --base)
403-
base_commit = detect_base_commit_from_base_line(patch_files)
421+
base_commit = detect_base_commit_from_base_line(all_patch_files)
404422
if base_commit
405423
puts "[OK] Base commit: #{base_commit} (from base-commit line)"
406424
puts ""
@@ -410,7 +428,7 @@ class HackorumPatch
410428
# Fall back to index hash detection
411429
puts "Detecting base commit from patch index entries..."
412430

413-
first_patch = patch_files.first
431+
first_patch = all_patch_files.first
414432
index_hashes = []
415433
new_file_count = 0
416434
content = File.read(first_patch)
@@ -563,6 +581,53 @@ class HackorumPatch
563581
puts ""
564582
end
565583

584+
def apply_diffs(diff_files)
585+
puts "Applying #{diff_files.size} diff files..."
586+
puts ""
587+
588+
diff_files.each_with_index do |diff_file, idx|
589+
basename = File.basename(diff_file, ".diff")
590+
puts " [#{idx + 1}/#{diff_files.size}] #{File.basename(diff_file)}"
591+
592+
# Apply the diff
593+
output = `git apply --3way #{Shellwords.escape(diff_file)} 2>&1`
594+
success = $?.success?
595+
596+
output.each_line { |line| puts " #{line}" } unless output.strip.empty?
597+
598+
unless success
599+
puts ""
600+
puts "[FAIL] Failed to apply #{File.basename(diff_file)}"
601+
puts ""
602+
puts "You can resolve conflicts manually and retry."
603+
raise "Diff application failed"
604+
end
605+
606+
# Stage all changes
607+
unless system("git add -A > /dev/null 2>&1")
608+
raise "Failed to stage changes for #{File.basename(diff_file)}"
609+
end
610+
611+
# Commit with simple message
612+
commit_msg = "Apply #{basename}"
613+
unless system("git commit -m #{Shellwords.escape(commit_msg)} > /dev/null 2>&1")
614+
# Check if there's actually anything to commit
615+
status = `git status --porcelain`.strip
616+
if status.empty?
617+
puts " (no changes to commit)"
618+
else
619+
raise "Failed to commit #{File.basename(diff_file)}"
620+
end
621+
else
622+
puts " Committed: #{commit_msg}"
623+
end
624+
end
625+
626+
puts ""
627+
puts "[OK] All diffs applied and committed successfully"
628+
puts ""
629+
end
630+
566631
def cleanup_temp_files
567632
FileUtils.rm_rf(@temp_dir) if @temp_dir && File.exist?(@temp_dir)
568633
end

public/scripts/hackorum-patch.changelog.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"date": "2026-01-21",
77
"changes": [
88
"Added version check to notify users of updates",
9-
"Added support for base-commit line from git format-patch --base"
9+
"Added support for base-commit line from git format-patch --base",
10+
"Added support for .diff files (applied with git apply and committed individually)"
1011
]
1112
},
1213
{

0 commit comments

Comments
 (0)