Fossil SCM
Merge recent trunk changes into the retro-sbsdiff branch.
Commit
066adeedfe9e688defd660873261e609d05cbccb
Parent
30478e4e7e01b99…
11 files changed
+5
-7
+8
+1
-1
+48
-5
+6
-3
+17
-29
+1
+1
-5
+13
-7
+12
-1
+19
-21
+5
-7
| --- debian/makedeb.sh | ||
| +++ debian/makedeb.sh | ||
| @@ -1,21 +1,19 @@ | ||
| 1 | 1 | #!/bin/bash |
| 2 | 2 | # A quick hack to generate a Debian package of fossil. i took most of this |
| 3 | 3 | # from Martin Krafft's "The Debian System" book. |
| 4 | 4 | |
| 5 | 5 | DEB_REV=${1-1} # .deb package build/revision number. |
| 6 | -PACKAGE_DEBNAME=fossil-scm | |
| 6 | +PACKAGE_DEBNAME=fossil | |
| 7 | 7 | THISDIR=${PWD} |
| 8 | 8 | |
| 9 | 9 | if uname -a | grep -i nexenta &>/dev/null; then |
| 10 | 10 | # Assume NexentaOS/GnuSolaris: |
| 11 | - DEB_PLATFORM=nexenta | |
| 12 | 11 | DEB_ARCH_NAME=solaris-i386 |
| 13 | 12 | DEB_ARCH_PKGDEPENDS="sunwcsl" # for -lsocket |
| 14 | 13 | else |
| 15 | - DEB_PLATFORM=${DEB_PLATFORM-ubuntu-gutsy} | |
| 16 | - DEB_ARCH_NAME=i386 | |
| 14 | + DEB_ARCH_NAME=$(dpkg --print-architecture) | |
| 17 | 15 | fi |
| 18 | 16 | |
| 19 | 17 | SRCDIR=$(cd ..; pwd) |
| 20 | 18 | test -e ${SRCDIR}/fossil || { |
| 21 | 19 | echo "This script must be run from a BUILT copy of the source tree." |
| @@ -41,11 +39,11 @@ | ||
| 41 | 39 | rm -fr DEBIAN |
| 42 | 40 | mkdir DEBIAN |
| 43 | 41 | |
| 44 | 42 | PACKAGE_VERSION=$(date +%Y.%m.%d) |
| 45 | 43 | PACKAGE_DEB_VERSION=${PACKAGE_VERSION}-${DEB_REV} |
| 46 | -DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}-dev-${DEB_ARCH_NAME}-${DEB_PLATFORM}.deb | |
| 44 | +DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}-dev-${DEB_ARCH_NAME}.deb | |
| 47 | 45 | PACKAGE_TIME=$(/bin/date) |
| 48 | 46 | |
| 49 | 47 | rm -f ${DEBFILE} |
| 50 | 48 | echo "Creating .deb package [${DEBFILE}]..." |
| 51 | 49 | |
| @@ -87,15 +85,15 @@ | ||
| 87 | 85 | true && { |
| 88 | 86 | CONTROL=DEBIAN/control |
| 89 | 87 | echo "Generating ${CONTROL}..." |
| 90 | 88 | cat <<EOF > ${CONTROL} |
| 91 | 89 | Package: ${PACKAGE_DEBNAME} |
| 92 | -Section: devel | |
| 90 | +Section: vcs | |
| 93 | 91 | Priority: optional |
| 94 | 92 | Maintainer: stephan beal <[email protected]> |
| 95 | 93 | Architecture: ${DEB_ARCH_NAME} |
| 96 | -Depends: libc6-dev ${DEB_ARCH_PKGDEPENDS+, }${DEB_ARCH_PKGDEPENDS} | |
| 94 | +Depends: libc6 ${DEB_ARCH_PKGDEPENDS+, }${DEB_ARCH_PKGDEPENDS} | |
| 97 | 95 | Version: ${PACKAGE_DEB_VERSION} |
| 98 | 96 | Description: Fossil is a unique SCM (Software Configuration Management) system. |
| 99 | 97 | This package contains the Fossil binary for *buntu/Debian systems. |
| 100 | 98 | Fossil is a unique SCM program which supports distributed source control |
| 101 | 99 | management using local repositories, access over HTTP CGI, or using the |
| 102 | 100 |
| --- debian/makedeb.sh | |
| +++ debian/makedeb.sh | |
| @@ -1,21 +1,19 @@ | |
| 1 | #!/bin/bash |
| 2 | # A quick hack to generate a Debian package of fossil. i took most of this |
| 3 | # from Martin Krafft's "The Debian System" book. |
| 4 | |
| 5 | DEB_REV=${1-1} # .deb package build/revision number. |
| 6 | PACKAGE_DEBNAME=fossil-scm |
| 7 | THISDIR=${PWD} |
| 8 | |
| 9 | if uname -a | grep -i nexenta &>/dev/null; then |
| 10 | # Assume NexentaOS/GnuSolaris: |
| 11 | DEB_PLATFORM=nexenta |
| 12 | DEB_ARCH_NAME=solaris-i386 |
| 13 | DEB_ARCH_PKGDEPENDS="sunwcsl" # for -lsocket |
| 14 | else |
| 15 | DEB_PLATFORM=${DEB_PLATFORM-ubuntu-gutsy} |
| 16 | DEB_ARCH_NAME=i386 |
| 17 | fi |
| 18 | |
| 19 | SRCDIR=$(cd ..; pwd) |
| 20 | test -e ${SRCDIR}/fossil || { |
| 21 | echo "This script must be run from a BUILT copy of the source tree." |
| @@ -41,11 +39,11 @@ | |
| 41 | rm -fr DEBIAN |
| 42 | mkdir DEBIAN |
| 43 | |
| 44 | PACKAGE_VERSION=$(date +%Y.%m.%d) |
| 45 | PACKAGE_DEB_VERSION=${PACKAGE_VERSION}-${DEB_REV} |
| 46 | DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}-dev-${DEB_ARCH_NAME}-${DEB_PLATFORM}.deb |
| 47 | PACKAGE_TIME=$(/bin/date) |
| 48 | |
| 49 | rm -f ${DEBFILE} |
| 50 | echo "Creating .deb package [${DEBFILE}]..." |
| 51 | |
| @@ -87,15 +85,15 @@ | |
| 87 | true && { |
| 88 | CONTROL=DEBIAN/control |
| 89 | echo "Generating ${CONTROL}..." |
| 90 | cat <<EOF > ${CONTROL} |
| 91 | Package: ${PACKAGE_DEBNAME} |
| 92 | Section: devel |
| 93 | Priority: optional |
| 94 | Maintainer: stephan beal <[email protected]> |
| 95 | Architecture: ${DEB_ARCH_NAME} |
| 96 | Depends: libc6-dev ${DEB_ARCH_PKGDEPENDS+, }${DEB_ARCH_PKGDEPENDS} |
| 97 | Version: ${PACKAGE_DEB_VERSION} |
| 98 | Description: Fossil is a unique SCM (Software Configuration Management) system. |
| 99 | This package contains the Fossil binary for *buntu/Debian systems. |
| 100 | Fossil is a unique SCM program which supports distributed source control |
| 101 | management using local repositories, access over HTTP CGI, or using the |
| 102 |
| --- debian/makedeb.sh | |
| +++ debian/makedeb.sh | |
| @@ -1,21 +1,19 @@ | |
| 1 | #!/bin/bash |
| 2 | # A quick hack to generate a Debian package of fossil. i took most of this |
| 3 | # from Martin Krafft's "The Debian System" book. |
| 4 | |
| 5 | DEB_REV=${1-1} # .deb package build/revision number. |
| 6 | PACKAGE_DEBNAME=fossil |
| 7 | THISDIR=${PWD} |
| 8 | |
| 9 | if uname -a | grep -i nexenta &>/dev/null; then |
| 10 | # Assume NexentaOS/GnuSolaris: |
| 11 | DEB_ARCH_NAME=solaris-i386 |
| 12 | DEB_ARCH_PKGDEPENDS="sunwcsl" # for -lsocket |
| 13 | else |
| 14 | DEB_ARCH_NAME=$(dpkg --print-architecture) |
| 15 | fi |
| 16 | |
| 17 | SRCDIR=$(cd ..; pwd) |
| 18 | test -e ${SRCDIR}/fossil || { |
| 19 | echo "This script must be run from a BUILT copy of the source tree." |
| @@ -41,11 +39,11 @@ | |
| 39 | rm -fr DEBIAN |
| 40 | mkdir DEBIAN |
| 41 | |
| 42 | PACKAGE_VERSION=$(date +%Y.%m.%d) |
| 43 | PACKAGE_DEB_VERSION=${PACKAGE_VERSION}-${DEB_REV} |
| 44 | DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}-dev-${DEB_ARCH_NAME}.deb |
| 45 | PACKAGE_TIME=$(/bin/date) |
| 46 | |
| 47 | rm -f ${DEBFILE} |
| 48 | echo "Creating .deb package [${DEBFILE}]..." |
| 49 | |
| @@ -87,15 +85,15 @@ | |
| 85 | true && { |
| 86 | CONTROL=DEBIAN/control |
| 87 | echo "Generating ${CONTROL}..." |
| 88 | cat <<EOF > ${CONTROL} |
| 89 | Package: ${PACKAGE_DEBNAME} |
| 90 | Section: vcs |
| 91 | Priority: optional |
| 92 | Maintainer: stephan beal <[email protected]> |
| 93 | Architecture: ${DEB_ARCH_NAME} |
| 94 | Depends: libc6 ${DEB_ARCH_PKGDEPENDS+, }${DEB_ARCH_PKGDEPENDS} |
| 95 | Version: ${PACKAGE_DEB_VERSION} |
| 96 | Description: Fossil is a unique SCM (Software Configuration Management) system. |
| 97 | This package contains the Fossil binary for *buntu/Debian systems. |
| 98 | Fossil is a unique SCM program which supports distributed source control |
| 99 | management using local repositories, access over HTTP CGI, or using the |
| 100 |
+8
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -44,10 +44,18 @@ | ||
| 44 | 44 | static const char *azName[] = { |
| 45 | 45 | "_FOSSIL_", |
| 46 | 46 | "_FOSSIL_-journal", |
| 47 | 47 | "_FOSSIL_-wal", |
| 48 | 48 | "_FOSSIL_-shm", |
| 49 | + ".fslckout", | |
| 50 | + ".fslckout-journal", | |
| 51 | + ".fslckout-wal", | |
| 52 | + ".fslckout-shm", | |
| 53 | + | |
| 54 | + /* The use of ".fos" as the name of the checkout database is | |
| 55 | + ** deprecated. Use ".fslckout" instead. At some point, the following | |
| 56 | + ** entries should be removed. 2012-02-04 */ | |
| 49 | 57 | ".fos", |
| 50 | 58 | ".fos-journal", |
| 51 | 59 | ".fos-wal", |
| 52 | 60 | ".fos-shm", |
| 53 | 61 | }; |
| 54 | 62 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -44,10 +44,18 @@ | |
| 44 | static const char *azName[] = { |
| 45 | "_FOSSIL_", |
| 46 | "_FOSSIL_-journal", |
| 47 | "_FOSSIL_-wal", |
| 48 | "_FOSSIL_-shm", |
| 49 | ".fos", |
| 50 | ".fos-journal", |
| 51 | ".fos-wal", |
| 52 | ".fos-shm", |
| 53 | }; |
| 54 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -44,10 +44,18 @@ | |
| 44 | static const char *azName[] = { |
| 45 | "_FOSSIL_", |
| 46 | "_FOSSIL_-journal", |
| 47 | "_FOSSIL_-wal", |
| 48 | "_FOSSIL_-shm", |
| 49 | ".fslckout", |
| 50 | ".fslckout-journal", |
| 51 | ".fslckout-wal", |
| 52 | ".fslckout-shm", |
| 53 | |
| 54 | /* The use of ".fos" as the name of the checkout database is |
| 55 | ** deprecated. Use ".fslckout" instead. At some point, the following |
| 56 | ** entries should be removed. 2012-02-04 */ |
| 57 | ".fos", |
| 58 | ".fos-journal", |
| 59 | ".fos-wal", |
| 60 | ".fos-shm", |
| 61 | }; |
| 62 |
+1
-1
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -146,11 +146,11 @@ | ||
| 146 | 146 | db_end_transaction(1); |
| 147 | 147 | fossil_exit(1); |
| 148 | 148 | } |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | - brid = content_put(&branch); | |
| 151 | + brid = content_put_ex(&branch, 0, 0, 0, isPrivate); | |
| 152 | 152 | if( brid==0 ){ |
| 153 | 153 | fossil_panic("trouble committing manifest: %s", g.zErrMsg); |
| 154 | 154 | } |
| 155 | 155 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); |
| 156 | 156 | if( manifest_crosslink(brid, &branch)==0 ){ |
| 157 | 157 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -146,11 +146,11 @@ | |
| 146 | db_end_transaction(1); |
| 147 | fossil_exit(1); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | brid = content_put(&branch); |
| 152 | if( brid==0 ){ |
| 153 | fossil_panic("trouble committing manifest: %s", g.zErrMsg); |
| 154 | } |
| 155 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); |
| 156 | if( manifest_crosslink(brid, &branch)==0 ){ |
| 157 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -146,11 +146,11 @@ | |
| 146 | db_end_transaction(1); |
| 147 | fossil_exit(1); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | brid = content_put_ex(&branch, 0, 0, 0, isPrivate); |
| 152 | if( brid==0 ){ |
| 153 | fossil_panic("trouble committing manifest: %s", g.zErrMsg); |
| 154 | } |
| 155 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); |
| 156 | if( manifest_crosslink(brid, &branch)==0 ){ |
| 157 |
+48
-5
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -19,10 +19,57 @@ | ||
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "clone.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | |
| 24 | +/* | |
| 25 | +** Delete all private content from a repository. | |
| 26 | +*/ | |
| 27 | +void delete_private_content(void){ | |
| 28 | + Bag toUndelta; | |
| 29 | + Stmt q; | |
| 30 | + int rid; | |
| 31 | + | |
| 32 | + /* Carefule: We are about to delete all BLOB entries that are private. | |
| 33 | + ** So make sure that any no public BLOBs are deltas from a private BLOB. | |
| 34 | + ** Otherwise after the deletion, we won't be able to recreate the public | |
| 35 | + ** BLOBs. | |
| 36 | + */ | |
| 37 | + db_prepare(&q, | |
| 38 | + "SELECT " | |
| 39 | + " rid, (SELECT uuid FROM blob WHERE rid=delta.rid)," | |
| 40 | + " srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)" | |
| 41 | + " FROM delta" | |
| 42 | + " WHERE srcid in private AND rid NOT IN private" | |
| 43 | + ); | |
| 44 | + bag_init(&toUndelta); | |
| 45 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 46 | + int rid = db_column_int(&q, 0); | |
| 47 | + const char *zId = db_column_text(&q, 1); | |
| 48 | + int srcid = db_column_int(&q, 2); | |
| 49 | + const char *zSrc = db_column_text(&q, 3); | |
| 50 | + fossil_warning( | |
| 51 | + "public artifact %S (%d) is a delta from private artifact %S (%d)\n", | |
| 52 | + zId, rid, zSrc, srcid | |
| 53 | + ); | |
| 54 | + bag_insert(&toUndelta, rid); | |
| 55 | + } | |
| 56 | + db_finalize(&q); | |
| 57 | + while( (rid = bag_first(&toUndelta))>0 ){ | |
| 58 | + content_undelta(rid); | |
| 59 | + bag_remove(&toUndelta, rid); | |
| 60 | + } | |
| 61 | + bag_clear(&toUndelta); | |
| 62 | + | |
| 63 | + /* Now it is safe to remove all private content | |
| 64 | + */ | |
| 65 | + db_multi_exec( | |
| 66 | + "DELETE FROM blob WHERE rid IN private;" | |
| 67 | + "DELETE FROM delta wHERE rid IN private;" | |
| 68 | + "DELETE FROM private;" | |
| 69 | + ); | |
| 70 | +} | |
| 24 | 71 | |
| 25 | 72 | |
| 26 | 73 | /* |
| 27 | 74 | ** COMMAND: clone |
| 28 | 75 | ** |
| @@ -72,15 +119,11 @@ | ||
| 72 | 119 | " VALUES('server-code', lower(hex(randomblob(20))),now());" |
| 73 | 120 | "REPLACE INTO config(name,value,mtime)" |
| 74 | 121 | " VALUES('last-sync-url', '%q',now());", |
| 75 | 122 | g.urlCanonical |
| 76 | 123 | ); |
| 77 | - db_multi_exec( | |
| 78 | - "DELETE FROM blob WHERE rid IN private;" | |
| 79 | - "DELETE FROM delta wHERE rid IN private;" | |
| 80 | - "DELETE FROM private;" | |
| 81 | - ); | |
| 124 | + delete_private_content(); | |
| 82 | 125 | shun_artifacts(); |
| 83 | 126 | db_create_default_users(1, zDefaultUser); |
| 84 | 127 | if( zDefaultUser ){ |
| 85 | 128 | g.zLogin = zDefaultUser; |
| 86 | 129 | }else{ |
| 87 | 130 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -19,10 +19,57 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "clone.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | |
| 25 | |
| 26 | /* |
| 27 | ** COMMAND: clone |
| 28 | ** |
| @@ -72,15 +119,11 @@ | |
| 72 | " VALUES('server-code', lower(hex(randomblob(20))),now());" |
| 73 | "REPLACE INTO config(name,value,mtime)" |
| 74 | " VALUES('last-sync-url', '%q',now());", |
| 75 | g.urlCanonical |
| 76 | ); |
| 77 | db_multi_exec( |
| 78 | "DELETE FROM blob WHERE rid IN private;" |
| 79 | "DELETE FROM delta wHERE rid IN private;" |
| 80 | "DELETE FROM private;" |
| 81 | ); |
| 82 | shun_artifacts(); |
| 83 | db_create_default_users(1, zDefaultUser); |
| 84 | if( zDefaultUser ){ |
| 85 | g.zLogin = zDefaultUser; |
| 86 | }else{ |
| 87 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -19,10 +19,57 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "clone.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** Delete all private content from a repository. |
| 26 | */ |
| 27 | void delete_private_content(void){ |
| 28 | Bag toUndelta; |
| 29 | Stmt q; |
| 30 | int rid; |
| 31 | |
| 32 | /* Carefule: We are about to delete all BLOB entries that are private. |
| 33 | ** So make sure that any no public BLOBs are deltas from a private BLOB. |
| 34 | ** Otherwise after the deletion, we won't be able to recreate the public |
| 35 | ** BLOBs. |
| 36 | */ |
| 37 | db_prepare(&q, |
| 38 | "SELECT " |
| 39 | " rid, (SELECT uuid FROM blob WHERE rid=delta.rid)," |
| 40 | " srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)" |
| 41 | " FROM delta" |
| 42 | " WHERE srcid in private AND rid NOT IN private" |
| 43 | ); |
| 44 | bag_init(&toUndelta); |
| 45 | while( db_step(&q)==SQLITE_ROW ){ |
| 46 | int rid = db_column_int(&q, 0); |
| 47 | const char *zId = db_column_text(&q, 1); |
| 48 | int srcid = db_column_int(&q, 2); |
| 49 | const char *zSrc = db_column_text(&q, 3); |
| 50 | fossil_warning( |
| 51 | "public artifact %S (%d) is a delta from private artifact %S (%d)\n", |
| 52 | zId, rid, zSrc, srcid |
| 53 | ); |
| 54 | bag_insert(&toUndelta, rid); |
| 55 | } |
| 56 | db_finalize(&q); |
| 57 | while( (rid = bag_first(&toUndelta))>0 ){ |
| 58 | content_undelta(rid); |
| 59 | bag_remove(&toUndelta, rid); |
| 60 | } |
| 61 | bag_clear(&toUndelta); |
| 62 | |
| 63 | /* Now it is safe to remove all private content |
| 64 | */ |
| 65 | db_multi_exec( |
| 66 | "DELETE FROM blob WHERE rid IN private;" |
| 67 | "DELETE FROM delta wHERE rid IN private;" |
| 68 | "DELETE FROM private;" |
| 69 | ); |
| 70 | } |
| 71 | |
| 72 | |
| 73 | /* |
| 74 | ** COMMAND: clone |
| 75 | ** |
| @@ -72,15 +119,11 @@ | |
| 119 | " VALUES('server-code', lower(hex(randomblob(20))),now());" |
| 120 | "REPLACE INTO config(name,value,mtime)" |
| 121 | " VALUES('last-sync-url', '%q',now());", |
| 122 | g.urlCanonical |
| 123 | ); |
| 124 | delete_private_content(); |
| 125 | shun_artifacts(); |
| 126 | db_create_default_users(1, zDefaultUser); |
| 127 | if( zDefaultUser ){ |
| 128 | g.zLogin = zDefaultUser; |
| 129 | }else{ |
| 130 |
M
src/db.c
+6
-3
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -821,12 +821,15 @@ | ||
| 821 | 821 | return 1; |
| 822 | 822 | } |
| 823 | 823 | |
| 824 | 824 | /* |
| 825 | 825 | ** Locate the root directory of the local repository tree. The root |
| 826 | -** directory is found by searching for a file named "_FOSSIL_" or ".fos" | |
| 826 | +** directory is found by searching for a file named "_FOSSIL_" or ".fslckout" | |
| 827 | 827 | ** that contains a valid repository database. |
| 828 | +** | |
| 829 | +** For legacy, also look for ".fos". The use of ".fos" is deprecated | |
| 830 | +** since "fos" has negative connotations in Hungarian, we are told. | |
| 828 | 831 | ** |
| 829 | 832 | ** If no valid _FOSSIL_ or .fos file is found, we move up one level and |
| 830 | 833 | ** try again. Once the file is found, the g.zLocalRoot variable is set |
| 831 | 834 | ** to the root of the repository tree and this routine returns 1. If |
| 832 | 835 | ** no database is found, then this routine return 0. |
| @@ -836,11 +839,11 @@ | ||
| 836 | 839 | ** is found, it is attached to the open database connection too. |
| 837 | 840 | */ |
| 838 | 841 | int db_open_local(void){ |
| 839 | 842 | int i, n; |
| 840 | 843 | char zPwd[2000]; |
| 841 | - static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; | |
| 844 | + static const char *aDbName[] = { "/_FOSSIL_", "/.fslckout", "/.fos" }; | |
| 842 | 845 | |
| 843 | 846 | if( g.localOpen) return 1; |
| 844 | 847 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 845 | 848 | n = strlen(zPwd); |
| 846 | 849 | if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; |
| @@ -872,11 +875,11 @@ | ||
| 872 | 875 | return 0; |
| 873 | 876 | } |
| 874 | 877 | |
| 875 | 878 | /* |
| 876 | 879 | ** Get the full pathname to the repository database file. The |
| 877 | -** local database (the _FOSSIL_ or .fos database) must have already | |
| 880 | +** local database (the _FOSSIL_ or .fslckout database) must have already | |
| 878 | 881 | ** been opened before this routine is called. |
| 879 | 882 | */ |
| 880 | 883 | const char *db_repository_filename(void){ |
| 881 | 884 | static char *zRepo = 0; |
| 882 | 885 | assert( g.localOpen ); |
| 883 | 886 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -821,12 +821,15 @@ | |
| 821 | return 1; |
| 822 | } |
| 823 | |
| 824 | /* |
| 825 | ** Locate the root directory of the local repository tree. The root |
| 826 | ** directory is found by searching for a file named "_FOSSIL_" or ".fos" |
| 827 | ** that contains a valid repository database. |
| 828 | ** |
| 829 | ** If no valid _FOSSIL_ or .fos file is found, we move up one level and |
| 830 | ** try again. Once the file is found, the g.zLocalRoot variable is set |
| 831 | ** to the root of the repository tree and this routine returns 1. If |
| 832 | ** no database is found, then this routine return 0. |
| @@ -836,11 +839,11 @@ | |
| 836 | ** is found, it is attached to the open database connection too. |
| 837 | */ |
| 838 | int db_open_local(void){ |
| 839 | int i, n; |
| 840 | char zPwd[2000]; |
| 841 | static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; |
| 842 | |
| 843 | if( g.localOpen) return 1; |
| 844 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 845 | n = strlen(zPwd); |
| 846 | if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; |
| @@ -872,11 +875,11 @@ | |
| 872 | return 0; |
| 873 | } |
| 874 | |
| 875 | /* |
| 876 | ** Get the full pathname to the repository database file. The |
| 877 | ** local database (the _FOSSIL_ or .fos database) must have already |
| 878 | ** been opened before this routine is called. |
| 879 | */ |
| 880 | const char *db_repository_filename(void){ |
| 881 | static char *zRepo = 0; |
| 882 | assert( g.localOpen ); |
| 883 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -821,12 +821,15 @@ | |
| 821 | return 1; |
| 822 | } |
| 823 | |
| 824 | /* |
| 825 | ** Locate the root directory of the local repository tree. The root |
| 826 | ** directory is found by searching for a file named "_FOSSIL_" or ".fslckout" |
| 827 | ** that contains a valid repository database. |
| 828 | ** |
| 829 | ** For legacy, also look for ".fos". The use of ".fos" is deprecated |
| 830 | ** since "fos" has negative connotations in Hungarian, we are told. |
| 831 | ** |
| 832 | ** If no valid _FOSSIL_ or .fos file is found, we move up one level and |
| 833 | ** try again. Once the file is found, the g.zLocalRoot variable is set |
| 834 | ** to the root of the repository tree and this routine returns 1. If |
| 835 | ** no database is found, then this routine return 0. |
| @@ -836,11 +839,11 @@ | |
| 839 | ** is found, it is attached to the open database connection too. |
| 840 | */ |
| 841 | int db_open_local(void){ |
| 842 | int i, n; |
| 843 | char zPwd[2000]; |
| 844 | static const char *aDbName[] = { "/_FOSSIL_", "/.fslckout", "/.fos" }; |
| 845 | |
| 846 | if( g.localOpen) return 1; |
| 847 | file_getcwd(zPwd, sizeof(zPwd)-20); |
| 848 | n = strlen(zPwd); |
| 849 | if( n==1 && zPwd[0]=='/' ) zPwd[0] = '.'; |
| @@ -872,11 +875,11 @@ | |
| 875 | return 0; |
| 876 | } |
| 877 | |
| 878 | /* |
| 879 | ** Get the full pathname to the repository database file. The |
| 880 | ** local database (the _FOSSIL_ or .fslckout database) must have already |
| 881 | ** been opened before this routine is called. |
| 882 | */ |
| 883 | const char *db_repository_filename(void){ |
| 884 | static char *zRepo = 0; |
| 885 | assert( g.localOpen ); |
| 886 |
+17
-29
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -19,32 +19,17 @@ | ||
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "diffcmd.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | |
| 24 | -/* | |
| 25 | -** Output the results of a diff. Output goes to stdout for command-line | |
| 26 | -** or to the CGI/HTTP result buffer for web pages. | |
| 27 | -*/ | |
| 28 | -static void diff_printf(const char *zFormat, ...){ | |
| 29 | - va_list ap; | |
| 30 | - va_start(ap, zFormat); | |
| 31 | - if( g.cgiOutput ){ | |
| 32 | - cgi_vprintf(zFormat, ap); | |
| 33 | - }else{ | |
| 34 | - vprintf(zFormat, ap); | |
| 35 | - } | |
| 36 | - va_end(ap); | |
| 37 | -} | |
| 38 | - | |
| 39 | 24 | /* |
| 40 | 25 | ** Print the "Index:" message that patches wants to see at the top of a diff. |
| 41 | 26 | */ |
| 42 | 27 | void diff_print_index(const char *zFile, int diffFlags){ |
| 43 | 28 | if( (diffFlags & DIFF_SIDEBYSIDE)==0 ){ |
| 44 | 29 | char *z = mprintf("Index: %s\n%.66c\n", zFile, '='); |
| 45 | - diff_printf("%s", z); | |
| 30 | + fossil_print("%s", z); | |
| 46 | 31 | fossil_free(z); |
| 47 | 32 | } |
| 48 | 33 | } |
| 49 | 34 | |
| 50 | 35 | /* |
| @@ -61,11 +46,11 @@ | ||
| 61 | 46 | z = mprintf("%.*c %.*s %.*c\n", |
| 62 | 47 | x/2, '=', n1, zLeft, (x+1)/2, '='); |
| 63 | 48 | }else{ |
| 64 | 49 | z = mprintf("--- %s\n+++ %s\n", zLeft, zRight); |
| 65 | 50 | } |
| 66 | - diff_printf("%s", z); | |
| 51 | + fossil_print("%s", z); | |
| 67 | 52 | fossil_free(z); |
| 68 | 53 | } |
| 69 | 54 | |
| 70 | 55 | /* |
| 71 | 56 | ** Show the difference between two files, one in memory and one on disk. |
| @@ -104,11 +89,11 @@ | ||
| 104 | 89 | /* Compute and output the differences */ |
| 105 | 90 | blob_zero(&out); |
| 106 | 91 | text_diff(pFile1, &file2, &out, diffFlags); |
| 107 | 92 | if( blob_size(&out) ){ |
| 108 | 93 | diff_print_filenames(zName, zName2, diffFlags); |
| 109 | - diff_printf("%s\n", blob_str(&out)); | |
| 94 | + fossil_print("%s\n", blob_str(&out)); | |
| 110 | 95 | } |
| 111 | 96 | |
| 112 | 97 | /* Release memory resources */ |
| 113 | 98 | blob_reset(&file2); |
| 114 | 99 | blob_reset(&out); |
| @@ -163,11 +148,11 @@ | ||
| 163 | 148 | Blob out; /* Diff output text */ |
| 164 | 149 | |
| 165 | 150 | blob_zero(&out); |
| 166 | 151 | text_diff(pFile1, pFile2, &out, diffFlags); |
| 167 | 152 | diff_print_filenames(zName, zName, diffFlags); |
| 168 | - diff_printf("%s\n", blob_str(&out)); | |
| 153 | + fossil_print("%s\n", blob_str(&out)); | |
| 169 | 154 | |
| 170 | 155 | /* Release memory resources */ |
| 171 | 156 | blob_reset(&out); |
| 172 | 157 | }else{ |
| 173 | 158 | Blob cmd; |
| @@ -211,11 +196,12 @@ | ||
| 211 | 196 | Blob content; |
| 212 | 197 | int isLink; |
| 213 | 198 | file_tree_name(zFileTreeName, &fname, 1); |
| 214 | 199 | historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0); |
| 215 | 200 | if( !isLink != !file_wd_islink(zFrom) ){ |
| 216 | - diff_printf("cannot compute difference between symlink and regular file\n"); | |
| 201 | + fossil_print("cannot compute difference between " | |
| 202 | + "symlink and regular file\n"); | |
| 217 | 203 | }else{ |
| 218 | 204 | diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, diffFlags); |
| 219 | 205 | } |
| 220 | 206 | blob_reset(&content); |
| 221 | 207 | blob_reset(&fname); |
| @@ -287,30 +273,31 @@ | ||
| 287 | 273 | int isLink = db_column_int(&q, 5); |
| 288 | 274 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 289 | 275 | char *zToFree = zFullName; |
| 290 | 276 | int showDiff = 1; |
| 291 | 277 | if( isDeleted ){ |
| 292 | - diff_printf("DELETED %s\n", zPathname); | |
| 278 | + fossil_print("DELETED %s\n", zPathname); | |
| 293 | 279 | if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } |
| 294 | 280 | }else if( file_access(zFullName, 0) ){ |
| 295 | - diff_printf("MISSING %s\n", zPathname); | |
| 281 | + fossil_print("MISSING %s\n", zPathname); | |
| 296 | 282 | if( !asNewFile ){ showDiff = 0; } |
| 297 | 283 | }else if( isNew ){ |
| 298 | - diff_printf("ADDED %s\n", zPathname); | |
| 284 | + fossil_print("ADDED %s\n", zPathname); | |
| 299 | 285 | srcid = 0; |
| 300 | 286 | if( !asNewFile ){ showDiff = 0; } |
| 301 | 287 | }else if( isChnged==3 ){ |
| 302 | - diff_printf("ADDED_BY_MERGE %s\n", zPathname); | |
| 288 | + fossil_print("ADDED_BY_MERGE %s\n", zPathname); | |
| 303 | 289 | srcid = 0; |
| 304 | 290 | if( !asNewFile ){ showDiff = 0; } |
| 305 | 291 | } |
| 306 | 292 | if( showDiff ){ |
| 307 | 293 | Blob content; |
| 308 | 294 | if( !isLink != !file_wd_islink(zFullName) ){ |
| 309 | 295 | diff_print_index(zPathname, diffFlags); |
| 310 | 296 | diff_print_filenames(zPathname, zPathname, diffFlags); |
| 311 | - diff_printf("cannot compute difference between symlink and regular file\n"); | |
| 297 | + fossil_print("cannot compute difference between " | |
| 298 | + "symlink and regular file\n"); | |
| 312 | 299 | continue; |
| 313 | 300 | } |
| 314 | 301 | if( srcid>0 ){ |
| 315 | 302 | content_get(srcid, &content); |
| 316 | 303 | }else{ |
| @@ -345,11 +332,12 @@ | ||
| 345 | 332 | zName = blob_str(&fname); |
| 346 | 333 | historical_version_of_file(zFrom, zName, &v1, &isLink1, 0, 0); |
| 347 | 334 | historical_version_of_file(zTo, zName, &v2, &isLink2, 0, 0); |
| 348 | 335 | if( isLink1 != isLink2 ){ |
| 349 | 336 | diff_print_filenames(zName, zName, diffFlags); |
| 350 | - diff_printf("cannot compute difference between symlink and regular file\n"); | |
| 337 | + fossil_print("cannot compute difference " | |
| 338 | + " between symlink and regular file\n"); | |
| 351 | 339 | }else{ |
| 352 | 340 | diff_file_mem(&v1, &v2, zName, zDiffCmd, diffFlags); |
| 353 | 341 | } |
| 354 | 342 | blob_reset(&v1); |
| 355 | 343 | blob_reset(&v2); |
| @@ -415,27 +403,27 @@ | ||
| 415 | 403 | cmp = -1; |
| 416 | 404 | }else{ |
| 417 | 405 | cmp = fossil_strcmp(pFromFile->zName, pToFile->zName); |
| 418 | 406 | } |
| 419 | 407 | if( cmp<0 ){ |
| 420 | - diff_printf("DELETED %s\n", pFromFile->zName); | |
| 408 | + fossil_print("DELETED %s\n", pFromFile->zName); | |
| 421 | 409 | if( asNewFlag ){ |
| 422 | 410 | diff_manifest_entry(pFromFile, 0, zDiffCmd, diffFlags); |
| 423 | 411 | } |
| 424 | 412 | pFromFile = manifest_file_next(pFrom,0); |
| 425 | 413 | }else if( cmp>0 ){ |
| 426 | - diff_printf("ADDED %s\n", pToFile->zName); | |
| 414 | + fossil_print("ADDED %s\n", pToFile->zName); | |
| 427 | 415 | if( asNewFlag ){ |
| 428 | 416 | diff_manifest_entry(0, pToFile, zDiffCmd, diffFlags); |
| 429 | 417 | } |
| 430 | 418 | pToFile = manifest_file_next(pTo,0); |
| 431 | 419 | }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){ |
| 432 | 420 | /* No changes */ |
| 433 | 421 | pFromFile = manifest_file_next(pFrom,0); |
| 434 | 422 | pToFile = manifest_file_next(pTo,0); |
| 435 | 423 | }else{ |
| 436 | - /* diff_printf("CHANGED %s\n", pFromFile->zName); */ | |
| 424 | + /* fossil_print("CHANGED %s\n", pFromFile->zName); */ | |
| 437 | 425 | diff_manifest_entry(pFromFile, pToFile, zDiffCmd, diffFlags); |
| 438 | 426 | pFromFile = manifest_file_next(pFrom,0); |
| 439 | 427 | pToFile = manifest_file_next(pTo,0); |
| 440 | 428 | } |
| 441 | 429 | } |
| 442 | 430 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -19,32 +19,17 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "diffcmd.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** Output the results of a diff. Output goes to stdout for command-line |
| 26 | ** or to the CGI/HTTP result buffer for web pages. |
| 27 | */ |
| 28 | static void diff_printf(const char *zFormat, ...){ |
| 29 | va_list ap; |
| 30 | va_start(ap, zFormat); |
| 31 | if( g.cgiOutput ){ |
| 32 | cgi_vprintf(zFormat, ap); |
| 33 | }else{ |
| 34 | vprintf(zFormat, ap); |
| 35 | } |
| 36 | va_end(ap); |
| 37 | } |
| 38 | |
| 39 | /* |
| 40 | ** Print the "Index:" message that patches wants to see at the top of a diff. |
| 41 | */ |
| 42 | void diff_print_index(const char *zFile, int diffFlags){ |
| 43 | if( (diffFlags & DIFF_SIDEBYSIDE)==0 ){ |
| 44 | char *z = mprintf("Index: %s\n%.66c\n", zFile, '='); |
| 45 | diff_printf("%s", z); |
| 46 | fossil_free(z); |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | /* |
| @@ -61,11 +46,11 @@ | |
| 61 | z = mprintf("%.*c %.*s %.*c\n", |
| 62 | x/2, '=', n1, zLeft, (x+1)/2, '='); |
| 63 | }else{ |
| 64 | z = mprintf("--- %s\n+++ %s\n", zLeft, zRight); |
| 65 | } |
| 66 | diff_printf("%s", z); |
| 67 | fossil_free(z); |
| 68 | } |
| 69 | |
| 70 | /* |
| 71 | ** Show the difference between two files, one in memory and one on disk. |
| @@ -104,11 +89,11 @@ | |
| 104 | /* Compute and output the differences */ |
| 105 | blob_zero(&out); |
| 106 | text_diff(pFile1, &file2, &out, diffFlags); |
| 107 | if( blob_size(&out) ){ |
| 108 | diff_print_filenames(zName, zName2, diffFlags); |
| 109 | diff_printf("%s\n", blob_str(&out)); |
| 110 | } |
| 111 | |
| 112 | /* Release memory resources */ |
| 113 | blob_reset(&file2); |
| 114 | blob_reset(&out); |
| @@ -163,11 +148,11 @@ | |
| 163 | Blob out; /* Diff output text */ |
| 164 | |
| 165 | blob_zero(&out); |
| 166 | text_diff(pFile1, pFile2, &out, diffFlags); |
| 167 | diff_print_filenames(zName, zName, diffFlags); |
| 168 | diff_printf("%s\n", blob_str(&out)); |
| 169 | |
| 170 | /* Release memory resources */ |
| 171 | blob_reset(&out); |
| 172 | }else{ |
| 173 | Blob cmd; |
| @@ -211,11 +196,12 @@ | |
| 211 | Blob content; |
| 212 | int isLink; |
| 213 | file_tree_name(zFileTreeName, &fname, 1); |
| 214 | historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0); |
| 215 | if( !isLink != !file_wd_islink(zFrom) ){ |
| 216 | diff_printf("cannot compute difference between symlink and regular file\n"); |
| 217 | }else{ |
| 218 | diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, diffFlags); |
| 219 | } |
| 220 | blob_reset(&content); |
| 221 | blob_reset(&fname); |
| @@ -287,30 +273,31 @@ | |
| 287 | int isLink = db_column_int(&q, 5); |
| 288 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 289 | char *zToFree = zFullName; |
| 290 | int showDiff = 1; |
| 291 | if( isDeleted ){ |
| 292 | diff_printf("DELETED %s\n", zPathname); |
| 293 | if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } |
| 294 | }else if( file_access(zFullName, 0) ){ |
| 295 | diff_printf("MISSING %s\n", zPathname); |
| 296 | if( !asNewFile ){ showDiff = 0; } |
| 297 | }else if( isNew ){ |
| 298 | diff_printf("ADDED %s\n", zPathname); |
| 299 | srcid = 0; |
| 300 | if( !asNewFile ){ showDiff = 0; } |
| 301 | }else if( isChnged==3 ){ |
| 302 | diff_printf("ADDED_BY_MERGE %s\n", zPathname); |
| 303 | srcid = 0; |
| 304 | if( !asNewFile ){ showDiff = 0; } |
| 305 | } |
| 306 | if( showDiff ){ |
| 307 | Blob content; |
| 308 | if( !isLink != !file_wd_islink(zFullName) ){ |
| 309 | diff_print_index(zPathname, diffFlags); |
| 310 | diff_print_filenames(zPathname, zPathname, diffFlags); |
| 311 | diff_printf("cannot compute difference between symlink and regular file\n"); |
| 312 | continue; |
| 313 | } |
| 314 | if( srcid>0 ){ |
| 315 | content_get(srcid, &content); |
| 316 | }else{ |
| @@ -345,11 +332,12 @@ | |
| 345 | zName = blob_str(&fname); |
| 346 | historical_version_of_file(zFrom, zName, &v1, &isLink1, 0, 0); |
| 347 | historical_version_of_file(zTo, zName, &v2, &isLink2, 0, 0); |
| 348 | if( isLink1 != isLink2 ){ |
| 349 | diff_print_filenames(zName, zName, diffFlags); |
| 350 | diff_printf("cannot compute difference between symlink and regular file\n"); |
| 351 | }else{ |
| 352 | diff_file_mem(&v1, &v2, zName, zDiffCmd, diffFlags); |
| 353 | } |
| 354 | blob_reset(&v1); |
| 355 | blob_reset(&v2); |
| @@ -415,27 +403,27 @@ | |
| 415 | cmp = -1; |
| 416 | }else{ |
| 417 | cmp = fossil_strcmp(pFromFile->zName, pToFile->zName); |
| 418 | } |
| 419 | if( cmp<0 ){ |
| 420 | diff_printf("DELETED %s\n", pFromFile->zName); |
| 421 | if( asNewFlag ){ |
| 422 | diff_manifest_entry(pFromFile, 0, zDiffCmd, diffFlags); |
| 423 | } |
| 424 | pFromFile = manifest_file_next(pFrom,0); |
| 425 | }else if( cmp>0 ){ |
| 426 | diff_printf("ADDED %s\n", pToFile->zName); |
| 427 | if( asNewFlag ){ |
| 428 | diff_manifest_entry(0, pToFile, zDiffCmd, diffFlags); |
| 429 | } |
| 430 | pToFile = manifest_file_next(pTo,0); |
| 431 | }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){ |
| 432 | /* No changes */ |
| 433 | pFromFile = manifest_file_next(pFrom,0); |
| 434 | pToFile = manifest_file_next(pTo,0); |
| 435 | }else{ |
| 436 | /* diff_printf("CHANGED %s\n", pFromFile->zName); */ |
| 437 | diff_manifest_entry(pFromFile, pToFile, zDiffCmd, diffFlags); |
| 438 | pFromFile = manifest_file_next(pFrom,0); |
| 439 | pToFile = manifest_file_next(pTo,0); |
| 440 | } |
| 441 | } |
| 442 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -19,32 +19,17 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "diffcmd.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** Print the "Index:" message that patches wants to see at the top of a diff. |
| 26 | */ |
| 27 | void diff_print_index(const char *zFile, int diffFlags){ |
| 28 | if( (diffFlags & DIFF_SIDEBYSIDE)==0 ){ |
| 29 | char *z = mprintf("Index: %s\n%.66c\n", zFile, '='); |
| 30 | fossil_print("%s", z); |
| 31 | fossil_free(z); |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | /* |
| @@ -61,11 +46,11 @@ | |
| 46 | z = mprintf("%.*c %.*s %.*c\n", |
| 47 | x/2, '=', n1, zLeft, (x+1)/2, '='); |
| 48 | }else{ |
| 49 | z = mprintf("--- %s\n+++ %s\n", zLeft, zRight); |
| 50 | } |
| 51 | fossil_print("%s", z); |
| 52 | fossil_free(z); |
| 53 | } |
| 54 | |
| 55 | /* |
| 56 | ** Show the difference between two files, one in memory and one on disk. |
| @@ -104,11 +89,11 @@ | |
| 89 | /* Compute and output the differences */ |
| 90 | blob_zero(&out); |
| 91 | text_diff(pFile1, &file2, &out, diffFlags); |
| 92 | if( blob_size(&out) ){ |
| 93 | diff_print_filenames(zName, zName2, diffFlags); |
| 94 | fossil_print("%s\n", blob_str(&out)); |
| 95 | } |
| 96 | |
| 97 | /* Release memory resources */ |
| 98 | blob_reset(&file2); |
| 99 | blob_reset(&out); |
| @@ -163,11 +148,11 @@ | |
| 148 | Blob out; /* Diff output text */ |
| 149 | |
| 150 | blob_zero(&out); |
| 151 | text_diff(pFile1, pFile2, &out, diffFlags); |
| 152 | diff_print_filenames(zName, zName, diffFlags); |
| 153 | fossil_print("%s\n", blob_str(&out)); |
| 154 | |
| 155 | /* Release memory resources */ |
| 156 | blob_reset(&out); |
| 157 | }else{ |
| 158 | Blob cmd; |
| @@ -211,11 +196,12 @@ | |
| 196 | Blob content; |
| 197 | int isLink; |
| 198 | file_tree_name(zFileTreeName, &fname, 1); |
| 199 | historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0); |
| 200 | if( !isLink != !file_wd_islink(zFrom) ){ |
| 201 | fossil_print("cannot compute difference between " |
| 202 | "symlink and regular file\n"); |
| 203 | }else{ |
| 204 | diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, diffFlags); |
| 205 | } |
| 206 | blob_reset(&content); |
| 207 | blob_reset(&fname); |
| @@ -287,30 +273,31 @@ | |
| 273 | int isLink = db_column_int(&q, 5); |
| 274 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 275 | char *zToFree = zFullName; |
| 276 | int showDiff = 1; |
| 277 | if( isDeleted ){ |
| 278 | fossil_print("DELETED %s\n", zPathname); |
| 279 | if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } |
| 280 | }else if( file_access(zFullName, 0) ){ |
| 281 | fossil_print("MISSING %s\n", zPathname); |
| 282 | if( !asNewFile ){ showDiff = 0; } |
| 283 | }else if( isNew ){ |
| 284 | fossil_print("ADDED %s\n", zPathname); |
| 285 | srcid = 0; |
| 286 | if( !asNewFile ){ showDiff = 0; } |
| 287 | }else if( isChnged==3 ){ |
| 288 | fossil_print("ADDED_BY_MERGE %s\n", zPathname); |
| 289 | srcid = 0; |
| 290 | if( !asNewFile ){ showDiff = 0; } |
| 291 | } |
| 292 | if( showDiff ){ |
| 293 | Blob content; |
| 294 | if( !isLink != !file_wd_islink(zFullName) ){ |
| 295 | diff_print_index(zPathname, diffFlags); |
| 296 | diff_print_filenames(zPathname, zPathname, diffFlags); |
| 297 | fossil_print("cannot compute difference between " |
| 298 | "symlink and regular file\n"); |
| 299 | continue; |
| 300 | } |
| 301 | if( srcid>0 ){ |
| 302 | content_get(srcid, &content); |
| 303 | }else{ |
| @@ -345,11 +332,12 @@ | |
| 332 | zName = blob_str(&fname); |
| 333 | historical_version_of_file(zFrom, zName, &v1, &isLink1, 0, 0); |
| 334 | historical_version_of_file(zTo, zName, &v2, &isLink2, 0, 0); |
| 335 | if( isLink1 != isLink2 ){ |
| 336 | diff_print_filenames(zName, zName, diffFlags); |
| 337 | fossil_print("cannot compute difference " |
| 338 | " between symlink and regular file\n"); |
| 339 | }else{ |
| 340 | diff_file_mem(&v1, &v2, zName, zDiffCmd, diffFlags); |
| 341 | } |
| 342 | blob_reset(&v1); |
| 343 | blob_reset(&v2); |
| @@ -415,27 +403,27 @@ | |
| 403 | cmp = -1; |
| 404 | }else{ |
| 405 | cmp = fossil_strcmp(pFromFile->zName, pToFile->zName); |
| 406 | } |
| 407 | if( cmp<0 ){ |
| 408 | fossil_print("DELETED %s\n", pFromFile->zName); |
| 409 | if( asNewFlag ){ |
| 410 | diff_manifest_entry(pFromFile, 0, zDiffCmd, diffFlags); |
| 411 | } |
| 412 | pFromFile = manifest_file_next(pFrom,0); |
| 413 | }else if( cmp>0 ){ |
| 414 | fossil_print("ADDED %s\n", pToFile->zName); |
| 415 | if( asNewFlag ){ |
| 416 | diff_manifest_entry(0, pToFile, zDiffCmd, diffFlags); |
| 417 | } |
| 418 | pToFile = manifest_file_next(pTo,0); |
| 419 | }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){ |
| 420 | /* No changes */ |
| 421 | pFromFile = manifest_file_next(pFrom,0); |
| 422 | pToFile = manifest_file_next(pTo,0); |
| 423 | }else{ |
| 424 | /* fossil_print("CHANGED %s\n", pFromFile->zName); */ |
| 425 | diff_manifest_entry(pFromFile, pToFile, zDiffCmd, diffFlags); |
| 426 | pFromFile = manifest_file_next(pFrom,0); |
| 427 | pToFile = manifest_file_next(pTo,0); |
| 428 | } |
| 429 | } |
| 430 |
+1
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -822,10 +822,11 @@ | ||
| 822 | 822 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 823 | 823 | free(zToFree); |
| 824 | 824 | #else |
| 825 | 825 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 826 | 826 | #endif |
| 827 | + fflush(toStdErr ? stderr : stdout); | |
| 827 | 828 | } |
| 828 | 829 | |
| 829 | 830 | /* |
| 830 | 831 | ** Write output for user consumption. If g.cgiOutput is enabled, then |
| 831 | 832 | ** send the output as part of the CGI reply. If g.cgiOutput is false, |
| 832 | 833 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -822,10 +822,11 @@ | |
| 822 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 823 | free(zToFree); |
| 824 | #else |
| 825 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 826 | #endif |
| 827 | } |
| 828 | |
| 829 | /* |
| 830 | ** Write output for user consumption. If g.cgiOutput is enabled, then |
| 831 | ** send the output as part of the CGI reply. If g.cgiOutput is false, |
| 832 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -822,10 +822,11 @@ | |
| 822 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 823 | free(zToFree); |
| 824 | #else |
| 825 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 826 | #endif |
| 827 | fflush(toStdErr ? stderr : stdout); |
| 828 | } |
| 829 | |
| 830 | /* |
| 831 | ** Write output for user consumption. If g.cgiOutput is enabled, then |
| 832 | ** send the output as part of the CGI reply. If g.cgiOutput is false, |
| 833 |
+1
-5
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -771,15 +771,11 @@ | ||
| 771 | 771 | } |
| 772 | 772 | } |
| 773 | 773 | db_begin_transaction(); |
| 774 | 774 | if( privateOnly || bVerily ){ |
| 775 | 775 | bNeedRebuild = db_exists("SELECT 1 FROM private"); |
| 776 | - db_multi_exec( | |
| 777 | - "DELETE FROM blob WHERE rid IN private;" | |
| 778 | - "DELETE FROM delta WHERE rid IN private;" | |
| 779 | - "DELETE FROM private;" | |
| 780 | - ); | |
| 776 | + delete_private_content(); | |
| 781 | 777 | } |
| 782 | 778 | if( !privateOnly ){ |
| 783 | 779 | db_multi_exec( |
| 784 | 780 | "UPDATE user SET pw='';" |
| 785 | 781 | "DELETE FROM config WHERE name GLOB 'last-sync-*';" |
| 786 | 782 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -771,15 +771,11 @@ | |
| 771 | } |
| 772 | } |
| 773 | db_begin_transaction(); |
| 774 | if( privateOnly || bVerily ){ |
| 775 | bNeedRebuild = db_exists("SELECT 1 FROM private"); |
| 776 | db_multi_exec( |
| 777 | "DELETE FROM blob WHERE rid IN private;" |
| 778 | "DELETE FROM delta WHERE rid IN private;" |
| 779 | "DELETE FROM private;" |
| 780 | ); |
| 781 | } |
| 782 | if( !privateOnly ){ |
| 783 | db_multi_exec( |
| 784 | "UPDATE user SET pw='';" |
| 785 | "DELETE FROM config WHERE name GLOB 'last-sync-*';" |
| 786 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -771,15 +771,11 @@ | |
| 771 | } |
| 772 | } |
| 773 | db_begin_transaction(); |
| 774 | if( privateOnly || bVerily ){ |
| 775 | bNeedRebuild = db_exists("SELECT 1 FROM private"); |
| 776 | delete_private_content(); |
| 777 | } |
| 778 | if( !privateOnly ){ |
| 779 | db_multi_exec( |
| 780 | "UPDATE user SET pw='';" |
| 781 | "DELETE FROM config WHERE name GLOB 'last-sync-*';" |
| 782 |
+13
-7
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -263,22 +263,26 @@ | ||
| 263 | 263 | /* |
| 264 | 264 | ** Add islink information |
| 265 | 265 | */ |
| 266 | 266 | db_multi_exec( |
| 267 | 267 | "UPDATE fv SET" |
| 268 | - " islinkv=coalesce((SELECT islink FROM vfile WHERE vid=%d AND pathname=fnt),0)," | |
| 269 | - " islinkt=coalesce((SELECT islink FROM vfile WHERE vid=%d AND pathname=fnt),0)", | |
| 268 | + " islinkv=coalesce((SELECT islink FROM vfile" | |
| 269 | + " WHERE vid=%d AND pathname=fnt),0)," | |
| 270 | + " islinkt=coalesce((SELECT islink FROM vfile" | |
| 271 | + " WHERE vid=%d AND pathname=fnt),0)", | |
| 270 | 272 | vid, tid |
| 271 | 273 | ); |
| 272 | 274 | |
| 273 | 275 | |
| 274 | 276 | if( debugFlag ){ |
| 275 | 277 | db_prepare(&q, |
| 276 | - "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe, islinkv, islinkt FROM fv" | |
| 278 | + "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe," | |
| 279 | + " islinkv, islinkt FROM fv" | |
| 277 | 280 | ); |
| 278 | 281 | while( db_step(&q)==SQLITE_ROW ){ |
| 279 | - fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d islinkv=%d islinkt=%d\n", | |
| 282 | + fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d" | |
| 283 | + " islinkv=%d islinkt=%d\n", | |
| 280 | 284 | db_column_int(&q, 0), |
| 281 | 285 | db_column_int(&q, 4), |
| 282 | 286 | db_column_int(&q, 5), |
| 283 | 287 | db_column_int(&q, 3), |
| 284 | 288 | db_column_int(&q, 6), |
| @@ -325,11 +329,12 @@ | ||
| 325 | 329 | /* |
| 326 | 330 | ** Alter the content of the checkout so that it conforms with the |
| 327 | 331 | ** target |
| 328 | 332 | */ |
| 329 | 333 | db_prepare(&q, |
| 330 | - "SELECT fn, idv, ridv, idt, ridt, chnged, fnt, isexe, islinkv, islinkt FROM fv ORDER BY 1" | |
| 334 | + "SELECT fn, idv, ridv, idt, ridt, chnged, fnt," | |
| 335 | + " isexe, islinkv, islinkt FROM fv ORDER BY 1" | |
| 331 | 336 | ); |
| 332 | 337 | db_prepare(&mtimeXfer, |
| 333 | 338 | "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" |
| 334 | 339 | " WHERE id=:idt" |
| 335 | 340 | ); |
| @@ -666,11 +671,12 @@ | ||
| 666 | 671 | int isExe = 0; |
| 667 | 672 | int isLink = 0; |
| 668 | 673 | char *zFull; |
| 669 | 674 | zFile = db_column_text(&q, 0); |
| 670 | 675 | zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 671 | - errCode = historical_version_of_file(zRevision, zFile, &record, &isLink, &isExe,2); | |
| 676 | + errCode = historical_version_of_file(zRevision, zFile, &record, | |
| 677 | + &isLink, &isExe,2); | |
| 672 | 678 | if( errCode==2 ){ |
| 673 | 679 | if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ |
| 674 | 680 | fossil_print("UNMANAGE: %s\n", zFile); |
| 675 | 681 | }else{ |
| 676 | 682 | undo_save(zFile); |
| @@ -692,11 +698,11 @@ | ||
| 692 | 698 | file_wd_setexe(zFull, isExe); |
| 693 | 699 | fossil_print("REVERTED: %s\n", zFile); |
| 694 | 700 | mtime = file_wd_mtime(zFull); |
| 695 | 701 | db_multi_exec( |
| 696 | 702 | "UPDATE vfile" |
| 697 | - " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d, mrid=rid," | |
| 703 | + " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d,mrid=rid," | |
| 698 | 704 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 699 | 705 | " WHERE pathname=%Q", |
| 700 | 706 | mtime, isExe, isLink, zFile |
| 701 | 707 | ); |
| 702 | 708 | } |
| 703 | 709 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -263,22 +263,26 @@ | |
| 263 | /* |
| 264 | ** Add islink information |
| 265 | */ |
| 266 | db_multi_exec( |
| 267 | "UPDATE fv SET" |
| 268 | " islinkv=coalesce((SELECT islink FROM vfile WHERE vid=%d AND pathname=fnt),0)," |
| 269 | " islinkt=coalesce((SELECT islink FROM vfile WHERE vid=%d AND pathname=fnt),0)", |
| 270 | vid, tid |
| 271 | ); |
| 272 | |
| 273 | |
| 274 | if( debugFlag ){ |
| 275 | db_prepare(&q, |
| 276 | "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe, islinkv, islinkt FROM fv" |
| 277 | ); |
| 278 | while( db_step(&q)==SQLITE_ROW ){ |
| 279 | fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d islinkv=%d islinkt=%d\n", |
| 280 | db_column_int(&q, 0), |
| 281 | db_column_int(&q, 4), |
| 282 | db_column_int(&q, 5), |
| 283 | db_column_int(&q, 3), |
| 284 | db_column_int(&q, 6), |
| @@ -325,11 +329,12 @@ | |
| 325 | /* |
| 326 | ** Alter the content of the checkout so that it conforms with the |
| 327 | ** target |
| 328 | */ |
| 329 | db_prepare(&q, |
| 330 | "SELECT fn, idv, ridv, idt, ridt, chnged, fnt, isexe, islinkv, islinkt FROM fv ORDER BY 1" |
| 331 | ); |
| 332 | db_prepare(&mtimeXfer, |
| 333 | "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" |
| 334 | " WHERE id=:idt" |
| 335 | ); |
| @@ -666,11 +671,12 @@ | |
| 666 | int isExe = 0; |
| 667 | int isLink = 0; |
| 668 | char *zFull; |
| 669 | zFile = db_column_text(&q, 0); |
| 670 | zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 671 | errCode = historical_version_of_file(zRevision, zFile, &record, &isLink, &isExe,2); |
| 672 | if( errCode==2 ){ |
| 673 | if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ |
| 674 | fossil_print("UNMANAGE: %s\n", zFile); |
| 675 | }else{ |
| 676 | undo_save(zFile); |
| @@ -692,11 +698,11 @@ | |
| 692 | file_wd_setexe(zFull, isExe); |
| 693 | fossil_print("REVERTED: %s\n", zFile); |
| 694 | mtime = file_wd_mtime(zFull); |
| 695 | db_multi_exec( |
| 696 | "UPDATE vfile" |
| 697 | " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d, mrid=rid," |
| 698 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 699 | " WHERE pathname=%Q", |
| 700 | mtime, isExe, isLink, zFile |
| 701 | ); |
| 702 | } |
| 703 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -263,22 +263,26 @@ | |
| 263 | /* |
| 264 | ** Add islink information |
| 265 | */ |
| 266 | db_multi_exec( |
| 267 | "UPDATE fv SET" |
| 268 | " islinkv=coalesce((SELECT islink FROM vfile" |
| 269 | " WHERE vid=%d AND pathname=fnt),0)," |
| 270 | " islinkt=coalesce((SELECT islink FROM vfile" |
| 271 | " WHERE vid=%d AND pathname=fnt),0)", |
| 272 | vid, tid |
| 273 | ); |
| 274 | |
| 275 | |
| 276 | if( debugFlag ){ |
| 277 | db_prepare(&q, |
| 278 | "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe," |
| 279 | " islinkv, islinkt FROM fv" |
| 280 | ); |
| 281 | while( db_step(&q)==SQLITE_ROW ){ |
| 282 | fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d" |
| 283 | " islinkv=%d islinkt=%d\n", |
| 284 | db_column_int(&q, 0), |
| 285 | db_column_int(&q, 4), |
| 286 | db_column_int(&q, 5), |
| 287 | db_column_int(&q, 3), |
| 288 | db_column_int(&q, 6), |
| @@ -325,11 +329,12 @@ | |
| 329 | /* |
| 330 | ** Alter the content of the checkout so that it conforms with the |
| 331 | ** target |
| 332 | */ |
| 333 | db_prepare(&q, |
| 334 | "SELECT fn, idv, ridv, idt, ridt, chnged, fnt," |
| 335 | " isexe, islinkv, islinkt FROM fv ORDER BY 1" |
| 336 | ); |
| 337 | db_prepare(&mtimeXfer, |
| 338 | "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" |
| 339 | " WHERE id=:idt" |
| 340 | ); |
| @@ -666,11 +671,12 @@ | |
| 671 | int isExe = 0; |
| 672 | int isLink = 0; |
| 673 | char *zFull; |
| 674 | zFile = db_column_text(&q, 0); |
| 675 | zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 676 | errCode = historical_version_of_file(zRevision, zFile, &record, |
| 677 | &isLink, &isExe,2); |
| 678 | if( errCode==2 ){ |
| 679 | if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ |
| 680 | fossil_print("UNMANAGE: %s\n", zFile); |
| 681 | }else{ |
| 682 | undo_save(zFile); |
| @@ -692,11 +698,11 @@ | |
| 698 | file_wd_setexe(zFull, isExe); |
| 699 | fossil_print("REVERTED: %s\n", zFile); |
| 700 | mtime = file_wd_mtime(zFull); |
| 701 | db_multi_exec( |
| 702 | "UPDATE vfile" |
| 703 | " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d,mrid=rid," |
| 704 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 705 | " WHERE pathname=%Q", |
| 706 | mtime, isExe, isLink, zFile |
| 707 | ); |
| 708 | } |
| 709 |
+12
-1
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -335,19 +335,30 @@ | ||
| 335 | 335 | } |
| 336 | 336 | |
| 337 | 337 | /* |
| 338 | 338 | ** Check to see if the directory named in zPath is the top of a checkout. |
| 339 | 339 | ** In other words, check to see if directory pPath contains a file named |
| 340 | -** "_FOSSIL_" or ".fos". Return true or false. | |
| 340 | +** "_FOSSIL_" or ".fslckout". Return true or false. | |
| 341 | 341 | */ |
| 342 | 342 | int vfile_top_of_checkout(const char *zPath){ |
| 343 | 343 | char *zFile; |
| 344 | 344 | int fileFound = 0; |
| 345 | 345 | |
| 346 | 346 | zFile = mprintf("%s/_FOSSIL_", zPath); |
| 347 | 347 | fileFound = file_size(zFile)>=1024; |
| 348 | 348 | fossil_free(zFile); |
| 349 | + if( !fileFound ){ | |
| 350 | + zFile = mprintf("%s/.fslckout", zPath); | |
| 351 | + fileFound = file_size(zFile)>=1024; | |
| 352 | + fossil_free(zFile); | |
| 353 | + } | |
| 354 | + | |
| 355 | + /* Check for ".fos" for legacy support. But the use of ".fos" as the | |
| 356 | + ** per-checkout database name is deprecated. At some point, all support | |
| 357 | + ** for ".fos" will end and this code should be removed. This comment | |
| 358 | + ** added on 2012-02-04. | |
| 359 | + */ | |
| 349 | 360 | if( !fileFound ){ |
| 350 | 361 | zFile = mprintf("%s/.fos", zPath); |
| 351 | 362 | fileFound = file_size(zFile)>=1024; |
| 352 | 363 | fossil_free(zFile); |
| 353 | 364 | } |
| 354 | 365 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -335,19 +335,30 @@ | |
| 335 | } |
| 336 | |
| 337 | /* |
| 338 | ** Check to see if the directory named in zPath is the top of a checkout. |
| 339 | ** In other words, check to see if directory pPath contains a file named |
| 340 | ** "_FOSSIL_" or ".fos". Return true or false. |
| 341 | */ |
| 342 | int vfile_top_of_checkout(const char *zPath){ |
| 343 | char *zFile; |
| 344 | int fileFound = 0; |
| 345 | |
| 346 | zFile = mprintf("%s/_FOSSIL_", zPath); |
| 347 | fileFound = file_size(zFile)>=1024; |
| 348 | fossil_free(zFile); |
| 349 | if( !fileFound ){ |
| 350 | zFile = mprintf("%s/.fos", zPath); |
| 351 | fileFound = file_size(zFile)>=1024; |
| 352 | fossil_free(zFile); |
| 353 | } |
| 354 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -335,19 +335,30 @@ | |
| 335 | } |
| 336 | |
| 337 | /* |
| 338 | ** Check to see if the directory named in zPath is the top of a checkout. |
| 339 | ** In other words, check to see if directory pPath contains a file named |
| 340 | ** "_FOSSIL_" or ".fslckout". Return true or false. |
| 341 | */ |
| 342 | int vfile_top_of_checkout(const char *zPath){ |
| 343 | char *zFile; |
| 344 | int fileFound = 0; |
| 345 | |
| 346 | zFile = mprintf("%s/_FOSSIL_", zPath); |
| 347 | fileFound = file_size(zFile)>=1024; |
| 348 | fossil_free(zFile); |
| 349 | if( !fileFound ){ |
| 350 | zFile = mprintf("%s/.fslckout", zPath); |
| 351 | fileFound = file_size(zFile)>=1024; |
| 352 | fossil_free(zFile); |
| 353 | } |
| 354 | |
| 355 | /* Check for ".fos" for legacy support. But the use of ".fos" as the |
| 356 | ** per-checkout database name is deprecated. At some point, all support |
| 357 | ** for ".fos" will end and this code should be removed. This comment |
| 358 | ** added on 2012-02-04. |
| 359 | */ |
| 360 | if( !fileFound ){ |
| 361 | zFile = mprintf("%s/.fos", zPath); |
| 362 | fileFound = file_size(zFile)>=1024; |
| 363 | fossil_free(zFile); |
| 364 | } |
| 365 |
+19
-21
| --- www/tech_overview.wiki | ||
| +++ www/tech_overview.wiki | ||
| @@ -5,41 +5,38 @@ | ||
| 5 | 5 | |
| 6 | 6 | <h2>1.0 Introduction</h2> |
| 7 | 7 | |
| 8 | 8 | At its lowest level, a Fossil repository consists of an unordered set |
| 9 | 9 | of immutable "artifacts". You might think of these artifacts as "files", |
| 10 | -since in many cases the artifacts exactly correspond to source code files | |
| 11 | -that are stored in the Fossil repository. But other "control artifacts" | |
| 10 | +since in many cases the artifacts exactly that. But other "control artifacts" | |
| 12 | 11 | are also included in the mix. These control artifacts define the relationships |
| 13 | 12 | between artifacts - which files go together to form a particular |
| 14 | 13 | version of the project, who checked in that version and when, what was |
| 15 | 14 | the check-in comment, what wiki pages are included with the project, what |
| 16 | 15 | are the edit histories of each wiki page, what bug reports or tickets are |
| 17 | -included, who contributed to the evolution of each ticket, and so forth, | |
| 18 | -and so on. This low-level file format is called the "global state" of | |
| 16 | +included, who contributed to the evolution of each ticket, and so forth. | |
| 17 | +This low-level file format is called the "global state" of | |
| 19 | 18 | the repository, since this is the information that is synced to peer |
| 20 | 19 | repositories using push and pull operations. The low-level file format |
| 21 | 20 | is also called "enduring" since it is intended to last for many years. |
| 22 | 21 | The details of the low-level, enduring, global file format |
| 23 | 22 | are [./fileformat.wiki | described separately]. |
| 24 | 23 | |
| 25 | 24 | This article is about how Fossil is currently implemented. Instead of |
| 26 | 25 | dealing with vague abstractions of "enduring file formats" as the |
| 27 | -[./fileformat.wiki | that other document] does, this article provides | |
| 26 | +[./fileformat.wiki | other document] does, this article provides | |
| 28 | 27 | some detail on how Fossil actually stores information on disk. |
| 29 | 28 | |
| 30 | 29 | <h2>2.0 Three Databases</h2> |
| 31 | 30 | |
| 32 | 31 | Fossil stores state information in |
| 33 | 32 | [http://www.sqlite.org/ | SQLite] database files. |
| 34 | 33 | SQLite keeps an entire relational database, including multiple tables and |
| 35 | 34 | indices, in a single disk file. The SQLite library allows the database |
| 36 | 35 | files to be efficiently queried and updated using the industry-standard |
| 37 | -SQL language. And SQLite makes updates to these database files atomic, | |
| 38 | -even if a system crashes or power failure occurs in the middle of the | |
| 39 | -update, meaning that repository content is protected even during severe | |
| 40 | -malfunctions. | |
| 36 | +SQL language. SQLite updates are atomic, so even in the event of | |
| 37 | +a system crashes or power failure the repository content is protected. | |
| 41 | 38 | |
| 42 | 39 | Fossil uses three separate classes of SQLite databases: |
| 43 | 40 | |
| 44 | 41 | <ol> |
| 45 | 42 | <li>The configuration database |
| @@ -152,14 +149,15 @@ | ||
| 152 | 149 | The artifacts are stored as BLOBs, compressed using |
| 153 | 150 | [http://www.zlib.net/ | zlib compression] and, where applicable, |
| 154 | 151 | using [./delta_encoder_algorithm.wiki | delta compression]. |
| 155 | 152 | The combination of zlib and delta compression results in a considerable |
| 156 | 153 | space savings. For the SQLite project, at the time of this writing, |
| 157 | -the total size of all artifacts is over 1.7 GB but thanks to the | |
| 154 | +the total size of all artifacts is over 2.0 GB but thanks to the | |
| 158 | 155 | combined zlib and delta compression, that content only takes up |
| 159 | -51.4 MB of space in the repository database, for a compression ratio | |
| 160 | -of about 33:1. | |
| 156 | +32 MB of space in the repository database, for a compression ratio | |
| 157 | +of about 64:1. The average size of a content BLOB in the database | |
| 158 | +is around 500 bytes. | |
| 161 | 159 | |
| 162 | 160 | Note that the zlib and delta compression is not an inherent part of the |
| 163 | 161 | Fossil file format; it is just an optimization. |
| 164 | 162 | The enduring file format for Fossil is the unordered |
| 165 | 163 | set of artifacts. The compression techniques are just a detail of |
| @@ -185,11 +183,11 @@ | ||
| 185 | 183 | |
| 186 | 184 | <h4>2.2.2 Project Metadata</h4> |
| 187 | 185 | |
| 188 | 186 | The global project state information in the repository database is |
| 189 | 187 | supplemented by computed metadata that makes querying the project state |
| 190 | -more efficient. Metadata includes but information such as the following: | |
| 188 | +more efficient. Metadata includes information such as the following: | |
| 191 | 189 | |
| 192 | 190 | * The names for all files found in any checkin. |
| 193 | 191 | * All check-ins that modify a given file |
| 194 | 192 | * Parents and children of each checkin. |
| 195 | 193 | * Potential timeline rows. |
| @@ -200,13 +198,13 @@ | ||
| 200 | 198 | * Current content of each ticket. |
| 201 | 199 | * Cross-references between tickets, checkins, and wiki pages. |
| 202 | 200 | |
| 203 | 201 | The metadata is held in various SQL tables in the repository database. |
| 204 | 202 | The metadata is designed to facilitate queries for the various timelines and |
| 205 | -reports that Fossil generates. | |
| 203 | +reports that Fossil generates. | |
| 206 | 204 | As the functionality of Fossil evolves, |
| 207 | -the schema for the metadata can and does change from time to time. | |
| 205 | +the schema for the metadata can and does change. | |
| 208 | 206 | But schema changes do no invalidate the repository. Remember that the |
| 209 | 207 | metadata contains no new information - only information that has been |
| 210 | 208 | extracted from the canonical artifacts and saved in a more useful form. |
| 211 | 209 | Hence, when the metadata schema changes, the prior metadata can be discarded |
| 212 | 210 | and the entire metadata corpus can be recomputed from the canonical |
| @@ -273,13 +271,13 @@ | ||
| 273 | 271 | <h4>2.2.5 Shunned Artifact List</h4> |
| 274 | 272 | |
| 275 | 273 | The set of canonical artifacts for a project - the global state for the |
| 276 | 274 | project - is intended to be an append-only database. In other words, |
| 277 | 275 | new artifacts can be added but artifacts can never be removed. But |
| 278 | -it sometimes happens that inappropriate content can be mistakenly or | |
| 279 | -maliciously added to a repository. When that happens, the only way | |
| 280 | -to get rid of the content is to [./shunning.wiki | "shun"] it. | |
| 276 | +it sometimes happens that inappropriate content is mistakenly or | |
| 277 | +maliciously added to a repository. The only way to get rid of | |
| 278 | +the undesired content is to [./shunning.wiki | "shun"] it. | |
| 281 | 279 | The "shun" table in the repository database records the SHA1 hash of |
| 282 | 280 | all shunned artifacts. |
| 283 | 281 | |
| 284 | 282 | The shun table can be pushed or pulled using |
| 285 | 283 | the [/help/config | fossil config] command with the "shun" AREA argument. |
| @@ -289,13 +287,13 @@ | ||
| 289 | 287 | |
| 290 | 288 | Unlike several other popular DVCSes, Fossil allows a single repository |
| 291 | 289 | to have multiple working checkouts. Each working checkout has a single |
| 292 | 290 | database in its root directory that records the state of that checkout. |
| 293 | 291 | The checkout database is named "_FOSSIL_" by default, but can be renamed |
| 294 | -to ".fos" if desired. (Future versions of Fossil might make ".fos" the | |
| 295 | -default name.) The checkout database records information such as the | |
| 296 | -following: | |
| 292 | +to ".fslckout" if desired. (Future versions of Fossil might make | |
| 293 | +".fslckout" the default name.) The checkout database records information | |
| 294 | +such as the following: | |
| 297 | 295 | |
| 298 | 296 | * The full pathname of the repository database file. |
| 299 | 297 | * The version that is currently checked out. |
| 300 | 298 | * Files that have been [/help/add | added], |
| 301 | 299 | [/help/rm | removed], or [/help/mv | renamed] but not |
| 302 | 300 |
| --- www/tech_overview.wiki | |
| +++ www/tech_overview.wiki | |
| @@ -5,41 +5,38 @@ | |
| 5 | |
| 6 | <h2>1.0 Introduction</h2> |
| 7 | |
| 8 | At its lowest level, a Fossil repository consists of an unordered set |
| 9 | of immutable "artifacts". You might think of these artifacts as "files", |
| 10 | since in many cases the artifacts exactly correspond to source code files |
| 11 | that are stored in the Fossil repository. But other "control artifacts" |
| 12 | are also included in the mix. These control artifacts define the relationships |
| 13 | between artifacts - which files go together to form a particular |
| 14 | version of the project, who checked in that version and when, what was |
| 15 | the check-in comment, what wiki pages are included with the project, what |
| 16 | are the edit histories of each wiki page, what bug reports or tickets are |
| 17 | included, who contributed to the evolution of each ticket, and so forth, |
| 18 | and so on. This low-level file format is called the "global state" of |
| 19 | the repository, since this is the information that is synced to peer |
| 20 | repositories using push and pull operations. The low-level file format |
| 21 | is also called "enduring" since it is intended to last for many years. |
| 22 | The details of the low-level, enduring, global file format |
| 23 | are [./fileformat.wiki | described separately]. |
| 24 | |
| 25 | This article is about how Fossil is currently implemented. Instead of |
| 26 | dealing with vague abstractions of "enduring file formats" as the |
| 27 | [./fileformat.wiki | that other document] does, this article provides |
| 28 | some detail on how Fossil actually stores information on disk. |
| 29 | |
| 30 | <h2>2.0 Three Databases</h2> |
| 31 | |
| 32 | Fossil stores state information in |
| 33 | [http://www.sqlite.org/ | SQLite] database files. |
| 34 | SQLite keeps an entire relational database, including multiple tables and |
| 35 | indices, in a single disk file. The SQLite library allows the database |
| 36 | files to be efficiently queried and updated using the industry-standard |
| 37 | SQL language. And SQLite makes updates to these database files atomic, |
| 38 | even if a system crashes or power failure occurs in the middle of the |
| 39 | update, meaning that repository content is protected even during severe |
| 40 | malfunctions. |
| 41 | |
| 42 | Fossil uses three separate classes of SQLite databases: |
| 43 | |
| 44 | <ol> |
| 45 | <li>The configuration database |
| @@ -152,14 +149,15 @@ | |
| 152 | The artifacts are stored as BLOBs, compressed using |
| 153 | [http://www.zlib.net/ | zlib compression] and, where applicable, |
| 154 | using [./delta_encoder_algorithm.wiki | delta compression]. |
| 155 | The combination of zlib and delta compression results in a considerable |
| 156 | space savings. For the SQLite project, at the time of this writing, |
| 157 | the total size of all artifacts is over 1.7 GB but thanks to the |
| 158 | combined zlib and delta compression, that content only takes up |
| 159 | 51.4 MB of space in the repository database, for a compression ratio |
| 160 | of about 33:1. |
| 161 | |
| 162 | Note that the zlib and delta compression is not an inherent part of the |
| 163 | Fossil file format; it is just an optimization. |
| 164 | The enduring file format for Fossil is the unordered |
| 165 | set of artifacts. The compression techniques are just a detail of |
| @@ -185,11 +183,11 @@ | |
| 185 | |
| 186 | <h4>2.2.2 Project Metadata</h4> |
| 187 | |
| 188 | The global project state information in the repository database is |
| 189 | supplemented by computed metadata that makes querying the project state |
| 190 | more efficient. Metadata includes but information such as the following: |
| 191 | |
| 192 | * The names for all files found in any checkin. |
| 193 | * All check-ins that modify a given file |
| 194 | * Parents and children of each checkin. |
| 195 | * Potential timeline rows. |
| @@ -200,13 +198,13 @@ | |
| 200 | * Current content of each ticket. |
| 201 | * Cross-references between tickets, checkins, and wiki pages. |
| 202 | |
| 203 | The metadata is held in various SQL tables in the repository database. |
| 204 | The metadata is designed to facilitate queries for the various timelines and |
| 205 | reports that Fossil generates. |
| 206 | As the functionality of Fossil evolves, |
| 207 | the schema for the metadata can and does change from time to time. |
| 208 | But schema changes do no invalidate the repository. Remember that the |
| 209 | metadata contains no new information - only information that has been |
| 210 | extracted from the canonical artifacts and saved in a more useful form. |
| 211 | Hence, when the metadata schema changes, the prior metadata can be discarded |
| 212 | and the entire metadata corpus can be recomputed from the canonical |
| @@ -273,13 +271,13 @@ | |
| 273 | <h4>2.2.5 Shunned Artifact List</h4> |
| 274 | |
| 275 | The set of canonical artifacts for a project - the global state for the |
| 276 | project - is intended to be an append-only database. In other words, |
| 277 | new artifacts can be added but artifacts can never be removed. But |
| 278 | it sometimes happens that inappropriate content can be mistakenly or |
| 279 | maliciously added to a repository. When that happens, the only way |
| 280 | to get rid of the content is to [./shunning.wiki | "shun"] it. |
| 281 | The "shun" table in the repository database records the SHA1 hash of |
| 282 | all shunned artifacts. |
| 283 | |
| 284 | The shun table can be pushed or pulled using |
| 285 | the [/help/config | fossil config] command with the "shun" AREA argument. |
| @@ -289,13 +287,13 @@ | |
| 289 | |
| 290 | Unlike several other popular DVCSes, Fossil allows a single repository |
| 291 | to have multiple working checkouts. Each working checkout has a single |
| 292 | database in its root directory that records the state of that checkout. |
| 293 | The checkout database is named "_FOSSIL_" by default, but can be renamed |
| 294 | to ".fos" if desired. (Future versions of Fossil might make ".fos" the |
| 295 | default name.) The checkout database records information such as the |
| 296 | following: |
| 297 | |
| 298 | * The full pathname of the repository database file. |
| 299 | * The version that is currently checked out. |
| 300 | * Files that have been [/help/add | added], |
| 301 | [/help/rm | removed], or [/help/mv | renamed] but not |
| 302 |
| --- www/tech_overview.wiki | |
| +++ www/tech_overview.wiki | |
| @@ -5,41 +5,38 @@ | |
| 5 | |
| 6 | <h2>1.0 Introduction</h2> |
| 7 | |
| 8 | At its lowest level, a Fossil repository consists of an unordered set |
| 9 | of immutable "artifacts". You might think of these artifacts as "files", |
| 10 | since in many cases the artifacts exactly that. But other "control artifacts" |
| 11 | are also included in the mix. These control artifacts define the relationships |
| 12 | between artifacts - which files go together to form a particular |
| 13 | version of the project, who checked in that version and when, what was |
| 14 | the check-in comment, what wiki pages are included with the project, what |
| 15 | are the edit histories of each wiki page, what bug reports or tickets are |
| 16 | included, who contributed to the evolution of each ticket, and so forth. |
| 17 | This low-level file format is called the "global state" of |
| 18 | the repository, since this is the information that is synced to peer |
| 19 | repositories using push and pull operations. The low-level file format |
| 20 | is also called "enduring" since it is intended to last for many years. |
| 21 | The details of the low-level, enduring, global file format |
| 22 | are [./fileformat.wiki | described separately]. |
| 23 | |
| 24 | This article is about how Fossil is currently implemented. Instead of |
| 25 | dealing with vague abstractions of "enduring file formats" as the |
| 26 | [./fileformat.wiki | other document] does, this article provides |
| 27 | some detail on how Fossil actually stores information on disk. |
| 28 | |
| 29 | <h2>2.0 Three Databases</h2> |
| 30 | |
| 31 | Fossil stores state information in |
| 32 | [http://www.sqlite.org/ | SQLite] database files. |
| 33 | SQLite keeps an entire relational database, including multiple tables and |
| 34 | indices, in a single disk file. The SQLite library allows the database |
| 35 | files to be efficiently queried and updated using the industry-standard |
| 36 | SQL language. SQLite updates are atomic, so even in the event of |
| 37 | a system crashes or power failure the repository content is protected. |
| 38 | |
| 39 | Fossil uses three separate classes of SQLite databases: |
| 40 | |
| 41 | <ol> |
| 42 | <li>The configuration database |
| @@ -152,14 +149,15 @@ | |
| 149 | The artifacts are stored as BLOBs, compressed using |
| 150 | [http://www.zlib.net/ | zlib compression] and, where applicable, |
| 151 | using [./delta_encoder_algorithm.wiki | delta compression]. |
| 152 | The combination of zlib and delta compression results in a considerable |
| 153 | space savings. For the SQLite project, at the time of this writing, |
| 154 | the total size of all artifacts is over 2.0 GB but thanks to the |
| 155 | combined zlib and delta compression, that content only takes up |
| 156 | 32 MB of space in the repository database, for a compression ratio |
| 157 | of about 64:1. The average size of a content BLOB in the database |
| 158 | is around 500 bytes. |
| 159 | |
| 160 | Note that the zlib and delta compression is not an inherent part of the |
| 161 | Fossil file format; it is just an optimization. |
| 162 | The enduring file format for Fossil is the unordered |
| 163 | set of artifacts. The compression techniques are just a detail of |
| @@ -185,11 +183,11 @@ | |
| 183 | |
| 184 | <h4>2.2.2 Project Metadata</h4> |
| 185 | |
| 186 | The global project state information in the repository database is |
| 187 | supplemented by computed metadata that makes querying the project state |
| 188 | more efficient. Metadata includes information such as the following: |
| 189 | |
| 190 | * The names for all files found in any checkin. |
| 191 | * All check-ins that modify a given file |
| 192 | * Parents and children of each checkin. |
| 193 | * Potential timeline rows. |
| @@ -200,13 +198,13 @@ | |
| 198 | * Current content of each ticket. |
| 199 | * Cross-references between tickets, checkins, and wiki pages. |
| 200 | |
| 201 | The metadata is held in various SQL tables in the repository database. |
| 202 | The metadata is designed to facilitate queries for the various timelines and |
| 203 | reports that Fossil generates. |
| 204 | As the functionality of Fossil evolves, |
| 205 | the schema for the metadata can and does change. |
| 206 | But schema changes do no invalidate the repository. Remember that the |
| 207 | metadata contains no new information - only information that has been |
| 208 | extracted from the canonical artifacts and saved in a more useful form. |
| 209 | Hence, when the metadata schema changes, the prior metadata can be discarded |
| 210 | and the entire metadata corpus can be recomputed from the canonical |
| @@ -273,13 +271,13 @@ | |
| 271 | <h4>2.2.5 Shunned Artifact List</h4> |
| 272 | |
| 273 | The set of canonical artifacts for a project - the global state for the |
| 274 | project - is intended to be an append-only database. In other words, |
| 275 | new artifacts can be added but artifacts can never be removed. But |
| 276 | it sometimes happens that inappropriate content is mistakenly or |
| 277 | maliciously added to a repository. The only way to get rid of |
| 278 | the undesired content is to [./shunning.wiki | "shun"] it. |
| 279 | The "shun" table in the repository database records the SHA1 hash of |
| 280 | all shunned artifacts. |
| 281 | |
| 282 | The shun table can be pushed or pulled using |
| 283 | the [/help/config | fossil config] command with the "shun" AREA argument. |
| @@ -289,13 +287,13 @@ | |
| 287 | |
| 288 | Unlike several other popular DVCSes, Fossil allows a single repository |
| 289 | to have multiple working checkouts. Each working checkout has a single |
| 290 | database in its root directory that records the state of that checkout. |
| 291 | The checkout database is named "_FOSSIL_" by default, but can be renamed |
| 292 | to ".fslckout" if desired. (Future versions of Fossil might make |
| 293 | ".fslckout" the default name.) The checkout database records information |
| 294 | such as the following: |
| 295 | |
| 296 | * The full pathname of the repository database file. |
| 297 | * The version that is currently checked out. |
| 298 | * Files that have been [/help/add | added], |
| 299 | [/help/rm | removed], or [/help/mv | renamed] but not |
| 300 |