Fossil Forum

Command 'open --empty' succeeds but (nearly) every subsequent command fails
Login

Command 'open --empty' succeeds but (nearly) every subsequent command fails

Command 'open --empty' succeeds but (nearly) every subsequent command fails

(1) By sebyte on 2023-09-08 11:23:59 [link] [source]

There seems to have been a regression when it comes to checkouts created using 'open --empty':

  ~/fossil/sandpit/bar $ fossil open --empty ../foo.fossil 
  project-name: <unnamed>
  [...]
  check-ins:    2
  ~/fossil/sandpit/bar $ fossil info
  Database error: unable to find the name of a repository database
  ~/fossil/sandpit/bar $ fossil branch current
  Database error: unable to find the name of a repository database
  ~/fossil/sandpit/bar $ fossil version
  This is fossil version 2.23 [dedfb13bf6] 2023-09-01 11:36:48 UTC

For context, here are two earlier discussions around the use of 'open --empty':

'branch current' returns nothing immediately after 'open --empty'

Revert fails in branchless checkouts

(2) By Preben Guldberg (preben) on 2023-09-09 12:34:28 in reply to 1 [source]

As far as I can tell, this is caused by check-in 4d8c30265b from January 24th.

In db_open_local_v2(), g.localOpen used to be set to 1, but is changed to use the db_lget_int("checkout", -1):

    -        g.localOpen = 1;
    +        g.localOpen = db_lget_int("checkout", -1);

When using fossil open --empty, this would then set g.localOpen to 0 (at least as I understand it by inspection of the resulting .fslckout db).

This in turn affects db_open_repository(), where the error stems from:

    void db_open_repository(const char *zDbName){
      if( g.repositoryOpen ) return;
      if( zDbName==0 ){
        if( g.localOpen ){
          zDbName = db_repository_filename();
        }
        if( zDbName==0 ){
          db_err("unable to find the name of a repository database");
        }
      }

I think this could be fixed by reverting the change concerning g.localOpen and amending the outer check in the following change in symbolic_name_to_rid():

    -  /* special keywords: "prev", "previous", "current", and "next" */
    -  if( g.localOpen && (vid=db_lget_int("checkout",0))!=0 ){
    +  /* special keywords: "prev", "previous", "current", "ckout", and
    +  ** "next" */
    +  if( g.localOpen>0 && (zType[0]=='*' || isCheckin!=0) ){
    +    const int vid = g.localOpen;
         if( fossil_strcmp(zTag, "current")==0 ){
           rid = vid;
         }else if( fossil_strcmp(zTag, "prev")==0
                   || fossil_strcmp(zTag, "previous")==0 ){
           rid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", vid);
         }else if( fossil_strcmp(zTag, "next")==0 ){
           rid = db_int(0, "SELECT cid FROM plink WHERE pid=%d"
                           "  ORDER BY isprim DESC, mtime DESC", vid);
    +    }else if( isCheckin>1 && fossil_strcmp(zTag, "ckout")==0 ){
    +      rid = RID_CKOUT;
         }
         if( rid ) return rid;
       }

The following patch addresses the problem for me for the commands mentioned.

Whether it has ramifications elsewhere in the code, I don't know, though.

Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -2541,11 +2541,11 @@
         while( n>0 && zPwd[n-1]=='/' ){
           n--;
           zPwd[n] = 0;
         }
         g.zLocalRoot = mprintf("%s/", zPwd);
-        g.localOpen = db_lget_int("checkout", -1);
+        g.localOpen = 1;
         db_open_repository(zDbName);
         return 1;
       }
     }
     if( bRootOnly ) break;

Index: src/name.c
==================================================================
--- src/name.c
+++ src/name.c
@@ -398,10 +398,11 @@
 ** the ticket-change or technote-change artifact, not the randomly generated
 ** hexadecimal identifier assigned to tickets and events.  Those identifiers
 ** live in a separate namespace.
 */
 int symbolic_name_to_rid(const char *zTag, const char *zType){
+  int vid = 0;
   int rid = 0;
   int nTag;
   int i;
   int startOfBranch = 0;
   const char *zXTag;     /* zTag with optional [...] removed */
@@ -436,12 +437,12 @@
     if( rid ) return rid;
   }
 
   /* special keywords: "prev", "previous", "current", "ckout", and
   ** "next" */
-  if( g.localOpen>0 && (zType[0]=='*' || isCheckin!=0) ){
-    const int vid = g.localOpen;
+  if( g.localOpen ) vid = db_lget_int("checkout",0);
+  if( vid!=0 && (zType[0]=='*' || isCheckin!=0) ){
     if( fossil_strcmp(zTag, "current")==0 ){
       rid = vid;
     }else if( fossil_strcmp(zTag, "prev")==0
               || fossil_strcmp(zTag, "previous")==0 ){
       rid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", vid);

(3) By Stephan Beal (stephan) on 2023-09-09 15:07:09 in reply to 2 [link] [source]

This in turn affects db_open_repository(), where the error stems from:

Good catch! That should now be resolved in the trunk version.

Thank you both for the report and the detailed analysis.