799-vc-mtime-old-git.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. From 47548a77525a0f4489c9c420ccc2159079365da8 Mon Sep 17 00:00:00 2001
  2. From: Bruno Haible <[email protected]>
  3. Date: Fri, 2 May 2025 12:09:40 +0200
  4. Subject: [PATCH] vc-mtime: Make it work with git versions < 2.28.
  5. * lib/vc-mtime.c (git_version): New variable.
  6. (is_git_present): Read the output of "git --version", and set
  7. git_version.
  8. (max_vc_mtime): Don't pass option --no-relative if the git version
  9. is < 2.28.
  10. ---
  11. ChangeLog | 9 ++++++
  12. lib/vc-mtime.c | 82 +++++++++++++++++++++++++++++++++++++++++++++-----
  13. 2 files changed, 83 insertions(+), 8 deletions(-)
  14. --- a/lib/vc-mtime.c
  15. +++ b/lib/vc-mtime.c
  16. @@ -53,7 +53,9 @@
  17. /* ========================================================================== */
  18. -/* Determines whether git is present. */
  19. +static const char *git_version;
  20. +
  21. +/* Determines whether git is present, and sets git_version if so. */
  22. static bool
  23. is_git_present (void)
  24. {
  25. @@ -63,17 +65,67 @@ is_git_present (void)
  26. if (!git_tested)
  27. {
  28. /* Test for presence of git:
  29. - "git --version >/dev/null 2>/dev/null" */
  30. + "git --version 2>/dev/null" */
  31. const char *argv[3];
  32. - int exitstatus;
  33. + pid_t child;
  34. + int fd[1];
  35. argv[0] = "git";
  36. argv[1] = "--version";
  37. argv[2] = NULL;
  38. - exitstatus = execute ("git", "git", argv, NULL, NULL,
  39. - false, false, true, true,
  40. - true, false, NULL);
  41. - git_present = (exitstatus == 0);
  42. + child = create_pipe_in ("git", "git", argv, NULL, NULL,
  43. + DEV_NULL, true, true, false, fd);
  44. + if (child == -1)
  45. + git_present = false;
  46. + else
  47. + {
  48. + /* Retrieve its result. */
  49. + FILE *fp = fdopen (fd[0], "r");
  50. + if (fp == NULL)
  51. + error (EXIT_FAILURE, errno, _("fdopen() failed"));
  52. +
  53. + char *line = NULL;
  54. + size_t linesize = 0;
  55. + size_t linelen = getline (&line, &linesize, fp);
  56. + if (linelen == (size_t)(-1))
  57. + {
  58. + fclose (fp);
  59. + wait_subprocess (child, "git", true, true, true, false, NULL);
  60. + git_present = false;
  61. + }
  62. + else
  63. + {
  64. + if (linelen > 0 && line[linelen - 1] == '\n')
  65. + line[linelen - 1] = '\0';
  66. +
  67. + /* Read until EOF (otherwise the child process may get a SIGPIPE
  68. + signal). */
  69. + while (getc (fp) != EOF)
  70. + ;
  71. +
  72. + fclose (fp);
  73. +
  74. + /* Remove zombie process from process list, and retrieve exit
  75. + status. */
  76. + int exitstatus =
  77. + wait_subprocess (child, "git", true, true, true, false, NULL);
  78. + if (exitstatus != 0)
  79. + {
  80. + free (line);
  81. + git_present = false;
  82. + }
  83. + else
  84. + {
  85. + /* The version starts at the first digit in the line. */
  86. + const char *p = line;
  87. + for (; *p != '0'; p++)
  88. + if (*p >= '0' && *p <= '9')
  89. + break;
  90. + git_version = p;
  91. + git_present = true;
  92. + }
  93. + }
  94. + }
  95. git_tested = true;
  96. }
  97. @@ -660,7 +712,21 @@ max_vc_mtime (struct timespec *max_of_mt
  98. argv[i++] = "git";
  99. argv[i++] = "diff";
  100. argv[i++] = "--name-only";
  101. - argv[i++] = "--no-relative";
  102. + /* With git versions >= 2.28, we pass option --no-relative,
  103. + in order to neutralize any possible customization of the
  104. + "diff.relative" property. With git versions < 2.28, this
  105. + is not needed, and the option --no-relative does not
  106. + exist. */
  107. + if (!(git_version[0] <= '1'
  108. + || (git_version[0] == '2' && git_version[1] == '.'
  109. + && ((git_version[2] >= '0' && git_version[2] <= '9'
  110. + && !(git_version[3] >= '0' && git_version[3] <= '9'))
  111. + || (((git_version[2] == '1'
  112. + && git_version[3] >= '0' && git_version[3] <= '9')
  113. + || (git_version[2] == '2'
  114. + && git_version[3] >= '0' && git_version[3] <= '7'))
  115. + && !(git_version[4] >= '0' && git_version[4] <= '9'))))))
  116. + argv[i++] = "--no-relative";
  117. argv[i++] = "-z";
  118. argv[i++] = "HEAD";
  119. argv[i++] = "--";