info-cvs
[Top][All Lists]
Advanced

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

Re: Editing author names in RCS files


From: Mark D. Baushke
Subject: Re: Editing author names in RCS files
Date: Tue, 07 Dec 2004 08:58:58 -0800

Sylvain Beucler <address@hidden> writes:

> On Mon, Dec 06, 2004 at 04:47:56PM -0800, Mark D. Baushke wrote:
> > Sylvain Beucler <address@hidden> writes:
> > 
> > > Hello,
> > > 
> > > I would like to fix a problem that occured at Savannah. The issue is
> > > pretty much described here:
> > > http://lists.gnu.org/archive/html/savannah-hackers/2004-12/msg00061.html
> > > 
> > > and to sum up, the logged username became uid##### instead of the
> > > actual username, for a few days about a year ago. For example, user
> > > "miles" became "uid65618":
> > > http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/filecache.el
> > > 
> > > The mapping uid<->user can be found using /etc/passwd.
> > > 
> > > 
> > > We would like to write a script to fix these usernames. However,
> > > rcs(1) is not meant to do it; moreover, the various RCS parser I had a
> > > look at are more concerned about extracting revisions than making
> > > changes to the actual RCS file, when they are not beta versions.
> > > 
> > > Various web and mailing list archive searches didn't help.
> > > 
> > > What do you think is the best way to fix the RCS files? Of course,
> > > "manual editing" is valid, but I have the failing to expect a quicker
> > > way :)
> > 
> > Quicker? Hmmm...
> > 
> >    find . -name \*,v -print0 \|
> >    xargs -0 perl -i.bak -pane \
> >   's,^(date\s+[0-9.]+;\s+author\s+)uid65618;(\s+state\s\S;$),$1miles;$2,g;'
> > 
> > Of course, I urge you to ensure that the repository is locked or
> > otherwise not actively being modified when you run the script.
> > 
> > I would suggest performing the initial runs of the script on a snapshot
> > of the repository and then doing a comparison of the .bak files with
> > the original versions to ensure everything looks correct.
> 
> Thanks. However, I was looking for a more "secure" way to do the
> job. In the best case, I would like to apply the script to fix ~2000
> repositories.

Ahhh, well, that does make a difference.

> The script you suggest could match a line in the deltas (for example,
> in a file discussing the RCS format) instead of in the administrative
> part. I could stop the substitution when I meet "desc(\s|\n)@", but I
> am afraid of missing that "separator" when parsing a RCS file
> generated by an older version of CVS - hence why I looked for a RCS
> parser.

Such parsers exist in RCS, CVS, CVSup(d).

> Moreover, it is difficult to test whether the substitution occured
> properly.
> 
> Any idea?

The following hack to the CVS sources will probably do what you want.

  cvs log > before
  cvs admin -guid65618=miles
  cvs log > after
  diff before after

I don't know about the advisiblity of making this a feature of CVS, so
unless other folks specify a need for this kind of addition, I probably
won't be incorporating it into a general CVS release.

        Good luck,
        -- Mark

Index: admin.c
===================================================================
RCS file: /cvs/ccvs/src/admin.c,v
retrieving revision 1.101
diff -u -p -u -p -r1.101 admin.c
--- admin.c     4 Oct 2004 20:37:50 -0000       1.101
+++ admin.c     7 Dec 2004 16:55:38 -0000
@@ -230,7 +230,7 @@ admin (int argc, char **argv)
     optind = 0;
     only_allowed_options = true;
     while ((c = getopt (argc, argv,
-                       "+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1)
+                       "+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:g:")) != -1)
     {
        if (
 # ifdef CLIENT_SUPPORT
@@ -371,6 +371,11 @@ admin (int argc, char **argv)
                strcat (admin_data.delete_revs, optarg);
                break;
 
+           case 'g':
+               /* Note that multiple -g options are valid.  */
+               arg_add (&admin_data, 'g', optarg);
+               break;
+
            case 's':
                /* Note that multiple -s options are valid.  */
                arg_add (&admin_data, 's', optarg);
@@ -614,6 +619,31 @@ admin (int argc, char **argv)
 
 
 
+struct rename_author {
+    char *oldauthor;
+    char *newauthor;
+};
+/*
+ * Replace old author value with newauthor value.
+ * This is called via walklist. 
+ */
+static int
+admin_rename_author (Node *p, void *closure)
+{
+    RCSVers *delta;
+    struct rename_author *ra = closure;
+    int cnt = 0;
+
+    delta = p->data;
+    if (!strcmp (delta->author, ra->oldauthor))
+    {
+       free (delta->author);
+       delta->author = xstrdup (ra->newauthor);
+       cnt++;
+    }
+    return cnt;
+}
+
 /*
  * Called to run "rcs" on a particular file.
  */
@@ -917,6 +947,42 @@ admin_fileproc (void *callerdat, struct 
                delta->state = tag;
                break;
 
+           case 'g':
+               /*
+                * -g oldauthor=newauthor
+                */
+               p = strchr (arg, '=');
+               if (p)
+               {
+                   struct rename_author ra;
+                   char buf[50];
+                   int cnt;
+
+                   *p = '\0';
+                   ra.oldauthor = arg + 2;
+                   ra.newauthor = p + 1;
+
+                   cvs_output ("changed author ", 0);
+                   cvs_output (ra.oldauthor, 0);
+                   cvs_output (" to ", 0);
+                   cvs_output (ra.newauthor, 0);
+                   cvs_output (" in ", 0);
+                   sprintf (buf, "%d",
+                            walklist (rcs->versions, admin_rename_author,
+                                      &ra));
+                   cvs_output (buf, 0);
+                   cvs_output (" revisions.", 0);
+                   cvs_output ("\n", 1);
+                   *p = '=';
+               }
+               else
+               {
+                   error (0, 0, "%s: %s option lacks replacment author",
+                          rcs->path, arg);
+                   status = 1;
+               }
+               break;
+
            case 'm':
                p = strchr (arg, ':');
                if (p == NULL)




reply via email to

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