dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Copyright (c) 2007 D. Richard Hipp dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is free software; you can redistribute it and/or dbda8d6ce9 2007-07-21 drh: ** modify it under the terms of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License version 2 as published by the Free Software Foundation. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is distributed in the hope that it will be useful, dbda8d6ce9 2007-07-21 drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of dbda8d6ce9 2007-07-21 drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dbda8d6ce9 2007-07-21 drh: ** General Public License for more details. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** You should have received a copy of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License along with this library; if not, write to the dbda8d6ce9 2007-07-21 drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, dbda8d6ce9 2007-07-21 drh: ** Boston, MA 02111-1307, USA. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Author contact information: dbda8d6ce9 2007-07-21 drh: ** drh@hwaci.com dbda8d6ce9 2007-07-21 drh: ** http://www.hwaci.com/drh/ dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ******************************************************************************* dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This file contains code used to check-out versions of the project dbda8d6ce9 2007-07-21 drh: ** from the local repository. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: #include "config.h" dbda8d6ce9 2007-07-21 drh: #include "add.h" dbda8d6ce9 2007-07-21 drh: #include <assert.h> dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** COMMAND: add dbda8d6ce9 2007-07-21 drh: ** c9fdb846fb 2007-08-18 drh: ** Usage: %fossil add FILE... 6b85fd173e 2008-05-10 drh: ** 6b85fd173e 2008-05-10 drh: ** Make arrangements to add one or more files to the current checkout 6b85fd173e 2008-05-10 drh: ** at the next commit. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void add_cmd(void){ dbda8d6ce9 2007-07-21 drh: int i; dbda8d6ce9 2007-07-21 drh: int vid; 141c31792b 2008-07-23 drh: Blob repo; dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: db_must_be_within_tree(); dbda8d6ce9 2007-07-21 drh: vid = db_lget_int("checkout",0); dbda8d6ce9 2007-07-21 drh: if( vid==0 ){ dbda8d6ce9 2007-07-21 drh: fossil_panic("no checkout to add to"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_begin_transaction(); 141c31792b 2008-07-23 drh: if( !file_tree_name(g.zRepositoryName, &repo, 0) ){ 141c31792b 2008-07-23 drh: blob_zero(&repo); 141c31792b 2008-07-23 drh: } dbda8d6ce9 2007-07-21 drh: for(i=2; i<g.argc; i++){ dbda8d6ce9 2007-07-21 drh: char *zName; dbda8d6ce9 2007-07-21 drh: char *zPath; dbda8d6ce9 2007-07-21 drh: Blob pathname; dbda8d6ce9 2007-07-21 drh: int isDir; dbda8d6ce9 2007-07-21 drh: c7278fd013 2007-09-22 jnc: zName = mprintf("%/", g.argv[i]); dbda8d6ce9 2007-07-21 drh: isDir = file_isdir(zName); dbda8d6ce9 2007-07-21 drh: if( isDir==1 ) continue; dbda8d6ce9 2007-07-21 drh: if( isDir==0 ){ 20bcbcf2f2 2007-08-08 drh: fossil_fatal("not found: %s", zName); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: if( isDir==2 && access(zName, R_OK) ){ 20bcbcf2f2 2007-08-08 drh: fossil_fatal("cannot open %s", zName); dbda8d6ce9 2007-07-21 drh: } 2ecc407d9b 2008-07-23 drh: file_tree_name(zName, &pathname, 1); dbda8d6ce9 2007-07-21 drh: zPath = blob_str(&pathname); 844718abbf 2008-05-13 drh: if( strcmp(zPath, "manifest")==0 844718abbf 2008-05-13 drh: || strcmp(zPath, "_FOSSIL_")==0 844718abbf 2008-05-13 drh: || strcmp(zPath, "manifest.uuid")==0 141c31792b 2008-07-23 drh: || blob_compare(&pathname, &repo)==0 844718abbf 2008-05-13 drh: ){ 844718abbf 2008-05-13 drh: fossil_warning("cannot add %s", zPath); dbda8d6ce9 2007-07-21 drh: }else{ 844718abbf 2008-05-13 drh: if( !file_is_simple_pathname(zPath) ){ 844718abbf 2008-05-13 drh: fossil_fatal("filename contains illegal characters: %s", zPath); 844718abbf 2008-05-13 drh: } 844718abbf 2008-05-13 drh: if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ 844718abbf 2008-05-13 drh: db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); 844718abbf 2008-05-13 drh: }else{ 844718abbf 2008-05-13 drh: db_multi_exec( 844718abbf 2008-05-13 drh: "INSERT INTO vfile(vid,deleted,rid,mrid,pathname)" 844718abbf 2008-05-13 drh: "VALUES(%d,0,0,0,%Q)", vid, zPath); 844718abbf 2008-05-13 drh: } dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: blob_reset(&pathname); dbda8d6ce9 2007-07-21 drh: free(zName); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_end_transaction(0); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** COMMAND: rm dbda8d6ce9 2007-07-21 drh: ** COMMAND: del dbda8d6ce9 2007-07-21 drh: ** c9fdb846fb 2007-08-18 drh: ** Usage: %fossil rm FILE... c9fdb846fb 2007-08-18 drh: ** or: %fossil del FILE... e146d800ac 2008-11-09 drh: ** dbda8d6ce9 2007-07-21 drh: ** Remove one or more files from the tree. e146d800ac 2008-11-09 drh: ** e146d800ac 2008-11-09 drh: ** This command does not remove the files from disk. It just marks the e146d800ac 2008-11-09 drh: ** files as no longer being part of the project. In other words, future e146d800ac 2008-11-09 drh: ** changes to the named files will not be versioned. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void del_cmd(void){ dbda8d6ce9 2007-07-21 drh: int i; dbda8d6ce9 2007-07-21 drh: int vid; dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: db_must_be_within_tree(); dbda8d6ce9 2007-07-21 drh: vid = db_lget_int("checkout", 0); dbda8d6ce9 2007-07-21 drh: if( vid==0 ){ dbda8d6ce9 2007-07-21 drh: fossil_panic("no checkout to remove from"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_begin_transaction(); dbda8d6ce9 2007-07-21 drh: for(i=2; i<g.argc; i++){ dbda8d6ce9 2007-07-21 drh: char *zName; dbda8d6ce9 2007-07-21 drh: char *zPath; dbda8d6ce9 2007-07-21 drh: Blob pathname; dbda8d6ce9 2007-07-21 drh: c7278fd013 2007-09-22 jnc: zName = mprintf("%/", g.argv[i]); 2ecc407d9b 2008-07-23 drh: file_tree_name(zName, &pathname, 1); dbda8d6ce9 2007-07-21 drh: zPath = blob_str(&pathname); dbda8d6ce9 2007-07-21 drh: if( !db_exists( dbda8d6ce9 2007-07-21 drh: "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ 20bcbcf2f2 2007-08-08 drh: fossil_fatal("not in the repository: %s", zName); dbda8d6ce9 2007-07-21 drh: }else{ dbda8d6ce9 2007-07-21 drh: db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: blob_reset(&pathname); dbda8d6ce9 2007-07-21 drh: free(zName); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0"); e146d800ac 2008-11-09 drh: db_end_transaction(0); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: e146d800ac 2008-11-09 drh: /* e146d800ac 2008-11-09 drh: ** Rename a single file. e146d800ac 2008-11-09 drh: ** e146d800ac 2008-11-09 drh: ** The original name of the file is zOrig. The new filename is zNew. e146d800ac 2008-11-09 drh: */ e146d800ac 2008-11-09 drh: static void mv_one_file(int vid, const char *zOrig, const char *zNew){ e146d800ac 2008-11-09 drh: printf("RENAME %s %s\n", zOrig, zNew); e146d800ac 2008-11-09 drh: db_multi_exec( e146d800ac 2008-11-09 drh: "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d", e146d800ac 2008-11-09 drh: zNew, zOrig, vid e146d800ac 2008-11-09 drh: ); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: e146d800ac 2008-11-09 drh: /* e146d800ac 2008-11-09 drh: ** COMMAND: mv e146d800ac 2008-11-09 drh: ** COMMAND: rename e146d800ac 2008-11-09 drh: ** e146d800ac 2008-11-09 drh: ** Usage: %fossil mv|rename OLDNAME NEWNAME e146d800ac 2008-11-09 drh: ** or: %fossil mv|rename OLDNAME... DIR e146d800ac 2008-11-09 drh: ** e146d800ac 2008-11-09 drh: ** Move or rename one or more files within the tree e146d800ac 2008-11-09 drh: ** 67f44bb301 2008-11-12 kejoki: ** This command does not rename the files on disk. All this command does is e146d800ac 2008-11-09 drh: ** record the fact that filenames have changed so that appropriate notations e146d800ac 2008-11-09 drh: ** can be made at the next commit/checkin. e146d800ac 2008-11-09 drh: */ e146d800ac 2008-11-09 drh: void mv_cmd(void){ e146d800ac 2008-11-09 drh: int i; e146d800ac 2008-11-09 drh: int vid; e146d800ac 2008-11-09 drh: char *zDest; e146d800ac 2008-11-09 drh: Blob dest; e146d800ac 2008-11-09 drh: Stmt q; e146d800ac 2008-11-09 drh: e146d800ac 2008-11-09 drh: db_must_be_within_tree(); e146d800ac 2008-11-09 drh: vid = db_lget_int("checkout", 0); e146d800ac 2008-11-09 drh: if( vid==0 ){ e146d800ac 2008-11-09 drh: fossil_panic("no checkout rename files in"); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: if( g.argc<4 ){ e146d800ac 2008-11-09 drh: usage("OLDNAME NEWNAME"); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: zDest = g.argv[g.argc-1]; e146d800ac 2008-11-09 drh: db_begin_transaction(); e146d800ac 2008-11-09 drh: file_tree_name(zDest, &dest, 1); e146d800ac 2008-11-09 drh: db_multi_exec( e146d800ac 2008-11-09 drh: "UPDATE vfile SET origname=pathname WHERE origname IS NULL;" e146d800ac 2008-11-09 drh: ); e146d800ac 2008-11-09 drh: db_multi_exec( e146d800ac 2008-11-09 drh: "CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);" e146d800ac 2008-11-09 drh: ); e146d800ac 2008-11-09 drh: if( file_isdir(zDest)!=1 ){ e146d800ac 2008-11-09 drh: Blob orig; e146d800ac 2008-11-09 drh: if( g.argc!=4 ){ e146d800ac 2008-11-09 drh: usage("OLDNAME NEWNAME"); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: file_tree_name(g.argv[2], &orig, 1); e146d800ac 2008-11-09 drh: db_multi_exec( e146d800ac 2008-11-09 drh: "INSERT INTO mv VALUES(%B,%B)", &orig, &dest e146d800ac 2008-11-09 drh: ); e146d800ac 2008-11-09 drh: }else{ 9fd8009007 2008-11-09 drh: if( blob_eq(&dest, ".") ){ 9fd8009007 2008-11-09 drh: blob_reset(&dest); 9fd8009007 2008-11-09 drh: }else{ 9fd8009007 2008-11-09 drh: blob_append(&dest, "/", 1); 9fd8009007 2008-11-09 drh: } e146d800ac 2008-11-09 drh: for(i=2; i<g.argc-1; i++){ e146d800ac 2008-11-09 drh: Blob orig; e146d800ac 2008-11-09 drh: char *zOrig; e146d800ac 2008-11-09 drh: int nOrig; e146d800ac 2008-11-09 drh: file_tree_name(g.argv[i], &orig, 1); e146d800ac 2008-11-09 drh: zOrig = blob_str(&orig); e146d800ac 2008-11-09 drh: nOrig = blob_size(&orig); e146d800ac 2008-11-09 drh: db_prepare(&q, e146d800ac 2008-11-09 drh: "SELECT pathname FROM vfile" e146d800ac 2008-11-09 drh: " WHERE vid=%d" e146d800ac 2008-11-09 drh: " AND (pathname='%s' OR pathname GLOB '%s/*')" e146d800ac 2008-11-09 drh: " ORDER BY 1", e146d800ac 2008-11-09 drh: vid, zOrig, zOrig e146d800ac 2008-11-09 drh: ); e146d800ac 2008-11-09 drh: while( db_step(&q)==SQLITE_ROW ){ e146d800ac 2008-11-09 drh: const char *zPath = db_column_text(&q, 0); e146d800ac 2008-11-09 drh: int nPath = db_column_bytes(&q, 0); e146d800ac 2008-11-09 drh: const char *zTail; e146d800ac 2008-11-09 drh: if( nPath==nOrig ){ e146d800ac 2008-11-09 drh: zTail = file_tail(zPath); e146d800ac 2008-11-09 drh: }else{ e146d800ac 2008-11-09 drh: zTail = &zPath[nOrig+1]; e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: db_multi_exec( 9fd8009007 2008-11-09 drh: "INSERT INTO mv VALUES('%s','%s%s')", e146d800ac 2008-11-09 drh: zPath, blob_str(&dest), zTail e146d800ac 2008-11-09 drh: ); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: db_finalize(&q); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: db_prepare(&q, "SELECT f, t FROM mv ORDER BY f"); e146d800ac 2008-11-09 drh: while( db_step(&q)==SQLITE_ROW ){ e146d800ac 2008-11-09 drh: const char *zFrom = db_column_text(&q, 0); e146d800ac 2008-11-09 drh: const char *zTo = db_column_text(&q, 1); e146d800ac 2008-11-09 drh: mv_one_file(vid, zFrom, zTo); e146d800ac 2008-11-09 drh: } e146d800ac 2008-11-09 drh: db_finalize(&q); dbda8d6ce9 2007-07-21 drh: db_end_transaction(0); dbda8d6ce9 2007-07-21 drh: }