Fossil SCM
Extend fossil ls with -r
Commit
87f51a3ded8a69279a54845a882107129b014c8c
Parent
8fa54638c2eea27…
1 file changed
+97
-4
+97
-4
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -265,44 +265,137 @@ | ||
| 265 | 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | 266 | } |
| 267 | 267 | db_record_repository_filename(0); |
| 268 | 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | 269 | } |
| 270 | + | |
| 271 | +/* | |
| 272 | +** Take care of -r version of ls command | |
| 273 | +*/ | |
| 274 | +static void ls_cmd_rev( | |
| 275 | + const char *zRev, /* Revision string given */ | |
| 276 | + int verboseFlag, /* Verbose flag given */ | |
| 277 | + int showAge, /* Age flag given */ | |
| 278 | + int timeOrder /* Order by time flag given */ | |
| 279 | +){ | |
| 280 | + Stmt q; | |
| 281 | + char *zOrderBy = "pathname COLLATE nocase"; | |
| 282 | + char *zName; | |
| 283 | + Blob where; | |
| 284 | + int rid; | |
| 285 | + int i; | |
| 286 | + | |
| 287 | + /* Handle given file names */ | |
| 288 | + blob_zero(&where); | |
| 289 | + for(i=2; i<g.argc; i++){ | |
| 290 | + Blob fname; | |
| 291 | + file_tree_name(g.argv[i], &fname, 1); | |
| 292 | + zName = blob_str(&fname); | |
| 293 | + if( fossil_strcmp(zName, ".")==0 ) { | |
| 294 | + blob_reset(&where); | |
| 295 | + break; | |
| 296 | + } | |
| 297 | + blob_append_sql(&where, | |
| 298 | + " %s (pathname=%Q %s) " | |
| 299 | + "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", | |
| 300 | + (blob_size(&where)>0) ? "OR" : "AND (", zName, | |
| 301 | + filename_collation(), zName, filename_collation(), | |
| 302 | + zName, filename_collation() | |
| 303 | + ); | |
| 304 | + } | |
| 305 | + if( blob_size(&where)>0 ){ | |
| 306 | + blob_append_sql(&where, ")"); | |
| 307 | + } | |
| 308 | + | |
| 309 | + rid = symbolic_name_to_rid(zRev, "ci"); | |
| 310 | + if( rid==0 ){ | |
| 311 | + fossil_fatal("not a valid check-in: %s", zRev); | |
| 312 | + } | |
| 313 | + | |
| 314 | + if( timeOrder ){ | |
| 315 | + zOrderBy = "mtime DESC"; | |
| 316 | + } | |
| 317 | + | |
| 318 | + compute_fileage(rid,0); | |
| 319 | + db_prepare(&q, | |
| 320 | + "SELECT datetime(fileage.mtime, 'localtime'), fileage.pathname,\n" | |
| 321 | + " blob.size, blob.uuid, blob2.uuid\n" | |
| 322 | + " FROM fileage, blob, blob as blob2\n" | |
| 323 | + " WHERE blob.rid=fileage.fid AND blob2.rid=fileage.mid %s\n" | |
| 324 | + " ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/ | |
| 325 | + ); | |
| 326 | + blob_reset(&where); | |
| 327 | + | |
| 328 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 329 | + const char *zTime = db_column_text(&q,0); | |
| 330 | + const char *zFile = db_column_text(&q,1); | |
| 331 | + int size = db_column_int(&q,2); | |
| 332 | + const char *zFUuid = db_column_text(&q,3); | |
| 333 | + const char *zCUuid = db_column_text(&q,4); | |
| 334 | + if( verboseFlag ){ | |
| 335 | + /* TBD: What to include in verbose. UUID? */ | |
| 336 | + fossil_print("%s %7d %S %S %s\n", zTime, size, zFUuid, zCUuid, zFile); | |
| 337 | + }else if( showAge ){ | |
| 338 | + fossil_print("%s %s\n", zTime, zFile); | |
| 339 | + }else{ | |
| 340 | + fossil_print("%s\n", zFile); | |
| 341 | + } | |
| 342 | + } | |
| 343 | + db_finalize(&q); | |
| 344 | +} | |
| 270 | 345 | |
| 271 | 346 | /* |
| 272 | 347 | ** COMMAND: ls |
| 273 | 348 | ** |
| 274 | -** Usage: %fossil ls ?OPTIONS? ?VERSION? ?FILENAMES? | |
| 349 | +** Usage: %fossil ls ?OPTIONS? ?FILENAMES? | |
| 275 | 350 | ** |
| 276 | 351 | ** Show the names of all files in the current checkout. The -v provides |
| 277 | 352 | ** extra information about each file. If FILENAMES are included, only |
| 278 | 353 | ** the files listed (or their children if they are directories) are shown. |
| 279 | 354 | ** |
| 355 | +** If -r is given a specific check-in is listed. In this case -R can be | |
| 356 | +** given to query another repository. | |
| 357 | +** | |
| 280 | 358 | ** Options: |
| 281 | -** --age Show when each file was committed | |
| 282 | -** -v|--verbose Provide extra information about each file. | |
| 359 | +** --age Show when each file was committed | |
| 360 | +** -v|--verbose Provide extra information about each file. | |
| 361 | +** -t Sort output in time order. | |
| 362 | +** -r VERSION The specific check-in to list | |
| 363 | +** -R|--repository FILE Extract info from repository FILE | |
| 283 | 364 | ** |
| 284 | 365 | ** See also: changes, extras, status |
| 285 | 366 | */ |
| 286 | 367 | void ls_cmd(void){ |
| 287 | 368 | int vid; |
| 288 | 369 | Stmt q; |
| 289 | 370 | int verboseFlag; |
| 290 | 371 | int showAge; |
| 372 | + int timeOrder; | |
| 291 | 373 | char *zOrderBy = "pathname"; |
| 292 | 374 | Blob where; |
| 293 | 375 | int i; |
| 294 | 376 | const char *zName; |
| 377 | + const char *zRev; | |
| 295 | 378 | |
| 296 | 379 | verboseFlag = find_option("verbose","v", 0)!=0; |
| 297 | 380 | if( !verboseFlag ){ |
| 298 | 381 | verboseFlag = find_option("l","l", 0)!=0; /* deprecated */ |
| 299 | 382 | } |
| 300 | 383 | showAge = find_option("age",0,0)!=0; |
| 384 | + zRev = find_option("r","r",1); | |
| 385 | + timeOrder = find_option("t","t",0)!=0; | |
| 386 | + | |
| 387 | + if( zRev!=0 ){ | |
| 388 | + db_find_and_open_repository(0, 0); | |
| 389 | + verify_all_options(); | |
| 390 | + ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder); | |
| 391 | + return; | |
| 392 | + } | |
| 393 | + | |
| 301 | 394 | db_must_be_within_tree(); |
| 302 | 395 | vid = db_lget_int("checkout", 0); |
| 303 | - if( find_option("t","t",0)!=0 ){ | |
| 396 | + if( timeOrder ){ | |
| 304 | 397 | if( showAge ){ |
| 305 | 398 | zOrderBy = mprintf("checkin_mtime(%d,rid) DESC", vid); |
| 306 | 399 | }else{ |
| 307 | 400 | zOrderBy = "mtime DESC"; |
| 308 | 401 | } |
| 309 | 402 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -265,44 +265,137 @@ | |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** COMMAND: ls |
| 273 | ** |
| 274 | ** Usage: %fossil ls ?OPTIONS? ?VERSION? ?FILENAMES? |
| 275 | ** |
| 276 | ** Show the names of all files in the current checkout. The -v provides |
| 277 | ** extra information about each file. If FILENAMES are included, only |
| 278 | ** the files listed (or their children if they are directories) are shown. |
| 279 | ** |
| 280 | ** Options: |
| 281 | ** --age Show when each file was committed |
| 282 | ** -v|--verbose Provide extra information about each file. |
| 283 | ** |
| 284 | ** See also: changes, extras, status |
| 285 | */ |
| 286 | void ls_cmd(void){ |
| 287 | int vid; |
| 288 | Stmt q; |
| 289 | int verboseFlag; |
| 290 | int showAge; |
| 291 | char *zOrderBy = "pathname"; |
| 292 | Blob where; |
| 293 | int i; |
| 294 | const char *zName; |
| 295 | |
| 296 | verboseFlag = find_option("verbose","v", 0)!=0; |
| 297 | if( !verboseFlag ){ |
| 298 | verboseFlag = find_option("l","l", 0)!=0; /* deprecated */ |
| 299 | } |
| 300 | showAge = find_option("age",0,0)!=0; |
| 301 | db_must_be_within_tree(); |
| 302 | vid = db_lget_int("checkout", 0); |
| 303 | if( find_option("t","t",0)!=0 ){ |
| 304 | if( showAge ){ |
| 305 | zOrderBy = mprintf("checkin_mtime(%d,rid) DESC", vid); |
| 306 | }else{ |
| 307 | zOrderBy = "mtime DESC"; |
| 308 | } |
| 309 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -265,44 +265,137 @@ | |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** Take care of -r version of ls command |
| 273 | */ |
| 274 | static void ls_cmd_rev( |
| 275 | const char *zRev, /* Revision string given */ |
| 276 | int verboseFlag, /* Verbose flag given */ |
| 277 | int showAge, /* Age flag given */ |
| 278 | int timeOrder /* Order by time flag given */ |
| 279 | ){ |
| 280 | Stmt q; |
| 281 | char *zOrderBy = "pathname COLLATE nocase"; |
| 282 | char *zName; |
| 283 | Blob where; |
| 284 | int rid; |
| 285 | int i; |
| 286 | |
| 287 | /* Handle given file names */ |
| 288 | blob_zero(&where); |
| 289 | for(i=2; i<g.argc; i++){ |
| 290 | Blob fname; |
| 291 | file_tree_name(g.argv[i], &fname, 1); |
| 292 | zName = blob_str(&fname); |
| 293 | if( fossil_strcmp(zName, ".")==0 ) { |
| 294 | blob_reset(&where); |
| 295 | break; |
| 296 | } |
| 297 | blob_append_sql(&where, |
| 298 | " %s (pathname=%Q %s) " |
| 299 | "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", |
| 300 | (blob_size(&where)>0) ? "OR" : "AND (", zName, |
| 301 | filename_collation(), zName, filename_collation(), |
| 302 | zName, filename_collation() |
| 303 | ); |
| 304 | } |
| 305 | if( blob_size(&where)>0 ){ |
| 306 | blob_append_sql(&where, ")"); |
| 307 | } |
| 308 | |
| 309 | rid = symbolic_name_to_rid(zRev, "ci"); |
| 310 | if( rid==0 ){ |
| 311 | fossil_fatal("not a valid check-in: %s", zRev); |
| 312 | } |
| 313 | |
| 314 | if( timeOrder ){ |
| 315 | zOrderBy = "mtime DESC"; |
| 316 | } |
| 317 | |
| 318 | compute_fileage(rid,0); |
| 319 | db_prepare(&q, |
| 320 | "SELECT datetime(fileage.mtime, 'localtime'), fileage.pathname,\n" |
| 321 | " blob.size, blob.uuid, blob2.uuid\n" |
| 322 | " FROM fileage, blob, blob as blob2\n" |
| 323 | " WHERE blob.rid=fileage.fid AND blob2.rid=fileage.mid %s\n" |
| 324 | " ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/ |
| 325 | ); |
| 326 | blob_reset(&where); |
| 327 | |
| 328 | while( db_step(&q)==SQLITE_ROW ){ |
| 329 | const char *zTime = db_column_text(&q,0); |
| 330 | const char *zFile = db_column_text(&q,1); |
| 331 | int size = db_column_int(&q,2); |
| 332 | const char *zFUuid = db_column_text(&q,3); |
| 333 | const char *zCUuid = db_column_text(&q,4); |
| 334 | if( verboseFlag ){ |
| 335 | /* TBD: What to include in verbose. UUID? */ |
| 336 | fossil_print("%s %7d %S %S %s\n", zTime, size, zFUuid, zCUuid, zFile); |
| 337 | }else if( showAge ){ |
| 338 | fossil_print("%s %s\n", zTime, zFile); |
| 339 | }else{ |
| 340 | fossil_print("%s\n", zFile); |
| 341 | } |
| 342 | } |
| 343 | db_finalize(&q); |
| 344 | } |
| 345 | |
| 346 | /* |
| 347 | ** COMMAND: ls |
| 348 | ** |
| 349 | ** Usage: %fossil ls ?OPTIONS? ?FILENAMES? |
| 350 | ** |
| 351 | ** Show the names of all files in the current checkout. The -v provides |
| 352 | ** extra information about each file. If FILENAMES are included, only |
| 353 | ** the files listed (or their children if they are directories) are shown. |
| 354 | ** |
| 355 | ** If -r is given a specific check-in is listed. In this case -R can be |
| 356 | ** given to query another repository. |
| 357 | ** |
| 358 | ** Options: |
| 359 | ** --age Show when each file was committed |
| 360 | ** -v|--verbose Provide extra information about each file. |
| 361 | ** -t Sort output in time order. |
| 362 | ** -r VERSION The specific check-in to list |
| 363 | ** -R|--repository FILE Extract info from repository FILE |
| 364 | ** |
| 365 | ** See also: changes, extras, status |
| 366 | */ |
| 367 | void ls_cmd(void){ |
| 368 | int vid; |
| 369 | Stmt q; |
| 370 | int verboseFlag; |
| 371 | int showAge; |
| 372 | int timeOrder; |
| 373 | char *zOrderBy = "pathname"; |
| 374 | Blob where; |
| 375 | int i; |
| 376 | const char *zName; |
| 377 | const char *zRev; |
| 378 | |
| 379 | verboseFlag = find_option("verbose","v", 0)!=0; |
| 380 | if( !verboseFlag ){ |
| 381 | verboseFlag = find_option("l","l", 0)!=0; /* deprecated */ |
| 382 | } |
| 383 | showAge = find_option("age",0,0)!=0; |
| 384 | zRev = find_option("r","r",1); |
| 385 | timeOrder = find_option("t","t",0)!=0; |
| 386 | |
| 387 | if( zRev!=0 ){ |
| 388 | db_find_and_open_repository(0, 0); |
| 389 | verify_all_options(); |
| 390 | ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder); |
| 391 | return; |
| 392 | } |
| 393 | |
| 394 | db_must_be_within_tree(); |
| 395 | vid = db_lget_int("checkout", 0); |
| 396 | if( timeOrder ){ |
| 397 | if( showAge ){ |
| 398 | zOrderBy = mprintf("checkin_mtime(%d,rid) DESC", vid); |
| 399 | }else{ |
| 400 | zOrderBy = "mtime DESC"; |
| 401 | } |
| 402 |