bug-cvs
[Top][All Lists]
Advanced

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

cvs rdiff -B feature


From: karl
Subject: cvs rdiff -B feature
Date: Mon, 3 Sep 2001 19:21:54 -0400 (EDT)

Enclosed is a patch that implements a new option -B to rdiff.  This
tells it not to output the contents of binary files, only the headers.
This is useful because diffs of arbitrary binary files cannot be parsed
by other tools.

In particular, I wrote a tool to show the history of changes made on a
branch since a given date, which uses rdiff.  (I'm happy to share the
tool if anyone wants it.)  It needs -B to get the right output.

It's also necessary to always get the time of the second file in the
diff, so the right time can be shown for removed files.

I posted this before, for 1.11, but apparently it never made it into the
sources.  Hope you'll accept it.

Thanks,
karl


*** /usr/local/gnu/src/cvs-1.11.1p1/src/ORIG/patch.c    Tue Apr 24 14:14:53 2001
--- /usr/local/gnu/src/cvs-1.11.1p1/src/patch.c Mon Sep  3 18:45:27 2001
***************
*** 28,33 ****
--- 28,34 ----
  static int force_tag_match = 1;
  static int patch_short = 0;
  static int toptwo_diffs = 0;
+ static int binary_file_info = 0;
  static int local = 0;
  static char *options = NULL;
  static char *rev1 = NULL;
***************
*** 53,58 ****
--- 54,60 ----
      "\t-s\tShort patch - one liner per file.\n",
      "\t-t\tTop two diffs - last change made to the file.\n",
      "\t-D date\tDate.\n",
+     "\t-B\tShow headers for binary files.\n",
      "\t-r rev\tRevision - symbolic or numeric.\n",
      "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
      "(Specify the --help global option for a list of other help options)\n",
***************
*** 73,79 ****
        usage (patch_usage);
  
      optind = 0;
!     while ((c = getopt (argc, argv, "+V:k:cuftsQqlRD:r:")) != -1)
      {
        switch (c)
        {
--- 75,81 ----
        usage (patch_usage);
  
      optind = 0;
!     while ((c = getopt (argc, argv, "+V:k:cuftsQqlRD:r:B")) != -1)
      {
        switch (c)
        {
***************
*** 103,108 ****
--- 105,113 ----
            case 's':
                patch_short = 1;
                break;
+           case 'B':
+               binary_file_info = 1;
+               break;
            case 'D':
                if (rev2 != NULL || date2 != NULL)
                    error (1, 0,
***************
*** 207,212 ****
--- 212,219 ----
            send_arg("-s");
        if (unidiff)
            send_arg("-u");
+       if (binary_file_info)
+           send_arg("-B");
  
        if (rev1)
            option_with_arg ("-r", rev1);
***************
*** 373,378 ****
--- 380,386 ----
      struct file_info *finfo;
  {
      struct utimbuf t;
+     time_t file2_time = -1;
      char *vers_tag, *vers_head;
      char *rcs = NULL;
      RCSNode *rcsfile;
***************
*** 389,394 ****
--- 397,403 ----
      char *cp1, *cp2;
      FILE *fp;
      int line_length;
+     char *diff_options;
  
      line1 = NULL;
      line1_chars_allocated = 0;
***************
*** 416,421 ****
--- 425,431 ----
                                    (int *) NULL);
        if (vers_head != NULL && RCS_isdead (rcsfile, vers_head))
        {
+           file2_time = RCS_getrevtime (rcsfile, vers_head, date2, 1);
            free (vers_head);
            vers_head = NULL;
        }
***************
*** 575,588 ****
            ret = 1;
            goto out;
        }
!       if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_head,
!                                                   (char *) 0, 0)) != -1)
!           /* I believe this timestamp only affects the dates in our diffs,
!              and therefore should be on the server, not the client.  */
!           (void) utime (tmpfile2, &t);
      }
  
!     switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, unidiff ? "-u" : "-c", 
tmpfile3))
      {
        case -1:                        /* fork/wait failure */
            error (1, errno, "fork for diff failed on %s", rcs);
--- 585,610 ----
            ret = 1;
            goto out;
        }
!       /* Always get file2_time so we can put the right timestamp in
!          the header if it was removed.  */
!       file2_time = RCS_getrevtime (rcsfile, vers_head, (char *) 0, 0);
      }
  
!     /* Set mod time on file2 */
!     if (file2_time != -1)
!     {
!         t.actime = t.modtime = file2_time;
!         /* I believe this timestamp only affects the dates in our diffs,
!            and therefore should be on the server, not the client.  */
!         (void) utime (tmpfile2, &t);
!     }
! 
!     if (unidiff)
!       diff_options = binary_file_info ? "-u --text" : "-u";
!     else
!       diff_options = binary_file_info ? "-c --text" : "-c";
!     
!     switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, diff_options, 
tmpfile3))
      {
        case -1:                        /* fork/wait failure */
            error (1, errno, "fork for diff failed on %s", rcs);
***************
*** 707,716 ****
            cvs_output (cp2, 0);
  
            /* spew the rest of the diff out */
!           while ((line_length
!                   = getline (&line1, &line1_chars_allocated, fp))
!                  >= 0)
                cvs_output (line1, 0);
            if (line_length < 0 && !feof (fp))
                error (0, errno, "cannot read %s", tmpfile3);
  
--- 729,741 ----
            cvs_output (cp2, 0);
  
            /* spew the rest of the diff out */
!           line_length = 0;
!           if (!binary_file_info)
!             while ((line_length
!                     = getline (&line1, &line1_chars_allocated, fp))
!                    >= 0)
                cvs_output (line1, 0);
+ 
            if (line_length < 0 && !feof (fp))
                error (0, errno, "cannot read %s", tmpfile3);
  

Diff finished at Mon Sep  3 19:21:05



reply via email to

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