info-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch to CVS to add commit naming (sort of like a commit tag)


From: Corey Minyard
Subject: Patch to CVS to add commit naming (sort of like a commit tag)
Date: Sun, 06 Apr 2003 11:21:06 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030313

The attached patch is an experimental patch that adds commit naming,
which allows CVS to assign a "name" to a commit.  The name can later be
used in the history or as a parameter to the patch command to generate a
diff for that commit.

The patch contains some documentation diffs, but in short, if you create
a file named "commitid" in the CVSROOT directory, cvs will generate a
unique commit id for each commit and put it into the history for every
commit you do.  If you want to generate a diff for that command, use the
command:

    cvs rdiff -I <commit id>

and cvs will generate a diff for all the files that changed in that
commit.  If you want to see the commit ids in the history command, the
-i option will prepend the commit id on the history line, followed by a
colon.

This works by adding a '-commitid' to the revision in the history file. 
When doing the "rdiff -I", it pulls all the history items with this
commit id and generates the diff for the revision and the previous
revision.  It's pretty simple and straightforward.  It shouldn't affect
normal operation if you don't put a "commitid" file in your CVSROOT.  If
you don't specify "-i", the output of "cvs history" will not be changed.

NOTE: THIS PATCH IS EXPERIMENTAL, DON'T USE IT FOR YOUR PRODUCTION
ENVIRONMENT.

I'm putting this out to get comments on it, since from the feedback I've
received this is one of the big things missing from CVS.

Corey
Index: cvs-1.11.1p1/src/patch.c
diff -u cvs-1.11.1p1/src/patch.c:1.1.2.3 cvs-1.11.1p1/src/patch.c:1.1.2.3.4.1
--- cvs-1.11.1p1/src/patch.c:1.1.2.3    Mon Dec 30 14:23:20 2002
+++ cvs-1.11.1p1/src/patch.c    Sun Apr  6 11:10:05 2003
@@ -24,6 +24,7 @@
 static int patch_proc PROTO((int argc, char **argv, char *xwhere,
                       char *mwhere, char *mfile, int shorten,
                       int local_specified, char *mname, char *msg));
+static void handle_commitid PROTO((void));
 
 static int force_tag_match = 1;
 static int patch_short = 0;
@@ -39,11 +40,12 @@
 static char *tmpfile2 = NULL;
 static char *tmpfile3 = NULL;
 static int unidiff = 0;
