File Annotation
Not logged in
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: **
b7a93530ef 2008-02-01       aku: ** This file contains code used to check-in 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 "checkin.h"
dbda8d6ce9 2007-07-21       drh: #include <assert.h>
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Generate text describing all changes.  Prepend zPrefix to each line
dbda8d6ce9 2007-07-21       drh: ** of output.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** We assume that vfile_check_signature has been run.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: static void status_report(Blob *report, const char *zPrefix){
dbda8d6ce9 2007-07-21       drh:   Stmt q;
dbda8d6ce9 2007-07-21       drh:   int nPrefix = strlen(zPrefix);
22552fb803 2007-08-03       dan:   db_prepare(&q,
e146d800ac 2008-11-09       drh:     "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
e146d800ac 2008-11-09       drh:     "  FROM vfile "
e146d800ac 2008-11-09       drh:     " WHERE file_is_selected(id)"
e146d800ac 2008-11-09       drh:     "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
22552fb803 2007-08-03       dan:   );
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zPathname = db_column_text(&q,0);
dbda8d6ce9 2007-07-21       drh:     int isDeleted = db_column_int(&q, 1);
dbda8d6ce9 2007-07-21       drh:     int isChnged = db_column_int(&q,2);
dbda8d6ce9 2007-07-21       drh:     int isNew = db_column_int(&q,3)==0;
e146d800ac 2008-11-09       drh:     int isRenamed = db_column_int(&q,4);
371dd6574c 2007-12-04       drh:     char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
dbda8d6ce9 2007-07-21       drh:     blob_append(report, zPrefix, nPrefix);
9346f2290c 2008-10-17       drh:     if( isDeleted ){
9346f2290c 2008-10-17       drh:       blob_appendf(report, "DELETED  %s\n", zPathname);
9346f2290c 2008-10-17       drh:     }else if( access(zFullName, 0) ){
371dd6574c 2007-12-04       drh:       blob_appendf(report, "MISSING  %s\n", zPathname);
371dd6574c 2007-12-04       drh:     }else if( isNew ){
dbda8d6ce9 2007-07-21       drh:       blob_appendf(report, "ADDED    %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }else if( isDeleted ){
dbda8d6ce9 2007-07-21       drh:       blob_appendf(report, "DELETED  %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }else if( isChnged==2 ){
dbda8d6ce9 2007-07-21       drh:       blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }else if( isChnged==3 ){
dbda8d6ce9 2007-07-21       drh:       blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname);
e146d800ac 2008-11-09       drh:     }else if( isChnged==1 ){
dbda8d6ce9 2007-07-21       drh:       blob_appendf(report, "EDITED   %s\n", zPathname);
e146d800ac 2008-11-09       drh:     }else if( isRenamed ){
e146d800ac 2008-11-09       drh:       blob_appendf(report, "RENAMED  %s\n", zPathname);
371dd6574c 2007-12-04       drh:     }
371dd6574c 2007-12-04       drh:     free(zFullName);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid"
dbda8d6ce9 2007-07-21       drh:                  " WHERE id=0");
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     blob_append(report, zPrefix, nPrefix);
dbda8d6ce9 2007-07-21       drh:     blob_appendf(report, "MERGED_WITH %s\n", db_column_text(&q, 0));
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** COMMAND: changes
dbda8d6ce9 2007-07-21       drh: **
c9fdb846fb 2007-08-18       drh: ** Usage: %fossil changes
6b85fd173e 2008-05-10       drh: **
c9fdb846fb 2007-08-18       drh: ** Report on the edit status of all files in the current checkout.
c9fdb846fb 2007-08-18       drh: ** See also the "status" and "extra" commands.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void changes_cmd(void){
dbda8d6ce9 2007-07-21       drh:   Blob report;
dbda8d6ce9 2007-07-21       drh:   int vid;
dbda8d6ce9 2007-07-21       drh:   db_must_be_within_tree();
dbda8d6ce9 2007-07-21       drh:   blob_zero(&report);
dbda8d6ce9 2007-07-21       drh:   vid = db_lget_int("checkout", 0);
dbda8d6ce9 2007-07-21       drh:   vfile_check_signature(vid);
dbda8d6ce9 2007-07-21       drh:   status_report(&report, "");
dbda8d6ce9 2007-07-21       drh:   blob_write_to_file(&report, "-");
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** COMMAND: status
6b85fd173e 2008-05-10       drh: **
c9fdb846fb 2007-08-18       drh: ** Usage: %fossil status
6b85fd173e 2008-05-10       drh: **
c9fdb846fb 2007-08-18       drh: ** Report on the status of the current checkout.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void status_cmd(void){
dbda8d6ce9 2007-07-21       drh:   int vid;
dbda8d6ce9 2007-07-21       drh:   db_must_be_within_tree();
dbda8d6ce9 2007-07-21       drh:        /* 012345678901234 */
dbda8d6ce9 2007-07-21       drh:   printf("repository:   %s\n", db_lget("repository",""));
dbda8d6ce9 2007-07-21       drh:   printf("local-root:   %s\n", g.zLocalRoot);
dbda8d6ce9 2007-07-21       drh:   printf("server-code:  %s\n", db_get("server-code", ""));
dbda8d6ce9 2007-07-21       drh:   vid = db_lget_int("checkout", 0);
dbda8d6ce9 2007-07-21       drh:   if( vid ){
dbda8d6ce9 2007-07-21       drh:     show_common_info(vid, "checkout:", 0);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   changes_cmd();
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** COMMAND: ls
dbda8d6ce9 2007-07-21       drh: **
c9fdb846fb 2007-08-18       drh: ** Usage: %fossil ls
6b85fd173e 2008-05-10       drh: **
c9fdb846fb 2007-08-18       drh: ** Show the names of all files in the current checkout
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void ls_cmd(void){
dbda8d6ce9 2007-07-21       drh:   int vid;
dbda8d6ce9 2007-07-21       drh:   Stmt q;
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:   vfile_check_signature(vid);
e146d800ac 2008-11-09       drh:   db_prepare(&q,
e146d800ac 2008-11-09       drh:      "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
e146d800ac 2008-11-09       drh:      "  FROM vfile"
e146d800ac 2008-11-09       drh:      " ORDER BY 1"
e146d800ac 2008-11-09       drh:   );
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zPathname = db_column_text(&q,0);
dbda8d6ce9 2007-07-21       drh:     int isDeleted = db_column_int(&q, 1);
dbda8d6ce9 2007-07-21       drh:     int isNew = db_column_int(&q,2)==0;
dbda8d6ce9 2007-07-21       drh:     int chnged = db_column_int(&q,3);
e146d800ac 2008-11-09       drh:     int renamed = db_column_int(&q,4);
89d100b845 2008-10-31       drh:     char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
dbda8d6ce9 2007-07-21       drh:     if( isNew ){
dbda8d6ce9 2007-07-21       drh:       printf("ADDED     %s\n", zPathname);
89d100b845 2008-10-31       drh:     }else if( access(zFullName, 0) ){
89d100b845 2008-10-31       drh:       printf("MISSING   %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }else if( isDeleted ){
dbda8d6ce9 2007-07-21       drh:       printf("DELETED   %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }else if( chnged ){
dbda8d6ce9 2007-07-21       drh:       printf("EDITED    %s\n", zPathname);
e146d800ac 2008-11-09       drh:     }else if( renamed ){
e146d800ac 2008-11-09       drh:       printf("RENAMED   %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }else{
dbda8d6ce9 2007-07-21       drh:       printf("UNCHANGED %s\n", zPathname);
dbda8d6ce9 2007-07-21       drh:     }
89d100b845 2008-10-31       drh:     free(zFullName);
c9fdb846fb 2007-08-18       drh:   }
c9fdb846fb 2007-08-18       drh:   db_finalize(&q);
c9fdb846fb 2007-08-18       drh: }
c9fdb846fb 2007-08-18       drh: 
c9fdb846fb 2007-08-18       drh: /*
554d896209 2009-08-09       bch: ** COMMAND: extras
554d896209 2009-08-09       bch: ** Usage: %fossil extras
6b85fd173e 2008-05-10       drh: **
c9fdb846fb 2007-08-18       drh: ** Print a list of all files in the source tree that are not part of
c9fdb846fb 2007-08-18       drh: ** the current checkout.  See also the "clean" command.
c9fdb846fb 2007-08-18       drh: */
c9fdb846fb 2007-08-18       drh: void extra_cmd(void){
c9fdb846fb 2007-08-18       drh:   Blob path;
2ecc407d9b 2008-07-23       drh:   Blob repo;
c9fdb846fb 2007-08-18       drh:   Stmt q;
849b94c631 2008-07-17       drh:   int n;
c9fdb846fb 2007-08-18       drh:   db_must_be_within_tree();
c9fdb846fb 2007-08-18       drh:   db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
849b94c631 2008-07-17       drh:   n = strlen(g.zLocalRoot);
849b94c631 2008-07-17       drh:   blob_init(&path, g.zLocalRoot, n-1);
849b94c631 2008-07-17       drh:   vfile_scan(0, &path, blob_size(&path));
c9fdb846fb 2007-08-18       drh:   db_prepare(&q,
c9fdb846fb 2007-08-18       drh:       "SELECT x FROM sfile"
95e17f4e3f 2007-08-25       drh:       " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
c9fdb846fb 2007-08-18       drh:       " ORDER BY 1");
2ecc407d9b 2008-07-23       drh:   if( file_tree_name(g.zRepositoryName, &repo, 0) ){
2ecc407d9b 2008-07-23       drh:     db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
2ecc407d9b 2008-07-23       drh:   }
c9fdb846fb 2007-08-18       drh:   while( db_step(&q)==SQLITE_ROW ){
c9fdb846fb 2007-08-18       drh:     printf("%s\n", db_column_text(&q, 0));
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
c9fdb846fb 2007-08-18       drh: ** COMMAND: clean
6b85fd173e 2008-05-10       drh: ** Usage: %fossil clean ?-all?
6b85fd173e 2008-05-10       drh: **
c9fdb846fb 2007-08-18       drh: ** Delete all "extra" files in the source tree.  "Extra" files are
c9fdb846fb 2007-08-18       drh: ** files that are not officially part of the checkout.  See also
8372cc0b81 2007-09-22       jnc: ** the "extra" command. This operation cannot be undone.
8372cc0b81 2007-09-22       jnc: **
8372cc0b81 2007-09-22       jnc: ** You will be prompted before removing each file. If you are
8372cc0b81 2007-09-22       jnc: ** sure you wish to remove all "extra" files you can specify the
8372cc0b81 2007-09-22       jnc: ** optional -all flag.
dbda8d6ce9 2007-07-21       drh: */
c9fdb846fb 2007-08-18       drh: void clean_cmd(void){
8372cc0b81 2007-09-22       jnc:   int allFlag;
2ecc407d9b 2008-07-23       drh:   Blob path, repo;
dbda8d6ce9 2007-07-21       drh:   Stmt q;
849b94c631 2008-07-17       drh:   int n;
8372cc0b81 2007-09-22       jnc:   allFlag = find_option("all","a",0)!=0;
dbda8d6ce9 2007-07-21       drh:   db_must_be_within_tree();
dbda8d6ce9 2007-07-21       drh:   db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
849b94c631 2008-07-17       drh:   n = strlen(g.zLocalRoot);
849b94c631 2008-07-17       drh:   blob_init(&path, g.zLocalRoot, n-1);
849b94c631 2008-07-17       drh:   vfile_scan(0, &path, blob_size(&path));
77327ae14e 2007-08-08       drh:   db_prepare(&q,
c9fdb846fb 2007-08-18       drh:       "SELECT %Q || x FROM sfile"
95e17f4e3f 2007-08-25       drh:       " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
c9fdb846fb 2007-08-18       drh:       " ORDER BY 1", g.zLocalRoot);
2ecc407d9b 2008-07-23       drh:   if( file_tree_name(g.zRepositoryName, &repo, 0) ){
2ecc407d9b 2008-07-23       drh:     db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
2ecc407d9b 2008-07-23       drh:   }
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
8372cc0b81 2007-09-22       jnc:     if( allFlag ){
8372cc0b81 2007-09-22       jnc:       unlink(db_column_text(&q, 0));
820a1a1a53 2007-09-23       drh:     }else{
820a1a1a53 2007-09-23       drh:       Blob ans;
820a1a1a53 2007-09-23       drh:       char *prompt = mprintf("remove unmanaged file \"%s\" [y/N]? ",
820a1a1a53 2007-09-23       drh:                               db_column_text(&q, 0));
820a1a1a53 2007-09-23       drh:       blob_zero(&ans);
820a1a1a53 2007-09-23       drh:       prompt_user(prompt, &ans);
820a1a1a53 2007-09-23       drh:       if( blob_str(&ans)[0]=='y' ){
820a1a1a53 2007-09-23       drh:         unlink(db_column_text(&q, 0));
820a1a1a53 2007-09-23       drh:       }
8372cc0b81 2007-09-22       jnc:     }
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Prepare a commit comment.  Let the user modify it using the
dbda8d6ce9 2007-07-21       drh: ** editor specified in the global_config table or either
dbda8d6ce9 2007-07-21       drh: ** the VISUAL or EDITOR environment variable.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Store the final commit comment in pComment.  pComment is assumed
dbda8d6ce9 2007-07-21       drh: ** to be uninitialized - any prior content is overwritten.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: static void prepare_commit_comment(Blob *pComment){
dbda8d6ce9 2007-07-21       drh:   const char *zEditor;
dbda8d6ce9 2007-07-21       drh:   char *zCmd;
dbda8d6ce9 2007-07-21       drh:   char *zFile;
dbda8d6ce9 2007-07-21       drh:   Blob text, line;
dbda8d6ce9 2007-07-21       drh:   char *zComment;
dbda8d6ce9 2007-07-21       drh:   int i;
dbda8d6ce9 2007-07-21       drh:   blob_set(&text,
6f0a9f730b 2008-11-26       drh:     "\n"
6f0a9f730b 2008-11-26       drh:     "# Enter comments on this check-in.  Lines beginning with # are ignored.\n"
6f0a9f730b 2008-11-26       drh:     "# The check-in comment follows wiki formatting rules.\n"
dbda8d6ce9 2007-07-21       drh:     "#\n"
dbda8d6ce9 2007-07-21       drh:   );
dbda8d6ce9 2007-07-21       drh:   status_report(&text, "# ");
134e2aeccc 2007-09-28       drh:   zEditor = db_get("editor", 0);
dbda8d6ce9 2007-07-21       drh:   if( zEditor==0 ){
dbda8d6ce9 2007-07-21       drh:     zEditor = getenv("VISUAL");
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   if( zEditor==0 ){
dbda8d6ce9 2007-07-21       drh:     zEditor = getenv("EDITOR");
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   if( zEditor==0 ){
baf68cc18f 2008-08-11       drh: #ifdef __MINGW32__
baf68cc18f 2008-08-11       drh:     zEditor = "notepad";
baf68cc18f 2008-08-11       drh: #else
dbda8d6ce9 2007-07-21       drh:     zEditor = "ed";
baf68cc18f 2008-08-11       drh: #endif
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'",
dbda8d6ce9 2007-07-21       drh:                    g.zLocalRoot);
e976aa6fcb 2008-06-08       drh: #ifdef __MINGW32__
e976aa6fcb 2008-06-08       drh:   blob_add_cr(&text);
e976aa6fcb 2008-06-08       drh: #endif
dbda8d6ce9 2007-07-21       drh:   blob_write_to_file(&text, zFile);
8372cc0b81 2007-09-22       jnc:   zCmd = mprintf("%s \"%s\"", zEditor, zFile);
c9fdb846fb 2007-08-18       drh:   printf("%s\n", zCmd);
dbda8d6ce9 2007-07-21       drh:   if( system(zCmd) ){
dbda8d6ce9 2007-07-21       drh:     fossil_panic("editor aborted");
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   blob_reset(&text);
dbda8d6ce9 2007-07-21       drh:   blob_read_from_file(&text, zFile);
e976aa6fcb 2008-06-08       drh:   blob_remove_cr(&text);
dbda8d6ce9 2007-07-21       drh:   unlink(zFile);
dbda8d6ce9 2007-07-21       drh:   free(zFile);
dbda8d6ce9 2007-07-21       drh:   blob_zero(pComment);
dbda8d6ce9 2007-07-21       drh:   while( blob_line(&text, &line) ){
dbda8d6ce9 2007-07-21       drh:     int i, n;
dbda8d6ce9 2007-07-21       drh:     char *z;
dbda8d6ce9 2007-07-21       drh:     n = blob_size(&line);
dbda8d6ce9 2007-07-21       drh:     z = blob_buffer(&line);
dbda8d6ce9 2007-07-21       drh:     for(i=0; i<n && isspace(z[i]);  i++){}
dbda8d6ce9 2007-07-21       drh:     if( i<n && z[i]=='#' ) continue;
f030c0aea7 2007-08-30       drh:     if( i<n || blob_size(pComment)>0 ){
f030c0aea7 2007-08-30       drh:       blob_appendf(pComment, "%b", &line);
f030c0aea7 2007-08-30       drh:     }
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   blob_reset(&text);
dbda8d6ce9 2007-07-21       drh:   zComment = blob_str(pComment);
dbda8d6ce9 2007-07-21       drh:   i = strlen(zComment);
dbda8d6ce9 2007-07-21       drh:   while( i>0 && isspace(zComment[i-1]) ){ i--; }
dbda8d6ce9 2007-07-21       drh:   blob_resize(pComment, i);
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
22552fb803 2007-08-03       dan: ** Populate the Global.aCommitFile[] based on the command line arguments
22552fb803 2007-08-03       dan: ** to a [commit] command. Global.aCommitFile is an array of integers
22552fb803 2007-08-03       dan: ** sized at (N+1), where N is the number of arguments passed to [commit].
22552fb803 2007-08-03       dan: ** The contents are the [id] values from the vfile table corresponding
22552fb803 2007-08-03       dan: ** to the filenames passed as arguments.
22552fb803 2007-08-03       dan: **
22552fb803 2007-08-03       dan: ** The last element of aCommitFile[] is always 0 - indicating the end
22552fb803 2007-08-03       dan: ** of the array.
22552fb803 2007-08-03       dan: **
22552fb803 2007-08-03       dan: ** If there were no arguments passed to [commit], aCommitFile is not
22552fb803 2007-08-03       dan: ** allocated and remains NULL. Other parts of the code interpret this
22552fb803 2007-08-03       dan: ** to mean "all files".
22552fb803 2007-08-03       dan: */
22552fb803 2007-08-03       dan: void select_commit_files(void){
22552fb803 2007-08-03       dan:   if( g.argc>2 ){
22552fb803 2007-08-03       dan:     int ii;
22552fb803 2007-08-03       dan:     Blob b;
aafd536a5c 2007-08-04       drh:     blob_zero(&b);
22552fb803 2007-08-03       dan:     g.aCommitFile = malloc(sizeof(int)*(g.argc-1));
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:     for(ii=2; ii<g.argc; ii++){
22552fb803 2007-08-03       dan:       int iId;
2ecc407d9b 2008-07-23       drh:       file_tree_name(g.argv[ii], &b, 1);
22552fb803 2007-08-03       dan:       iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
22552fb803 2007-08-03       dan:       if( iId<0 ){
22552fb803 2007-08-03       dan:         fossil_fatal("fossil knows nothing about: %s", g.argv[ii]);
22552fb803 2007-08-03       dan:       }
22552fb803 2007-08-03       dan:       g.aCommitFile[ii-2] = iId;
aafd536a5c 2007-08-04       drh:       blob_reset(&b);
22552fb803 2007-08-03       dan:     }
22552fb803 2007-08-03       dan:     g.aCommitFile[ii-2] = 0;
22552fb803 2007-08-03       dan:   }
22552fb803 2007-08-03       dan: }
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan: /*
faf09dc7ae 2009-01-22       drh: ** Return true if the check-in with RID=rid is a leaf.
42c2a18e73 2009-01-22       drh: ** A leaf has no children in the same branch.
b6e22e62cf 2009-01-20       drh: */
b7f32a71ab 2009-01-20       drh: int is_a_leaf(int rid){
42c2a18e73 2009-01-22       drh:   int rc;
faf09dc7ae 2009-01-22       drh:   static const char zSql[] =
42c2a18e73 2009-01-22       drh:     @ SELECT 1 FROM plink
42c2a18e73 2009-01-22       drh:     @  WHERE pid=%d
42c2a18e73 2009-01-22       drh:     @    AND coalesce((SELECT value FROM tagxref
42c2a18e73 2009-01-22       drh:     @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
42c2a18e73 2009-01-22       drh:     @       =coalesce((SELECT value FROM tagxref
42c2a18e73 2009-01-22       drh:     @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
faf09dc7ae 2009-01-22       drh:   ;
42c2a18e73 2009-01-22       drh:   rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
42c2a18e73 2009-01-22       drh:   return rc==0;
b6e22e62cf 2009-01-20       drh: }
b6e22e62cf 2009-01-20       drh: 
b6e22e62cf 2009-01-20       drh: /*
2bde9f9b3d 2008-10-21       drh: ** COMMAND: ci
dbda8d6ce9 2007-07-21       drh: ** COMMAND: commit
dbda8d6ce9 2007-07-21       drh: **
4ac75b9107 2009-01-24       drh: ** Usage: %fossil commit ?OPTIONS? ?FILE...?
c9fdb846fb 2007-08-18       drh: **
dbda8d6ce9 2007-07-21       drh: ** Create a new version containing all of the changes in the current
c9fdb846fb 2007-08-18       drh: ** checkout.  You will be prompted to enter a check-in comment unless
4c78a18ad2 2008-08-14       bch: ** the "-m" option is used to specify a comment line.  You will be
c9fdb846fb 2007-08-18       drh: ** prompted for your GPG passphrase in order to sign the new manifest
c9fdb846fb 2007-08-18       drh: ** unless the "--nosign" options is used.  All files that have
c9fdb846fb 2007-08-18       drh: ** changed will be committed unless some subset of files is specified
c9fdb846fb 2007-08-18       drh: ** on the command line.
4ac75b9107 2009-01-24       drh: **
4ac75b9107 2009-01-24       drh: ** The --branch option followed by a branch name cases the new check-in
4ac75b9107 2009-01-24       drh: ** to be placed in the named branch.  The --bgcolor option can be followed
4ac75b9107 2009-01-24       drh: ** by a color name (ex:  '#ffc0c0') to specify the background color of
4ac75b9107 2009-01-24       drh: ** entries in the new branch when shown in the web timeline interface.
4ac75b9107 2009-01-24       drh: **
4ac75b9107 2009-01-24       drh: ** A check-in is not permitted to fork unless the --force or -f
4ac75b9107 2009-01-24       drh: ** option appears.  A check-in is not allowed against a closed check-in.
4ac75b9107 2009-01-24       drh: **
4ac75b9107 2009-01-24       drh: ** Options:
22552fb803 2007-08-03       dan: **
4ac75b9107 2009-01-24       drh: **    --comment|-m COMMENT-TEXT
4ac75b9107 2009-01-24       drh: **    --branch NEW-BRANCH-NAME
4ac75b9107 2009-01-24       drh: **    --bgcolor COLOR
4ac75b9107 2009-01-24       drh: **    --nosign
4ac75b9107 2009-01-24       drh: **    --force|-f
4ac75b9107 2009-01-24       drh: **
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void commit_cmd(void){
dbda8d6ce9 2007-07-21       drh:   int rc;
dbda8d6ce9 2007-07-21       drh:   int vid, nrid, nvid;
dbda8d6ce9 2007-07-21       drh:   Blob comment;
9a9cd81738 2007-08-09       drh:   const char *zComment;
dbda8d6ce9 2007-07-21       drh:   Stmt q;
dbda8d6ce9 2007-07-21       drh:   Stmt q2;
dbda8d6ce9 2007-07-21       drh:   char *zUuid, *zDate;
6aff11f03f 2007-08-03       drh:   int noSign = 0;        /* True to omit signing the manifest using GPG */
4c82c7773f 2007-08-30       drh:   int isAMerge = 0;      /* True if checking in a merge */
fff234b77c 2007-09-25       drh:   int forceFlag = 0;     /* Force a fork */
dbda8d6ce9 2007-07-21       drh:   char *zManifestFile;   /* Name of the manifest file */
33c31f73cd 2008-02-21       drh:   int nBasename;         /* Length of "g.zLocalRoot/" */
4ac75b9107 2009-01-24       drh:   const char *zBranch;   /* Create a new branch with this name */
4ac75b9107 2009-01-24       drh:   const char *zBgColor;  /* Set background color when branching */
f6790b7c3c 2009-02-26       drh:   const char *zDateOvrd; /* Override date string */
8b630bb57a 2009-08-08       drh:   const char *zUserOvrd; /* Override user name */
33c31f73cd 2008-02-21       drh:   Blob filename;         /* complete filename */
dbda8d6ce9 2007-07-21       drh:   Blob manifest;
741aac4d4e 2007-08-25       drh:   Blob muuid;            /* Manifest uuid */
dbda8d6ce9 2007-07-21       drh:   Blob mcksum;           /* Self-checksum on the manifest */
dbda8d6ce9 2007-07-21       drh:   Blob cksum1, cksum2;   /* Before and after commit checksums */
3945057916 2007-08-01       drh:   Blob cksum1b;          /* Checksum recorded in the manifest */
3945057916 2007-08-01       drh: 
b714ab1ea7 2008-05-07       drh:   url_proxy_options();
4ac75b9107 2009-01-24       drh:   noSign = find_option("nosign",0,0)!=0;
9a9cd81738 2007-08-09       drh:   zComment = find_option("comment","m",1);
e0580dfeee 2008-02-04       drh:   forceFlag = find_option("force", "f", 0)!=0;
4ac75b9107 2009-01-24       drh:   zBranch = find_option("branch","b",1);
4ac75b9107 2009-01-24       drh:   zBgColor = find_option("bgcolor",0,1);
f6790b7c3c 2009-02-26       drh:   zDateOvrd = find_option("date-override",0,1);
8b630bb57a 2009-08-08       drh:   zUserOvrd = find_option("user-override",0,1);
dbda8d6ce9 2007-07-21       drh:   db_must_be_within_tree();
417e7662e5 2008-06-06       drh:   noSign = db_get_boolean("omitsign", 0)|noSign;
3f706b92a5 2008-06-06       drh:   if( db_get_boolean("clearsign", 1)==0 ){ noSign = 1; }
6aff11f03f 2007-08-03       drh:   verify_all_options();
fff234b77c 2007-09-25       drh: 
fff234b77c 2007-09-25       drh:   /*
fff234b77c 2007-09-25       drh:   ** Autosync if requested.
fff234b77c 2007-09-25       drh:   */
49b59bc559 2008-02-09       drh:   autosync(AUTOSYNC_PULL);
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   /* There are two ways this command may be executed. If there are
22552fb803 2007-08-03       dan:   ** no arguments following the word "commit", then all modified files
22552fb803 2007-08-03       dan:   ** in the checked out directory are committed. If one or more arguments
22552fb803 2007-08-03       dan:   ** follows "commit", then only those files are committed.
22552fb803 2007-08-03       dan:   **
22552fb803 2007-08-03       dan:   ** After the following function call has returned, the Global.aCommitFile[]
22552fb803 2007-08-03       dan:   ** array is allocated to contain the "id" field from the vfile table
22552fb803 2007-08-03       dan:   ** for each file to be committed. Or, if aCommitFile is NULL, all files
22552fb803 2007-08-03       dan:   ** should be committed.
22552fb803 2007-08-03       dan:   */
22552fb803 2007-08-03       dan:   select_commit_files();
4c82c7773f 2007-08-30       drh:   isAMerge = db_exists("SELECT 1 FROM vmerge");
4c82c7773f 2007-08-30       drh:   if( g.aCommitFile && isAMerge ){
aafd536a5c 2007-08-04       drh:     fossil_fatal("cannot do a partial commit of a merge");
aafd536a5c 2007-08-04       drh:   }
22552fb803 2007-08-03       dan: 
dbda8d6ce9 2007-07-21       drh:   user_select();
e2a42f7a68 2008-01-29       drh:   /*
e2a42f7a68 2008-01-29       drh:   ** Check that the user exists.
e2a42f7a68 2008-01-29       drh:   */
e2a42f7a68 2008-01-29       drh:   if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
e2a42f7a68 2008-01-29       drh:     fossil_fatal("no such user: %s", g.zLogin);
e2a42f7a68 2008-01-29       drh:   }
e2a42f7a68 2008-01-29       drh: 
dbda8d6ce9 2007-07-21       drh:   db_begin_transaction();
9346f2290c 2008-10-17       drh:   db_record_repository_filename(0);
dbda8d6ce9 2007-07-21       drh:   rc = unsaved_changes();
fff234b77c 2007-09-25       drh:   if( rc==0 && !isAMerge && !forceFlag ){
dbda8d6ce9 2007-07-21       drh:     fossil_panic("nothing has changed");
dbda8d6ce9 2007-07-21       drh:   }
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   /* If one or more files that were named on the command line have not
22552fb803 2007-08-03       dan:   ** been modified, bail out now.
22552fb803 2007-08-03       dan:   */
22552fb803 2007-08-03       dan:   if( g.aCommitFile ){
22552fb803 2007-08-03       dan:     Blob unmodified;
22552fb803 2007-08-03       dan:     memset(&unmodified, 0, sizeof(Blob));
22552fb803 2007-08-03       dan:     blob_init(&unmodified, 0, 0);
22552fb803 2007-08-03       dan:     db_blob(&unmodified,
22552fb803 2007-08-03       dan:       "SELECT pathname FROM vfile WHERE chnged = 0 AND file_is_selected(id)"
22552fb803 2007-08-03       dan:     );
22552fb803 2007-08-03       dan:     if( strlen(blob_str(&unmodified)) ){
22552fb803 2007-08-03       dan:       fossil_panic("file %s has not changed", blob_str(&unmodified));
22552fb803 2007-08-03       dan:     }
22552fb803 2007-08-03       dan:   }
22552fb803 2007-08-03       dan: 
dbda8d6ce9 2007-07-21       drh:   vid = db_lget_int("checkout", 0);
4ac75b9107 2009-01-24       drh: 
4ac75b9107 2009-01-24       drh:   /*
4ac75b9107 2009-01-24       drh:   ** Do not allow a commit that will cause a fork unless the --force flag
4ac75b9107 2009-01-24       drh:   ** is used.
4ac75b9107 2009-01-24       drh:   */
4ac75b9107 2009-01-24       drh:   if( zBranch==0 && forceFlag==0 && !is_a_leaf(vid) ){
4ac75b9107 2009-01-24       drh:     fossil_fatal("would fork.  \"update\" first or use -f or --force.");
4ac75b9107 2009-01-24       drh:   }
4ac75b9107 2009-01-24       drh: 
4ac75b9107 2009-01-24       drh:   /*
4ac75b9107 2009-01-24       drh:   ** Do not allow a commit against a closed leaf
4ac75b9107 2009-01-24       drh:   */
4ac75b9107 2009-01-24       drh:   if( db_exists("SELECT 1 FROM tagxref"
4ac75b9107 2009-01-24       drh:                 " WHERE tagid=%d AND rid=%d AND tagtype>0",
4ac75b9107 2009-01-24       drh:                 TAG_CLOSED, vid) ){
4ac75b9107 2009-01-24       drh:     fossil_fatal("cannot commit against a closed leaf");
4ac75b9107 2009-01-24       drh:   }
4ac75b9107 2009-01-24       drh: 
dbda8d6ce9 2007-07-21       drh:   vfile_aggregate_checksum_disk(vid, &cksum1);
9a9cd81738 2007-08-09       drh:   if( zComment ){
9a9cd81738 2007-08-09       drh:     blob_zero(&comment);
9a9cd81738 2007-08-09       drh:     blob_append(&comment, zComment, -1);
9a9cd81738 2007-08-09       drh:   }else{
9a9cd81738 2007-08-09       drh:     prepare_commit_comment(&comment);
6f0a9f730b 2008-11-26       drh:     if( blob_size(&comment)==0 ){
6f0a9f730b 2008-11-26       drh:       Blob ans;
6f0a9f730b 2008-11-26       drh:       blob_zero(&ans);
6f0a9f730b 2008-11-26       drh:       prompt_user("empty check-in comment.  continue [y/N]? ", &ans);
6f0a9f730b 2008-11-26       drh:       if( blob_str(&ans)[0]!='y' ){
6f0a9f730b 2008-11-26       drh:         db_end_transaction(1);
6f0a9f730b 2008-11-26       drh:         exit(1);
6f0a9f730b 2008-11-26       drh:       }
6f0a9f730b 2008-11-26       drh:     }
9a9cd81738 2007-08-09       drh:   }
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   /* Step 1: Insert records for all modified files into the blob
22552fb803 2007-08-03       dan:   ** table. If there were arguments passed to this command, only
22552fb803 2007-08-03       dan:   ** the identified fils are inserted (if they have been modified).
22552fb803 2007-08-03       dan:   */
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q,
22552fb803 2007-08-03       dan:     "SELECT id, %Q || pathname, mrid FROM vfile "
22552fb803 2007-08-03       dan:     "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)"
22552fb803 2007-08-03       dan:     , g.zLocalRoot
22552fb803 2007-08-03       dan:   );
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     int id, rid;
dbda8d6ce9 2007-07-21       drh:     const char *zFullname;
dbda8d6ce9 2007-07-21       drh:     Blob content;
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh:     id = db_column_int(&q, 0);
dbda8d6ce9 2007-07-21       drh:     zFullname = db_column_text(&q, 1);
dbda8d6ce9 2007-07-21       drh:     rid = db_column_int(&q, 2);
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh:     blob_zero(&content);
dbda8d6ce9 2007-07-21       drh:     blob_read_from_file(&content, zFullname);
573a464cb7 2007-08-10       drh:     nrid = content_put(&content, 0, 0);
f6790b7c3c 2009-02-26       drh:     blob_reset(&content);
dbda8d6ce9 2007-07-21       drh:     if( rid>0 ){
dbda8d6ce9 2007-07-21       drh:       content_deltify(rid, nrid, 0);
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     db_multi_exec("UPDATE vfile SET mrid=%d, rid=%d WHERE id=%d", nrid,nrid,id);
e1c1877c99 2007-09-08       drh:     db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh:   /* Create the manifest */
dbda8d6ce9 2007-07-21       drh:   blob_zero(&manifest);
1871a93dd4 2007-08-30       drh:   if( blob_size(&comment)==0 ){
1871a93dd4 2007-08-30       drh:     blob_append(&comment, "(no comment)", -1);
1871a93dd4 2007-08-30       drh:   }
dbda8d6ce9 2007-07-21       drh:   blob_appendf(&manifest, "C %F\n", blob_str(&comment));
f6790b7c3c 2009-02-26       drh:   zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
dbda8d6ce9 2007-07-21       drh:   zDate[10] = 'T';
dbda8d6ce9 2007-07-21       drh:   blob_appendf(&manifest, "D %s\n", zDate);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q,
e146d800ac 2008-11-09       drh:     "SELECT pathname, uuid, origname"
e146d800ac 2008-11-09       drh:     "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
ac1dea8eac 2007-07-24       drh:     " WHERE NOT deleted AND vfile.vid=%d"
dbda8d6ce9 2007-07-21       drh:     " ORDER BY 1", vid);
33c31f73cd 2008-02-21       drh:   blob_zero(&filename);
33c31f73cd 2008-02-21       drh:   blob_appendf(&filename, "%s/", g.zLocalRoot);
33c31f73cd 2008-02-21       drh:   nBasename = blob_size(&filename);
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zName = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:     const char *zUuid = db_column_text(&q, 1);
e146d800ac 2008-11-09       drh:     const char *zOrig = db_column_text(&q, 2);
33c31f73cd 2008-02-21       drh:     const char *zPerm;
33c31f73cd 2008-02-21       drh:     blob_append(&filename, zName, -1);
33c31f73cd 2008-02-21       drh:     if( file_isexe(blob_str(&filename)) ){
33c31f73cd 2008-02-21       drh:       zPerm = " x";
33c31f73cd 2008-02-21       drh:     }else{
33c31f73cd 2008-02-21       drh:       zPerm = "";
33c31f73cd 2008-02-21       drh:     }
33c31f73cd 2008-02-21       drh:     blob_resize(&filename, nBasename);
e146d800ac 2008-11-09       drh:     if( zOrig==0 || strcmp(zOrig,zName)==0 ){
e146d800ac 2008-11-09       drh:       blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
e146d800ac 2008-11-09       drh:     }else{
e146d800ac 2008-11-09       drh:       if( zPerm[0]==0 ){ zPerm = " w"; }
e146d800ac 2008-11-09       drh:       blob_appendf(&manifest, "F %F %s%s %F\n", zName, zUuid, zPerm, zOrig);
e146d800ac 2008-11-09       drh:     }
33c31f73cd 2008-02-21       drh:   }
33c31f73cd 2008-02-21       drh:   blob_reset(&filename);
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
dbda8d6ce9 2007-07-21       drh:   blob_appendf(&manifest, "P %s", zUuid);
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
dbda8d6ce9 2007-07-21       drh:   db_bind_int(&q2, ":id", 0);
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q2)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     int mid = db_column_int(&q2, 0);
dbda8d6ce9 2007-07-21       drh:     zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
dbda8d6ce9 2007-07-21       drh:     if( zUuid ){
dbda8d6ce9 2007-07-21       drh:       blob_appendf(&manifest, " %s", zUuid);
dbda8d6ce9 2007-07-21       drh:       free(zUuid);
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_reset(&q2);
22552fb803 2007-08-03       dan: 
dbda8d6ce9 2007-07-21       drh:   blob_appendf(&manifest, "\n");
dbda8d6ce9 2007-07-21       drh:   blob_appendf(&manifest, "R %b\n", &cksum1);
4ac75b9107 2009-01-24       drh:   if( zBranch && zBranch[0] ){
4ac75b9107 2009-01-24       drh:     Stmt q;
4ac75b9107 2009-01-24       drh:     if( zBgColor && zBgColor[0] ){
4ac75b9107 2009-01-24       drh:       blob_appendf(&manifest, "T *bgcolor * %F\n", zBgColor);
4ac75b9107 2009-01-24       drh:     }
4ac75b9107 2009-01-24       drh:     blob_appendf(&manifest, "T *branch * %F\n", zBranch);
4ac75b9107 2009-01-24       drh:     blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
4ac75b9107 2009-01-24       drh: 
4ac75b9107 2009-01-24       drh:     /* Cancel all other symbolic tags */
4ac75b9107 2009-01-24       drh:     db_prepare(&q,
4ac75b9107 2009-01-24       drh:         "SELECT tagname FROM tagxref, tag"
4ac75b9107 2009-01-24       drh:         " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
4ac75b9107 2009-01-24       drh:         "   AND tagtype>0 AND tagname GLOB 'sym-*'"
4ac75b9107 2009-01-24       drh:         "   AND tagname!='sym-'||%Q"
4ac75b9107 2009-01-24       drh:         " ORDER BY tagname",
4ac75b9107 2009-01-24       drh:         vid, zBranch);
4ac75b9107 2009-01-24       drh:     while( db_step(&q)==SQLITE_ROW ){
4ac75b9107 2009-01-24       drh:       const char *zTag = db_column_text(&q, 0);
8be6204607 2009-02-09   bharder:       blob_appendf(&manifest, "T -%F *\n", zTag);
4ac75b9107 2009-01-24       drh:     }
4ac75b9107 2009-01-24       drh:     db_finalize(&q);
4ac75b9107 2009-01-24       drh:   }
8b630bb57a 2009-08-08       drh:   blob_appendf(&manifest, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
dbda8d6ce9 2007-07-21       drh:   md5sum_blob(&manifest, &mcksum);
dbda8d6ce9 2007-07-21       drh:   blob_appendf(&manifest, "Z %b\n", &mcksum);
dbda8d6ce9 2007-07-21       drh:   zManifestFile = mprintf("%smanifest", g.zLocalRoot);
6aff11f03f 2007-08-03       drh:   if( !noSign && clearsign(&manifest, &manifest) ){
e37451d9c2 2007-08-01       drh:     Blob ans;
e37451d9c2 2007-08-01       drh:     blob_zero(&ans);
e37451d9c2 2007-08-01       drh:     prompt_user("unable to sign manifest.  continue [y/N]? ", &ans);
e37451d9c2 2007-08-01       drh:     if( blob_str(&ans)[0]!='y' ){
e37451d9c2 2007-08-01       drh:       db_end_transaction(1);
e37451d9c2 2007-08-01       drh:       exit(1);
e37451d9c2 2007-08-01       drh:     }
e37451d9c2 2007-08-01       drh:   }
e37451d9c2 2007-08-01       drh:   blob_write_to_file(&manifest, zManifestFile);
dbda8d6ce9 2007-07-21       drh:   blob_reset(&manifest);
dbda8d6ce9 2007-07-21       drh:   blob_read_from_file(&manifest, zManifestFile);
dbda8d6ce9 2007-07-21       drh:   free(zManifestFile);
573a464cb7 2007-08-10       drh:   nvid = content_put(&manifest, 0, 0);
dbda8d6ce9 2007-07-21       drh:   if( nvid==0 ){
dbda8d6ce9 2007-07-21       drh:     fossil_panic("trouble committing manifest: %s", g.zErrMsg);
dbda8d6ce9 2007-07-21       drh:   }
e1c1877c99 2007-09-08       drh:   db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
dbda8d6ce9 2007-07-21       drh:   manifest_crosslink(nvid, &manifest);
dbda8d6ce9 2007-07-21       drh:   content_deltify(vid, nvid, 0);
dbda8d6ce9 2007-07-21       drh:   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
dbda8d6ce9 2007-07-21       drh:   printf("New_Version: %s\n", zUuid);
741aac4d4e 2007-08-25       drh:   zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
741aac4d4e 2007-08-25       drh:   blob_zero(&muuid);
741aac4d4e 2007-08-25       drh:   blob_appendf(&muuid, "%s\n", zUuid);
741aac4d4e 2007-08-25       drh:   blob_write_to_file(&muuid, zManifestFile);
741aac4d4e 2007-08-25       drh:   free(zManifestFile);
741aac4d4e 2007-08-25       drh:   blob_reset(&muuid);
741aac4d4e 2007-08-25       drh: 
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   /* Update the vfile and vmerge tables */
22552fb803 2007-08-03       dan:   db_multi_exec(
22552fb803 2007-08-03       dan:     "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
22552fb803 2007-08-03       dan:     "DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
22552fb803 2007-08-03       dan:     "UPDATE vfile SET vid=%d;"
e146d800ac 2008-11-09       drh:     "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
e146d800ac 2008-11-09       drh:     " WHERE file_is_selected(id);"
22552fb803 2007-08-03       dan:     , vid, nvid
22552fb803 2007-08-03       dan:   );
dbda8d6ce9 2007-07-21       drh:   db_lset_int("checkout", nvid);
dbda8d6ce9 2007-07-21       drh: 
22552fb803 2007-08-03       dan:   /* Verify that the repository checksum matches the expected checksum
22552fb803 2007-08-03       dan:   ** calculated before the checkin started (and stored as the R record
22552fb803 2007-08-03       dan:   ** of the manifest file).
22552fb803 2007-08-03       dan:   */
dbda8d6ce9 2007-07-21       drh:   vfile_aggregate_checksum_repository(nvid, &cksum2);
dbda8d6ce9 2007-07-21       drh:   if( blob_compare(&cksum1, &cksum2) ){
dbda8d6ce9 2007-07-21       drh:     fossil_panic("tree checksum does not match repository after commit");
dbda8d6ce9 2007-07-21       drh:   }
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   /* Verify that the manifest checksum matches the expected checksum */
3945057916 2007-08-01       drh:   vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
3945057916 2007-08-01       drh:   if( blob_compare(&cksum1, &cksum1b) ){
3945057916 2007-08-01       drh:     fossil_panic("manifest checksum does not agree with manifest: "
3945057916 2007-08-01       drh:                  "%b versus %b", &cksum1, &cksum1b);
3945057916 2007-08-01       drh:   }
5c3e87171a 2007-08-01       drh:   if( blob_compare(&cksum1, &cksum2) ){
3945057916 2007-08-01       drh:     fossil_panic("tree checksum does not match manifest after commit: "
3945057916 2007-08-01       drh:                  "%b versus %b", &cksum1, &cksum2);
3945057916 2007-08-01       drh:   }
22552fb803 2007-08-03       dan: 
22552fb803 2007-08-03       dan:   /* Verify that the commit did not modify any disk images. */
dbda8d6ce9 2007-07-21       drh:   vfile_aggregate_checksum_disk(nvid, &cksum2);
dbda8d6ce9 2007-07-21       drh:   if( blob_compare(&cksum1, &cksum2) ){
dbda8d6ce9 2007-07-21       drh:     fossil_panic("tree checksums before and after commit do not match");
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh: 
a36177bcce 2007-09-11       drh:   /* Clear the undo/redo stack */
a36177bcce 2007-09-11       drh:   undo_reset();
a36177bcce 2007-09-11       drh: 
dbda8d6ce9 2007-07-21       drh:   /* Commit */
dbda8d6ce9 2007-07-21       drh:   db_end_transaction(0);
0431f14edf 2007-09-25       jnc: 
49b59bc559 2008-02-09       drh:   autosync(AUTOSYNC_PUSH);
8d5ab7913e 2009-01-21       drh:   if( count_nonbranch_children(vid)>1 ){
49b59bc559 2008-02-09       drh:     printf("**** warning: a fork has occurred *****\n");
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku: /*
b7a93530ef 2008-02-01       aku: ** COMMAND: test-import-manifest
b7a93530ef 2008-02-01       aku: **
b7a93530ef 2008-02-01       aku: ** Usage: %fossil test-import-manifest DATE COMMENT ?-p PARENT_RECORDID?... ?-f (FILE_RECORDID PATH)?...
b7a93530ef 2008-02-01       aku: **
4c78a18ad2 2008-08-14       bch: ** Create a new version containing the specified file
b7a93530ef 2008-02-01       aku: ** revisions (if any), and child of the given PARENT version.
b7a93530ef 2008-02-01       aku: */
b7a93530ef 2008-02-01       aku: void import_manifest_cmd(void){
b7a93530ef 2008-02-01       aku:   const char* zDate;    /* argument - timestamp, as seconds since epoch (int) */
b7a93530ef 2008-02-01       aku:   const char* zComment; /* argument - manifest comment */
b7a93530ef 2008-02-01       aku:   char* zDateFmt;       /* timestamp formatted for the manifest */
b7a93530ef 2008-02-01       aku:   int* zParents;        /* arguments - array of parent references */
b7a93530ef 2008-02-01       aku:   int zParentCount;     /* number of found parent references */
b7a93530ef 2008-02-01       aku:   Blob manifest;        /* container for the manifest to be generated */
b7a93530ef 2008-02-01       aku:   Blob mcksum;          /* Self-checksum on the manifest */
b7a93530ef 2008-02-01       aku:   Blob cksum, cksum2;   /* Before and after commit checksums */
b7a93530ef 2008-02-01       aku:   Blob cksum1b;         /* Checksum recorded in the manifest */
b7a93530ef 2008-02-01       aku:   const char* parent;   /* loop variable when collecting parent references */
b7a93530ef 2008-02-01       aku:   int i, mid;           /* Another loop index, and id of new manifest */
b7a93530ef 2008-02-01       aku:   Stmt q;               /* sql statement to query table of files */
b7fc4d9d04 2008-03-05       aku:   char* zMidUuid;       /* Uuid for the newly generated manifest */
b7fc4d9d04 2008-03-05       aku: 
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku: #define USAGE ("DATE COMMENT ?-p|-parent PARENT_RID...? ?-f|-file (FILE_RID PATH)...?")
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Validate and process arguments, collect information.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   db_must_be_within_tree();
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /* Mandatory arguments */
b7a93530ef 2008-02-01       aku:   if (g.argc < 4) {
b7a93530ef 2008-02-01       aku:     usage (USAGE);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   zDate    = g.argv[2];
b7a93530ef 2008-02-01       aku:   zComment = g.argv[3];
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   remove_from_argv (2,2);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /* Pull the optional parent arguments
b7a93530ef 2008-02-01       aku:   **
b7a93530ef 2008-02-01       aku:   ** Note: In principle it is possible that the loop below extracts
b7a93530ef 2008-02-01       aku:   ** the wrong arguments, if we ever try to import a file whose path
b7a93530ef 2008-02-01       aku:   ** starts with -p/-parent. In that case however the removal of two
b7a93530ef 2008-02-01       aku:   ** arguments will leave the file bereft of an argument and the
b7a93530ef 2008-02-01       aku:   ** recheck of the number of arguments below should catch that.
b7a93530ef 2008-02-01       aku:   **
b7a93530ef 2008-02-01       aku:   ** For a test command this is acceptable, it won't have lots of
b7a93530ef 2008-02-01       aku:   ** safety nets.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   zParentCount = 0;
b7a93530ef 2008-02-01       aku:   zParents = (int*)malloc(sizeof(int)*(1+g.argc));
b7a93530ef 2008-02-01       aku:   /* 1+, to be ok with the default even if no arguments around */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   while ((parent = find_option("parent","p",1)) != NULL) {
b7a93530ef 2008-02-01       aku:     /* Check and store ... */
b7a93530ef 2008-02-01       aku:     zParents [zParentCount] = name_to_rid (parent);
b7a93530ef 2008-02-01       aku:     zParentCount ++;
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Fall back to the root manifest as parent if none were specified
b7a93530ef 2008-02-01       aku:   ** explicitly.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   if (!zParentCount) {
b7a93530ef 2008-02-01       aku:     zParents [zParentCount] = 1; /* HACK: rid 1 is the baseline manifest
b7a93530ef 2008-02-01       aku: 				 ** which was entered when the repository
b7a93530ef 2008-02-01       aku: 				 ** was created via 'new'. It always has
b7a93530ef 2008-02-01       aku: 				 ** rid 1.
b7a93530ef 2008-02-01       aku: 				 */
b7a93530ef 2008-02-01       aku:     zParentCount ++;
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /* Pull the file arguments, at least one has to be present. They are
b7a93530ef 2008-02-01       aku:   ** the only things we can have here, now, and they are triples of
b7a93530ef 2008-02-01       aku:   ** '-f FID PATH', so use of find_option is out, and we can check the
b7a93530ef 2008-02-01       aku:   ** number of arguments.
b7a93530ef 2008-02-01       aku:   **
b7a93530ef 2008-02-01       aku:   ** Note: We store the data in a temp. table, so that we later can
b7a93530ef 2008-02-01       aku:   **       pull it sorted, and also easily get the associated hash
b7a93530ef 2008-02-01       aku:   **       identifiers.
b7a93530ef 2008-02-01       aku:   **
b7a93530ef 2008-02-01       aku:   ** Note 2: We expect at least one file, otherwise the manifest won't
b7a93530ef 2008-02-01       aku:   ** be recognized as a baseline by the manifest parser.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   if (((g.argc-2) % 3 != 0) || (g.argc < 5)) {
b7a93530ef 2008-02-01       aku:     usage (USAGE);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   db_begin_transaction();
b7a93530ef 2008-02-01       aku:   db_multi_exec ("CREATE TEMP TABLE __im ("
dfb6ee3bac 2008-02-02       aku: 		 "rid      INTEGER NOT NULL,"
dfb6ee3bac 2008-02-02       aku: 		 "pathname TEXT    NOT NULL)" );
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   while (g.argc > 2) {
b7a93530ef 2008-02-01       aku:     /* Check and store ... */
b7a93530ef 2008-02-01       aku:     if (strcmp("-f",   g.argv[2]) &&
b7a93530ef 2008-02-01       aku: 	strcmp("-file",g.argv[2])) {
b7a93530ef 2008-02-01       aku:       usage (USAGE);
b7a93530ef 2008-02-01       aku:     }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:     /* DANGER The %s for the path might lead itself to an injection
b7a93530ef 2008-02-01       aku:     ** attack. For now (i.e. testing) this is ok, but do something
b7a93530ef 2008-02-01       aku:     ** better in the future.
41561125cd 2007-09-26       jnc:     */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:     db_multi_exec("INSERT INTO __im VALUES(%d,'%s')",
b7a93530ef 2008-02-01       aku: 		  name_to_rid (g.argv[3]), g.argv[4] );
b7a93530ef 2008-02-01       aku:     remove_from_argv (2,3);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   verify_all_options();
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Determine the user the manifest will belong to, and check that
b7a93530ef 2008-02-01       aku:   ** this user exists.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   user_select();
b7a93530ef 2008-02-01       aku:   if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
b7a93530ef 2008-02-01       aku:     fossil_fatal("no such user: %s", g.zLogin);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Now generate the manifest in memory.
b7a93530ef 2008-02-01       aku:   **
b7a93530ef 2008-02-01       aku:   ** Start with comment and date. The latter is converted to the
b7a93530ef 2008-02-01       aku:   ** proper format before insertion.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   blob_zero(&manifest);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   if (!strlen(zComment)) {
b7a93530ef 2008-02-01       aku:     blob_appendf(&manifest, "C %F\n", "(no comment)");
b7a93530ef 2008-02-01       aku:   } else {
bd9703dee6 2008-02-02       aku:     blob_appendf(&manifest, "C %F\n", zComment);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   zDateFmt = db_text(0, "SELECT datetime(%Q,'unixepoch')",zDate);
b7a93530ef 2008-02-01       aku:   zDateFmt[10] = 'T';
b7a93530ef 2008-02-01       aku:   blob_appendf(&manifest, "D %s\n", zDateFmt);
b7a93530ef 2008-02-01       aku:   free(zDateFmt);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Follow with all the collected files, properly sorted. Here were
b7a93530ef 2008-02-01       aku:   ** also compute the checksum over the files (paths, sizes,
b7a93530ef 2008-02-01       aku:   ** contents), similar to what 'vfile_aggregate_checksum_repository'
b7a93530ef 2008-02-01       aku:   ** does.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   md5sum_init();
b7a93530ef 2008-02-01       aku:   db_prepare(&q,
b7a93530ef 2008-02-01       aku: 	     "SELECT pathname, uuid, __im.rid"
b7a93530ef 2008-02-01       aku: 	     " FROM __im JOIN blob ON __im.rid=blob.rid"
b7a93530ef 2008-02-01       aku: 	     " ORDER BY 1");
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   while( db_step(&q)==SQLITE_ROW ){
b7a93530ef 2008-02-01       aku:     char zBuf[100];
b7a93530ef 2008-02-01       aku:     Blob file;
b7a93530ef 2008-02-01       aku:     const char *zName = db_column_text(&q, 0);
b7a93530ef 2008-02-01       aku:     const char *zUuid = db_column_text(&q, 1);
b7a93530ef 2008-02-01       aku:     int         zRid  = db_column_int (&q, 2);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:     /* Extend the manifest */
b7a93530ef 2008-02-01       aku:     blob_appendf(&manifest, "F %F %s\n", zName, zUuid);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:     /* Update the checksum */
b7a93530ef 2008-02-01       aku:     md5sum_step_text(zName, -1);
b7a93530ef 2008-02-01       aku:     blob_zero(&file);
b7a93530ef 2008-02-01       aku:     content_get(zRid, &file);
b7a93530ef 2008-02-01       aku:     sprintf(zBuf, " %d\n", blob_size(&file));
b7a93530ef 2008-02-01       aku:     md5sum_step_text(zBuf, -1);
b7a93530ef 2008-02-01       aku:     md5sum_step_blob(&file);
b7a93530ef 2008-02-01       aku:     blob_reset(&file);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku:   db_finalize(&q);
b7a93530ef 2008-02-01       aku:   md5sum_finish (&cksum);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Follow with all the specified parents. We know that there is at
b7a93530ef 2008-02-01       aku:   ** least one.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   blob_appendf(&manifest, "P");
b7a93530ef 2008-02-01       aku:   for (i=0;i<zParentCount;i++) {
e146d800ac 2008-11-09       drh:     char* zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", zParents[i]);
b7a93530ef 2008-02-01       aku:     blob_appendf(&manifest, " %s", zUuid);
b7a93530ef 2008-02-01       aku:     free(zUuid);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku:   blob_appendf(&manifest, "\n");
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Complete the manifest with user name and the various checksums
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   blob_appendf(&manifest, "R %b\n", &cksum);
b7a93530ef 2008-02-01       aku:   blob_appendf(&manifest, "U %F\n", g.zLogin);
b7a93530ef 2008-02-01       aku:   md5sum_blob(&manifest, &mcksum);
b7a93530ef 2008-02-01       aku:   blob_appendf(&manifest, "Z %b\n", &mcksum);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** Now insert the new manifest, try to compress it relative to first
b7a93530ef 2008-02-01       aku:   ** parent (primary).
b7a93530ef 2008-02-01       aku:    */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*blob_write_to_file (&manifest, "TEST_MANIFEST");*/
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   mid = content_put(&manifest, 0, 0);
b7a93530ef 2008-02-01       aku:   if( mid==0 ){
b7a93530ef 2008-02-01       aku:     fossil_panic("trouble committing manifest: %s", g.zErrMsg);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   content_deltify(zParents[0], mid, 0);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /* Verify that the repository checksum matches the expected checksum
b7a93530ef 2008-02-01       aku:   ** calculated before the checkin started (and stored as the R record
b7a93530ef 2008-02-01       aku:   ** of the manifest file).
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   vfile_aggregate_checksum_manifest(mid, &cksum2, &cksum1b);
b7a93530ef 2008-02-01       aku:   if( blob_compare(&cksum, &cksum1b) ){
b7a93530ef 2008-02-01       aku:     fossil_panic("manifest checksum does not agree with manifest: "
b7a93530ef 2008-02-01       aku:                  "%b versus %b", &cksum, &cksum1b);
b7a93530ef 2008-02-01       aku:   }
b7a93530ef 2008-02-01       aku:   if( blob_compare(&cksum, &cksum2) ){
b7a93530ef 2008-02-01       aku:     fossil_panic("tree checksum does not match manifest after commit: "
b7a93530ef 2008-02-01       aku:                  "%b versus %b", &cksum, &cksum2);
0431f14edf 2007-09-25       jnc:   }
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7a93530ef 2008-02-01       aku:   ** At last commit all changes, after getting rid of the temp
b7a93530ef 2008-02-01       aku:   ** holder for the files, and release allocated memory.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   db_multi_exec("DROP TABLE __im");
b7fc4d9d04 2008-03-05       aku:   zMidUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
b7a93530ef 2008-02-01       aku:   db_end_transaction(0);
b7a93530ef 2008-02-01       aku:   free(zParents);
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku:   /*
b7fc4d9d04 2008-03-05       aku:   ** At the very last inform the caller about the id and uuid of the
b7fc4d9d04 2008-03-05       aku:   ** new manifest.
b7a93530ef 2008-02-01       aku:   */
b7a93530ef 2008-02-01       aku: 
b7fc4d9d04 2008-03-05       aku: 
b7fc4d9d04 2008-03-05       aku:   printf("inserted as record %d, %s\n", mid, zMidUuid);
b7fc4d9d04 2008-03-05       aku:   free(zMidUuid);
b7a93530ef 2008-02-01       aku:   return;
b7a93530ef 2008-02-01       aku: 
b7a93530ef 2008-02-01       aku: #undef USAGE
dbda8d6ce9 2007-07-21       drh: }