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.
Commit
19677d76295ee6c18229dc3be8136fc3932ba25505ceb68e83ed2c7b09a4cc2b
Parent
0d813dbf91826ff…
1 file changed
+45
-34
M
src/db.c
+45
-34
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -3122,19 +3122,22 @@ | ||
| 3122 | 3122 | static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 }; |
| 3123 | 3123 | const char *zWorkDir; /* --workdir value */ |
| 3124 | 3124 | const char *zRepo = 0; /* Name of the repository file */ |
| 3125 | 3125 | const char *zRepoDir = 0; /* --repodir value */ |
| 3126 | 3126 | Blob normalizedRepoName; /* Normalized repository filename */ |
| 3127 | + char *zPwd; /* Initial working directory */ | |
| 3128 | + int isUri = 0; /* True if REPOSITORY is a URI */ | |
| 3127 | 3129 | |
| 3128 | 3130 | url_proxy_options(); |
| 3129 | 3131 | emptyFlag = find_option("empty",0,0)!=0; |
| 3130 | 3132 | keepFlag = find_option("keep",0,0)!=0; |
| 3131 | 3133 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 3132 | 3134 | allowNested = find_option("nested",0,0)!=0; |
| 3133 | 3135 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 3134 | 3136 | zWorkDir = find_option("workdir",0,1); |
| 3135 | 3137 | zRepoDir = find_option("repodir",0,1); |
| 3138 | + zPwd = file_getcwd(0,0); | |
| 3136 | 3139 | |
| 3137 | 3140 | |
| 3138 | 3141 | /* We should be done with options.. */ |
| 3139 | 3142 | verify_all_options(); |
| 3140 | 3143 | |
| @@ -3141,53 +3144,24 @@ | ||
| 3141 | 3144 | if( g.argc!=3 && g.argc!=4 ){ |
| 3142 | 3145 | usage("REPOSITORY-FILENAME ?VERSION?"); |
| 3143 | 3146 | } |
| 3144 | 3147 | zRepo = g.argv[2]; |
| 3145 | 3148 | blob_init(&normalizedRepoName, 0, 0); |
| 3146 | - | |
| 3147 | - /* If REPOSITORY looks like a URI, then try to clone it first */ | |
| 3148 | 3149 | if( sqlite3_strglob("http://*", zRepo)==0 |
| 3149 | 3150 | || sqlite3_strglob("https://*", zRepo)==0 |
| 3150 | 3151 | || sqlite3_strglob("ssh:*", zRepo)==0 |
| 3151 | 3152 | || sqlite3_strglob("file:*", zRepo)==0 |
| 3152 | 3153 | ){ |
| 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; | |
| 3183 | 3155 | } |
| 3184 | 3156 | |
| 3185 | 3157 | /* If --workdir is specified, change to the requested working directory */ |
| 3186 | 3158 | 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 | + } | |
| 3189 | 3163 | if( file_isdir(zWorkDir, ExtFILE)!=1 ){ |
| 3190 | 3164 | file_mkfolder(zWorkDir, ExtFILE, 0, 0); |
| 3191 | 3165 | if( file_mkdir(zWorkDir, ExtFILE, 0) ){ |
| 3192 | 3166 | fossil_fatal("cannot create directory %s", zWorkDir); |
| 3193 | 3167 | } |
| @@ -3198,10 +3172,47 @@ | ||
| 3198 | 3172 | } |
| 3199 | 3173 | |
| 3200 | 3174 | if( !allowNested && db_open_local(0) ){ |
| 3201 | 3175 | fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot); |
| 3202 | 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 | + | |
| 3203 | 3214 | db_open_repository(zRepo); |
| 3204 | 3215 | |
| 3205 | 3216 | /* Figure out which revision to open. */ |
| 3206 | 3217 | if( !emptyFlag ){ |
| 3207 | 3218 | if( g.argc==4 ){ |
| 3208 | 3219 |
| --- 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 |