Fossil SCM

Add the "mv" and "rename" commands (aliases for the same thing).

drh 2008-11-09 19:22 trunk
Commit e146d800ac37390cfec72c43ddbb88f583970c89
+106
--- src/add.c
+++ src/add.c
@@ -96,11 +96,16 @@
9696
** COMMAND: rm
9797
** COMMAND: del
9898
**
9999
** Usage: %fossil rm FILE...
100100
** or: %fossil del FILE...
101
+**
101102
** Remove one or more files from the tree.
103
+**
104
+** This command does not remove the files from disk. It just marks the
105
+** files as no longer being part of the project. In other words, future
106
+** changes to the named files will not be versioned.
102107
*/
103108
void del_cmd(void){
104109
int i;
105110
int vid;
106111
@@ -128,5 +133,106 @@
128133
free(zName);
129134
}
130135
db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
131136
db_end_transaction(0);
132137
}
138
+
139
+/*
140
+** Rename a single file.
141
+**
142
+** The original name of the file is zOrig. The new filename is zNew.
143
+*/
144
+static void mv_one_file(int vid, const char *zOrig, const char *zNew){
145
+ printf("RENAME %s %s\n", zOrig, zNew);
146
+ db_multi_exec(
147
+ "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d",
148
+ zNew, zOrig, vid
149
+ );
150
+}
151
+
152
+/*
153
+** COMMAND: mv
154
+** COMMAND: rename
155
+**
156
+** Usage: %fossil mv|rename OLDNAME NEWNAME
157
+** or: %fossil mv|rename OLDNAME... DIR
158
+**
159
+** Move or rename one or more files within the tree
160
+**
161
+** This command does rename the files on disk. All this command does is
162
+** record the fact that filenames have changed so that appropriate notations
163
+** can be made at the next commit/checkin.
164
+*/
165
+void mv_cmd(void){
166
+ int i;
167
+ int vid;
168
+ char *zDest;
169
+ Blob dest;
170
+ Stmt q;
171
+
172
+ db_must_be_within_tree();
173
+ vid = db_lget_int("checkout", 0);
174
+ if( vid==0 ){
175
+ fossil_panic("no checkout rename files in");
176
+ }
177
+ if( g.argc<4 ){
178
+ usage("OLDNAME NEWNAME");
179
+ }
180
+ zDest = g.argv[g.argc-1];
181
+ db_begin_transaction();
182
+ file_tree_name(zDest, &dest, 1);
183
+ db_multi_exec(
184
+ "UPDATE vfile SET origname=pathname WHERE origname IS NULL;"
185
+ );
186
+ db_multi_exec(
187
+ "CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);"
188
+ );
189
+ if( file_isdir(zDest)!=1 ){
190
+ Blob orig;
191
+ if( g.argc!=4 ){
192
+ usage("OLDNAME NEWNAME");
193
+ }
194
+ file_tree_name(g.argv[2], &orig, 1);
195
+ db_multi_exec(
196
+ "INSERT INTO mv VALUES(%B,%B)", &orig, &dest
197
+ );
198
+ }else{
199
+ for(i=2; i<g.argc-1; i++){
200
+ Blob orig;
201
+ char *zOrig;
202
+ int nOrig;
203
+ file_tree_name(g.argv[i], &orig, 1);
204
+ zOrig = blob_str(&orig);
205
+ nOrig = blob_size(&orig);
206
+ db_prepare(&q,
207
+ "SELECT pathname FROM vfile"
208
+ " WHERE vid=%d"
209
+ " AND (pathname='%s' OR pathname GLOB '%s/*')"
210
+ " ORDER BY 1",
211
+ vid, zOrig, zOrig
212
+ );
213
+ while( db_step(&q)==SQLITE_ROW ){
214
+ const char *zPath = db_column_text(&q, 0);
215
+ int nPath = db_column_bytes(&q, 0);
216
+ const char *zTail;
217
+ if( nPath==nOrig ){
218
+ zTail = file_tail(zPath);
219
+ }else{
220
+ zTail = &zPath[nOrig+1];
221
+ }
222
+ db_multi_exec(
223
+ "INSERT INTO mv VALUES('%s','%s/%s')",
224
+ zPath, blob_str(&dest), zTail
225
+ );
226
+ }
227
+ db_finalize(&q);
228
+ }
229
+ }
230
+ db_prepare(&q, "SELECT f, t FROM mv ORDER BY f");
231
+ while( db_step(&q)==SQLITE_ROW ){
232
+ const char *zFrom = db_column_text(&q, 0);
233
+ const char *zTo = db_column_text(&q, 1);
234
+ mv_one_file(vid, zFrom, zTo);
235
+ }
236
+ db_finalize(&q);
237
+ db_end_transaction(0);
238
+}
133239
--- src/add.c
+++ src/add.c
@@ -96,11 +96,16 @@
96 ** COMMAND: rm
97 ** COMMAND: del
98 **
99 ** Usage: %fossil rm FILE...
100 ** or: %fossil del FILE...
 
