Fossil SCM

Enhance the "fossil diff" command so that it accepts directories as arguments and shows diffs on all files contained within those directories.

drh 2015-12-15 20:07 trunk
Commit c46f98055cf49687423e15a134ed1445ff10fbd6
1 file changed +165 -168
+165 -168
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -38,12 +38,11 @@
3838
/*
3939
** Use the "exec-rel-paths" setting and the --exec-abs-paths and
4040
** --exec-rel-paths command line options to determine whether
4141
** certain external commands are executed using relative paths.
4242
*/
43
-static int determine_exec_relative_option(int force)
44
-{
43
+static int determine_exec_relative_option(int force){
4544
static int relativePaths = -1;
4645
if( force || relativePaths==-1 ){
4746
int relPathOption = find_option("exec-rel-paths", 0, 0)!=0;
4847
int absPathOption = find_option("exec-abs-paths", 0, 0)!=0;
4948
#if defined(FOSSIL_ENABLE_EXEC_REL_PATHS)
@@ -54,10 +53,60 @@
5453
if( relPathOption ){ relativePaths = 1; }
5554
if( absPathOption ){ relativePaths = 0; }
5655
}
5756
return relativePaths;
5857
}
58
+
59
+#if INTERFACE
60
+/*
61
+** An array of FileDirList objects describe the files and directories listed
62
+** on the command line of a "diff" command. Only those objects listed are
63
+** actually diffed.
64
+*/
65
+struct FileDirList {
66
+ int nUsed; /* Number of times each entry is used */
67
+ int nName; /* Length of the entry */
68
+ char *zName; /* Text of the entry */
69
+};
70
+#endif
71
+
72
+/*
73
+** Return true if zFile is a file named on the azInclude[] list or is
74
+** a file in a directory named on the azInclude[] list.
75
+**
76
+** if azInclude is NULL, then always include zFile.
77
+*/
78
+static int file_dir_match(FileDirList *p, const char *zFile){
79
+ int i = 0;
80
+ if( p==0 || strcmp(p->zName,".")==0 ) return 1;
81
+ if( filenames_are_case_sensitive() ){
82
+ while( p->zName ){
83
+ if( strcmp(zFile, p->zName)==0
84
+ || (strncmp(zFile, p->zName, p->nName)==0
85
+ && zFile[p->nName]=='/')
86
+ ){
87
+ break;
88
+ }
89
+ p++;
90
+ }
91
+ }else{
92
+ while( p->zName ){
93
+ if( fossil_stricmp(zFile, p->zName)==0
94
+ || (fossil_strnicmp(zFile, p->zName, p->nName)==0
95
+ && zFile[p->nName]=='/')
96
+ ){
97
+ break;
98
+ }
99
+ p++;
100
+ }
101
+ }
102
+ if( p->zName ){
103
+ p->nUsed++;
104
+ return 1;
105
+ }
106
+ return 0;
107
+}
59108
60109
/*
61110
** Print the "Index:" message that patches wants to see at the top of a diff.
62111
*/
63112
void diff_print_index(const char *zFile, u64 diffFlags){
@@ -297,46 +346,10 @@
297346
file_delete(zTemp2);
298347
blob_reset(&cmd);
299348
}
300349
}
301350
302
-/*
303
-** Do a diff against a single file named in zFile from version zFrom
304
-** against the same file on disk.
305
-**
306
-** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
307
-** command zDiffCmd to do the diffing.
308
-**
309
-** When using an external diff program, zBinGlob contains the GLOB patterns
310
-** for file names to treat as binary. If fIncludeBinary is zero, these files
311
-** will be skipped in addition to files that may contain binary content.
312
-*/
313
-static void diff_one_against_disk(
314
- const char *zFrom, /* Version tag for the "before" file */
315
- const char *zDiffCmd, /* Use this "diff" command */
316
- const char *zBinGlob, /* Treat file names matching this as binary */
317
- int fIncludeBinary, /* Include binary files for external diff */
318
- u64 diffFlags, /* Diff control flags */
319
- const char *zFile /* Name of the file to be diffed */
320
-){
321
- Blob fname;
322
- Blob content;
323
- int isLink;
324
- int isBin;
325
- file_tree_name(zFile, &fname, 0, 1);
326
- historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
327
- fIncludeBinary ? 0 : &isBin, 0);
328
- if( !isLink != !file_wd_islink(zFrom) ){
329
- fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
330
- }else{
331
- diff_file(&content, isBin, zFile, zFile,
332
- zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
333
- }
334
- blob_reset(&content);
335
- blob_reset(&fname);
336
-}
337
-
338351
/*
339352
** Run a diff between the version zFrom and files on disk. zFrom might
340353
** be NULL which means to simply show the difference between the edited
341354
** files on disk and the check-out on which they are based.
342355
**
@@ -345,16 +358,17 @@
345358
**
346359
** When using an external diff program, zBinGlob contains the GLOB patterns
347360
** for file names to treat as binary. If fIncludeBinary is zero, these files
348361
** will be skipped in addition to files that may contain binary content.
349362
*/
350
-static void diff_all_against_disk(
363
+static void diff_against_disk(
351364
const char *zFrom, /* Version to difference from */
352365
const char *zDiffCmd, /* Use this diff command. NULL for built-in */
353366
const char *zBinGlob, /* Treat file names matching this as binary */
354367
int fIncludeBinary, /* Treat file names matching this as binary */
355
- u64 diffFlags /* Flags controlling diff output */
368
+ u64 diffFlags, /* Flags controlling diff output */
369
+ FileDirList *pFileDir /* Which files to diff */
356370
){
357371
int vid;
358372
Blob sql;
359373
Stmt q;
360374
int asNewFile; /* Treat non-existant files as empty files */
@@ -410,10 +424,11 @@
410424
int isLink = db_column_int(&q, 5);
411425
const char *zFullName;
412426
int showDiff = 1;
413427
Blob fname;
414428
429
+ if( !file_dir_match(pFileDir, zPathname) ) continue;
415430
if( determine_exec_relative_option(0) ){
416431
blob_zero(&fname);
417432
file_relative_name(zPathname, &fname, 1);
418433
}else{
419434
blob_set(&fname, g.zLocalRoot);
@@ -463,43 +478,10 @@
463478
}
464479
db_finalize(&q);
465480
db_end_transaction(1); /* ROLLBACK */
466481
}
467482
468
-/*
469
-** Do a diff of a single file named in zFile against the
470
-** version of this file held in the undo buffer.
471
-**
472
-** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
473
-** command zDiffCmd to do the diffing.
474
-**
475
-** When using an external diff program, zBinGlob contains the GLOB patterns
476
-** for file names to treat as binary. If fIncludeBinary is zero, these files
477
-** will be skipped in addition to files that may contain binary content.
478
-*/
479
-static void diff_one_against_undo(
480
- const char *zDiffCmd, /* Use this "diff" command */
481
- const char *zBinGlob, /* Treat file names matching this as binary */
482
- int fIncludeBinary, /* Include binary files for external diff */
483
- u64 diffFlags, /* Diff control flags */
484
- const char *zFile /* Name of the file to be diffed */
485
-){
486
- Blob fname;
487
- Blob content;
488
-
489
- blob_init(&content, 0, 0);
490
- file_tree_name(zFile, &fname, 0, 1);
491
- db_blob(&content, "SELECT content FROM undo WHERE pathname=%Q",
492
- blob_str(&fname));
493
- if( blob_size(&content) ){
494
- diff_file(&content, 0, zFile, zFile,
495
- zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
496
- }
497
- blob_reset(&content);
498
- blob_reset(&fname);
499
-}
500
-
501483
/*
502484
** Run a diff between the undo buffer and files on disk.
503485
**
504486
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
505487
** command zDiffCmd to do the diffing.
@@ -506,76 +488,35 @@
506488
**
507489
** When using an external diff program, zBinGlob contains the GLOB patterns
508490
** for file names to treat as binary. If fIncludeBinary is zero, these files
509491
** will be skipped in addition to files that may contain binary content.
510492
*/
511
-static void diff_all_against_undo(
493
+static void diff_against_undo(
512494
const char *zDiffCmd, /* Use this diff command. NULL for built-in */
513495
const char *zBinGlob, /* Treat file names matching this as binary */
514496
int fIncludeBinary, /* Treat file names matching this as binary */
515
- u64 diffFlags /* Flags controlling diff output */
497
+ u64 diffFlags, /* Flags controlling diff output */
498
+ FileDirList *pFileDir /* List of files and directories to diff */
516499
){
517500
Stmt q;
518501
Blob content;
519502
db_prepare(&q, "SELECT pathname, content FROM undo");
520503
blob_init(&content, 0, 0);
521504
while( db_step(&q)==SQLITE_ROW ){
505
+ char *zFullName;
522506
const char *zFile = (const char*)db_column_text(&q, 0);
523
- char *zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
507
+ if( !file_dir_match(pFileDir, zFile) ) continue;
508
+ zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
524509
db_column_blob(&q, 1, &content);
525510
diff_file(&content, 0, zFullName, zFile,
526511
zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
527512
fossil_free(zFullName);
528513
blob_reset(&content);
529514
}
530515
db_finalize(&q);
531516
}
532517
533
-/*
534
-** Output the differences between two versions of a single file.
535
-** zFrom and zTo are the check-ins containing the two file versions.
536
-**
537
-** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
538
-** command zDiffCmd to do the diffing.
539
-**
540
-** When using an external diff program, zBinGlob contains the GLOB patterns
541
-** for file names to treat as binary. If fIncludeBinary is zero, these files
542
-** will be skipped in addition to files that may contain binary content.
543
-*/
544
-static void diff_one_two_versions(
545
- const char *zFrom, /* Version tag for the "before" file */
546
- const char *zTo, /* Version tag for the "after" file */
547
- const char *zDiffCmd, /* Use this "diff" command */
548
- const char *zBinGlob, /* GLOB pattern for files that are binary */
549
- int fIncludeBinary, /* True to show binary files */
550
- u64 diffFlags, /* Diff flags */
551
- const char *zFile /* Name of the file to be diffed */
552
-){
553
- char *zName;
554
- Blob fname;
555
- Blob v1, v2;
556
- int isLink1, isLink2;
557
- int isBin1, isBin2;
558
- if( diffFlags & DIFF_BRIEF ) return;
559
- file_tree_name(zFile, &fname, 0, 1);
560
- zName = blob_str(&fname);
561
- historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
562
- fIncludeBinary ? 0 : &isBin1, 0);
563
- historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
564
- fIncludeBinary ? 0 : &isBin2, 0);
565
- if( isLink1 != isLink2 ){
566
- diff_print_filenames(zName, zName, diffFlags);
567
- fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
568
- }else{
569
- diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
570
- zBinGlob, fIncludeBinary, diffFlags);
571
- }
572
- blob_reset(&v1);
573
- blob_reset(&v2);
574
- blob_reset(&fname);
575
-}
576
-
577518
/*
578519
** Show the difference between two files identified by ManifestFile
579520
** entries.
580521
**
581522
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
@@ -634,17 +575,18 @@
634575
**
635576
** When using an external diff program, zBinGlob contains the GLOB patterns
636577
** for file names to treat as binary. If fIncludeBinary is zero, these files
637578
** will be skipped in addition to files that may contain binary content.
638579
*/
639
-static void diff_all_two_versions(
580
+static void diff_two_versions(
640581
const char *zFrom,
641582
const char *zTo,
642583
const char *zDiffCmd,
643584
const char *zBinGlob,
644585
int fIncludeBinary,
645
- u64 diffFlags
586
+ u64 diffFlags,
587
+ FileDirList *pFileDir
646588
){
647589
Manifest *pFrom, *pTo;
648590
ManifestFile *pFromFile, *pToFile;
649591
int asNewFlag = (diffFlags & DIFF_VERBOSE)!=0 ? 1 : 0;
650592
@@ -663,33 +605,40 @@
663605
cmp = -1;
664606
}else{
665607
cmp = fossil_strcmp(pFromFile->zName, pToFile->zName);
666608
}
667609
if( cmp<0 ){
668
- fossil_print("DELETED %s\n", pFromFile->zName);
669
- if( asNewFlag ){
670
- diff_manifest_entry(pFromFile, 0, zDiffCmd, zBinGlob,
671
- fIncludeBinary, diffFlags);
610
+ if( file_dir_match(pFileDir, pFromFile->zName) ){
611
+ fossil_print("DELETED %s\n", pFromFile->zName);
612
+ if( asNewFlag ){
613
+ diff_manifest_entry(pFromFile, 0, zDiffCmd, zBinGlob,
614
+ fIncludeBinary, diffFlags);
615
+ }
672616
}
673617
pFromFile = manifest_file_next(pFrom,0);
674618
}else if( cmp>0 ){
675
- fossil_print("ADDED %s\n", pToFile->zName);
676
- if( asNewFlag ){
677
- diff_manifest_entry(0, pToFile, zDiffCmd, zBinGlob,
678
- fIncludeBinary, diffFlags);
619
+ if( file_dir_match(pFileDir, pToFile->zName) ){
620
+ fossil_print("ADDED %s\n", pToFile->zName);
621
+ if( asNewFlag ){
622
+ diff_manifest_entry(0, pToFile, zDiffCmd, zBinGlob,
623
+ fIncludeBinary, diffFlags);
624
+ }
679625
}
680626
pToFile = manifest_file_next(pTo,0);
681627
}else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
682628
/* No changes */
629
+ (void)file_dir_match(pFileDir, pFromFile->zName); /* Record name usage */
683630
pFromFile = manifest_file_next(pFrom,0);
684631
pToFile = manifest_file_next(pTo,0);
685632
}else{
686
- if( diffFlags & DIFF_BRIEF ){
687
- fossil_print("CHANGED %s\n", pFromFile->zName);
688
- }else{
689
- diff_manifest_entry(pFromFile, pToFile, zDiffCmd, zBinGlob,
690
- fIncludeBinary, diffFlags);
633
+ if( file_dir_match(pFileDir, pToFile->zName) ){
634
+ if( diffFlags & DIFF_BRIEF ){
635
+ fossil_print("CHANGED %s\n", pFromFile->zName);
636
+ }else{
637
+ diff_manifest_entry(pFromFile, pToFile, zDiffCmd, zBinGlob,
638
+ fIncludeBinary, diffFlags);
639
+ }
691640
}
692641
pFromFile = manifest_file_next(pFrom,0);
693642
pToFile = manifest_file_next(pTo,0);
694643
}
695644
}
@@ -805,10 +754,53 @@
805754
const char *diff_get_binary_glob(void){
806755
const char *zBinGlob = find_option("binary", 0, 1);
807756
if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
808757
return zBinGlob;
809758
}
759
+
760
+/*
761
+** The input is a list of file and/or directory names either in the current
762
+** checkout, or in the undo buffer if useUndo is true, or in check-outs
763
+** zFrom and/or zTo if they are not null. Return a new list that consists
764
+** of only filenames. Any directories on the input list are expected into
765
+** multiple files in the output list. The output list uses space obtained
766
+** from malloc() and is NULL terminated.
767
+*/
768
+static char **diff_expand_dirs(
769
+ int argc, /* Number of entries in argv[] */
770
+ const char **argv, /* List of files and/or directories to be diffed */
771
+ const char *zFrom, /* Source check-in name, or NULL */
772
+ const char *zTo, /* Target check-in name, or NULL */
773
+ int useUndo /* True if diffing against the undo buffer */
774
+){
775
+ Stmt q;
776
+ int i;
777
+ db_multi_exec(
778
+ "CREATE TEMP TABLE dfiles("
779
+ " name TEXT PRIMARY KEY,"
780
+ " path TEXT"
781
+ ") WITHOUT ROWID;"
782
+ "CREATE TEMP TABLE allowed("
783
+ " fn TEXT PRIMARY KEY"
784
+ ") WITHOUT ROWID;"
785
+ );
786
+ if( useUndo ){
787
+ db_multi_exec(
788
+ "INSERT OR IGNORE INTO allowed(fn)"
789
+ " SELECT pathname FROM undo INTERSECT SELECT pathname FROM vfile;"
790
+ );
791
+ }else if( zTo ){
792
+ }
793
+ db_prepare(&q, "INSERT OR IGNORE INTO dfiles(names) VALUES(:txt)");
794
+ for(i=0; i<argc; i++){
795
+ db_bind_text(&q, ":txt", argv[i]);
796
+ db_step(&q);
797
+ db_reset(&q);
798
+ }
799
+ db_finalize(&q);
800
+
801
+}
810802
811803
/*
812804
** COMMAND: diff
813805
** COMMAND: gdiff
814806
**
@@ -874,10 +866,11 @@
874866
const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
875867
const char *zBinGlob = 0; /* Treat file names matching this as binary */
876868
int fIncludeBinary = 0; /* Include binary files for external diff */
877869
int againstUndo = 0; /* Diff against files in the undo buffer */
878870
u64 diffFlags = 0; /* Flags to control the DIFF */
871
+ FileDirList *pFileDir = 0; /* Restrict the diff to these files */
879872
880873
if( find_option("tk",0,0)!=0 ){
881874
diff_tk("diff", 2);
882875
return;
883876
}
@@ -915,47 +908,51 @@
915908
}
916909
zBinGlob = diff_get_binary_glob();
917910
fIncludeBinary = diff_include_binary_files();
918911
determine_exec_relative_option(1);
919912
verify_all_options();
913
+ if( g.argc>=3 ){
914
+ int i;
915
+ Blob fname;
916
+ pFileDir = fossil_malloc( sizeof(*pFileDir) * (g.argc-1) );
917
+ memset(pFileDir, 0, sizeof(*pFileDir) * (g.argc-1));
918
+ for(i=2; i<g.argc; i++){
919
+ file_tree_name(g.argv[i], &fname, 0, 1);
920
+ pFileDir[i-2].zName = fossil_strdup(blob_str(&fname));
921
+ if( strcmp(pFileDir[i-2].zName,".")==0 ){
922
+ pFileDir[0].zName[0] = '.';
923
+ pFileDir[0].zName[1] = 0;
924
+ break;
925
+ }
926
+ pFileDir[i-2].nName = blob_size(&fname);
927
+ pFileDir[i-2].nUsed = 0;
928
+ blob_reset(&fname);
929
+ }
930
+ }
920931
if( againstUndo ){
921932
if( db_lget_int("undo_available",0)==0 ){
922933
fossil_print("No undo or redo is available\n");
923934
return;
924935
}
925
- if( g.argc>=3 ){
926
- int i;
927
- for(i=2; i<g.argc; i++){
928
- diff_one_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
929
- diffFlags, g.argv[i]);
930
- }
931
- }else{
932
- diff_all_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
933
- diffFlags);
934
- }
935
- }else if( zTo==0 ){
936
- if( g.argc>=3 ){
937
- int i;
938
- for(i=2; i<g.argc; i++){
939
- diff_one_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
940
- diffFlags, g.argv[i]);
941
- }
942
- }else{
943
- diff_all_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
944
- diffFlags);
945
- }
946
- }else{
947
- if( g.argc>=3 ){
948
- int i;
949
- for(i=2; i<g.argc; i++){
950
- diff_one_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
951
- diffFlags, g.argv[i]);
952
- }
953
- }else{
954
- diff_all_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
955
- diffFlags);
956
- }
936
+ diff_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
937
+ diffFlags, pFileDir);
938
+ }else if( zTo==0 ){
939
+ diff_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
940
+ diffFlags, pFileDir);
941
+ }else{
942
+ diff_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
943
+ diffFlags, pFileDir);
944
+ }
945
+ if( pFileDir ){
946
+ int i;
947
+ for(i=0; pFileDir[i].zName; i++){
948
+ if( pFileDir[i].nUsed==0 && strcmp(pFileDir[0].zName,".")!=0 ){
949
+ fossil_fatal("not found: '%s'", g.argv[i+2]);
950
+ }
951
+ fossil_free(pFileDir[i].zName);
952
+ }
953
+ fossil_free(pFileDir);
957954
}
958955
}
959956
960957
/*
961958
** WEBPAGE: vpatch
@@ -969,7 +966,7 @@
969966
login_check_credentials();
970967
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
971968
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
972969
973970
cgi_set_content_type("text/plain");
974
- diff_all_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE);
971
+ diff_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE, 0);
975972
}
976973
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -38,12 +38,11 @@
38 /*
39 ** Use the "exec-rel-paths" setting and the --exec-abs-paths and
40 ** --exec-rel-paths command line options to determine whether
41 ** certain external commands are executed using relative paths.
42 */
43 static int determine_exec_relative_option(int force)
44 {
45 static int relativePaths = -1;
46 if( force || relativePaths==-1 ){
47 int relPathOption = find_option("exec-rel-paths", 0, 0)!=0;
48 int absPathOption = find_option("exec-abs-paths", 0, 0)!=0;
49 #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS)
@@ -54,10 +53,60 @@
54 if( relPathOption ){ relativePaths = 1; }
55 if( absPathOption ){ relativePaths = 0; }
56 }
57 return relativePaths;
58 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
60 /*
61 ** Print the "Index:" message that patches wants to see at the top of a diff.
62 */
63 void diff_print_index(const char *zFile, u64 diffFlags){
@@ -297,46 +346,10 @@
297 file_delete(zTemp2);
298 blob_reset(&cmd);
299 }
300 }
301
302 /*
303 ** Do a diff against a single file named in zFile from version zFrom
304 ** against the same file on disk.
305 **
306 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
307 ** command zDiffCmd to do the diffing.
308 **
309 ** When using an external diff program, zBinGlob contains the GLOB patterns
310 ** for file names to treat as binary. If fIncludeBinary is zero, these files
311 ** will be skipped in addition to files that may contain binary content.
312 */
313 static void diff_one_against_disk(
314 const char *zFrom, /* Version tag for the "before" file */
315 const char *zDiffCmd, /* Use this "diff" command */
316 const char *zBinGlob, /* Treat file names matching this as binary */
317 int fIncludeBinary, /* Include binary files for external diff */
318 u64 diffFlags, /* Diff control flags */
319 const char *zFile /* Name of the file to be diffed */
320 ){
321 Blob fname;
322 Blob content;
323 int isLink;
324 int isBin;
325 file_tree_name(zFile, &fname, 0, 1);
326 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
327 fIncludeBinary ? 0 : &isBin, 0);
328 if( !isLink != !file_wd_islink(zFrom) ){
329 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
330 }else{
331 diff_file(&content, isBin, zFile, zFile,
332 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
333 }
334 blob_reset(&content);
335 blob_reset(&fname);
336 }
337
338 /*
339 ** Run a diff between the version zFrom and files on disk. zFrom might
340 ** be NULL which means to simply show the difference between the edited
341 ** files on disk and the check-out on which they are based.
342 **
@@ -345,16 +358,17 @@
345 **
346 ** When using an external diff program, zBinGlob contains the GLOB patterns
347 ** for file names to treat as binary. If fIncludeBinary is zero, these files
348 ** will be skipped in addition to files that may contain binary content.
349 */
350 static void diff_all_against_disk(
351 const char *zFrom, /* Version to difference from */
352 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
353 const char *zBinGlob, /* Treat file names matching this as binary */
354 int fIncludeBinary, /* Treat file names matching this as binary */
355 u64 diffFlags /* Flags controlling diff output */
 
356 ){
357 int vid;
358 Blob sql;
359 Stmt q;
360 int asNewFile; /* Treat non-existant files as empty files */
@@ -410,10 +424,11 @@
410 int isLink = db_column_int(&q, 5);
411 const char *zFullName;
412 int showDiff = 1;
413 Blob fname;
414
 
415 if( determine_exec_relative_option(0) ){
416 blob_zero(&fname);
417 file_relative_name(zPathname, &fname, 1);
418 }else{
419 blob_set(&fname, g.zLocalRoot);
@@ -463,43 +478,10 @@
463 }
464 db_finalize(&q);
465 db_end_transaction(1); /* ROLLBACK */
466 }
467
468 /*
469 ** Do a diff of a single file named in zFile against the
470 ** version of this file held in the undo buffer.
471 **
472 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
473 ** command zDiffCmd to do the diffing.
474 **
475 ** When using an external diff program, zBinGlob contains the GLOB patterns
476 ** for file names to treat as binary. If fIncludeBinary is zero, these files
477 ** will be skipped in addition to files that may contain binary content.
478 */
479 static void diff_one_against_undo(
480 const char *zDiffCmd, /* Use this "diff" command */
481 const char *zBinGlob, /* Treat file names matching this as binary */
482 int fIncludeBinary, /* Include binary files for external diff */
483 u64 diffFlags, /* Diff control flags */
484 const char *zFile /* Name of the file to be diffed */
485 ){
486 Blob fname;
487 Blob content;
488
489 blob_init(&content, 0, 0);
490 file_tree_name(zFile, &fname, 0, 1);
491 db_blob(&content, "SELECT content FROM undo WHERE pathname=%Q",
492 blob_str(&fname));
493 if( blob_size(&content) ){
494 diff_file(&content, 0, zFile, zFile,
495 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
496 }
497 blob_reset(&content);
498 blob_reset(&fname);
499 }
500
501 /*
502 ** Run a diff between the undo buffer and files on disk.
503 **
504 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
505 ** command zDiffCmd to do the diffing.
@@ -506,76 +488,35 @@
506 **
507 ** When using an external diff program, zBinGlob contains the GLOB patterns
508 ** for file names to treat as binary. If fIncludeBinary is zero, these files
509 ** will be skipped in addition to files that may contain binary content.
510 */
511 static void diff_all_against_undo(
512 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
513 const char *zBinGlob, /* Treat file names matching this as binary */
514 int fIncludeBinary, /* Treat file names matching this as binary */
515 u64 diffFlags /* Flags controlling diff output */
 
516 ){
517 Stmt q;
518 Blob content;
519 db_prepare(&q, "SELECT pathname, content FROM undo");
520 blob_init(&content, 0, 0);
521 while( db_step(&q)==SQLITE_ROW ){
 
522 const char *zFile = (const char*)db_column_text(&q, 0);
523 char *zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
 
524 db_column_blob(&q, 1, &content);
525 diff_file(&content, 0, zFullName, zFile,
526 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
527 fossil_free(zFullName);
528 blob_reset(&content);
529 }
530 db_finalize(&q);
531 }
532
533 /*
534 ** Output the differences between two versions of a single file.
535 ** zFrom and zTo are the check-ins containing the two file versions.
536 **
537 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
538 ** command zDiffCmd to do the diffing.
539 **
540 ** When using an external diff program, zBinGlob contains the GLOB patterns
541 ** for file names to treat as binary. If fIncludeBinary is zero, these files
542 ** will be skipped in addition to files that may contain binary content.
543 */
544 static void diff_one_two_versions(
545 const char *zFrom, /* Version tag for the "before" file */
546 const char *zTo, /* Version tag for the "after" file */
547 const char *zDiffCmd, /* Use this "diff" command */
548 const char *zBinGlob, /* GLOB pattern for files that are binary */
549 int fIncludeBinary, /* True to show binary files */
550 u64 diffFlags, /* Diff flags */
551 const char *zFile /* Name of the file to be diffed */
552 ){
553 char *zName;
554 Blob fname;
555 Blob v1, v2;
556 int isLink1, isLink2;
557 int isBin1, isBin2;
558 if( diffFlags & DIFF_BRIEF ) return;
559 file_tree_name(zFile, &fname, 0, 1);
560 zName = blob_str(&fname);
561 historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
562 fIncludeBinary ? 0 : &isBin1, 0);
563 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
564 fIncludeBinary ? 0 : &isBin2, 0);
565 if( isLink1 != isLink2 ){
566 diff_print_filenames(zName, zName, diffFlags);
567 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
568 }else{
569 diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
570 zBinGlob, fIncludeBinary, diffFlags);
571 }
572 blob_reset(&v1);
573 blob_reset(&v2);
574 blob_reset(&fname);
575 }
576
577 /*
578 ** Show the difference between two files identified by ManifestFile
579 ** entries.
580 **
581 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
@@ -634,17 +575,18 @@
634 **
635 ** When using an external diff program, zBinGlob contains the GLOB patterns
636 ** for file names to treat as binary. If fIncludeBinary is zero, these files
637 ** will be skipped in addition to files that may contain binary content.
638 */
639 static void diff_all_two_versions(
640 const char *zFrom,
641 const char *zTo,
642 const char *zDiffCmd,
643 const char *zBinGlob,
644 int fIncludeBinary,
645 u64 diffFlags
 
646 ){
647 Manifest *pFrom, *pTo;
648 ManifestFile *pFromFile, *pToFile;
649 int asNewFlag = (diffFlags & DIFF_VERBOSE)!=0 ? 1 : 0;
650
@@ -663,33 +605,40 @@
663 cmp = -1;
664 }else{
665 cmp = fossil_strcmp(pFromFile->zName, pToFile->zName);
666 }
667 if( cmp<0 ){
668 fossil_print("DELETED %s\n", pFromFile->zName);
669 if( asNewFlag ){
670 diff_manifest_entry(pFromFile, 0, zDiffCmd, zBinGlob,
671 fIncludeBinary, diffFlags);
 
 
672 }
673 pFromFile = manifest_file_next(pFrom,0);
674 }else if( cmp>0 ){
675 fossil_print("ADDED %s\n", pToFile->zName);
676 if( asNewFlag ){
677 diff_manifest_entry(0, pToFile, zDiffCmd, zBinGlob,
678 fIncludeBinary, diffFlags);
 
 
679 }
680 pToFile = manifest_file_next(pTo,0);
681 }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
682 /* No changes */
 
