Changes to VERSION.
Changes to src/add.c.
Changes to src/checkin.c.
︙ | | |
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
|
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
|
/* The status command ends with warnings about ambiguous leaves (forks). */
if( command==STATUS ){
leaf_ambiguity_warning(vid, vid);
}
}
/*
** Characters used for drawing a file hierarchy graph.
*/
#if _WIN32
/* ASCII only available on Windows */
#define ENTRY "|-- "
#define LASTE "`-- "
#define CONTU "| "
#define BLANK " "
#else
/* All other platforms support Unicode box-drawing chracters */
#define ENTRY "\342\224\234\342\224\200\342\224\200 "
#define LASTE "\342\224\224\342\224\200\342\224\200 "
#define CONTU "\342\224\202 "
#define BLANK " "
#endif
/* zIn is a string that is guaranteed to be followed by \n. Return
** a pointer to the next line after the \n. The returned value might
** point to the \000 string terminator.
*/
static const char *next_line(const char *zIn){
const char *z = strchr(zIn, '\n');
assert( z!=0 );
return z+1;
}
/* zIn is a non-empty list of filenames in sorted order and separated
** by \n. There might be a cluster of lines that have the same n-character
** prefix. Return a pointer to the start of the last line of that
** cluster. The return value might be zIn if the first line of zIn is
** unique in its first n character.
*/
static const char *last_line(const char *zIn, int n){
const char *zLast = zIn;
const char *z;
while( 1 ){
z = next_line(zLast);
if( z[0]==0 || (n>0 && strncmp(zIn, z, n)!=0) ) break;
zLast = z;
}
return zLast;
}
/*
** Print a section of a filelist hierarchy graph. This is a helper
** routine for print_filelist_as_tree() below.
*/
static const char *print_filelist_section(
const char *zIn, /* List of filenames, separated by \n */
const char *zLast, /* Last filename in the list to print */
const char *zPrefix, /* Prefix so put before each output line */
int nDir /* Ignore this many characters of directory name */
){
while( zIn<=zLast ){
int i;
for(i=nDir; zIn[i]!='\n' && zIn[i]!='/'; i++){}
if( zIn[i]=='/' ){
char *zSubPrefix;
const char *zSubLast = last_line(zIn, i+1);
zSubPrefix = mprintf("%s%s", zPrefix, zSubLast==zLast ? BLANK : CONTU);
fossil_print("%s%s%.*s\n", zPrefix, zSubLast==zLast ? LASTE : ENTRY,
i-nDir, &zIn[nDir]);
zIn = print_filelist_section(zIn, zSubLast, zSubPrefix, i+1);
fossil_free(zSubPrefix);
}else{
fossil_print("%s%s%.*s\n", zPrefix, zIn==zLast ? LASTE : ENTRY,
i-nDir, &zIn[nDir]);
zIn = next_line(zIn);
}
}
return zIn;
}
/*
** Input blob pList is a list of filenames, one filename per line,
** in sorted order and with / directory separators. Output this list
** as a tree in a manner similar to the "tree" command on Linux.
*/
static void print_filelist_as_tree(Blob *pList){
char *zAll;
const char *zLast;
fossil_print("%s\n", g.zLocalRoot);
zAll = blob_str(pList);
if( zAll[0] ){
zLast = last_line(zAll, 0);
print_filelist_section(zAll, zLast, "", 0);
}
}
/*
** Take care of -r version of ls command
*/
static void ls_cmd_rev(
const char *zRev, /* Revision string given */
int verboseFlag, /* Verbose flag given */
int showAge, /* Age flag given */
int timeOrder, /* Order by time flag given */
int timeOrder /* Order by time flag given */
int treeFmt /* Show output in the tree format */
){
Stmt q;
char *zOrderBy = "pathname COLLATE nocase";
char *zName;
Blob where;
int rid;
int i;
Blob out;
/* Handle given file names */
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);
|
︙ | | |
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
|
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
|
-
-
-
-
+
-
-
-
-
|
"SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n"
" blob.size\n"
" FROM fileage, blob\n"
" WHERE blob.rid=fileage.fid %s\n"
" ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
);
blob_reset(&where);
if( treeFmt ) blob_init(&out, 0, 0);
while( db_step(&q)==SQLITE_ROW ){
const char *zTime = db_column_text(&q,0);
const char *zFile = db_column_text(&q,1);
int size = db_column_int(&q,2);
if( treeFmt ){
blob_appendf(&out, "%s\n", zFile);
}else if( verboseFlag ){
if( verboseFlag ){
fossil_print("%s %7d %s\n", zTime, size, zFile);
}else if( showAge ){
fossil_print("%s %s\n", zTime, zFile);
}else{
fossil_print("%s\n", zFile);
}
}
db_finalize(&q);
if( treeFmt ){
print_filelist_as_tree(&out);
blob_reset(&out);
}
}
/*
** COMMAND: ls
**
** Usage: %fossil ls ?OPTIONS? ?PATHS ...?
**
|
︙ | | |
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
|
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
|
-
-
+
-
-
-
-
-
-
+
|
** path and name (case insensitive sort if -r). If neither --age nor -r
** are used, -t sorts by modification time, otherwise by commit time.
**
** Options:
** --age Show when each file was committed
** -v|--verbose Provide extra information about each file
** -t Sort output in time order
** --tree Tree format
** -r VERSION The specific check-in to list
** -R|--repository REPO Extract info from repository REPO
** --hash With -v, verify file status using hashing
** rather than relying on file sizes and mtimes
**
** See also: [[changes]], [[extras]], [[status]], [[tree]]
** See also: [[changes]], [[extras]], [[status]]
*/
void ls_cmd(void){
int vid;
Stmt q;
int verboseFlag;
int showAge;
int treeFmt;
int timeOrder;
char *zOrderBy = "pathname";
Blob where;
int i;
int useHash = 0;
const char *zName;
const char *zRev;
verboseFlag = find_option("verbose","v", 0)!=0;
if( !verboseFlag ){
verboseFlag = find_option("l","l", 0)!=0; /* deprecated */
}
showAge = find_option("age",0,0)!=0;
zRev = find_option("r","r",1);
timeOrder = find_option("t","t",0)!=0;
if( verboseFlag ){
useHash = find_option("hash",0,0)!=0;
}
treeFmt = find_option("tree",0,0)!=0;
if( treeFmt ){
if( zRev==0 ) zRev = "current";
}
if( zRev!=0 ){
db_find_and_open_repository(0, 0);
verify_all_options();
ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder,treeFmt);
ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder);
return;
}else if( find_option("R",0,1)!=0 ){
fossil_fatal("the -r is required in addition to -R");
}
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
|
︙ | | |
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
|
827
828
829
830
831
832
833
834
835
836
837
838
839
840
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
fossil_print("%s%s\n", type, zPathname);
}
free(zFullName);
}
db_finalize(&q);
}
/*
** COMMAND: tree
**
** Usage: %fossil tree ?OPTIONS? ?PATHS ...?
**
** List all files in the current check-out in after the fashion of the
** "tree" command. If PATHS is included, only the named files
** (or their children if directories) are shown.
**
** Options:
** -r VERSION The specific check-in to list
** -R|--repository REPO Extract info from repository REPO
**
** See also: [[ls]]
*/
void tree_cmd(void){
const char *zRev;
zRev = find_option("r","r",1);
if( zRev==0 ) zRev = "current";
db_find_and_open_repository(0, 0);
verify_all_options();
ls_cmd_rev(zRev,0,0,0,1);
}
/*
** COMMAND: extras
**
** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
**
** Print a list of all files in the source tree that are not part of the
** current check-out. See also the "clean" command. If paths are specified,
|
︙ | | |
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
|
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
|
-
-
-
-
-
-
-
-
-
-
+
-
|
** --abs-paths Display absolute pathnames
** --case-sensitive BOOL Override case-sensitive setting
** --dotfiles Include files beginning with a dot (".")
** --header Identify the repository if there are extras
** --ignore CSG Ignore files matching patterns from the argument
** --rel-paths Display pathnames relative to the current working
** directory
** --tree Show output in the tree format
**
** See also: [[changes]], [[clean]], [[status]]
*/
void extras_cmd(void){
Blob report = BLOB_INITIALIZER;
const char *zIgnoreFlag = find_option("ignore",0,1);
unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
unsigned flags = C_EXTRA;
int showHdr = find_option("header",0,0)!=0;
int treeFmt = find_option("tree",0,0)!=0;
Glob *pIgnore;
if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
db_must_be_within_tree();
if( determine_cwd_relative_option() ){
flags |= C_RELPATH;
}
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
if( treeFmt ){
flags &= ~C_RELPATH;
}
/* We should be done with options.. */
verify_all_options();
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
pIgnore = glob_create(zIgnoreFlag);
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
glob_free(pIgnore);
blob_zero(&report);
status_report(&report, flags);
if( blob_size(&report) ){
if( showHdr ){
fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
g.zLocalRoot);
}
if( treeFmt ){
print_filelist_as_tree(&report);
}else{
blob_write_to_file(&report, "-");
blob_write_to_file(&report, "-");
}
}
blob_reset(&report);
}
/*
** COMMAND: clean
**
|
︙ | | |
Changes to src/graph.c.
Changes to test/amend.test.
Changes to test/merge5.test.
Changes to test/stash.test.
Changes to test/tester.tcl.
Changes to test/utf.test.
︙ | | |
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
-
+
|
proc utf-check {testname args} {
global tempPath
set i 1
foreach {fileName result} $args {
set fileName [file join $tempPath $fileName]
fossil test-looks-like-utf $fileName
set result [string map [list %TEMP% $tempPath \r\n \n] $result]
# if {$::RESULT ne $result} {puts stdout $::RESULT; exit}
# if {$::RESULT ne $result} {puts stdout $::RESULT}
test utf-check-$testname.$i {$::RESULT eq $result}
incr i
}
}
unset -nocomplain enc
array set enc [list \
|
︙ | | |
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
|
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
Has flag LOOK_LONE_LF: no
Has flag LOOK_CRLF: no
Has flag LOOK_LONG: no
Has flag LOOK_INVALID: no
Has flag LOOK_ODD: no
Has flag LOOK_SHORT: no}
#utf-check 1179 utf-check-1179-2-129-1.jnk \
#{File "%TEMP%/utf-check-1179-2-129-1.jnk" has 7 bytes.
#Starts with UTF-8 BOM: no
#Starts with UTF-16 BOM: yes
#Looks like UTF-8: yes
#Has flag LOOK_NUL: no
#Has flag LOOK_CR: no
#Has flag LOOK_LONE_CR: no
#Has flag LOOK_LF: no
#Has flag LOOK_LONE_LF: no
#Has flag LOOK_CRLF: no
#Has flag LOOK_LONG: no
#Has flag LOOK_INVALID: yes
#Has flag LOOK_ODD: no
#Has flag LOOK_SHORT: no}
utf-check 1179 utf-check-1179-2-129-1.jnk \
{File "%TEMP%/utf-check-1179-2-129-1.jnk" has 7 bytes.
Starts with UTF-8 BOM: no
Starts with UTF-16 BOM: yes
Looks like UTF-8: no
Has flag LOOK_NUL: yes
Has flag LOOK_CR: no
Has flag LOOK_LONE_CR: no
Has flag LOOK_LF: no
Has flag LOOK_LONE_LF: no
Has flag LOOK_CRLF: no
Has flag LOOK_LONG: no
Has flag LOOK_INVALID: yes
Has flag LOOK_ODD: no
Has flag LOOK_SHORT: no}
utf-check 1180 utf-check-1180-2-130-0.jnk \
{File "%TEMP%/utf-check-1180-2-130-0.jnk" has 4 bytes.
Starts with UTF-8 BOM: no
Starts with UTF-16 BOM: yes
Looks like UTF-16: yes
Has flag LOOK_NUL: no
|
︙ | | |
24119
24120
24121
24122
24123
24124
24125
24126
24127
24128
24129
24130
24131
24132
24133
24134
24135
24136
24137
24138
24139
24140
24141
24142
24143
24144
24145
24146
24147
24148
24149
24150
24151
24152
24153
24154
24155
24156
24157
24158
24159
24160
24161
24162
24163
|
24119
24120
24121
24122
24123
24124
24125
24126
24127
24128
24129
24130
24131
24132
24133
24134
24135
24136
24137
24138
24139
24140
24141
24142
24143
24144
24145
24146
24147
24148
24149
24150
24151
24152
24153
24154
24155
24156
24157
24158
24159
24160
24161
24162
24163
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
Has flag LOOK_LONE_LF: no
Has flag LOOK_CRLF: no
Has flag LOOK_LONG: no
Has flag LOOK_INVALID: yes
Has flag LOOK_ODD: no
Has flag LOOK_SHORT: no}
#utf-check 1586 utf-check-1586-3-128-0.jnk \
#{File "%TEMP%/utf-check-1586-3-128-0.jnk" has 6 bytes.
#Starts with UTF-8 BOM: no
#Starts with UTF-16 BOM: reversed
#Looks like UTF-16: no
#Has flag LOOK_NUL: yes
#Has flag LOOK_CR: no
#Has flag LOOK_LONE_CR: no
#Has flag LOOK_LF: no
#Has flag LOOK_LONE_LF: no
#Has flag LOOK_CRLF: no
#Has flag LOOK_LONG: no
#Has flag LOOK_INVALID: no
#Has flag LOOK_ODD: no
#Has flag LOOK_SHORT: no}
utf-check 1586 utf-check-1586-3-128-0.jnk \
{File "%TEMP%/utf-check-1586-3-128-0.jnk" has 6 bytes.
Starts with UTF-8 BOM: no
Starts with UTF-16 BOM: no
Looks like UTF-8: no
Has flag LOOK_NUL: yes
Has flag LOOK_CR: no
Has flag LOOK_LONE_CR: no
Has flag LOOK_LF: no
Has flag LOOK_LONE_LF: no
Has flag LOOK_CRLF: no
Has flag LOOK_LONG: no
Has flag LOOK_INVALID: yes
Has flag LOOK_ODD: no
Has flag LOOK_SHORT: no}
#utf-check 1587 utf-check-1587-3-128-1.jnk \
#{File "%TEMP%/utf-check-1587-3-128-1.jnk" has 7 bytes.
#Starts with UTF-8 BOM: no
#Starts with UTF-16 BOM: reversed
#Looks like UTF-8: no
#Has flag LOOK_NUL: yes
#Has flag LOOK_CR: no
#Has flag LOOK_LONE_CR: no
#Has flag LOOK_LF: no
#Has flag LOOK_LONE_LF: no
#Has flag LOOK_CRLF: no
#Has flag LOOK_LONG: no
#Has flag LOOK_INVALID: yes
#Has flag LOOK_ODD: no
#Has flag LOOK_SHORT: no}
utf-check 1587 utf-check-1587-3-128-1.jnk \
{File "%TEMP%/utf-check-1587-3-128-1.jnk" has 7 bytes.
Starts with UTF-8 BOM: no
Starts with UTF-16 BOM: no
Looks like UTF-8: no
Has flag LOOK_NUL: yes
Has flag LOOK_CR: no
Has flag LOOK_LONE_CR: no
Has flag LOOK_LF: no
Has flag LOOK_LONE_LF: no
Has flag LOOK_CRLF: no
Has flag LOOK_LONG: no
Has flag LOOK_INVALID: yes
Has flag LOOK_ODD: no
Has flag LOOK_SHORT: no}
utf-check 1588 utf-check-1588-3-129-0.jnk \
{File "%TEMP%/utf-check-1588-3-129-0.jnk" has 6 bytes.
Starts with UTF-8 BOM: no
Starts with UTF-16 BOM: no
Looks like UTF-8: no
Has flag LOOK_NUL: yes
|
︙ | | |
Changes to www/changes.wiki.
Deleted www/colordiff.md.
Changes to www/embeddeddoc.wiki.
Changes to www/gitusers.md.
︙ | | |
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
-
-
-
+
+
+
|
[gpull]: https://git-scm.com/docs/git-pull
[gcokoan]: https://stevelosh.com/blog/2013/04/git-koans/#s2-one-thing-well
#### <a id="close" name="dotfile"></a> Closing a Check-Out
The [`fossil close`][close] command dissociates a check-out directory from the
Fossil repository database, _nondestructively_ inverting [`fossil open`][open].
(Contrast Git’s [closest alternative](#worktree), `git worktree remove`, which *is*
destructive!) This Fossil command does not
Fossil repository database, nondestructively inverting [`fossil open`][open].
(Contrast [its closest inverse](#worktree), `git worktree remove`, which *is*
destructive in Git!) This Fossil command does not
remove the managed files, and unless you give the `--force`
option, it won’t let you close the check-out with uncommitted changes to
those managed files.
The `close` command also refuses to run without `--force` when you have
certain other precious per-checkout data that Fossil stores in the
`.fslckout` file at the root of a check-out directory. This is a SQLite
|
︙ | | |
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
|
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
|
-
-
-
-
-
+
+
+
+
+
|
constants are equal.
Yet the constants are *not* equal because Fossil
reads from a single disk file rather than visit potentially many
files in sequence as Git must, so the OS’s buffer cache can result in
[still better performance][35pct].
Unlike Git’s log, Fossil’s timeline shows info across all branches by
default, a feature for maintaining better situational awareness.
It is possible to restrict the timeline to a single branch using `fossil timeline -b`.
Similarly, to restrict the timeline using the web UI equivalent,
click the name of a branch on the `/timeline` or `/brlist` page. (Or
Unlike Git’s log, Fossil’s timeline shows info across branches by
default, a feature for maintaining better situational awareness. Although the
`fossil timeline` command has no way to show a single branch’s commits,
you can restrict your view like this using the web UI equivalent by
clicking the name of a branch on the `/timeline` or `/brlist` page. (Or
manually, by adding the `r=` query parameter.) Note that even in this
case, the Fossil timeline still shows other branches where they interact
with the one you’ve referenced in this way; again, better situational
awareness.
#### <a id="emu-log"></a> Emulating `git log`
|
︙ | | |
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
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
542
543
544
545
546
547
548
549
550
551
|
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
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
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
|
character and such, because it doesn’t recognize Fossil commit messages
and apply similar rules as to Git commit messages.
[cskin]: ./customskin.md
[lsl]: https://chris.beams.io/posts/git-commit/#limit-50
<a id="autocommit"></a>
## Fossil Never Auto-Commits
There are several features in Git besides its `commit` command that
produce a new commit to the repository, and by default, they do it
without prompting or even asking for a commit message. These include
Git’s [`rebase`](#rebase), `merge`, and [`cherrypick`](#cpickrev)
commands, plus the [commit splitting](#comsplit) sub-feature
“`git commit -p`”.
Fossil never does this, on firm philosophical grounds: we wish to be
able to test that each potentially repository-changing command does not
break anything _before_ freezing it immutably into the [Merkle
tree](./blockchain.md). Where Fossil has equivalent commands, they
modify the checkout tree alone, requiring a separate `commit` command
afterward, withheld until the user has satisfied themselves that the
command’s result is correct.
We believe this is the main reason Git lacks an [autosync](#autosync)
feature: making push a manual step gives the user a chance to rewrite
history after triggering one of these autocommits locally, should the
automatic commit fail to work out as expected. Fossil chooses the
inverse path under the philosophy that commits are *commitments,* not
something you’re allowed to go back and rewrite later.
This is also why there is no automatic commit message writing feature in
Fossil, as in these autocommit-triggering Git commands. The user is
meant to write the commit message by hand after they are sure it’s
correct, in clear-headed retrospective fashion. Having the tool do it
prospectively before one can test the result is simply backwards.
<a id="staging"></a>
## There Is No Staging Area
Fossil omits the "Git index" or "staging area" concept. When you
type "`fossil commit`" _all_ changes in your check-out are committed,
by default. There is no need for the "-a" option as with Git.
automatically. There is no need for the "-a" option as with Git.
If you only want to commit _some_ of the changes, list the names
of the files or directories you want to commit as arguments, like this:
fossil commit src/feature.c doc/feature.md examples/feature
Note that the last element is a directory name, meaning “any changed
file under the `examples/feature` directory.”
Although there are currently no
<a id="comsplit"></a>
## Commit Splitting
<a id="csplit"></a>[commit splitting][gcspl] features in Fossil like
[Git’s commit splitting features][gcspl] rely on
other features of Git that Fossil purposefully lacks, as covered in the
prior two sections: [autocommit](#autocommit) and [the staging
area](#staging).
While there is no direct Fossil equivalent for
`git add -p`, `git commit -p`, or `git rebase -i`, you can get the same
effect by converting an uncommitted change set to a patch and then
running it through [Patchouli].
Rather than use `fossil diff -i` to produce such a patch, a safer and
more idiomatic method would be:
fossil stash save -m 'my big ball-o-hackage'
fossil stash diff > my-changes.patch
That stores your changes in the stash, then lets you operate on a copy
of that patch. Each time you re-run the second command, it will take the
current state of the working directory into account to produce a
potentially different patch, likely smaller because it leaves out patch
hunks already applied.
In this way, the combination of working tree and stash replaces the need
for Git’s index feature.
This also solves a philosophical problem with `git commit -p`: how can
you test that a split commit doesn’t break anything if you do it as part
of the commit action? Git’s lack of an autosync feature means you can
commit locally and then rewrite history if the commit doesn’t work out,
but we’d rather make changes only to the working directory, test the
changes there, and only commit once we’re sure it’s right.
We believe we know how to do commit splitting in a way compatible with
the Fossil philosophy, without following Git’s ill-considered design
leads. It amounts to automating the above process through an interactive
variant of [`fossil stash apply`][stash], as currently prototyped in the
third-party tool [`fnc`][fnc] and [its interactive `stash`
command][fncsta]. We merely await someone’s [contribution][ctrb] of this
This also explains why we don’t have anything like `git rebase -i`
to split an existing commit: in Fossil, commits are *commitments,* not
something you’re allowed to go back and rewrite later.
If someone does [contribute][ctrb] a commit splitting feature to Fossil,
we’d expect it to be an interactive form of
[`fossil stash apply`][stash], rather than follow Git’s ill-considered
design leads.
Until then, there’s the third-party tool [`fnc`][fnc] and
[its interactive `stash` command][fncsta].
feature into Fossil proper.
[ctrb]: https://fossil-scm.org/fossil/doc/trunk/www/contribute.wiki
[fnc]: https://fnc.bsdbox.org/
[fncsta]: https://fnc.bsdbox.org/uv/doc/fnc.1.html#stash
[gcspl]: https://git-scm.com/docs/git-rebase#_splitting_commits
[Patchouli]: https://pypi.org/project/patchouli/
|
︙ | | |
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
|
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
|
-
+
-
+
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
draft was written, it’s been revised multiple times to address less
common objections as well. Chances are not good that you are going to
come up with a new objection that we haven’t already considered and
addressed there.
There is only one sub-feature of `git rebase` that is philosophically
compatible with Fossil yet which currently has no functional equivalent.
We [covered this and the workaround for its lack](#comsplit) above.
We [covered this and the workaround for its lack](#csplit) above.
[3]: ./rebaseharm.md
<a id="cdiff"></a>
## <a id="cdiff"></a> Colorized Diffs
## Colorized Diffs
When you run `git diff` on an ANSI X3.64 capable terminal, it uses color
to distinguish insertions, deletions, and replacements, but as of this
writing, `fossil diff` produces traditional uncolored [unified diff
format][udiff] output, suitable for producing a [patch file][pfile].
Nevertheless, there are multiple ways to get colorized diff output from
Fossil:
There are [many methods](./colordiff.md) for solving this.
* The most direct method is to delegate diff behavior back to Git:
fossil set --global diff-command 'git diff --no-index'
The flag permits it to diff files that aren’t inside a Git repository.
* Another method is to install [`colordiff`][cdiff] — included in
[many package systems][cdpkg] — then say:
fossil set --global diff-command 'colordiff -wu'
Because this is unconditional, unlike `git diff --color=auto`, you
will then have to remember to add the `-i` option to `fossil diff`
commands when you want color disabled, such as when producing
`patch(1)` files or piping diff output to another command that
doesn’t understand ANSI escape sequences. There’s an example of this
[below](#dstat).
* Use the Fossil web UI to diff existing commits.
* To diff the current working directory contents against some parent
instead, Fossil’s diff command can produce
colorized HTML output and open it in the OS’s default web browser.
For example, `fossil diff -by` will show side-by-side diffs.
* Use the older `fossil diff --tk` option to do much the same using
Tcl/Tk instead of a browser.
Viewed this way, Fossil doesn’t lack colorized diffs, it simply has
*one* method where they *aren’t* colorized.
[cdpkg]: https://repology.org/project/colordiff/versions
[pfile]: https://en.wikipedia.org/wiki/Patch_(Unix)
[udiff]: https://en.wikipedia.org/wiki/Diff#Unified_format
## <a id="show"></a> Showing Information About Commits
While there is no direct equivalent to Git’s “`show`” command, similar
|
︙ | | |
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
|
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
|
-
-
-
+
+
+
+
+
|
The `--numstat` output is a bit cryptic, so we recommend delegating
this task to [the widely-available `diffstat` tool][dst], which gives
a histogram in its default output mode rather than bare integers:
fossil diff -i -v --from 2020-04-01 | diffstat
We gave the `-i` flag in both cases to force Fossil to use its internal
diff implementation, bypassing [your local `diff-command` setting][dcset]
since the `--numstat` option has no effect when you have an external diff
command set.
diff implementation, bypassing [your local `diff-command` setting][dcset].
The `--numstat` option has no effect when you have an external diff
command set, and some diff command alternatives like
[`colordiff`][cdiff] (covered [above](#cdiff)) produce output that confuses `diffstat`.
If you leave off the `-v` flag in the second example, the `diffstat`
output won’t include info about any newly-added files.
[cdiff]: https://www.colordiff.org/
[dcset]: https://fossil-scm.org/home/help?cmd=diff-command
[dst]: https://invisible-island.net/diffstat/diffstat.html
<a id="btnames"></a>
## Branch and Tag Names
|
︙ | | |
Changes to www/hints.wiki.
Changes to www/index.wiki.
Changes to www/mkindex.tcl.
Changes to www/permutedindex.html.