Fossil SCM

Add the --keep option to the "open" and "checkout" commands. Added the --latest option to "checkout". These changes allow one to shift the baseline version and repository of a checkout without changing any files in the checkout.

drh 2009-05-28 02:44 trunk
Commit 915bfd99fec69f978f199412bdb2c3da54a24156
2 files changed +62 -22 +20 -5
+62 -22
--- src/checkout.c
+++ src/checkout.c
@@ -135,63 +135,104 @@
135135
136136
/*
137137
** COMMAND: checkout
138138
** COMMAND: co
139139
**
140
-** Usage: %fossil checkout VERSION ?-f|--force?
140
+** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
141141
**
142142
** Check out a version specified on the command-line. This command
143
-** will not overwrite edited files in the current checkout unless
144
-** the --force option appears on the command-line.
143
+** will abort if there are edited files in the current checkout unless
144
+** the --force option appears on the command-line. The --keep option
145
+** leaves files on disk unchanged, except the manifest and manifest.uuid
146
+** files.
147
+**
148
+** The --latest flag can be used in place of VERSION to checkout the
149
+** latest version in the repository.
145150
**
146151
** See also the "update" command.
147152
*/
148153
void checkout_cmd(void){
149
- int forceFlag;
150
- int noWrite;
154
+ int forceFlag; /* Force checkout even if edits exist */
155
+ int keepFlag; /* Do not change any files on disk */
156
+ int latestFlag; /* Checkout the latest version */
157
+ char *zVers; /* Version to checkout */
151158
int vid, prior;
152159
Blob cksum1, cksum1b, cksum2;
153160
154161
db_must_be_within_tree();
155162
db_begin_transaction();
156163
forceFlag = find_option("force","f",0)!=0;
157
- noWrite = find_option("dontwrite",0,0)!=0;
158
- if( g.argc!=3 ) usage("?--force? VERSION");
164
+ keepFlag = find_option("keep",0,0)!=0;
165
+ latestFlag = find_option("latest",0,0)!=0;
166
+ if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){
167
+ usage("VERSION|--latest ?--force? ?--keep?");
168
+ }
159169
if( !forceFlag && unsaved_changes()==1 ){
160170
fossil_fatal("there are unsaved changes in the current checkout");
161171
}
162172
if( forceFlag ){
163173
db_multi_exec("DELETE FROM vfile");
164174
prior = 0;
165175
}else{
166176
prior = db_lget_int("checkout",0);
167177
}
168
- vid = load_vfile(g.argv[2]);
178
+ if( latestFlag ){
179
+ compute_leaves(db_lget_int("checkout",0), 1);
180
+ zVers = db_text(0, "SELECT uuid FROM leaves, event, blob"
181
+ " WHERE event.objid=leaves.rid AND blob.rid=leaves.rid"
182
+ " ORDER BY event.mtime DESC");
183
+ if( zVers==0 ){
184
+ fossil_fatal("cannot local \"latest\" checkout");
185
+ }
186
+ }else{
187
+ zVers = g.argv[2];
188
+ }
189
+ vid = load_vfile(zVers);
169190
if( prior==vid ){
170191
return;
171192
}
172
- if( !noWrite ){
193
+ if( !keepFlag ){
173194
uncheckout(prior);
174195
}
175196
db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
176
- if( !noWrite ){
197
+ if( !keepFlag ){
177198
vfile_to_disk(vid, 0, 1);
178
- manifest_to_disk(vid);
179
- db_lset_int("checkout", vid);
180
- undo_reset();
181199
}
200
+ manifest_to_disk(vid);
201
+ db_lset_int("checkout", vid);
202
+ undo_reset();
182203
db_multi_exec("DELETE FROM vmerge");
183
- vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
184
- vfile_aggregate_checksum_disk(vid, &cksum2);
185
- if( blob_compare(&cksum1, &cksum2) ){
186
- printf("WARNING: manifest checksum does not agree with disk\n");
187
- }
188
- if( blob_compare(&cksum1, &cksum1b) ){
189
- printf("WARNING: manifest checksum does not agree with manifest\n");
204
+ if( !keepFlag ){
205
+ vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
206
+ vfile_aggregate_checksum_disk(vid, &cksum2);
207
+ if( blob_compare(&cksum1, &cksum2) ){
208
+ printf("WARNING: manifest checksum does not agree with disk\n");
209
+ }
210
+ if( blob_compare(&cksum1, &cksum1b) ){
211
+ printf("WARNING: manifest checksum does not agree with manifest\n");
212
+ }
190213
}
191214
db_end_transaction(0);
192215
}
216
+
217
+/*
218
+** Unlink the local database file
219
+*/
220
+void unlink_local_database(void){
221
+ static const char *azFile[] = {
222
+ "%s_FOSSIL_",
223
+ "%s_FOSSIL_-journal",
224
+ "%s.fos",
225
+ "%s.fos-journal",
226
+ };
227
+ int i;
228
+ for(i=0; i<sizeof(azFile)/sizeof(azFile[0]); i++){
229
+ char *z = mprintf(azFile[i], g.zLocalRoot);
230
+ unlink(z);
231
+ free(z);
232
+ }
233
+}
193234
194235
/*
195236
** COMMAND: close
196237
**
197238
** Usage: %fossil close ?-f|--force?
@@ -205,8 +246,7 @@
205246
db_must_be_within_tree();
206247
if( !forceFlag && unsaved_changes()==1 ){
207248
fossil_fatal("there are unsaved changes in the current checkout");
208249
}
209250
db_close();
210
- unlink(mprintf("%s_FOSSIL_", g.zLocalRoot));
211
- unlink(mprintf("%s_FOSSIL_-journal", g.zLocalRoot));
251
+ unlink_local_database();
212252
}
213253
--- src/checkout.c
+++ src/checkout.c
@@ -135,63 +135,104 @@
135
136 /*
137 ** COMMAND: checkout
138 ** COMMAND: co
139 **
140 ** Usage: %fossil checkout VERSION ?-f|--force?
141 **
142 ** Check out a version specified on the command-line. This command
143 ** will not overwrite edited files in the current checkout unless
144 ** the --force option appears on the command-line.
 
 
 
 
 
145 **
146 ** See also the "update" command.
147 */
148 void checkout_cmd(void){
149 int forceFlag;
150 int noWrite;
 
 
151 int vid, prior;
152 Blob cksum1, cksum1b, cksum2;
153
154 db_must_be_within_tree();
155 db_begin_transaction();
156 forceFlag = find_option("force","f",0)!=0;
157 noWrite = find_option("dontwrite",0,0)!=0;
158 if( g.argc!=3 ) usage("?--force? VERSION");
 
 
 
159 if( !forceFlag && unsaved_changes()==1 ){
160 fossil_fatal("there are unsaved changes in the current checkout");
161 }
162 if( forceFlag ){
163 db_multi_exec("DELETE FROM vfile");
164 prior = 0;
165 }else{
166 prior = db_lget_int("checkout",0);
167 }
168 vid = load_vfile(g.argv[2]);
 
 
 
 
 
 
 
 
 
 
 
169 if( prior==vid ){
170 return;
171 }
172 if( !noWrite ){
173 uncheckout(prior);
174 }
175 db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
176 if( !noWrite ){
177 vfile_to_disk(vid, 0, 1);
178 manifest_to_disk(vid);
179 db_lset_int("checkout", vid);
180 undo_reset();
181 }
 
 
 
182 db_multi_exec("DELETE FROM vmerge");
183 vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
184 vfile_aggregate_checksum_disk(vid, &cksum2);
185 if( blob_compare(&cksum1, &cksum2) ){
186 printf("WARNING: manifest checksum does not agree with disk\n");
187 }
188 if( blob_compare(&cksum1, &cksum1b) ){
189 printf("WARNING: manifest checksum does not agree with manifest\n");
 
 
190 }
191 db_end_transaction(0);
192 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
194 /*
195 ** COMMAND: close
196 **
197 ** Usage: %fossil close ?-f|--force?
@@ -205,8 +246,7 @@
205 db_must_be_within_tree();
206 if( !forceFlag && unsaved_changes()==1 ){
207 fossil_fatal("there are unsaved changes in the current checkout");
208 }
209 db_close();
210 unlink(mprintf("%s_FOSSIL_", g.zLocalRoot));
211 unlink(mprintf("%s_FOSSIL_-journal", g.zLocalRoot));
212 }
213
--- src/checkout.c
+++ src/checkout.c
@@ -135,63 +135,104 @@
135
136 /*
137 ** COMMAND: checkout
138 ** COMMAND: co
139 **
140 ** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
141 **
142 ** Check out a version specified on the command-line. This command
143 ** will abort if there are edited files in the current checkout unless
144 ** the --force option appears on the command-line. The --keep option
145 ** leaves files on disk unchanged, except the manifest and manifest.uuid
146 ** files.
147 **
148 ** The --latest flag can be used in place of VERSION to checkout the
149 ** latest version in the repository.
150 **
151 ** See also the "update" command.
152 */
153 void checkout_cmd(void){
154 int forceFlag; /* Force checkout even if edits exist */
155 int keepFlag; /* Do not change any files on disk */
156 int latestFlag; /* Checkout the latest version */
157 char *zVers; /* Version to checkout */
158 int vid, prior;
159 Blob cksum1, cksum1b, cksum2;
160
161 db_must_be_within_tree();
162 db_begin_transaction();
163 forceFlag = find_option("force","f",0)!=0;
164 keepFlag = find_option("keep",0,0)!=0;
165 latestFlag = find_option("latest",0,0)!=0;
166 if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){
167 usage("VERSION|--latest ?--force? ?--keep?");
168 }
169 if( !forceFlag && unsaved_changes()==1 ){
170 fossil_fatal("there are unsaved changes in the current checkout");
171 }
172 if( forceFlag ){
173 db_multi_exec("DELETE FROM vfile");
174 prior = 0;
175 }else{
176 prior = db_lget_int("checkout",0);
177 }
178 if( latestFlag ){
179 compute_leaves(db_lget_int("checkout",0), 1);
180 zVers = db_text(0, "SELECT uuid FROM leaves, event, blob"
181 " WHERE event.objid=leaves.rid AND blob.rid=leaves.rid"
182 " ORDER BY event.mtime DESC");
183 if( zVers==0 ){
184 fossil_fatal("cannot local \"latest\" checkout");
185 }
186 }else{
187 zVers = g.argv[2];
188 }
189 vid = load_vfile(zVers);
190 if( prior==vid ){
191 return;
192 }
193 if( !keepFlag ){
194 uncheckout(prior);
195 }
196 db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
197 if( !keepFlag ){
198 vfile_to_disk(vid, 0, 1);
 
 
 
199 }
200 manifest_to_disk(vid);
201 db_lset_int("checkout", vid);
202 undo_reset();
203 db_multi_exec("DELETE FROM vmerge");
204 if( !keepFlag ){
205 vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
206 vfile_aggregate_checksum_disk(vid, &cksum2);
207 if( blob_compare(&cksum1, &cksum2) ){
208 printf("WARNING: manifest checksum does not agree with disk\n");
209 }
210 if( blob_compare(&cksum1, &cksum1b) ){
211 printf("WARNING: manifest checksum does not agree with manifest\n");
212 }
213 }
214 db_end_transaction(0);
215 }
216
217 /*
218 ** Unlink the local database file
219 */
220 void unlink_local_database(void){
221 static const char *azFile[] = {
222 "%s_FOSSIL_",
223 "%s_FOSSIL_-journal",
224 "%s.fos",
225 "%s.fos-journal",
226 };
227 int i;
228 for(i=0; i<sizeof(azFile)/sizeof(azFile[0]); i++){
229 char *z = mprintf(azFile[i], g.zLocalRoot);
230 unlink(z);
231 free(z);
232 }
233 }
234
235 /*
236 ** COMMAND: close
237 **
238 ** Usage: %fossil close ?-f|--force?
@@ -205,8 +246,7 @@
246 db_must_be_within_tree();
247 if( !forceFlag && unsaved_changes()==1 ){
248 fossil_fatal("there are unsaved changes in the current checkout");
249 }
250 db_close();
251 unlink_local_database();
 
252 }
253
+20 -5
--- src/db.c
+++ src/db.c
@@ -1243,23 +1243,29 @@
12431243
}
12441244
12451245
/*
12461246
** COMMAND: open
12471247
**
1248
-** Usage: %fossil open FILENAME
1248
+** Usage: %fossil open FILENAME ?VERSION? ?--keep?
12491249
**
12501250
** Open a connection to the local repository in FILENAME. A checkout
12511251
** for the repository is created with its root at the working directory.
1252
+** If VERSION is specified then that version is checked out. Otherwise
1253
+** the latest version is checked out. No files other than "manifest"
1254
+** and "manifest.uuid" are modified if the --keep option is present.
1255
+**
12521256
** See also the "close" command.
12531257
*/
12541258
void cmd_open(void){
12551259
Blob path;
12561260
int vid;
1257
- static char *azNewArgv[] = { 0, "update", "--latest", 0 };
1261
+ int keepFlag;
1262
+ static char *azNewArgv[] = { 0, "checkout", "--latest", 0, 0, 0 };
12581263
url_proxy_options();
1259
- if( g.argc!=3 ){
1260
- usage("REPOSITORY-FILENAME");
1264
+ keepFlag = find_option("keep",0,0)!=0;
1265
+ if( g.argc!=3 && g.argc!=4 ){
1266
+ usage("REPOSITORY-FILENAME ?VERSION?");
12611267
}
12621268
if( db_open_local() ){
12631269
fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
12641270
}
12651271
file_canonical_name(g.argv[2], &path);
@@ -1271,14 +1277,23 @@
12711277
vid = db_int(0, "SELECT pid FROM plink y"
12721278
" WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)");
12731279
if( vid==0 ){
12741280
db_lset_int("checkout", 1);
12751281
}else{
1282
+ char **oldArgv = g.argv;
1283
+ int oldArgc = g.argc;
12761284
db_lset_int("checkout", vid);
1285
+ azNewArgv[0] = g.argv[0];
12771286
g.argv = azNewArgv;
12781287
g.argc = 3;
1279
- update_cmd();
1288
+ if( oldArgc==4 ){
1289
+ azNewArgv[g.argc-1] = oldArgv[3];
1290
+ }
1291
+ if( keepFlag ){
1292
+ azNewArgv[g.argc++] = "--keep";
1293
+ }
1294
+ checkout_cmd();
12801295
g.argc = 2;
12811296
info_cmd();
12821297
}
12831298
}
12841299
12851300
--- src/db.c
+++ src/db.c
@@ -1243,23 +1243,29 @@
1243 }
1244
1245 /*
1246 ** COMMAND: open
1247 **
1248 ** Usage: %fossil open FILENAME
1249 **
1250 ** Open a connection to the local repository in FILENAME. A checkout
1251 ** for the repository is created with its root at the working directory.
 
 
 
 
1252 ** See also the "close" command.
1253 */
1254 void cmd_open(void){
1255 Blob path;
1256 int vid;
1257 static char *azNewArgv[] = { 0, "update", "--latest", 0 };
 
1258 url_proxy_options();
1259 if( g.argc!=3 ){
1260 usage("REPOSITORY-FILENAME");
 
1261 }
1262 if( db_open_local() ){
1263 fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
1264 }
1265 file_canonical_name(g.argv[2], &path);
@@ -1271,14 +1277,23 @@
1271 vid = db_int(0, "SELECT pid FROM plink y"
1272 " WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)");
1273 if( vid==0 ){
1274 db_lset_int("checkout", 1);
1275 }else{
 
 
1276 db_lset_int("checkout", vid);
 
1277 g.argv = azNewArgv;
1278 g.argc = 3;
1279 update_cmd();
 
 
 
 
 
 
1280 g.argc = 2;
1281 info_cmd();
1282 }
1283 }
1284
1285
--- src/db.c
+++ src/db.c
@@ -1243,23 +1243,29 @@
1243 }
1244
1245 /*
1246 ** COMMAND: open
1247 **
1248 ** Usage: %fossil open FILENAME ?VERSION? ?--keep?
1249 **
1250 ** Open a connection to the local repository in FILENAME. A checkout
1251 ** for the repository is created with its root at the working directory.
1252 ** If VERSION is specified then that version is checked out. Otherwise
1253 ** the latest version is checked out. No files other than "manifest"
1254 ** and "manifest.uuid" are modified if the --keep option is present.
1255 **
1256 ** See also the "close" command.
1257 */
1258 void cmd_open(void){
1259 Blob path;
1260 int vid;
1261 int keepFlag;
1262 static char *azNewArgv[] = { 0, "checkout", "--latest", 0, 0, 0 };
1263 url_proxy_options();
1264 keepFlag = find_option("keep",0,0)!=0;
1265 if( g.argc!=3 && g.argc!=4 ){
1266 usage("REPOSITORY-FILENAME ?VERSION?");
1267 }
1268 if( db_open_local() ){
1269 fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
1270 }
1271 file_canonical_name(g.argv[2], &path);
@@ -1271,14 +1277,23 @@
1277 vid = db_int(0, "SELECT pid FROM plink y"
1278 " WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)");
1279 if( vid==0 ){
1280 db_lset_int("checkout", 1);
1281 }else{
1282 char **oldArgv = g.argv;
1283 int oldArgc = g.argc;
1284 db_lset_int("checkout", vid);
1285 azNewArgv[0] = g.argv[0];
1286 g.argv = azNewArgv;
1287 g.argc = 3;
1288 if( oldArgc==4 ){
1289 azNewArgv[g.argc-1] = oldArgv[3];
1290 }
1291 if( keepFlag ){
1292 azNewArgv[g.argc++] = "--keep";
1293 }
1294 checkout_cmd();
1295 g.argc = 2;
1296 info_cmd();
1297 }
1298 }
1299
1300

Keyboard Shortcuts

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