Index: src/checkin.c ================================================================== --- src/checkin.c +++ src/checkin.c @@ -886,13 +886,17 @@ /* ** Issue a warning and give the user an opportunity to abandon out ** if a Unicode (UTF-16) byte-order-mark (BOM) or a \r\n line ending ** is seen in a text file. +** +** Return 1 if the user pressed 'c'. In that case, the file will have +** been converted to UTF-8 (if it was UTF-16) with NL line-endings, +** and the original file will have been renamed to "-original". */ -static void commit_warning( - const Blob *p, /* The content of the file being committed. */ +static int commit_warning( + Blob *p, /* The content of the file being committed. */ int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */ int binOk, /* Non-zero if binary warnings should be disabled. */ const char *zFilename /* The full name of the file being committed. */ ){ int eType; /* return value of looks_like_utf8/utf16() */ @@ -899,50 +903,71 @@ int fUnicode; /* return value of starts_with_utf16_bom() */ char *zMsg; /* Warning message */ Blob fname; /* Relative pathname of the file */ static int allOk = 0; /* Set to true to disable this routine */ - if( allOk ) return; + if( allOk ) return 0; fUnicode = starts_with_utf16_bom(p); eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p); if( eType==0 || eType==-1 || fUnicode ){ const char *zWarning; + const char *c = "c=convert/"; Blob ans; char cReply; if( eType==-1 && fUnicode ){ zWarning = "Unicode and CR/NL line endings"; }else if( eType==-1 ){ if( crnlOk ){ - return; /* We don't want CR/NL warnings for this file. */ + return 0; /* We don't want CR/NL warnings for this file. */ } zWarning = "CR/NL line endings"; }else if( eType==0 ){ if( binOk ){ - return; /* We don't want binary warnings for this file. */ + return 0; /* We don't want binary warnings for this file. */ } zWarning = "binary data"; + c = ""; /* We cannot automatically convert binary files */ }else{ zWarning = "Unicode"; +#ifndef _WIN32 + c = ""; /* On UNIX, we cannot automatically convert unicode files */ +#endif } file_relative_name(zFilename, &fname, 0); blob_zero(&ans); zMsg = mprintf( - "%s contains %s. commit anyhow (a=all/y/N)? ", - blob_str(&fname), zWarning); + "%s contains %s. commit anyhow (a=all/%sy/N)? ", + blob_str(&fname), zWarning, c); prompt_user(zMsg, &ans); fossil_free(zMsg); cReply = blob_str(&ans)[0]; if( cReply=='a' || cReply=='A' ){ allOk = 1; + }else if( (c[0] != 0) && (cReply=='c' || cReply=='C') ){ + char *zOrig = file_newname(zFilename, "original", 1); + FILE *f; + blob_write_to_file(p, zOrig); + fossil_free(zOrig); + f = fossil_fopen(zFilename, "wb"); + if( fUnicode ) { + static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF }; + fwrite(bom, 1, 3, f); + blob_strip_bom(p, 0); + } + blob_remove_cr(p); + fwrite(blob_buffer(p), 1, blob_size(p), f); + fclose(f); + return 1; }else if( cReply!='y' && cReply!='Y' ){ fossil_fatal("Abandoning commit due to %s in %s", zWarning, blob_str(&fname)); } blob_reset(&ans); blob_reset(&fname); } + return 0; } /* ** qsort() comparison routine for an array of pointers to strings. */ @@ -1042,10 +1067,11 @@ Blob cksum1, cksum2; /* Before and after commit checksums */ Blob cksum1b; /* Checksum recorded in the manifest */ int szD; /* Size of the delta manifest */ int szB; /* Size of the baseline manifest */ int nConflict = 0; /* Number of unresolved merge conflicts */ + int abortCommit = 0; Blob ans; char cReply; url_proxy_options(); noSign = find_option("nosign",0,0)!=0; @@ -1277,11 +1303,11 @@ /* Instead of file content, put link destination path */ blob_read_link(&content, zFullname); }else{ blob_read_from_file(&content, zFullname); } - commit_warning(&content, crnlOk, binOk, zFullname); + abortCommit |= commit_warning(&content, crnlOk, binOk, zFullname); if( chnged==1 && contains_merge_marker(&content) ){ Blob fname; /* Relative pathname of the file */ nConflict++; file_relative_name(zFullname, &fname, 0); @@ -1298,10 +1324,12 @@ db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); } db_finalize(&q); if( nConflict && !allowConflict ){ fossil_fatal("abort due to unresolve merge conflicts"); + } else if( abortCommit ){ + fossil_fatal("files are converted on your request. Please re-test before committing"); } /* Create the new manifest */ if( blob_size(&comment)==0 ){ blob_append(&comment, "(no comment)", -1);