This was probably a stupid question.  What I really wanted to know was
- will the file change if I do a "fossil update".   I now have a 
newer version of emacs integration done.  

Much thanks to drh for the finfo changes in the tree.  My zip from
last time doesn't seem to have made it.  I'm attaching files inline.

Here are the fossil related changes:

 1. fossil finfo -b|--brief <filename> gives a brief 
     (one line per revision, and it prints revision numbers).  The revision
     numbers are checkin-numbers.
 2. fossil finfo -s|--status <filename> prints the
     edited state and the (checkin) revision numbers.
 3. fossil finfo -p|--print -r|--revision <rev> <filename>.  Prints the
     file from the specified (checkin) revision number.
 4. fossil update --local, does a local update without an autosync, even if
    autosync was turned on.
 5. fossil update -n|--nochange, goes through the update process (syncing if 
--local
    was not specified), but does not change any checked out file.  It prints
    out the actions it would do if -n was not specified
 6. fossil update -v|--verbose, prints messages to stdout for unchanged/edited 
files

The vc-fossil.el included here uses  
    fossil finfo -l -b
    fossil finfo -s
    fossil finfo -p -r 
    fossil update --local -n -v
    fossil diff -r 


first below is fossil diff of my clone, after 3.6.20 sqlite3 upgrade.
I have merged in drh's changes from this weekend. second is the
current vc-fossil.el.  There must be a better way to submit patches,
but I don't know about it yet.

If it makes sense, I'd suggest adding vc-fossil.el as a new file to
the repository.

Thanks

 - Venkat

Index: src/finfo.c
===================================================================
fossil diff /proj/baliva/users/venkat/fossil/tool/head/fossil/src/finfo.c
--- src/finfo.c
+++ src/finfo.c
@@ -27,71 +27,165 @@
 #include "finfo.h"
 
 /*
 ** COMMAND: finfo
 **
-** Usage: %fossil finfo FILENAME
+** Usage: %fossil finfo -l|--log ?-b|--brief? FILENAME / -s|--status FILENAME 
/ -p|--print ?-r|--revision REV?FILENAME
 **
-** Print the change history for a single file.
+** Print the complete change history for a single file going backwards
+** in time.  If -l is specified the full comment is printed, otherwise
+** one line is printed per revision.
 **
 ** The "--limit N" and "--offset P" options limits the output to the first
 ** N changes after skipping P changes.
+**
+** In the -s form prints the status as <status> <revision>
+**
+** In the -p form prints to stdout the revision of the file specified by REV
+**
 */
