Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fold print_changes() into status_cmd() (formerly changes_cmd()). Remove C_SHA1SUM, C_HEADER, and C_VERBOSE flags which are no longer needed for communicating options to print_changes(). Move locate_unmanaged_files() closer to the top of the file so status_cmd() can call it. Implement C_UNMODIFIED and C_EXTRA in status_report(). Document the fact that the changes and status commands take optional path arguments. Let changes and status commands accept --case-sensitive (was already done), --dotfiles, and --ignore for the benefit of --extras. Incorporate search for extra files into status_cmd(). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | andygoth-changes |
Files: | files | file ages | folders |
SHA1: |
f15d20e39b55c7ac3e007a5df8429388 |
User & Date: | andygoth 2016-11-06 02:35:35.578 |
Context
2016-11-06
| ||
02:39 | Remove flag debug prints from status_cmd() now that it seems to be stable ... (check-in: 31c6140e user: andygoth tags: andygoth-changes) | |
02:35 | Fold print_changes() into status_cmd() (formerly changes_cmd()). Remove C_SHA1SUM, C_HEADER, and C_VERBOSE flags which are no longer needed for communicating options to print_changes(). Move locate_unmanaged_files() closer to the top of the file so status_cmd() can call it. Implement C_UNMODIFIED and C_EXTRA in status_report(). Document the fact that the changes and status commands take optional path arguments. Let changes and status commands accept --case-sensitive (was already done), --dotfiles, and --ignore for the benefit of --extras. Incorporate search for extra files into status_cmd(). ... (check-in: f15d20e3 user: andygoth tags: andygoth-changes) | |
2016-11-05
| ||
23:11 | Merge the status command into the changes command. ... (check-in: 2c3a108c user: andygoth tags: andygoth-changes) | |
Changes
Changes to src/checkin.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 | #include <assert.h> /* ** Change filter options. */ enum { /* Zero-based bit indexes. */ | | | | < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > | | | | > > > > | > | > > > | > | > > > > > > > | > | | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #include <assert.h> /* ** Change filter options. */ enum { /* Zero-based bit indexes. */ CB_EDITED , CB_UPDATED , CB_CHANGED, CB_MISSING , CB_ADDED, CB_DELETED, CB_RENAMED, CB_CONFLICT, CB_META , CB_UNMODIFIED, CB_EXTRA, CB_MERGE , CB_RELPATH, CB_CLASSIFY, CB_FATAL , CB_COMMENT , /* Bitmask values. */ C_EDITED = 1 << CB_EDITED, /* Edited, merged, and conflicted files. */ C_UPDATED = 1 << CB_UPDATED, /* Files updated by merge/integrate. */ C_CHANGED = 1 << CB_CHANGED, /* Treated the same as the above two. */ C_MISSING = 1 << CB_MISSING, /* Missing and non- files. */ C_ADDED = 1 << CB_ADDED, /* Added files. */ C_DELETED = 1 << CB_DELETED, /* Deleted files. */ C_RENAMED = 1 << CB_RENAMED, /* Renamed files. */ C_CONFLICT = 1 << CB_CONFLICT, /* Files having merge conflicts. */ C_META = 1 << CB_META, /* Files with metadata changes. */ C_UNMODIFIED = 1 << CB_UNMODIFIED,/* Unmodified files. */ C_EXTRA = 1 << CB_EXTRA, /* Unmanaged files. */ C_MERGE = 1 << CB_MERGE, /* Merge contributors. */ C_FILTER = C_EDITED | C_UPDATED | C_CHANGED | C_MISSING | C_ADDED | C_DELETED | C_RENAMED | C_CONFLICT | C_META | C_UNMODIFIED | C_EXTRA | C_MERGE, C_ALL = C_FILTER & ~(C_EXTRA | C_MERGE), C_RELPATH = 1 << CB_RELPATH, /* Show relative paths. */ C_CLASSIFY = 1 << CB_CLASSIFY, /* Show file change types. */ C_DEFAULT = (C_ALL & ~C_UNMODIFIED) | C_MERGE | C_CLASSIFY, C_FATAL = (1 << CB_FATAL) | C_MISSING, /* Fail on MISSING/NOT_A_FILE. */ C_COMMENT = 1 << CB_COMMENT, /* Precede each line with "# ". */ }; /* ** Create a TEMP table named SFILE and add all unmanaged files named on ** the command-line to that table. If directories are named, then add ** all unmanaged files contained underneath those directories. If there ** are no files or directories named on the command-line, then add all ** unmanaged files anywhere in the checkout. */ static void locate_unmanaged_files( int argc, /* Number of command-line arguments to examine */ char **argv, /* values of command-line arguments */ unsigned scanFlags, /* Zero or more SCAN_xxx flags */ Glob *pIgnore1, /* Do not add files that match this GLOB */ Glob *pIgnore2 /* Omit files matching this GLOB too */ ){ Blob name; /* Name of a candidate file or directory */ char *zName; /* Name of a candidate file or directory */ int isDir; /* 1 for a directory, 0 if doesn't exist, 2 for anything else */ int i; /* Loop counter */ int nRoot; /* length of g.zLocalRoot */ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)", filename_collation()); nRoot = (int)strlen(g.zLocalRoot); if( argc==0 ){ blob_init(&name, g.zLocalRoot, nRoot - 1); vfile_scan(&name, blob_size(&name), scanFlags, pIgnore1, pIgnore2); blob_reset(&name); }else{ for(i=0; i<argc; i++){ file_canonical_name(argv[i], &name, 0); zName = blob_str(&name); isDir = file_wd_isdir(zName); if( isDir==1 ){ vfile_scan(&name, nRoot-1, scanFlags, pIgnore1, pIgnore2); }else if( isDir==0 ){ fossil_warning("not found: %s", &zName[nRoot]); }else if( file_access(zName, R_OK) ){ fossil_fatal("cannot open %s", &zName[nRoot]); }else{ db_multi_exec( "INSERT OR IGNORE INTO sfile(x) VALUES(%Q)", &zName[nRoot] ); } blob_reset(&name); } } } /* ** Generate text describing all changes. ** ** We assume that vfile_check_signature has been run. */ static void status_report( Blob *report, /* Append the status report here */ unsigned flags /* Filter and other configuration flags */ ){ Stmt q; int nErr = 0; Blob rewrittenPathname; Blob sql = BLOB_INITIALIZER, where = BLOB_INITIALIZER; const char *zName; int i; /* Assemble the path-limiting WHERE clause, if any. */ blob_zero(&where); for(i=2; i<g.argc; i++){ Blob fname; file_tree_name(g.argv[i], &fname, 0, 1); zName = blob_str(&fname); if( fossil_strcmp(zName, ".")==0 ){ blob_reset(&where); break; } blob_append_sql(&where, " %s (pathname=%Q %s) " "OR (pathname>'%q/' %s AND pathname<'%q0' %s)", (blob_size(&where)>0) ? "OR" : "AND", zName, filename_collation(), zName, filename_collation(), zName, filename_collation() ); } /* Start building the SELECT statement. */ blob_zero(&sql); blob_append_sql(&sql, "SELECT pathname, deleted, chnged, rid," " coalesce(origname!=pathname,0) AS renamed, islink, 1 AS managed" " FROM vfile" " WHERE is_selected(id)%s", blob_sql_text(&where)); /* Exclude unmodified files unless requested. */ if( !(flags & C_UNMODIFIED) ){ blob_append_sql(&sql, " AND (chnged OR deleted OR rid=0 OR pathname!=origname)"); } /* If C_EXTRA, add unmanaged files to the query result too. */ if( flags & C_EXTRA ){ blob_append_sql(&sql, " UNION ALL SELECT x AS pathname, 0, 0, 0, 0, 0, 0" " FROM sfile WHERE 1%s", blob_sql_text(&where)); } /* Append an ORDER BY clause then compile the query. */ blob_append_sql(&sql, " ORDER BY pathname"); db_prepare(&q, "%s", blob_sql_text(&sql)); blob_reset(&sql); blob_reset(&where); /* Execute the query and assemble the report. */ blob_zero(&rewrittenPathname); while( db_step(&q)==SQLITE_ROW ){ const char *zPathname = db_column_text(&q, 0); const char *zClass = 0; int isManaged = db_column_int(&q, 6); int isDeleted = db_column_int(&q, 1); int isChnged = db_column_int(&q, 2); int isNew = isManaged && !db_column_int(&q, 3); int isRenamed = db_column_int(&q, 4); int isLink = db_column_int(&q, 5); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); int isMissing = !file_wd_isfile_or_link(zFullName); /* Determine the file change classification, if any. */ if( (flags & C_DELETED) && isDeleted ){ zClass = "DELETED"; }else if( (flags & C_MISSING) && isMissing ){ |
︙ | ︙ | |||
148 149 150 151 152 153 154 | }else if( (flags & C_META) && isChnged==8 ){ zClass = "UNEXEC"; }else if( (flags & C_META) && isChnged==9 ){ zClass = "UNLINK"; }else if( (flags & C_CONFLICT) && isChnged && !isLink && file_contains_merge_marker(zFullName) ){ zClass = "CONFLICT"; | | > | | < > > < | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | }else if( (flags & C_META) && isChnged==8 ){ zClass = "UNEXEC"; }else if( (flags & C_META) && isChnged==9 ){ zClass = "UNLINK"; }else if( (flags & C_CONFLICT) && isChnged && !isLink && file_contains_merge_marker(zFullName) ){ zClass = "CONFLICT"; }else if( (flags & (C_EDITED | C_CHANGED)) && isChnged && (isChnged<2 || isChnged>9) ){ zClass = "EDITED"; }else if( (flags & C_RENAMED) && isRenamed ){ zClass = "RENAMED"; }else if( (flags & C_UNMODIFIED) && isManaged && !isDeleted && !isMissing && !isNew && !isChnged && !isRenamed ){ zClass = "UNMODIFIED"; }else if( (flags & C_EXTRA) && !isManaged ){ zClass = "EXTRA"; } /* TODO: reimplement ls and extras in terms of this function. */ /* Only report files for which a change classification was determined. */ if( zClass ){ /* If C_COMMENT, precede each line with "# ". */ if( flags & C_COMMENT ){ blob_append(report, "# ", 2); |
︙ | ︙ | |||
241 242 243 244 245 246 247 | int absPathOption = find_option("abs-paths", 0, 0)!=0; int relPathOption = find_option("rel-paths", 0, 0)!=0; if( absPathOption ){ relativePaths = 0; } if( relPathOption ){ relativePaths = 1; } return relativePaths; } | < < < < < < < < < < < < < < < < < < < < < | | > > | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | int absPathOption = find_option("abs-paths", 0, 0)!=0; int relPathOption = find_option("rel-paths", 0, 0)!=0; if( absPathOption ){ relativePaths = 0; } if( relPathOption ){ relativePaths = 1; } return relativePaths; } /* ** COMMAND: changes ** COMMAND: status ** ** Usage: %fossil changes|status ?OPTIONS? ?PATHS ...? ** ** Report the change status of files in the current checkout. If one or ** more PATHS are specified, only changes among the named files and ** directories are reported. Directories are searched recursively. ** ** The status command is similar to the changes command, except it lacks ** several of the options supported by changes and it has its own header ** and footer information. The header information is a subset of that ** shown by the info command, and the footer shows if there are any forks. ** Change type classification is always enabled for the status command. ** |
︙ | ︙ | |||
316 317 318 319 320 321 322 323 324 325 326 327 328 329 | ** ** General options: ** --abs-paths Display absolute pathnames. ** --rel-paths Display pathnames relative to the current working ** directory. ** --sha1sum Verify file status using SHA1 hashing rather than ** relying on file mtimes. ** ** Options specific to the changes command: ** --header Identify the repository if report is non-empty. ** -v|--verbose Say "(none)" if the change report is empty. ** --classify Start each line with the file's change type. ** --no-classify Do not print file change types. ** | > > > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | ** ** General options: ** --abs-paths Display absolute pathnames. ** --rel-paths Display pathnames relative to the current working ** directory. ** --sha1sum Verify file status using SHA1 hashing rather than ** relying on file mtimes. ** --case-sensitive <BOOL> Override case-sensitive setting. ** --dotfiles Include unmanaged files beginning with a dot. ** --ignore <CSG> Ignore unmanaged files matching CSG glob patterns. ** ** Options specific to the changes command: ** --header Identify the repository if report is non-empty. ** -v|--verbose Say "(none)" if the change report is empty. ** --classify Start each line with the file's change type. ** --no-classify Do not print file change types. ** |
︙ | ︙ | |||
354 355 356 357 358 359 360 | } flagDefs[] = { {"edited" , C_EDITED , 0}, {"updated" , C_UPDATED , 0}, {"changed" , C_CHANGED, 0}, {"missing" , C_MISSING , 0}, {"added" , C_ADDED , 0}, {"deleted" , C_DELETED , 0}, {"renamed" , C_RENAMED, 0}, {"conflict" , C_CONFLICT , 0}, {"meta" , C_META , 0}, {"unmodified" , C_UNMODIFIED, 0}, {"all" , C_ALL , 0}, {"extra" , C_EXTRA , 0}, | < < | | < > > > > > > > > > > > > > > > > | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | } flagDefs[] = { {"edited" , C_EDITED , 0}, {"updated" , C_UPDATED , 0}, {"changed" , C_CHANGED, 0}, {"missing" , C_MISSING , 0}, {"added" , C_ADDED , 0}, {"deleted" , C_DELETED , 0}, {"renamed" , C_RENAMED, 0}, {"conflict" , C_CONFLICT , 0}, {"meta" , C_META , 0}, {"unmodified" , C_UNMODIFIED, 0}, {"all" , C_ALL , 0}, {"extra" , C_EXTRA , 0}, {"merge" , C_MERGE , 0}, {"classify" , C_CLASSIFY , 1}, }, noFlagDefs[] = { {"no-merge", C_MERGE , 0}, {"no-classify", C_CLASSIFY , 1}, }; #ifdef FOSSIL_DEBUG static const char *const bits[] = { "EDITED", "UPDATED", "CHANGED", "MISSING", "ADDED", "DELETED", "RENAMED", "CONFLICT", "META", "UNMODIFIED", "EXTRA", "MERGE", "RELPATH", "CLASSIFY", }; #endif Blob report = BLOB_INITIALIZER; int useSha1sum = find_option("sha1sum", 0, 0)!=0; int showHdr = find_option("header",0,0)!=0; int verboseFlag = find_option("verbose","v",0)!=0; const char *zIgnoreFlag = find_option("ignore", 0, 1); unsigned scanFlags = 0; int changes = g.argv[1][0]=='c'; unsigned flags = 0; int vid, i; /* If --ignore is not specified, use the ignore-glob setting. */ if( !zIgnoreFlag ){ zIgnoreFlag = db_get("ignore-glob", 0); } /* Get the --dotfiles argument, or read it from the dotfiles setting. */ if( find_option("dotfiles", 0, 0) || db_get_boolean("dotfiles", 0) ){ scanFlags = SCAN_ALL; } /* Load affirmative flag options. */ for( i=0; i<count(flagDefs); ++i ){ if( (!flagDefs[i].changesOnly || changes) && find_option(flagDefs[i].option, 0, 0) ){ flags |= flagDefs[i].mask; } |
︙ | ︙ | |||
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | flags &= ~noFlagDefs[i].mask; } } /* Confirm current working directory is within checkout. */ db_must_be_within_tree(); /* Relative path flag determination is done by a shared function. */ if( determine_cwd_relative_option() ){ flags |= C_RELPATH; } #ifdef FOSSIL_DEBUG for( i=0; i<count(bits); ++i ){ if( flags & (1 << i) ){ printf("%s ", bits[i]); } } printf("\n"); #endif /* We should be done with options. */ verify_all_options(); /* The status command prints general information before the change list. */ if( !changes ){ | > > > > > > > > > > > > > > > < | > | > > > > > > > > > > | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | flags &= ~noFlagDefs[i].mask; } } /* Confirm current working directory is within checkout. */ db_must_be_within_tree(); /* Get checkout version. l*/ vid = db_lget_int("checkout", 0); /* Relative path flag determination is done by a shared function. */ if( determine_cwd_relative_option() ){ flags |= C_RELPATH; } #ifdef FOSSIL_DEBUG for( i=0; i<count(bits); ++i ){ if( flags & (1 << i) ){ printf("%s ", bits[i]); } } printf("\n"); #endif /* We should be done with options. */ verify_all_options(); /* Check for changed files. */ vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0); /* Search for unmanaged files if requested. Exclude reserved files. */ if( flags & C_EXTRA ){ Glob *pIgnore = glob_create(zIgnoreFlag); locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); glob_free(pIgnore); db_multi_exec("DELETE FROM sfile WHERE x IN (%s)", fossil_all_reserved_names(0)); } /* The status command prints general information before the change list. */ if( !changes ){ fossil_print("repository: %s\n", db_repository_filename()); fossil_print("local-root: %s\n", g.zLocalRoot); if( g.zConfigDbName ){ fossil_print("config-db: %s\n", g.zConfigDbName); } if( vid ){ show_common_info(vid, "checkout:", 1, 1); } db_record_repository_filename(0); } /* Find and print all requested changes. */ blob_zero(&report); status_report(&report, flags); if( blob_size(&report) ){ if( showHdr ){ fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"), g.zLocalRoot); } blob_write_to_file(&report, "-"); }else if( verboseFlag ){ fossil_print(" (none)\n"); } blob_reset(&report); /* The status command ends with warnings about ambiguous leaves (forks). */ if( !changes ){ leaf_ambiguity_warning(vid, vid); } } |
︙ | ︙ | |||
664 665 666 667 668 669 670 | fossil_print("%s%s\n", type, zPathname); } free(zFullName); } db_finalize(&q); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | fossil_print("%s%s\n", type, zPathname); } free(zFullName); } db_finalize(&q); } /* ** COMMAND: extras ** ** Usage: %fossil extras ?OPTIONS? ?PATH1 ...? ** ** Print a list of all files in the source tree that are not part of the ** current checkout. See also the "clean" command. If paths are specified, |
︙ | ︙ |