101 ** Remove one or more files from the tree.
 
 
 
 
102 */
103 void del_cmd(void){
104 int i;
105 int vid;
106
@@ -128,5 +133,106 @@
128 free(zName);
129 }
130 db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
131 db_end_transaction(0);
132 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
--- src/add.c
+++ src/add.c
@@ -96,11 +96,16 @@
96 ** COMMAND: rm
97 ** COMMAND: del
98 **
99 ** Usage: %fossil rm FILE...
100 ** or: %fossil del FILE...
101 **
102 ** Remove one or more files from the tree.
103 **
104 ** This command does not remove the files from disk. It just marks the
105 ** files as no longer being part of the project. In other words, future
106 ** changes to the named files will not be versioned.
107 */
108 void del_cmd(void){
109 int i;
110 int vid;
111
@@ -128,5 +133,106 @@
133 free(zName);
134 }
135 db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
136 db_end_transaction(0);
137 }
138
139 /*
140 ** Rename a single file.
141 **
142 ** The original name of the file is zOrig. The new filename is zNew.
143 */
144 static void mv_one_file(int vid, const char *zOrig, const char *zNew){
145 printf("RENAME %s %s\n", zOrig, zNew);
146 db_multi_exec(
147 "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d",
148 zNew, zOrig, vid
149 );
150 }
151
152 /*
153 ** COMMAND: mv
154 ** COMMAND: rename
155 **
156 ** Usage: %fossil mv|rename OLDNAME NEWNAME
157 ** or: %fossil mv|rename OLDNAME... DIR
158 **
159 ** Move or rename one or more files within the tree
160 **
161 ** This command does rename the files on disk. All this command does is
162 ** record the fact that filenames have changed so that appropriate notations
163 ** can be made at the next commit/checkin.
164 */
165 void mv_cmd(void){
166 int i;
167 int vid;
168 char *zDest;
169 Blob dest;
170 Stmt q;
171
172 db_must_be_within_tree();
173 vid = db_lget_int("checkout", 0);
174 if( vid==0 ){
175 fossil_panic("no checkout rename files in");
176 }
177 if( g.argc<4 ){
178 usage("OLDNAME NEWNAME");
179 }
180 zDest = g.argv[g.argc-1];
181 db_begin_transaction();
182 file_tree_name(zDest, &dest, 1);
183 db_multi_exec(
184 "UPDATE vfile SET origname=pathname WHERE origname IS NULL;"
185 );
186 db_multi_exec(
187 "CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);"
188 );
189 if( file_isdir(zDest)!=1 ){
190 Blob orig;
191 if( g.argc!=4 ){
192 usage("OLDNAME NEWNAME");
193 }
194 file_tree_name(g.argv[2], &orig, 1);
195 db_multi_exec(
196 "INSERT INTO mv VALUES(%B,%B)", &orig, &dest
197 );
198 }else{
199 for(i=2; i<g.argc-1; i++){
200 Blob orig;
201 char *zOrig;
202 int nOrig;
203 file_tree_name(g.argv[i], &orig, 1);
204 zOrig = blob_str(&orig);
205 nOrig = blob_size(&orig);
206 db_prepare(&q,
207 "SELECT pathname FROM vfile"
208 " WHERE vid=%d"
209 " AND (pathname='%s' OR pathname GLOB '%s/*')"
210 " ORDER BY 1",
211 vid, zOrig, zOrig
212 );
213 while( db_step(&q)==SQLITE_ROW ){
214 const char *zPath = db_column_text(&q, 0);
215 int nPath = db_column_bytes(&q, 0);
216 const char *zTail;
217 if( nPath==nOrig ){
218 zTail = file_tail(zPath);
219 }else{
220 zTail = &zPath[nOrig+1];
221 }
222 db_multi_exec(
223 "INSERT INTO mv VALUES('%s','%s/%s')",
224 zPath, blob_str(&dest), zTail
225 );
226 }
227 db_finalize(&q);
228 }
229 }
230 db_prepare(&q, "SELECT f, t FROM mv ORDER BY f");
231 while( db_step(&q)==SQLITE_ROW ){
232 const char *zFrom = db_column_text(&q, 0);
233 const char *zTo = db_column_text(&q, 1);
234 mv_one_file(vid, zFrom, zTo);
235 }
236 db_finalize(&q);
237 db_end_transaction(0);
238 }
239
+28 -9
--- src/checkin.c
+++ src/checkin.c
@@ -36,18 +36,21 @@
3636
*/
3737
static void status_report(Blob *report, const char *zPrefix){
3838
Stmt q;
3939
int nPrefix = strlen(zPrefix);
4040
db_prepare(&q,
41
- "SELECT pathname, deleted, chnged, rid FROM vfile "
42
- "WHERE file_is_selected(id) AND (chnged OR deleted OR rid=0) ORDER BY 1"
41
+ "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
42
+ " FROM vfile "
43
+ " WHERE file_is_selected(id)"
44
+ " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
4345
);
4446
while( db_step(&q)==SQLITE_ROW ){
4547
const char *zPathname = db_column_text(&q,0);
4648
int isDeleted = db_column_int(&q, 1);
4749
int isChnged = db_column_int(&q,2);
4850
int isNew = db_column_int(&q,3)==0;
51
+ int isRenamed = db_column_int(&q,4);
4952
char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
5053
blob_append(report, zPrefix, nPrefix);
5154
if( isDeleted ){
5255
blob_appendf(report, "DELETED %s\n", zPathname);
5356
}else if( access(zFullName, 0) ){
@@ -58,12 +61,14 @@
5861
blob_appendf(report, "DELETED %s\n", zPathname);
5962
}else if( isChnged==2 ){
6063
blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname);
6164
}else if( isChnged==3 ){
6265
blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname);
63
- }else{
66
+ }else if( isChnged==1 ){
6467
blob_appendf(report, "EDITED %s\n", zPathname);
68
+ }else if( isRenamed ){
69
+ blob_appendf(report, "RENAMED %s\n", zPathname);
6570
}
6671
free(zFullName);
6772
}
6873
db_finalize(&q);
6974
db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid"
@@ -127,26 +132,32 @@
127132
Stmt q;
128133
129134
db_must_be_within_tree();
130135
vid = db_lget_int("checkout", 0);
131136
vfile_check_signature(vid);
132
- db_prepare(&q, "SELECT pathname, deleted, rid, chnged FROM vfile"
133
- " ORDER BY 1");
137
+ db_prepare(&q,
138
+ "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
139
+ " FROM vfile"
140
+ " ORDER BY 1"
141
+ );
134142
while( db_step(&q)==SQLITE_ROW ){
135143
const char *zPathname = db_column_text(&q,0);
136144
int isDeleted = db_column_int(&q, 1);
137145
int isNew = db_column_int(&q,2)==0;
138146
int chnged = db_column_int(&q,3);
147
+ int renamed = db_column_int(&q,4);
139148
char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
140149
if( isNew ){
141150
printf("ADDED %s\n", zPathname);
142151
}else if( access(zFullName, 0) ){
143152
printf("MISSING %s\n", zPathname);
144153
}else if( isDeleted ){
145154
printf("DELETED %s\n", zPathname);
146155
}else if( chnged ){
147156
printf("EDITED %s\n", zPathname);
157
+ }else if( renamed ){
158
+ printf("RENAMED %s\n", zPathname);
148159
}else{
149160
printf("UNCHANGED %s\n", zPathname);
150161
}
151162
free(zFullName);
152163
}
@@ -480,28 +491,35 @@
480491
blob_appendf(&manifest, "C %F\n", blob_str(&comment));
481492
zDate = db_text(0, "SELECT datetime('now')");
482493
zDate[10] = 'T';
483494
blob_appendf(&manifest, "D %s\n", zDate);
484495
db_prepare(&q,
485
- "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid"
496
+ "SELECT pathname, uuid, origname"
497
+ " FROM vfile JOIN blob ON vfile.mrid=blob.rid"
486498
" WHERE NOT deleted AND vfile.vid=%d"
487499
" ORDER BY 1", vid);
488500
blob_zero(&filename);
489501
blob_appendf(&filename, "%s/", g.zLocalRoot);
490502
nBasename = blob_size(&filename);
491503
while( db_step(&q)==SQLITE_ROW ){
492504
const char *zName = db_column_text(&q, 0);
493505
const char *zUuid = db_column_text(&q, 1);
506
+ const char *zOrig = db_column_text(&q, 2);
494507
const char *zPerm;
495508
blob_append(&filename, zName, -1);
496509
if( file_isexe(blob_str(&filename)) ){
497510
zPerm = " x";
498511
}else{
499512
zPerm = "";
500513
}
501514
blob_resize(&filename, nBasename);
502
- blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
515
+ if( zOrig==0 || strcmp(zOrig,zName)==0 ){
516
+ blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
517
+ }else{
518
+ if( zPerm[0]==0 ){ zPerm = " w"; }
519
+ blob_appendf(&manifest, "F %F %s%s %F\n", zName, zUuid, zPerm, zOrig);
520
+ }
503521
}
504522
blob_reset(&filename);
505523
db_finalize(&q);
506524
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
507525
blob_appendf(&manifest, "P %s", zUuid);
@@ -557,11 +575,12 @@
557575
/* Update the vfile and vmerge tables */
558576
db_multi_exec(
559577
"DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
560578
"DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
561579
"UPDATE vfile SET vid=%d;"
562
- "UPDATE vfile SET rid=mrid, chnged=0, deleted=0 WHERE file_is_selected(id);"
580
+ "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
581
+ " WHERE file_is_selected(id);"
563582
, vid, nvid
564583
);
565584
db_lset_int("checkout", nvid);
566585
567586
/* Verify that the repository checksum matches the expected checksum
@@ -791,11 +810,11 @@
791810
** least one.
792811
*/
793812
794813
blob_appendf(&manifest, "P");
795814
for (i=0;i<zParentCount;i++) {
796
- char* zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", zParents [i]);
815
+ char* zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", zParents[i]);
797816
blob_appendf(&manifest, " %s", zUuid);
798817
free(zUuid);
799818
}
800819
blob_appendf(&manifest, "\n");
801820
802821
--- src/checkin.c
+++ src/checkin.c
@@ -36,18 +36,21 @@
36 */
37 static void status_report(Blob *report, const char *zPrefix){
38 Stmt q;
39 int nPrefix = strlen(zPrefix);
40 db_prepare(&q,
41 "SELECT pathname, deleted, chnged, rid FROM vfile "
42 "WHERE file_is_selected(id) AND (chnged OR deleted OR rid=0) ORDER BY 1"
 
 
43 );
44 while( db_step(&q)==SQLITE_ROW ){
45 const char *zPathname = db_column_text(&q,0);
46 int isDeleted = db_column_int(&q, 1);
47 int isChnged = db_column_int(&q,2);
48 int isNew = db_column_int(&q,3)==0;
 
49 char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
50 blob_append(report, zPrefix, nPrefix);
51 if( isDeleted ){
52 blob_appendf(report, "DELETED %s\n", zPathname);
53 }else if( access(zFullName, 0) ){
@@ -58,12 +61,14 @@
58 blob_appendf(report, "DELETED %s\n", zPathname);
59 }else if( isChnged==2 ){
60 blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname);
61 }else if( isChnged==3 ){
62 blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname);
63 }else{
64 blob_appendf(report, "EDITED %s\n", zPathname);
 
 
65 }
66 free(zFullName);
67 }
68 db_finalize(&q);
69 db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid"
@@ -127,26 +132,32 @@
127 Stmt q;
128
129 db_must_be_within_tree();
130 vid = db_lget_int("checkout", 0);
131 vfile_check_signature(vid);
132 db_prepare(&q, "SELECT pathname, deleted, rid, chnged FROM vfile"
133 " ORDER BY 1");
 
 
 