+
 void finfo_cmd(void){
-  Stmt q;
-  int vid;
-  Blob dest;
-  const char *zFilename;
-  const char *zLimit;
-  const char *zOffset;
-  int iLimit, iOffset;
+  int vid;
 
   db_must_be_within_tree();
   vid = db_lget_int("checkout", 0);
   if( vid==0 ){
     fossil_panic("no checkout to finfo files in");
   }
-  zLimit = find_option("limit",0,1);
-  iLimit = zLimit ? atoi(zLimit) : -1;
-  zOffset = find_option("offset",0,1);
-  iOffset = zOffset ? atoi(zOffset) : 0;
-  if (g.argc<3) {
-    usage("FILENAME");
-  }
-  file_tree_name(g.argv[2], &dest, 1);
-  zFilename = blob_str(&dest);
-  db_prepare(&q,
-    "SELECT b.uuid, ci.uuid, date(event.mtime,'localtime'),"
-    "       coalesce(event.ecomment, event.comment),"
-    "       coalesce(event.euser, event.user)"
-    "  FROM mlink, blob b, event, blob ci"
-    " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
-    "   AND b.rid=mlink.fid"
-    "   AND event.objid=mlink.mid"
-    "   AND event.objid=ci.rid"
-    " ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
-    zFilename, iLimit, iOffset
-  );
+  vfile_check_signature(vid);
+  if (find_option("status","s",0)) {
+      Stmt q;
+      Blob line;
+      Blob fname;
+
+      if (g.argc != 3) {
+         usage("-s|--status FILENAME");
+      }
+      file_tree_name(g.argv[2], &fname, 1);
+      db_prepare(&q,
+                "SELECT pathname, deleted, rid, chnged, 
coalesce(origname!=pathname,0)"
+                "  FROM vfile WHERE vfile.pathname=%B", &fname);
+      blob_zero(&line);
+      if ( db_step(&q)==SQLITE_ROW ) {
+         Blob uuid;
+         int isDeleted = db_column_int(&q, 1);
+         int isNew = db_column_int(&q,2) == 0;
+         int chnged = db_column_int(&q,3);
+         int renamed = db_column_int(&q,4);
+
+         blob_zero(&uuid);
+         db_blob(&uuid,"SELECT uuid FROM blob, mlink, vfile WHERE "
+                 "blob.rid = mlink.mid AND mlink.fid = vfile.rid AND "
+                 "vfile.pathname=%B",&fname);
+         if (isNew) {
+             blob_appendf(&line, "new");
+         } else if (isDeleted) {
+             blob_appendf(&line, "deleted");
+         } else if (renamed) {
+             blob_appendf(&line, "renamed");
+         } else if (chnged) {
+             blob_appendf(&line, "edited");
+         } else {
+             blob_appendf(&line, "unchanged");
+         }
+         blob_appendf(&line, " ");
+         blob_appendf(&line, " %10.10s", blob_str(&uuid));
+         blob_reset(&uuid);
+      } else {
+         blob_appendf(&line, "unknown 0000000000");
+      }
+      db_finalize(&q);
+      printf("%s\n", blob_str(&line));
+      blob_reset(&fname);
+      blob_reset(&line);
+  } else if (find_option("print","p",0)) {
+      Blob record;
+      Blob fname;
+      const char *zRevision = find_option("revision", "r", 1);
+
+      file_tree_name(g.argv[2], &fname, 1);
+      if (zRevision) {
+         historical_version_of_file(zRevision, blob_str(&fname), &record);
+      } else {
+         int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", 
&fname);
+         if( rid==0 ){
+             fossil_fatal("no history for file: %b", &fname);
+         }
+         content_get(rid, &record);
+      }
+      blob_write_to_file(&record, "-");
+      blob_reset(&record);
+      blob_reset(&fname);
+  } else if (find_option("log","l",0)) {
+      Blob line;
+      Stmt q;
+      Blob fname;
+      int rid;
+      const char *zFilename;
+      const char *zLimit;
+      const char *zOffset;
+      int iLimit, iOffset, iVerbose;
 
-  printf("History of %s\n", zFilename);
-  while( db_step(&q)==SQLITE_ROW ){
-    const char *zFileUuid = db_column_text(&q, 0);
-    const char *zCiUuid = db_column_text(&q, 1);
-    const char *zDate = db_column_text(&q, 2);
-    const char *zCom = db_column_text(&q, 3);
-    const char *zUser = db_column_text(&q, 4);
-    char *zOut;
-    printf("%s ", zDate);
-    zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])",
-                            zCiUuid, zCom, zUser, zFileUuid);
-    comment_print(zOut, 11, 79);
-    sqlite3_free(zOut);
+      zLimit = find_option("limit",0,1);
+      iLimit = zLimit ? atoi(zLimit) : -1;
+      zOffset = find_option("offset",0,1);
+      iOffset = zOffset ? atoi(zOffset) : 0;
+      iVerbose = (find_option("brief","b",0) == 0);
+      if (g.argc != 3) {
+         usage("-l|--log ?-v|--verbose? FILENAME");
+      }
+      file_tree_name(g.argv[2], &fname, 1);
+      rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
+      if( rid==0 ){
+         fossil_fatal("no history for file: %b", &fname);
+      }
+      zFilename = blob_str(&fname);
+      db_prepare(&q,
+                "SELECT b.uuid, ci.uuid, date(event.mtime,'localtime'),"
+                "       coalesce(event.ecomment, event.comment),"
+                "       coalesce(event.euser, event.user)"
+                "  FROM mlink, blob b, event, blob ci"
+                " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
+                "   AND b.rid=mlink.fid"
+                "   AND event.objid=mlink.mid"
+                "   AND event.objid=ci.rid"
+                " ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
+                zFilename, iLimit, iOffset
+         );
+      blob_zero(&line);
+      if (iVerbose) {
+         printf("History of %s\n", blob_str(&fname));
+      }
+      while( db_step(&q)==SQLITE_ROW ){
+         const char *zFileUuid = db_column_text(&q, 0);
+         const char *zCiUuid = db_column_text(&q,1);
+         const char *zDate = db_column_text(&q, 2);
+         const char *zCom = db_column_text(&q, 3);
+         const char *zUser = db_column_text(&q, 4);
+         char *zOut;
+         if (iVerbose) {
+             printf("%s ", zDate);
+             zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])",
+                                    zCiUuid, zCom, zUser, zFileUuid);
+             comment_print(zOut, 11, 79);
+             sqlite3_free(zOut);
+         } else {
+             blob_reset(&line);
+             blob_appendf(&line, "%.10s ", zCiUuid);
+             blob_appendf(&line, "%.10s ", zDate);
+             blob_appendf(&line, "%8.8s ", zUser);
+             blob_appendf(&line,"%-40.40s\n", zCom );
+             comment_print(blob_str(&line), 0, 79);
+         }
+      }
+      db_finalize(&q);
+      blob_reset(&fname);
+  } else {
+      usage("at least one of -p,-s,-l must be specified");
   }
