summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/quilt.in6
-rw-r--r--lib/backup-files.c91
-rw-r--r--po/de.po24
-rw-r--r--po/fr.po38
-rw-r--r--po/quilt.pot24
-rw-r--r--quilt.changes12
-rw-r--r--quilt/add.in2
-rw-r--r--quilt/pop.in5
-rw-r--r--quilt/remove.in2
-rw-r--r--quilt/snapshot.in5
-rwxr-xr-xscripts/apatch.in11
-rwxr-xr-xscripts/rpatch.in23
-rw-r--r--test/new.test53
-rw-r--r--test/test.quiltrc2
14 files changed, 199 insertions, 99 deletions
diff --git a/bin/quilt.in b/bin/quilt.in
index 858ae88..3be2f0a 100644
--- a/bin/quilt.in
+++ b/bin/quilt.in
@@ -7,7 +7,11 @@
# See the COPYING and AUTHORS files for more details.
export TEXTDOMAIN=quilt
-export QUILTRC=$HOME/.quiltrc
+
+if [ -z "$QUILTRC" ]
+then
+ export QUILTRC=$HOME/.quiltrc
+fi
usage()
{
diff --git a/lib/backup-files.c b/lib/backup-files.c
index 5f37ef5..fcbd2ff 100644
--- a/lib/backup-files.c
+++ b/lib/backup-files.c
@@ -25,6 +25,8 @@
* -B and -Z options.
*/
+#define _GNU_SOURCE
+
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -33,14 +35,16 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <alloca.h>
+#include <ftw.h>
const char *progname;
-enum { what_backup, what_restore, what_remove };
+enum { what_noop, what_backup, what_restore, what_remove };
const char *opt_prefix="", *opt_suffix="", *opt_file;
-int opt_silent, opt_what=what_backup, opt_ignore_missing;
-int opt_nolinks;
+int opt_silent, opt_what=what_noop, opt_ignore_missing;
+int opt_nolinks, opt_walk_directory;
#define LINE_LENGTH 1024
@@ -48,11 +52,12 @@ int opt_nolinks;
void
usage(void)
{
- printf("Usage: %s [-B prefix] [-z suffix] [-f {filelist|-}] [-s] [-r|-x] [-L] filename ...\n"
+ printf("Usage: %s [-B prefix] [-z suffix] [-f {filelist|-}] [-s] [-b|-r|-x] [-L] {filename|-} ...\n"
"\n"
"\tCreate hard linked backup copies of a list of files\n"
"\tread from standard input.\n"
"\n"
+ "\t-b\tCreate backup\n"
"\t-r\tRestore the backup\n"
"\t-x\tRemove backup files and empty parent directories\n"
"\t-B\tPath name prefix for backup files\n"
@@ -63,10 +68,13 @@ usage(void)
}
void
-create_parents(char *filename)
+create_parents(const char *filename)
{
struct stat st;
- char *f = strchr(filename, '/');
+ char *fn = alloca(strlen(filename) + 1), *f;
+
+ strcpy(fn, filename);
+ f = strchr(fn, '/');
if (f == NULL)
return;
@@ -74,7 +82,7 @@ create_parents(char *filename)
if (stat(f, &st) != 0) {
while (f != NULL) {
*f = '\0';
- mkdir(filename, 0777);
+ mkdir(fn, 0777);
*f = '/';
f = strchr(f+1, '/');
}
@@ -205,26 +213,20 @@ ensure_nolinks(const char *filename)
}
int
-process_file(char *file)
+process_file(const char *file)
{
- char backup[LINE_LENGTH];
-
- if (strlen(opt_prefix) + strlen(file) +
- strlen(opt_suffix) >= sizeof(backup)) {
- perror("Line buffer too small\n");
- return 1;
- }
+ char *backup = alloca(strlen(opt_prefix) + strlen(file) +
+ strlen(opt_suffix) + 1);
- snprintf(backup, sizeof(backup), "%s%s%s",
- opt_prefix, file, opt_suffix);
+ sprintf(backup, "%s%s%s", opt_prefix, file, opt_suffix);
if (opt_what == what_backup) {
struct stat st;
- int new_file = (stat(file, &st) == -1 && errno == ENOENT);
+ int missing_file = (stat(file, &st) == -1 && errno == ENOENT);
unlink(backup);
create_parents(backup);
- if (new_file) {
+ if (missing_file) {
int fd;
if (!opt_silent)
@@ -289,19 +291,56 @@ process_file(char *file)
unlink(backup);
remove_parents(backup);
return 0;
+ } else if (opt_what == what_noop) {
+ struct stat st;
+ int missing_file = (stat(file, &st) == -1 && errno == ENOENT);
+
+ if (!missing_file && opt_nolinks) {
+ if (ensure_nolinks(file))
+ return 1;
+ }
+ return 0;
} else
return 1;
}
int
+walk(const char *path, const struct stat *stat, int flag, struct FTW *ftw)
+{
+ size_t prefix_len=strlen(opt_prefix), suffix_len=strlen(opt_suffix);
+ size_t len = strlen(path);
+ char *p;
+
+ if (flag == FTW_DNR) {
+ perror(path);
+ return 1;
+ }
+ if (!S_ISREG(stat->st_mode))
+ return 0;
+ if (strncmp(opt_prefix, path, prefix_len))
+ return 0; /* prefix does not match */
+ if (len < suffix_len || strcmp(opt_suffix, path + len - suffix_len))
+ return 0; /* suffix does not match */
+
+ p = alloca(len - prefix_len - suffix_len + 1);
+ memcpy(p, path + prefix_len, len - prefix_len - suffix_len);
+ p[len - prefix_len - suffix_len] = '\0';
+ return process_file(p);
+}
+
+int
main(int argc, char *argv[])
{
int opt, status=0;
progname = argv[0];
- while ((opt = getopt(argc, argv, "rxB:z:f:shFL")) != -1) {
+ while ((opt = getopt(argc, argv, "brxB:z:f:shFL")) != -1) {
switch(opt) {
+ case 'b':
+ opt_what = what_backup;
+ break;
+
case 'r':
opt_what = what_restore;
break;
@@ -377,7 +416,17 @@ main(int argc, char *argv[])
}
}
for (; optind < argc; optind++) {
- if ((status = process_file(argv[optind])) != 0)
+ if (strcmp(argv[optind], "-") == 0) {
+ char *dir = strdup(opt_prefix), *d = strrchr(dir, '/');
+ if (d)
+ *(d+1) = '\0';
+ else
+ d = ".";
+ status = nftw(dir, walk, 0, 0);
+ free(dir);
+ } else
+ status = process_file(argv[optind]);
+ if (status)
return status;
}
diff --git a/po/de.po b/po/de.po
index c87a1c3..9103d18 100644
--- a/po/de.po
+++ b/po/de.po
@@ -11,15 +11,15 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../bin/quilt.in:15
+#: ../bin/quilt.in:19
msgid "Usage: quilt [--trace] [--quiltrc=XX] command [-h] ..."
msgstr "Verwendung: quilt [--trace] [--quiltrc=XX] befehl [-h] ..."
-#: ../bin/quilt.in:17
+#: ../bin/quilt.in:21
msgid "Commands are:"
msgstr "Vorhandene Befehle:"
-#: ../bin/quilt.in:22
+#: ../bin/quilt.in:26
msgid ""
"\n"
"Common options to all commands:\n"
@@ -560,7 +560,7 @@ msgstr "Kein Patch entfernt"
msgid "Interrupted by user"
msgstr "Unterbrechung durch Benutzer"
-#: ../quilt/pop.in:183 ../quilt/push.in:216
+#: ../quilt/pop.in:188 ../quilt/push.in:216
msgid "Now at patch $patch"
msgstr "Jetzt in Patch $patch"
@@ -883,23 +883,23 @@ msgstr "Unterbrechung durch Benutzer; Patch $patch wurde nicht angewandt."
msgid "Patch file $patch_file appears to be empty"
msgstr "Patch-Datei $patch_file scheint leer zu sein"
-#: ../scripts/apatch.in:83
+#: ../scripts/apatch.in:80
msgid "Applying $patch"
msgstr "Anwenden von $patch"
-#: ../scripts/apatch.in:119
+#: ../scripts/apatch.in:116
msgid "Patch $patch appears to be empty, applied"
msgstr "Patch $patch scheint leer zu sein, angewandt"
-#: ../scripts/apatch.in:122
+#: ../scripts/apatch.in:119
msgid "Applied $patch (forced; needs refresh)"
msgstr "Patch $patch angewandt (erzwungen, muß aufgefrischt werden (Refresh))"
-#: ../scripts/apatch.in:126
+#: ../scripts/apatch.in:123
msgid "Patch $patch does not apply (enforce with -f)"
msgstr "Patch $patch läßt sich nicht anwenden (erzwingen mit -f)"
-#: ../scripts/apatch.in:183 ../scripts/rpatch.in:189
+#: ../scripts/apatch.in:180 ../scripts/rpatch.in:178
msgid "The topmost patch $top needs to be refreshed first."
msgstr "Der oberste Patch $top muss zuerst aufgefrischt werden (Refresh)."
@@ -911,10 +911,6 @@ msgstr "Verwendung: $0 [-fRq] patchname"
msgid "Patch $patch does not remove cleanly (enforce with -f)."
msgstr "Patch $patch kann nicht entfernt werden (erzwingen mit -f)."
-#: ../scripts/rpatch.in:117
-msgid "Patch $patch appears to be empty, removed"
-msgstr "Patch $patch scheint leer zu sein, entfernt"
-
-#: ../scripts/rpatch.in:131
+#: ../scripts/rpatch.in:122
msgid "Removing $patch"
msgstr "Entferne $patch"
diff --git a/po/fr.po b/po/fr.po
index 86f34a8..61d8f1a 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -12,15 +12,15 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../bin/quilt.in:15
+#: ../bin/quilt.in:19
msgid "Usage: quilt [--trace] [--quiltrc=XX] command [-h] ..."
msgstr "Usage : quilt [--trace] [--quiltrc=XX] commande [-h] ..."
-#: ../bin/quilt.in:17
+#: ../bin/quilt.in:21
msgid "Commands are:"
msgstr "Les commandes sont :"
-#: ../bin/quilt.in:22
+#: ../bin/quilt.in:26
msgid ""
"\n"
"Common options to all commands:\n"
@@ -78,7 +78,7 @@ msgstr "Le patch $patch n'est pas appliqué"
#: ../quilt/add.in:82 ../quilt/delete.in:67 ../quilt/diff.in:168
#: ../quilt/files.in:75 ../quilt/fold.in:78 ../quilt/fork.in:64
-#: ../quilt/pop.in:181 ../quilt/push.in:179 ../quilt/push.in:213
+#: ../quilt/pop.in:181 ../quilt/push.in:179 ../quilt/push.in:214
#: ../quilt/refresh.in:107 ../quilt/remove.in:80
msgid "No patches applied"
msgstr "Aucun patch n'est appliqué"
@@ -565,11 +565,11 @@ msgstr "Le patch $stop_at_patch n'est pas appliqué."
msgid "No patch removed"
msgstr "Aucun patch retiré"
-#: ../quilt/pop.in:172 ../quilt/push.in:204
+#: ../quilt/pop.in:172 ../quilt/push.in:205
msgid "Interrupted by user"
msgstr "Interrompu par l'utilisateur"
-#: ../quilt/pop.in:183 ../quilt/push.in:215
+#: ../quilt/pop.in:188 ../quilt/push.in:216
msgid "Now at patch $patch"
msgstr "Le patch $patch est maintenant au sommet"
@@ -657,7 +657,7 @@ msgstr "Le patch $stop_at_patch est introuvable dans le fichier de série"
msgid "Patch $stop_at_patch is already applied."
msgstr "Le patch $stop_at_patch est déjà appliqué."
-#: ../quilt/push.in:183
+#: ../quilt/push.in:184
msgid ""
"The topmost patch $top is not in the series file anymore;\n"
"cannot determine the next patch from the series file.\n"
@@ -668,7 +668,7 @@ msgstr ""
"Veuillez utiliser pop -f pour le patch du sommet, et vérifier \n"
"votre fichier de série."
-#: ../quilt/push.in:189
+#: ../quilt/push.in:190
msgid "File series fully applied, ends at patch $top"
msgstr "La série est complètement appliquée. Le dernier patch est $top."
@@ -800,7 +800,8 @@ msgstr ""
#: ../quilt/setup.in:27
msgid "Usage: quilt setup [-d path-prefix] [-v] {specfile|seriesfile}"
-msgstr "Usage : quilt setup [-d répertoire_source] [-v] {fichier_séries|fichier_spec}"
+msgstr ""
+"Usage : quilt setup [-d répertoire_source] [-v] {fichier_séries|fichier_spec}"
#: ../quilt/setup.in:30
msgid ""
@@ -812,7 +813,8 @@ msgid ""
"-v\tverbose debug output."
msgstr ""
"\n"
-"Initialise un arbre de sources à partir d'un fichier de spécification rpm, ou d'un fichier de série quilt.\n"
+"Initialise un arbre de sources à partir d'un fichier de spécification rpm, "
+"ou d'un fichier de série quilt.\n"
"\n"
"-d\tpréfix de chemin optionel (sous-répertoire).\n"
"\n"
@@ -898,24 +900,24 @@ msgstr "Interrompu par l'utilisateur ; le patch $patch n'a pas été appliqué."
msgid "Patch file $patch_file appears to be empty"
msgstr "Le fichier de patch $patch_file semble vide"
-#: ../scripts/apatch.in:83
+#: ../scripts/apatch.in:80
msgid "Applying $patch"
msgstr "Application de $patch"
-#: ../scripts/apatch.in:119
+#: ../scripts/apatch.in:116
msgid "Patch $patch appears to be empty, applied"
msgstr "Le patch $patch semble vide. Il a été appliqué."
-#: ../scripts/apatch.in:122
+#: ../scripts/apatch.in:119
msgid "Applied $patch (forced; needs refresh)"
msgstr "$patch a été appliqué (forcé ; vous devriez le rafraîchir)"
-#: ../scripts/apatch.in:126
+#: ../scripts/apatch.in:123
msgid "Patch $patch does not apply (enforce with -f)"
msgstr ""
"Le patch $patch ne s'applique pas proprement (forcez l'application avec -f)"
-#: ../scripts/apatch.in:183 ../scripts/rpatch.in:189
+#: ../scripts/apatch.in:180 ../scripts/rpatch.in:178
msgid "The topmost patch $top needs to be refreshed first."
msgstr "Le patch au sommet $top doit être rafraichi au préalable."
@@ -927,10 +929,6 @@ msgstr "Usage: $0 [-fRq] nom_de_patch"
msgid "Patch $patch does not remove cleanly (enforce with -f)."
msgstr "Le patch $patch ne se retire pas proprement (forcez avec -f)"
-#: ../scripts/rpatch.in:117
-msgid "Patch $patch appears to be empty, removed"
-msgstr "Le patch $patch semble vide. Il a été retiré."
-
-#: ../scripts/rpatch.in:131
+#: ../scripts/rpatch.in:122
msgid "Removing $patch"
msgstr "Retrait de $patch"
diff --git a/po/quilt.pot b/po/quilt.pot
index d903fe4..7473b55 100644
--- a/po/quilt.pot
+++ b/po/quilt.pot
@@ -1,12 +1,12 @@
-#: ../bin/quilt.in:15
+#: ../bin/quilt.in:19
msgid "Usage: quilt [--trace] [--quiltrc=XX] command [-h] ..."
msgstr ""
-#: ../bin/quilt.in:17
+#: ../bin/quilt.in:21
msgid "Commands are:"
msgstr ""
-#: ../bin/quilt.in:22
+#: ../bin/quilt.in:26
msgid ""
"\n"
"Common options to all commands:\n"
@@ -417,7 +417,7 @@ msgstr ""
msgid "Interrupted by user"
msgstr ""
-#: ../quilt/pop.in:183 ../quilt/push.in:216
+#: ../quilt/pop.in:188 ../quilt/push.in:216
msgid "Now at patch $patch"
msgstr ""
@@ -653,23 +653,23 @@ msgstr ""
msgid "Patch file $patch_file appears to be empty"
msgstr ""
-#: ../scripts/apatch.in:83
+#: ../scripts/apatch.in:80
msgid "Applying $patch"
msgstr ""
-#: ../scripts/apatch.in:119
+#: ../scripts/apatch.in:116
msgid "Patch $patch appears to be empty, applied"
msgstr ""
-#: ../scripts/apatch.in:122
+#: ../scripts/apatch.in:119
msgid "Applied $patch (forced; needs refresh)"
msgstr ""
-#: ../scripts/apatch.in:126
+#: ../scripts/apatch.in:123
msgid "Patch $patch does not apply (enforce with -f)"
msgstr ""
-#: ../scripts/apatch.in:183 ../scripts/rpatch.in:189
+#: ../scripts/apatch.in:180 ../scripts/rpatch.in:178
msgid "The topmost patch $top needs to be refreshed first."
msgstr ""
@@ -681,10 +681,6 @@ msgstr ""
msgid "Patch $patch does not remove cleanly (enforce with -f)."
msgstr ""
-#: ../scripts/rpatch.in:117
-msgid "Patch $patch appears to be empty, removed"
-msgstr ""
-
-#: ../scripts/rpatch.in:131
+#: ../scripts/rpatch.in:122
msgid "Removing $patch"
msgstr ""
diff --git a/quilt.changes b/quilt.changes
index 7ba2ba0..8efae38 100644
--- a/quilt.changes
+++ b/quilt.changes
@@ -1,4 +1,16 @@
-------------------------------------------------------------------
+Sun Jun 6 02:02:32 CEST 2004 - agruen@suse.de
+
+- backup-file.c: Add code to recursively search .pc directories.
+ Add a "no-op" mode as default, and allow to just unlink files.
+- apatch/rpatch: let backup-files search .pc directories instead
+ of generating temporary file lists.
+- rpatch/pop: unlink files of topmost patch after popping instead
+ of unlinking at each step.
+- If QUILTRC is set in the environment, use this as the
+ configuration file.
+
+-------------------------------------------------------------------
Sat Jun 5 16:12:17 CEST 2004 - agruen@suse.de
- Return exit status 2 when commands go beyond the series (top
diff --git a/quilt/add.in b/quilt/add.in
index 55613ee..0dd0c5e 100644
--- a/quilt/add.in
+++ b/quilt/add.in
@@ -101,7 +101,7 @@ do
continue
fi
- if ! @LIB@/backup-files -s -L -B $QUILT_PC/$patch/ $SUBDIR$file
+ if ! @LIB@/backup-files -b -s -L -B $QUILT_PC/$patch/ $SUBDIR$file
then
echo $"Failed to back up file $SUBDIR$file" >&2
status=1
diff --git a/quilt/pop.in b/quilt/pop.in
index 2a8e62f..b80eac4 100644
--- a/quilt/pop.in
+++ b/quilt/pop.in
@@ -180,6 +180,11 @@ if [ -z "$patch" ]
then
echo $"No patches applied"
else
+ # Ensure that the files in the topmost patch have a link count
+ # of one: This will automatically be the case in the usual
+ # situations, but we don't want to risk file corruption in weird
+ # corner cases such as files added to a patch but not modified.
+ @LIB@/backup-files -L -s -B $QUILT_PC/$patch/ -
echo $"Now at patch $patch"
fi
### Local Variables:
diff --git a/quilt/remove.in b/quilt/remove.in
index 53e4f75..1003659 100644
--- a/quilt/remove.in
+++ b/quilt/remove.in
@@ -101,7 +101,7 @@ do
fi
# Restore file from backup
- if ! @LIB@/backup-files -s -B $QUILT_PC/$patch/ -r $SUBDIR$file
+ if ! @LIB@/backup-files -b -s -B $QUILT_PC/$patch/ -r $SUBDIR$file
then
echo $"Failed to remove file $SUBDIR$file from patch $patch"
status=1
diff --git a/quilt/snapshot.in b/quilt/snapshot.in
index 172a3df..f92e149 100644
--- a/quilt/snapshot.in
+++ b/quilt/snapshot.in
@@ -67,14 +67,13 @@ snap_subdir=.snap
# Clean up from previous snapshot
rm -rf $QUILT_PC/$snap_subdir
-mkdir -p $QUILT_PC/$snap_subdir
-
if [ -n "$opt_remove" ]
then
exit 0
fi
# Save current working state
+mkdir -p $QUILT_PC/$snap_subdir
for patch in $(applied_patches); do
files_in_patch $patch
done \
@@ -85,7 +84,7 @@ done \
}
{ print }
' \
-| @LIB@/backup-files -s -L -f - -B "$QUILT_PC/$snap_subdir/"
+| @LIB@/backup-files -b -s -L -f - -B "$QUILT_PC/$snap_subdir/"
### Local Variables:
### mode: shell-script
diff --git a/scripts/apatch.in b/scripts/apatch.in
index 94c74b4..38235cc 100755
--- a/scripts/apatch.in
+++ b/scripts/apatch.in
@@ -62,17 +62,14 @@ apply_patch()
rollback_patch()
{
- local patch=$1 pc_file=$(gen_tempfile)
+ local patch=$1
- # FIXME backup_files should scan the directory hierarchy itself.
- files_in_patch $patch > $pc_file
- @LIB@/backup-files $silent_unless_verbose \
- -f $pc_file -B $QUILT_PC/$patch/ -r
if [ -z "$opt_leave_rejects" ]
then
- @SED@ -e 's/$/\.rej/' $pc_file | xargs rm -f
+ files_in_patch | @SED@ -e 's/$/\.rej/' | xargs rm -f
fi
- rm -f $pc_file
+
+ @LIB@/backup-files $silent_unless_verbose -r -B $QUILT_PC/$patch/ -
}
apatch()
diff --git a/scripts/rpatch.in b/scripts/rpatch.in
index 9b5d6e7..bbe988f 100755
--- a/scripts/rpatch.in
+++ b/scripts/rpatch.in
@@ -49,7 +49,7 @@ files_may_have_changed()
# and report any pending changes.
check_for_pending_changes()
{
- local patch=$1 pc_file=$2
+ local patch=$1
local patch_file=$(patch_file_name $patch)
local patch_args=$(patch_args $patch)
local workdir=$(gen_tempfile -d quilt) status=0
@@ -90,10 +90,10 @@ check_for_pending_changes()
fi
local remains=$(gen_tempfile)
- while read file
+ for file in $(files_in_patch $patch)
do
diff_file $file $workdir/$file $file >> $remains
- done < $pc_file
+ done
if [ -s $remains ]
then
@@ -108,35 +108,24 @@ check_for_pending_changes()
rpatch()
{
- local patch=$1 pc_file=$(gen_tempfile) status=0
-
- # FIXME backup-files should scan the directory tree itself.
- files_in_patch $patch > $pc_file
- if ! [ -s $pc_file ]
- then
- echo $"Patch $patch appears to be empty, removed"
- remove_from_db $patch
- return 0
- fi
+ local patch=$1 status=0
trap "" SIGINT
if [ -z "$opt_force" ] && \
( [ -n "$opt_remove" ] || files_may_have_changed $patch )
then
- check_for_pending_changes $patch $pc_file || status=1
+ check_for_pending_changes $patch || status=1
fi
if [ $status -eq 0 ]
then
echo $"Removing $patch"
rm -f "$QUILT_PC/$patch/.timestamp"
- @LIB@/backup-files $silent -r -L -f $pc_file \
- -B $QUILT_PC/$patch/
+ @LIB@/backup-files $silent -r -B $QUILT_PC/$patch/ -
status=$?
remove_from_db $patch
rm -f $QUILT_PC/$patch~refresh
fi
- rm -f $pc_file
trap - SIGINT
return $status
}
diff --git a/test/new.test b/test/new.test
new file mode 100644
index 0000000..dfa8f64
--- /dev/null
+++ b/test/new.test
@@ -0,0 +1,53 @@
+ $ mkdir -p d/patches
+ $ cd d
+
+ $ echo reject > f
+ $ echo p.diff > patches/series
+ $ cat > patches/p.diff
+ < --- d.orig/f
+ < +++ d/f
+ < @@ -1 +1 @@
+ < -old
+ < +new
+ < --- d.orig/g
+ < +++ d/g
+ < @@ -0,0 +1 @@
+ < +added
+
+
+ $ quilt push
+ > Applying p.diff
+ > patching file f
+ > Hunk #1 FAILED at 1.
+ > 1 out of 1 hunk FAILED -- rejects in file f
+ > patching file g
+ > Patch p.diff does not apply (enforce with -f)
+
+ $ quilt push -f
+ > Applying p.diff
+ > patching file f
+ > Hunk #1 FAILED at 1.
+ > 1 out of 1 hunk FAILED -- saving rejects to file f.rej
+ > patching file g
+ > Applied p.diff (forced; needs refresh)
+
+ $ echo new > f
+ $ quilt refresh
+ > Refreshed patch p.diff
+ $ cat patches/p.diff | sed -e "s/\\t.*//"
+ > Index: d/f
+ > ===================================================================
+ > --- d.orig/f
+ > +++ d/f
+ > @@ -1 +1 @@
+ > -reject
+ > +new
+ > Index: d/g
+ > ===================================================================
+ > --- d.orig/g
+ > +++ d/g
+ > @@ -0,0 +1 @@
+ > +added
+
+ $ cd ..
+ $ rm -rf d
diff --git a/test/test.quiltrc b/test/test.quiltrc
new file mode 100644
index 0000000..468812d
--- /dev/null
+++ b/test/test.quiltrc
@@ -0,0 +1,2 @@
+# Define this to generate diffs without timestamps.
+QUILT_NO_DIFF_TIMESTAMPS=yes