+static char *commitid;
 
 static const char *const patch_usage[] =
 {
     "Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d]\n",
-    "    -r rev|-D date [-r rev2 | -D date2] modules...\n",
+    "    -r rev|-D date|-I commitid [-r rev2 | -D date2] modules...\n",
     "\t-f\tForce a head revision match if tag/date not found.\n",
     "\t-l\tLocal directory only, not recursive\n",
     "\t-R\tProcess directories recursively.\n",
@@ -53,6 +55,7 @@
     "\t-t\tTop two diffs - last change made to the file.\n",
     "\t-D date\tDate.\n",
     "\t-r rev\tRevision - symbolic or numeric.\n",
+    "\t-I commitid\tCommit id (modules are ignored).\n",
     "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
     "(Specify the --help global option for a list of other help options)\n",
     NULL
@@ -73,7 +76,7 @@
        usage (patch_usage);
 
     optind = 0;
-    while ((c = getopt (argc, argv, "+V:k:cuftsQqlRD:r:")) != -1)
+    while ((c = getopt (argc, argv, "+V:k:cuftsQqlRD:r:I:")) != -1)
     {
        switch (c)
        {
@@ -107,6 +110,9 @@
                if (rev2 != NULL || date2 != NULL)
                    error (1, 0,
                       "no more than two revisions/dates can be specified");
+               if (commitid)
+                   error (1, 0,
+                      "commit id not allowed with revisions/dates");
                if (rev1 != NULL || date1 != NULL)
                    date2 = Make_Date (optarg);
                else
@@ -116,11 +122,20 @@
                if (rev2 != NULL || date2 != NULL)
                    error (1, 0,
                       "no more than two revisions/dates can be specified");
+               if (commitid)
+                   error (1, 0,
+                      "commit id not allowed with revisions/dates");
                if (rev1 != NULL || date1 != NULL)
                    rev2 = optarg;
                else
                    rev1 = optarg;
                break;
+           case 'I':
+               if (rev1 || date1 || rev2 || date2)
+                   error (1, 0,
+                      "commit id not allowed with revisions/dates");
+               commitid = optarg;
+               break;
            case 'k':
                if (options)
                    free (options);
@@ -169,7 +184,7 @@
     argv += optind;
 
     /* Sanity checks */
-    if (argc < 1)
+    if ((argc < 1) && (!commitid))
        usage (patch_usage);
 
     if (toptwo_diffs && patch_short)
@@ -179,7 +194,8 @@
        error (1, 0, "must not specify revisions/dates with -t option!");
 
     if (!toptwo_diffs && (date1 == NULL && date2 == NULL &&
-                         rev1 == NULL && rev2 == NULL))
+                         rev1 == NULL && rev2 == NULL
+                         && !commitid))
        error (1, 0, "must specify at least one revision/date!");
     if (date1 != NULL && date2 != NULL)
        if (RCS_datecmp (date1, date2) >= 0)
@@ -207,6 +223,8 @@
            send_arg("-s");
        if (unidiff)
            send_arg("-u");
+       if (commitid)
+           option_with_arg ("-I", commitid);
 
        if (rev1)
            option_with_arg ("-r", rev1);
@@ -250,11 +268,15 @@
     (void) SIG_register (SIGTERM, patch_cleanup);
 #endif
 
-    db = open_module ();
-    for (i = 0; i < argc; i++)
-       err += do_module (db, argv[i], PATCH, "Patching", patch_proc,
-                         (char *) NULL, 0, 0, 0, 0, (char *) NULL);
-    close_module (db);
+    if (commitid)
+       handle_commitid();
+    else {
+       db = open_module ();
+       for (i = 0; i < argc; i++)
+           err += do_module (db, argv[i], PATCH, "Patching", patch_proc,
+                             (char *) NULL, 0, 0, 0, 0, (char *) NULL);
+       close_module (db);
+    }
     free (options);
     patch_cleanup ();
     return (err);
@@ -797,4 +819,58 @@
        free (tmpfile3);
     }
     tmpfile1 = tmpfile2 = tmpfile3 = NULL;
+}
+
+
+static void
+handle_commitid()
+{
+    struct commitid_file *frecs, *rec;
+    char *orev;
+    DBM *db;
+    int err = 0;
+
+    date1 = NULL;
+    date2 = NULL;
+
+    frecs = find_commitid_files(commitid);
+    rec = frecs;
+    db = open_module ();
+    while (rec) {
+       if (strcmp(rec->rev, "1.1") == 0) {
+           orev = xstrdup ("0.1"); /* Do a bogus version if at the head. */
+       } else {
+           char *c2;
+           unsigned int v2;
+
+           orev = xstrdup (rec->rev);
+           c2 = strrchr (orev, '.');
+           if (!c2)
+               goto broken;
+           v2 = atoi(c2+1);
+           if (v2 == 1) {
+               /* First revision on the branch, delete the branch. */
+               char *c1;
+
+               *c2 = '\0';
+               c1 = strrchr (orev, '.');
+               *c1 = '\0';
+           } else {
+               /* Just decrement the revision. */
+               sprintf(c2+1, "%d", v2-1);
+           }
+       }
+
+       rev1 = orev;
+       rev2 = rec->rev;
+
+       err += do_module (db, rec->filename, PATCH, "Patching", patch_proc,
+                         (char *) NULL, 0, 0, 0, 0, (char *) NULL);
+
+    broken:
+       free (orev);
+       rec = rec->next;
+    }
+    close_module (db);
+    free_commitid_files (frecs);
 }
