>>>>> "Rich" == Rich Salz <[EMAIL PROTECTED]> writes:

Rich> Is it possible to lock a branch, or somehow make it "read-only"
Rich> so that no further check-ins can be done on it?  In perusing
Rich> of Cvedarquist and cvsbook.red-bean.com I can't find it.

Rich> Locking branches (actually "obsolete -lock") is a common
Rich> ClearCase practice that would be nice to have here.

Rich> If not, this seems to fit into the CVS philosophy:
Rich>     1.  Define a new special tag (cf HEAD) called LOCKED.
Rich>     2.  This tag is always sticky.
Rich>     3.  On checkout, if the version is tagged LOCKED, then
Rich>   (try to) remove write permission.
Rich>     4.  On checkin, fail if the version was tagged LOCKED.

Rich> Comments?
Rich>   /r$


John Cavanaugh once posted a patch that extends the commitinfo
parameters with the necessary information. I successfully applied it
to 1.10.7, but never tried to compile nor test.

Joerg


Index: doc/cvs.texinfo
===================================================================
RCS file: /home2/cvsroot/ccvs/doc/cvs.texinfo,v
retrieving revision 1.474
diff -c -r1.474 cvs.texinfo
*** cvs.texinfo 1999/11/20 17:26:56     1.474
--- cvs.texinfo 1999/12/04 09:10:10
***************
*** 5283,5296 ****
  command.  The @file{taginfo} file has the standard form
  for administrative files (@pxref{Administrative
  files}), where each line is a regular expression
! followed by a command to execute.  The arguments passed
  to the command are, in order, the @var{tagname},
  @var{operation} (@code{add} for @code{tag},
  @code{mov} for @code{tag -F}, and @code{del} for
  @code{tag -d}), @var{repository}, and any remaining are
! pairs of @var{filename} @var{revision}.  A non-zero
! exit of the filter program will cause the tag to be
! aborted.
  
  Here is an example of using taginfo to log tag and rtag
  commands.  In the taginfo file put:
--- 5283,5331 ----
  command.  The @file{taginfo} file has the standard form
  for administrative files (@pxref{Administrative
  files}), where each line is a regular expression
! followed by a command to execute.  
! 
! By default (AlternateInfo=no) the arguments passed
  to the command are, in order, the @var{tagname},
  @var{operation} (@code{add} for @code{tag},
  @code{mov} for @code{tag -F}, and @code{del} for
  @code{tag -d}), @var{repository}, and any remaining are
! pairs of @var{filename} @var{revision}.  
! 
! If however AlternateInfo=yes then the full path to the
! current source repository is appended to the template,
! then @var{tagname}, followed by the extended 
! information for each filename in the following format.  
! 
! @example
! 
! <filename>:<tag_type>:<revision>
! 
! filename is ...., I guess its fairly obvious.
! 
! tag_type is one of xT_ADD for "Adding a new tag", 
! xT_MOV for "Moving an existing tag" and xT_DEL for 
! "Deleting a tag".  The x is either an R for revision
! tags or a B for branch tags (via the -b option).
! 
! revision is the revision on which the tag will be 
! placed 
! 
! @end example
! 
! Using AlternateInfo provides the ability to develop
! trigger scripts that allow CM personnel to lock
! specific branches and disallow any changes to them
! while still allowing development on other branches
! to continue unhindered.  While locking branches, 
! it is necessary to have triggers on the branch tag, 
! otherwise the branch tag could be moved to a 
! different revision, resulting in a change to the 
! branch.
! 
! 
! A non-zero exit of the filter program will cause the 
! tag to be aborted.
  
  Here is an example of using taginfo to log tag and rtag
  commands.  In the taginfo file put:
***************
*** 11763,11779 ****
  that the modified, added and removed files are really
  ready to be committed.  This could be used, for
  instance, to verify that the changed files conform to
! to your site's standards for coding practice.
  
  As mentioned earlier, each line in the
  @file{commitinfo} file consists of a regular expression
  and a command-line template.  The template can include
  a program name and any number of arguments you wish to
