Index: auto.def ================================================================== --- auto.def +++ auto.def @@ -5,10 +5,12 @@ options { with-openssl:path|auto|none => {Look for OpenSSL in the given path, or auto or none} with-miniz=0 => {Use miniz from the source tree} with-zlib:path => {Look for zlib in the given path} + with-exec-rel-paths=0 + => {Enable relative paths for external diff/gdiff} with-legacy-mv-rm=0 => {Enable legacy behavior for mv/rm (skip checkout files)} with-th1-docs=0 => {Enable TH1 for embedded documentation pages} with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages} with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism} @@ -91,10 +93,16 @@ if {[opt-bool with-legacy-mv-rm]} { define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_LEGACY_MV_RM define FOSSIL_ENABLE_LEGACY_MV_RM msg-result "Legacy mv/rm support enabled" } + +if {[opt-bool with-exec-rel-paths]} { + define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_EXEC_REL_PATHS + define FOSSIL_ENABLE_EXEC_REL_PATHS + msg-result "Relative paths in external diff/gdiff enabled" +} if {[opt-bool with-th1-docs]} { define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_TH1_DOCS define FOSSIL_ENABLE_TH1_DOCS msg-result "TH1 embedded documentation support enabled" @@ -156,20 +164,45 @@ } else { set libs "$tclconfig(TCL_LIB_SPEC) $tclconfig(TCL_LIBS)" } set cflags $tclconfig(TCL_INCLUDE_SPEC) if {!$tclprivatestubs} { + set foundtcl 0; # Did we find a working Tcl library? cc-with [list -cflags $cflags -libs $libs] { if {$tclstubs} { - if {![cc-check-functions Tcl_InitStubs]} { - user-error "Cannot find a usable Tcl stubs library $msg" + if {[cc-check-functions Tcl_InitStubs]} { + set foundtcl 1 } } else { - if {![cc-check-functions Tcl_CreateInterp]} { - user-error "Cannot find a usable Tcl library $msg" + if {[cc-check-functions Tcl_CreateInterp]} { + set foundtcl 1 + } + } + } + if {!$foundtcl && [string match *-lieee* $libs]} { + # On some systems, using "-lieee" from TCL_LIB_SPEC appears + # to cause issues. + msg-result "Removing \"-lieee\" and retrying for Tcl..." + set libs [string map [list -lieee ""] $libs] + cc-with [list -cflags $cflags -libs $libs] { + if {$tclstubs} { + if {[cc-check-functions Tcl_InitStubs]} { + set foundtcl 1 + } + } else { + if {[cc-check-functions Tcl_CreateInterp]} { + set foundtcl 1 + } } } + } + if {!$foundtcl} { + if {$tclstubs} { + user-error "Cannot find a usable Tcl stubs library $msg" + } else { + user-error "Cannot find a usable Tcl library $msg" + } } } set version $tclconfig(TCL_VERSION)$tclconfig(TCL_PATCH_LEVEL) msg-result "Found Tcl $version at $tclconfig(TCL_PREFIX)" if {!$tclprivatestubs} { Index: src/bisect.c ================================================================== --- src/bisect.c +++ src/bisect.c @@ -177,16 +177,17 @@ static void bisect_chart(int sortByCkinTime){ char *zLog = db_lget("bisect-log",""); Blob log, id; Stmt q; int cnt = 0; + int iCurrent = db_lget_int("checkout",0); blob_init(&log, zLog, -1); db_multi_exec( "CREATE TEMP TABLE bilog(" " seq INTEGER PRIMARY KEY," /* Sequence of events */ " stat TEXT," /* Type of occurrence */ - " rid INTEGER" /* Check-in number */ + " rid INTEGER UNIQUE" /* Check-in number */ ");" ); db_prepare(&q, "INSERT OR IGNORE INTO bilog(seq,stat,rid)" " VALUES(:seq,:stat,:rid)"); while( blob_token(&log, &id) ){ @@ -197,28 +198,31 @@ db_step(&q); db_reset(&q); } db_bind_int(&q, ":seq", ++cnt); db_bind_text(&q, ":stat", "CURRENT"); - db_bind_int(&q, ":rid", db_lget_int("checkout", 0)); + db_bind_int(&q, ":rid", iCurrent); db_step(&q); db_finalize(&q); db_prepare(&q, "SELECT bilog.seq, bilog.stat," - " substr(blob.uuid,1,16), datetime(event.mtime)" + " substr(blob.uuid,1,16), datetime(event.mtime)," + " blob.rid==%d" " FROM bilog, blob, event" " WHERE blob.rid=bilog.rid AND event.objid=bilog.rid" " AND event.type='ci'" " ORDER BY %s bilog.rowid ASC", - (sortByCkinTime ? "event.mtime DESC, " : "") + iCurrent, (sortByCkinTime ? "event.mtime DESC, " : "") ); while( db_step(&q)==SQLITE_ROW ){ - fossil_print("%3d %-7s %s %s\n", + const char *zGoodBad = db_column_text(&q, 1); + fossil_print("%3d %-7s %s %s%s\n", db_column_int(&q, 0), - db_column_text(&q, 1), + zGoodBad, db_column_text(&q, 3), - db_column_text(&q, 2)); + db_column_text(&q, 2), + (db_column_int(&q, 4) && zGoodBad[0]!='C') ? " CURRENT" : ""); } db_finalize(&q); } /* Index: src/checkin.c ================================================================== --- src/checkin.c +++ src/checkin.c @@ -2,11 +2,11 @@ ** Copyright (c) 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) - +** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: @@ -62,11 +62,12 @@ zName, filename_collation() ); } db_prepare(&q, - "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0), islink" + "SELECT pathname, deleted, chnged," + " rid, coalesce(origname!=pathname,0), islink" " FROM vfile " " WHERE is_selected(id) %s" " AND (chnged OR deleted OR rid=0 OR pathname!=origname)" " ORDER BY 1 /*scan*/", blob_sql_text(&where) @@ -435,11 +436,12 @@ " ORDER BY %s", vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/ ); }else{ db_prepare(&q, - "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0), islink" + "SELECT pathname, deleted, rid, chnged," + " coalesce(origname!=pathname,0), islink" " FROM vfile %s" " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/ ); } blob_reset(&where); @@ -645,11 +647,11 @@ ** (versionable) clean-glob, ignore-glob, and keep-glob settings. ** Files and subdirectories whose names begin with "." are automatically ** ignored unless the --dotfiles option is used. ** ** The --verily option ignores the keep-glob and ignore-glob settings -** and turns on --force, --dotfiles, and --emptydirs. Use the --verily +** and turns on --dotfiles, and --emptydirs. Use the --verily ** option when you really want to clean up everything. Extreme care ** should be exercised when using the --verily option. ** ** Options: ** --allckouts Check for empty directories within any checkouts @@ -672,13 +674,14 @@ ** argument. Matching files, if any, are removed ** prior to checking for any empty directories; ** therefore, directories that contain only files ** that were removed will be removed as well. ** -f|--force Remove files without prompting. +** -i|--prompt Prompt before removing each file. ** -x|--verily WARNING: Removes everything that is not a managed ** file or the repository itself. This option -** implies the --force, --emptydirs, --dotfiles, and +** implies the --emptydirs, --dotfiles, and ** --disable-undo options. Furthermore, it completely ** disregards the keep-glob and ignore-glob settings. ** However, it does honor the --ignore and --keep ** options. ** --clean WARNING: Never prompt to delete any files matching @@ -700,10 +703,11 @@ */ void clean_cmd(void){ int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; int emptyDirsFlag, dirsOnlyFlag; int disableUndo, noPrompt; + int alwaysPrompt = 0; unsigned scanFlags = 0; int verilyFlag = 0; const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag; Glob *pIgnore, *pKeep, *pClean; int nRoot; @@ -720,10 +724,11 @@ if( !dryRunFlag ){ dryRunFlag = find_option("whatif",0,0)!=0; } disableUndo = find_option("disable-undo",0,0)!=0; noPrompt = find_option("no-prompt",0,0)!=0; + alwaysPrompt = find_option("prompt","i",0)!=0; allFileFlag = allDirFlag = find_option("force","f",0)!=0; dirsOnlyFlag = find_option("dirsonly",0,0)!=0; emptyDirsFlag = find_option("emptydirs","d",0)!=0 || dirsOnlyFlag; if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; @@ -732,17 +737,18 @@ verboseFlag = find_option("verbose","v",0)!=0; zKeepFlag = find_option("keep",0,1); zCleanFlag = find_option("clean",0,1); db_must_be_within_tree(); if( find_option("verily","x",0)!=0 ){ - verilyFlag = allFileFlag = allDirFlag = 1; + verilyFlag = 1; emptyDirsFlag = 1; disableUndo = 1; scanFlags |= SCAN_ALL; zCleanFlag = 0; + noPrompt = 1; } - if( zIgnoreFlag==0 && !verilyFlag ){ + if( zIgnoreFlag==0 ){ zIgnoreFlag = db_get("ignore-glob", 0); } if( zKeepFlag==0 && !verilyFlag ){ zKeepFlag = db_get("keep-glob", 0); } @@ -758,11 +764,12 @@ g.allowSymlinks = 1; /* Find symlinks too */ if( !dirsOnlyFlag ){ Stmt q; Blob repo; if( !dryRunFlag && !disableUndo ) undo_begin(); - locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); + locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, + verilyFlag ? 0 : pIgnore, 0); db_prepare(&q, "SELECT %Q || x FROM sfile" " WHERE x NOT IN (%s)" " ORDER BY 1", g.zLocalRoot, fossil_all_reserved_names(0) @@ -778,27 +785,45 @@ fossil_print("KEPT file \"%s\" not removed (due to --keep" " or \"keep-glob\")\n", zName+nRoot); } continue; } - if( !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ + if( !dryRunFlag && !glob_match(pClean, zName+nRoot) + && !(verilyFlag && glob_match(pIgnore, zName+nRoot)) ){ + char *zPrompt = 0; + char cReply; + Blob ans = empty_blob; int undoRc = UNDO_NONE; - if( !disableUndo ){ + if( alwaysPrompt ){ + zPrompt = mprintf("Remove unmanaged file \"%s\" (a=all/y/N)? ", + zName+nRoot); + prompt_user(zPrompt, &ans); + fossil_free(zPrompt); + cReply = fossil_toupper(blob_str(&ans)[0]); + blob_reset(&ans); + if( cReply=='N' ) continue; + if( cReply=='A' ){ + allFileFlag = 1; + alwaysPrompt = 0; + }else{ + undoRc = UNDO_SAVED_OK; + } + }else if( !disableUndo ){ undoRc = undo_maybe_save(zName+nRoot, UNDO_SIZE_LIMIT); } if( undoRc!=UNDO_SAVED_OK ){ - char cReply; if( allFileFlag ){ cReply = 'Y'; }else if( !noPrompt ){ Blob ans; - char *prompt = mprintf("\nWARNING: Deletion of this file will " - "not be undoable via the 'undo'\n" - " command because %s.\n\n" - "Remove unmanaged file \"%s\" (a=all/y/N)? ", - undo_save_message(undoRc), zName+nRoot); - prompt_user(prompt, &ans); + zPrompt = mprintf("\nWARNING: Deletion of this file will " + "not be undoable via the 'undo'\n" + " command because %s.\n\n" + "Remove unmanaged file \"%s\" (a=all/y/N)? ", + undo_save_message(undoRc), zName+nRoot); + prompt_user(zPrompt, &ans); + fossil_free(zPrompt); cReply = blob_str(&ans)[0]; blob_reset(&ans); }else{ cReply = 'N'; } @@ -811,11 +836,11 @@ } if( dryRunFlag || file_delete(zName)==0 ){ if( verboseFlag || dryRunFlag ){ fossil_print("Removed unmanaged file: %s\n", zName+nRoot); } - }else if( verboseFlag ){ + }else{ fossil_print("Could not remove file: %s\n", zName+nRoot); } } db_finalize(&q); if( !dryRunFlag && !disableUndo ) undo_finish(); @@ -823,12 +848,12 @@ if( emptyDirsFlag ){ Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); Stmt q; Blob root; blob_init(&root, g.zLocalRoot, nRoot - 1); - vfile_dir_scan(&root, blob_size(&root), scanFlags, pIgnore, - pEmptyDirs); + vfile_dir_scan(&root, blob_size(&root), scanFlags, + verilyFlag ? 0 : pIgnore, pEmptyDirs); blob_reset(&root); db_prepare(&q, "SELECT %Q || x FROM dscan_temp" " WHERE x NOT IN (%s) AND y = 0" " ORDER BY 1 DESC", @@ -841,18 +866,20 @@ fossil_print("KEPT directory \"%s\" not removed (due to --keep" " or \"keep-glob\")\n", zName+nRoot); } continue; } - if( !allDirFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ + if( !allDirFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) + && !(verilyFlag && glob_match(pIgnore, zName+nRoot)) ){ char cReply; if( !noPrompt ){ Blob ans; char *prompt = mprintf("Remove empty directory \"%s\" (a=all/y/N)? ", zName+nRoot); prompt_user(prompt, &ans); cReply = blob_str(&ans)[0]; + fossil_free(prompt); blob_reset(&ans); }else{ cReply = 'N'; } if( cReply=='a' || cReply=='A' ){ Index: src/db.c ================================================================== --- src/db.c +++ src/db.c @@ -2247,16 +2247,10 @@ }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){ g.zOpenRevision = db_get("main-branch", "trunk"); } } - if( g.zOpenRevision ){ - /* Since the repository is open and we know the revision now, - ** refresh the allow-symlinks flag. */ - g.allowSymlinks = db_get_boolean("allow-symlinks", 0); - } - #if defined(_WIN32) || defined(__CYGWIN__) # define LOCALDB_NAME "./_FOSSIL_" #else # define LOCALDB_NAME "./.fslckout" #endif @@ -2265,10 +2259,15 @@ "COMMIT; PRAGMA journal_mode=WAL; BEGIN;", #endif (char*)0); db_delete_on_failure(LOCALDB_NAME); db_open_local(0); + if( g.zOpenRevision ){ + /* Since the repository is open and we know the revision now, + ** refresh the allow-symlinks flag. */ + g.allowSymlinks = db_get_boolean("allow-symlinks", 0); + } db_lset("repository", g.argv[2]); db_record_repository_filename(g.argv[2]); db_lset_int("checkout", 0); azNewArgv[0] = g.argv[0]; g.argv = azNewArgv; @@ -2356,11 +2355,15 @@ #endif /* INTERFACE */ const Setting aSetting[] = { { "access-log", 0, 0, 0, 0, "off" }, { "admin-log", 0, 0, 0, 0, "off" }, +#if defined(_WIN32) { "allow-symlinks", 0, 0, 1, 0, "off" }, +#else + { "allow-symlinks", 0, 0, 1, 0, "on" }, +#endif { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, { "auto-hyperlink", 0, 0, 0, 0, "on", }, { "auto-shun", 0, 0, 0, 0, "on" }, { "autosync", 0, 0, 0, 0, "on" }, { "autosync-tries", 0, 16, 0, 0, "1" }, @@ -2380,10 +2383,15 @@ { "dont-push", 0, 0, 0, 0, "off" }, { "dotfiles", 0, 0, 1, 0, "off" }, { "editor", 0, 32, 0, 0, "" }, { "empty-dirs", 0, 40, 1, 0, "" }, { "encoding-glob", 0, 40, 1, 0, "" }, +#if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) + { "exec-rel-paths", 0, 0, 0, 0, "on" }, +#else + { "exec-rel-paths", 0, 0, 0, 0, "off" }, +#endif { "gdiff-command", 0, 40, 0, 0, "gdiff" }, { "gmerge-command", 0, 40, 0, 0, "" }, { "hash-digits", 0, 5, 0, 0, "10" }, { "http-port", 0, 16, 0, 0, "8080" }, { "https-login", 0, 0, 0, 0, "off" }, @@ -2555,10 +2563,13 @@ ** encoding-glob The VALUE is a comma or newline-separated list of GLOB ** (versionable) patterns specifying files that the "commit" command will ** ignore when issuing warnings about text files that may ** use another encoding than ASCII or UTF-8. Set to "*" ** to disable encoding checking. +** +** exec-rel-paths When executing certain external commands (e.g. diff and +** gdiff), use relative paths. ** ** gdiff-command External command to run when performing a graphical ** diff. If undefined, text diff will be used. ** ** gmerge-command A graphical merge conflict resolver command operating Index: src/diffcmd.c ================================================================== --- src/diffcmd.c +++ src/diffcmd.c @@ -32,10 +32,32 @@ /* ** Used when the name for the diff is unknown. */ #define DIFF_NO_NAME "(unknown)" + +/* +** Use the "exec-rel-paths" setting and the --exec-abs-paths and +** --exec-rel-paths command line options to determine whether +** certain external commands are executed using relative paths. +*/ +static int determine_exec_relative_option(int force) +{ + static int relativePaths = -1; + if( force || relativePaths==-1 ){ + int relPathOption = find_option("exec-rel-paths", 0, 0)!=0; + int absPathOption = find_option("exec-abs-paths", 0, 0)!=0; +#if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) + relativePaths = db_get_boolean("exec-rel-paths", 1); +#else + relativePaths = db_get_boolean("exec-rel-paths", 0); +#endif + if( relPathOption ){ relativePaths = 1; } + if( absPathOption ){ relativePaths = 0; } + } + return relativePaths; +} /* ** Print the "Index:" message that patches wants to see at the top of a diff. */ void diff_print_index(const char *zFile, u64 diffFlags){ @@ -384,13 +406,22 @@ int isDeleted = db_column_int(&q, 1); int isChnged = db_column_int(&q,2); int isNew = db_column_int(&q,3); int srcid = db_column_int(&q, 4); int isLink = db_column_int(&q, 5); - char *zToFree = mprintf("%s%s", g.zLocalRoot, zPathname); - const char *zFullName = zToFree; + const char *zFullName; int showDiff = 1; + Blob fname; + + if( determine_exec_relative_option(0) ){ + blob_zero(&fname); + file_relative_name(zPathname, &fname, 1); + }else{ + blob_set(&fname, g.zLocalRoot); + blob_append(&fname, zPathname, -1); + } + zFullName = blob_str(&fname); if( isDeleted ){ fossil_print("DELETED %s\n", zPathname); if( !asNewFile ){ showDiff = 0; zFullName = NULL_DEVICE; } }else if( file_access(zFullName, F_OK) ){ fossil_print("MISSING %s\n", zPathname); @@ -400,10 +431,14 @@ srcid = 0; if( !asNewFile ){ showDiff = 0; } }else if( isChnged==3 ){ fossil_print("ADDED_BY_MERGE %s\n", zPathname); srcid = 0; + if( !asNewFile ){ showDiff = 0; } + }else if( isChnged==5 ){ + fossil_print("ADDED_BY_INTEGRATE %s\n", zPathname); + srcid = 0; if( !asNewFile ){ showDiff = 0; } } if( showDiff ){ Blob content; int isBin; @@ -422,11 +457,11 @@ diff_print_index(zPathname, diffFlags); diff_file(&content, isBin, zFullName, zPathname, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); blob_reset(&content); } - free(zToFree); + blob_reset(&fname); } db_finalize(&q); db_end_transaction(1); /* ROLLBACK */ } @@ -812,10 +847,12 @@ ** --binary PATTERN Treat files that match the glob PATTERN as binary ** --branch BRANCH Show diff of all changes on BRANCH ** --brief Show filenames only ** --context|-c N Use N lines of context ** --diff-binary BOOL Include binary files when using external commands +** --exec-abs-paths Force absolute path names with external commands. +** --exec-rel-paths Force relative path names with external commands. ** --from|-r VERSION select VERSION as source for the diff ** --internal|-i use internal diff logic ** --side-by-side|-y side-by-side diff ** --strip-trailing-cr Strip trailing CR ** --tk Launch a Tcl/Tk GUI for display @@ -876,10 +913,11 @@ if( !isInternDiff ){ zDiffCmd = diff_command_external(isGDiff); } zBinGlob = diff_get_binary_glob(); fIncludeBinary = diff_include_binary_files(); + determine_exec_relative_option(1); verify_all_options(); if( againstUndo ){ if( db_lget_int("undo_available",0)==0 ){ fossil_print("No undo or redo is available\n"); return; Index: src/doc.c ================================================================== --- src/doc.c +++ src/doc.c @@ -160,11 +160,11 @@ { "lha", 3, "application/octet-stream" }, { "lsp", 3, "application/x-lisp" }, { "lzh", 3, "application/octet-stream" }, { "m", 1, "text/plain" }, { "m3u", 3, "audio/x-mpegurl" }, - { "man", 3, "application/x-troff-man" }, + { "man", 3, "text/plain" }, { "markdown", 8, "text/x-markdown" }, { "md", 2, "text/x-markdown" }, { "me", 2, "application/x-troff-me" }, { "mesh", 4, "model/mesh" }, { "mid", 3, "audio/midi" }, @@ -181,10 +181,11 @@ { "mpeg", 4, "video/mpeg" }, { "mpg", 3, "video/mpeg" }, { "mpga", 4, "audio/mpeg" }, { "ms", 2, "application/x-troff-ms" }, { "msh", 3, "model/mesh" }, + { "n", 1, "text/plain" }, { "nc", 2, "application/x-netcdf" }, { "oda", 3, "application/oda" }, { "odp", 3, "application/vnd.oasis.opendocument.presentation" }, { "ods", 3, "application/vnd.oasis.opendocument.spreadsheet" }, { "odt", 3, "application/vnd.oasis.opendocument.text" }, Index: src/json_timeline.c ================================================================== --- src/json_timeline.c +++ src/json_timeline.c @@ -326,11 +326,11 @@ " blob.uuid as uuid," " (SELECT uuid FROM blob WHERE rid=pid) as parent," " blob.size as size" " FROM mlink, blob" " WHERE mid=%d AND pid!=fid" - " AND blob.rid=fid " + " AND blob.rid=fid AND NOT mlink.isaux" " ORDER BY name /*sort*/", rid ); while( (SQLITE_ROW == db_step(&q)) ){ cson_value * rowV = cson_value_new_object(); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -1060,10 +1060,13 @@ #if defined(FOSSIL_ENABLE_SSL) fossil_print("SSL (%s)\n", SSLeay_version(SSLEAY_VERSION)); #endif #if defined(FOSSIL_ENABLE_LEGACY_MV_RM) fossil_print("LEGACY_MV_RM\n"); +#endif +#if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) + fossil_print("EXEC_REL_PATHS\n"); #endif #if defined(FOSSIL_ENABLE_TH1_DOCS) fossil_print("TH1_DOCS\n"); #endif #if defined(FOSSIL_ENABLE_TH1_HOOKS) Index: src/makemake.tcl ================================================================== --- src/makemake.tcl +++ src/makemake.tcl @@ -505,10 +505,14 @@ #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 + +#### Enable relative paths in external diff/gdiff +# +# FOSSIL_ENABLE_EXEC_REL_PATHS = 1 #### Enable legacy treatment of mv/rm (skip checkout files) # # FOSSIL_ENABLE_LEGACY_MV_RM = 1 @@ -710,10 +714,16 @@ # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif + +# With relative paths in external diff/gdiff +ifdef FOSSIL_ENABLE_EXEC_REL_PATHS +TCC += -DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +RCC += -DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +endif # With legacy treatment of mv/rm ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 @@ -1339,10 +1349,15 @@ # Link everything except SQLite dynamically? !ifndef FOSSIL_DYNAMIC_BUILD FOSSIL_DYNAMIC_BUILD = 0 !endif + +# Enable relative paths in external diff/gdiff? +!ifndef FOSSIL_ENABLE_EXEC_REL_PATHS +FOSSIL_ENABLE_EXEC_REL_PATHS = 0 +!endif # Enable the JSON API? !ifndef FOSSIL_ENABLE_JSON FOSSIL_ENABLE_JSON = 0 !endif @@ -1557,10 +1572,15 @@ TCC = $(TCC) /DFOSSIL_ENABLE_SSL=1 RCC = $(RCC) /DFOSSIL_ENABLE_SSL=1 LIBS = $(LIBS) $(SSLLIB) LIBDIR = $(LIBDIR) /LIBPATH:$(SSLLIBDIR) !endif + +!if $(FOSSIL_ENABLE_EXEC_REL_PATHS)!=0 +TCC = $(TCC) /DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +RCC = $(RCC) /DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +!endif !if $(FOSSIL_ENABLE_LEGACY_MV_RM)!=0 TCC = $(TCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC = $(RCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 !endif Index: src/merge.c ================================================================== --- src/merge.c +++ src/merge.c @@ -226,10 +226,16 @@ db_must_be_within_tree(); if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_fatal("nothing is checked out"); + } + if( !dryRunFlag ){ + if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, + db_get_int("autosync-tries", 1)) ){ + fossil_fatal("Cannot proceed with merge"); + } } /* Find mid, the artifactID of the version to be merged into the current ** check-out */ if( g.argc==3 ){ Index: src/rebuild.c ================================================================== --- src/rebuild.c +++ src/rebuild.c @@ -533,10 +533,11 @@ ** --ifneeded Only do the rebuild if it would change the schema version ** --index Always add in the full-text search index ** --noverify Skip the verification of changes to the BLOB table ** --noindex Always omit the full-text search index ** --pagesize N Set the database pagesize to N. (512..65536 and power of 2) +** --quiet Only show output if there are errors ** --randomize Scan artifacts in a random order ** --stats Show artifact statistics after rebuilding ** --vacuum Run VACUUM on the database after rebuilding ** --wal Set Write-Ahead-Log journalling mode on the database ** Index: src/th_main.c ================================================================== --- src/th_main.c +++ src/th_main.c @@ -510,10 +510,32 @@ zOut = htmlize((char*)argv[1], argl[1]); Th_SetResult(interp, zOut, -1); free(zOut); return TH_OK; } + +/* +** TH1 command: encode64 STRING +** +** Encode the specified string using Base64 and return the result. +*/ +static int encode64Cmd( + Th_Interp *interp, + void *p, + int argc, + const char **argv, + int *argl +){ + char *zOut; + if( argc!=2 ){ + return Th_WrongNumArgs(interp, "encode64 STRING"); + } + zOut = encode64((char*)argv[1], argl[1]); + Th_SetResult(interp, zOut, -1); + free(zOut); + return TH_OK; +} /* ** TH1 command: date ** ** Return a string which is the current time and date. If the @@ -631,10 +653,11 @@ ** Return true if the fossil binary has the given compile-time feature ** enabled. The set of features includes: ** ** "ssl" = FOSSIL_ENABLE_SSL ** "legacyMvRm" = FOSSIL_ENABLE_LEGACY_MV_RM +** "execRelPaths" = FOSSIL_ENABLE_EXEC_REL_PATHS ** "th1Docs" = FOSSIL_ENABLE_TH1_DOCS ** "th1Hooks" = FOSSIL_ENABLE_TH1_HOOKS ** "tcl" = FOSSIL_ENABLE_TCL ** "useTclStubs" = USE_TCL_STUBS ** "tclStubs" = FOSSIL_ENABLE_TCL_STUBS @@ -642,10 +665,12 @@ ** "json" = FOSSIL_ENABLE_JSON ** "markdown" = FOSSIL_ENABLE_MARKDOWN ** "unicodeCmdLine" = !BROKEN_MINGW_CMDLINE ** "dynamicBuild" = FOSSIL_DYNAMIC_BUILD ** +** Specifying an unknown feature will return a value of false, it will not +** raise a script error. */ static int hasfeatureCmd( Th_Interp *interp, void *p, int argc, @@ -668,10 +693,15 @@ #endif #if defined(FOSSIL_ENABLE_LEGACY_MV_RM) else if( 0 == fossil_strnicmp( zArg, "legacyMvRm\0", 11 ) ){ rc = 1; } +#endif +#if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) + else if( 0 == fossil_strnicmp( zArg, "execRelPaths\0", 13 ) ){ + rc = 1; + } #endif #if defined(FOSSIL_ENABLE_TH1_DOCS) else if( 0 == fossil_strnicmp( zArg, "th1Docs\0", 8 ) ){ rc = 1; } @@ -1727,10 +1757,11 @@ {"combobox", comboboxCmd, 0}, {"date", dateCmd, 0}, {"decorate", wikiCmd, (void*)&aFlags[2]}, {"dir", dirCmd, 0}, {"enable_output", enableOutputCmd, 0}, + {"encode64", encode64Cmd, 0}, {"getParameter", getParameterCmd, 0}, {"glob_match", globMatchCmd, 0}, {"globalState", globalStateCmd, 0}, {"httpize", httpizeCmd, 0}, {"hascap", hascapCmd, (void*)&zeroInt}, Index: src/th_tcl.c ================================================================== --- src/th_tcl.c +++ src/th_tcl.c @@ -24,10 +24,18 @@ #include "sqlite3.h" #include "th.h" #include "tcl.h" +/* +** This macro is used to verify that the header version of Tcl meets some +** minimum requirement. +*/ +#define MINIMUM_TCL_VERSION(major, minor) \ + ((TCL_MAJOR_VERSION > (major)) || \ + ((TCL_MAJOR_VERSION == (major)) && (TCL_MINOR_VERSION >= (minor)))) + /* ** These macros are designed to reduce the redundant code required to marshal ** arguments from TH1 to Tcl. */ #define USE_ARGV_TO_OBJV() \ @@ -285,17 +293,21 @@ ** Is the loaded version of Tcl one where TIP #285 (asynchronous script ** cancellation) is available? This should return non-zero only for Tcl ** 8.6 and higher. */ static int canUseTip285(){ +#if MINIMUM_TCL_VERSION(8, 6) int major = -1, minor = -1, patchLevel = -1, type = -1; Tcl_GetVersion(&major, &minor, &patchLevel, &type); if( major<0 || minor<0 || patchLevel<0 || type<0 ){ return 0; /* NOTE: Invalid version info, assume bad. */ } return (major>8 || (major==8 && minor>=6)); +#else + return 0; +#endif } /* ** Creates and initializes a Tcl interpreter for use with the specified TH1 ** interpreter. Stores the created Tcl interpreter in the Tcl context supplied @@ -1064,13 +1076,15 @@ Tcl_Preserve((ClientData)tclInterp); while( Tcl_DoOneEvent(flags) ){ if( Tcl_InterpDeleted(tclInterp) ){ break; } +#if MINIMUM_TCL_VERSION(8, 6) if( useTip285 && Tcl_Canceled(tclInterp, 0)!=TCL_OK ){ break; } +#endif } Tcl_Release((ClientData)tclInterp); return rc; } Index: src/timeline.c ================================================================== --- src/timeline.c +++ src/timeline.c @@ -1862,11 +1862,11 @@ " (fid==0) AS isdel," " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name," " (SELECT uuid FROM blob WHERE rid=fid)," " (SELECT uuid FROM blob WHERE rid=pid)" " FROM mlink" - " WHERE mid=:mid AND pid!=fid" + " WHERE mid=:mid AND pid!=fid AND NOT mlink.isaux" " ORDER BY 3 /*sort*/" ); fchngQueryInit = 1; } db_bind_int(&fchngQuery, ":mid", rid); Index: test/th1.test ================================================================== --- test/th1.test +++ test/th1.test @@ -861,13 +861,13 @@ # NOTE: This test may fail if the command names do not always come # out in a deterministic order from TH1. # fossil test-th-eval "info commands" test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\ -enable_output uplevel dir http expr glob_match utime styleFooter catch if\ -tclReady searchable reinitialize combobox lindex query html anoncap randhex\ -llength for set break regexp markdown styleHeader puts return checkout\ +enable_output uplevel dir http expr glob_match utime styleFooter encode64\ +catch if tclReady searchable reinitialize combobox lindex query html anoncap\ +randhex llength for set break regexp markdown styleHeader puts return checkout\ decorate artifact trace wiki proc hascap globalState continue getParameter\ hasfeature setting lsearch breakpoint upvar render repository string unset\ setParameter list error info rename anycap httpize}} ############################################################################### @@ -1245,5 +1245,27 @@

Other Features

Text can show emphasis or emphasis or strong emphassis.

}}} + +############################################################################### + +fossil test-th-eval {encode64 test} +test th1-encode64-1 {$RESULT eq "dGVzdA=="} + +############################################################################### + +fossil test-th-eval {encode64 test\x00} +test th1-encode64-2 {$RESULT eq "dGVzdAA="} + +############################################################################### + +# +# TODO: Modify the result of this test if the source file (i.e. +# "ajax/cgi-bin/fossil-json.cgi.example") changes. +# +fossil test-th-eval --open-config \ + {encode64 [artifact trunk ajax/cgi-bin/fossil-json.cgi.example]} + +test th1-encode64-3 {$RESULT eq \ +"IyEvcGF0aC90by9mb3NzaWwvYmluYXJ5CnJlcG9zaXRvcnk6IC9wYXRoL3RvL3JlcG8uZnNsCg=="} Index: win/Makefile.mingw ================================================================== --- win/Makefile.mingw +++ win/Makefile.mingw @@ -56,10 +56,14 @@ #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 + +#### Enable relative paths in external diff/gdiff +# +# FOSSIL_ENABLE_EXEC_REL_PATHS = 1 #### Enable legacy treatment of mv/rm (skip checkout files) # # FOSSIL_ENABLE_LEGACY_MV_RM = 1 @@ -261,10 +265,16 @@ # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif + +# With relative paths in external diff/gdiff +ifdef FOSSIL_ENABLE_EXEC_REL_PATHS +TCC += -DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +RCC += -DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +endif # With legacy treatment of mv/rm ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 Index: win/Makefile.mingw.mistachkin ================================================================== --- win/Makefile.mingw.mistachkin +++ win/Makefile.mingw.mistachkin @@ -56,10 +56,14 @@ #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 + +#### Enable relative paths in external diff/gdiff +# +# FOSSIL_ENABLE_EXEC_REL_PATHS = 1 #### Enable legacy treatment of mv/rm (skip checkout files) # FOSSIL_ENABLE_LEGACY_MV_RM = 1 @@ -261,10 +265,16 @@ # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif + +# With relative paths in external diff/gdiff +ifdef FOSSIL_ENABLE_EXEC_REL_PATHS +TCC += -DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +RCC += -DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +endif # With legacy treatment of mv/rm ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 Index: win/Makefile.msc ================================================================== --- win/Makefile.msc +++ win/Makefile.msc @@ -46,10 +46,15 @@ # Link everything except SQLite dynamically? !ifndef FOSSIL_DYNAMIC_BUILD FOSSIL_DYNAMIC_BUILD = 0 !endif + +# Enable relative paths in external diff/gdiff? +!ifndef FOSSIL_ENABLE_EXEC_REL_PATHS +FOSSIL_ENABLE_EXEC_REL_PATHS = 0 +!endif # Enable the JSON API? !ifndef FOSSIL_ENABLE_JSON FOSSIL_ENABLE_JSON = 0 !endif @@ -264,10 +269,15 @@ TCC = $(TCC) /DFOSSIL_ENABLE_SSL=1 RCC = $(RCC) /DFOSSIL_ENABLE_SSL=1 LIBS = $(LIBS) $(SSLLIB) LIBDIR = $(LIBDIR) /LIBPATH:$(SSLLIBDIR) !endif + +!if $(FOSSIL_ENABLE_EXEC_REL_PATHS)!=0 +TCC = $(TCC) /DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +RCC = $(RCC) /DFOSSIL_ENABLE_EXEC_REL_PATHS=1 +!endif !if $(FOSSIL_ENABLE_LEGACY_MV_RM)!=0 TCC = $(TCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC = $(RCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 !endif Index: win/fossil.rc ================================================================== --- win/fossil.rc +++ win/fossil.rc @@ -125,10 +125,15 @@ #if defined(FOSSIL_ENABLE_LEGACY_MV_RM) VALUE "LegacyMvRm", "Yes\0" #else VALUE "LegacyMvRm", "No\0" #endif /* defined(FOSSIL_ENABLE_LEGACY_MV_RM) */ +#if defined(FOSSIL_ENABLE_EXEC_REL_PATHS) + VALUE "ExecRelPaths", "Yes\0" +#else + VALUE "ExecRelPaths", "No\0" +#endif /* defined(FOSSIL_ENABLE_EXEC_REL_PATHS) */ #if defined(FOSSIL_ENABLE_TH1_DOCS) VALUE "Th1Docs", "Yes\0" #else VALUE "Th1Docs", "No\0" #endif /* defined(FOSSIL_ENABLE_TH1_DOCS) */ Index: www/changes.wiki ================================================================== --- www/changes.wiki +++ www/changes.wiki @@ -1,11 +1,9 @@ Change Log -

Changes for Version 1.34 (2015-??-??)

+

Changes for Version 1.34 (2015-11-02)

- * Fix --hard option to [/help?cmd=mv|fossil mv] and [/help?cmd=rm|fossil rm] - to enable them to work properly with certain relative paths. * Make the [/help?cmd=clean|fossil clean] command undoable for files less than 10MiB. * Update internal Unicode character tables, used in regular expression handling, from version 7.0 to 8.0. * Add the new [/help?cmd=amend|amend] command which is used to modify @@ -12,24 +10,30 @@ tags of a "check-in". * Fix bug in [/help?cmd=import|import] command, handling version 3 of the svndump format for subversion. * Add the [/help?cmd=all|all cache] command. * TH1 enhancements: -