-  db_finalize(&q);
-  blob_reset(&dest);
-}
-
+}
 
 /*
 ** WEBPAGE: finfo
 ** URL: /finfo?name=FILENAME
 **

Index: src/update.c
===================================================================
fossil diff /proj/baliva/users/venkat/fossil/tool/head/fossil/src/update.c
--- src/update.c
+++ src/update.c
@@ -53,14 +53,20 @@
   int vid;              /* Current version */
   int tid=0;            /* Target version - version we are changing to */
   Stmt q;
   int latestFlag;       /* Pick the latest version if true */
   int forceFlag;        /* True force the update */
+  int nochangeFlag;    /* Do not modify any files other than repository */
+  int verboseFlag;     /* Print states of all files */
+  int localFlag;        /* if 1, do not autosync */
 
   url_proxy_options();
   latestFlag = find_option("latest",0, 0)!=0;
   forceFlag = find_option("force","f",0)!=0;
+  nochangeFlag = find_option("nochange","n",0)!= 0;
+  verboseFlag = find_option("verbose","v",0)!= 0;
+  localFlag = find_option("local", 0,0) != 0;
   if( g.argc!=3 && g.argc!=2 ){
     usage("?VERSION?");
   }
   db_must_be_within_tree();
   vid = db_lget_int("checkout", 0);
@@ -79,11 +85,11 @@
     if( !is_a_version(tid) ){
       fossil_fatal("not a version: %s", g.argv[2]);
     }
   }
 
