Index: patch-2.6.1/patch.man
===================================================================
--- patch-2.6.1.orig/patch.man
+++ patch-2.6.1/patch.man
@@ -557,6 +557,15 @@ instead of the default
 .B \&.rej
 file.  When \fIrejectfile\fP is \fB\-\fP, discard rejects.
 .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.6.1/src/patch.c
===================================================================
--- patch-2.6.1.orig/src/patch.c
+++ patch-2.6.1/src/patch.c
@@ -52,6 +52,7 @@ static void reinitialize_almost_everythi
 static void remove_if_needed (char const *, int volatile *);
 static void usage (FILE *, int) __attribute__((noreturn));
 
+static void reject_header (const char *filename);
 static void abort_hunk (bool, bool);
 static void abort_hunk_context (bool, bool);
 static void abort_hunk_unified (bool, bool);
@@ -83,6 +84,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;
@@ -159,6 +161,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 ();
+
     if (inname && outfile)
       {
 	apply_empty_patch = true;
@@ -205,8 +211,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)
@@ -295,6 +302,8 @@ main (int argc, char **argv)
 			|| ! where
 			|| ! apply_hunk (&outstate, where))))
 	      {
+		if (!failed)
+		  reject_header(outname);
 		abort_hunk (! failed, reverse);
 		failed++;
 		if (verbosity == VERBOSE ||
@@ -331,7 +340,8 @@ main (int argc, char **argv)
 		    fclose (outstate.ofp);
 		    outstate.ofp = 0;
 		  }
-		fclose (rejfp);
+		if (!global_reject)
+		  fclose (rejfp);
 		continue;
 	      }
 
@@ -430,13 +440,13 @@ main (int argc, char **argv)
 	struct stat rejst;
 
 	if ((failed && fstat (fileno (rejfp), &rejst) != 0)
-	    || fclose (rejfp) != 0)
+	    || (( !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 && (! rejname || strcmp (rejname, "-") != 0)) {
+	    if (!global_reject && outname && (! rejname || strcmp (rejname, "-") != 0)) {
 		char *rej = rejname;
 		if (!rejname) {
 		    /* FIXME: This should really be done differnely!  */
@@ -485,6 +495,23 @@ main (int argc, char **argv)
       }
       set_signals (true);
     }
+    if (global_reject)
+      {
+	struct stat rejst;
+
+	if ((somefailed && fstat (fileno (rejfp), &rejst) != 0)
+	    || 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,
+			 &rejst, global_reject, 0644, false);
+	    /*}*/
+	  }
+      }
     if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
       write_fatal ();
     cleanup ();
@@ -572,6 +599,7 @@ static struct option const longopts[] =
   {"posix", no_argument, NULL, CHAR_MAX + 7},
   {"quoting-style", required_argument, NULL, CHAR_MAX + 8},
   {"reject-format", required_argument, NULL, CHAR_MAX + 9},
+  {"global-reject-file", required_argument, NULL, CHAR_MAX + 10},
   {NULL, no_argument, NULL, 0}
 };
 
@@ -636,6 +664,7 @@ static char const *const option_help[] =
 "",
 "  -d DIR  --directory=DIR  Change the working directory to DIR first.",
 "  --reject-format=FORMAT  Create 'context' or 'unified' rejects.",
+"  --global-reject-file=file  Put all rejects into one file.",
 "  --binary  Read and write data in binary mode.",
 "",
 "  -v  --version  Output version info.",
@@ -852,6 +881,9 @@ get_some_switches (void)
 		else
 		  usage (stderr, 2);
 		break;
+	    case CHAR_MAX + 10:
+		global_reject = savestr (optarg);
+		break;
 	    default:
 		usage (stderr, 2);
 	}
@@ -1512,6 +1544,37 @@ similar (register char const *a, registe
     }
 }
 
+ 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));
+}
+
 /* Make a temporary file.  */
 
 #if HAVE_MKTEMP && ! HAVE_DECL_MKTEMP && ! defined mktemp
