Fossil

Check-in [15a7b1fd37]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More improvements to "fossil open": Make sure the --repodir is converted into a full pathname so that it is unaffected by --workdir. Report an error with --nested if the new repo would be rooted in the same directory as another repository.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 15a7b1fd377dd67b4c302ad708fd918ad380e9e383599c699233b724155028d4
User & Date: drh 2020-08-08 15:01:30.436
Context
2020-08-08
17:09
Imported a 2-line polyfill for MSIE's missing NodeList.forEach, courtesy of the Mozilla docs. check-in: 4dd270761d user: stephan tags: trunk
15:01
More improvements to "fossil open": Make sure the --repodir is converted into a full pathname so that it is unaffected by --workdir. Report an error with --nested if the new repo would be rooted in the same directory as another repository. check-in: 15a7b1fd37 user: drh tags: trunk
12:41
wikiedit now relabels the Save button while save is in progress, per forum feedback. check-in: 9f3747d8a5 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
1712
1713
1714
1715
1716
1717
1718




1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
** For legacy, also look for ".fos".  The use of ".fos" is deprecated
** since "fos" has negative connotations in Hungarian, we are told.
**
** If no valid _FOSSIL_ or .fslckout file is found, we move up one level and
** try again. Once the file is found, the g.zLocalRoot variable is set
** to the root of the repository tree and this routine returns 1.  If
** no database is found, then this routine return 0.




**
** This routine always opens the user database regardless of whether or
** not the repository database is found.  If the _FOSSIL_ or .fslckout file
** is found, it is attached to the open database connection too.
*/
int db_open_local(const char *zDbName){
  int i, n;
  char zPwd[2000];
  static const char *(aDbName[]) = { "_FOSSIL_", ".fslckout", ".fos" };

  if( g.localOpen ) return 1;
  file_getcwd(zPwd, sizeof(zPwd)-20);
  n = strlen(zPwd);







>
>
>
>





|







1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
** For legacy, also look for ".fos".  The use of ".fos" is deprecated
** since "fos" has negative connotations in Hungarian, we are told.
**
** If no valid _FOSSIL_ or .fslckout file is found, we move up one level and
** try again. Once the file is found, the g.zLocalRoot variable is set
** to the root of the repository tree and this routine returns 1.  If
** no database is found, then this routine return 0.
**
** In db_open_local_v2(), if the bRootOnly flag is true, then only
** look in the CWD for the checkout database.  Do not scan upwards in
** the file hierarchy.
**
** This routine always opens the user database regardless of whether or
** not the repository database is found.  If the _FOSSIL_ or .fslckout file
** is found, it is attached to the open database connection too.
*/
int db_open_local_v2(const char *zDbName, int bRootOnly){
  int i, n;
  char zPwd[2000];
  static const char *(aDbName[]) = { "_FOSSIL_", ".fslckout", ".fos" };

  if( g.localOpen ) return 1;
  file_getcwd(zPwd, sizeof(zPwd)-20);
  n = strlen(zPwd);
1745
1746
1747
1748
1749
1750
1751

1752
1753
1754
1755
1756
1757
1758
1759



1760
1761
1762
1763
1764
1765
1766
        }
        g.zLocalRoot = mprintf("%s/", zPwd);
        g.localOpen = 1;
        db_open_repository(zDbName);
        return 1;
      }
    }

    n--;
    while( n>1 && zPwd[n]!='/' ){ n--; }
    while( n>1 && zPwd[n-1]=='/' ){ n--; }
    zPwd[n] = 0;
  }

  /* A checkout database file could not be found */
  return 0;



}

/*
** Get the full pathname to the repository database file.  The
** local database (the _FOSSIL_ or .fslckout database) must have already
** been opened before this routine is called.
*/







>








>
>
>







1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
        }
        g.zLocalRoot = mprintf("%s/", zPwd);
        g.localOpen = 1;
        db_open_repository(zDbName);
        return 1;
      }
    }
    if( bRootOnly ) break;
    n--;
    while( n>1 && zPwd[n]!='/' ){ n--; }
    while( n>1 && zPwd[n-1]=='/' ){ n--; }
    zPwd[n] = 0;
  }

  /* A checkout database file could not be found */
  return 0;
}
int db_open_local(const char *zDbName){
  return db_open_local_v2(zDbName, 0);
}