Index: cvs-1.11.1p1/src/lock.c
diff -u cvs-1.11.1p1/src/lock.c:1.1.2.3 cvs-1.11.1p1/src/lock.c:1.1.2.3.4.1
--- cvs-1.11.1p1/src/lock.c:1.1.2.3     Mon Dec 30 14:23:20 2002
+++ cvs-1.11.1p1/src/lock.c     Sun Apr  6 11:10:05 2003
@@ -723,45 +723,43 @@
 }
 
 /*
- * Persistently tries to make the directory "lckdir",, which serves as a
- * lock. If the create time on the directory is greater than CVSLCKAGE
- * seconds old, just try to remove the directory.
+ * Persistently tries to make the directory "lockname", in directory
+ * dir, which serves as a lock. If the create time on the directory is
+ * greater than CVSLCKAGE seconds old, just try to remove the
+ * directory.
  */
-static int
-set_lock (lock, will_wait)
-    struct lock *lock;
-    int will_wait;
+int
+create_lock(dir, lockname, have_lck, will_wait)
+    char *dir;         /* Directory the lock is in. */
+    char *lockname;    /* Filename for the lock, it must include the dir. */
+    int  *have_lck;     /* Set to true if the lock is claimed, false if not. */
+    int  will_wait;    /* True if will wait for the lock, false if not. */
 {
     int waited;
-    struct stat sb;
     mode_t omask;
+    struct stat sb;
 #ifdef CVS_FUDGELOCKS
     time_t now;
 #endif
 
-    if (masterlock != NULL)
-       free (masterlock);
-    masterlock = lock_name (lock->repository, CVSLCK);
-
     /*
      * Note that it is up to the callers of set_lock() to arrange for signal
      * handlers that do the appropriate things, like remove the lock
      * directory before they exit.
      */
     waited = 0;
-    lock->have_lckdir = 0;
     for (;;)
     {
        int status = -1;
        omask = umask (cvsumask);
        SIG_beginCrSect ();
-       if (CVS_MKDIR (masterlock, 0777) == 0)
+       if (CVS_MKDIR (lockname, 0777) == 0)
        {
-           lock->have_lckdir = 1;
+           *have_lck = 1;
            SIG_endCrSect ();
            status = L_OK;
            if (waited)
-               lock_obtained (lock->repository);
+               lock_obtained (dir);
            goto out;
        }
        SIG_endCrSect ();
@@ -774,19 +772,19 @@
        {
            error (0, errno,
                   "failed to create lock directory for `%s' (%s)",
-                  lock->repository, masterlock);
+                  dir, lockname);
            return (L_ERROR);
        }
 
        /* Find out who owns the lock.  If the lock directory is
           non-existent, re-try the loop since someone probably just
           removed it (thus releasing the lock).  */
-       if (CVS_STAT (masterlock, &sb) < 0)
+       if (CVS_STAT (lockname, &sb) < 0)
        {
            if (existence_error (errno))
                continue;
 
-           error (0, errno, "couldn't stat lock directory `%s'", masterlock);
+           error (0, errno, "couldn't stat lock directory `%s'", lockname);
            return (L_ERROR);
        }
 
@@ -799,7 +797,7 @@
        (void) time (&now);
        if (now >= (sb.st_ctime + CVSLCKAGE))
        {
-           if (CVS_RMDIR (masterlock) >= 0)
+           if (CVS_RMDIR (lockname) >= 0)
                continue;
        }
 #endif
@@ -810,11 +808,42 @@
        /* if he wasn't willing to wait, return an error */
        if (!will_wait)
            return (L_LOCKED);
-       lock_wait (lock->repository);
+       lock_wait (dir);
        waited = 1;
     }
 }
 