683 pFromFile = manifest_file_next(pFrom,0);
684 pToFile = manifest_file_next(pTo,0);
685 }else{
686 if( diffFlags & DIFF_BRIEF ){
687 fossil_print("CHANGED %s\n", pFromFile->zName);
688 }else{
689 diff_manifest_entry(pFromFile, pToFile, zDiffCmd, zBinGlob,
690 fIncludeBinary, diffFlags);
 
 
691 }
692 pFromFile = manifest_file_next(pFrom,0);
693 pToFile = manifest_file_next(pTo,0);
694 }
695 }
@@ -805,10 +754,53 @@
805 const char *diff_get_binary_glob(void){
806 const char *zBinGlob = find_option("binary", 0, 1);
807 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
808 return zBinGlob;
809 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
810
811 /*
812 ** COMMAND: diff
813 ** COMMAND: gdiff
814 **
@@ -874,10 +866,11 @@
874 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
875 const char *zBinGlob = 0; /* Treat file names matching this as binary */
876 int fIncludeBinary = 0; /* Include binary files for external diff */
877 int againstUndo = 0; /* Diff against files in the undo buffer */
878 u64 diffFlags = 0; /* Flags to control the DIFF */
 
879
880 if( find_option("tk",0,0)!=0 ){
881 diff_tk("diff", 2);
882 return;
883 }
@@ -915,47 +908,51 @@
915 }
916 zBinGlob = diff_get_binary_glob();
917 fIncludeBinary = diff_include_binary_files();
918 determine_exec_relative_option(1);
919 verify_all_options();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
920 if( againstUndo ){
921 if( db_lget_int("undo_available",0)==0 ){
922 fossil_print("No undo or redo is available\n");
923 return;
924 }
925 if( g.argc>=3 ){
926 int i;
927 for(i=2; i<g.argc; i++){
928 diff_one_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
929 diffFlags, g.argv[i]);
930 }
931 }else{
932 diff_all_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
933 diffFlags);
934 }
935 }else if( zTo==0 ){
936 if( g.argc>=3 ){
937 int i;
938 for(i=2; i<g.argc; i++){
939 diff_one_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
940 diffFlags, g.argv[i]);
941 }
942 }else{
943 diff_all_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
944 diffFlags);
945 }
946 }else{
947 if( g.argc>=3 ){
948 int i;
949 for(i=2; i<g.argc; i++){
950 diff_one_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
951 diffFlags, g.argv[i]);
952 }
953 }else{
954 diff_all_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
955 diffFlags);
956 }
957 }
958 }
959
960 /*
961 ** WEBPAGE: vpatch
@@ -969,7 +966,7 @@
969 login_check_credentials();
970 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
971 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
972
973 cgi_set_content_type("text/plain");
974 diff_all_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE);
975 }
976
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -38,12 +38,11 @@
38 /*
39 ** Use the "exec-rel-paths" setting and the --exec-abs-paths and
40 ** --exec-rel-paths command line options to determine whether
41 ** certain external commands are executed using relative paths.
42 */
43 static int determine_exec_relative_option(int force){
 
44 static int relativePaths = -1;
45 if( force || relativePaths==-1 ){
46 int relPathOption = find_option("exec-rel-paths", 0, 0)!=0;
47 int absPathOption = find_option("exec-abs-paths", 0, 0)!=0;
48 #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS)
@@ -54,10 +53,60 @@
53 if( relPathOption ){ relativePaths = 1; }
54 if( absPathOption ){ relativePaths = 0; }
55 }
56 return relativePaths;
57 }
58
59 #if INTERFACE
60 /*
61 ** An array of FileDirList objects describe the files and directories listed
62 ** on the command line of a "diff" command. Only those objects listed are
63 ** actually diffed.
64 */
65 struct FileDirList {
66 int nUsed; /* Number of times each entry is used */
67 int nName; /* Length of the entry */
68 char *zName; /* Text of the entry */
69 };
70 #endif
71
72 /*
73 ** Return true if zFile is a file named on the azInclude[] list or is
74 ** a file in a directory named on the azInclude[] list.
75 **
76 ** if azInclude is NULL, then always include zFile.
77 */
78 static int file_dir_match(FileDirList *p, const char *zFile){
79 int i = 0;
80 if( p==0 || strcmp(p->zName,".")==0 ) return 1;
81 if( filenames_are_case_sensitive() ){
82 while( p->zName ){
83 if( strcmp(zFile, p->zName)==0
84 || (strncmp(zFile, p->zName, p->nName)==0
85 && zFile[p->nName]=='/')
86 ){
87 break;
88 }
89 p++;
90 }
91 }else{
92 while( p->zName ){
93 if( fossil_stricmp(zFile, p->zName)==0
94 || (fossil_strnicmp(zFile, p->zName, p->nName)==0
95 && zFile[p->nName]=='/')
96 ){
97 break;
98 }
99 p++;
100 }
101 }
102 if( p->zName ){
103 p->nUsed++;
104 return 1;
105 }
106 return 0;
107 }
108
109 /*
110 ** Print the "Index:" message that patches wants to see at the top of a diff.
111 */
112 void diff_print_index(const char *zFile, u64 diffFlags){
@@ -297,46 +346,10 @@
346 file_delete(zTemp2);
347 blob_reset(&cmd);
348 }
349 }
350
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351 /*
352 ** Run a diff between the version zFrom and files on disk. zFrom might
353 ** be NULL which means to simply show the difference between the edited
354 ** files on disk and the check-out on which they are based.
355 **
@@ -345,16 +358,17 @@
358 **
359 ** When using an external diff program, zBinGlob contains the GLOB patterns
360 ** for file names to treat as binary. If fIncludeBinary is zero, these files
361 ** will be skipped in addition to files that may contain binary content.
362 */
363 static void diff_against_disk(
364 const char *zFrom, /* Version to difference from */
365 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
366 const char *zBinGlob, /* Treat file names matching this as binary */
367 int fIncludeBinary, /* Treat file names matching this as binary */
368 u64 diffFlags, /* Flags controlling diff output */
369 FileDirList *pFileDir /* Which files to diff */
370 ){
371 int vid;
372 Blob sql;
373 Stmt q;
374 int asNewFile; /* Treat non-existant files as empty files */
@@ -410,10 +424,11 @@
424 int isLink = db_column_int(&q, 5);
425 const char *zFullName;
426 int showDiff = 1;
427 Blob fname;
428
429 if( !file_dir_match(pFileDir, zPathname) ) continue;
430 if( determine_exec_relative_option(0) ){
431 blob_zero(&fname);
432 file_relative_name(zPathname, &fname, 1);
433 }else{
434 blob_set(&fname, g.zLocalRoot);
@@ -463,43 +478,10 @@
478 }
479 db_finalize(&q);
480 db_end_transaction(1); /* ROLLBACK */
481 }
482
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483 /*
484 ** Run a diff between the undo buffer and files on disk.
485 **
486 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
487 ** command zDiffCmd to do the diffing.
@@ -506,76 +488,35 @@
488 **
489 ** When using an external diff program, zBinGlob contains the GLOB patterns
490 ** for file names to treat as binary. If fIncludeBinary is zero, these files
491 ** will be skipped in addition to files that may contain binary content.
492 */
493 static void diff_against_undo(
494 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
495 const char *zBinGlob, /* Treat file names matching this as binary */
496 int fIncludeBinary, /* Treat file names matching this as binary */
497 u64 diffFlags, /* Flags controlling diff output */
498 FileDirList *pFileDir /* List of files and directories to diff */
499 ){
500 Stmt q;
501 Blob content;
502 db_prepare(&q, "SELECT pathname, content FROM undo");
503 blob_init(&content, 0, 0);
504 while( db_step(&q)==SQLITE_ROW ){
505 char *zFullName;
506 const char *zFile = (const char*)db_column_text(&q, 0);
507 if( !file_dir_match(pFileDir, zFile) ) continue;
508 zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
509 db_column_blob(&q, 1, &content);
510 diff_file(&content, 0, zFullName, zFile,
511 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
512 fossil_free(zFullName);
513 blob_reset(&content);
514 }
515 db_finalize(&q);
516 }
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518 /*
519 ** Show the difference between two files identified by ManifestFile
520 ** entries.
521 **
522 ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
@@ -634,17 +575,18 @@
575 **
576 ** When using an external diff program, zBinGlob contains the GLOB patterns
577 ** for file names to treat as binary. If fIncludeBinary is zero, these files
578 ** will be skipped in addition to files that may contain binary content.
579 */
580 static void diff_two_versions(
581 const char *zFrom,
582 const char *zTo,
583 const char *zDiffCmd,
584 const char *zBinGlob,
585 int fIncludeBinary,
586 u64 diffFlags,
587 FileDirList *pFileDir
588 ){
589 Manifest *pFrom, *pTo;
590 ManifestFile *pFromFile, *pToFile;
591 int asNewFlag = (diffFlags & DIFF_VERBOSE)!=0 ? 1 : 0;
592
@@ -663,33 +605,40 @@
605 cmp = -1;
606 }else{
607 cmp = fossil_strcmp(pFromFile->zName, pToFile->zName);
608 }
609 if( cmp<0 ){
610 if( file_dir_match(pFileDir, pFromFile->zName) ){
611 fossil_print("DELETED %s\n", pFromFile->zName);
612 if( asNewFlag ){
613 diff_manifest_entry(pFromFile, 0, zDiffCmd, zBinGlob,
614 fIncludeBinary, diffFlags);
615 }
616 }
617 pFromFile = manifest_file_next(pFrom,0);
618 }else if( cmp>0 ){
619 if( file_dir_match(pFileDir, pToFile->zName) ){
620 fossil_print("ADDED %s\n", pToFile->zName);
621 if( asNewFlag ){
622 diff_manifest_entry(0, pToFile, zDiffCmd, zBinGlob,
623 fIncludeBinary, diffFlags);
624 }
625 }
626 pToFile = manifest_file_next(pTo,0);
627 }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
628 /* No changes */
629 (void)file_dir_match(pFileDir, pFromFile->zName); /* Record name usage */
630 pFromFile = manifest_file_next(pFrom,0);
631 pToFile = manifest_file_next(pTo,0);
632 }else{
633 if( file_dir_match(pFileDir, pToFile->zName) ){
634 if( diffFlags & DIFF_BRIEF ){
635 fossil_print("CHANGED %s\n", pFromFile->zName);
636 }else{
637 diff_manifest_entry(pFromFile, pToFile, zDiffCmd, zBinGlob,
638 fIncludeBinary, diffFlags);
639 }
640 }
641 pFromFile = manifest_file_next(pFrom,0);
642 pToFile = manifest_file_next(pTo,0);
643 }
644 }
@@ -805,10 +754,53 @@
754 const char *diff_get_binary_glob(void){
755 const char *zBinGlob = find_option("binary", 0, 1);
756 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
757 return zBinGlob;
758 }
759
760 /*
761 ** The input is a list of file and/or directory names either in the current
762 ** checkout, or in the undo buffer if useUndo is true, or in check-outs
763 ** zFrom and/or zTo if they are not null. Return a new list that consists
764 ** of only filenames. Any directories on the input list are expected into
765 ** multiple files in the output list. The output list uses space obtained
766 ** from malloc() and is NULL terminated.
767 */
768 static char **diff_expand_dirs(
769 int argc, /* Number of entries in argv[] */
770 const char **argv, /* List of files and/or directories to be diffed */
771 const char *zFrom, /* Source check-in name, or NULL */
772 const char *zTo, /* Target check-in name, or NULL */
773 int useUndo /* True if diffing against the undo buffer */
774 ){
775 Stmt q;
776 int i;
777 db_multi_exec(
778 "CREATE TEMP TABLE dfiles("
779 " name TEXT PRIMARY KEY,"
780 " path TEXT"
781 ") WITHOUT ROWID;"
782 "CREATE TEMP TABLE allowed("
783 " fn TEXT PRIMARY KEY"
784 ") WITHOUT ROWID;"
785 );
786 if( useUndo ){
787 db_multi_exec(
788 "INSERT OR IGNORE INTO allowed(fn)"
789 " SELECT pathname FROM undo INTERSECT SELECT pathname FROM vfile;"
790 );
791 }else if( zTo ){
792 }
793 db_prepare(&q, "INSERT OR IGNORE INTO dfiles(names) VALUES(:txt)");
794 for(i=0; i<argc; i++){
795 db_bind_text(&q, ":txt", argv[i]);
796 db_step(&q);
797 db_reset(&q);
798 }
799 db_finalize(&q);
800
801 }
802
803 /*
804 ** COMMAND: diff
805 ** COMMAND: gdiff
806 **
@@ -874,10 +866,11 @@
866 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
867 const char *zBinGlob = 0; /* Treat file names matching this as binary */
868 int fIncludeBinary = 0; /* Include binary files for external diff */
869 int againstUndo = 0; /* Diff against files in the undo buffer */
870 u64 diffFlags = 0; /* Flags to control the DIFF */
871 FileDirList *pFileDir = 0; /* Restrict the diff to these files */
872
873 if( find_option("tk",0,0)!=0 ){
874 diff_tk("diff", 2);
875 return;
876 }
@@ -915,47 +908,51 @@
908 }
909 zBinGlob = diff_get_binary_glob();
910 fIncludeBinary = diff_include_binary_files();
911 determine_exec_relative_option(1);
912 verify_all_options();
913 if( g.argc>=3 ){
914 int i;
915 Blob fname;
916 pFileDir = fossil_malloc( sizeof(*pFileDir) * (g.argc-1) );
917 memset(pFileDir, 0, sizeof(*pFileDir) * (g.argc-1));
918 for(i=2; i<g.argc; i++){
919 file_tree_name(g.argv[i], &fname, 0, 1);
920 pFileDir[i-2].zName = fossil_strdup(blob_str(&fname));
921 if( strcmp(pFileDir[i-2].zName,".")==0 ){
922 pFileDir[0].zName[0] = '.';
923 pFileDir[0].zName[1] = 0;
924 break;
925 }
926 pFileDir[i-2].nName = blob_size(&fname);
927 pFileDir[i-2].nUsed = 0;
928 blob_reset(&fname);
929 }
930 }
931 if( againstUndo ){
932 if( db_lget_int("undo_available",0)==0 ){
933 fossil_print("No undo or redo is available\n");
934 return;
935 }
936 diff_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
937 diffFlags, pFileDir);
938 }else if( zTo==0 ){
939 diff_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
940 diffFlags, pFileDir);
941 }else{
942 diff_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
943 diffFlags, pFileDir);
944 }
945 if( pFileDir ){
946 int i;
947 for(i=0; pFileDir[i].zName; i++){
948 if( pFileDir[i].nUsed==0 && strcmp(pFileDir[0].zName,".")!=0 ){
949 fossil_fatal("not found: '%s'", g.argv[i+2]);
950 }
951 fossil_free(pFileDir[i].zName);
952 }
953 fossil_free(pFileDir);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
954 }
955 }
956
957 /*
958 ** WEBPAGE: vpatch
@@ -969,7 +966,7 @@
966 login_check_credentials();
967 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
968 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
969
970 cgi_set_content_type("text/plain");
971 diff_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE, 0);
972 }
973

Keyboard Shortcuts

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