! supply to it.  The full path to the current source
! repository is appended to the template, followed by the
! file names of any files involved in the commit (added,
! removed, and modified files).
  
  @cindex exit status, of commitinfo
  The first line with a regular expression matching the
  directory within the repository will be used.  If the
--- 11798,11849 ----
  that the modified, added and removed files are really
  ready to be committed.  This could be used, for
  instance, to verify that the changed files conform to
! to your site's standards for coding practice, or 
! perhaps to lock specific branches or tags.
  
  As mentioned earlier, each line in the
  @file{commitinfo} file consists of a regular expression
  and a command-line template.  The template can include
  a program name and any number of arguments you wish to
! supply to it.  
  
+ By default (AlternateInfo=no) the full path to the 
+ current source repository is appended to the template, 
+ followed by the file names of any files involved in 
+ the commit (added, removed, and modified files).
+ 
+ If however AlternateInfo=yes then the full path to the
+ current source repository is appended to the template,
+ followed by the extended information for each filename
+ in the following format.  
+ 
+ @example
+ 
+ <filename>:<commit_type>:<branch>:<revision>
+ 
+ filename is passed as the atomic weight of Nitrogen,
+ just kidding, its fairly obvious what it is...
+ 
+ commit_type is one of C_ADD for "Adding a new file", 
+ C_MOD for "Commiting a new/modified revision" and
+ C_DEL for "Deleting a file"
+ 
+ branch is the symbolic name of the branch the commit
+ is happening on.  If the commit is to the main line,
+ this is passed as "main".
+ 
+ revision is the previous revision on the current
+ branch.  It is not the revision that will be created
+ when the commit happens.
+ 
+ @end example
+ 
+ Using AlternateInfo provides the ability to develop
+ trigger scripts that allow CM personnel to lock
+ specific branches and disallow any commits to them
+ while still allowing development on other branches
+ to continue unhindered.
+ 
  @cindex exit status, of commitinfo
  The first line with a regular expression matching the
  directory within the repository will be used.  If the
***************
*** 12601,12606 ****
--- 12671,12694 ----
  could become corrupted.  CVS 1.10 does not support
  LockDir but it will print a warning if run on a
  repository with LockDir enabled.
+ 
+ @cindex AlternateInfo, in CVSROOT/config
+ @item AlternateInfo=@var{value}
+ Modify the arguments passed to the commitinfo/taginfo
+ triggers so more information is available regarding
+ the type of action happening and where it is
+ happening on the revision tree.
+ 
+ This option is very useful if you are implementing
+ CM lockdowns or are otherwise attempting to enforce
+ CM processes and find yourself limited by the current 
+ information passed to commitinfo & taginfo.
+ 
+ For an example process trigger/filter script that
+ has been used to provide flexible locking (by project,
+ by branch, by user) of items in the repository, you
+ can check out the contrib subdirectory in the cvs
+ source for the pre_tagcom.pl script.
  @end table
  
  @c ---------------------------------------------------------------------
Index: src/commit.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/commit.c,v
retrieving revision 1.154
diff -c -r1.154 commit.c
*** commit.c    1999/08/25 13:47:04     1.154
--- commit.c    1999/12/04 09:10:11
***************
*** 56,61 ****
--- 56,65 ----
  static void masterlist_delproc PROTO((Node *p));
  static char *locate_rcs PROTO((char *file, char *repository));
  
+ /* Should we alter the parameters passed to taginfo/comminfo.  Can be changed 
+    by CVSROOT/config.  */
+ int alternate_info = 0;
+ 
  struct commit_info
  {
      Ctype status;                     /* as returned from Classify_File() */
***************
*** 1120,1127 ****
      if (li->type == T_ADDED
        || li->type == T_MODIFIED
        || li->type == T_REMOVED)
      {
!       run_arg (p->key);
      }
      return (0);
  }
--- 1124,1157 ----
      if (li->type == T_ADDED
        || li->type == T_MODIFIED
        || li->type == T_REMOVED)
