Fossil

Check-in [2ecc407d9b]
Login

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

Overview
Comment:The "extra" and "clean" commands ignore the repository file if the repository happens to be within the check-out. Ticket [c7b35be88].
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2ecc407d9be8f079f8cd631ddbb2e0884a1254a3
User & Date: drh 2008-07-23 13:01:23.000
Context
2008-07-23
17:36
Do not allow the current repository to be added to the set of files for a repository. Ticket [8e9136e8]. check-in: 141c31792b user: drh tags: trunk
13:01
The "extra" and "clean" commands ignore the repository file if the repository happens to be within the check-out. Ticket [c7b35be88]. check-in: 2ecc407d9b user: drh tags: trunk
2008-07-21
01:37
Fix a typo in the "concepts.wiki" documentation. check-in: bad9999d7d user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/add.c.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    if( isDir==1 ) continue;
    if( isDir==0 ){
      fossil_fatal("not found: %s", zName);
    }
    if( isDir==2 && access(zName, R_OK) ){
      fossil_fatal("cannot open %s", zName);
    }
    file_tree_name(zName, &pathname);
    zPath = blob_str(&pathname);
    if( strcmp(zPath, "manifest")==0
     || strcmp(zPath, "_FOSSIL_")==0
     || strcmp(zPath, "manifest.uuid")==0
    ){
      fossil_warning("cannot add %s", zPath);
    }else{







|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    if( isDir==1 ) continue;
    if( isDir==0 ){
      fossil_fatal("not found: %s", zName);
    }
    if( isDir==2 && access(zName, R_OK) ){
      fossil_fatal("cannot open %s", zName);
    }
    file_tree_name(zName, &pathname, 1);
    zPath = blob_str(&pathname);
    if( strcmp(zPath, "manifest")==0
     || strcmp(zPath, "_FOSSIL_")==0
     || strcmp(zPath, "manifest.uuid")==0
    ){
      fossil_warning("cannot add %s", zPath);
    }else{
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  db_begin_transaction();
  for(i=2; i<g.argc; i++){
    char *zName;
    char *zPath;
    Blob pathname;

    zName = mprintf("%/", g.argv[i]);
    file_tree_name(zName, &pathname);
    zPath = blob_str(&pathname);
    if( !db_exists(
             "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){
      fossil_fatal("not in the repository: %s", zName);
    }else{
      db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath);
    }
    blob_reset(&pathname);
    free(zName);
  }
  db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
  db_end_transaction(0);
}







|













107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  db_begin_transaction();
  for(i=2; i<g.argc; i++){
    char *zName;
    char *zPath;
    Blob pathname;

    zName = mprintf("%/", g.argv[i]);
    file_tree_name(zName, &pathname, 1);
    zPath = blob_str(&pathname);
    if( !db_exists(
             "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){
      fossil_fatal("not in the repository: %s", zName);
    }else{
      db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath);
    }
    blob_reset(&pathname);
    free(zName);
  }
  db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
  db_end_transaction(0);
}
Changes to src/checkin.c.
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202



203
204
205
206
207
208
209
** Usage: %fossil extra
**
** Print a list of all files in the source tree that are not part of
** the current checkout.  See also the "clean" command.
*/
void extra_cmd(void){
  Blob path;

  Stmt q;
  int n;
  db_must_be_within_tree();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
  n = strlen(g.zLocalRoot);
  blob_init(&path, g.zLocalRoot, n-1);
  vfile_scan(0, &path, blob_size(&path));
  db_prepare(&q, 
      "SELECT x FROM sfile"
      " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
      " ORDER BY 1");



  while( db_step(&q)==SQLITE_ROW ){
    printf("%s\n", db_column_text(&q, 0));
  }
  db_finalize(&q);
}