/*
** Get the full pathname to the repository database file.  The
** local database (the _FOSSIL_ or .fslckout database) must have already
** been opened before this routine is called.
*/
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
  int allowNested;
  int allowSymlinks;
  int setmtimeFlag;              /* --setmtime.  Set mtimes on files */
  static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
  const char *zWorkDir;          /* --workdir value */
  const char *zRepo = 0;         /* Name of the repository file */
  const char *zRepoDir = 0;      /* --repodir value */
  Blob normalizedRepoName;       /* Normalized repository filename */
  char *zPwd;                    /* Initial working directory */
  int isUri = 0;                 /* True if REPOSITORY is a URI */

  url_proxy_options();
  emptyFlag = find_option("empty",0,0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  forceMissingFlag = find_option("force-missing",0,0)!=0;







<







3127
3128
3129
3130
3131
3132
3133

3134
3135
3136
3137
3138
3139
3140
  int allowNested;
  int allowSymlinks;
  int setmtimeFlag;              /* --setmtime.  Set mtimes on files */
  static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
  const char *zWorkDir;          /* --workdir value */
  const char *zRepo = 0;         /* Name of the repository file */
  const char *zRepoDir = 0;      /* --repodir value */

  char *zPwd;                    /* Initial working directory */
  int isUri = 0;                 /* True if REPOSITORY is a URI */

  url_proxy_options();
  emptyFlag = find_option("empty",0,0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  forceMissingFlag = find_option("force-missing",0,0)!=0;
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160

3161

3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  zRepo = g.argv[2];
  blob_init(&normalizedRepoName, 0, 0);
  if( sqlite3_strglob("http://*", zRepo)==0
   || sqlite3_strglob("https://*", zRepo)==0
   || sqlite3_strglob("ssh:*", zRepo)==0
   || sqlite3_strglob("file:*", zRepo)==0
  ){
    isUri = 1;
  }

  /* If --workdir is specified, change to the requested working directory */
  if( zWorkDir ){
    if( !isUri ){
      file_canonical_name(zRepo, &normalizedRepoName, 0);

      zRepo = blob_str(&normalizedRepoName);

    }
    if( file_isdir(zWorkDir, ExtFILE)!=1 ){
      file_mkfolder(zWorkDir, ExtFILE, 0, 0);
      if( file_mkdir(zWorkDir, ExtFILE, 0) ){
        fossil_fatal("cannot create directory %s", zWorkDir);
      }
    }
    if( file_chdir(zWorkDir, 0) ){
      fossil_fatal("unable to make %s the working directory", zWorkDir);
    }
  }

  if( !allowNested && db_open_local(0) ){
    fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
  }

  /* If REPOSITORY looks like a URI, then try to clone it first */
  if( isUri ){
    char *zNewBase;   /* Base name of the cloned repository file */
    const char *zUri; /* URI to clone */
    int i;            /* Loop counter */







<











|
>
|
>












|
|







3148
3149
3150
3151
3152
3153
3154

3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  zRepo = g.argv[2];

  if( sqlite3_strglob("http://*", zRepo)==0
   || sqlite3_strglob("https://*", zRepo)==0
   || sqlite3_strglob("ssh:*", zRepo)==0
   || sqlite3_strglob("file:*", zRepo)==0
  ){
    isUri = 1;
  }

  /* If --workdir is specified, change to the requested working directory */
  if( zWorkDir ){
    if( !isUri ){
      zRepo = file_canonical_name_dup(zRepo);
    }
    if( zRepoDir ){
      zRepoDir = file_canonical_name_dup(zRepoDir);
    }
    if( file_isdir(zWorkDir, ExtFILE)!=1 ){
      file_mkfolder(zWorkDir, ExtFILE, 0, 0);
      if( file_mkdir(zWorkDir, ExtFILE, 0) ){
        fossil_fatal("cannot create directory %s", zWorkDir);
      }
    }
    if( file_chdir(zWorkDir, 0) ){
      fossil_fatal("unable to make %s the working directory", zWorkDir);
    }
  }

  if( db_open_local_v2(0, allowNested) ){
    fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
  }

  /* If REPOSITORY looks like a URI, then try to clone it first */
  if( isUri ){
    char *zNewBase;   /* Base name of the cloned repository file */
    const char *zUri; /* URI to clone */
    int i;            /* Loop counter */
Changes to src/file.c.
1103
1104
1105
1106
1107
1108
1109


1110
1111
1112
1113
1114
1115
1116
** Compute a canonical pathname for a file or directory.
** Make the name absolute if it is relative.
** Remove redundant / characters
** Remove all /./ path elements.
** Convert /A/../ to just /
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.


*/
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
  blob_zero(pOut);
  if( file_is_absolute_path(zOrigName) ){
    blob_appendf(pOut, "%/", zOrigName);
  }else{
    char zPwd[2000];







>
>







1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
** Compute a canonical pathname for a file or directory.
** Make the name absolute if it is relative.
** Remove redundant / characters
** Remove all /./ path elements.
** Convert /A/../ to just /
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.
**
** See also: file_canonical_name_dup()
*/
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
  blob_zero(pOut);
  if( file_is_absolute_path(zOrigName) ){
    blob_appendf(pOut, "%/", zOrigName);
  }else{
    char zPwd[2000];
1138
1139
1140
1141
1142
1143
1144















1145
1146
1147
1148
1149
1150
1151
      zOut[0] = fossil_toupper(zOut[0]);
    }
  }
#endif
  blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
                                       blob_size(pOut), slash));
}
















/*
** The input is the name of an executable, such as one might
** type on a command-line.  This routine resolves that name into
** a full pathname.  The result is obtained from fossil_malloc()
** and should be freed by the caller.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
      zOut[0] = fossil_toupper(zOut[0]);
    }
  }
#endif
  blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
                                       blob_size(pOut), slash));
}

/*
** Compute the canonical name of a file.  Store that name in
** memory obtained from fossil_malloc() and return a pointer to the
** name.
**
** See also: file_canonical_name()
*/
char *file_canonical_name_dup(const char *zOrigName){
  Blob x;
  if( zOrigName==0 ) return 0;
  blob_init(&x, 0, 0);
  file_canonical_name(zOrigName, &x, 0);
  return blob_str(&x);
}

/*
** The input is the name of an executable, such as one might
** type on a command-line.  This routine resolves that name into
** a full pathname.  The result is obtained from fossil_malloc()
** and should be freed by the caller.
**