>>>>> "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);
}