File Annotation
Not logged in
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: 
b6e22e62cf 2009-01-20       drh: /*
b6e22e62cf 2009-01-20       drh: **  fossil branch new    BRANCH-NAME ?ORIGIN-CHECK-IN? ?-bgcolor COLOR?
b6e22e62cf 2009-01-20       drh: **  argv0  argv1  argv2  argv3       argv4
b6e22e62cf 2009-01-20       drh: */
b8a8959ec5 2007-09-23       jnc: void branch_new(void){
b6e22e62cf 2009-01-20       drh:   int rootid;            /* RID of the root check-in - what we branch off of */
b6e22e62cf 2009-01-20       drh:   int brid;              /* RID of the branch check-in */
b6e22e62cf 2009-01-20       drh:   int noSign;            /* True if the branch is unsigned */
b6e22e62cf 2009-01-20       drh:   int i;                 /* Loop counter */
b6e22e62cf 2009-01-20       drh:   char *zUuid;           /* Artifact ID of origin */
b6e22e62cf 2009-01-20       drh:   Stmt q;                /* Generic query */
b6e22e62cf 2009-01-20       drh:   const char *zBranch;   /* Name of the new branch */
b6e22e62cf 2009-01-20       drh:   char *zDate;           /* Date that branch was created */
b6e22e62cf 2009-01-20       drh:   char *zComment;        /* Check-in comment for the new branch */
b6e22e62cf 2009-01-20       drh:   const char *zColor;    /* Color of the new branch */
b6e22e62cf 2009-01-20       drh:   Blob branch;           /* manifest for the new branch */
b6e22e62cf 2009-01-20       drh:   Blob parent;           /* root check-in manifest */
b6e22e62cf 2009-01-20       drh:   Manifest mParent;      /* Parsed parent manifest */
b6e22e62cf 2009-01-20       drh:   Blob mcksum;           /* Self-checksum on the manifest */
b8a8959ec5 2007-09-23       jnc: 
b8a8959ec5 2007-09-23       jnc:   noSign = find_option("nosign","",0)!=0;
b8a8959ec5 2007-09-23       jnc:   zColor = find_option("bgcolor","c",1);
b8a8959ec5 2007-09-23       jnc:   verify_all_options();
b6e22e62cf 2009-01-20       drh:   if( g.argc<3 ){
b6e22e62cf 2009-01-20       drh:     usage("branch new BRANCH-NAME ?ROOT-CHECK-IN? ?-bgcolor COLOR?");
b6e22e62cf 2009-01-20       drh:   }
b6e22e62cf 2009-01-20       drh:   db_find_and_open_repository(1);
b6e22e62cf 2009-01-20       drh:   noSign = db_get_int("omitsign", 0)|noSign;
b8a8959ec5 2007-09-23       jnc: 
b8a8959ec5 2007-09-23       jnc:   /* fossil branch new name */
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:   }
b6e22e62cf 2009-01-20       drh:   if( db_exists(
b6e22e62cf 2009-01-20       drh:         "SELECT 1 FROM tagxref"
b6e22e62cf 2009-01-20       drh:         " WHERE tagtype>0"
b6e22e62cf 2009-01-20       drh:         "   AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')",
b6e22e62cf 2009-01-20       drh:         zBranch)!=0 ){
b6e22e62cf 2009-01-20       drh:     fossil_fatal("branch \"%s\" already exists", zBranch);
b6e22e62cf 2009-01-20       drh:   }
b8a8959ec5 2007-09-23       jnc: 
b8a8959ec5 2007-09-23       jnc:   user_select();
b8a8959ec5 2007-09-23       jnc:   db_begin_transaction();
b6e22e62cf 2009-01-20       drh:   if( g.argc<5 ){
b6e22e62cf 2009-01-20       drh:     if( unsaved_changes() ){
b6e22e62cf 2009-01-20       drh:       fossil_fatal("there are uncommitted changes. please commit first");
b6e22e62cf 2009-01-20       drh:     }
b6e22e62cf 2009-01-20       drh:     rootid = db_lget_int("checkout", 0);
b6e22e62cf 2009-01-20       drh:   }else{
b6e22e62cf 2009-01-20       drh:     rootid = name_to_rid(g.argv[4]);
b6e22e62cf 2009-01-20       drh:   }
b6e22e62cf 2009-01-20       drh:   if( rootid==0 ){
b6e22e62cf 2009-01-20       drh:     fossil_fatal("unable to locate check-in off of which to branch");
b8a8959ec5 2007-09-23       jnc:   }
b8a8959ec5 2007-09-23       jnc: 
b6e22e62cf 2009-01-20       drh:   /* Create a manifest for the new branch */
b6e22e62cf 2009-01-20       drh:   blob_zero(&branch);
b6e22e62cf 2009-01-20       drh:   zComment = mprintf("Create new branch named \"%h\"", zBranch);
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "C %F\n", zComment);
b8a8959ec5 2007-09-23       jnc:   zDate = db_text(0, "SELECT datetime('now')");
b8a8959ec5 2007-09-23       jnc:   zDate[10] = 'T';
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "D %s\n", zDate);
b8a8959ec5 2007-09-23       jnc: 
b6e22e62cf 2009-01-20       drh:   /* Copy all of the content from the parent into the branch */
b6e22e62cf 2009-01-20       drh:   content_get(rootid, &parent);
b6e22e62cf 2009-01-20       drh:   manifest_parse(&mParent, &parent);
b6e22e62cf 2009-01-20       drh:   if( mParent.type!=CFTYPE_MANIFEST ){
b6e22e62cf 2009-01-20       drh:     fossil_fatal("%s is not a valid check-in", g.argv[4]);
2ad378d065 2007-09-23       jnc:   }
b6e22e62cf 2009-01-20       drh:   for(i=0; i<mParent.nFile; ++i){
b6e22e62cf 2009-01-20       drh:     if( mParent.aFile[i].zPerm[0] ){
b6e22e62cf 2009-01-20       drh:       blob_appendf(&branch, "F %F %s %s\n",
b6e22e62cf 2009-01-20       drh:                    mParent.aFile[i].zName,
b6e22e62cf 2009-01-20       drh:                    mParent.aFile[i].zUuid,
b6e22e62cf 2009-01-20       drh:                    mParent.aFile[i].zPerm);
2ad378d065 2007-09-23       jnc:     }else{
b6e22e62cf 2009-01-20       drh:       blob_appendf(&branch, "F %F %s\n",
b6e22e62cf 2009-01-20       drh:                    mParent.aFile[i].zName,
b6e22e62cf 2009-01-20       drh:                    mParent.aFile[i].zUuid);
2ad378d065 2007-09-23       jnc:     }
ce08928aaa 2008-02-08       drh:   }
b6e22e62cf 2009-01-20       drh:   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rootid);
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "P %s\n", zUuid);
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "R %s\n", mParent.zRepoCksum);
b6e22e62cf 2009-01-20       drh:   manifest_clear(&mParent);
b8a8959ec5 2007-09-23       jnc: 
b6e22e62cf 2009-01-20       drh:   /* Add the symbolic branch name and the "newbranch" tag to identify
b6e22e62cf 2009-01-20       drh:   ** this as a new branch */
ce08928aaa 2008-02-08       drh:   if( zColor!=0 ){
b6e22e62cf 2009-01-20       drh:     blob_appendf(&branch, "T *bgcolor * %F\n", zColor);
b8a8959ec5 2007-09-23       jnc:   }
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "T *sym-%F *\n", zBranch);
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "T +newbranch *\n");
b8a8959ec5 2007-09-23       jnc: 
b6e22e62cf 2009-01-20       drh:   /* Cancel all other symbolic tags */
b8a8959ec5 2007-09-23       jnc:   db_prepare(&q,
b6e22e62cf 2009-01-20       drh:       "SELECT tagname FROM tagxref, tag"
b6e22e62cf 2009-01-20       drh:       " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
b6e22e62cf 2009-01-20       drh:       "   AND tagtype>0 AND tagname GLOB 'sym-*'"
b6e22e62cf 2009-01-20       drh:       " ORDER BY tagname",
b6e22e62cf 2009-01-20       drh:       rootid);
b8a8959ec5 2007-09-23       jnc:   while( db_step(&q)==SQLITE_ROW ){
b6e22e62cf 2009-01-20       drh:     const char *zTag = db_column_text(&q, 0);
b6e22e62cf 2009-01-20       drh:     blob_appendf(&branch, "T -%s *\n", zTag);
b8a8959ec5 2007-09-23       jnc:   }
b8a8959ec5 2007-09-23       jnc:   db_finalize(&q);
b8a8959ec5 2007-09-23       jnc: 
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "U %F\n", g.zLogin);
b6e22e62cf 2009-01-20       drh:   md5sum_blob(&branch, &mcksum);
b6e22e62cf 2009-01-20       drh:   blob_appendf(&branch, "Z %b\n", &mcksum);
b6e22e62cf 2009-01-20       drh:   if( !noSign && clearsign(&branch, &branch) ){
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: 
b6e22e62cf 2009-01-20       drh:   brid = content_put(&branch, 0, 0);
b6e22e62cf 2009-01-20       drh:   if( brid==0 ){
b8a8959ec5 2007-09-23       jnc:     fossil_panic("trouble committing manifest: %s", g.zErrMsg);
b8a8959ec5 2007-09-23       jnc:   }
b6e22e62cf 2009-01-20       drh:   db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
b6e22e62cf 2009-01-20       drh:   if( manifest_crosslink(brid, &branch)==0 ){
b6e22e62cf 2009-01-20       drh:     fossil_panic("unable to install new manifest");
b6e22e62cf 2009-01-20       drh:   }
b6e22e62cf 2009-01-20       drh:   content_deltify(rootid, brid, 0);
b6e22e62cf 2009-01-20       drh:   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
b6e22e62cf 2009-01-20       drh:   printf("New branch: %s\n", zUuid);
b6e22e62cf 2009-01-20       drh:   if( g.argc==3 ){
b6e22e62cf 2009-01-20       drh:     printf(
b6e22e62cf 2009-01-20       drh:       "\n"
b6e22e62cf 2009-01-20       drh:       "Note: the local check-out has not been updated to the new\n"
b6e22e62cf 2009-01-20       drh:       "      branch.  To begin working on the new branch, do this:\n"
b6e22e62cf 2009-01-20       drh:       "\n"
b6e22e62cf 2009-01-20       drh:       "      %s update %s\n",
b6e22e62cf 2009-01-20       drh:       g.argv[0], zBranch
b6e22e62cf 2009-01-20       drh:     );
b8a8959ec5 2007-09-23       jnc:   }
b8a8959ec5 2007-09-23       jnc: 
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: **
b6e22e62cf 2009-01-20       drh: **    %fossil branch new BRANCH-NAME ?ROOT-CHECK-IN? ?-bgcolor COLOR?
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;
4e683ef07b 2008-05-05       drh:   db_find_and_open_repository(1);
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 ){
b7f32a71ab 2009-01-20       drh:     Stmt q;
b7f32a71ab 2009-01-20       drh:     db_prepare(&q,
b7f32a71ab 2009-01-20       drh:       "%s"
b7f32a71ab 2009-01-20       drh:       "   AND blob.rid IN (SELECT rid FROM tagxref"
b7f32a71ab 2009-01-20       drh:       "                     WHERE tagid=%d AND tagtype==1)"
b7f32a71ab 2009-01-20       drh:       " ORDER BY event.mtime DESC",
b7f32a71ab 2009-01-20       drh:       timeline_query_for_tty(), TAG_NEWBRANCH
b7f32a71ab 2009-01-20       drh:     );
b7f32a71ab 2009-01-20       drh:     print_timeline(&q, 2000);
b7f32a71ab 2009-01-20       drh:     db_finalize(&q);
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: }