-  if( tid==0 ){
+  if( tid==0 && localFlag == 0){
     /*
     ** Do an autosync pull prior to the update, if autosync is on and they
     ** did not want a specific version (i.e. another branch, a past revision).
     ** By not giving a specific version, they are asking for the latest, thus
     ** pull to get the latest, then update.
@@ -107,13 +113,16 @@
     tid = db_int(0, "SELECT rid FROM leaves, event"
                     " WHERE event.objid=leaves.rid"
                     " ORDER BY event.mtime DESC");
   }
 
-  db_begin_transaction();
+  if (!nochangeFlag) {
+      db_begin_transaction();
+  }
   vfile_check_signature(vid);
-  undo_begin();
+  if (!nochangeFlag)
+      undo_begin();
   load_vfile_from_rid(tid);
 
   /*
   ** The record.fn field is used to match files against each other.  The
   ** FV table contains one row for each each unique filename in
@@ -179,70 +188,94 @@
       */
       printf("CONFLICT %s\n", zName);
     }else if( idt>0 && idv==0 ){
       /* File added in the target. */
       printf("ADD %s\n", zName);
-      undo_save(zName);
-      vfile_to_disk(0, idt, 0);
+      if (!nochangeFlag) {
+         undo_save(zName);
+         vfile_to_disk(0, idt, 0);
+      }
+    }else if ( idt>0 && idv>0 && ridt == ridv){
+      /* We have latest version */
+       if (verboseFlag) {
+           if (chnged) {
+               printf("EDITED %s\n", zName);
+           } else {
+               printf("UNCHANGED %s\n", zName);
+           }
+       }
     }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
       /* The file is unedited.  Change it to the target version */
       printf("UPDATE %s\n", zName);
-      undo_save(zName);
-      vfile_to_disk(0, idt, 0);
+      if (!nochangeFlag) {
+         undo_save(zName);
+         vfile_to_disk(0, idt, 0);
+      }
     }else if( idt==0 && idv>0 ){
       if( ridv==0 ){
         /* Added in current checkout.  Continue to hold the file as
         ** as an addition */
-        db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
+       if (verboseFlag) {
+           printf("ADDED %s\n", zName);
+       }
+       if (!nochangeFlag) {
+           db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
+       }
       }else if( chnged ){
         printf("CONFLICT %s\n", zName);
       }else{
         char *zFullPath;
         printf("REMOVE %s\n", zName);
-        undo_save(zName);
-        zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
-        unlink(zFullPath);
-        free(zFullPath);
+       if (!nochangeFlag) {
+           undo_save(zName);
+           zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
+           unlink(zFullPath);
+           free(zFullPath);
+       }
       }
     }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
       /* Merge the changes in the current tree into the target version */
-      Blob e, r, t, v;
-      int rc;
-      char *zFullPath;
       printf("MERGE %s\n", zName);
-      undo_save(zName);
-      zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
-      content_get(ridt, &t);
-      content_get(ridv, &v);
-      blob_zero(&e);
-      blob_read_from_file(&e, zFullPath);
-      rc = blob_merge(&v, &e, &t, &r);
-      if( rc>=0 ){
-        blob_write_to_file(&r, zFullPath);
-        if( rc>0 ){
-          printf("***** %d merge conflicts in %s\n", rc, zName);
-        }
-      }else{
-        printf("***** Cannot merge binary file %s\n", zName);
-      }
-      free(zFullPath);
-      blob_reset(&v);
-      blob_reset(&e);
-      blob_reset(&t);
-      blob_reset(&r);
-
+      if (!nochangeFlag) {
+         Blob e, r, t, v;
+         int rc;
+         char *zFullPath;
+
+         undo_save(zName);
+         zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
+         content_get(ridt, &t);
+         content_get(ridv, &v);
+         blob_zero(&e);
+         blob_read_from_file(&e, zFullPath);
+         rc = blob_merge(&v, &e, &t, &r);
+         if( rc>=0 ){
+             blob_write_to_file(&r, zFullPath);
+             if( rc>0 ){
+                 printf("***** %d merge conflicts in %s\n", rc, zName);
+             }
+         }else{
+             printf("***** Cannot merge binary file %s\n", zName);
+         }
+         free(zFullPath);
+         blob_reset(&v);
+         blob_reset(&e);
+         blob_reset(&t);
+         blob_reset(&r);
+      }
     }
   }
   db_finalize(&q);
 
   /*
   ** Clean up the mid and pid VFILE entries.  Then commit the changes.
   */