/*
** COMMAND: clean
** Usage: %fossil clean ?-all?
**
** Delete all "extra" files in the source tree.  "Extra" files are
** files that are not officially part of the checkout.  See also
** the "extra" command. This operation cannot be undone. 
**
** You will be prompted before removing each file. If you are
** sure you wish to remove all "extra" files you can specify the
** optional -all flag.
*/
void clean_cmd(void){
  int allFlag;
  Blob path;
  Stmt q;
  int n;
  allFlag = find_option("all","a",0)!=0;
  db_must_be_within_tree();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
  n = strlen(g.zLocalRoot);
  blob_init(&path, g.zLocalRoot, n-1);
  vfile_scan(0, &path, blob_size(&path));
  db_prepare(&q, 
      "SELECT %Q || x FROM sfile"
      " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
      " ORDER BY 1", g.zLocalRoot);



  while( db_step(&q)==SQLITE_ROW ){
    if( allFlag ){
      unlink(db_column_text(&q, 0));
    }else{
      Blob ans;
      char *prompt = mprintf("remove unmanaged file \"%s\" [y/N]? ",
                              db_column_text(&q, 0));







>











>
>
>




















|












>
>
>







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
** Usage: %fossil extra
**
** Print a list of all files in the source tree that are not part of
** the current checkout.  See also the "clean" command.
*/
void extra_cmd(void){
  Blob path;
  Blob repo;
  Stmt q;
  int n;
  db_must_be_within_tree();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
  n = strlen(g.zLocalRoot);
  blob_init(&path, g.zLocalRoot, n-1);
  vfile_scan(0, &path, blob_size(&path));
  db_prepare(&q, 
      "SELECT x FROM sfile"
      " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
      " ORDER BY 1");
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
  }
  while( db_step(&q)==SQLITE_ROW ){
    printf("%s\n", db_column_text(&q, 0));
  }
  db_finalize(&q);
}

/*
** COMMAND: clean
** Usage: %fossil clean ?-all?
**
** Delete all "extra" files in the source tree.  "Extra" files are
** files that are not officially part of the checkout.  See also
** the "extra" command. This operation cannot be undone. 
**
** You will be prompted before removing each file. If you are
** sure you wish to remove all "extra" files you can specify the
** optional -all flag.
*/
void clean_cmd(void){
  int allFlag;
  Blob path, repo;
  Stmt q;
  int n;
  allFlag = find_option("all","a",0)!=0;
  db_must_be_within_tree();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
  n = strlen(g.zLocalRoot);
  blob_init(&path, g.zLocalRoot, n-1);
  vfile_scan(0, &path, blob_size(&path));
  db_prepare(&q, 
      "SELECT %Q || x FROM sfile"
      " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')"
      " ORDER BY 1", g.zLocalRoot);
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
  }
  while( db_step(&q)==SQLITE_ROW ){
    if( allFlag ){
      unlink(db_column_text(&q, 0));
    }else{
      Blob ans;
      char *prompt = mprintf("remove unmanaged file \"%s\" [y/N]? ",
                              db_column_text(&q, 0));
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    int ii;
    Blob b;
    blob_zero(&b);
    g.aCommitFile = malloc(sizeof(int)*(g.argc-1));

    for(ii=2; ii<g.argc; ii++){
      int iId;
      file_tree_name(g.argv[ii], &b);
      iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
      if( iId<0 ){
        fossil_fatal("fossil knows nothing about: %s", g.argv[ii]);
      }
      g.aCommitFile[ii-2] = iId;
      blob_reset(&b);
    }







|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    int ii;
    Blob b;
    blob_zero(&b);
    g.aCommitFile = malloc(sizeof(int)*(g.argc-1));

    for(ii=2; ii<g.argc; ii++){
      int iId;
      file_tree_name(g.argv[ii], &b, 1);
      iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
      if( iId<0 ){
        fossil_fatal("fossil knows nothing about: %s", g.argv[ii]);
      }
      g.aCommitFile[ii-2] = iId;
      blob_reset(&b);
    }
Changes to src/diffcmd.c.
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    if( zExternalCommand==0 ){
      internalDiff=1;
    }
    blob_zero(&cmd);
    blob_appendf(&cmd, "%s ", zExternalCommand);
  }
  zFile = g.argv[g.argc-1];
  file_tree_name(zFile, &fname);

  blob_zero(&vname);
  do{
    blob_reset(&vname);
    blob_appendf(&vname, "%s~%d", zFile, cnt++);
  }while( access(blob_str(&vname),0)==0 );








|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    if( zExternalCommand==0 ){
      internalDiff=1;
    }
    blob_zero(&cmd);
    blob_appendf(&cmd, "%s ", zExternalCommand);
  }
  zFile = g.argv[g.argc-1];
  file_tree_name(zFile, &fname, 1);

  blob_zero(&vname);
  do{
    blob_reset(&vname);
    blob_appendf(&vname, "%s~%d", zFile, cnt++);
  }while( access(blob_str(&vname),0)==0 );

Changes to src/file.c.
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333

334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
    blob_reset(&x);
  }
}

/*
** Compute a pathname for a file relative to the root of the local
** tree.  Return TRUE on success.  On failure, print and error
** message and quit.

**
** The root of the tree is defined by the g.zLocalRoot variable.
*/
int file_tree_name(const char *zOrigName, Blob *pOut){
  int n;
  Blob full;
  db_must_be_within_tree();
  file_canonical_name(zOrigName, &full);
  n = strlen(g.zLocalRoot);
  if( blob_size(&full)<=n || memcmp(g.zLocalRoot, blob_buffer(&full), n) ){
    blob_reset(&full);

    fossil_fatal("file outside of checkout tree: %s", zOrigName);

    return 0;
  }
  blob_zero(pOut);
  blob_append(pOut, blob_buffer(&full)+n, blob_size(&full)-n);
  return 1;
}

