/* ** Copyright (c) 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to check-out versions of the project ** from the local repository. */ #include "config.h" #include "checkout.h" #include /* ** Check to see if there is an existing checkout that has been ** modified. Return values: ** ** 0: There is an existing checkout but it is unmodified ** 1: There is a modified checkout - there are unsaved changes ** 2: There is no existing checkout */ int unsaved_changes(void){ int vid; db_must_be_within_tree(); vid = db_lget_int("checkout",0); if( vid==0 ) return 2; vfile_check_signature(vid, 1); return db_exists("SELECT 1 FROM vfile WHERE chnged" " OR coalesce(origname!=pathname,0)"); } /* ** Undo the current check-out. Unlink all files from the disk. ** Clear the VFILE table. */ void uncheckout(int vid){ if( vid==0 ) return; vfile_unlink(vid); db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid); } /* ** Given the abbreviated UUID name of a version, load the content of that ** version in the VFILE table. Return the VID for the version. ** ** If anything goes wrong, panic. */ int load_vfile(const char *zName){ Blob uuid; int vid; blob_init(&uuid, zName, -1); if( name_to_uuid(&uuid, 1) ){ fossil_panic(g.zErrMsg); } vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); if( vid==0 ){ fossil_fatal("no such check-in: %s", g.argv[2]); } if( !is_a_version(vid) ){ fossil_fatal("object [%.10s] is not a check-in", blob_str(&uuid)); } load_vfile_from_rid(vid); return vid; } /* ** Load a vfile from a record ID. */ void load_vfile_from_rid(int vid){ Blob manifest; if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){ return; } content_get(vid, &manifest); vfile_build(vid, &manifest); blob_reset(&manifest); } /* ** Set or clear the vfile.isexe flag for a file. */ static void set_or_clear_isexe(const char *zFilename, int vid, int onoff){ db_multi_exec("UPDATE vfile SET isexe=%d WHERE vid=%d and pathname=%Q", onoff, vid, zFilename); } /* ** Read the manifest file given by vid out of the repository ** and store it in the root of the local check-out. */ void manifest_to_disk(int vid){ char *zManFile; Blob manifest; Blob hash; Blob filename; int baseLen; int i; Manifest m; blob_zero(&manifest); zManFile = mprintf("%smanifest", g.zLocalRoot); content_get(vid, &manifest); blob_write_to_file(&manifest, zManFile); free(zManFile); blob_zero(&hash); sha1sum_blob(&manifest, &hash); zManFile = mprintf("%smanifest.uuid", g.zLocalRoot); blob_append(&hash, "\n", 1); blob_write_to_file(&hash, zManFile); free(zManFile); blob_reset(&hash); manifest_parse(&m, &manifest); blob_zero(&filename); blob_appendf(&filename, "%s/", g.zLocalRoot); baseLen = blob_size(&filename); for(i=0; i