mirror of
https://https.git.savannah.gnu.org/git/patch.git
synced 2026-01-27 01:44:34 +00:00
Make "patch -r rejfile" work even when there are several rejects
With a patch that includes rejects in more than one file and with the -r option, rejects would overwrite themselves and only the rejects from the last file would remain. Fix this.
This commit is contained in:
parent
9371e1ac99
commit
b80bfda68f
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
2009-03-21 Andreas Gruenbacher <agruen@suse.de>
|
||||
|
||||
* patch.c (main): With -r, instead of moving the global reject
|
||||
file into place, copy the first reject into the file, and
|
||||
append all the rest. Discard rejects with -r -.
|
||||
* patch.man: Document the latter.
|
||||
* util.c (copy_to_fd): New function.
|
||||
(copy_file): Use that.
|
||||
(append_to_file): New function.
|
||||
* util.h (append_to_file): Add function declaration.
|
||||
* tests/global-reject-files: New test case.
|
||||
* Makefile.in (TESTS): Add test case.
|
||||
|
||||
2009-03-20 Andreas Gruenbacher <agruen@suse.de>
|
||||
|
||||
* patch.c: New option --reject-format=FORMAT.
|
||||
|
||||
@ -88,7 +88,7 @@ HDRS = argmatch.h backupfile.h common.h dirname.h \
|
||||
MISC = AUTHORS COPYING ChangeLog INSTALL Makefile.in NEWS README VERSION \
|
||||
aclocal.m4 config.hin configure configure.ac install-sh \
|
||||
mkinstalldirs patch.man stdbool_.h timespec.h
|
||||
TESTS = tests/corrupt-reject-files tests/crlf-handling \
|
||||
TESTS = tests/corrupt-reject-files tests/crlf-handling tests/global-reject-files \
|
||||
tests/no-newline-triggers-assert tests/preserve-c-function-names \
|
||||
tests/preserve-mode-and-timestamp \
|
||||
tests/reject-format tests/remember-backup-files
|
||||
|
||||
18
patch.c
18
patch.c
@ -124,6 +124,7 @@ main (int argc, char **argv)
|
||||
struct outstate outstate;
|
||||
struct stat outst;
|
||||
char numbuf[LINENUM_LENGTH_BOUND + 1];
|
||||
bool written_to_rejname = false;
|
||||
|
||||
exit_failure = 2;
|
||||
program_name = argv[0];
|
||||
@ -427,7 +428,7 @@ main (int argc, char **argv)
|
||||
somefailed = true;
|
||||
say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1),
|
||||
skip_rest_of_patch ? "ignored" : "FAILED");
|
||||
if (outname) {
|
||||
if (outname && (! rejname || strcmp (rejname, "-") != 0)) {
|
||||
char *rej = rejname;
|
||||
if (!rejname) {
|
||||
rej = xmalloc (strlen (outname) + 5);
|
||||
@ -437,8 +438,19 @@ main (int argc, char **argv)
|
||||
say (" -- saving rejects to file %s", quotearg (rej));
|
||||
if (! dry_run)
|
||||
{
|
||||
move_file (TMPREJNAME, &TMPREJNAME_needs_removal, 0,
|
||||
rej, 0666, false);
|
||||
if (rejname)
|
||||
{
|
||||
if (! written_to_rejname)
|
||||
{
|
||||
copy_file (TMPREJNAME, rejname, 0, 0, 0666);
|
||||
written_to_rejname = true;
|
||||
}
|
||||
else
|
||||
append_to_file (TMPREJNAME, rejname);
|
||||
}
|
||||
else
|
||||
move_file (TMPREJNAME, &TMPREJNAME_needs_removal, 0,
|
||||
rej, 0666, false);
|
||||
}
|
||||
if (!rejname)
|
||||
free (rej);
|
||||
|
||||
@ -514,7 +514,7 @@ Put rejects into
|
||||
.I rejectfile
|
||||
instead of the default
|
||||
.B \&.rej
|
||||
file.
|
||||
file. When \fIrejectfile\fP is \fB\-\fP, discard rejects.
|
||||
.TP
|
||||
\fB\-R\fP or \fB\*=reverse\fP
|
||||
Assume that this patch was created with the old and new files swapped.
|
||||
|
||||
90
tests/global-reject-files
Executable file
90
tests/global-reject-files
Executable file
@ -0,0 +1,90 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification,
|
||||
# in any medium, are permitted without royalty provided the copyright
|
||||
# notice and this notice are preserved.
|
||||
|
||||
# More than one reject to
|
||||
|
||||
. $srcdir/test-lib.sh
|
||||
|
||||
require_cat
|
||||
require_diff
|
||||
use_local_patch
|
||||
use_tmpdir
|
||||
|
||||
# ==============================================================
|
||||
|
||||
cat > ab.diff <<EOF
|
||||
--- a
|
||||
+++ a
|
||||
@@ -1 +1 @@
|
||||
-one
|
||||
+two
|
||||
--- b
|
||||
+++ b
|
||||
@@ -1 +1 @@
|
||||
-three
|
||||
+four
|
||||
EOF
|
||||
|
||||
echo one > a
|
||||
echo three > b
|
||||
|
||||
check 'patch -p0 < ab.diff' <<EOF
|
||||
patching file a
|
||||
patching file b
|
||||
EOF
|
||||
|
||||
# ==============================================================
|
||||
|
||||
check 'patch -p0 -f < ab.diff || echo "Status: $?"' <<EOF
|
||||
patching file a
|
||||
Hunk #1 FAILED at 1.
|
||||
1 out of 1 hunk FAILED -- saving rejects to file a.rej
|
||||
patching file b
|
||||
Hunk #1 FAILED at 1.
|
||||
1 out of 1 hunk FAILED -- saving rejects to file b.rej
|
||||
Status: 1
|
||||
EOF
|
||||
|
||||
check 'cat a.rej' <<EOF
|
||||
--- a
|
||||
+++ a
|
||||
@@ -1 +1 @@
|
||||
-one
|
||||
+two
|
||||
EOF
|
||||
|
||||
check 'cat b.rej' <<EOF
|
||||
--- b
|
||||
+++ b
|
||||
@@ -1 +1 @@
|
||||
-three
|
||||
+four
|
||||
EOF
|
||||
|
||||
check 'patch -p0 -f -r ab.rej < ab.diff || echo "Status: $?"' <<EOF
|
||||
patching file a
|
||||
Hunk #1 FAILED at 1.
|
||||
1 out of 1 hunk FAILED -- saving rejects to file ab.rej
|
||||
patching file b
|
||||
Hunk #1 FAILED at 1.
|
||||
1 out of 1 hunk FAILED -- saving rejects to file ab.rej
|
||||
Status: 1
|
||||
EOF
|
||||
|
||||
check 'cat ab.rej' <<EOF
|
||||
--- a
|
||||
+++ a
|
||||
@@ -1 +1 @@
|
||||
-one
|
||||
+two
|
||||
--- b
|
||||
+++ b
|
||||
@@ -1 +1 @@
|
||||
-three
|
||||
+four
|
||||
EOF
|
||||
35
util.c
35
util.c
@ -294,19 +294,14 @@ create_file (char const *file, int open_flags, mode_t mode)
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Copy a file. */
|
||||
|
||||
void
|
||||
copy_file (char const *from, char const *to, struct stat *tost,
|
||||
int to_flags, mode_t mode)
|
||||
static void
|
||||
copy_to_fd (const char *from, int tofd)
|
||||
{
|
||||
int tofd;
|
||||
int fromfd;
|
||||
size_t i;
|
||||
|
||||
if ((fromfd = open (from, O_RDONLY | O_BINARY)) < 0)
|
||||
pfatal ("Can't reopen file %s", quotearg (from));
|
||||
tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode);
|
||||
while ((i = read (fromfd, buf, bufsize)) != 0)
|
||||
{
|
||||
if (i == (size_t) -1)
|
||||
@ -316,11 +311,37 @@ copy_file (char const *from, char const *to, struct stat *tost,
|
||||
}
|
||||
if (close (fromfd) != 0)
|
||||
read_fatal ();
|
||||
}
|
||||
|
||||
/* Copy a file. */
|
||||
|
||||
void
|
||||
copy_file (char const *from, char const *to, struct stat *tost,
|
||||
int to_flags, mode_t mode)
|
||||
{
|
||||
int tofd;
|
||||
|
||||
tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode);
|
||||
copy_to_fd (from, tofd);
|
||||
if ((tost && fstat (tofd, tost) != 0)
|
||||
|| close (tofd) != 0)
|
||||
write_fatal ();
|
||||
}
|
||||
|
||||
/* Append to file. */
|
||||
|
||||
void
|
||||
append_to_file (char const *from, char const *to)
|
||||
{
|
||||
int tofd;
|
||||
|
||||
if ((tofd = open (to, O_WRONLY | O_BINARY | O_APPEND)) < 0)
|
||||
pfatal ("Can't reopen file %s", quotearg (to));
|
||||
copy_to_fd (from, tofd);
|
||||
if (close (tofd) != 0)
|
||||
write_fatal ();
|
||||
}
|
||||
|
||||
static char const DEV_NULL[] = NULL_DEVICE;
|
||||
|
||||
static char const RCSSUFFIX[] = ",v";
|
||||
|
||||
1
util.h
1
util.h
@ -47,6 +47,7 @@ int systemic (char const *);
|
||||
char *format_linenum (char[LINENUM_LENGTH_BOUND + 1], LINENUM);
|
||||
void Fseek (FILE *, file_offset, int);
|
||||
void copy_file (char const *, char const *, struct stat *, int, mode_t);
|
||||
void append_to_file (char const *, char const *);
|
||||
void exit_with_signal (int) __attribute__ ((noreturn));
|
||||
void ignore_signals (void);
|
||||
void init_backup_hash_table (void);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user