-  db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid);
-  manifest_to_disk(tid);
-  db_lset_int("checkout", tid);
-  db_end_transaction(0);
+  if (!nochangeFlag) {
+      db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid);
+      manifest_to_disk(tid);
+      db_lset_int("checkout", tid);
+      db_end_transaction(0);
+  }
 }
 
 
 /*
 ** Get the contents of a file within a given revision.

;;; vc-fossil.el --- VC backend for the fossil sofware configuraiton management 
system
;; Author: Venkat Iyer <[email protected]>

;;; Commentary:

;; This file contains a VC backend for the fossil version control
;; system.
;;

;;; Installation:

;; 1. Put this file somewhere in the emacs load-path.  2. Add Fossil
;; to the list of supported backends in `vc-handled-backends'
;;
;; e.g.    (add-to-list 'vc-handled-backends 'Fossil)

;;; Implemented Functions
;; BACKEND PROPERTIES
;; * revision-granularity
;; STATE-QUERYING FUNCTIONS
;; * registered (file)   
;; * state (file) - 'up-to-date 'edited 'needs-patch 'needs-merge 
;; * workfile-version (file)
;; * checkout-model (file)
;; - workfile-unchanged-p (file)
;; STATE-CHANGING FUNCTIONS
;; * register (file &optional rev comment)
;; * checkin (file rev comment)
;; * find-version (file rev buffer)
;; * checkout (file &optional editable rev)
;; * revert (file &optional contents-done)
;; - responsible-p (file)
;; HISTORY FUNCTIONS
;; * print-log (file &optional buffer)
;; * diff (file &optional rev1 rev2 buffer)
;; MISCELLANEOUS
;; - delete-file (file)
;; - rename-file (old new)

(eval-when-compile (require 'cl) (require 'vc))

;;; BACKEND PROPERTIES

(defun vc-fossil-revision-granularity ()
     'repository)

(defun vc-fossil-command (buffer okstatus file-or-list &rest flags)
  "A wrapper around `vc-do-command' for use in vc-fossil.el.
   The difference to vc-do-command is that this function always invokes 
`fossil'."
  (apply 'vc-do-command buffer okstatus "fossil" file-or-list flags ))


;; Should merge this with next function.

(defun vc-fossil-run (&rest args)
  "Run a fossil command on FILE and return its output as string."
  (let* ((ok t)
         (str (with-output-to-string
                (with-current-buffer standard-output
                  (unless (eq 0 (apply #'call-process "fossil" nil '(t nil) nil
                                       (append args)))
                    (setq ok nil))))))
    (and ok str)))


(defun vc-fossil-filestr (file &rest args)
  "Run a fossil command on FILE and return its output as string."
  (let* ((ok t)
         (str (with-output-to-string
                (with-current-buffer standard-output
                  (unless (eq 0 (apply #'call-process "fossil" nil '(t nil) nil
                                       (append args (list (file-relative-name 
file)))))
                    (setq ok nil))))))
    (and ok str)))

;;; STATE-QUERYING FUNCTIONS

(defun vc-fossil-registered (file)
  "Check whether FILE is registered with fossil."
  (with-temp-buffer
    (let* ((dir (file-name-directory file))
           (name (file-relative-name file dir)))
      (and (ignore-errors
             (when dir (cd dir))
             (eq 0 (call-process "fossil" nil '(t nil) nil "finfo" "-s" name)))
             (let ((str (buffer-string)))
               (and (not 
                    (string= (substring str 0 7) "unknown"))))))))

(defun vc-fossil-state (file)
  "Fossil specific version of `vc-state'."
  (let ((state (vc-fossil-filestr file "finfo" "-s")))
    (if (not state)
        nil
      (if (string-match "unchanged" state)
              'up-to-date 'edited))))


(defun vc-fossil-dir-state (dir)
  (with-temp-buffer
    (vc-fossil-command (current-buffer) nil nil "update" "-n" "-v" "--local")
    (goto-char (point-min))
    (let ((status-word nil)
          (file nil))
      (while (not (eobp))
        (setq line (buffer-substring-no-properties (point) (line-end-position)))
        (setq status-word (car (split-string line)))
        (setq file (expand-file-name (substring line (+ (length status-word) 
1))))
        ; (message (format "File <%s> of status <%s>" file status-word))
        (cond
         ((string= status-word "UNCHANGED")
          (vc-file-setprop file 'vc-backend 'Fossil)
          (vc-file-setprop file 'vc-state 'up-to-date))
         ((or (string= status-word "EDITED") (string= status-word "CONFLICT") 
(string= status-word "ADDED")
              (string= status-word "REMOVE"))
          (vc-file-setprop file 'vc-backend 'Fossil)
          (vc-file-setprop file 'vc-state   'edited))
         ((string= status-word "UPDATE")
          (vc-file-setprop file 'vc-backend 'Fossil)
          (vc-file-setprop file 'vc-state   'needs-patch))
         ((string= status-word "MERGE")
          (vc-file-setprop file 'vc-backend 'Fossil)
          (vc-file-setprop file 'vc-state   'needs-merge))
         ((string= status-word "UNKNOWN")
          (vc-file-setprop file 'vc-backend 'none)
          (vc-file-setprop file 'vc-state   'nil)))
        (forward-line)))))
         

(defun vc-fossil-workfile-version (file)
  "Fossil specific version of `vc-workfile-version'."
  (let ((state (vc-fossil-filestr file "finfo" "-s")))
    (if (not state)
        nil
      (car (cdr (split-string state))))))

(defun vc-fossil-checkout-model (file)
  'implicit)

(defun vc-fossil-workfile-unchanged-p (file)
  (eq 'up-to-date (vc-fossil-state file)))

;;; STATE-CHANGING FUNCTIONS

(defun vc-fossil-create-repo ()
  "Create a new Fossil Repository."
  (vc-fossil-command nil 0 nil "new"))

;; We ignore the comment.  There's no comment on add.
(defun vc-fossil-register (files &optional rev comment)
  "Register FILE into the fossil version-control system."
  (vc-fossil-command nil 0 files "add"))

(defun vc-fossil-responsible-p (file)
  "Check whether FILE (directory) is handled by fossil."
  (let ((dir (if (file-directory-p file) file (file-name-directory file))))
        (and (ignore-errors
              (when dir (cd dir))
              (if (vc-fossil-run "info") t)))))

(defun vc-fossil-unregister (file)
  (vc-fossil-command nil 0 file "rm"))


(defun vc-fossil-checkin (files rev comment)
  (vc-fossil-command nil 0 files "commit" "-m" comment))


(defun vc-fossil-find-version (file rev buffer)
  (if (string= rev "")
      (vc-fossil-command buffer 0 file "finfo" "-p")
      (vc-fossil-command buffer 0 file "finfo" "-r" rev "-p")))

(defun vc-fossil-checkout (file &optional editable rev)
  (if (eq rev t)
      (vc-fossil-command nil 0 nil "update")
    ((vc-fossil-command nil 0 nil "update" rev)
  )))

(defun vc-fossil-revert (file &optional contents-done)
  "Revert FILE to the version stored in the fossil repository."
  (if contents-done t
    (vc-fossil-command nil 0 file "revert" "--yes")))

;; HISTORY FUNCTIONS

(defun vc-fossil-print-log (file &optional buffer)
  "Print full log for a file"
  (vc-fossil-command buffer 0 file "finfo" "-l" "-b"))

(defun vc-fossil-diff (file &optional rev1 rev2 buffer)
  "Get Differences for a file"
  (if (and rev1 rev2)
      (error "Can't handle 2 revisions in diff <%s> and <%s>" rev1 rev2)
    (let ((buf (or buffer "*vc-diff*")))
      (vc-fossil-command buf 0 file "diff" "-i" "-r" rev1))))

;;; MISCELLANEOUS

(defun vc-fossil-delete-file (file)
  (vc-fossil-command nil 0 file "rm"))

(defun vc-fossil-rename-file (old new)
  (vc-fossil-command nil 0 (list old new) "mv"))

(provide 'vc-fossil)
;; End of vc-fossil.el

_______________________________________________
fossil-users mailing list
[email protected]
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to