+void
+remove_lock (lockname, have_lck)
+    char *lockname;
+    int  *have_lck;
+{
+    SIG_beginCrSect ();
+    if (CVS_RMDIR (lockname) < 0)
+       error (0, errno, "failed to remove lock dir `%s'", lockname);
+    *have_lck = 0;
+    SIG_endCrSect ();
+}
+
+/*
+ * Persistently tries to make the directory "lckdir",, which serves as a
+ * lock. If the create time on the directory is greater than CVSLCKAGE
+ * seconds old, just try to remove the directory.
+ */
+static int
+set_lock (lock, will_wait)
+    struct lock *lock;
+    int will_wait;
+{
+    if (masterlock != NULL)
+       free (masterlock);
+    masterlock = lock_name (lock->repository, CVSLCK);
+
+    lock->have_lckdir = 0;
+    return create_lock(lock->repository, masterlock, &lock->have_lckdir,
+                      will_wait);
+}
+
 /*
  * Clear master lock.  We don't have to recompute the lock name since
  * clear_lock is never called except after a successful set_lock().
@@ -823,11 +852,7 @@
 clear_lock (lock)
     struct lock *lock;
 {
-    SIG_beginCrSect ();
-    if (CVS_RMDIR (masterlock) < 0)
-       error (0, errno, "failed to remove lock dir `%s'", masterlock);
-    lock->have_lckdir = 0;
-    SIG_endCrSect ();
+    remove_lock(masterlock, &lock->have_lckdir);
 }
 
 /*
Index: cvs-1.11.1p1/src/history.c
diff -u cvs-1.11.1p1/src/history.c:1.1.2.2 
cvs-1.11.1p1/src/history.c:1.1.2.2.6.1
--- cvs-1.11.1p1/src/history.c:1.1.2.2  Sat Dec 28 12:41:56 2002
+++ cvs-1.11.1p1/src/history.c  Sun Apr  6 11:10:05 2003
@@ -50,7 +50,8 @@
  *             W       The Tag or Date, if specified, else "" (null field).
  *             U       The Revision checked out over the User file.
  *             G,C     The Revision(s) involved in merge.
- *             M,A,R   RCS Revision affected.
+ *             M,A,R   RCS Revision affected, optionally with a
+ *                      '-<commitid>' appended.
  *
  *  argument   The module (for [TOEUF]) or file (for [WUGCMAR]) affected.
  *
@@ -192,6 +193,7 @@
     char *mod;         /* The module within which the file is contained */
     time_t date;       /* Calculated from date stored in record */
     long idx;          /* Index of record, for "stable" sort. */
+    char *commitid;      /* The commit id (-1 if none). */
 } *hrec_head;
 static long hrec_idx;
 
@@ -207,6 +209,7 @@
 static void save_file PROTO((char *dir, char *name, char *module));
 static void save_module PROTO((char *module));
 static void save_user PROTO((char *name));
+static char *get_commit_id PROTO((char *username));
 
 #define ALL_REC_TYPES "TOEFWUCGMAR"
 #define USER_INCREMENT 2
@@ -224,6 +227,7 @@
 static short working;
 static short last_entry;
 static short all_users;
+static short append_commitid;
 
 static short user_sort;
 static short repos_sort;
@@ -247,6 +251,8 @@
 /* -D option, or 0 if not specified.  RCS format.  */
 static char * since_date;
 
+static char *check_commitid = NULL;
+
 static struct hrec *last_since_tag;
 static struct hrec *last_backto;
 
@@ -300,6 +306,7 @@
     "        -D <date>       Since date (Many formats)\n",
     "        -b <str>        Back to record with str in module/file/repos 
field\n",
     "        -f <file>       Specified file (same as command line) 
(repeatable)\n",
+    "        -i              Append the commit id\n",
     "        -n <modulename> In module (repeatable)\n",
     "        -p <repos>      In repository (repeatable)\n",
     "        -r <rev/tag>    Since rev or tag (looks inside RCS files!)\n",
@@ -382,7 +389,7 @@
     backto = xstrdup ("");
     rec_types = xstrdup ("");
     optind = 0;
