Print this page
3272 findunref should support git

@@ -74,12 +74,12 @@
         const char      *name;
         checkscm_func_t *checkfunc;
         chdirscm_func_t *chdirfunc;
 } scm_t;
 
-static checkscm_func_t check_tw, check_hg;
-static chdirscm_func_t chdir_hg;
+static checkscm_func_t check_tw, check_hg, check_git;
+static chdirscm_func_t chdir_hg, chdir_git;
 static int      pnset_add(pnset_t *, const char *);
 static int      pnset_check(const pnset_t *, const char *);
 static void     pnset_empty(pnset_t *);
 static void     pnset_free(pnset_t *);
 static int      checkpath(const char *, const struct stat *, int, struct FTW *);

@@ -90,15 +90,17 @@
 static const scm_t scms[] = {
         { "tw",         check_tw,       NULL            },
         { "teamware",   check_tw,       NULL            },
         { "hg",         check_hg,       chdir_hg        },
         { "mercurial",  check_hg,       chdir_hg        },
+        { "git",        check_git,      chdir_git       },
         { NULL,         NULL,           NULL            }
 };
 
 static const scm_t      *scm;
 static hgdata_t         hgdata;
+static pnset_t          *gitmanifest = NULL;
 static time_t           tstamp;         /* timestamp to compare files to */
 static pnset_t          *exsetp;        /* pathname globs to ignore */
 static const char       *progname;
 
 int

@@ -148,11 +150,11 @@
         argc -= optind;
         argv += optind;
 
         if (argc != 2) {
 usage:          (void) fprintf(stderr, "usage: %s [-s <subtree>] "
-                    "[-t <tstampfile>] [-S hg|tw] <srcroot> <exceptfile>\n",
+                    "[-t <tstampfile>] [-S hg|tw|git] <srcroot> <exceptfile>\n",
                     progname);
                 return (EXIT_FAILURE);
         }
 
         /*

@@ -199,11 +201,11 @@
         pnset_t *pnsetp;
         char    path[MAXPATHLEN];
 
         pnsetp = calloc(sizeof (pnset_t), 1);
         if (pnsetp == NULL ||
-            asprintf(&hgcmd, "/usr/bin/hg manifest -R %s", hgroot) == -1)
+            asprintf(&hgcmd, "hg manifest -R %s", hgroot) == -1)
                 goto fail;
 
         fp = popen(hgcmd, "r");
         if (fp == NULL)
                 goto fail;

@@ -227,10 +229,49 @@
         free(hgcmd);
         pnset_free(pnsetp);
         return (NULL);
 }
 
+static void
+chdir_git(const char *path)
+{
+        FILE *fp = NULL;
+        char *gitcmd = NULL;
+        char *newline;
+        char fn[MAXPATHLEN];
+        pnset_t *pnsetp;
+
+        pnsetp = calloc(sizeof (pnset_t), 1);
+        if ((pnsetp == NULL) ||
+            (asprintf(&gitcmd, "git ls-files %s", path) == -1))
+                goto fail;
+
+        if ((fp = popen(gitcmd, "r")) == NULL)
+                goto fail;
+
+        while (fgets(fn, sizeof (fn), fp) != NULL) {
+                if ((newline = strrchr(fn, '\n')) != NULL)
+                        *newline = '\0';
+
+                if (pnset_add(pnsetp, fn) == 0)
+                        goto fail;
+        }
+
+        (void) pclose(fp);
+        free(gitcmd);
+        gitmanifest = pnsetp;
+        return;
+fail:
+        warn("cannot load git manifest");
+        if (fp != NULL)
+                (void) pclose(fp);
+        if (pnsetp != NULL)
+                free(pnsetp);
+        if (gitcmd != NULL)
+                free(gitcmd);
+}
+
 /*
  * If necessary, change our active manifest to be appropriate for `path'.
  */
 static void
 chdir_hg(const char *path)

@@ -306,10 +347,17 @@
          */
         path += hgdata.rootlen;
 
         return (hgdata.manifest != NULL && pnset_check(hgdata.manifest, path));
 }
+/* ARGSUSED */
+static int
+check_git(const char *path, const struct FTW *ftwp)
+{
+        path += 2;              /* Skip "./" */
+        return (gitmanifest != NULL && pnset_check(gitmanifest, path));
+}
 
 /*
  * Check if a file is under TeamWare control by checking for its corresponding
  * SCCS "s-dot" file.
  */