summaryrefslogtreecommitdiff
path: root/src/metaentry.c
diff options
context:
space:
mode:
authorAdam Spragg <adam@spra.gg>2022-05-18 10:42:10 +0100
committerAdam Spragg <adam@spra.gg>2022-05-18 17:19:47 +0100
commitce62a76e4570b6368384b3995c1ba106389df454 (patch)
tree6c64057c5d228f7b543b6ed538e15146254b9481 /src/metaentry.c
parent260fc47f01ef64368721ec93de4cbd988357b32b (diff)
Sort entries in Format 1 files by path, ASCIIbetically.
This ensures that the files are stable, and not subject to the order in which the OS returns directory entries. This should prevent unnecessary changes, and therefore unnecessary merge conflicts.
Diffstat (limited to 'src/metaentry.c')
-rw-r--r--src/metaentry.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/src/metaentry.c b/src/metaentry.c
index ed0e23d..7f1012f 100644
--- a/src/metaentry.c
+++ b/src/metaentry.c
@@ -432,50 +432,84 @@ mentries_tofile_v0(const struct metahash *mhash, FILE * to)
}
}
+/* Compare two mentries by path */
+static int
+mentry_cmp_path(const struct metaentry *a, const struct metaentry *b)
+{
+ return strcmp(a->path, b->path);
+}
+
+/* Compare two mentries by path, as is sutiable for qsort(3) */
+static int
+mentry_cmp_path_q(const void *a, const void *b)
+{
+ return mentry_cmp_path(*((const struct metaentry **) a),
+ *((const struct metaentry **) b));
+}
+
/* Stores metaentries to a Format 1 file */
static void
mentries_tofile_v1(const struct metahash *mhash, FILE * to)
{
const struct metaentry *mentry;
- int key;
+ const struct metaentry **entarr;
+ int key, entries = 0;
struct tm tm;
char tmbuf[20];
unsigned i;
- fputc('\n', to);
+ for (key = 0; key < HASH_INDEXES; key++) {
+ for (mentry = mhash->bucket[key]; mentry; mentry = mentry->next) {
+ ++entries;
+ }
+ }
+ entarr = xmalloc(entries * sizeof(struct metaentry *));
+ i = 0;
for (key = 0; key < HASH_INDEXES; key++) {
for (mentry = mhash->bucket[key]; mentry; mentry = mentry->next) {
- write_string_url(mentry->path, to);
+ entarr[i++] = mentry;
+ }
+ }
- fputc('\t', to);
- write_string_url(mentry->owner, to);
+ qsort(entarr, entries, sizeof(struct metaentry *), mentry_cmp_path_q);
- fputc('\t', to);
- write_string_url(mentry->group, to);
+ fputc('\n', to);
- fputc('\t', to);
- fprintf(to, "%.6o", mentry->mode);
+ for (key = 0; key < entries; key++) {
+ mentry = entarr[key];
- fputc('\t', to);
- gmtime_r(&mentry->mtime, &tm);
- strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%dT%H:%M:%S", &tm);
- fputs(tmbuf, to);
+ write_string_url(mentry->path, to);
- fputc('.', to);
- fprintf(to, "%.9ldZ", mentry->mtimensec);
+ fputc('\t', to);
+ write_string_url(mentry->owner, to);
- for (i = 0; i < mentry->xattrs; i++) {
- fputc('\t', to);
- write_string_url(mentry->xattr_names[i], to);
- fputc('\t', to);
- write_binary_url(mentry->xattr_values[i],
- mentry->xattr_lvalues[i], to);
- }
+ fputc('\t', to);
+ write_string_url(mentry->group, to);
- fputc('\n', to);
+ fputc('\t', to);
+ fprintf(to, "%.6o", mentry->mode);
+
+ fputc('\t', to);
+ gmtime_r(&mentry->mtime, &tm);
+ strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%dT%H:%M:%S", &tm);
+ fputs(tmbuf, to);
+
+ fputc('.', to);
+ fprintf(to, "%.9ldZ", mentry->mtimensec);
+
+ for (i = 0; i < mentry->xattrs; i++) {
+ fputc('\t', to);
+ write_string_url(mentry->xattr_names[i], to);
+ fputc('\t', to);
+ write_binary_url(mentry->xattr_values[i],
+ mentry->xattr_lvalues[i], to);
}
+
+ fputc('\n', to);
}
+
+ free(entarr);
}
/* Stores metaentries to a file */