1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 10:38:13 +00:00

LibDiff+patch: Support multiple patches in a single patch file

Multiple patches may be concatenated in the same patch file, such as git
commits which are changing multiple files at the same time. To handle
this, parse each patch in order in the patch file, and apply each patch
sequentially.

To determine whether we are at the end of a patch (and not just parsing
another hunk) the parser will look for a leading '@@ ' after every hunk.
If that is found, there is another hunk. Otherwise, we must be at the
end of this patch.
This commit is contained in:
Shannon Booth 2023-07-12 10:37:26 +12:00 committed by Sam Atkins
parent ddbd77cca1
commit dd373eacbc
4 changed files with 57 additions and 20 deletions

View file

@ -65,25 +65,28 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto patch_content = TRY(input->read_until_eof());
// FIXME: Support multiple patches in the patch file.
Diff::Parser parser(patch_content);
Diff::Patch patch;
patch.header = TRY(parser.parse_header(strip_count));
patch.hunks = TRY(parser.parse_hunks());
// FIXME: Support adding/removing a file, and asking for file to patch as fallback otherwise.
StringView to_patch;
if (FileSystem::is_regular_file(patch.header.old_file_path)) {
to_patch = patch.header.old_file_path;
} else if (is_adding_file(patch) || FileSystem::is_regular_file(patch.header.new_file_path)) {
to_patch = patch.header.new_file_path;
} else {
warnln("Unable to determine file to patch");
return 1;
while (!parser.is_eof()) {
Diff::Patch patch = TRY(parser.parse_patch(strip_count));
if (patch.header.format == Diff::Format::Unknown)
break;
// FIXME: Support adding/removing a file, and asking for file to patch as fallback otherwise.
StringView to_patch;
if (FileSystem::is_regular_file(patch.header.old_file_path)) {
to_patch = patch.header.old_file_path;
} else if (is_adding_file(patch) || FileSystem::is_regular_file(patch.header.new_file_path)) {
to_patch = patch.header.new_file_path;
} else {
warnln("Unable to determine file to patch");
return 1;
}
outln("patching file {}", to_patch);
TRY(do_patch(to_patch, patch));
}
outln("patching file {}", to_patch);
TRY(do_patch(to_patch, patch));
return 0;
}