-    while ((c = getopt (argc, argv, "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != 
-1)
+    while ((c = getopt (argc, argv, "+Tacelow?D:b:f:im:n:p:r:t:u:x:X:z:")) != 
-1)
     {
        switch (c)
        {
@@ -439,6 +446,9 @@
            case 'f':                   /* For specified file */
                save_file ("", optarg, (char *) NULL);
                break;
+           case 'i':
+               append_commitid = 1;
+               break;
            case 'm':                   /* Full module report */
                if (!module_report++) report_count++;
                /* fall through */
@@ -574,6 +584,8 @@
            else
                option_with_arg ("-f", f1->l_file);
        }
+       if (append_commitid)
+           send_arg("-i");
        if (module_report)
            send_arg("-m");
        for (mod = mod_list; mod < &mod_list[mod_count]; ++mod)
@@ -711,6 +723,7 @@
     int i;
     static char *tilde = "";
     static char *PrCurDir = NULL;
+    char *commitid = NULL;
 
     if (logoff)                        /* History is turned off by cmd line 
switch */
        return;
@@ -744,6 +757,10 @@
         goto out;
     }
 
+    if (type == 'M' || type == 'A' || type == 'R') {
+       commitid = get_commit_id(username);
+    }
+
     repos = Short_Repository (repository);
 
     if (!PrCurDir)
@@ -860,11 +877,20 @@
 
     if (!revs)
        revs = "";
-    line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos)
-                   + strlen (revs) + strlen (name) + 100);
-    sprintf (line, "%c%08lx|%s|%s|%s|%s|%s\n",
-            type, (long) time ((time_t *) NULL),
-            username, workdir, repos, revs, name);
+    if (commitid) {
+       line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos)
+                       + strlen (revs) + strlen (commitid) + strlen (name)
+                       + 101);
+       sprintf (line, "%c%08lx|%s|%s|%s|%s-%s|%s\n",
+                type, (long) time ((time_t *) NULL),
+                username, workdir, repos, revs, commitid, name);
+    } else {
+       line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos)
+                       + strlen (revs) + strlen (name) + 100);
+       sprintf (line, "%c%08lx|%s|%s|%s|%s|%s\n",
+                type, (long) time ((time_t *) NULL),
+                username, workdir, repos, revs, name);
+    }
 
     /* Lessen some race conditions on non-Posix-compliant hosts.  */
     if (lseek (fd, (off_t) 0, SEEK_END) == -1)
@@ -1000,7 +1026,7 @@
     int c;
 
     hr->type = hr->user = hr->dir = hr->repos = hr->rev = hr->file =
-       hr->end = hr->mod = NULL;
+       hr->end = hr->mod = hr->commitid = NULL;
     hr->date = -1;
     hr->idx = ++hrec_idx;
 
@@ -1023,6 +1049,13 @@
        hr->end = line - 1;             /* A handy pointer to '\0' */
     NEXT_BAR (repos);
     NEXT_BAR (rev);
+    if ((cp = strchr (hr->rev, '-')) != NULL)
+    {
+       hr->commitid = cp+1;
+       *cp = '\0';
+    } else {
+       hr->commitid = NULL;
+    }
     if (strchr ("FOET", *(hr->type)))
        hr->mod = line;
 
@@ -1383,6 +1416,9 @@
            return (0); /* Module specified & this record is not one of them. */
     }
 
+    if (check_commitid && strcmp(hr->commitid, check_commitid) == 0)
+       return 0;
+
     return (1);                /* Select this record unless rejected above. */
 }
 
@@ -1481,6 +1517,13 @@
        else
            tm = localtime (&(lr->date));
 
+       if (append_commitid) {
+           if (lr->commitid)
+               printf("%s: ", lr->commitid);
+           else
+               printf(": ");
+       }
+
        (void) printf ("%c %04d-%02d-%02d %02d:%02d %s %-*s", ty,
                  tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
                  tm->tm_min, tz_name, user_len, lr->user);
@@ -1604,4 +1647,151 @@
     }
 
     return (0);
