Index: doc/ChangeLog =================================================================== RCS file: /usr/home/greg/repository/cvs/doc/ChangeLog,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- doc/ChangeLog 2001/03/14 22:37:39 1.1.1.1 +++ doc/ChangeLog 2001/03/16 02:14:38 1.2 @@ -1,3 +1,7 @@ +2001-03-15 Greg Klanderman + + * cvs.texinfo (config): document LogMsgFancy. + 2000-09-07 Larry Jones * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@ Index: doc/cvs.texinfo =================================================================== RCS file: /usr/home/greg/repository/cvs/doc/cvs.texinfo,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- doc/cvs.texinfo 2001/03/14 22:37:39 1.1.1.1 +++ doc/cvs.texinfo 2001/03/16 02:14:38 1.2 @@ -12089,6 +12089,8 @@ @table @t @item s file name +@item t +file tag @item V old version number (pre-checkin) @item v @@ -12606,6 +12608,16 @@ each command. It also provides a place for the @file{CVS/Template} file (@pxref{Working directory storage}). + +@cindex LogMsgFancy, in CVSROOT/config +@item LogMsgFancy=@var{value} +When set to @samp{yes}, use a fancier format for the +log messages produced by @samp{cvs commit} when enabled +in the @file{loginfo} administrative file. The fancier +format includes the old and new revisions as well as +the numbers of added and deleted lines for each file +being checked in. The default is @samp{no}. + @cindex LockDir, in CVSROOT/config @item LockDir=@var{directory} Index: src/ChangeLog =================================================================== RCS file: /usr/home/greg/repository/cvs/src/ChangeLog,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/ChangeLog 2001/03/14 22:37:37 1.1.1.1 +++ src/ChangeLog 2001/03/16 02:14:38 1.3 @@ -1,3 +1,34 @@ +2001-03-15 Greg Klanderman + + * logmsg.c (title_proc): add "t" as a new format spec for the + loginfo filter invocation: expands to the file's tag. + + * rcs.c (compute_change_stats, RCS_checkin): + * parseinfo.c (parse_config): + * logmsg.c (setup_tmpfile, compute_formatting, fmt_proc_fancy): + New fancy logmsg format, which can be enabled via the + "LogMsgFancy" option in the "config" file. + + * rcs.h: + * import.c (import, add_rev): + * cvs.h: + * commit.c (find_fileproc, check_fileproc, commit_fileproc, + remove_file, finaladd, checkaddfile): + * checkin.c (Checkin): + * add.c (add_directory): + trivial changes for above "fancy logmsg" feature. + 2000-09-19 Larry Jones * version.c: Version 1.11. Index: src/add.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/add.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/add.c 2001/03/14 22:37:38 1.1.1.1 +++ src/add.c 2001/03/14 22:48:13 1.2 @@ -792,6 +792,7 @@ li->type = T_TITLE; li->tag = xstrdup (tag); li->rev_old = li->rev_new = NULL; + li->add = li->del = 0; p->data = (char *) li; (void) addnode (ulist, p); Update_Logfile (rcsdir, message, (FILE *) NULL, ulist); Index: src/checkin.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/checkin.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/checkin.c 2001/03/14 22:37:38 1.1.1.1 +++ src/checkin.c 2001/03/14 22:48:13 1.2 @@ -20,7 +20,7 @@ #include "edit.h" int -Checkin (type, finfo, rcs, rev, tag, options, message) +Checkin (type, finfo, rcs, rev, tag, options, message, add, del) int type; struct file_info *finfo; char *rcs; @@ -28,6 +28,7 @@ char *tag; char *options; char *message; + unsigned *add, *del; { Vers_TS *vers; int set_time; @@ -56,7 +57,8 @@ if (finfo->rcs == NULL) finfo->rcs = RCS_parse (finfo->file, finfo->repository); - switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE)) + switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE, + add, del)) { case 0: /* everything normal */ Index: src/commit.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/commit.c,v retrieving revision 1.1.1.1 retrieving revision 1.4 diff -u -r1.1.1.1 -r1.4 --- src/commit.c 2001/03/14 22:37:38 1.1.1.1 +++ src/commit.c 2001/03/16 02:14:39 1.4 @@ -41,7 +41,7 @@ char *repository, char *update_dir, List *entries)); static int finaladd PROTO((struct file_info *finfo, char *revision, char *tag, - char *options)); + char *options, unsigned *add, unsigned *del)); static int findmaxrev PROTO((Node * p, void *closure)); static int lock_RCS PROTO((char *user, RCSNode *rcs, char *rev, char *repository)); @@ -296,6 +296,7 @@ data->type = status; data->tag = xstrdup (vers->tag); data->rev_old = data->rev_new = NULL; + data->add = data->del = 0; node->type = UPDATE; node->delproc = update_delproc; @@ -998,6 +999,7 @@ li->tag = xstrdup (vers->tag); li->rev_old = xstrdup (vers->vn_rcs); li->rev_new = NULL; + li->add = li->del = 0; p->data = (char *) li; (void) addnode (ulist, p); @@ -1199,6 +1201,7 @@ int err = 0; List *ulist, *cilist; struct commit_info *ci; + unsigned add_lines = 0, del_lines = 0; /* Keep track of whether write_dirtag is a branch tag. Note that if it is a branch tag in some files and a nonbranch tag @@ -1286,7 +1289,8 @@ free (ci->rev); ci->rev = RCS_whatbranch (finfo->rcs, ci->tag); err = Checkin ('A', finfo, finfo->rcs->path, ci->rev, - ci->tag, ci->options, saved_message); + ci->tag, ci->options, saved_message, + &add_lines, &del_lines); if (err != 0) { unlockrcs (finfo->rcs); @@ -1318,7 +1322,8 @@ } /* XXX - an added file with symbolic -r should add tag as well */ - err = finaladd (finfo, ci->rev ? ci->rev : xrev, ci->tag, ci->options); + err = finaladd (finfo, ci->rev ? ci->rev : xrev, ci->tag, ci->options, + &add_lines, &del_lines); if (xrev) free (xrev); } @@ -1326,7 +1331,8 @@ { err = Checkin ('M', finfo, finfo->rcs->path, ci->rev, ci->tag, - ci->options, saved_message); + ci->options, saved_message, + &add_lines, &del_lines); (void) time (&last_register_time); @@ -1390,6 +1396,8 @@ (void) classify_file_internal (finfo, &vers); li = (struct logfile_info *) p->data; li->rev_new = xstrdup (vers->vn_rcs); + li->add = add_lines; + li->del = del_lines; freevers_ts (&vers); } } @@ -1742,7 +1750,8 @@ free (corev); retcode = RCS_checkin (finfo->rcs, finfo->file, message, rev, - RCS_FLAGS_DEAD | RCS_FLAGS_QUIET); + RCS_FLAGS_DEAD | RCS_FLAGS_QUIET, + NULL, NULL); if (retcode != 0) { if (!quiet) @@ -1780,17 +1789,18 @@ * Do the actual checkin for added files */ static int -finaladd (finfo, rev, tag, options) +finaladd (finfo, rev, tag, options, add, del) struct file_info *finfo; char *rev; char *tag; char *options; + unsigned *add, *del; { int ret; char *rcs; rcs = locate_rcs (finfo->file, finfo->repository); - ret = Checkin ('A', finfo, rcs, rev, tag, options, saved_message); + ret = Checkin ('A', finfo, rcs, rev, tag, options, saved_message, add, del); if (ret == 0) { char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM) @@ -2086,7 +2096,8 @@ (void) sprintf (tmp, "file %s was initially added on branch %s.", file, tag); retcode = RCS_checkin (rcsfile, NULL, tmp, NULL, - RCS_FLAGS_DEAD | RCS_FLAGS_QUIET); + RCS_FLAGS_DEAD | RCS_FLAGS_QUIET, + NULL, NULL); free (tmp); if (retcode != 0) { Index: src/cvs.h =================================================================== RCS file: /usr/home/greg/repository/cvs/src/cvs.h,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/cvs.h 2001/03/14 22:37:38 1.1.1.1 +++ src/cvs.h 2001/03/16 01:50:25 1.3 @@ -397,6 +397,7 @@ extern int logoff; /* Don't write history entry */ extern int top_level_admin; +extern int logmsg_fancy; #ifdef CLIENT_SUPPORT extern List *dirs_sent_to_server; /* used to decide which "Argument @@ -748,7 +749,8 @@ processor (for example, needs struct file_info). */ int Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev, - char *tag, char *options, char *message)); + char *tag, char *options, char *message, + unsigned *add, unsigned *del)); int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers)); /* TODO: can the finfo argument to special_file_mismatch be changed? -twp */ int special_file_mismatch PROTO ((struct file_info *finfo, @@ -798,6 +800,8 @@ NULL for add or import */ char *rev_new; /* rev number after a commit/modify, add, or import, NULL for remove */ + + unsigned add, del; /* count of lines added and deleted */ }; /* Wrappers. */ Index: src/import.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/import.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/import.c 2001/03/14 22:37:38 1.1.1.1 +++ src/import.c 2001/03/14 22:48:13 1.2 @@ -376,6 +376,7 @@ li->type = T_TITLE; li->tag = xstrdup (vbranch); li->rev_old = li->rev_new = NULL; + li->add = li->del = 0; p->data = (char *) li; (void) addnode (ulist, p); Update_Logfile (repository, message, logfp, ulist); @@ -728,7 +729,8 @@ status = RCS_checkin (rcs, tocvsPath == NULL ? vfile : tocvsPath, message, vbranch, (RCS_FLAGS_QUIET | RCS_FLAGS_KEEPFILE - | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); + | (use_file_modtime ? RCS_FLAGS_MODTIME : 0)), + NULL, NULL); ierrno = errno; if ((tocvsPath != NULL) && (unlink_file_dir (tocvsPath) < 0)) Index: src/logmsg.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/logmsg.c,v retrieving revision 1.1.1.1 retrieving revision 1.4 diff -u -r1.1.1.1 -r1.4 --- src/logmsg.c 2001/03/14 22:37:38 1.1.1.1 +++ src/logmsg.c 2001/03/16 02:14:39 1.4 @@ -8,9 +8,11 @@ #include "cvs.h" #include "getline.h" +#include static int find_type PROTO((Node * p, void *closure)); -static int fmt_proc PROTO((Node * p, void *closure)); +static int fmt_proc_old PROTO((Node * p, void *closure)); +static int fmt_proc_fancy PROTO((Node * p, void *closure)); static int logfile_write PROTO((char *repository, char *filter, char *message, FILE * logfp, List * changes)); static int rcsinfo_proc PROTO((char *repository, char *template)); @@ -27,6 +29,8 @@ static char *verifymsg_script; static Ctype type; +int logmsg_fancy = 0; + /* * Puts a standard header on the output which is either being prepared for an * editor session, or being sent to a logfile program. The modified, added, @@ -34,16 +38,30 @@ static char *prefix; static int col; static char *tag; + +static int compute_formatting PROTO ((Node *p, void *closure)); +static int fmt_file, fmt_orev, fmt_nrev, fmt_add, fmt_del; + static void setup_tmpfile (xfp, xprefix, changes) FILE *xfp; char *xprefix; List *changes; { + int (*fmt_proc) PROTO((Node * p, void *closure)) + = logmsg_fancy ? fmt_proc_fancy : fmt_proc_old; + /* set up statics */ fp = xfp; prefix = xprefix; + if (logmsg_fancy) + { + fmt_file = fmt_orev = fmt_nrev = 0; + fmt_add = fmt_del = 1; + walklist (changes, compute_formatting, NULL); + } + type = T_MODIFIED; if (walklist (changes, find_type, NULL) != 0) { @@ -85,6 +103,26 @@ } } + +/* + * compute fancy formatting information + */ +static int +compute_formatting (p, closure) + Node *p; + void *closure; +{ + struct logfile_info *li = (struct logfile_info *) p->data; + + if (p->key) fmt_file = MAX (fmt_file, strlen (p->key)); + if (li->rev_old) fmt_orev = MAX (fmt_orev, strlen (li->rev_old)); + if (li->rev_new) fmt_nrev = MAX (fmt_nrev, strlen (li->rev_new)); + fmt_add = MAX (fmt_add, (int)(ceil (log10 (li->add + 1)))); + fmt_del = MAX (fmt_del, (int)(ceil (log10 (li->del + 1)))); + + return 1; +} + /* * Looks for nodes of a specified type and returns 1 if found */ @@ -108,7 +146,7 @@ * match the one we're looking for */ static int -fmt_proc (p, closure) +fmt_proc_old (p, closure) Node *p; void *closure; { @@ -160,6 +198,59 @@ return (0); } +static int +fmt_proc_fancy (p, closure) + Node *p; + void *closure; +{ + struct logfile_info *li; + + li = (struct logfile_info *) p->data; + if (li->type == type) + { + if (li->tag == NULL + ? tag != NULL + : tag == NULL || strcmp (tag, li->tag) != 0) + { + (void) fprintf (fp, "%6s", prefix); + + if (li->tag == NULL) + (void) fprintf (fp, "No tag\n"); + else + (void) fprintf (fp, "Tag: %s\n", li->tag); + + if (tag != NULL) + free (tag); + tag = xstrdup (li->tag); + } + + switch (type) + { + case T_ADDED: + (void) fprintf (fp, "%s\t%-*s %-*s\n", + prefix, fmt_file, p->key, + fmt_orev, li->rev_new); + break; + + case T_REMOVED: + (void) fprintf (fp, "%s\t%-*s %-*s\n", + prefix, fmt_file, p->key, + fmt_orev, li->rev_old); + break; + + default: + case T_MODIFIED: + (void) fprintf (fp, "%s\t%-*s %-*s %-*s +%-*d -%-*d\n", + prefix, fmt_file, p->key, + fmt_orev, li->rev_old, + fmt_nrev, li->rev_new, + fmt_add, li->add, fmt_del, li->del); + break; + } + } + return (0); +} + /* * Builds a temporary file using setup_tmpfile() and invokes the user's * editor on the file. The header garbage in the resultant file is then @@ -611,6 +702,16 @@ (void) strcat (str_list, (li->rev_new ? li->rev_new : "NONE")); break; + case 't': + str_list = + xrealloc (str_list, + (strlen (str_list) + + (li->tag ? strlen (li->tag) : 0) + + 10) + ); + (void) strcat (str_list, (li->tag + ? li->tag : "NONE")); + break; /* All other characters, we insert an empty field (but we do put in the comma separating it from other fields). This way if future CVS versions add formatting @@ -672,6 +773,7 @@ s = file name V = old version number (pre-checkin) v = new version number (post-checkin) + t = file tag For example, valid format strings are: Index: src/parseinfo.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/parseinfo.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/parseinfo.c 2001/03/14 22:37:38 1.1.1.1 +++ src/parseinfo.c 2001/03/16 01:50:25 1.2 @@ -367,6 +367,18 @@ goto error_return; } } + else if (strcmp (line, "LogMsgFancy") == 0) + { + if (strcmp (p, "no") == 0) + logmsg_fancy = 0; + else if (strcmp (p, "yes") == 0) + logmsg_fancy = 1; + else + { + error (0, 0, "unrecognized value '%s' for LogMsgFancy", p); + goto error_return; + } + } else if (strcmp (line, "LockDir") == 0) { if (lock_dir != NULL) Index: src/rcs.c =================================================================== RCS file: /usr/home/greg/repository/cvs/src/rcs.c,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- src/rcs.c 2001/03/14 22:37:39 1.1.1.1 +++ src/rcs.c 2001/03/16 01:50:25 1.3 @@ -4772,6 +4772,69 @@ return newrevnum; } + +static void compute_change_stats PROTO ((char *, int, unsigned *, unsigned *)); + +static void +compute_change_stats(text, len, addp, delp) + char *text; + int len; + unsigned *addp; + unsigned *delp; +{ + unsigned add=0, del=0; + char *cp; + + if (addp == NULL || delp == NULL) + return; + + *addp = 0; + *delp = 0; + + if (text == NULL) + return; + + cp = text; + while (cp < text + len) { + char op; + unsigned long count; + + op = *cp++; + if (op != 'a' && op != 'd') + return; + + (void) strtoul (cp, &cp, 10); + if (*cp++ != ' ') + return; + + count = strtoul (cp, &cp, 10); + if (*cp++ != '\012') + return; + + if (op == 'd') + del += count; + else { + add += count; + while (count != 0) + { + if (*cp == '\012') + --count; + else if (cp == text + len) + { + if (count != 1) + return; + else + break; + } + ++cp; + } + } + } + + *addp = add; + *delp = del; +} + /* Check in to RCSFILE with revision REV (which must be greater than the largest revision) and message MESSAGE (which is checked for legality). If FLAGS & RCS_FLAGS_DEAD, check in a dead revision. @@ -4794,12 +4857,13 @@ or zero for success. */ int -RCS_checkin (rcs, workfile, message, rev, flags) +RCS_checkin (rcs, workfile, message, rev, flags, add, del) RCSNode *rcs; char *workfile; char *message; char *rev; int flags; + unsigned *add, *del; { RCSVers *delta, *commitpt; Deltatext *dtext; @@ -5302,6 +5366,9 @@ commitpt->text->text = xstrdup (""); commitpt->text->len = 0; } + + compute_change_stats (commitpt->text->text, commitpt->text->len, + del, add); /* NB: the diff was reversed.. */ } else { @@ -5333,6 +5400,8 @@ dtext->text = xstrdup (""); dtext->len = 0; } + + compute_change_stats (dtext->text, dtext->len, add, del); } /* Update DELTA linkage. It is important not to do this before Index: src/rcs.h =================================================================== RCS file: /usr/home/greg/repository/cvs/src/rcs.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/rcs.h 2001/03/14 22:37:38 1.1.1.1 +++ src/rcs.h 2001/03/14 22:48:13 1.2 @@ -218,7 +218,7 @@ int RCS_checkout PROTO ((RCSNode *, char *, char *, char *, char *, char *, RCSCHECKOUTPROC, void *)); int RCS_checkin PROTO ((RCSNode *rcs, char *workfile, char *message, - char *rev, int flags)); + char *rev, int flags, unsigned *add, unsigned *del)); int RCS_cmp_file PROTO ((RCSNode *, char *, char *, const char *)); int RCS_settag PROTO ((RCSNode *, const char *, const char *)); int RCS_deltag PROTO ((RCSNode *, const char *));