b8a8959ec5 2007-09-23 jnc: /* b8a8959ec5 2007-09-23 jnc: ** Copyright (c) 2007 D. Richard Hipp b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** This program is free software; you can redistribute it and/or b8a8959ec5 2007-09-23 jnc: ** modify it under the terms of the GNU General Public b8a8959ec5 2007-09-23 jnc: ** License version 2 as published by the Free Software Foundation. b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** This program is distributed in the hope that it will be useful, b8a8959ec5 2007-09-23 jnc: ** but WITHOUT ANY WARRANTY; without even the implied warranty of b8a8959ec5 2007-09-23 jnc: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU b8a8959ec5 2007-09-23 jnc: ** General Public License for more details. b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** You should have received a copy of the GNU General Public b8a8959ec5 2007-09-23 jnc: ** License along with this library; if not, write to the b8a8959ec5 2007-09-23 jnc: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, b8a8959ec5 2007-09-23 jnc: ** Boston, MA 02111-1307, USA. b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** Author contact information: b8a8959ec5 2007-09-23 jnc: ** drh@hwaci.com b8a8959ec5 2007-09-23 jnc: ** http://www.hwaci.com/drh/ b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ******************************************************************************* b8a8959ec5 2007-09-23 jnc: ** 07eaead5dc 2007-09-23 jnc: ** This file contains code used to create new branches within a repository. b8a8959ec5 2007-09-23 jnc: */ b8a8959ec5 2007-09-23 jnc: #include "config.h" b8a8959ec5 2007-09-23 jnc: #include "branch.h" b8a8959ec5 2007-09-23 jnc: #include <assert.h> b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: void branch_new(void){ b8a8959ec5 2007-09-23 jnc: int vid, nvid, noSign; b8a8959ec5 2007-09-23 jnc: Stmt q; 2ad378d065 2007-09-23 jnc: char *zBranch, *zUuid, *zDate, *zComment; b8a8959ec5 2007-09-23 jnc: const char *zColor; b8a8959ec5 2007-09-23 jnc: Blob manifest; b8a8959ec5 2007-09-23 jnc: Blob mcksum; /* Self-checksum on the manifest */ 2ad378d065 2007-09-23 jnc: Blob cksum1, cksum2; /* Before and after commit checksums */ b8a8959ec5 2007-09-23 jnc: Blob cksum1b; /* Checksum recorded in the manifest */ b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: noSign = find_option("nosign","",0)!=0; b8a8959ec5 2007-09-23 jnc: db_must_be_within_tree(); a21806dcf3 2007-10-07 jnc: noSign = db_get_int("omitsign", 0)|noSign; b8a8959ec5 2007-09-23 jnc: zColor = find_option("bgcolor","c",1); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: verify_all_options(); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* fossil branch new name */ b8a8959ec5 2007-09-23 jnc: if( g.argc<3 ){ ce08928aaa 2008-02-08 drh: usage("branch new ?-bgcolor COLOR? BRANCH-NAME"); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: zBranch = g.argv[3]; 2ad378d065 2007-09-23 jnc: if( zBranch==0 || zBranch[0]==0 ){ 2ad378d065 2007-09-23 jnc: fossil_panic("branch name cannot be empty"); 2ad378d065 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: user_select(); b8a8959ec5 2007-09-23 jnc: db_begin_transaction(); b8a8959ec5 2007-09-23 jnc: if( unsaved_changes() ){ b8a8959ec5 2007-09-23 jnc: fossil_panic("there are uncommitted changes. please commit first"); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: vid = db_lget_int("checkout", 0); 2ad378d065 2007-09-23 jnc: vfile_aggregate_checksum_disk(vid, &cksum1); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* Create our new manifest */ b8a8959ec5 2007-09-23 jnc: blob_zero(&manifest); b8a8959ec5 2007-09-23 jnc: zComment = mprintf("Branch created %s", zBranch); b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "C %F\n", zComment); 2ad378d065 2007-09-23 jnc: zDate = db_text(0, "SELECT datetime('now')"); 2ad378d065 2007-09-23 jnc: zDate[10] = 'T'; b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "D %s\n", zDate); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: db_prepare(&q, b8a8959ec5 2007-09-23 jnc: "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid" b8a8959ec5 2007-09-23 jnc: " WHERE NOT deleted AND vfile.vid=%d" b8a8959ec5 2007-09-23 jnc: " ORDER BY 1", vid); b8a8959ec5 2007-09-23 jnc: while( db_step(&q)==SQLITE_ROW ){ b8a8959ec5 2007-09-23 jnc: const char *zName = db_column_text(&q, 0); b8a8959ec5 2007-09-23 jnc: const char *zUuid = db_column_text(&q, 1); b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "F %F %s\n", zName, zUuid); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: db_finalize(&q); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "P %s\n", zUuid); b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "R %b\n", &cksum1); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: if( zColor!=0 ){ b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "T *bgcolor * %F\n", zColor); ce08928aaa 2008-02-08 drh: blob_appendf(&manifest, "T *sym-%F *\n", zBranch); 2ad378d065 2007-09-23 jnc: }else{ ce08928aaa 2008-02-08 drh: blob_appendf(&manifest, "T *sym-%F *\n", zBranch); 2ad378d065 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* Cancel any tags that propagate */ b8a8959ec5 2007-09-23 jnc: db_prepare(&q, b8a8959ec5 2007-09-23 jnc: "SELECT tagname" b8a8959ec5 2007-09-23 jnc: " FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid" b8a8959ec5 2007-09-23 jnc: " WHERE rid=%d AND tagtype=2", vid); b8a8959ec5 2007-09-23 jnc: while( db_step(&q)==SQLITE_ROW ){ b8a8959ec5 2007-09-23 jnc: const char *zTagname = db_column_text(&q, 0); b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "T -%s *\n", zTagname); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: db_finalize(&q); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "U %F\n", g.zLogin); b8a8959ec5 2007-09-23 jnc: md5sum_blob(&manifest, &mcksum); b8a8959ec5 2007-09-23 jnc: blob_appendf(&manifest, "Z %b\n", &mcksum); b8a8959ec5 2007-09-23 jnc: if( !noSign && clearsign(&manifest, &manifest) ){ b8a8959ec5 2007-09-23 jnc: Blob ans; b8a8959ec5 2007-09-23 jnc: blob_zero(&ans); b8a8959ec5 2007-09-23 jnc: prompt_user("unable to sign manifest. continue [y/N]? ", &ans); b8a8959ec5 2007-09-23 jnc: if( blob_str(&ans)[0]!='y' ){ b8a8959ec5 2007-09-23 jnc: db_end_transaction(1); b8a8959ec5 2007-09-23 jnc: exit(1); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: 17596784d0 2007-09-23 jnc: /*blob_write_to_file(&manifest, "manifest.new");*/ b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: nvid = content_put(&manifest, 0, 0); b8a8959ec5 2007-09-23 jnc: if( nvid==0 ){ b8a8959ec5 2007-09-23 jnc: fossil_panic("trouble committing manifest: %s", g.zErrMsg); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); b8a8959ec5 2007-09-23 jnc: manifest_crosslink(nvid, &manifest); b8a8959ec5 2007-09-23 jnc: content_deltify(vid, nvid, 0); b8a8959ec5 2007-09-23 jnc: zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); 2ad378d065 2007-09-23 jnc: printf("Branch Version: %s\n", zUuid); 2ad378d065 2007-09-23 jnc: printf("\n"); 2ad378d065 2007-09-23 jnc: printf("Notice: working copy not updated to the new branch. If\n"); 2ad378d065 2007-09-23 jnc: printf(" you wish to work on the new branch, update to\n"); 2ad378d065 2007-09-23 jnc: printf(" that branch first:\n"); 2ad378d065 2007-09-23 jnc: printf("\n"); 2ad378d065 2007-09-23 jnc: printf(" fossil update %s\n", zBranch); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* Verify that the manifest checksum matches the expected checksum */ b8a8959ec5 2007-09-23 jnc: vfile_aggregate_checksum_repository(nvid, &cksum2); b8a8959ec5 2007-09-23 jnc: vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b); b8a8959ec5 2007-09-23 jnc: if( blob_compare(&cksum1, &cksum1b) ){ b8a8959ec5 2007-09-23 jnc: fossil_panic("manifest checksum does not agree with manifest: " b8a8959ec5 2007-09-23 jnc: "%b versus %b", &cksum1, &cksum1b); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* Verify that the commit did not modify any disk images. */ b8a8959ec5 2007-09-23 jnc: vfile_aggregate_checksum_disk(vid, &cksum2); 2ad378d065 2007-09-23 jnc: if( blob_compare(&cksum1, &cksum2) ){ b8a8959ec5 2007-09-23 jnc: fossil_panic("tree checksums before and after commit do not match"); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* Clear the undo/redo stack */ b8a8959ec5 2007-09-23 jnc: undo_reset(); b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* Commit */ b8a8959ec5 2007-09-23 jnc: db_end_transaction(0); e4517465f3 2007-09-25 jnc: fff234b77c 2007-09-25 drh: /* Do an autosync push, if requested */ 49b59bc559 2008-02-09 drh: autosync(AUTOSYNC_PUSH); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: b8a8959ec5 2007-09-23 jnc: /* b8a8959ec5 2007-09-23 jnc: ** COMMAND: branch b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** Usage: %fossil branch SUBCOMMAND ... ?-R|--repository FILE? b8a8959ec5 2007-09-23 jnc: ** 66b13f1015 2008-02-07 bch: ** Run various subcommands on the branches of the open repository or b8a8959ec5 2007-09-23 jnc: ** of the repository identified by the -R or --repository option. b8a8959ec5 2007-09-23 jnc: ** ce08928aaa 2008-02-08 drh: ** %fossil branch new ?-bgcolor COLOR? BRANCH-NAME b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** Create a new branch BRANCH-NAME. You can optionally give b8a8959ec5 2007-09-23 jnc: ** a commit message and branch color. b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** %fossil branch list b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: ** List all branches b8a8959ec5 2007-09-23 jnc: ** b8a8959ec5 2007-09-23 jnc: */ b8a8959ec5 2007-09-23 jnc: void branch_cmd(void){ b8a8959ec5 2007-09-23 jnc: int n; b8a8959ec5 2007-09-23 jnc: db_find_and_open_repository(); b8a8959ec5 2007-09-23 jnc: if( g.argc<3 ){ b8a8959ec5 2007-09-23 jnc: usage("new|list ..."); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: n = strlen(g.argv[2]); b8a8959ec5 2007-09-23 jnc: if( n>=2 && strncmp(g.argv[2],"new",n)==0 ){ b8a8959ec5 2007-09-23 jnc: branch_new(); b8a8959ec5 2007-09-23 jnc: }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ 07eaead5dc 2007-09-23 jnc: fossil_panic("branch list is not yet completed"); b8a8959ec5 2007-09-23 jnc: }else{ b8a8959ec5 2007-09-23 jnc: fossil_panic("branch subcommand should be one of: " b8a8959ec5 2007-09-23 jnc: "new list"); b8a8959ec5 2007-09-23 jnc: } b8a8959ec5 2007-09-23 jnc: }