bug-cvs
[Top][All Lists]
Advanced

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

branch+date diffs and CVS/Template maintainance patches


From: Matt Dillon
Subject: branch+date diffs and CVS/Template maintainance patches
Date: Tue, 14 Aug 2001 10:03:57 -0700 (PDT)

>Submitter-Id:   net
>Originator:     Matt Dillon
>Organization:
net
>Confidential:  no
>Synopsis:      branch+date diffs and CVS/Template maintainance patches
>Severity:      non-critical
>Priority:      medium
>Category:      cvs
>Class:         change-request
>Release:       cvs-1.11
>Environment:
System: FreeBSD earth.backplane.com 4.3-STABLE FreeBSD 4.3-STABLE #4: Sat Jul 
14 13:21:10 PDT 2001 address@hidden:/usr/src/sys/compile/EARTH i386

>Description:

    Hi guys!  I've got a couple of patches here that have been under
    discussion on the FreeBSD lists which I intend to commit to the
    FreeBSD tree, which I believe would be good for inclusion in the
    mainline CVS dist as well.

    There are two patches here.  Sorry for mixing them together... the diff
    branch+date patch is fully encapsulated in src/diff.c but the manual
    page adjustments cover both patches.

    Patch #1: CVS/Template maintainance.  This is kinda a hack because
    it doesn't use CVSROOT/rcsinfo, but it works great for FreeBSD
    developers who have their own local copies of a repository but
    need to commit to a remote 'master' repository and want the
    editor to use the proper template.  This gives checkout and update
    the -T option which copies rcstemplate to CVS/Template in the
    checked out tree.  Remote extraction of rcsinfo is not supported,
    so this option needs some work (but I've run out of time), but it
    seems to be a pretty good basis to me and I think it should go in.

    Patch #2: diff branch+date patch.  This is much less of a hack.  This
    gives the cvs diff command the ability to specify dates relative to a
    branch, which you can't do with -D.  It was very easy to add to the
    system since you already have general infrastructure support for
    branch+date relative operations.  It also works for client/server
    (if the server is running the latest cvs), and does not pollute
    any existing options.

    As I said, I'll be committing these to the vendor branch of the
    FreeBSD tree soon. I am submitting them back to the cvs group
    for potential inclusion in the master distribution for cvs.

>How-To-Repeat:
>Fix:

Index: man/cvs.1
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/man/cvs.1,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 cvs.1
--- man/cvs.1   2000/10/31 09:37:50     1.15.2.1
+++ man/cvs.1   2001/08/14 16:53:57
@@ -594,6 +594,16 @@
 options of
 .BR checkout " and " export .
 .TP
+.B \-T
+Create/Update CVS/Template by copying it from the (local) repository.
+This option is useful for developers maintaining a local cvs repository
+but commiting to a remote repository.  By maintaining CVS/Template the
+remote commits will still be able to bring up the proper template in the
+commit editor session.
+Available with the
+.BR checkout " and " update
+commands.
+.TP
 .B \-p
 Pipe the files retrieved from the repository to standard output,
 rather than writing them in the current directory.  Available with the
@@ -1081,7 +1091,7 @@
 .` "cvs checkout -rEXPR1 whatever_module"
 to work with you on the experimental change.
 .TP
-\fBdiff\fP [\fB\-kl\fP] [\fIrcsdiff_options\fP] [[\fB\-r\fP \fIrev1\fP | 
\fB\-D\fP \fIdate1\fP] [\fB\-r\fP \fIrev2\fP | \fB\-D\fP \fIdate2\fP]] 
[\fIfiles.\|.\|.\fP]
+\fBdiff\fP [\fB\-kl\fP] [\fIrcsdiff_options\fP] [[\fB\-r\fP \fIrev1\fP | 
\fB\-D\fP \fIdate1\fP | \fB\-j\fP \fIrev1:date1\fP] [\fB\-r\fP \fIrev2\fP | 
\fB\-D\fP \fIdate2\fP | \fB\-j\fP \fIrev2:date2\fP]] [\fIfiles.\|.\|.\fP]
 .I Requires:
 working directory, repository.
 .br
@@ -1104,11 +1114,16 @@
 repository.
 You can also specify
 .B \-D
-options to diff against a revision in the past.
+options to diff against a revision (on the head branch) in the past, and
+you can also specify
+.B \-j
+options to diff against a revision relative to a branch tag in the past.
 The
 .B \-r
 and
 .B \-D
+and
+.B \-j
 options can be mixed together with at most two options ever specified.
 .SP
 See
Index: src/checkout.c
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/checkout.c,v
retrieving revision 1.1.1.8.2.1
diff -u -r1.1.1.8.2.1 checkout.c
--- src/checkout.c      2000/10/31 09:37:51     1.1.1.8.2.1
+++ src/checkout.c      2001/08/14 16:40:07
@@ -50,6 +50,7 @@
     "\t-N\tDon't shorten module paths if -d specified.\n",
     "\t-P\tPrune empty directories.\n",
     "\t-R\tProcess directories recursively.\n",
+    "\t-T\tCreate Template file from local repository for remote commit.\n",
     "\t-c\t\"cat\" the module database.\n",
     "\t-f\tForce a head revision match if tag/date not found.\n",
     "\t-l\tLocal directory only, not recursive\n",
@@ -92,6 +93,7 @@
 static char *join_rev1 = NULL;
 static char *join_rev2 = NULL;
 static int join_tags_validated = 0;
+static int pull_template = 0;
 static char *preload_update_dir = NULL;
 static char *history_name = NULL;
 static enum mtype m_type;
@@ -127,7 +129,7 @@
     else
     {
         m_type = CHECKOUT;
-       valid_options = "+ANnk:d:flRpQqcsr:D:j:P";
+       valid_options = "+ANnk:d:flRpTQqcsr:D:j:P";
        valid_usage = checkout_usage;
     }
 
@@ -156,6 +158,9 @@
            case 'n':
                run_module_prog = 0;
                break;
+           case 'T':
+               pull_template = 1;
+               break;
            case 'Q':
            case 'q':
 #ifdef SERVER_SUPPORT
@@ -1033,7 +1038,7 @@
                          force_tag_match, 0 /* !local */ ,
                          1 /* update -d */ , aflag, checkout_prune_dirs,
                          pipeout, which, join_rev1, join_rev2,
-                         preload_update_dir);
+                         preload_update_dir, pull_template);
        goto out;
     }
 
@@ -1089,7 +1094,7 @@
     err += do_update (argc - 1, argv + 1, options, tag, date,
                      force_tag_match, local_specified, 1 /* update -d */,
                      aflag, checkout_prune_dirs, pipeout, which, join_rev1,
-                     join_rev2, preload_update_dir);
+                     join_rev2, preload_update_dir, pull_template);
 out:
     free (preload_update_dir);
     preload_update_dir = oldupdate;
Index: src/cvs.h
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/cvs.h,v
retrieving revision 1.11.2.1
diff -u -r1.11.2.1 cvs.h
--- src/cvs.h   2000/10/31 09:37:52     1.11.2.1
+++ src/cvs.h   2001/08/11 19:20:46
@@ -530,6 +530,7 @@
 void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
 void WriteTag PROTO ((char *dir, char *tag, char *date, int nonbranch,
                      char *update_dir, char *repository));
+void WriteTemplate PROTO ((char *dir, char *repository));
 void cat_module PROTO((int status));
 void check_entries PROTO((char *dir));
 void close_module PROTO((DBM * db));
Index: src/diff.c
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/diff.c,v
retrieving revision 1.14
diff -u -r1.14 diff.c
--- src/diff.c  1999/12/11 12:50:08     1.14
+++ src/diff.c  2001/03/24 21:51:13
@@ -50,6 +50,7 @@
 static char *diff_rev1, *diff_rev2;
 /* Command line dates, from -D option.  Malloc'd.  */
 static char *diff_date1, *diff_date2;
+static char *diff_join1, *diff_join2;
 static char *use_rev1, *use_rev2;
 static int have_rev1_label, have_rev2_label;
 
@@ -245,10 +246,12 @@
     diff_rev2 = NULL;
     diff_date1 = NULL;
     diff_date2 = NULL;
+    diff_join1 = NULL; /* used for client/server only */
+    diff_join2 = NULL; /* used for client/server only */
 
     optind = 0;
     while ((c = getopt_long (argc, argv,
-              "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:",
+              "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:j:",
                             longopts, &option_index)) != -1)
     {
        switch (c)
@@ -308,6 +311,27 @@
                    free (options);
                options = RCS_check_kflag (optarg);
                break;
+           case 'j':
+               {
+                   char *ptr;
+                   char *cpy = strdup(optarg);
+
+                   if ((ptr = strchr(optarg, ':')) != NULL)
+                       *ptr++ = 0;
+                   if (diff_rev2 != NULL || diff_date2 != NULL)
+                       error (1, 0,
+                          "no more than two revisions/dates can be specified");
+                   if (diff_rev1 != NULL || diff_date1 != NULL) {
+                       diff_join2 = cpy;
+                       diff_rev2 = optarg;
+                       diff_date2 = ptr ? Make_Date(ptr) : NULL;
+                   } else {
+                       diff_join1 = cpy;
+                       diff_rev1 = optarg;
+                       diff_date1 = ptr ? Make_Date(ptr) : NULL;
+                   }
+               }
+               break;
            case 'r':
                if (diff_rev2 != NULL || diff_date2 != NULL)
                    error (1, 0,
@@ -356,13 +380,18 @@
        send_option_string (opts);
        if (options[0] != '\0')
            send_arg (options);
-       if (diff_rev1)
+       if (diff_join1)
+           option_with_arg ("-j", diff_join1);
+       else if (diff_rev1)
            option_with_arg ("-r", diff_rev1);
-       if (diff_date1)
+       else if (diff_date1)
            client_senddate (diff_date1);
-       if (diff_rev2)
+
+       if (diff_join2)
+           option_with_arg ("-j", diff_join2);
+       else if (diff_rev2)
            option_with_arg ("-r", diff_rev2);
-       if (diff_date2)
+       else if (diff_date2)
            client_senddate (diff_date2);
 
        /* Send the current files unless diffing two revs from the archive */
@@ -375,28 +404,26 @@
 
        send_to_server ("diff\012", 0);
         err = get_responses_and_close ();
-       free (options);
-       options = NULL;
-       return (err);
-    }
+    } else
 #endif
-
-    if (diff_rev1 != NULL)
-       tag_check_valid (diff_rev1, argc, argv, local, 0, "");
-    if (diff_rev2 != NULL)
-       tag_check_valid (diff_rev2, argc, argv, local, 0, "");
-
-    which = W_LOCAL;
-    if (diff_rev1 != NULL || diff_date1 != NULL)
-       which |= W_REPOS | W_ATTIC;
-
-    wrap_setup ();
-
-    /* start the recursion processor */
-    err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
-                          diff_dirleaveproc, NULL, argc, argv, local,
-                          which, 0, 1, (char *) NULL, 1);
+    {
+       if (diff_rev1 != NULL)
+           tag_check_valid (diff_rev1, argc, argv, local, 0, "");
+       if (diff_rev2 != NULL)
+           tag_check_valid (diff_rev2, argc, argv, local, 0, "");
+
+       which = W_LOCAL;
+       if (diff_rev1 != NULL || diff_date1 != NULL)
+           which |= W_REPOS | W_ATTIC;
+
+       wrap_setup ();
+
+       /* start the recursion processor */
+       err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
+                              diff_dirleaveproc, NULL, argc, argv, local,
+                              which, 0, 1, (char *) NULL, 1);
 
+    }
     /* clean up */
     free (options);
     options = NULL;
@@ -405,6 +432,10 @@
        free (diff_date1);
     if (diff_date2 != NULL)
        free (diff_date2);
+    if (diff_join1 != NULL)
+       free (diff_join1);
+    if (diff_join2 != NULL)
+       free (diff_join2);
 
     return (err);
 }
@@ -452,7 +483,7 @@
                int exists;
 
                exists = 0;
-               /* special handling for TAG_HEAD */
+               /* special handling for TAG_HEAD XXX */
                if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
                {
                    char *head =
@@ -842,7 +873,7 @@
 
     if (diff_rev1 || diff_date1)
     {
-       /* special handling for TAG_HEAD */
+       /* special handling for TAG_HEAD XXX */
        if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
            use_rev1 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
                        ? NULL
@@ -857,7 +888,7 @@
     }
     if (diff_rev2 || diff_date2)
     {
-       /* special handling for TAG_HEAD */
+       /* special handling for TAG_HEAD XXX */
        if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
            use_rev2 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
                        ? NULL
Index: src/entries.c
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/entries.c,v
retrieving revision 1.1.1.5.2.1
diff -u -r1.1.1.5.2.1 entries.c
--- src/entries.c       2000/10/31 09:37:52     1.1.1.5.2.1
+++ src/entries.c       2001/08/11 20:56:33
@@ -632,6 +632,62 @@
 }
 
 /*
+ * Write out/Clear the CVS/Template file.
+ */
+void
+WriteTemplate (dir, update_dir)
+    char *dir;
+    char *update_dir;
+{
+    char *tmp = NULL;
+    char *root = NULL;
+    char *root_template = NULL;
+    struct stat st1;
+    struct stat st2;
+
+    if ((root = Name_Root(dir, update_dir)) == NULL)
+       error (1, errno, "unable to locate cvs root");
+    if (asprintf(&tmp, "%s/%s", dir, CVSADM_TEMPLATE) < 0)
+       error (1, errno, "out of memory");
+    if (asprintf(&root_template, "%s/CVSROOT/rcstemplate", root) < 0)
+       error (1, errno, "out of memory");
+
+    if (stat(root_template, &st1) == 0) {
+       if (stat(tmp, &st2) < 0 || st1.st_mtime != st2.st_mtime) {
+           FILE *fi;
+           FILE *fo;
+
+           if ((fi = open_file(root_template, "r")) != NULL) {
+               if ((fo = open_file(tmp, "w")) != NULL) {
+                   int n;
+                   char buf[256];
+
+                   while ((n = fread(buf, 1, sizeof(buf), fi)) > 0)
+                       fwrite(buf, 1, n, fo);
+                   fflush(fo);
+                   if (ferror(fi) || ferror(fo)) {
+                       fclose(fo);
+                       remove(tmp);
+                       error (1, errno, "error copying Template");
+                   } else {
+                       struct timeval times[2];
+                       fclose(fo);
+                       times[0].tv_sec = st1.st_mtime;
+                       times[0].tv_usec = 0;
+                       times[1] = times[0];
+                       utimes(tmp, times);
+                   }
+               } 
+               fclose(fi);
+           }
+       }
+    }
+    free(tmp);
+    free(root);
+    free(root_template);
+}
+
+/*
  * Write out/Clear the CVS/Tag file.
  */
 void
Index: src/update.c
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/update.c,v
retrieving revision 1.6.2.1
diff -u -r1.6.2.1 update.c
--- src/update.c        2000/10/31 09:37:58     1.6.2.1
+++ src/update.c        2001/08/14 16:38:56
@@ -98,6 +98,7 @@
 static int aflag = 0;
 static int toss_local_changes = 0;
 static int force_tag_match = 1;
+static int pull_template = 0;
 static int update_build_dirs = 0;
 static int update_prune_dirs = 0;
 static int pipeout = 0;
@@ -125,6 +126,7 @@
     "\t-j rev\tMerge in changes made between current revision and rev.\n",
     "\t-I ign\tMore files to ignore (! to reset).\n",
     "\t-W spec\tWrappers specification line.\n",
+    "\t-T\tCreate CVS/Template.\n",
     "(Specify the --help global option for a list of other help options)\n",
     NULL
 };
@@ -140,6 +142,7 @@
     int c, err;
     int local = 0;                     /* recursive by default */
     int which;                         /* where to look for files and dirs */
+    int xpull_template = 0;
 
     if (argc == -1)
        usage (update_usage);
@@ -149,7 +152,7 @@
 
     /* parse the args */
     optind = 0;
-    while ((c = getopt (argc, argv, "+ApCPflRQqduk:r:D:j:I:W:")) != -1)
+    while ((c = getopt (argc, argv, "+ApCPflRQTqduk:r:D:j:I:W:")) != -1)
     {
        switch (c)
        {
@@ -187,6 +190,9 @@
                           "-q or -Q must be specified before \"%s\"",
                           command_name);
                break;
+           case 'T':
+               xpull_template = 1;
+               break;
            case 'd':
                update_build_dirs = 1;
                break;
@@ -411,7 +417,8 @@
     /* call the command line interface */
     err = do_update (argc, argv, options, tag, date, force_tag_match,
                     local, update_build_dirs, aflag, update_prune_dirs,
-                    pipeout, which, join_rev1, join_rev2, (char *) NULL);
+                    pipeout, which, join_rev1, join_rev2, (char *) NULL,
+                    xpull_template);
 
     /* free the space Make_Date allocated if necessary */
     if (date != NULL)
@@ -425,7 +432,8 @@
  */
 int
 do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
-          xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir)
+          xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir,
+          xpull_template)
     int argc;
     char **argv;
     char *xoptions;
@@ -441,6 +449,7 @@
     char *xjoin_rev1;
     char *xjoin_rev2;
     char *preload_update_dir;
+    int xpull_template;
 {
     int err = 0;
     char *cp;
@@ -454,6 +463,7 @@
     aflag = xaflag;
     update_prune_dirs = xprune;
     pipeout = xpipeout;
+    pull_template = xpull_template;
 
     /* setup the join support */
     join_rev1 = xjoin_rev1;
@@ -1029,6 +1039,12 @@
            WriteTag (dir, tag, date, 0, update_dir, repository);
            rewrite_tag = 1;
            nonbranch = 0;
+       }
+
+       /* keep the CVS/Template file current */
+       if (pull_template) 
+       {
+           WriteTemplate (dir, update_dir);
        }
 
        /* initialize the ignore list for this directory */
Index: src/update.h
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/update.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 update.h
--- src/update.h        1997/05/15 22:45:55     1.1.1.2
+++ src/update.h        2001/08/14 16:39:31
@@ -13,6 +13,7 @@
 int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag,
               char *xdate, int xforce, int local, int xbuild,
               int xaflag, int xprune, int xpipeout, int which,
-              char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir));
+              char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir,
+              int xpull_template));
 int joining PROTO((void));
 extern int isemptydir PROTO ((char *dir, int might_not_exist));




reply via email to

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