134 while( db_step(&q)==SQLITE_ROW ){
135 const char *zPathname = db_column_text(&q,0);
136 int isDeleted = db_column_int(&q, 1);
137 int isNew = db_column_int(&q,2)==0;
138 int chnged = db_column_int(&q,3);
 
139 char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
140 if( isNew ){
141 printf("ADDED %s\n", zPathname);
142 }else if( access(zFullName, 0) ){
143 printf("MISSING %s\n", zPathname);
144 }else if( isDeleted ){
145 printf("DELETED %s\n", zPathname);
146 }else if( chnged ){
147 printf("EDITED %s\n", zPathname);
 
 
148 }else{
149 printf("UNCHANGED %s\n", zPathname);
150 }
151 free(zFullName);
152 }
@@ -480,28 +491,35 @@
480 blob_appendf(&manifest, "C %F\n", blob_str(&comment));
481 zDate = db_text(0, "SELECT datetime('now')");
482 zDate[10] = 'T';
483 blob_appendf(&manifest, "D %s\n", zDate);
484 db_prepare(&q,
485 "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid"
 
486 " WHERE NOT deleted AND vfile.vid=%d"
487 " ORDER BY 1", vid);
488 blob_zero(&filename);
489 blob_appendf(&filename, "%s/", g.zLocalRoot);
490 nBasename = blob_size(&filename);
491 while( db_step(&q)==SQLITE_ROW ){
492 const char *zName = db_column_text(&q, 0);
493 const char *zUuid = db_column_text(&q, 1);
 
494 const char *zPerm;
495 blob_append(&filename, zName, -1);
496 if( file_isexe(blob_str(&filename)) ){
497 zPerm = " x";
498 }else{
499 zPerm = "";
500 }
501 blob_resize(&filename, nBasename);
502 blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
 
 
 
 
 
503 }
504 blob_reset(&filename);
505 db_finalize(&q);
506 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
507 blob_appendf(&manifest, "P %s", zUuid);
@@ -557,11 +575,12 @@
557 /* Update the vfile and vmerge tables */
558 db_multi_exec(
559 "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
560 "DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
561 "UPDATE vfile SET vid=%d;"
562 "UPDATE vfile SET rid=mrid, chnged=0, deleted=0 WHERE file_is_selected(id);"
 
563 , vid, nvid
564 );
565 db_lset_int("checkout", nvid);
566
567 /* Verify that the repository checksum matches the expected checksum
@@ -791,11 +810,11 @@
791 ** least one.
792 */
793
794 blob_appendf(&manifest, "P");
795 for (i=0;i<zParentCount;i++) {
796 char* zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", zParents [i]);
797 blob_appendf(&manifest, " %s", zUuid);
798 free(zUuid);
799 }
800 blob_appendf(&manifest, "\n");
801
802
--- src/checkin.c
+++ src/checkin.c
@@ -36,18 +36,21 @@
36 */
37 static void status_report(Blob *report, const char *zPrefix){
38 Stmt q;
39 int nPrefix = strlen(zPrefix);
40 db_prepare(&q,
41 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
42 " FROM vfile "
43 " WHERE file_is_selected(id)"
44 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
45 );
46 while( db_step(&q)==SQLITE_ROW ){
47 const char *zPathname = db_column_text(&q,0);
48 int isDeleted = db_column_int(&q, 1);
49 int isChnged = db_column_int(&q,2);
50 int isNew = db_column_int(&q,3)==0;
51 int isRenamed = db_column_int(&q,4);
52 char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
53 blob_append(report, zPrefix, nPrefix);
54 if( isDeleted ){
55 blob_appendf(report, "DELETED %s\n", zPathname);
56 }else if( access(zFullName, 0) ){
@@ -58,12 +61,14 @@
61 blob_appendf(report, "DELETED %s\n", zPathname);
62 }else if( isChnged==2 ){
63 blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname);
64 }else if( isChnged==3 ){
65 blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname);
66 }else if( isChnged==1 ){
67 blob_appendf(report, "EDITED %s\n", zPathname);
68 }else if( isRenamed ){
69 blob_appendf(report, "RENAMED %s\n", zPathname);
70 }
71 free(zFullName);
72 }
73 db_finalize(&q);
74 db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid"
@@ -127,26 +132,32 @@
132 Stmt q;
133
134 db_must_be_within_tree();
135 vid = db_lget_int("checkout", 0);
136 vfile_check_signature(vid);
137 db_prepare(&q,
138 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
139 " FROM vfile"
140 " ORDER BY 1"
141 );
142 while( db_step(&q)==SQLITE_ROW ){
143 const char *zPathname = db_column_text(&q,0);
144 int isDeleted = db_column_int(&q, 1);
145 int isNew = db_column_int(&q,2)==0;
146 int chnged = db_column_int(&q,3);
147 int renamed = db_column_int(&q,4);
148 char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
149 if( isNew ){
150 printf("ADDED %s\n", zPathname);
151 }else if( access(zFullName, 0) ){
152 printf("MISSING %s\n", zPathname);
153 }else if( isDeleted ){
154 printf("DELETED %s\n", zPathname);
155 }else if( chnged ){
156 printf("EDITED %s\n", zPathname);
157 }else if( renamed ){
158 printf("RENAMED %s\n", zPathname);
159 }else{
160 printf("UNCHANGED %s\n", zPathname);
161 }
162 free(zFullName);
163 }
@@ -480,28 +491,35 @@
491 blob_appendf(&manifest, "C %F\n", blob_str(&comment));
492 zDate = db_text(0, "SELECT datetime('now')");
493 zDate[10] = 'T';
494 blob_appendf(&manifest, "D %s\n", zDate);
495 db_prepare(&q,
496 "SELECT pathname, uuid, origname"
497 " FROM vfile JOIN blob ON vfile.mrid=blob.rid"
498 " WHERE NOT deleted AND vfile.vid=%d"
499 " ORDER BY 1", vid);
500 blob_zero(&filename);
501 blob_appendf(&filename, "%s/", g.zLocalRoot);
502 nBasename = blob_size(&filename);
503 while( db_step(&q)==SQLITE_ROW ){
504 const char *zName = db_column_text(&q, 0);
505 const char *zUuid = db_column_text(&q, 1);
506 const char *zOrig = db_column_text(&q, 2);
507 const char *zPerm;
508 blob_append(&filename, zName, -1);
509 if( file_isexe(blob_str(&filename)) ){
510 zPerm = " x";
511 }else{
512 zPerm = "";
513 }
514 blob_resize(&filename, nBasename);
515 if( zOrig==0 || strcmp(zOrig,zName)==0 ){
516 blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
517 }else{
518 if( zPerm[0]==0 ){ zPerm = " w"; }
519 blob_appendf(&manifest, "F %F %s%s %F\n", zName, zUuid, zPerm, zOrig);
520 }
521 }
522 blob_reset(&filename);
523 db_finalize(&q);
524 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
525 blob_appendf(&manifest, "P %s", zUuid);
@@ -557,11 +575,12 @@
575 /* Update the vfile and vmerge tables */
576 db_multi_exec(
577 "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
578 "DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
579 "UPDATE vfile SET vid=%d;"
580 "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
581 " WHERE file_is_selected(id);"
582 , vid, nvid
583 );
584 db_lset_int("checkout", nvid);
585
586 /* Verify that the repository checksum matches the expected checksum
@@ -791,11 +810,11 @@
810 ** least one.
811 */
812
813 blob_appendf(&manifest, "P");
814 for (i=0;i<zParentCount;i++) {
815 char* zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", zParents[i]);
816 blob_appendf(&manifest, " %s", zUuid);
817 free(zUuid);
818 }
819 blob_appendf(&manifest, "\n");
820
821
+2 -1
--- src/checkout.c
+++ src/checkout.c
@@ -40,11 +40,12 @@
4040
int vid;
4141
db_must_be_within_tree();
4242
vid = db_lget_int("checkout",0);
4343
if( vid==0 ) return 2;
4444
vfile_check_signature(vid);
45
- return db_exists("SELECT 1 FROM vfile WHERE chnged");
45
+ return db_exists("SELECT 1 FROM vfile WHERE chnged"
46
+ " OR coalesce(origname!=pathname,0)");
4647
}
4748
4849
/*
4950
** Undo the current check-out. Unlink all files from the disk.
5051
** Clear the VFILE table.
5152
--- src/checkout.c
+++ src/checkout.c
@@ -40,11 +40,12 @@
40 int vid;
41 db_must_be_within_tree();
42 vid = db_lget_int("checkout",0);
43 if( vid==0 ) return 2;
44 vfile_check_signature(vid);
45 return db_exists("SELECT 1 FROM vfile WHERE chnged");
 
46 }
47
48 /*
49 ** Undo the current check-out. Unlink all files from the disk.
50 ** Clear the VFILE table.
51
--- src/checkout.c
+++ src/checkout.c
@@ -40,11 +40,12 @@
40 int vid;
41 db_must_be_within_tree();
42 vid = db_lget_int("checkout",0);
43 if( vid==0 ) return 2;
44 vfile_check_signature(vid);
45 return db_exists("SELECT 1 FROM vfile WHERE chnged"
46 " OR coalesce(origname!=pathname,0)");
47 }
48
49 /*
50 ** Undo the current check-out. Unlink all files from the disk.
51 ** Clear the VFILE table.
52
+11
--- src/db.c
+++ src/db.c
@@ -674,17 +674,28 @@
674674
** If zDbName is a valid local database file, open it and return
675675
** true. If it is not a valid local database file, return 0.
676676
*/
677677
static int isValidLocalDb(const char *zDbName){
678678
i64 lsize;
679
+ int rc;
680
+ sqlite3_stmt *pStmt;
681
+
679682
if( access(zDbName, F_OK) ) return 0;
680683
lsize = file_size(zDbName);
681684
if( lsize%1024!=0 || lsize<4096 ) return 0;
682685
db_open_or_attach(zDbName, "localdb");
683686
g.localOpen = 1;
684687
db_open_config();
685688
db_open_repository(0);
689
+
690
+ /* If the "origname" column is missing from the vfile table, then
691
+ ** add it now. */
692
+ rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
693
+ if( rc==SQLITE_ERROR ){
694
+ sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
695
+ }
696
+
686697
return 1;
687698
}
688699
689700
/*
690701
** Locate the root directory of the local repository tree. The root
691702
--- src/db.c
+++ src/db.c
@@ -674,17 +674,28 @@
674 ** If zDbName is a valid local database file, open it and return
675 ** true. If it is not a valid local database file, return 0.
676 */
677 static int isValidLocalDb(const char *zDbName){
678 i64 lsize;
 
 
 
679 if( access(zDbName, F_OK) ) return 0;
680 lsize = file_size(zDbName);
681 if( lsize%1024!=0 || lsize<4096 ) return 0;
682 db_open_or_attach(zDbName, "localdb");
683 g.localOpen = 1;
684 db_open_config();
685 db_open_repository(0);
 
 
 
 
 
 
 
 
686 return 1;
687 }
688
689 /*
690 ** Locate the root directory of the local repository tree. The root
691
--- src/db.c
+++ src/db.c
@@ -674,17 +674,28 @@
674 ** If zDbName is a valid local database file, open it and return
675 ** true. If it is not a valid local database file, return 0.
676 */
677 static int isValidLocalDb(const char *zDbName){
678 i64 lsize;
679 int rc;
680 sqlite3_stmt *pStmt;
681
682 if( access(zDbName, F_OK) ) return 0;
683 lsize = file_size(zDbName);
684 if( lsize%1024!=0 || lsize<4096 ) return 0;
685 db_open_or_attach(zDbName, "localdb");
686 g.localOpen = 1;
687 db_open_config();
688 db_open_repository(0);
689
690 /* If the "origname" column is missing from the vfile table, then
691 ** add it now. */
692 rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
693 if( rc==SQLITE_ERROR ){
694 sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
695 }
696
697 return 1;
698 }
699
700 /*
701 ** Locate the root directory of the local repository tree. The root
702
+13
--- src/file.c
+++ src/file.c
@@ -51,10 +51,23 @@
5151
if( stat(zFilename, &buf)!=0 ){
5252
return -1;
5353
}
5454
return buf.st_mtime;
5555
}
56
+
57
+/*
58
+** Return the tail of a file pathname. The tail is the last component
59
+** of the path. For example, the tail of "/a/b/c.d" is "c.d".
60
+*/
61
+const char *file_tail(const char *z){
62
+ const char *zTail = z;
63
+ while( z[0] ){
64
+ if( z[0]=='/' ) zTail = &z[1];
65
+ z++;
66
+ }
67
+ return zTail;
68
+}
5669
5770
/*
5871
** Copy the content of a file from one place to another.
5972
*/
6073
void file_copy(const char *zFrom, const char *zTo){
6174
--- src/file.c
+++ src/file.c
@@ -51,10 +51,23 @@
51 if( stat(zFilename, &buf)!=0 ){
52 return -1;
53 }
54 return buf.st_mtime;
55 }
 
 
 
 
 
 
 
 
 
 
 
 
 
