Skip to content

Commit

Permalink
fix: stg import --reject should create empty commit
Browse files Browse the repository at this point in the history
When trying to import a patch that does not apply cleanly, and using
--reject option, stg should apply what it can, leave the rest in .rej
files, and create an empty commit. The work to apply the patch is
outsourced to "git apply --reject" which exits with status code 1 if
patch is applied partially and it is treated as error by stg import.

Fix the issue by treating exit codes less than 128 from "git apply
--reject" as success (128 signals hard error).

Also add a test case and fix up documentation for "stg import".

Closes: #471

Signed-off-by: Dmitry Torokhov <dtor@google.com>
  • Loading branch information
dtor committed Jul 15, 2024
1 parent 2c8d707 commit 4e6c20a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/cmd/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ fn make() -> clap::Command {
allows the patches source to be fetched from a url instead of from a \
local file.\n\
\n\
If a patch does not apply cleanly, the failed diff is written to a \
.stgit-failed.patch file and an empty patch is added to the stack.\n\
If a patch does not apply cleanly import is aborted unless '--reject' \
is specified, in which case it will apply to the work tree the parts \
of the patch that are applicable, leave the rejected hunks in \
corresponding *.rej files, and add an empty patch to the stack.\n\
\n\
The patch description must be separated from the diff with a \"---\" line.",
)
Expand Down
10 changes: 9 additions & 1 deletion src/stupid/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,18 @@ impl<'repo, 'index> StupidContext<'repo, 'index> {
if let Some(context_lines) = context_lines {
command.arg(format!("-C{context_lines}"));
}
let error_threshold = if reject {
// When allowing rejects "git apply" returns exit code 1 when it can't
// apply patch in its entirety. Exit code 128 is a hard error.
128
} else {
// Any non-zero error code is considered an error.
1
};
command
.stdout(Stdio::null())
.in_and_out(diff)?
.require_success("apply --index")?;
.require_code_less_than("apply --index", error_threshold)?;
Ok(())
}

Expand Down
10 changes: 10 additions & 0 deletions t/t1800-import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,16 @@ test_expect_success 'Import series from stdin' '
stg delete --top
'

test_expect_success 'Import patch that does not apply cleanly with --reject' '
stg import --reject "$TEST_DIRECTORY"/t1800/diff-with-rejects &&
git log -1 --pretty=format:%b >body &&
test_when_finished "rm foo.txt.rej body" &&
test "$(echo $(stg top))" = "diff-with-rejects" &&
test_line_count = 0 body &&
stg reset --hard &&
stg delete --top
'

test_expect_success STG_IMPORT_URL 'Attempt url' '
general_error stg import --url 2>err &&
grep -e "required arguments were not provided" err
Expand Down
29 changes: 29 additions & 0 deletions t/t1800/diff-with-rejects
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
test patch with rejects

---

t/t1800/foo.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/t/t1800/foo.txt b/t/t1800/foo.txt
index ad01662f..d609de80 100644
--- a/foo.txt
+++ b/foo.txt
@@ -6,7 +6,7 @@ dobidim
dobidum
dobodam
dobodim
-dobodum
+dObodum
dibedam
dibedim
dibedum
@@ -18,7 +18,7 @@ dibodim
dibodum
dabedam
dabedim
-Dabedum
+dAbedum
dabidam
dabidim
dabidum

0 comments on commit 4e6c20a

Please sign in to comment.