Check-in [d778ffea81]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Prompt the user for permission to overwrite files on "fossil open". Ticket [17389900b2e5bd816]
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d778ffea81e7f76b71833cb41f4866c511fafb2c
User & Date: drh 2010-06-23 13:30:32.000
Context
2010-06-23
15:23
Update to the latest SQLite which contains a bug fix in the current-time function on windows. check-in: 34178e2771 user: drh tags: trunk
13:30
Prompt the user for permission to overwrite files on "fossil open". Ticket [17389900b2e5bd816] check-in: d778ffea81 user: drh tags: trunk
11:58
Fix to a "help" message. No code changes. check-in: b892572644 user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/checkout.c.
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
** See also the "update" command.
*/
void checkout_cmd(void){
  int forceFlag;                 /* Force checkout even if edits exist */
  int keepFlag;                  /* Do not change any files on disk */
  int latestFlag;                /* Checkout the latest version */
  char *zVers;                   /* Version to checkout */

  int vid, prior;
  Blob cksum1, cksum1b, cksum2;
  
  db_must_be_within_tree();
  db_begin_transaction();
  forceFlag = find_option("force","f",0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  latestFlag = find_option("latest",0,0)!=0;

  if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){
     usage("VERSION|--latest ?--force? ?--keep?");
  }
  if( !forceFlag && unsaved_changes()==1 ){
    fossil_fatal("there are unsaved changes in the current checkout");
  }
  if( forceFlag ){







>








>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
** See also the "update" command.
*/
void checkout_cmd(void){
  int forceFlag;                 /* Force checkout even if edits exist */
  int keepFlag;                  /* Do not change any files on disk */
  int latestFlag;                /* Checkout the latest version */
  char *zVers;                   /* Version to checkout */
  int promptFlag;                /* True to prompt before overwriting */
  int vid, prior;
  Blob cksum1, cksum1b, cksum2;
  
  db_must_be_within_tree();
  db_begin_transaction();
  forceFlag = find_option("force","f",0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  latestFlag = find_option("latest",0,0)!=0;
  promptFlag = find_option("prompt",0,0)!=0;  /* Prompt user before overwrite */
  if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){
     usage("VERSION|--latest ?--force? ?--keep?");
  }
  if( !forceFlag && unsaved_changes()==1 ){
    fossil_fatal("there are unsaved changes in the current checkout");
  }
  if( forceFlag ){
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    return;
  }
  if( !keepFlag ){
    uncheckout(prior);
  }
  db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
  if( !keepFlag ){
    vfile_to_disk(vid, 0, 1);
  }
  manifest_to_disk(vid);
  db_lset_int("checkout", vid);
  undo_reset();
  db_multi_exec("DELETE FROM vmerge");
  if( !keepFlag ){
    vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);







|







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    return;
  }
  if( !keepFlag ){
    uncheckout(prior);
  }
  db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
  if( !keepFlag ){
    vfile_to_disk(vid, 0, 1, promptFlag);
  }
  manifest_to_disk(vid);
  db_lset_int("checkout", vid);
  undo_reset();
  db_multi_exec("DELETE FROM vmerge");
  if( !keepFlag ){
    vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
Changes to src/db.c.
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
**
** See also the "close" command.
*/
void cmd_open(void){
  Blob path;
  int vid;
  int keepFlag;
  static char *azNewArgv[] = { 0, "checkout", "--latest", 0, 0, 0 };
  url_proxy_options();
  keepFlag = find_option("keep",0,0)!=0;
  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  if( db_open_local() ){
    fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);







|







1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
**
** See also the "close" command.
*/
void cmd_open(void){
  Blob path;
  int vid;
  int keepFlag;
  static char *azNewArgv[] = { 0, "checkout", "--prompt", "--latest", 0, 0 };
  url_proxy_options();
  keepFlag = find_option("keep",0,0)!=0;
  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  if( db_open_local() ){
    fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
    db_lset_int("checkout", 1);
  }else{
    char **oldArgv = g.argv;
    int oldArgc = g.argc;
    db_lset_int("checkout", vid);
    azNewArgv[0] = g.argv[0];
    g.argv = azNewArgv;
    g.argc = 3;
    if( oldArgc==4 ){
      azNewArgv[g.argc-1] = oldArgv[3];
    }
    if( keepFlag ){
      azNewArgv[g.argc++] = "--keep";
    }
    checkout_cmd();







|







1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
    db_lset_int("checkout", 1);
  }else{
    char **oldArgv = g.argv;
    int oldArgc = g.argc;
    db_lset_int("checkout", vid);
    azNewArgv[0] = g.argv[0];
    g.argv = azNewArgv;
    g.argc = 4;
    if( oldArgc==4 ){
      azNewArgv[g.argc-1] = oldArgv[3];
    }
    if( keepFlag ){
      azNewArgv[g.argc++] = "--keep";
    }
    checkout_cmd();
Changes to src/http_ssl.c.
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
                "saved certificate for this host!";
    }
    prompt = mprintf("\nUnknown SSL certificate:\n\n%s\n\n%s\n"
                     "Accept certificate [a=always/y/N]? ", desc, warning);
    BIO_free(mem);

    Blob ans;
    blob_zero(&ans);
    prompt_user(prompt, &ans);
    free(prompt);
    if( blob_str(&ans)[0]!='y' && blob_str(&ans)[0]!='a' ) {
      X509_free(cert);
      ssl_set_errmsg("SSL certificate declined");
      ssl_close();
      return 1;
    }
    if( blob_str(&ans)[0]=='a' ) {
      ssl_save_certificate(cert);
    }

  }
  X509_free(cert);
  return 0;
}

/*
** Save certificate to global config.







<











>







195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
                "saved certificate for this host!";
    }
    prompt = mprintf("\nUnknown SSL certificate:\n\n%s\n\n%s\n"
                     "Accept certificate [a=always/y/N]? ", desc, warning);
    BIO_free(mem);

    Blob ans;

    prompt_user(prompt, &ans);
    free(prompt);
    if( blob_str(&ans)[0]!='y' && blob_str(&ans)[0]!='a' ) {
      X509_free(cert);
      ssl_set_errmsg("SSL certificate declined");
      ssl_close();
      return 1;
    }
    if( blob_str(&ans)[0]=='a' ) {
      ssl_save_certificate(cert);
    }
    blob_reset(&ans);
  }
  X509_free(cert);
  return 0;
}

/*
** Save certificate to global config.
Changes to src/merge.c.
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
      vid, idm
    );
    idv = db_last_insert_rowid();
    db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
    zName = db_column_text(&q, 2);
    printf("ADDED %s\n", zName);
    undo_save(zName);
    vfile_to_disk(0, idm, 0);
  }
  db_finalize(&q);
  
  /*
  ** Find files that have changed from pid->mid but not pid->vid. 
  ** Copy the mid content over into vid.
  */







|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
      vid, idm
    );
    idv = db_last_insert_rowid();
    db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
    zName = db_column_text(&q, 2);
    printf("ADDED %s\n", zName);
    undo_save(zName);
    vfile_to_disk(0, idm, 0, 0);
  }
  db_finalize(&q);
  
  /*
  ** Find files that have changed from pid->mid but not pid->vid. 
  ** Copy the mid content over into vid.
  */
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
    char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idv);
    /* Copy content from idm over into idv.  Overwrite idv. */
    printf("UPDATE %s\n", zName);
    undo_save(zName);
    db_multi_exec(
      "UPDATE vfile SET mrid=%d, chnged=2 WHERE id=%d", ridm, idv
    );
    vfile_to_disk(0, idv, 0);
    free(zName);
  }
  db_finalize(&q);

  /*
  ** Do a three-way merge on files that have changes pid->mid and pid->vid
  */







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
    char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idv);
    /* Copy content from idm over into idv.  Overwrite idv. */
    printf("UPDATE %s\n", zName);
    undo_save(zName);
    db_multi_exec(
      "UPDATE vfile SET mrid=%d, chnged=2 WHERE id=%d", ridm, idv
    );
    vfile_to_disk(0, idv, 0, 0);
    free(zName);
  }
  db_finalize(&q);

  /*
  ** Do a three-way merge on files that have changes pid->mid and pid->vid
  */