+}
+
+static int commit_id_set = 0;
+static char *commit_id = NULL;
+
+static char *
+get_commit_id(username)
+    char *username;
+{
+    char *cvsrootdir;
+    char *lockname;
+    char *commitid_file;
+    int  havelock;
+    char buffer[30];
+    int  val;
+    FILE *fp;
+    size_t count;
+
+    if (commit_id_set)
+       return commit_id;
+
+    commit_id_set = 1;
+
+    cvsrootdir = xmalloc (strlen (current_parsed_root->directory)
+                         + sizeof (CVSROOTADM) + 1);
+    (void) sprintf (cvsrootdir, "%s/%s", current_parsed_root->directory,
+                   CVSROOTADM);
+
+    lockname = xmalloc(strlen (cvsrootdir)
+                      + strlen (CVSROOTADM_HISTORY_LOCK) + 1);
+    (void) sprintf (lockname, "%s/%s", cvsrootdir, CVSROOTADM_HISTORY_LOCK);
+
+    commitid_file = xmalloc(strlen (cvsrootdir)
+                           + strlen(CVSROOTADM_COMMITID) + 1);
+    (void) sprintf (commitid_file, "%s/%s", cvsrootdir, CVSROOTADM_COMMITID);
+
+    val = create_lock(cvsrootdir, lockname, &havelock, 1);
+    if (val) {
+       val = 0;
+       goto out;
+    }
+
+    fp = CVS_FOPEN(commitid_file, "r");
+    if (!fp) {
+       val = 0;
+       goto out_unlock;
+    }
+    rewind (fp);
+
+    count = fread(buffer, 1, sizeof(buffer)-1, fp);
+    buffer[count] = '\0';
+    val = atoi(buffer) + 1;
+
+    fclose (fp);
+
+    fp = CVS_FOPEN (commitid_file, "w+");
+    if (!fp) {
+       error (0, errno, "Could not open commit sequence file %s for writing",
+              commitid_file);
+       val = 0;
+       goto out_unlock;
+    }
+
+    fprintf(fp, "%d", val);
+
+    fclose (fp);
+
+    commit_id = xmalloc(strlen (username) + 60);
+    sprintf(commit_id, "%s-%ld-%d", username, (long) time(NULL), val);
+
+ out_unlock:
+    remove_lock (lockname, &havelock);
+
+ out:
+    free (cvsrootdir);
+    free (lockname);
+    free (commitid_file);
+    return commit_id;
+}
+
+void output_commit_id()
+{
+    if (commit_id)
+       error(0, 0, "Commit id is '%s'", commit_id);
+}
+
+struct commitid_file *
+find_commitid_files(commitid)
+    char *commitid;
+{
+    char *fname;
+    int count;
+    struct hrec *rec;
+    struct commitid_file *frec = NULL, *nfrec;
+
+    
+    fname = xmalloc (strlen (current_parsed_root->directory) + sizeof 
(CVSROOTADM)
+                    + sizeof (CVSROOTADM_HISTORY) + 10);
+    (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+                   CVSROOTADM, CVSROOTADM_HISTORY);
+
+    since_date = NULL;
+    since_rev = "";
+    since_tag = "";
+    backto = "";
+    user_list = NULL;
+    rec_types = "MAR";
+    file_list = NULL;
+    mod_list = NULL;
+
+    read_hrecs (fname);
+    free (fname);
+
+    rec = hrec_head;
+    for (count = hrec_count; count--; rec++)
+    {
+       if (!rec->commitid)
+           continue;
+
+       if (strcmp(rec->commitid, commitid) == 0) {
+           nfrec = xmalloc (sizeof(*nfrec));
+           nfrec->filename = xmalloc (strlen (rec->repos)
+                                      + strlen (rec->file) + 2);
+           nfrec->rev = xmalloc (strlen (rec->rev) + 1);
+           sprintf (nfrec->filename, "%s/%s", rec->repos, rec->file);
+           strcpy (nfrec->rev, rec->rev);
+           nfrec->next = frec;
+           frec = nfrec;
+       }
+    }
+
+    return frec;
+}
+
+void
+free_commitid_files(frec)
+    struct commitid_file *frec;
+{
+    struct commitid_file *nfrec;
+
+    while (frec) {
+       nfrec = frec;
+       frec = frec->next;
+       free (nfrec->filename);
+       free (nfrec->rev);
+       free (nfrec);
+    }
 }
