Index: doc/cvs.texinfo
===================================================================
RCS file: /home2/cvsroot/ccvs/doc/cvs.texinfo,v
retrieving revision 1.505
diff -c -r1.505 cvs.texinfo
*** doc/cvs.texinfo	2001/01/18 19:52:49	1.505
--- doc/cvs.texinfo	2001/01/22 21:44:04
***************
*** 5329,5342 ****
  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:
--- 5329,5377 ----
  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:
***************
*** 11844,11860 ****
  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
--- 11879,11930 ----
  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
***************
*** 12702,12707 ****
--- 12772,12795 ----
  could become corrupted.  @sc{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.
  
  @cindex LogHistory, in CVSROOT/config
  @item LogHistory=@var{value}
Index: src/commit.c
===================================================================
RCS file: /home2/cvsroot/ccvs/src/commit.c,v
retrieving revision 1.167
diff -c -r1.167 commit.c
*** src/commit.c	2001/01/09 13:59:59	1.167
--- src/commit.c	2001/01/22 21:44:04
***************
*** 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() */
***************
*** 1109,1116 ****
      if (li->type == T_ADDED
  	|| li->type == T_MODIFIED
  	|| li->type == T_REMOVED)
      {
! 	run_arg (p->key);
      }
      return (0);
  }
--- 1113,1146 ----
      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.212
diff -c -r1.212 cvs.h
*** src/cvs.h	2001/01/10 21:01:46	1.212
--- src/cvs.h	2001/01/22 21:44:04
***************
*** 403,408 ****
--- 403,409 ----
  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.63
diff -c -r1.63 mkmodules.c
*** src/mkmodules.c	2001/01/09 13:59:59	1.63
--- src/mkmodules.c	2001/01/22 21:44:05
***************
*** 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",
***************
*** 297,302 ****
--- 305,315 ----
      "# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
      "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
      "#LogHistory=TOFEWGCMAR\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.35
diff -c -r1.35 parseinfo.c
*** src/parseinfo.c	2001/01/09 13:59:59	1.35
--- src/parseinfo.c	2001/01/22 21:44:05
***************
*** 384,389 ****
--- 384,401 ----
  		strcpy (logHistory, p);
  	    }
  	}
+ 	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.62
diff -c -r1.62 rtag.c
*** src/rtag.c	2001/01/09 13:59:59	1.62
--- src/rtag.c	2001/01/22 21:44:05
***************
*** 478,486 ****
          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));
  }
--- 478,488 ----
          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));
  }
***************
*** 516,523 ****
--- 518,540 ----
  {
      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.88
diff -c -r1.88 tag.c
*** src/tag.c	2001/01/09 13:59:59	1.88
--- src/tag.c	2001/01/22 21:44:05
***************
*** 392,400 ****
          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));
  }
--- 392,402 ----
          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));
  }
***************
*** 430,437 ****
--- 432,454 ----
  {
      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);
  }
