Index: patch-2.5.9/patch.man
===================================================================
--- patch-2.5.9.orig/patch.man
+++ patch-2.5.9/patch.man
@@ -520,6 +520,15 @@ file.
 \fB\*=reject\-unified\fP
 Produce unified reject files. The default is to produce context type reject files.
 .TP
+.BI \*=global\-reject\-file= rejectfile
+Put all rejects into
+.I rejectfile
+instead of creating separate reject files for all files that have rejects. The
+.I rejectfile
+will contain headers that identify which file each reject refers to. Note that
+the global reject file is created even if \-\-dry\-run is specified (while
+non-global reject files will only be created without \-\-dry\-run).
+.TP
 \fB\-R\fP  or  \fB\*=reverse\fP
 Assume that this patch was created with the old and new files swapped.
 (Yes, I'm afraid that does happen occasionally, human nature being what it
Index: patch-2.5.9/patch.c
===================================================================
--- patch-2.5.9.orig/patch.c
+++ patch-2.5.9/patch.c
@@ -67,6 +67,7 @@ static bool similar (char const *, size_
 static bool spew_output (struct outstate *);
 static char const *make_temp (char);
 static int numeric_string (char const *, bool, char const *);
+static void reject_header (const char *filename);
 static void abort_hunk (void);
 static void cleanup (void);
 static void get_some_switches (void);
@@ -98,6 +99,7 @@ static int Argc;
 static char * const *Argv;
 
 static FILE *rejfp;  /* reject file pointer */
+static char *global_reject;
 
 static char const *patchname;
 static char *rejname;
@@ -172,6 +174,10 @@ main (int argc, char **argv)
     /* Make sure we clean up in case of disaster.  */
     set_signals (false);
 
+    /* initialize global reject file */
+    if (global_reject)
+      init_reject ();
+
     for (
 	open_patch_file (patchname);
 	there_is_another_patch();
@@ -208,8 +214,9 @@ main (int argc, char **argv)
 	    init_output (TMPOUTNAME, exclusive, &outstate);
 	  }
 
-	/* initialize reject file */
-	init_reject ();
+	/* initialize per-patch reject file */
+	if (!global_reject)
+	  init_reject ();
 
 	/* find out where all the lines are */
 	if (!skip_rest_of_patch)
@@ -278,6 +285,8 @@ main (int argc, char **argv)
 
 	    newwhere = pch_newfirst() + last_offset;
 	    if (skip_rest_of_patch) {
+		if (!failed)
+		  reject_header(outname);
 		abort_hunk();
 		failed++;
 		if (verbosity == VERBOSE)
@@ -292,6 +301,8 @@ main (int argc, char **argv)
 		  say ("Patch attempted to create file %s, which already exists.\n",
 		       quotearg (inname));
 
+		if (!failed)
+		  reject_header(outname);
 		abort_hunk();
 		failed++;
 		if (verbosity != SILENT)
@@ -299,6 +310,8 @@ main (int argc, char **argv)
 		       format_linenum (numbuf, newwhere));
 	    }
 	    else if (! apply_hunk (&outstate, where)) {
+		if (!failed)
+		  reject_header(outname);
 		abort_hunk ();
 		failed++;
 		if (verbosity != SILENT)
@@ -332,7 +345,8 @@ main (int argc, char **argv)
 		    fclose (outstate.ofp);
 		    outstate.ofp = 0;
 		  }
-		fclose (rejfp);
+		if (!global_reject)
+		  fclose (rejfp);
 		continue;
 	      }
 
@@ -412,13 +426,13 @@ main (int argc, char **argv)
 	    }
       }
       if (diff_type != ED_DIFF) {
-	if (fclose (rejfp) != 0)
+	if (!global_reject && fclose (rejfp) != 0)
 	    write_fatal ();
 	if (failed) {
 	    somefailed = true;
 	    say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1),
 		 skip_rest_of_patch ? "ignored" : "FAILED");
-	    if (outname) {
+	    if (!global_reject && outname) {
 		char *rej = rejname;
 		if (!rejname) {
 		    rej = xmalloc (strlen (outname) + 5);
@@ -445,6 +459,20 @@ main (int argc, char **argv)
       }
       set_signals (true);
     }
+    if (global_reject)
+      {
+	if (fclose (rejfp) != 0)
+	  write_fatal ();
+	if (somefailed)
+	  {
+	  say (" -- saving rejects to file %s\n", quotearg (global_reject));
+	  /*if (! dry_run)
+	    {*/
+	      move_file (TMPREJNAME, &TMPREJNAME_needs_removal,
+			 global_reject, 0644, false);
+	    /*}*/
+	  }
+      }
     if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
       write_fatal ();
     cleanup ();
@@ -523,6 +551,7 @@ static struct option const longopts[] =
   {"posix", no_argument, NULL, CHAR_MAX + 7},
   {"quoting-style", required_argument, NULL, CHAR_MAX + 8},
   {"unified-reject-files", no_argument, NULL, CHAR_MAX + 9},
+  {"global-reject-file", required_argument, NULL, CHAR_MAX + 10},
   {NULL, no_argument, NULL, 0}
 };
 
@@ -582,6 +611,7 @@ static char const *const option_help[] =
 "  --dry-run  Do not actually change any files; just print what would happen.",
 "  --posix  Conform to the POSIX standard.",
 "  --unified-reject-files  Create unified reject files.",
+"  --global-reject-file=file  Put all rejects into one file.",
 "",
 "  -d DIR  --directory=DIR  Change the working directory to DIR first.",
 #if HAVE_SETMODE_DOS
@@ -784,6 +814,9 @@ get_some_switches (void)
 	    case CHAR_MAX + 9:
 		unified_reject_files = true;
 		break;
+	    case CHAR_MAX + 10:
+		global_reject = savestr (optarg);
+		break;
 	    default:
 		usage (stderr, 2);
 	}
@@ -933,6 +966,37 @@ locate_hunk (LINENUM fuzz)
 }
 
 static char *
+format_timestamp (char timebuf[37], bool which)
+{
+  time_t ts = pch_timestamp(which);
+  if (ts != -1)
+    {
+      struct tm *tm = localtime(&ts);
+      strftime(timebuf, 37, "\t%Y-%m-%d %H:%M:%S.000000000 %z", tm);
+    }
+  else
+    timebuf[0] = 0;
+  return timebuf;
+}
+
+/* Write a header in a reject file that combines multiple hunks. */
+static void
+reject_header (const char *outname)
+{
+    char timebuf0[37], timebuf1[37];
+    if (!global_reject)
+      return;
+    if (diff_type == UNI_DIFF)
+	fprintf(rejfp, "--- %s.orig%s\n+++ %s%s\n",
+		outname, format_timestamp(timebuf0, reverse),
+		outname, format_timestamp(timebuf1, !reverse));
+    else
+	fprintf(rejfp, "*** %s.orig%s\n--- %s%s\n",
+		outname, format_timestamp(timebuf0, reverse),
+		outname, format_timestamp(timebuf1, !reverse));
+}
+
+static char *
 format_linerange (char rangebuf[LINENUM_LENGTH_BOUND*2 + 2],
 		  LINENUM first, LINENUM lines)
 {
