Overview
SHA1 Hash: | 9346f2290c84084f4641a48a5e0fc813d1587251 |
---|---|
Date: | 2008-10-17 00:20:21 |
User: | drh |
Comment: | Added the "all" command for things like "fossil all sync". I am not sure "all" is quite the right name for this command, so I may yet change it. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Added src/allrepo.c version [044b203277]
@@ -1,1 +1,143 @@ +/* +** Copyright (c) 2008 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** 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. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains code to implement the "all" command-line method. +*/ +#include "config.h" +#include "allrepo.h" +#include <assert.h> + +/* +** The input string is a filename. Return a new copy of this +** filename if the filename requires quoting due to special characters +** such as spaces in the name. +** +** If the filename cannot be safely quoted, return a NULL pointer. +** +** Space to hold the returned string is obtained from malloc. A new +** string is returned even if no quoting is needed. +*/ +static char *quoteFilename(const char *zFilename){ + int i, c; + int needQuote = 0; + for(i=0; (c = zFilename[i])!=0; i++){ + if( c=='"' ) return 0; + if( isspace(c) ) needQuote = 1; + if( c=='\\' && zFilename[i+1]==0 ) return 0; + if( c=='$' ) return 0; + } + if( needQuote ){ + return mprintf("\"%s\"", zFilename); + }else{ + return mprintf("%s", zFilename); + } +} + + +/* +** COMMAND: all +** +** Usage: %fossil add (list|pull|push|sync) +** +** The ~/.fossil file records the location of all repositories for a +** user. This command performs certain operations on all repositories +** that can be useful before or after a period of disconnection operation. +** Available operations are: +** +** list Display the location of all repositories +** +** pull Run a "pull" operation on all repositories +** +** push Run a "push" on all repositories +** +** sync Run a "sync" on all repositories +*/ +void all_cmd(void){ + int n; + Stmt q; + const char *zCmd; + char *zSyscmd; + char *zFossil; + char *zQFilename; + int nMissing; + + if( g.argc<3 ){ + usage("list|pull|push|sync"); + } + n = strlen(g.argv[2]); + db_open_config(); + db_prepare(&q, "SELECT substr(name, 6) FROM global_config" + " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1"); + zCmd = g.argv[2]; + if( strncmp(zCmd, "list", n)==0 ){ + zCmd = "list"; + }else if( strncmp(zCmd, "push", n)==0 ){ + zCmd = "push"; + }else if( strncmp(zCmd, "pull", n)==0 ){ + zCmd = "pull"; + }else if( strncmp(zCmd, "sync", n)==0 ){ + zCmd = "sync"; + }else{ + fossil_fatal("\"all\" subcommand should be one of: " + "list push pull sync"); + } + zFossil = quoteFilename(g.argv[0]); + nMissing = 0; + while( db_step(&q)==SQLITE_ROW ){ + const char *zFilename = db_column_text(&q, 0); + if( access(zFilename, 0) ){ + nMissing++; + continue; + } + if( zCmd[0]=='l' ){ + printf("%s\n", zFilename); + continue; + } + zQFilename = quoteFilename(zFilename); + zSyscmd = mprintf("%s %s -R %s -autourl", + zFossil, zCmd, zQFilename); + printf("%s\n", zSyscmd); + fflush(stdout); + system(zSyscmd); + free(zSyscmd); + free(zQFilename); + } + /* If any repositories hows names appear in the ~/.fossil file could not + ** be found, remove those names from the ~/.fossil file. + */ + if( nMissing ){ + db_begin_transaction(); + db_reset(&q); + while( db_step(&q)==SQLITE_ROW ){ + const char *zFilename = db_column_text(&q, 0); + if( access(zFilename, 0) ){ + const char *zRepo = mprintf("repo:%s", zFilename); + db_unset(zRepo, 1); + free(zRepo); + } + } + db_finalize(&q); + db_end_transaction(0); + } +}
Modified src/checkin.c from [425f4bbcea] to [4a866358e3].
@@ -46,11 +46,13 @@ int isDeleted = db_column_int(&q, 1); int isChnged = db_column_int(&q,2); int isNew = db_column_int(&q,3)==0; char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname); blob_append(report, zPrefix, nPrefix); - if( access(zFullName, 0) ){ + if( isDeleted ){ + blob_appendf(report, "DELETED %s\n", zPathname); + }else if( access(zFullName, 0) ){ blob_appendf(report, "MISSING %s\n", zPathname); }else if( isNew ){ blob_appendf(report, "ADDED %s\n", zPathname); }else if( isDeleted ){ blob_appendf(report, "DELETED %s\n", zPathname); @@ -398,10 +400,11 @@ if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){ fossil_fatal("no such user: %s", g.zLogin); } db_begin_transaction(); + db_record_repository_filename(0); rc = unsaved_changes(); if( rc==0 && !isAMerge && !forceFlag ){ fossil_panic("nothing has changed"); }
Modified src/db.c from [b821ea8fc7] to [d2615a7db8].
@@ -555,10 +555,11 @@ ** it does not already exist. */ void db_open_config(void){ char *zDbName; const char *zHome; + if( g.configOpen ) return; #ifdef __MINGW32__ zHome = getenv("LOCALAPPDATA"); if( zHome==0 ){ zHome = getenv("APPDATA"); if( zHome==0 ){ @@ -575,11 +576,10 @@ /* . filenames give some window systems problems and many apps problems */ zDbName = mprintf("%//_fossil", zHome); #else zDbName = mprintf("%s/.fossil", zHome); #endif - if( g.configOpen ) return; if( file_size(zDbName)<1024*3 ){ db_init_database(zDbName, zConfigSchema, (char*)0); } db_open_or_attach(zDbName, "configdb"); g.configOpen = 1; @@ -1120,10 +1120,31 @@ void db_lset_int(const char *zName, int value){ db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value); } /* +** Record the name of a local repository in the global_config() database. +** The repostiroy filename %s is recorded as an entry with a "name" field +** of the following form: +** +** repo:%s +** +** The value field is set to 1. +*/ +void db_record_repository_filename(const char *zName){ + if( zName==0 ){ + if( !g.localOpen ) return; + zName = db_lget("repository", 0); + } + db_multi_exec( + "INSERT OR IGNORE INTO global_config(name,value)" + "VALUES('repo:%q',1)", + zName + ); +} + +/* ** COMMAND: open ** ** Usage: open FILENAME ** ** Open a connection to the local repository in FILENAME. A checkout @@ -1144,10 +1165,11 @@ file_canonical_name(g.argv[2], &path); db_open_repository(blob_str(&path)); db_init_database("./_FOSSIL_", zLocalSchema, (char*)0); db_open_local(); db_lset("repository", blob_str(&path)); + db_record_repository_filename(blob_str(&path)); vid = db_int(0, "SELECT pid FROM plink y" " WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)"); if( vid==0 ){ db_lset_int("checkout", 1); }else{
Modified src/main.mk from [441865bbd2] to [4242635d97].
@@ -13,10 +13,11 @@ SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/admin.c \ + $(SRCDIR)/allrepo.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ $(SRCDIR)/browse.c \ $(SRCDIR)/cgi.c \ @@ -79,10 +80,11 @@ $(SRCDIR)/zip.c TRANS_SRC = \ add_.c \ admin_.c \ + allrepo_.c \ bag_.c \ blob_.c \ branch_.c \ browse_.c \ cgi_.c \ @@ -145,10 +147,11 @@ zip_.c OBJ = \ add.o \ admin.o \ + allrepo.o \ bag.o \ blob.o \ branch.o \ browse.o \ cgi.o \ @@ -249,16 +252,16 @@ # noop clean: rm -f *.o *_.c $(APPNAME) VERSION.h rm -f translate makeheaders mkindex page_index.h headers - rm -f add.h admin.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h construct.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h schema.h setup.h sha1.h shun.h stat.h style.h sync.h tag.h tagview.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h + rm -f add.h admin.h allrepo.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h construct.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h schema.h setup.h sha1.h shun.h stat.h style.h sync.h tag.h tagview.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h page_index.h: $(TRANS_SRC) mkindex ./mkindex $(TRANS_SRC) >$@ -headers: page_index.h makeheaders $(TRANS_SRC) VERSION.h - ./makeheaders add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h +headers: page_index.h makeheaders VERSION.h + ./makeheaders add_.c:add.h admin_.c:admin.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h touch headers headers: Makefile Makefile: add_.c: $(SRCDIR)/add.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/add.c | sed -f $(SRCDIR)/VERSION >add_.c @@ -272,10 +275,17 @@ admin.o: admin_.c admin.h $(SRCDIR)/config.h $(XTCC) -o admin.o -c admin_.c admin.h: headers +allrepo_.c: $(SRCDIR)/allrepo.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/allrepo.c | sed -f $(SRCDIR)/VERSION >allrepo_.c + +allrepo.o: allrepo_.c allrepo.h $(SRCDIR)/config.h + $(XTCC) -o allrepo.o -c allrepo_.c + +allrepo.h: headers bag_.c: $(SRCDIR)/bag.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/bag.c | sed -f $(SRCDIR)/VERSION >bag_.c bag.o: bag_.c bag.h $(SRCDIR)/config.h $(XTCC) -o bag.o -c bag_.c
Modified src/makemake.tcl from [cffe151e34] to [a62edbeae5].
@@ -7,10 +7,11 @@ # "translate" and "makeheaders" # set src { add admin + allrepo bag blob branch browse cgi
Modified src/sync.c from [4404bbdd39] to [c4538ea75a].
@@ -72,18 +72,20 @@ ** of a server to sync against. If no argument is given, use the ** most recently synced URL. Remember the current URL for next time. */ void process_sync_args(void){ const char *zUrl = 0; + int urlOptional = find_option("autourl",0,0)!=0; url_proxy_options(); db_find_and_open_repository(1); if( g.argc==2 ){ zUrl = db_get("last-sync-url", 0); }else if( g.argc==3 ){ zUrl = g.argv[2]; } if( zUrl==0 ){ + if( urlOptional ) exit(0); usage("URL"); } url_parse(zUrl); if( g.urlIsFile ){ fossil_fatal("network sync only");
Modified src/xfer.c from [4b3dcbe795] to [cdde3a92c3].
@@ -818,10 +818,13 @@ assert( pushFlag || pullFlag || cloneFlag || configMask ); assert( !g.urlIsFile ); /* This only works for networking */ db_begin_transaction(); + if( pullFlag || cloneFlag ){ + db_record_repository_filename(0); + } db_multi_exec( "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" ); blobarray_zero(xfer.aToken, count(xfer.aToken)); blob_zero(&send);