Fossil SCM

If the committed file has CR/NL or UTF-16 (or both), give the user the possibility to convert it to resp NL or UTF-8 (or both) without committing

jan.nijtmans 2012-11-05 13:10 trunk
Commit c6223a8e2a380c07993fd34d4ea02904f3bea939
1 file changed +39 -8
+39 -8
--- src/checkin.c
+++ src/checkin.c
@@ -890,13 +890,17 @@
890890
891891
/*
892892
** Issue a warning and give the user an opportunity to abandon out
893893
** if a Unicode (UTF-16) byte-order-mark (BOM) or a \r\n line ending
894894
** is seen in a text file.
895
+**
896
+** Return 1 if the user pressed 'c'. In that case, the file will have
897
+** been converted to UTF-8 (if it was UTF-16) with NL line-endings,
898
+** and the original file will have been renamed to "<filename>-original".
895899
*/
896
-static void commit_warning(
897
- const Blob *p, /* The content of the file being committed. */
900
+static int commit_warning(
901
+ Blob *p, /* The content of the file being committed. */
898902
int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */
899903
int binOk, /* Non-zero if binary warnings should be disabled. */
900904
const char *zFilename /* The full name of the file being committed. */
901905
){
902906
int eType; /* return value of looks_like_utf8/utf16() */
@@ -903,50 +907,74 @@
903907
int fUnicode; /* return value of starts_with_utf16_bom() */
904908
char *zMsg; /* Warning message */
905909
Blob fname; /* Relative pathname of the file */
906910
static int allOk = 0; /* Set to true to disable this routine */
907911
908
- if( allOk ) return;
912
+ if( allOk ) return 0;
909913
fUnicode = starts_with_utf16_bom(p);
910914
eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
911915
if( eType==0 || eType==-1 || fUnicode ){
912916
const char *zWarning;
917
+ const char *c = "c=convert/";
913918
Blob ans;
914919
char cReply;
915920
916921
if( eType==-1 && fUnicode ){
917922
zWarning = "Unicode and CR/NL line endings";
918923
}else if( eType==-1 ){
919924
if( crnlOk ){
920
- return; /* We don't want CR/NL warnings for this file. */
925
+ return 0; /* We don't want CR/NL warnings for this file. */
921926
}
922927
zWarning = "CR/NL line endings";
923928
}else if( eType==0 ){
924929
if( binOk ){
925
- return; /* We don't want binary warnings for this file. */
930
+ return 0; /* We don't want binary warnings for this file. */
926931
}
927932
zWarning = "binary data";
928933
}else{
929934
zWarning = "Unicode";
935
+#ifndef _WIN32
936
+ c = ""; /* On UNIX, we cannot convert unicode files */
937
+#endif
930938
}
931939
file_relative_name(zFilename, &fname, 0);
932940
blob_zero(&ans);
933941
zMsg = mprintf(
934
- "%s contains %s. commit anyhow (a=all/y/N)? ",
935
- blob_str(&fname), zWarning);
942
+ "%s contains %s. commit anyhow (a=all/%sy/N)? ",
943
+ blob_str(&fname), zWarning, c);
936944
prompt_user(zMsg, &ans);
937945
fossil_free(zMsg);
938946
cReply = blob_str(&ans)[0];
939947
if( cReply=='a' || cReply=='A' ){
940948
allOk = 1;
949
+ }else if( (cReply=='c' || cReply=='C')
950
+#ifndef _WIN32
951
+ && fUnicode
952
+#endif
953
+ ){
954
+ char *zOrig = file_newname(zFilename, "original", 1);
955
+ FILE *f;
956
+ blob_write_to_file(p, zOrig);
957
+ fossil_free(zOrig);
958
+ f = fossil_fopen(zFilename, "wb");
959
+ if( fUnicode ) {
960
+ static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
961
+ fwrite(bom, 1, 3, f);
962
+ blob_strip_bom(p, 0);
963
+ }
964
+ blob_remove_cr(p);
965
+ fwrite(blob_buffer(p), 1, blob_size(p), f);
966
+ fclose(f);
967
+ return 1;
941968
}else if( cReply!='y' && cReply!='Y' ){
942969
fossil_fatal("Abandoning commit due to %s in %s",
943970
zWarning, blob_str(&fname));
944971
}
945972
blob_reset(&ans);
946973
blob_reset(&fname);
947974
}
975
+ return 0;
948976
}
949977
950978
/*
951979
** qsort() comparison routine for an array of pointers to strings.
952980
*/
@@ -1044,10 +1072,11 @@
10441072
Blob cksum1, cksum2; /* Before and after commit checksums */
10451073
Blob cksum1b; /* Checksum recorded in the manifest */
10461074
int szD; /* Size of the delta manifest */
10471075
int szB; /* Size of the baseline manifest */
10481076
int nConflict = 0; /* Number of unresolved merge conflicts */
1077
+ int abortCommit = 0;
10491078
Blob ans;
10501079
char cReply;
10511080
10521081
url_proxy_options();
10531082
noSign = find_option("nosign",0,0)!=0;
@@ -1278,11 +1307,11 @@
12781307
/* Instead of file content, put link destination path */
12791308
blob_read_link(&content, zFullname);
12801309
}else{
12811310
blob_read_from_file(&content, zFullname);
12821311
}
1283
- commit_warning(&content, crnlOk, binOk, zFullname);
1312
+ abortCommit |= commit_warning(&content, crnlOk, binOk, zFullname);
12841313
if( chnged==1 && contains_merge_marker(&content) ){
12851314
Blob fname; /* Relative pathname of the file */
12861315
12871316
nConflict++;
12881317
file_relative_name(zFullname, &fname, 0);
@@ -1299,10 +1328,12 @@
12991328
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
13001329
}
13011330
db_finalize(&q);
13021331
if( nConflict && !allowConflict ){
13031332
fossil_fatal("abort due to unresolve merge conflicts");
1333
+ } else if( abortCommit ){
1334
+ fossil_fatal("files are converted on your request. Please re-test before committing");
13041335
}
13051336
13061337
/* Create the new manifest */
13071338
if( blob_size(&comment)==0 ){
13081339
blob_append(&comment, "(no comment)", -1);
13091340
--- src/checkin.c
+++ src/checkin.c
@@ -890,13 +890,17 @@
890
891 /*
892 ** Issue a warning and give the user an opportunity to abandon out
893 ** if a Unicode (UTF-16) byte-order-mark (BOM) or a \r\n line ending
894 ** is seen in a text file.
 
 
 
 
895 */
896 static void commit_warning(
897 const Blob *p, /* The content of the file being committed. */
898 int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */
899 int binOk, /* Non-zero if binary warnings should be disabled. */
900 const char *zFilename /* The full name of the file being committed. */
901 ){
902 int eType; /* return value of looks_like_utf8/utf16() */
@@ -903,50 +907,74 @@
903 int fUnicode; /* return value of starts_with_utf16_bom() */
904 char *zMsg; /* Warning message */
905 Blob fname; /* Relative pathname of the file */
906 static int allOk = 0; /* Set to true to disable this routine */
907
908 if( allOk ) return;
909 fUnicode = starts_with_utf16_bom(p);
910 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
911 if( eType==0 || eType==-1 || fUnicode ){
912 const char *zWarning;
 
913 Blob ans;
914 char cReply;
915
916 if( eType==-1 && fUnicode ){
917 zWarning = "Unicode and CR/NL line endings";
918 }else if( eType==-1 ){
919 if( crnlOk ){
920 return; /* We don't want CR/NL warnings for this file. */
921 }
922 zWarning = "CR/NL line endings";
923 }else if( eType==0 ){
924 if( binOk ){
925 return; /* We don't want binary warnings for this file. */
926 }
927 zWarning = "binary data";
928 }else{
929 zWarning = "Unicode";
 
 
 
930 }
931 file_relative_name(zFilename, &fname, 0);
932 blob_zero(&ans);
933 zMsg = mprintf(
934 "%s contains %s. commit anyhow (a=all/y/N)? ",
935 blob_str(&fname), zWarning);
936 prompt_user(zMsg, &ans);
937 fossil_free(zMsg);
938 cReply = blob_str(&ans)[0];
939 if( cReply=='a' || cReply=='A' ){
940 allOk = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
941 }else if( cReply!='y' && cReply!='Y' ){
942 fossil_fatal("Abandoning commit due to %s in %s",
943 zWarning, blob_str(&fname));
944 }
945 blob_reset(&ans);
946 blob_reset(&fname);
947 }
 
948 }
949
950 /*
951 ** qsort() comparison routine for an array of pointers to strings.
952 */
@@ -1044,10 +1072,11 @@
1044 Blob cksum1, cksum2; /* Before and after commit checksums */
1045 Blob cksum1b; /* Checksum recorded in the manifest */
1046 int szD; /* Size of the delta manifest */
1047 int szB; /* Size of the baseline manifest */
1048 int nConflict = 0; /* Number of unresolved merge conflicts */
 
1049 Blob ans;
1050 char cReply;
1051
1052 url_proxy_options();
1053 noSign = find_option("nosign",0,0)!=0;
@@ -1278,11 +1307,11 @@
1278 /* Instead of file content, put link destination path */
1279 blob_read_link(&content, zFullname);
1280 }else{
1281 blob_read_from_file(&content, zFullname);
1282 }
1283 commit_warning(&content, crnlOk, binOk, zFullname);
1284 if( chnged==1 && contains_merge_marker(&content) ){
1285 Blob fname; /* Relative pathname of the file */
1286
1287 nConflict++;
1288 file_relative_name(zFullname, &fname, 0);
@@ -1299,10 +1328,12 @@
1299 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
1300 }
1301 db_finalize(&q);
1302 if( nConflict && !allowConflict ){
1303 fossil_fatal("abort due to unresolve merge conflicts");
 
 
1304 }
1305
1306 /* Create the new manifest */
1307 if( blob_size(&comment)==0 ){
1308 blob_append(&comment, "(no comment)", -1);
1309
--- src/checkin.c
+++ src/checkin.c
@@ -890,13 +890,17 @@
890
891 /*
892 ** Issue a warning and give the user an opportunity to abandon out
893 ** if a Unicode (UTF-16) byte-order-mark (BOM) or a \r\n line ending
894 ** is seen in a text file.
895 **
896 ** Return 1 if the user pressed 'c'. In that case, the file will have
897 ** been converted to UTF-8 (if it was UTF-16) with NL line-endings,
898 ** and the original file will have been renamed to "<filename>-original".
899 */
900 static int commit_warning(
901 Blob *p, /* The content of the file being committed. */
902 int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */
903 int binOk, /* Non-zero if binary warnings should be disabled. */
904 const char *zFilename /* The full name of the file being committed. */
905 ){
906 int eType; /* return value of looks_like_utf8/utf16() */
@@ -903,50 +907,74 @@
907 int fUnicode; /* return value of starts_with_utf16_bom() */
908 char *zMsg; /* Warning message */
909 Blob fname; /* Relative pathname of the file */
910 static int allOk = 0; /* Set to true to disable this routine */
911
912 if( allOk ) return 0;
913 fUnicode = starts_with_utf16_bom(p);
914 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
915 if( eType==0 || eType==-1 || fUnicode ){
916 const char *zWarning;
917 const char *c = "c=convert/";
918 Blob ans;
919 char cReply;
920
921 if( eType==-1 && fUnicode ){
922 zWarning = "Unicode and CR/NL line endings";
923 }else if( eType==-1 ){
924 if( crnlOk ){
925 return 0; /* We don't want CR/NL warnings for this file. */
926 }
927 zWarning = "CR/NL line endings";
928 }else if( eType==0 ){
929 if( binOk ){
930 return 0; /* We don't want binary warnings for this file. */
931 }
932 zWarning = "binary data";
933 }else{
934 zWarning = "Unicode";
935 #ifndef _WIN32
936 c = ""; /* On UNIX, we cannot convert unicode files */
937 #endif
938 }
939 file_relative_name(zFilename, &fname, 0);
940 blob_zero(&ans);
941 zMsg = mprintf(
942 "%s contains %s. commit anyhow (a=all/%sy/N)? ",
943 blob_str(&fname), zWarning, c);
944 prompt_user(zMsg, &ans);
945 fossil_free(zMsg);
946 cReply = blob_str(&ans)[0];
947 if( cReply=='a' || cReply=='A' ){
948 allOk = 1;
949 }else if( (cReply=='c' || cReply=='C')
950 #ifndef _WIN32
951 && fUnicode
952 #endif
953 ){
954 char *zOrig = file_newname(zFilename, "original", 1);
955 FILE *f;
956 blob_write_to_file(p, zOrig);
957 fossil_free(zOrig);
958 f = fossil_fopen(zFilename, "wb");
959 if( fUnicode ) {
960 static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
961 fwrite(bom, 1, 3, f);
962 blob_strip_bom(p, 0);
963 }
964 blob_remove_cr(p);
965 fwrite(blob_buffer(p), 1, blob_size(p), f);
966 fclose(f);
967 return 1;
968 }else if( cReply!='y' && cReply!='Y' ){
969 fossil_fatal("Abandoning commit due to %s in %s",
970 zWarning, blob_str(&fname));
971 }
972 blob_reset(&ans);
973 blob_reset(&fname);
974 }
975 return 0;
976 }
977
978 /*
979 ** qsort() comparison routine for an array of pointers to strings.
980 */
@@ -1044,10 +1072,11 @@
1072 Blob cksum1, cksum2; /* Before and after commit checksums */
1073 Blob cksum1b; /* Checksum recorded in the manifest */
1074 int szD; /* Size of the delta manifest */
1075 int szB; /* Size of the baseline manifest */
1076 int nConflict = 0; /* Number of unresolved merge conflicts */
1077 int abortCommit = 0;
1078 Blob ans;
1079 char cReply;
1080
1081 url_proxy_options();
1082 noSign = find_option("nosign",0,0)!=0;
@@ -1278,11 +1307,11 @@
1307 /* Instead of file content, put link destination path */
1308 blob_read_link(&content, zFullname);
1309 }else{
1310 blob_read_from_file(&content, zFullname);
1311 }
1312 abortCommit |= commit_warning(&content, crnlOk, binOk, zFullname);
1313 if( chnged==1 && contains_merge_marker(&content) ){
1314 Blob fname; /* Relative pathname of the file */
1315
1316 nConflict++;
1317 file_relative_name(zFullname, &fname, 0);
@@ -1299,10 +1328,12 @@
1328 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
1329 }
1330 db_finalize(&q);
1331 if( nConflict && !allowConflict ){
1332 fossil_fatal("abort due to unresolve merge conflicts");
1333 } else if( abortCommit ){
1334 fossil_fatal("files are converted on your request. Please re-test before committing");
1335 }
1336
1337 /* Create the new manifest */
1338 if( blob_size(&comment)==0 ){
1339 blob_append(&comment, "(no comment)", -1);
1340

Keyboard Shortcuts

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