Fossil SCM

When doing an open on a URI, verify that the working directory is not within an existing checkout prior to performing the clone.

drh 2020-08-08 01:55 trunk
Commit 19677d76295ee6c18229dc3be8136fc3932ba25505ceb68e83ed2c7b09a4cc2b
1 file changed +45 -34
+45 -34
--- src/db.c
+++ src/db.c
@@ -3122,19 +3122,22 @@
31223122
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
31233123
const char *zWorkDir; /* --workdir value */
31243124
const char *zRepo = 0; /* Name of the repository file */
31253125
const char *zRepoDir = 0; /* --repodir value */
31263126
Blob normalizedRepoName; /* Normalized repository filename */
3127
+ char *zPwd; /* Initial working directory */
3128
+ int isUri = 0; /* True if REPOSITORY is a URI */
31273129
31283130
url_proxy_options();
31293131
emptyFlag = find_option("empty",0,0)!=0;
31303132
keepFlag = find_option("keep",0,0)!=0;
31313133
forceMissingFlag = find_option("force-missing",0,0)!=0;
31323134
allowNested = find_option("nested",0,0)!=0;
31333135
setmtimeFlag = find_option("setmtime",0,0)!=0;
31343136
zWorkDir = find_option("workdir",0,1);
31353137
zRepoDir = find_option("repodir",0,1);
3138
+ zPwd = file_getcwd(0,0);
31363139
31373140
31383141
/* We should be done with options.. */
31393142
verify_all_options();
31403143
@@ -3141,53 +3144,24 @@
31413144
if( g.argc!=3 && g.argc!=4 ){
31423145
usage("REPOSITORY-FILENAME ?VERSION?");
31433146
}
31443147
zRepo = g.argv[2];
31453148
blob_init(&normalizedRepoName, 0, 0);
3146
-
3147
- /* If REPOSITORY looks like a URI, then try to clone it first */
31483149
if( sqlite3_strglob("http://*", zRepo)==0
31493150
|| sqlite3_strglob("https://*", zRepo)==0
31503151
|| sqlite3_strglob("ssh:*", zRepo)==0
31513152
|| sqlite3_strglob("file:*", zRepo)==0
31523153
){
3153
- char *zNewBase; /* Base name of the cloned repository file */
3154
- const char *zUri; /* URI to clone */
3155
- int i; /* Loop counter */
3156
- int rc; /* Result code from fossil_system() */
3157
- Blob cmd; /* Clone command to be run */
3158
- char *zCmd; /* String version of the clone command */
3159
-
3160
- zUri = zRepo;
3161
- zNewBase = fossil_strdup(file_tail(zUri));
3162
- for(i=(int)strlen(zNewBase)-1; i>1 && zNewBase[i]!='.'; i--){}
3163
- if( zNewBase[i]=='.' ) zNewBase[i] = 0;
3164
- if( zRepoDir==0 ) zRepoDir = ".";
3165
- zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3166
- fossil_free(zNewBase);
3167
- blob_init(&cmd, 0, 0);
3168
- blob_append_escaped_arg(&cmd, g.nameOfExe);
3169
- blob_append(&cmd, " clone", -1);
3170
- blob_append_escaped_arg(&cmd, zUri);
3171
- blob_append_escaped_arg(&cmd, zRepo);
3172
- zCmd = blob_str(&cmd);
3173
- fossil_print("%s\n", zCmd);
3174
- rc = fossil_system(zCmd);
3175
- if( rc ){
3176
- fossil_fatal("clone of %s failed", zUri);
3177
- }
3178
- blob_reset(&cmd);
3179
- }else if( zRepoDir ){
3180
- fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3181
- "argument is a URI that begins with http:, https:, ssh:, "
3182
- "or file:");
3154
+ isUri = 1;
31833155
}
31843156
31853157
/* If --workdir is specified, change to the requested working directory */
31863158
if( zWorkDir ){
3187
- file_canonical_name(zRepo, &normalizedRepoName, 0);
3188
- zRepo = blob_str(&normalizedRepoName);
3159
+ if( !isUri ){
3160
+ file_canonical_name(zRepo, &normalizedRepoName, 0);
3161
+ zRepo = blob_str(&normalizedRepoName);
3162
+ }
31893163
if( file_isdir(zWorkDir, ExtFILE)!=1 ){
31903164
file_mkfolder(zWorkDir, ExtFILE, 0, 0);
31913165
if( file_mkdir(zWorkDir, ExtFILE, 0) ){
31923166
fossil_fatal("cannot create directory %s", zWorkDir);
31933167
}
@@ -3198,10 +3172,47 @@
31983172
}
31993173
32003174
if( !allowNested && db_open_local(0) ){
32013175
fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
32023176
}
3177
+
3178
+ /* If REPOSITORY looks like a URI, then try to clone it first */
3179
+ if( isUri ){
3180
+ char *zNewBase; /* Base name of the cloned repository file */
3181
+ const char *zUri; /* URI to clone */
3182
+ int i; /* Loop counter */
3183
+ int rc; /* Result code from fossil_system() */
3184
+ Blob cmd; /* Clone command to be run */
3185
+ char *zCmd; /* String version of the clone command */
3186
+
3187
+ zUri = zRepo;
3188
+ zNewBase = fossil_strdup(file_tail(zUri));
3189
+ for(i=(int)strlen(zNewBase)-1; i>1 && zNewBase[i]!='.'; i--){}
3190
+ if( zNewBase[i]=='.' ) zNewBase[i] = 0;
3191
+ if( zRepoDir==0 ) zRepoDir = zPwd;
3192
+ zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3193
+ fossil_free(zNewBase);
3194
+ blob_init(&cmd, 0, 0);
3195
+ blob_append_escaped_arg(&cmd, g.nameOfExe);
3196
+ blob_append(&cmd, " clone", -1);
3197
+ blob_append_escaped_arg(&cmd, zUri);
3198
+ blob_append_escaped_arg(&cmd, zRepo);
3199
+ zCmd = blob_str(&cmd);
3200
+ fossil_print("%s\n", zCmd);
3201
+ if( zWorkDir ) file_chdir(zPwd, 0);
3202
+ rc = fossil_system(zCmd);
3203
+ if( rc ){
3204
+ fossil_fatal("clone of %s failed", zUri);
3205
+ }
3206
+ blob_reset(&cmd);
3207
+ if( zWorkDir ) file_chdir(zWorkDir, 0);
3208
+ }else if( zRepoDir ){
3209
+ fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3210
+ "argument is a URI that begins with http:, https:, ssh:, "
3211
+ "or file:");
3212
+ }
3213
+
32033214
db_open_repository(zRepo);
32043215
32053216
/* Figure out which revision to open. */
32063217
if( !emptyFlag ){
32073218
if( g.argc==4 ){
32083219
--- src/db.c
+++ src/db.c
@@ -3122,19 +3122,22 @@
3122 static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
3123 const char *zWorkDir; /* --workdir value */
3124 const char *zRepo = 0; /* Name of the repository file */
3125 const char *zRepoDir = 0; /* --repodir value */
3126 Blob normalizedRepoName; /* Normalized repository filename */
 
 
3127
3128 url_proxy_options();
3129 emptyFlag = find_option("empty",0,0)!=0;
3130 keepFlag = find_option("keep",0,0)!=0;
3131 forceMissingFlag = find_option("force-missing",0,0)!=0;
3132 allowNested = find_option("nested",0,0)!=0;
3133 setmtimeFlag = find_option("setmtime",0,0)!=0;
3134 zWorkDir = find_option("workdir",0,1);
3135 zRepoDir = find_option("repodir",0,1);
 
3136
3137
3138 /* We should be done with options.. */
3139 verify_all_options();
3140
@@ -3141,53 +3144,24 @@
3141 if( g.argc!=3 && g.argc!=4 ){
3142 usage("REPOSITORY-FILENAME ?VERSION?");
3143 }
3144 zRepo = g.argv[2];
3145 blob_init(&normalizedRepoName, 0, 0);
3146
3147 /* If REPOSITORY looks like a URI, then try to clone it first */
3148 if( sqlite3_strglob("http://*", zRepo)==0
3149 || sqlite3_strglob("https://*", zRepo)==0
3150 || sqlite3_strglob("ssh:*", zRepo)==0
3151 || sqlite3_strglob("file:*", zRepo)==0
3152 ){
3153 char *zNewBase; /* Base name of the cloned repository file */
3154 const char *zUri; /* URI to clone */
3155 int i; /* Loop counter */
3156 int rc; /* Result code from fossil_system() */
3157 Blob cmd; /* Clone command to be run */
3158 char *zCmd; /* String version of the clone command */
3159
3160 zUri = zRepo;
3161 zNewBase = fossil_strdup(file_tail(zUri));
3162 for(i=(int)strlen(zNewBase)-1; i>1 && zNewBase[i]!='.'; i--){}
3163 if( zNewBase[i]=='.' ) zNewBase[i] = 0;
3164 if( zRepoDir==0 ) zRepoDir = ".";
3165 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3166 fossil_free(zNewBase);
3167 blob_init(&cmd, 0, 0);
3168 blob_append_escaped_arg(&cmd, g.nameOfExe);
3169 blob_append(&cmd, " clone", -1);
3170 blob_append_escaped_arg(&cmd, zUri);
3171 blob_append_escaped_arg(&cmd, zRepo);
3172 zCmd = blob_str(&cmd);
3173 fossil_print("%s\n", zCmd);
3174 rc = fossil_system(zCmd);
3175 if( rc ){
3176 fossil_fatal("clone of %s failed", zUri);
3177 }
3178 blob_reset(&cmd);
3179 }else if( zRepoDir ){
3180 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3181 "argument is a URI that begins with http:, https:, ssh:, "
3182 "or file:");
3183 }
3184
3185 /* If --workdir is specified, change to the requested working directory */
3186 if( zWorkDir ){
3187 file_canonical_name(zRepo, &normalizedRepoName, 0);
3188 zRepo = blob_str(&normalizedRepoName);
 
 
3189 if( file_isdir(zWorkDir, ExtFILE)!=1 ){
3190 file_mkfolder(zWorkDir, ExtFILE, 0, 0);
3191 if( file_mkdir(zWorkDir, ExtFILE, 0) ){
3192 fossil_fatal("cannot create directory %s", zWorkDir);
3193 }
@@ -3198,10 +3172,47 @@
3198 }
3199
3200 if( !allowNested && db_open_local(0) ){
3201 fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
3202 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3203 db_open_repository(zRepo);
3204
3205 /* Figure out which revision to open. */
3206 if( !emptyFlag ){
3207 if( g.argc==4 ){
3208
--- src/db.c
+++ src/db.c
@@ -3122,19 +3122,22 @@
3122 static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
3123 const char *zWorkDir; /* --workdir value */
3124 const char *zRepo = 0; /* Name of the repository file */
3125 const char *zRepoDir = 0; /* --repodir value */
3126 Blob normalizedRepoName; /* Normalized repository filename */
3127 char *zPwd; /* Initial working directory */
3128 int isUri = 0; /* True if REPOSITORY is a URI */
3129
3130 url_proxy_options();
3131 emptyFlag = find_option("empty",0,0)!=0;
3132 keepFlag = find_option("keep",0,0)!=0;
3133 forceMissingFlag = find_option("force-missing",0,0)!=0;
3134 allowNested = find_option("nested",0,0)!=0;
3135 setmtimeFlag = find_option("setmtime",0,0)!=0;
3136 zWorkDir = find_option("workdir",0,1);
3137 zRepoDir = find_option("repodir",0,1);
3138 zPwd = file_getcwd(0,0);
3139
3140
3141 /* We should be done with options.. */
3142 verify_all_options();
3143
@@ -3141,53 +3144,24 @@
3144 if( g.argc!=3 && g.argc!=4 ){
3145 usage("REPOSITORY-FILENAME ?VERSION?");
3146 }
3147 zRepo = g.argv[2];
3148 blob_init(&normalizedRepoName, 0, 0);
 
 
3149 if( sqlite3_strglob("http://*", zRepo)==0
3150 || sqlite3_strglob("https://*", zRepo)==0
3151 || sqlite3_strglob("ssh:*", zRepo)==0
3152 || sqlite3_strglob("file:*", zRepo)==0
3153 ){
3154 isUri = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3155 }
3156
3157 /* If --workdir is specified, change to the requested working directory */
3158 if( zWorkDir ){
3159 if( !isUri ){
3160 file_canonical_name(zRepo, &normalizedRepoName, 0);
3161 zRepo = blob_str(&normalizedRepoName);
3162 }
3163 if( file_isdir(zWorkDir, ExtFILE)!=1 ){
3164 file_mkfolder(zWorkDir, ExtFILE, 0, 0);
3165 if( file_mkdir(zWorkDir, ExtFILE, 0) ){
3166 fossil_fatal("cannot create directory %s", zWorkDir);
3167 }
@@ -3198,10 +3172,47 @@
3172 }
3173
3174 if( !allowNested && db_open_local(0) ){
3175 fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
3176 }
3177
3178 /* If REPOSITORY looks like a URI, then try to clone it first */
3179 if( isUri ){
3180 char *zNewBase; /* Base name of the cloned repository file */
3181 const char *zUri; /* URI to clone */
3182 int i; /* Loop counter */
3183 int rc; /* Result code from fossil_system() */
3184 Blob cmd; /* Clone command to be run */
3185 char *zCmd; /* String version of the clone command */
3186
3187 zUri = zRepo;
3188 zNewBase = fossil_strdup(file_tail(zUri));
3189 for(i=(int)strlen(zNewBase)-1; i>1 && zNewBase[i]!='.'; i--){}
3190 if( zNewBase[i]=='.' ) zNewBase[i] = 0;
3191 if( zRepoDir==0 ) zRepoDir = zPwd;
3192 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3193 fossil_free(zNewBase);
3194 blob_init(&cmd, 0, 0);
3195 blob_append_escaped_arg(&cmd, g.nameOfExe);
3196 blob_append(&cmd, " clone", -1);
3197 blob_append_escaped_arg(&cmd, zUri);
3198 blob_append_escaped_arg(&cmd, zRepo);
3199 zCmd = blob_str(&cmd);
3200 fossil_print("%s\n", zCmd);
3201 if( zWorkDir ) file_chdir(zPwd, 0);
3202 rc = fossil_system(zCmd);
3203 if( rc ){
3204 fossil_fatal("clone of %s failed", zUri);
3205 }
3206 blob_reset(&cmd);
3207 if( zWorkDir ) file_chdir(zWorkDir, 0);
3208 }else if( zRepoDir ){
3209 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3210 "argument is a URI that begins with http:, https:, ssh:, "
3211 "or file:");
3212 }
3213
3214 db_open_repository(zRepo);
3215
3216 /* Figure out which revision to open. */
3217 if( !emptyFlag ){
3218 if( g.argc==4 ){
3219

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button