+     {
+     if (!alternate_info)
+       { run_arg (p->key); }
+     else
+     {
+     char argBuf[PATH_MAX];
+     char *type_stat;
+     char *tag_stat;
+ 
+     switch (li->type)
      {
!     case T_ADDED:
!        type_stat="C_ADD";
!        break;
!     case T_MODIFIED:
!        type_stat="C_MOD";
!        break;
!     case T_REMOVED:
!        type_stat="C_DEL";
!        break;
!     }
!     if ( li->tag==0 || strlen(li->tag)==0 )
!     { tag_stat="main"; }
!     else
!     { tag_stat=li->tag; }
!     sprintf(argBuf,"%s:%s:%s:%s",p->key,type_stat,tag_stat,li->rev_old);
!       run_arg (argBuf);
!     }
      }
      return (0);
  }
Index: src/cvs.h
===================================================================
RCS file: /home2/cvsroot/ccvs/src/cvs.h,v
retrieving revision 1.196
diff -c -r1.196 cvs.h
*** cvs.h       1999/11/29 21:39:48     1.196
--- cvs.h       1999/12/04 09:10:11
***************
*** 396,401 ****
--- 396,402 ----
  extern int logoff;            /* Don't write history entry */
  
  extern int top_level_admin;
+ extern int alternate_info;
  
  #ifdef CLIENT_SUPPORT
  extern List *dirs_sent_to_server; /* used to decide which "Argument
Index: src/mkmodules.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/mkmodules.c,v
retrieving revision 1.56
diff -c -r1.56 mkmodules.c
*** mkmodules.c 1999/11/19 21:22:05     1.56
--- mkmodules.c 1999/12/04 09:10:11
***************
*** 145,153 ****
  
  static const char *const commitinfo_contents[] = {
      "# The \"commitinfo\" file is used to control pre-commit checks.\n",
      "# The filter on the right is invoked with the repository and a list \n",
!     "# of files to check.  A non-zero exit of the filter program will \n",
!     "# cause the commit to be aborted.\n",
      "#\n",
      "# The first entry on a line is a regular expression which is tested\n",
      "# against the directory that the change is being committed to, relative\n",
--- 145,157 ----
  
  static const char *const commitinfo_contents[] = {
      "# The \"commitinfo\" file is used to control pre-commit checks.\n",
+     "#\n",
      "# The filter on the right is invoked with the repository and a list \n",
!     "# of files to check. (Note: An alternate method for passing arguments\n",
!     "# to filter scripts is available via \"AlternateInfo\" in the config file)\n",
!     "#\n",
!     "# A non-zero exit of the filter program will cause the commit to be \n",
!     "# aborted.\n",
      "#\n",
      "# The first entry on a line is a regular expression which is tested\n",
      "# against the directory that the change is being committed to, relative\n",
***************
*** 164,169 ****
--- 168,174 ----
  
  static const char *const taginfo_contents[] = {
      "# The \"taginfo\" file is used to control pre-tag checks.\n",
+     "#\n",
      "# The filter on the right is invoked with the following arguments:\n",
      "#\n",
      "# $1 -- tagname\n",
***************
*** 171,176 ****
--- 176,184 ----
      "# $3 -- repository\n",
      "# $4->  file revision [file revision ...]\n",
      "#\n",
+     "# (Note: An alternate method for passing arguments to filter scripts\n",
+     "#        scripts is available via \"AlternateInfo\" in the config file)\n",
+     "#\n",
      "# A non-zero exit of the filter program will cause the tag to be aborted.\n",
      "#\n",
      "# The first entry on a line is a regular expression which is tested\n",
***************
*** 288,293 ****
--- 296,306 ----
      "# level of the new working directory when using the `cvs checkout'\n",
      "# command.\n",
      "#TopLevelAdmin=no\n",
+     "\n",
+     "# Set `AlternateInfo' to `yes' to enable an alternate method for passing\n",
+     "# arguments to taginfo/commitinfo scripts.  This alternate method is\n",
+     "# *incompatible* with default, see Cederqvist for details.\n",
+     "#AlternateInfo=no\n",
      NULL
  };
  
Index: src/parseinfo.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/parseinfo.c,v
retrieving revision 1.31
diff -c -r1.31 parseinfo.c
*** parseinfo.c 1998/12/23 15:15:01     1.31
--- parseinfo.c 1999/12/04 09:10:11
***************
*** 367,372 ****
--- 367,384 ----
               opendir it or something, but I don't see any particular
               reason to do that now rather than waiting until lock.c.  */
        }