/*
** COMMAND:  test-tree-name
**
** Test the operation of the tree name generator.
*/
void cmd_test_tree_name(void){
  int i;
  Blob x;
  blob_zero(&x);
  for(i=2; i<g.argc; i++){
    if( file_tree_name(g.argv[i], &x) ){
      printf("%s\n", blob_buffer(&x));
      blob_reset(&x);
    }
  }
}

/*







|
>



|







>
|
>

















|







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
    blob_reset(&x);
  }
}

/*
** Compute a pathname for a file relative to the root of the local
** tree.  Return TRUE on success.  On failure, print and error
** message and quit if the errFatal flag is true.  If errFatal is
** false, then simply return 0.
**
** The root of the tree is defined by the g.zLocalRoot variable.
*/
int file_tree_name(const char *zOrigName, Blob *pOut, int errFatal){
  int n;
  Blob full;
  db_must_be_within_tree();
  file_canonical_name(zOrigName, &full);
  n = strlen(g.zLocalRoot);
  if( blob_size(&full)<=n || memcmp(g.zLocalRoot, blob_buffer(&full), n) ){
    blob_reset(&full);
    if( errFatal ){
      fossil_fatal("file outside of checkout tree: %s", zOrigName);
    }
    return 0;
  }
  blob_zero(pOut);
  blob_append(pOut, blob_buffer(&full)+n, blob_size(&full)-n);
  return 1;
}

/*
** COMMAND:  test-tree-name
**
** Test the operation of the tree name generator.
*/
void cmd_test_tree_name(void){
  int i;
  Blob x;
  blob_zero(&x);
  for(i=2; i<g.argc; i++){
    if( file_tree_name(g.argv[i], &x, 1) ){
      printf("%s\n", blob_buffer(&x));
      blob_reset(&x);
    }
  }
}

/*
Changes to src/undo.c.
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    int i;
    if( undo_available==0 ){
      fossil_fatal("no update or merge operation is available to undo");
    }
    for(i=2; i<g.argc; i++){
      const char *zFile = g.argv[i];
      Blob path;
      file_tree_name(zFile, &path);
      undo_one(blob_str(&path), 0);
      blob_reset(&path);
    }
  }
  db_end_transaction(0);
}








|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    int i;
    if( undo_available==0 ){
      fossil_fatal("no update or merge operation is available to undo");
    }
    for(i=2; i<g.argc; i++){
      const char *zFile = g.argv[i];
      Blob path;
      file_tree_name(zFile, &path, 1);
      undo_one(blob_str(&path), 0);
      blob_reset(&path);
    }
  }
  db_end_transaction(0);
}

253
254
255
256
257
258
259
260
261
262
263
264
265
266
    int i;
    if( undo_available==0 ){
      fossil_fatal("no update or merge operation is available to redo");
    }
    for(i=2; i<g.argc; i++){
      const char *zFile = g.argv[i];
      Blob path;
      file_tree_name(zFile, &path);
      undo_one(blob_str(&path), 0);
      blob_reset(&path);
    }
  }
  db_end_transaction(0);
}







|






253
254
255
256
257
258
259
260
261
262
263
264
265
266
    int i;
    if( undo_available==0 ){
      fossil_fatal("no update or merge operation is available to redo");
    }
    for(i=2; i<g.argc; i++){
      const char *zFile = g.argv[i];
      Blob path;
      file_tree_name(zFile, &path, 1);
      undo_one(blob_str(&path), 0);
      blob_reset(&path);
    }
  }
  db_end_transaction(0);
}
Changes to src/update.c.
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  if( g.argc<3 ){
    usage("?OPTIONS FILE");
  }
  db_must_be_within_tree();
  
  zFile = mprintf("%/", g.argv[g.argc-1]);

  file_tree_name(zFile, &fname);

  if( access(zFile, 0) ) yesRevert = 1;  
  if( yesRevert==0 ){
    char *prompt = mprintf("revert file %B? this will"
                           " destroy local changes [y/N]? ",
                           &fname);
    blob_zero(&ans);







|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  if( g.argc<3 ){
    usage("?OPTIONS FILE");
  }
  db_must_be_within_tree();
  
  zFile = mprintf("%/", g.argv[g.argc-1]);

  file_tree_name(zFile, &fname, 1);

  if( access(zFile, 0) ) yesRevert = 1;  
  if( yesRevert==0 ){
    char *prompt = mprintf("revert file %B? this will"
                           " destroy local changes [y/N]? ",
                           &fname);
    blob_zero(&ans);