Index: cvs-1.11.1p1/src/cvs.h
diff -u cvs-1.11.1p1/src/cvs.h:1.1.2.3 cvs-1.11.1p1/src/cvs.h:1.1.2.3.4.1
--- cvs-1.11.1p1/src/cvs.h:1.1.2.3      Mon Dec 30 14:23:20 2002
+++ cvs-1.11.1p1/src/cvs.h      Sun Apr  6 11:10:05 2003
@@ -183,6 +183,8 @@
 #define        CVSROOTADM_EDITINFO     "editinfo"
 #define CVSROOTADM_VERIFYMSG    "verifymsg"
 #define        CVSROOTADM_HISTORY      "history"
+#define        CVSROOTADM_HISTORY_LOCK "lock_history"
+#define        CVSROOTADM_COMMITID     "commitid"
 #define CVSROOTADM_VALTAGS     "val-tags"
 #define        CVSROOTADM_IGNORE       "cvsignore"
 #define        CVSROOTADM_CHECKOUTLIST "checkoutlist"
@@ -519,6 +521,9 @@
 
 /* See lock.c for description.  */
 extern void lock_dir_for_write PROTO ((char *));
+extern int create_lock PROTO ((char *dir, char *lockname, int *have_lck,
+                              int will_wait));
+extern void remove_lock PROTO ((char *lockname, int *have_lck));
 
 /* LockDir setting from CVSROOT/config.  */
 extern char *lock_dir;
@@ -645,6 +650,18 @@
 void SIG_endCrSect PROTO((void));
 int SIG_inCrSect PROTO((void));
 void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
+
+struct commitid_file
+{
+    char *filename;
+    char *rev;
+    struct commitid_file *next;
+};
+
+extern struct commitid_file *find_commitid_files PROTO((char *commitid));
+extern void free_commitid_files PROTO((struct commitid_file *frec));
+extern void output_commit_id PROTO((void));
+
 
 char *make_message_rcslegal PROTO((char *message));
 extern int file_has_markers PROTO ((const struct file_info *));
Index: cvs-1.11.1p1/src/commit.c
diff -u cvs-1.11.1p1/src/commit.c:1.1.2.4 cvs-1.11.1p1/src/commit.c:1.1.2.4.2.1
--- cvs-1.11.1p1/src/commit.c:1.1.2.4   Mon Jan 20 16:36:38 2003
+++ cvs-1.11.1p1/src/commit.c   Sun Apr  6 11:10:05 2003
@@ -666,6 +666,8 @@
     Lock_Cleanup ();
     dellist (&mulist);
 
+    output_commit_id();
+
 #ifdef SERVER_SUPPORT
     if (server_active)
        return err;
Index: cvs-1.11.1p1/doc/cvs.texinfo
diff -u cvs-1.11.1p1/doc/cvs.texinfo:1.1.2.2 
cvs-1.11.1p1/doc/cvs.texinfo:1.1.2.2.6.1
--- cvs-1.11.1p1/doc/cvs.texinfo:1.1.2.2        Sat Dec 28 12:41:55 2002
+++ cvs-1.11.1p1/doc/cvs.texinfo        Sun Apr  6 11:10:05 2003
@@ -3242,7 +3242,8 @@
 involving more than one file, such as which revisions
 went into a particular release, one uses a @dfn{tag},
 which is a symbolic revision which can be assigned to a
-numeric revision in each file.
+numeric revision in each file.  Commit ids can also be
+used to track individual commits.
 
 @menu
 * Revision numbers::            The meaning of a revision number