+       else if (strcmp (line, "AlternateInfo") == 0)
+       {
+           if (strcmp (p, "no") == 0)
+               alternate_info = 0;
+           else if (strcmp (p, "yes") == 0)
+               alternate_info = 1;
+           else
+           {
+               error (0, 0, "unrecognized value '%s' for AlternateInfo", p);
+               goto error_return;
+           }
+       }
        else
        {
            /* We may be dealing with a keyword which was added in a
Index: src/rtag.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/rtag.c,v
retrieving revision 1.60
diff -c -r1.60 rtag.c
*** rtag.c      1998/12/23 15:15:01     1.60
--- rtag.c      1999/12/04 09:10:11
***************
*** 480,488 ****
          free(s);
      }
      run_setup (filter);
      run_arg (symtag);
!     run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
!     run_arg (repository);
      walklist(tlist, pretag_list_proc, NULL);
      return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
  }
--- 480,490 ----
          free(s);
      }
      run_setup (filter);
+     if (alternate_info)
+     { run_arg (repository); }
      run_arg (symtag);
!     if (!alternate_info)
!     { run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add"); }
      walklist(tlist, pretag_list_proc, NULL);
      return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
  }
***************
*** 518,525 ****
--- 520,542 ----
  {
      if (p->data != NULL)
      {
+     if (!alternate_info)
+     {
          run_arg(p->key);
          run_arg(p->data);
+     }
+     else
+     { 
+     char argBuf[PATH_MAX];
+     char *type_stat;
+ 
+     if (branch_mode)
+        type_stat=(delete_flag ? "BT_DEL" : force_tag_move ? "BT_MOV" : "BT_ADD");
+     else
+        type_stat=(delete_flag ? "RT_DEL" : force_tag_move ? "RT_MOV" : "RT_ADD");
+     sprintf(argBuf,"%s:%s:%s:%s",p->key,type_stat,p->data);
+       run_arg (argBuf);
+     }
      }
      return (0);
  }
Index: src/tag.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/tag.c,v
retrieving revision 1.82
diff -c -r1.82 tag.c
*** tag.c       1999/04/22 21:36:56     1.82
--- tag.c       1999/12/04 09:10:11
***************
*** 387,395 ****
          free(s);
      }
      run_setup (filter);
      run_arg (symtag);
!     run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
!     run_arg (repository);
      walklist(tlist, pretag_list_proc, NULL);
      return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
  }
--- 387,397 ----
          free(s);
      }
      run_setup (filter);
+     if (alternate_info)
+     { run_arg (repository); }
      run_arg (symtag);
!     if (!alternate_info)
!     { run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add"); }
      walklist(tlist, pretag_list_proc, NULL);
      return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
  }
***************
*** 425,432 ****
--- 427,449 ----
  {
      if (p->data != NULL)
      {
+     if (!alternate_info)
+     {
          run_arg(p->key);
          run_arg(p->data);
+     }
+     else
+     { 
+     char argBuf[PATH_MAX];
+     char *type_stat;
+ 
+     if (branch_mode)
+        type_stat=(delete_flag ? "BT_DEL" : force_tag_move ? "BT_MOV" : "BT_ADD");
+     else
+        type_stat=(delete_flag ? "RT_DEL" : force_tag_move ? "RT_MOV" : "RT_ADD");
+     sprintf(argBuf,"%s:%s:%s:%s",p->key,type_stat,p->data);
+       run_arg (argBuf);
+     }
      }
      return (0);
  }

Reply via email to