| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- From 47548a77525a0f4489c9c420ccc2159079365da8 Mon Sep 17 00:00:00 2001
- From: Bruno Haible <[email protected]>
- Date: Fri, 2 May 2025 12:09:40 +0200
- Subject: [PATCH] vc-mtime: Make it work with git versions < 2.28.
- * lib/vc-mtime.c (git_version): New variable.
- (is_git_present): Read the output of "git --version", and set
- git_version.
- (max_vc_mtime): Don't pass option --no-relative if the git version
- is < 2.28.
- ---
- ChangeLog | 9 ++++++
- lib/vc-mtime.c | 82 +++++++++++++++++++++++++++++++++++++++++++++-----
- 2 files changed, 83 insertions(+), 8 deletions(-)
- --- a/lib/vc-mtime.c
- +++ b/lib/vc-mtime.c
- @@ -53,7 +53,9 @@
-
- /* ========================================================================== */
-
- -/* Determines whether git is present. */
- +static const char *git_version;
- +
- +/* Determines whether git is present, and sets git_version if so. */
- static bool
- is_git_present (void)
- {
- @@ -63,17 +65,67 @@ is_git_present (void)
- if (!git_tested)
- {
- /* Test for presence of git:
- - "git --version >/dev/null 2>/dev/null" */
- + "git --version 2>/dev/null" */
- const char *argv[3];
- - int exitstatus;
- + pid_t child;
- + int fd[1];
-
- argv[0] = "git";
- argv[1] = "--version";
- argv[2] = NULL;
- - exitstatus = execute ("git", "git", argv, NULL, NULL,
- - false, false, true, true,
- - true, false, NULL);
- - git_present = (exitstatus == 0);
- + child = create_pipe_in ("git", "git", argv, NULL, NULL,
- + DEV_NULL, true, true, false, fd);
- + if (child == -1)
- + git_present = false;
- + else
- + {
- + /* Retrieve its result. */
- + FILE *fp = fdopen (fd[0], "r");
- + if (fp == NULL)
- + error (EXIT_FAILURE, errno, _("fdopen() failed"));
- +
- + char *line = NULL;
- + size_t linesize = 0;
- + size_t linelen = getline (&line, &linesize, fp);
- + if (linelen == (size_t)(-1))
- + {
- + fclose (fp);
- + wait_subprocess (child, "git", true, true, true, false, NULL);
- + git_present = false;
- + }
- + else
- + {
- + if (linelen > 0 && line[linelen - 1] == '\n')
- + line[linelen - 1] = '\0';
- +
- + /* Read until EOF (otherwise the child process may get a SIGPIPE
- + signal). */
- + while (getc (fp) != EOF)
- + ;
- +
- + fclose (fp);
- +
- + /* Remove zombie process from process list, and retrieve exit
- + status. */
- + int exitstatus =
- + wait_subprocess (child, "git", true, true, true, false, NULL);
- + if (exitstatus != 0)
- + {
- + free (line);
- + git_present = false;
- + }
- + else
- + {
- + /* The version starts at the first digit in the line. */
- + const char *p = line;
- + for (; *p != '0'; p++)
- + if (*p >= '0' && *p <= '9')
- + break;
- + git_version = p;
- + git_present = true;
- + }
- + }
- + }
- git_tested = true;
- }
-
- @@ -660,7 +712,21 @@ max_vc_mtime (struct timespec *max_of_mt
- argv[i++] = "git";
- argv[i++] = "diff";
- argv[i++] = "--name-only";
- - argv[i++] = "--no-relative";
- + /* With git versions >= 2.28, we pass option --no-relative,
- + in order to neutralize any possible customization of the
- + "diff.relative" property. With git versions < 2.28, this
- + is not needed, and the option --no-relative does not
- + exist. */
- + if (!(git_version[0] <= '1'
- + || (git_version[0] == '2' && git_version[1] == '.'
- + && ((git_version[2] >= '0' && git_version[2] <= '9'
- + && !(git_version[3] >= '0' && git_version[3] <= '9'))
- + || (((git_version[2] == '1'
- + && git_version[3] >= '0' && git_version[3] <= '9')
- + || (git_version[2] == '2'
- + && git_version[3] >= '0' && git_version[3] <= '7'))
- + && !(git_version[4] >= '0' && git_version[4] <= '9'))))))
- + argv[i++] = "--no-relative";
- argv[i++] = "-z";
- argv[i++] = "HEAD";
- argv[i++] = "--";
|