56
57 /*
58 ** Copy the content of a file from one place to another.
59 */
60 void file_copy(const char *zFrom, const char *zTo){
61
--- src/file.c
+++ src/file.c
@@ -51,10 +51,23 @@
51 if( stat(zFilename, &buf)!=0 ){
52 return -1;
53 }
54 return buf.st_mtime;
55 }
56
57 /*
58 ** Return the tail of a file pathname. The tail is the last component
59 ** of the path. For example, the tail of "/a/b/c.d" is "c.d".
60 */
61 const char *file_tail(const char *z){
62 const char *zTail = z;
63 while( z[0] ){
64 if( z[0]=='/' ) zTail = &z[1];
65 z++;
66 }
67 return zTail;
68 }
69
70 /*
71 ** Copy the content of a file from one place to another.
72 */
73 void file_copy(const char *zFrom, const char *zTo){
74
+4 -3
--- src/schema.c
+++ src/schema.c
@@ -337,12 +337,12 @@
337337
@ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
338338
@ value CLOB, -- Content of the named parameter
339339
@ CHECK( typeof(name)='text' AND length(name)>=1 )
340340
@ );
341341
@
342
-@ -- Each entry in the vfile table represents a single file or folder
343
-@ -- that is part of a version.
342
+@ -- Each entry in the vfile table represents a single file in the
343
+@ -- current checkout.
344344
@ --
345345
@ -- The file.rid field is 0 for files or folders that have been
346346
@ -- added but not yet committed.
347347
@ --
348348
@ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
@@ -359,11 +359,12 @@
359359
@ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
360360
@ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
361361
@ deleted BOOLEAN DEFAULT 0, -- True if deleted
362362
@ rid INTEGER, -- Originally from this repository record
363363
@ mrid INTEGER, -- Based on this record due to a merge
364
-@ pathname TEXT, -- Full pathname
364
+@ pathname TEXT, -- Full pathname relative to root
365
+@ origname TEXT -- Original pathname. NULL if unchanged
365366
@ UNIQUE(pathname,vid)
366367
@ );
367368
@
368369
@ -- This table holds a record of uncommitted merges in the local
369370
@ -- file tree. If a VFILE entry with id has merged with another
370371
--- src/schema.c
+++ src/schema.c
@@ -337,12 +337,12 @@
337 @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
338 @ value CLOB, -- Content of the named parameter
339 @ CHECK( typeof(name)='text' AND length(name)>=1 )
340 @ );
341 @
342 @ -- Each entry in the vfile table represents a single file or folder
343 @ -- that is part of a version.
344 @ --
345 @ -- The file.rid field is 0 for files or folders that have been
346 @ -- added but not yet committed.
347 @ --
348 @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
@@ -359,11 +359,12 @@
359 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
360 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
361 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
362 @ rid INTEGER, -- Originally from this repository record
363 @ mrid INTEGER, -- Based on this record due to a merge
364 @ pathname TEXT, -- Full pathname
 
365 @ UNIQUE(pathname,vid)
366 @ );
367 @
368 @ -- This table holds a record of uncommitted merges in the local
369 @ -- file tree. If a VFILE entry with id has merged with another
370
--- src/schema.c
+++ src/schema.c
@@ -337,12 +337,12 @@
337 @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry
338 @ value CLOB, -- Content of the named parameter
339 @ CHECK( typeof(name)='text' AND length(name)>=1 )
340 @ );
341 @
342 @ -- Each entry in the vfile table represents a single file in the
343 @ -- current checkout.
344 @ --
345 @ -- The file.rid field is 0 for files or folders that have been
346 @ -- added but not yet committed.
347 @ --
348 @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
@@ -359,11 +359,12 @@
359 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
360 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
361 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
362 @ rid INTEGER, -- Originally from this repository record
363 @ mrid INTEGER, -- Based on this record due to a merge
364 @ pathname TEXT, -- Full pathname relative to root
365 @ origname TEXT -- Original pathname. NULL if unchanged
366 @ UNIQUE(pathname,vid)
367 @ );
368 @
369 @ -- This table holds a record of uncommitted merges in the local
370 @ -- file tree. If a VFILE entry with id has merged with another
371

Keyboard Shortcuts

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