Hash :
78269749
Author :
Date :
2025-05-01T17:26:27
vc-mtime: Add API for more efficient use of git. Reported by Serhii Tereshchenko, Arthur, Adam YS, Foucauld Degeorges at <https://savannah.gnu.org/bugs/?66865>. * lib/vc-mtime.h (max_vc_mtime): New declaration. * lib/vc-mtime.c: Include <errno.h>, <stdio.h>, <string.h>, filename.h, xalloc.h, xgetcwd.h, xvasprintf.h, gl_map.h, gl_xmap.h, gl_hash_map.h, hashkey-string.h, unlocked-io.h. (is_git_present): New function, extracted from vc_mtime. (vc_mtime): Invoke it. (MAX_COMMAND_LENGTH, MAX_CMD_LEN): New macros. (abs_git_checkout): New function, based on execute_and_read_line in lib/javacomp.c. (ancestor_level, relativize): New functions. (struct accumulator): New type. (accumulate): New function. (max_vc_mtime): New function. (test_ancestor_level, test_relativize, main) [TEST]: New functions. * modules/vc-mtime (Depends-on): Add filename, xalloc, xgetcwd, canonicalize-lgpl, xvasprintf, str_startswith, map, xmap, hash-map, hashkey-string, getdelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
/* Return the version-control based modification time of a file.
Copyright (C) 2025 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
#ifndef _VC_MTIME_H
#define _VC_MTIME_H
/* Get struct timespec. */
#include <time.h>
/* The "version-controlled modification time" vc_mtime(F) of a file F
is defined as:
- If F is under version control and not modified locally:
the time of the last change of F in the version control system.
- Otherwise: The modification time of F on disk.
For now, the only VCS supported by this module is git. (hg and svn are
hardly in use any more.)
This has the properties that:
- Different users who have checked out the same git repo on different
machines, at different times, and not done local modifications,
get the same vc_mtime(F).
- If a user has modified F locally, the modification time of that file
counts.
- If that user then reverts the modification, they then again get the
same vc_mtime(F) as everyone else.
- Different users who have unpacked the same tarball (without .git
directory) on different machines, at different times, also get the same
vc_mtime(F) [but possibly a different one than when the .git directory
was present]. (Assuming a POSIX compliant file system.)
- When a user commits local modifications into git, this only increases
(not decreases) the vc_mtime(F).
The purpose of the version-controlled modification time is to produce a
reproducible timestamp(Z) of a file Z that depends on files X1, ..., Xn,
in such a way that
- timestamp(Z) is reproducible, that is, different users on different
machines get the same value.
- timestamp(Z) is related to reality. It's not just a dummy, like what
is suggested in <https://reproducible-builds.org/docs/timestamps/>.
- One can arrange for timestamp(Z) to respect the modification time
relations of a build system.
There are two uses of such a timestamp:
- It can be set as the modification time of file Z in a file system, or
- It can be embedded in Z, with the purpose of telling a user how old
the file Z is. For example, in PDF files or in generated documentation,
such a time is embedded in a special place.
The simplest example is a file Z that depends on files X1, ..., Xn.
Generally one will define
timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn))
for an embedded timestamp, or
timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn)) + 1 second
for a time stamp in a file system. The added second
1. accounts for fractional seconds in mtime(X1), ..., mtime(Xn),
2. allows for 'make' implementation that attempt to rebuild Z
if mtime(Z) == mtime(Xi).
A more complicated example is when there are intermediate built files, not
under version control. For example, if the build process produces
X1, X2 -> Y1
X3, X4 -> Y2
Y1, Y2, X5 -> Z
where Y1 and Y2 are intermediate built files, you should ignore the
mtime(Y1), mtime(Y2), and consider only the vc_mtime(X1), ..., vc_mtime(X5).
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Determines the version-controlled modification time of FILENAME, stores it
in *MTIME, and returns 0.
Upon failure, it returns -1. */
extern int vc_mtime (struct timespec *mtime, const char *filename);
/* Determines the maximum of the version-controlled modification times of
FILENAMES[0..NFILES-1], and returns 0.
Upon failure, it returns -1.
NFILES must be > 0. */
extern int max_vc_mtime (struct timespec *max_of_mtimes,
size_t nfiles, const char * const *filenames);
#ifdef __cplusplus
}
#endif
#endif /* _VC_MTIME_H */