summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/manual/repo.md16
-rw-r--r--src/libostree/ostree-repo-checkout.c4
-rw-r--r--src/libostree/ostree-repo-commit.c8
-rw-r--r--src/libostree/ostree-repo-libarchive.c6
-rw-r--r--src/libostree/ostree-repo-private.h2
-rw-r--r--src/libostree/ostree-repo.c8
-rwxr-xr-xtests/basic-test.sh4
7 files changed, 35 insertions, 13 deletions
diff --git a/docs/manual/repo.md b/docs/manual/repo.md
index d6f67090..bce7e0c9 100644
--- a/docs/manual/repo.md
+++ b/docs/manual/repo.md
@@ -47,6 +47,22 @@ payload sections. The header contains uid, gid, mode, and symbolic
link target (for symlinks), as well as extended attributes. After the
header, for regular files, the content follows.
+The OSTree data format intentionally does not contain timestamps. The reasoning
+is that data files may be downloaded at different times, and by different build
+systems, and so will have different timestamps but identical physical content.
+These files may be large, so most users would like them to be shared, both in
+the repository and between the repository and deployments.
+
+This could cause problems with programs that check if files are out-of-date by
+comparing timestamps. For Git, the logical choice is to not mess with
+timestamps, because unnecessary rebuilding is better than a broken tree.
+However, OSTree has to hardlink files to check them out, and commits are assumed
+to be internally consistent with no build steps needed. For this reason, OSTree
+acts as though all timestamps are set to time_t 1, so that comparisons will be
+considered up-to-date. 1 is a better choice than 0 because some programs use 0
+as a special value; for example, GNU Tar warns of an "implausibly old time
+stamp" with 0.
+
# Repository types and locations
Also unlike git, an OSTree repository can be in one of three separate
diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c
index 95d3747b..227227b6 100644
--- a/src/libostree/ostree-repo-checkout.c
+++ b/src/libostree/ostree-repo-checkout.c
@@ -752,12 +752,12 @@ checkout_tree_at (OstreeRepo *self,
}
}
- /* Set directory mtime to 0, so that it is constant for all checkouts.
+ /* Set directory mtime to OSTREE_TIMESTAMP, so that it is constant for all checkouts.
* Must be done after setting permissions and creating all children.
*/
if (!did_exist)
{
- const struct timespec times[2] = { { 0, UTIME_OMIT }, { 0, } };
+ const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} };
do
res = futimens (destination_dfd, times);
while (G_UNLIKELY (res == -1 && errno == EINTR));
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 6cb46ca9..6166c652 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -210,7 +210,6 @@ commit_loose_object_trusted (OstreeRepo *self,
else
{
int res;
- struct timespec times[2];
if (objtype == OSTREE_OBJECT_TYPE_FILE && self->mode == OSTREE_REPO_MODE_BARE)
{
@@ -266,12 +265,9 @@ commit_loose_object_trusted (OstreeRepo *self,
{
/* To satisfy tools such as guile which compare mtimes
* to determine whether or not source files need to be compiled,
- * set the modification time to 0.
+ * set the modification time to OSTREE_TIMESTAMP.
*/
- times[0].tv_sec = 0; /* atime */
- times[0].tv_nsec = UTIME_OMIT;
- times[1].tv_sec = 0; /* mtime */
- times[1].tv_nsec = 0;
+ const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} };
do
res = futimens (fd, times);
while (G_UNLIKELY (res == -1 && errno == EINTR));
diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c
index 0d62124d..45427ef7 100644
--- a/src/libostree/ostree-repo-libarchive.c
+++ b/src/libostree/ostree-repo-libarchive.c
@@ -982,9 +982,9 @@ file_to_archive_entry_common (GFile *root,
}
archive_entry_update_pathname_utf8 (entry, pathstr);
- archive_entry_set_ctime (entry, ts, 0);
- archive_entry_set_mtime (entry, ts, 0);
- archive_entry_set_atime (entry, ts, 0);
+ archive_entry_set_ctime (entry, ts, OSTREE_TIMESTAMP);
+ archive_entry_set_mtime (entry, ts, OSTREE_TIMESTAMP);
+ archive_entry_set_atime (entry, ts, OSTREE_TIMESTAMP);
archive_entry_set_uid (entry, g_file_info_get_attribute_uint32 (file_info, "unix::uid"));
archive_entry_set_gid (entry, g_file_info_get_attribute_uint32 (file_info, "unix::gid"));
archive_entry_set_mode (entry, g_file_info_get_attribute_uint32 (file_info, "unix::mode"));
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index 62a3c8f6..35b05c76 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -36,6 +36,8 @@ G_BEGIN_DECLS
#define _OSTREE_SUMMARY_CACHE_DIR "summaries"
#define _OSTREE_CACHE_DIR "cache"
+#define OSTREE_TIMESTAMP (1)
+
typedef enum {
OSTREE_REPO_TEST_ERROR_PRE_COMMIT = (1 << 0)
} OstreeRepoTestErrorFlags;
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 6af5d8e6..fd02833a 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -942,6 +942,14 @@ ostree_repo_is_writable (OstreeRepo *self,
return self->writable;
}
+/**
+ * _ostree_repo_update_mtime:
+ * @self: Repo
+ * @error: a #GError
+ *
+ * Bump the mtime of the repository so that programs
+ * can detect that the refs have updated.
+ */
gboolean
_ostree_repo_update_mtime (OstreeRepo *self,
GError **error)
diff --git a/tests/basic-test.sh b/tests/basic-test.sh
index 93f67f17..0fe372dc 100755
--- a/tests/basic-test.sh
+++ b/tests/basic-test.sh
@@ -386,9 +386,9 @@ else
$OSTREE checkout test2 test2-checkout
fi
stat '--format=%Y' test2-checkout/baz/cow > cow-mtime
-assert_file_has_content cow-mtime 0
+assert_file_has_content cow-mtime 1
stat '--format=%Y' test2-checkout/baz/deeper > deeper-mtime
-assert_file_has_content deeper-mtime 0
+assert_file_has_content deeper-mtime 1
echo "ok content mtime"
cd ${test_tmpdir}