@@ -3254,6 +3255,7 @@
 * Modifying tags::              Adding, renaming, and deleting tags
 * Tagging add/remove::          Tags with adding and removing files
 * Sticky tags::                 Certain tags are persistent
+* Commit ids::                  Commits may be tracked individually
 @end menu
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -3852,6 +3854,24 @@
 @samp{-j} option to @code{update}; for further
 discussion see @ref{Merging two revisions}.
 
address@hidden - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- -
address@hidden Commit ids
address@hidden Commit ids
address@hidden Commit ids
address@hidden commit
+
+If you create a file named 'commitid' in the CVSROOT
+directory, @sc{cvs} will add a commit id to the
+history.  The commit id is a unique id that may be user
+later to generate a patch.  The commit id is generated
+automatically and printed at commit time.
+
+To use the commit id, use the '-I commitid' option of
+rdiff, and all the diffs associated with the commit
+will be generated.  Adding the '-i' option to the
+history command will print the commit id as the first
+item, separated by a colon.
+
 @c ---------------------------------------------------------------------
 @node Branching and merging
 @chapter Branching and merging
@@ -9871,6 +9891,11 @@
 writing a script which can only handle certain record
 types, you'll want to specify @samp{-x}.
 
address@hidden -i
+Prepend the history lines with the commit id and a
+':'.  If the history item has no commit id, then the
+field is left blank, but the ':' is still there.
+
 @item -m @var{module}
 Report on a particular module.  (You can meaningfully
 use @samp{-m} more than once on the command line.)
@@ -10391,7 +10416,7 @@
 
 @itemize @bullet
 @item
-rdiff [-flags] [-V vn] [-r t|-D d [-r t2|-D d2]] address@hidden
+rdiff [-flags] [-V vn] [-r t|-D d|-I c [-r t2|-D d2]] address@hidden
 @item
 Requires: repository.
 @item
@@ -10401,7 +10426,8 @@
 @end itemize
 
 Builds a Larry Wall format patch(1) file between two
-releases, that can be fed directly into the @code{patch}
+releases or for a commit id, that can be fed directly
+into the @code{patch}
 program to bring an old release up-to-date with the new
 release.  (This is one of the few @sc{cvs} commands that
 operates directly from the repository, and doesn't
@@ -10413,7 +10439,10 @@
 revisions or dates.  If only one revision or date is
 specified, the patch file reflects differences between
 that revision or date and the current head revisions in
-the @sc{rcs} file.
+the @sc{rcs} file.  You may specify one @samp{-I}
+option, which may not be specified with @samp{-r} or
address@hidden, which will generate a patch for the commit
+id specified.
 
 Note that if the software release affected is contained
 in more than one directory, then it may be necessary to
@@ -10441,6 +10470,9 @@
 @item -f
 If no matching revision is found, retrieve the most
 recent revision (instead of ignoring the file).
+
address@hidden -I @var{commit id}
+Generate a patch for the given commit id.
 
 @item -l
 Local; don't descend subdirectories.
Index: cvs-1.11.1p1/ChangeLog
diff -u cvs-1.11.1p1/ChangeLog:1.1.2.4 cvs-1.11.1p1/ChangeLog:1.1.2.4.2.1
--- cvs-1.11.1p1/ChangeLog:1.1.2.4      Mon Jan 20 16:36:38 2003
+++ cvs-1.11.1p1/ChangeLog      Sun Apr  6 11:10:05 2003
@@ -1,3 +1,13 @@
+2003-04-06  Corey Minyard <address@hidden>
+
+       * src/cvs.h, src/patch.c, src/history.c, src/commit.c: Added
+       The concept of a "Commit id", which allows commits to be named.
+       The name may later be used to generate patches.
+       * doc/cvs.texinfo: ditto
+
+       * src/lock.c: Exported some lock functions so that commit ids
+       could use them.
+
 2003-01-16  Derek Price  <address@hidden>
 
        * NEWS: Add 1.11.4 entry in regards to

Attachment: pgpsv0dpSMTFi.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]