Fossil SCM

Add the "fossil patch diff" command.

drh 2021-06-23 18:25 trunk
Commit 72d07a52c36c196f45335c633a26f5c2551f87ec329665c66037b48b6f7253fc
2 files changed +135 -15 +1 -2
+135 -15
--- src/patch.c
+++ src/patch.c
@@ -82,12 +82,12 @@
8282
/*
8383
** mkdelta(X,Y)
8484
**
8585
** X is an numeric artifact id. Y is a filename.
8686
**
87
-** Compute a compressed delta that carries X into Y. Or return NULL
88
-** if X is equal to Y.
87
+** Compute a compressed delta that carries X into Y. Or return
88
+** and zero-length blob if X is equal to Y.
8989
*/
9090
static void mkdeltaFunc(
9191
sqlite3_context *context,
9292
int argc,
9393
sqlite3_value **argv
@@ -126,10 +126,11 @@
126126
if( blob_size(&x)==blob_size(&y)
127127
&& memcmp(blob_buffer(&x), blob_buffer(&y), blob_size(&x))==0
128128
){
129129
blob_reset(&y);
130130
blob_reset(&x);
131
+ sqlite3_result_blob64(context, "", 0, SQLITE_STATIC);
131132
return;
132133
}
133134
nOut = delta_create(blob_buffer(&x),blob_size(&x),
134135
blob_buffer(&y),blob_size(&y), aOut);
135136
blob_reset(&x);
@@ -167,11 +168,12 @@
167168
" pathname TEXT,\n" /* Filename */
168169
" origname TEXT,\n" /* Name before rename. NULL if not renamed */
169170
" hash TEXT,\n" /* Baseline hash. NULL for new files. */
170171
" isexe BOOL,\n" /* True if executable */
171172
" islink BOOL,\n" /* True if is a symbolic link */
172
- " delta BLOB\n" /* Delta. NULL if file deleted or unchanged */
173
+ " delta BLOB\n" /* compressed delta. NULL if deleted.
174
+ ** length 0 if unchanged */
173175
");"
174176
"CREATE TABLE patch.cfg(\n"
175177
" key TEXT,\n"
176178
" value ANY\n"
177179
");"
@@ -322,14 +324,14 @@
322324
db_column_text(&q,1));
323325
}
324326
db_finalize(&q);
325327
}
326328
db_prepare(&q,
327
- "SELECT pathname,"
328
- " hash IS NULL AND delta IS NOT NULL," /* isNew */
329
- " delta IS NULL," /* delete if origname NULL */
330
- " origname"
329
+ "SELECT pathname," /* 0: new name */
330
+ " hash IS NULL AND delta IS NOT NULL," /* 1: isNew */
331
+ " delta IS NULL," /* 2: isDeleted */
332
+ " origname" /* 3: old name or NULL */
331333
" FROM patch.chng ORDER BY 1");
332334
while( db_step(&q)==SQLITE_ROW ){
333335
const char *zClass = "EDIT";
334336
const char *zName = db_column_text(&q,0);
335337
const char *zOrigName = db_column_text(&q, 3);
@@ -486,13 +488,17 @@
486488
int isExe = db_column_int(&q,2);
487489
int isLink = db_column_int(&q,3);
488490
Blob data;
489491
490492
blob_init(&data, 0, 0);
491
- db_column_blob(&q, 4, &data);
492
- blob_uncompress(&data, &data);
493
- if( zHash ){
493
+ db_ephemeral_blob(&q, 4, &data);
494
+ if( blob_size(&data) ){
495
+ blob_uncompress(&data, &data);
496
+ }
497
+ if( blob_size(&data)==0 ){
498
+ /* No changes to the file */
499
+ }else if( zHash ){
494500
Blob basis;
495501
int rid = fast_uuid_to_rid(zHash);
496502
int outSize, sz;
497503
char *aOut;
498504
if( rid==0 ){
@@ -553,19 +559,35 @@
553559
blob_reset(&cmd);
554560
}
555561
}
556562
557563
/*
558
-** Find the filename of the patch file to be used by
559
-** "fossil patch apply" or "fossil patch create".
564
+** This routine processes the
565
+**
566
+** ... [--dir64 DIR64] [DIRECTORY] FILENAME
567
+**
568
+** part of various "fossil patch" subcommands.
569
+**
570
+** Find and return the filename of the patch file to be used by
571
+** "fossil patch apply" or "fossil patch create". Space to hold
572
+** the returned name is obtained from fossil_malloc() and should
573
+** be freed by the caller.
560574
**
561
-** If the name is "-" return NULL.
575
+** If the name is "-" return NULL. The caller will interpret this
576
+** to mean the patch is coming in over stdin or going out over
577
+** stdout.
562578
**
563
-** Otherwise, if there is a prior DIRECTORY argument, or if
579
+** If there is a prior DIRECTORY argument, or if
564580
** the --dir64 option is present, first chdir to the specified
565
-** directory, and translate the name in the argument accordingly.
581
+** directory, and adjust the path of FILENAME as appropriate so
582
+** that it still points to the same file.
566583
**
584
+** The --dir64 option is undocumented. The argument to --dir64
585
+** is a base64-encoded directory name. The --dir64 option is used
586
+** to transmit the directory as part of the command argument to
587
+** a "ssh" command without having to worry about quoting
588
+** any special characters in the filename.
567589
**
568590
** The returned name is obtained from fossil_malloc() and should
569591
** be freed by the caller.
570592
*/
571593
static char *patch_find_patch_filename(const char *zCmdName){
@@ -604,10 +626,12 @@
604626
}
605627
606628
/*
607629
** Create a FILE* that will execute the remote side of a push or pull
608630
** using ssh (probably) or fossil for local pushes and pulls. Return
631
+** a FILE* obtained from popen() into which we write the patch, or from
632
+** which we read the patch, depending on whether this is a push or pull.
609633
*/
610634
static FILE *patch_remote_command(
611635
unsigned mFlags, /* flags */
612636
const char *zThisCmd, /* "push" or "pull" */
613637
const char *zRemoteCmd, /* "apply" or "create" */
@@ -650,10 +674,73 @@
650674
}
651675
blob_reset(&cmd);
652676
return f;
653677
}
654678
679
+/*
680
+** Show a diff for the patch currently loaded into database "patch".
681
+*/
682
+static void patch_diff(
683
+ const char *zDiffCmd, /* Command used for diffing */
684
+ const char *zBinGlob, /* GLOB pattern to determine binary files */
685
+ int fIncludeBinary, /* Do diffs against binary files */
686
+ u64 diffFlags /* Other diff flags */
687
+){
688
+ Stmt q;
689
+ Blob empty;
690
+ blob_zero(&empty);
691
+ db_prepare(&q,
692
+ "SELECT"
693
+ " blob.rid," /* 0: rid of the baseline */
694
+ " pathname," /* 1: new pathname */
695
+ " origname," /* 2: original pathname. Null if not renamed */
696
+ " delta" /* 3: delta. NULL if deleted. empty is no change */
697
+ " FROM patch.chng, blob WHERE blob.uuid=patch.chng.hash"
698
+ " ORDER BY pathname"
699
+ );
700
+ while( db_step(&q)==SQLITE_ROW ){
701
+ int rid = db_column_int(&q, 0);
702
+// const char *zOrig = db_column_text(&q, 2);
703
+ const char *zName = db_column_text(&q, 1);
704
+ int isBin1, isBin2;
705
+ Blob a, b;
706
+ if( db_column_type(&q,3)==SQLITE_NULL ){
707
+ fossil_print("DELETE %s\n", zName);
708
+ diff_print_index(zName, diffFlags, 0);
709
+ isBin2 = 0;
710
+ content_get(rid, &a);
711
+ isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
712
+ diff_file_mem(&a, &empty, isBin1, isBin2, zName, zDiffCmd,
713
+ zBinGlob, fIncludeBinary, diffFlags);
714
+ }else if( rid==0 ){
715
+ db_ephemeral_blob(&q, 3, &a);
716
+ blob_uncompress(&a, &a);
717
+ fossil_print("ADDED %s\n", zName);
718
+ diff_print_index(zName, diffFlags, 0);
719
+ isBin1 = 0;
720
+ isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
721
+ diff_file_mem(&empty, &a, isBin1, isBin2, zName, zDiffCmd,
722
+ zBinGlob, fIncludeBinary, diffFlags);
723
+ blob_reset(&a);
724
+ }else if( db_column_bytes(&q, 3)>0 ){
725
+ Blob delta;
726
+ db_ephemeral_blob(&q, 3, &delta);
727
+ blob_uncompress(&delta, &delta);
728
+ content_get(rid, &a);
729
+ blob_delta_apply(&a, &delta, &b);
730
+ isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
731
+ isBin2 = fIncludeBinary ? 0 : looks_like_binary(&b);
732
+ diff_file_mem(&a, &b, isBin1, isBin2, zName,
733
+ zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
734
+ blob_reset(&a);
735
+ blob_reset(&b);
736
+ blob_reset(&delta);
737
+ }
738
+ }
739
+ db_finalize(&q);
740
+}
741
+
655742
656743
/*
657744
** COMMAND: patch
658745
**
659746
** Usage: %fossil patch SUBCOMMAND ?ARGS ..?
@@ -678,10 +765,15 @@
678765
** -f|--force Apply the patch even though there are unsaved
679766
** changes in the current check-out.
680767
** -n|--dryrun Do nothing, but print what would have happened.
681768
** -v|--verbose Extra output explaining what happens.
682769
**
770
+** > fossil patch diff [DIRECTORY] FILENAME
771
+**
772
+** Show a human-readable diff for the patch. All the usual
773
+** diff flags apply. (See help for "fossil diff").
774
+**
683775
** > fossil patch push REMOTE-CHECKOUT
684776
**
685777
** Create a patch for the current check-out, transfer that patch to
686778
** a remote machine (using ssh) and apply the patch there. The
687779
** REMOTE-CHECKOUT is in one of the following formats:
@@ -733,10 +825,38 @@
733825
char *zOut;
734826
zOut = patch_find_patch_filename("create");
735827
db_must_be_within_tree();
736828
patch_create(zOut, stdout);
737829
fossil_free(zOut);
830
+ }else
831
+ if( strncmp(zCmd, "diff", n)==0 ){
832
+ const char *zDiffCmd = 0;
833
+ const char *zBinGlob = 0;
834
+ int fIncludeBinary = 0;
835
+ u64 diffFlags;
836
+ char *zIn;
837
+
838
+ if( find_option("tk",0,0)!=0 ){
839
+ db_close(0);
840
+ diff_tk("patch diff", 3);
841
+ return;
842
+ }
843
+ if( find_option("internal","i",0)==0 ){
844
+ zDiffCmd = diff_command_external(zCmd[0]=='g');
845
+ }
846
+ diffFlags = diff_options();
847
+ if( find_option("verbose","v",0)!=0 ) diffFlags |= DIFF_VERBOSE;
848
+ if( zDiffCmd ){
849
+ zBinGlob = diff_get_binary_glob();
850
+ fIncludeBinary = diff_include_binary_files();
851
+ }
852
+ zIn = patch_find_patch_filename("apply");
853
+ db_must_be_within_tree();
854
+ verify_all_options();
855
+ patch_attach(zIn, stdin);
856
+ patch_diff( zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
857
+ fossil_free(zIn);
738858
}else
739859
if( strncmp(zCmd, "pull", n)==0 ){
740860
FILE *pIn = 0;
741861
unsigned flags = 0;
742862
if( find_option("dryrun","n",0) ) flags |= PATCH_DRYRUN;
743863
--- src/patch.c
+++ src/patch.c
@@ -82,12 +82,12 @@
82 /*
83 ** mkdelta(X,Y)
84 **
85 ** X is an numeric artifact id. Y is a filename.
86 **
87 ** Compute a compressed delta that carries X into Y. Or return NULL
88 ** if X is equal to Y.
89 */
90 static void mkdeltaFunc(
91 sqlite3_context *context,
92 int argc,
93 sqlite3_value **argv
@@ -126,10 +126,11 @@
126 if( blob_size(&x)==blob_size(&y)
127 && memcmp(blob_buffer(&x), blob_buffer(&y), blob_size(&x))==0
128 ){
129 blob_reset(&y);
130 blob_reset(&x);
 
131 return;
132 }
133 nOut = delta_create(blob_buffer(&x),blob_size(&x),
134 blob_buffer(&y),blob_size(&y), aOut);
135 blob_reset(&x);
@@ -167,11 +168,12 @@
167 " pathname TEXT,\n" /* Filename */
168 " origname TEXT,\n" /* Name before rename. NULL if not renamed */
169 " hash TEXT,\n" /* Baseline hash. NULL for new files. */
170 " isexe BOOL,\n" /* True if executable */
171 " islink BOOL,\n" /* True if is a symbolic link */
172 " delta BLOB\n" /* Delta. NULL if file deleted or unchanged */
 
173 ");"
174 "CREATE TABLE patch.cfg(\n"
175 " key TEXT,\n"
176 " value ANY\n"
177 ");"
@@ -322,14 +324,14 @@
322 db_column_text(&q,1));
323 }
324 db_finalize(&q);
325 }
326 db_prepare(&q,
327 "SELECT pathname,"
328 " hash IS NULL AND delta IS NOT NULL," /* isNew */
329 " delta IS NULL," /* delete if origname NULL */
330 " origname"
331 " FROM patch.chng ORDER BY 1");
332 while( db_step(&q)==SQLITE_ROW ){
333 const char *zClass = "EDIT";
334 const char *zName = db_column_text(&q,0);
335 const char *zOrigName = db_column_text(&q, 3);
@@ -486,13 +488,17 @@
486 int isExe = db_column_int(&q,2);
487 int isLink = db_column_int(&q,3);
488 Blob data;
489
490 blob_init(&data, 0, 0);
491 db_column_blob(&q, 4, &data);
492 blob_uncompress(&data, &data);
493 if( zHash ){
 
 
 
 
494 Blob basis;
495 int rid = fast_uuid_to_rid(zHash);
496 int outSize, sz;
497 char *aOut;
498 if( rid==0 ){
@@ -553,19 +559,35 @@
553 blob_reset(&cmd);
554 }
555 }
556
557 /*
558 ** Find the filename of the patch file to be used by
559 ** "fossil patch apply" or "fossil patch create".
 
 
 
 
 
 
 
 
560 **
561 ** If the name is "-" return NULL.
 
 
562 **
563 ** Otherwise, if there is a prior DIRECTORY argument, or if
564 ** the --dir64 option is present, first chdir to the specified
565 ** directory, and translate the name in the argument accordingly.
 
566 **
 
 
 
 
 
567 **
568 ** The returned name is obtained from fossil_malloc() and should
569 ** be freed by the caller.
570 */
571 static char *patch_find_patch_filename(const char *zCmdName){
@@ -604,10 +626,12 @@
604 }
605
606 /*
607 ** Create a FILE* that will execute the remote side of a push or pull
608 ** using ssh (probably) or fossil for local pushes and pulls. Return
 
 
609 */
610 static FILE *patch_remote_command(
611 unsigned mFlags, /* flags */
612 const char *zThisCmd, /* "push" or "pull" */
613 const char *zRemoteCmd, /* "apply" or "create" */
@@ -650,10 +674,73 @@
650 }
651 blob_reset(&cmd);
652 return f;
653 }
654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
656 /*
657 ** COMMAND: patch
658 **
659 ** Usage: %fossil patch SUBCOMMAND ?ARGS ..?
@@ -678,10 +765,15 @@
678 ** -f|--force Apply the patch even though there are unsaved
679 ** changes in the current check-out.
680 ** -n|--dryrun Do nothing, but print what would have happened.
681 ** -v|--verbose Extra output explaining what happens.
682 **
 
 
 
 
 
683 ** > fossil patch push REMOTE-CHECKOUT
684 **
685 ** Create a patch for the current check-out, transfer that patch to
686 ** a remote machine (using ssh) and apply the patch there. The
687 ** REMOTE-CHECKOUT is in one of the following formats:
@@ -733,10 +825,38 @@
733 char *zOut;
734 zOut = patch_find_patch_filename("create");
735 db_must_be_within_tree();
736 patch_create(zOut, stdout);
737 fossil_free(zOut);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
738 }else
739 if( strncmp(zCmd, "pull", n)==0 ){
740 FILE *pIn = 0;
741 unsigned flags = 0;
742 if( find_option("dryrun","n",0) ) flags |= PATCH_DRYRUN;
743
--- src/patch.c
+++ src/patch.c
@@ -82,12 +82,12 @@
82 /*
83 ** mkdelta(X,Y)
84 **
85 ** X is an numeric artifact id. Y is a filename.
86 **
87 ** Compute a compressed delta that carries X into Y. Or return
88 ** and zero-length blob if X is equal to Y.
89 */
90 static void mkdeltaFunc(
91 sqlite3_context *context,
92 int argc,
93 sqlite3_value **argv
@@ -126,10 +126,11 @@
126 if( blob_size(&x)==blob_size(&y)
127 && memcmp(blob_buffer(&x), blob_buffer(&y), blob_size(&x))==0
128 ){
129 blob_reset(&y);
130 blob_reset(&x);
131 sqlite3_result_blob64(context, "", 0, SQLITE_STATIC);
132 return;
133 }
134 nOut = delta_create(blob_buffer(&x),blob_size(&x),
135 blob_buffer(&y),blob_size(&y), aOut);
136 blob_reset(&x);
@@ -167,11 +168,12 @@
168 " pathname TEXT,\n" /* Filename */
169 " origname TEXT,\n" /* Name before rename. NULL if not renamed */
170 " hash TEXT,\n" /* Baseline hash. NULL for new files. */
171 " isexe BOOL,\n" /* True if executable */
172 " islink BOOL,\n" /* True if is a symbolic link */
173 " delta BLOB\n" /* compressed delta. NULL if deleted.
174 ** length 0 if unchanged */
175 ");"
176 "CREATE TABLE patch.cfg(\n"
177 " key TEXT,\n"
178 " value ANY\n"
179 ");"
@@ -322,14 +324,14 @@
324 db_column_text(&q,1));
325 }
326 db_finalize(&q);
327 }
328 db_prepare(&q,
329 "SELECT pathname," /* 0: new name */
330 " hash IS NULL AND delta IS NOT NULL," /* 1: isNew */
331 " delta IS NULL," /* 2: isDeleted */
332 " origname" /* 3: old name or NULL */
333 " FROM patch.chng ORDER BY 1");
334 while( db_step(&q)==SQLITE_ROW ){
335 const char *zClass = "EDIT";
336 const char *zName = db_column_text(&q,0);
337 const char *zOrigName = db_column_text(&q, 3);
@@ -486,13 +488,17 @@
488 int isExe = db_column_int(&q,2);
489 int isLink = db_column_int(&q,3);
490 Blob data;
491
492 blob_init(&data, 0, 0);
493 db_ephemeral_blob(&q, 4, &data);
494 if( blob_size(&data) ){
495 blob_uncompress(&data, &data);
496 }
497 if( blob_size(&data)==0 ){
498 /* No changes to the file */
499 }else if( zHash ){
500 Blob basis;
501 int rid = fast_uuid_to_rid(zHash);
502 int outSize, sz;
503 char *aOut;
504 if( rid==0 ){
@@ -553,19 +559,35 @@
559 blob_reset(&cmd);
560 }
561 }
562
563 /*
564 ** This routine processes the
565 **
566 ** ... [--dir64 DIR64] [DIRECTORY] FILENAME
567 **
568 ** part of various "fossil patch" subcommands.
569 **
570 ** Find and return the filename of the patch file to be used by
571 ** "fossil patch apply" or "fossil patch create". Space to hold
572 ** the returned name is obtained from fossil_malloc() and should
573 ** be freed by the caller.
574 **
575 ** If the name is "-" return NULL. The caller will interpret this
576 ** to mean the patch is coming in over stdin or going out over
577 ** stdout.
578 **
579 ** If there is a prior DIRECTORY argument, or if
580 ** the --dir64 option is present, first chdir to the specified
581 ** directory, and adjust the path of FILENAME as appropriate so
582 ** that it still points to the same file.
583 **
584 ** The --dir64 option is undocumented. The argument to --dir64
585 ** is a base64-encoded directory name. The --dir64 option is used
586 ** to transmit the directory as part of the command argument to
587 ** a "ssh" command without having to worry about quoting
588 ** any special characters in the filename.
589 **
590 ** The returned name is obtained from fossil_malloc() and should
591 ** be freed by the caller.
592 */
593 static char *patch_find_patch_filename(const char *zCmdName){
@@ -604,10 +626,12 @@
626 }
627
628 /*
629 ** Create a FILE* that will execute the remote side of a push or pull
630 ** using ssh (probably) or fossil for local pushes and pulls. Return
631 ** a FILE* obtained from popen() into which we write the patch, or from
632 ** which we read the patch, depending on whether this is a push or pull.
633 */
634 static FILE *patch_remote_command(
635 unsigned mFlags, /* flags */
636 const char *zThisCmd, /* "push" or "pull" */
637 const char *zRemoteCmd, /* "apply" or "create" */
@@ -650,10 +674,73 @@
674 }
675 blob_reset(&cmd);
676 return f;
677 }
678
679 /*
680 ** Show a diff for the patch currently loaded into database "patch".
681 */
682 static void patch_diff(
683 const char *zDiffCmd, /* Command used for diffing */
684 const char *zBinGlob, /* GLOB pattern to determine binary files */
685 int fIncludeBinary, /* Do diffs against binary files */
686 u64 diffFlags /* Other diff flags */
687 ){
688 Stmt q;
689 Blob empty;
690 blob_zero(&empty);
691 db_prepare(&q,
692 "SELECT"
693 " blob.rid," /* 0: rid of the baseline */
694 " pathname," /* 1: new pathname */
695 " origname," /* 2: original pathname. Null if not renamed */
696 " delta" /* 3: delta. NULL if deleted. empty is no change */
697 " FROM patch.chng, blob WHERE blob.uuid=patch.chng.hash"
698 " ORDER BY pathname"
699 );
700 while( db_step(&q)==SQLITE_ROW ){
701 int rid = db_column_int(&q, 0);
702 // const char *zOrig = db_column_text(&q, 2);
703 const char *zName = db_column_text(&q, 1);
704 int isBin1, isBin2;
705 Blob a, b;
706 if( db_column_type(&q,3)==SQLITE_NULL ){
707 fossil_print("DELETE %s\n", zName);
708 diff_print_index(zName, diffFlags, 0);
709 isBin2 = 0;
710 content_get(rid, &a);
711 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
712 diff_file_mem(&a, &empty, isBin1, isBin2, zName, zDiffCmd,
713 zBinGlob, fIncludeBinary, diffFlags);
714 }else if( rid==0 ){
715 db_ephemeral_blob(&q, 3, &a);
716 blob_uncompress(&a, &a);
717 fossil_print("ADDED %s\n", zName);
718 diff_print_index(zName, diffFlags, 0);
719 isBin1 = 0;
720 isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
721 diff_file_mem(&empty, &a, isBin1, isBin2, zName, zDiffCmd,
722 zBinGlob, fIncludeBinary, diffFlags);
723 blob_reset(&a);
724 }else if( db_column_bytes(&q, 3)>0 ){
725 Blob delta;
726 db_ephemeral_blob(&q, 3, &delta);
727 blob_uncompress(&delta, &delta);
728 content_get(rid, &a);
729 blob_delta_apply(&a, &delta, &b);
730 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
731 isBin2 = fIncludeBinary ? 0 : looks_like_binary(&b);
732 diff_file_mem(&a, &b, isBin1, isBin2, zName,
733 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
734 blob_reset(&a);
735 blob_reset(&b);
736 blob_reset(&delta);
737 }
738 }
739 db_finalize(&q);
740 }
741
742
743 /*
744 ** COMMAND: patch
745 **
746 ** Usage: %fossil patch SUBCOMMAND ?ARGS ..?
@@ -678,10 +765,15 @@
765 ** -f|--force Apply the patch even though there are unsaved
766 ** changes in the current check-out.
767 ** -n|--dryrun Do nothing, but print what would have happened.
768 ** -v|--verbose Extra output explaining what happens.
769 **
770 ** > fossil patch diff [DIRECTORY] FILENAME
771 **
772 ** Show a human-readable diff for the patch. All the usual
773 ** diff flags apply. (See help for "fossil diff").
774 **
775 ** > fossil patch push REMOTE-CHECKOUT
776 **
777 ** Create a patch for the current check-out, transfer that patch to
778 ** a remote machine (using ssh) and apply the patch there. The
779 ** REMOTE-CHECKOUT is in one of the following formats:
@@ -733,10 +825,38 @@
825 char *zOut;
826 zOut = patch_find_patch_filename("create");
827 db_must_be_within_tree();
828 patch_create(zOut, stdout);
829 fossil_free(zOut);
830 }else
831 if( strncmp(zCmd, "diff", n)==0 ){
832 const char *zDiffCmd = 0;
833 const char *zBinGlob = 0;
834 int fIncludeBinary = 0;
835 u64 diffFlags;
836 char *zIn;
837
838 if( find_option("tk",0,0)!=0 ){
839 db_close(0);
840 diff_tk("patch diff", 3);
841 return;
842 }
843 if( find_option("internal","i",0)==0 ){
844 zDiffCmd = diff_command_external(zCmd[0]=='g');
845 }
846 diffFlags = diff_options();
847 if( find_option("verbose","v",0)!=0 ) diffFlags |= DIFF_VERBOSE;
848 if( zDiffCmd ){
849 zBinGlob = diff_get_binary_glob();
850 fIncludeBinary = diff_include_binary_files();
851 }
852 zIn = patch_find_patch_filename("apply");
853 db_must_be_within_tree();
854 verify_all_options();
855 patch_attach(zIn, stdin);
856 patch_diff( zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
857 fossil_free(zIn);
858 }else
859 if( strncmp(zCmd, "pull", n)==0 ){
860 FILE *pIn = 0;
861 unsigned flags = 0;
862 if( find_option("dryrun","n",0) ) flags |= PATCH_DRYRUN;
863
+1 -2
--- src/stash.c
+++ src/stash.c
@@ -442,11 +442,10 @@
442442
if( fBaseline ){
443443
content_get(rid, &a);
444444
isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
445445
diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
446446
zBinGlob, fIncludeBinary, diffFlags);
447
- }else{
448447
}
449448
}else{
450449
Blob delta;
451450
int isOrigLink = file_islink(zOPath);
452451
db_ephemeral_blob(&q, 6, &delta);
@@ -472,11 +471,11 @@
472471
blob_reset(&a);
473472
blob_reset(&b);
474473
}
475474
blob_reset(&delta);
476475
}
477
- }
476
+ }
478477
db_finalize(&q);
479478
}
480479
481480
/*
482481
** Drop the indicated stash
483482
--- src/stash.c
+++ src/stash.c
@@ -442,11 +442,10 @@
442 if( fBaseline ){
443 content_get(rid, &a);
444 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
445 diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
446 zBinGlob, fIncludeBinary, diffFlags);
447 }else{
448 }
449 }else{
450 Blob delta;
451 int isOrigLink = file_islink(zOPath);
452 db_ephemeral_blob(&q, 6, &delta);
@@ -472,11 +471,11 @@
472 blob_reset(&a);
473 blob_reset(&b);
474 }
475 blob_reset(&delta);
476 }
477 }
478 db_finalize(&q);
479 }
480
481 /*
482 ** Drop the indicated stash
483
--- src/stash.c
+++ src/stash.c
@@ -442,11 +442,10 @@
442 if( fBaseline ){
443 content_get(rid, &a);
444 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
445 diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
446 zBinGlob, fIncludeBinary, diffFlags);
 
447 }
448 }else{
449 Blob delta;
450 int isOrigLink = file_islink(zOPath);
451 db_ephemeral_blob(&q, 6, &delta);
@@ -472,11 +471,11 @@
471 blob_reset(&a);
472 blob_reset(&b);
473 }
474 blob_reset(&delta);
475 }
476 }
477 db_finalize(&q);
478 }
479
480 /*
481 ** Drop the indicated stash
482

Keyboard Shortcuts

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