Changes to src/update.c.
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
      ** but also exists in the target checkout.  Use the current version.
      */
      printf("CONFLICT %s\n", zName);
    }else if( idt>0 && idv==0 ){
      /* File added in the target. */
      printf("ADD %s\n", zName);
      undo_save(zName);
      if( !nochangeFlag ) vfile_to_disk(0, idt, 0);
    }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
      /* The file is unedited.  Change it to the target version */
      printf("UPDATE %s\n", zName);
      undo_save(zName);
      if( !nochangeFlag ) vfile_to_disk(0, idt, 0);
    }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){
      /* The file missing from the local check-out. Restore it to the
      ** version that appears in the target. */
      printf("UPDATE %s\n", zName);
      undo_save(zName);
      if( !nochangeFlag ) vfile_to_disk(0, idt, 0);
    }else if( idt==0 && idv>0 ){
      if( ridv==0 ){
        /* Added in current checkout.  Continue to hold the file as
        ** as an addition */
        db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
      }else if( chnged ){
        /* Edited locally but deleted from the target.  Delete it. */







|




|





|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
      ** but also exists in the target checkout.  Use the current version.
      */
      printf("CONFLICT %s\n", zName);
    }else if( idt>0 && idv==0 ){
      /* File added in the target. */
      printf("ADD %s\n", zName);
      undo_save(zName);
      if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
      /* The file is unedited.  Change it to the target version */
      printf("UPDATE %s\n", zName);
      undo_save(zName);
      if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){
      /* The file missing from the local check-out. Restore it to the
      ** version that appears in the target. */
      printf("UPDATE %s\n", zName);
      undo_save(zName);
      if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt==0 && idv>0 ){
      if( ridv==0 ){
        /* Added in current checkout.  Continue to hold the file as
        ** as an addition */
        db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
      }else if( chnged ){
        /* Edited locally but deleted from the target.  Delete it. */
Changes to src/vfile.c.
202
203
204
205
206
207
208
209





210
211
212
213
214
215
216
  db_end_transaction(0);
}

/*
** Write all files from vid to the disk.  Or if vid==0 and id!=0
** write just the specific file where VFILE.ID=id.
*/
void vfile_to_disk(int vid, int id, int verbose){





  Stmt q;
  Blob content;
  int nRepos = strlen(g.zLocalRoot);

  if( vid>0 && id==0 ){
    db_prepare(&q, "SELECT id, %Q || pathname, mrid"
                   "  FROM vfile"







|
>
>
>
>
>







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  db_end_transaction(0);
}

/*
** Write all files from vid to the disk.  Or if vid==0 and id!=0
** write just the specific file where VFILE.ID=id.
*/
void vfile_to_disk(
  int vid,               /* vid to write to disk */
  int id,                /* Write this one file, if not zero */
  int verbose,           /* Output progress information */
  int promptFlag         /* Prompt user to confirm overwrites */
){
  Stmt q;
  Blob content;
  int nRepos = strlen(g.zLocalRoot);

  if( vid>0 && id==0 ){
    db_prepare(&q, "SELECT id, %Q || pathname, mrid"
                   "  FROM vfile"
226
227
228
229
230
231
232

















233
234
235
236
237
238
239
  while( db_step(&q)==SQLITE_ROW ){
    int id, rid;
    const char *zName;

    id = db_column_int(&q, 0);
    zName = db_column_text(&q, 1);
    rid = db_column_int(&q, 2);

















    content_get(rid, &content);
    if( verbose ) printf("%s\n", &zName[nRepos]);
    blob_write_to_file(&content, zName);
    blob_reset(&content);
    db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
                  file_mtime(zName), id);
  }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  while( db_step(&q)==SQLITE_ROW ){
    int id, rid;
    const char *zName;

    id = db_column_int(&q, 0);
    zName = db_column_text(&q, 1);
    rid = db_column_int(&q, 2);
    if( promptFlag ){
      if( file_size(zName)>=0 ){
        Blob ans;
        char *zMsg;
        char cReply;
        zMsg = mprintf("overwrite %s (a=always/y/N)? ", zName);
        prompt_user(zMsg, &ans);
        free(zMsg);
        cReply = blob_str(&ans)[0];
        blob_reset(&ans);
        if( cReply=='a' || cReply=='A' ){
          promptFlag = 0;
          cReply = 'y';
        }
        if( cReply=='n' || cReply=='N' ) continue;
      }
    }
    content_get(rid, &content);
    if( verbose ) printf("%s\n", &zName[nRepos]);
    blob_write_to_file(&content, zName);
    blob_reset(&content);
    db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
                  file_mtime(zName), id);
  }