Fossil SCM

Make sure that pending deletes from "fossil rm" operations are preserved across a "fossil update".

drh 2012-11-06 19:47 branch-1.19
Commit 76c6f8fcb8a98627d0f8a982bfbbeacae8f13db9
+17 -6
--- src/update.c
+++ src/update.c
@@ -207,19 +207,20 @@
207207
" idt INTEGER," /* VFILE entry for target version */
208208
" chnged BOOLEAN," /* True if current version has been edited */
209209
" ridv INTEGER," /* Record ID for current version */
210210
" ridt INTEGER," /* Record ID for target */
211211
" isexe BOOLEAN," /* Does target have execute permission? */
212
+ " deleted BOOLEAN DEFAULT 0,"/* File marke by "rm" to become unmanaged */
212213
" fnt TEXT" /* Filename of same file on target version */
213214
");"
214215
);
215216
216217
/* Add files found in the current version
217218
*/
218219
db_multi_exec(
219
- "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,isexe,chnged)"
220
- " SELECT pathname, pathname, id, 0, rid, 0, isexe, chnged"
220
+ "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,isexe,chnged,deleted)"
221
+ " SELECT pathname, pathname, id, 0, rid, 0, isexe, chnged, deleted"
221222
" FROM vfile WHERE vid=%d",
222223
vid
223224
);
224225
225226
/* Compute file name changes on V->T. Record name changes in files that
@@ -311,11 +312,12 @@
311312
/*
312313
** Alter the content of the checkout so that it conforms with the
313314
** target
314315
*/
315316
db_prepare(&q,
316
- "SELECT fn, idv, ridv, idt, ridt, chnged, fnt, isexe FROM fv ORDER BY 1"
317
+ "SELECT fn, idv, ridv, idt, ridt, chnged, fnt,"
318
+ " isexe, deleted FROM fv ORDER BY 1"
317319
);
318320
db_prepare(&mtimeXfer,
319321
"UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
320322
" WHERE id=:idt"
321323
);
@@ -329,17 +331,21 @@
329331
int idt = db_column_int(&q, 3); /* VFILE entry for target */
330332
int ridt = db_column_int(&q, 4); /* RecordID for target */
331333
int chnged = db_column_int(&q, 5); /* Current is edited */
332334
const char *zNewName = db_column_text(&q,6);/* New filename */
333335
int isexe = db_column_int(&q, 7); /* EXE perm for new file */
336
+ int deleted = db_column_int(&q, 8); /* Marked for deletion */
334337
char *zFullPath; /* Full pathname of the file */
335338
char *zFullNewPath; /* Full pathname of dest */
336339
char nameChng; /* True if the name changed */
337340
338341
zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
339342
zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
340343
nameChng = fossil_strcmp(zName, zNewName);
344
+ if( deleted ){
345
+ db_multi_exec("UPDATE vfile SET deleted=1 WHERE id=%d", idt);
346
+ }
341347
if( idv>0 && ridv==0 && idt>0 && ridt>0 ){
342348
/* Conflict. This file has been added to the current checkout
343349
** but also exists in the target checkout. Use the current version.
344350
*/
345351
fossil_print("CONFLICT %s\n", zName);
@@ -347,19 +353,24 @@
347353
}else if( idt>0 && idv==0 ){
348354
/* File added in the target. */
349355
fossil_print("ADD %s\n", zName);
350356
undo_save(zName);
351357
if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
352
- }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
358
+ }else if( idt>0 && idv>0 && ridt!=ridv && (chnged==0 || deleted) ){
353359
/* The file is unedited. Change it to the target version */
354360
undo_save(zName);
355
- fossil_print("UPDATE %s\n", zName);
361
+ if( deleted ){
362
+ fossil_print("UPDATE %s - change to unmanged file\n", zName);
363
+ }else{
364
+ fossil_print("UPDATE %s\n", zName);
365
+ }
356366
if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
357367
}else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){
358368
/* The file missing from the local check-out. Restore it to the
359369
** version that appears in the target. */
360
- fossil_print("UPDATE %s\n", zName);
370
+ fossil_print("UPDATE %s%s\n", zName,
371
+ deleted?" - change to unmanaged file":"");
361372
undo_save(zName);
362373
if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
363374
}else if( idt==0 && idv>0 ){
364375
if( ridv==0 ){
365376
/* Added in current checkout. Continue to hold the file as
366377
367378
ADDED test/update-test-1.sh
368379
ADDED test/update-test-2.sh
--- src/update.c
+++ src/update.c
@@ -207,19 +207,20 @@
207 " idt INTEGER," /* VFILE entry for target version */
208 " chnged BOOLEAN," /* True if current version has been edited */
209 " ridv INTEGER," /* Record ID for current version */
210 " ridt INTEGER," /* Record ID for target */
211 " isexe BOOLEAN," /* Does target have execute permission? */
 
212 " fnt TEXT" /* Filename of same file on target version */
213 ");"
214 );
215
216 /* Add files found in the current version
217 */
218 db_multi_exec(
219 "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,isexe,chnged)"
220 " SELECT pathname, pathname, id, 0, rid, 0, isexe, chnged"
221 " FROM vfile WHERE vid=%d",
222 vid
223 );
224
225 /* Compute file name changes on V->T. Record name changes in files that
@@ -311,11 +312,12 @@
311 /*
312 ** Alter the content of the checkout so that it conforms with the
313 ** target
314 */
315 db_prepare(&q,
316 "SELECT fn, idv, ridv, idt, ridt, chnged, fnt, isexe FROM fv ORDER BY 1"
 
317 );
318 db_prepare(&mtimeXfer,
319 "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
320 " WHERE id=:idt"
321 );
@@ -329,17 +331,21 @@
329 int idt = db_column_int(&q, 3); /* VFILE entry for target */
330 int ridt = db_column_int(&q, 4); /* RecordID for target */
331 int chnged = db_column_int(&q, 5); /* Current is edited */
332 const char *zNewName = db_column_text(&q,6);/* New filename */
333 int isexe = db_column_int(&q, 7); /* EXE perm for new file */
 
334 char *zFullPath; /* Full pathname of the file */
335 char *zFullNewPath; /* Full pathname of dest */
336 char nameChng; /* True if the name changed */
337
338 zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
339 zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
340 nameChng = fossil_strcmp(zName, zNewName);
 
 
 
341 if( idv>0 && ridv==0 && idt>0 && ridt>0 ){
342 /* Conflict. This file has been added to the current checkout
343 ** but also exists in the target checkout. Use the current version.
344 */
345 fossil_print("CONFLICT %s\n", zName);
@@ -347,19 +353,24 @@
347 }else if( idt>0 && idv==0 ){
348 /* File added in the target. */
349 fossil_print("ADD %s\n", zName);
350 undo_save(zName);
351 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
352 }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
353 /* The file is unedited. Change it to the target version */
354 undo_save(zName);
355 fossil_print("UPDATE %s\n", zName);
 
 
 
 
356 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
357 }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){
358 /* The file missing from the local check-out. Restore it to the
359 ** version that appears in the target. */
360 fossil_print("UPDATE %s\n", zName);
 
361 undo_save(zName);
362 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
363 }else if( idt==0 && idv>0 ){
364 if( ridv==0 ){
365 /* Added in current checkout. Continue to hold the file as
366
367 DDED test/update-test-1.sh
368 DDED test/update-test-2.sh
--- src/update.c
+++ src/update.c
@@ -207,19 +207,20 @@
207 " idt INTEGER," /* VFILE entry for target version */
208 " chnged BOOLEAN," /* True if current version has been edited */
209 " ridv INTEGER," /* Record ID for current version */
210 " ridt INTEGER," /* Record ID for target */
211 " isexe BOOLEAN," /* Does target have execute permission? */
212 " deleted BOOLEAN DEFAULT 0,"/* File marke by "rm" to become unmanaged */
213 " fnt TEXT" /* Filename of same file on target version */
214 ");"
215 );
216
217 /* Add files found in the current version
218 */
219 db_multi_exec(
220 "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,isexe,chnged,deleted)"
221 " SELECT pathname, pathname, id, 0, rid, 0, isexe, chnged, deleted"
222 " FROM vfile WHERE vid=%d",
223 vid
224 );
225
226 /* Compute file name changes on V->T. Record name changes in files that
@@ -311,11 +312,12 @@
312 /*
313 ** Alter the content of the checkout so that it conforms with the
314 ** target
315 */
316 db_prepare(&q,
317 "SELECT fn, idv, ridv, idt, ridt, chnged, fnt,"
318 " isexe, deleted FROM fv ORDER BY 1"
319 );
320 db_prepare(&mtimeXfer,
321 "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
322 " WHERE id=:idt"
323 );
@@ -329,17 +331,21 @@
331 int idt = db_column_int(&q, 3); /* VFILE entry for target */
332 int ridt = db_column_int(&q, 4); /* RecordID for target */
333 int chnged = db_column_int(&q, 5); /* Current is edited */
334 const char *zNewName = db_column_text(&q,6);/* New filename */
335 int isexe = db_column_int(&q, 7); /* EXE perm for new file */
336 int deleted = db_column_int(&q, 8); /* Marked for deletion */
337 char *zFullPath; /* Full pathname of the file */
338 char *zFullNewPath; /* Full pathname of dest */
339 char nameChng; /* True if the name changed */
340
341 zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
342 zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
343 nameChng = fossil_strcmp(zName, zNewName);
344 if( deleted ){
345 db_multi_exec("UPDATE vfile SET deleted=1 WHERE id=%d", idt);
346 }
347 if( idv>0 && ridv==0 && idt>0 && ridt>0 ){
348 /* Conflict. This file has been added to the current checkout
349 ** but also exists in the target checkout. Use the current version.
350 */
351 fossil_print("CONFLICT %s\n", zName);
@@ -347,19 +353,24 @@
353 }else if( idt>0 && idv==0 ){
354 /* File added in the target. */
355 fossil_print("ADD %s\n", zName);
356 undo_save(zName);
357 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
358 }else if( idt>0 && idv>0 && ridt!=ridv && (chnged==0 || deleted) ){
359 /* The file is unedited. Change it to the target version */
360 undo_save(zName);
361 if( deleted ){
362 fossil_print("UPDATE %s - change to unmanged file\n", zName);
363 }else{
364 fossil_print("UPDATE %s\n", zName);
365 }
366 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
367 }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){
368 /* The file missing from the local check-out. Restore it to the
369 ** version that appears in the target. */
370 fossil_print("UPDATE %s%s\n", zName,
371 deleted?" - change to unmanaged file":"");
372 undo_save(zName);
373 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
374 }else if( idt==0 && idv>0 ){
375 if( ridv==0 ){
376 /* Added in current checkout. Continue to hold the file as
377
378 DDED test/update-test-1.sh
379 DDED test/update-test-2.sh
--- a/test/update-test-1.sh
+++ b/test/update-test-1.sh
@@ -0,0 +1,44 @@
1
+#!/bin/sh
2
+#
3
+# Run this script in an empty directory. A single argument is the full
4
+# pathname of the fossil binary. Example:
5
+#
6
+# sh update-test-1.sh /home/drh/fossil/m1/fossil
7
+#
8
+export FOSSIL=$1
9
+rm -rf aaa bbb update-test-1.fossil
10
+
11
+# Create a test repository
12
+$FOSSIL new update-test-1.fossil
13
+
14
+# In checkout aaa, add file one.txt
15
+mkdir aaa
16
+cd aaa
17
+$FOSSIL open ../update-test-1.fossil
18
+echo one >one.txt
19
+$FOSSIL add one.txt
20
+$FOSSIL commit -m add-one --tag add-one
21
+
22
+# Open checkout bbb.
23
+mkdir ../bbb
24
+cd ../bbb
25
+$FOSSIL open ../update-test-1.fossil
26
+
27
+# Back in aaa, add file two.txt
28
+cd ../aaa
29
+echo two >two.txt
30
+$FOSSIL add two.txt
31
+$FOSSIL commit -m add-two --tag add-two
32
+
33
+# In bbb, delete file one.txt. Then update the change from aaa that
34
+# adds file two. Verify that one.txt says deleted.
35
+cd ../bbb
36
+$FOSSIL rm one.txt
37
+$FOSSIL changes
38
+echo '========================================================================'
39
+$FOSSIL update
40
+echo '======== The previous should show "ADD two.txt" ========================'
41
+$FOSSIL changes
42
+echo '======== The previous should show "DELETE one.txt" ====================='
43
+$FOSSIL commit --test -m check-in
44
+echo '======== Only file two.txt is checked in ==============================='
--- a/test/update-test-1.sh
+++ b/test/update-test-1.sh
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/update-test-1.sh
+++ b/test/update-test-1.sh
@@ -0,0 +1,44 @@
1 #!/bin/sh
2 #
3 # Run this script in an empty directory. A single argument is the full
4 # pathname of the fossil binary. Example:
5 #
6 # sh update-test-1.sh /home/drh/fossil/m1/fossil
7 #
8 export FOSSIL=$1
9 rm -rf aaa bbb update-test-1.fossil
10
11 # Create a test repository
12 $FOSSIL new update-test-1.fossil
13
14 # In checkout aaa, add file one.txt
15 mkdir aaa
16 cd aaa
17 $FOSSIL open ../update-test-1.fossil
18 echo one >one.txt
19 $FOSSIL add one.txt
20 $FOSSIL commit -m add-one --tag add-one
21
22 # Open checkout bbb.
23 mkdir ../bbb
24 cd ../bbb
25 $FOSSIL open ../update-test-1.fossil
26
27 # Back in aaa, add file two.txt
28 cd ../aaa
29 echo two >two.txt
30 $FOSSIL add two.txt
31 $FOSSIL commit -m add-two --tag add-two
32
33 # In bbb, delete file one.txt. Then update the change from aaa that
34 # adds file two. Verify that one.txt says deleted.
35 cd ../bbb
36 $FOSSIL rm one.txt
37 $FOSSIL changes
38 echo '========================================================================'
39 $FOSSIL update
40 echo '======== The previous should show "ADD two.txt" ========================'
41 $FOSSIL changes
42 echo '======== The previous should show "DELETE one.txt" ====================='
43 $FOSSIL commit --test -m check-in
44 echo '======== Only file two.txt is checked in ==============================='
--- a/test/update-test-2.sh
+++ b/test/update-test-2.sh
@@ -0,0 +1,44 @@
1
+#!/bin/sh
2
+#
3
+# Run this script in an empty directory. A single argument is the full
4
+# pathname of the fossil binary. Example:
5
+#
6
+# sh update-test-2.sh /home/drh/fossil/m1/fossil
7
+#
8
+export FOSSIL=$1
9
+rm -rf aaa bbb update-test-2.fossil
10
+
11
+# Create a test repository
12
+$FOSSIL new update-test-2.fossil
13
+
14
+# In checkout aaa, add file one.txt.
15
+mkdir aaa
16
+cd aaa
17
+$FOSSIL open ../update-test-2.fossil
18
+echo one >one.txt
19
+$FOSSIL add one.txt
20
+$FOSSIL commit -m add-one --tag add-one
21
+
22
+# Create checkout bbb.
23
+mkdir ../bbb
24
+cd ../bbb
25
+$FOSSIL open ../update-test-2.fossil
26
+
27
+# Back in aaa, make changes to one.txt. Add file two.txt.
28
+cd ../aaa
29
+echo change >>one.txt
30
+echo two >two.txt
31
+$FOSSIL add two.txt
32
+$FOSSIL commit -m 'chng one and add two' --tag add-two
33
+
34
+# In bbb, remove one.txt, then update.
35
+cd ../bbb
36
+$FOSSIL rm one.txt
37
+$FOSSIL changes
38
+echo '========================================================================'
39
+$FOSSIL update
40
+echo '======== Previous should show "ADD two.txt" and conflict on one.txt ===='
41
+$FOSSIL changes
42
+echo '======== The previous should show "DELETE one.txt" ====================='
43
+$FOSSIL commit --test -m 'check-in'
44
+echo '======== Only file two.txt is checked in ==============================='
--- a/test/update-test-2.sh
+++ b/test/update-test-2.sh
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/update-test-2.sh
+++ b/test/update-test-2.sh
@@ -0,0 +1,44 @@
1 #!/bin/sh
2 #
3 # Run this script in an empty directory. A single argument is the full
4 # pathname of the fossil binary. Example:
5 #
6 # sh update-test-2.sh /home/drh/fossil/m1/fossil
7 #
8 export FOSSIL=$1
9 rm -rf aaa bbb update-test-2.fossil
10
11 # Create a test repository
12 $FOSSIL new update-test-2.fossil
13
14 # In checkout aaa, add file one.txt.
15 mkdir aaa
16 cd aaa
17 $FOSSIL open ../update-test-2.fossil
18 echo one >one.txt
19 $FOSSIL add one.txt
20 $FOSSIL commit -m add-one --tag add-one
21
22 # Create checkout bbb.
23 mkdir ../bbb
24 cd ../bbb
25 $FOSSIL open ../update-test-2.fossil
26
27 # Back in aaa, make changes to one.txt. Add file two.txt.
28 cd ../aaa
29 echo change >>one.txt
30 echo two >two.txt
31 $FOSSIL add two.txt
32 $FOSSIL commit -m 'chng one and add two' --tag add-two
33
34 # In bbb, remove one.txt, then update.
35 cd ../bbb
36 $FOSSIL rm one.txt
37 $FOSSIL changes
38 echo '========================================================================'
39 $FOSSIL update
40 echo '======== Previous should show "ADD two.txt" and conflict on one.txt ===='
41 $FOSSIL changes
42 echo '======== The previous should show "DELETE one.txt" ====================='
43 $FOSSIL commit --test -m 'check-in'
44 echo '======== Only file two.txt is checked in ==============================='

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button