Fossil SCM

Do a better job of merging branches that contain lots of file renames.

drh 2011-09-02 16:19 trunk
Commit 0b93b0f958b0d70a1f352fca4c53ab7574a890ac
+1 -1
--- src/bisect.c
+++ src/bisect.c
@@ -42,11 +42,11 @@
4242
}
4343
bisect.good = db_lget_int("bisect-good", 0);
4444
if( bisect.good==0 ){
4545
fossil_fatal("no \"good\" version has been identified");
4646
}
47
- p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"));
47
+ p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"), 0);
4848
if( p==0 ){
4949
char *zBad = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.bad);
5050
char *zGood = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.good);
5151
fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
5252
zGood, zBad);
5353
--- src/bisect.c
+++ src/bisect.c
@@ -42,11 +42,11 @@
42 }
43 bisect.good = db_lget_int("bisect-good", 0);
44 if( bisect.good==0 ){
45 fossil_fatal("no \"good\" version has been identified");
46 }
47 p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"));
48 if( p==0 ){
49 char *zBad = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.bad);
50 char *zGood = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.good);
51 fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
52 zGood, zBad);
53
--- src/bisect.c
+++ src/bisect.c
@@ -42,11 +42,11 @@
42 }
43 bisect.good = db_lget_int("bisect-good", 0);
44 if( bisect.good==0 ){
45 fossil_fatal("no \"good\" version has been identified");
46 }
47 p = path_shortest(bisect.good, bisect.bad, bisect_option("direct-only"), 0);
48 if( p==0 ){
49 char *zBad = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.bad);
50 char *zGood = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", bisect.good);
51 fossil_fatal("no path from good ([%S]) to bad ([%S]) or back",
52 zGood, zBad);
53
+4 -4
--- src/merge.c
+++ src/merge.c
@@ -196,19 +196,19 @@
196196
);
197197
198198
/*
199199
** Compute name changes from P->V
200200
*/
201
- find_filename_changes(vid, pid, &nChng, &aChng, debugFlag ? "P->V" : 0);
201
+ find_filename_changes(pid, vid, 0, &nChng, &aChng, debugFlag ? "P->V" : 0);
202202
if( nChng ){
203203
for(i=0; i<nChng; i++){
204204
char *z;
205
- z = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]);
205
+ z = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]);
206206
db_multi_exec(
207207
"UPDATE fv SET fnp=%Q, fnm=%Q"
208208
" WHERE fn=(SELECT name FROM filename WHERE fnid=%d)",
209
- z, z, aChng[i*2]
209
+ z, z, aChng[i*2+1]
210210
);
211211
free(z);
212212
}
213213
fossil_free(aChng);
214214
db_multi_exec("UPDATE fv SET fnm=fnp WHERE fnp!=fn");
@@ -226,11 +226,11 @@
226226
);
227227
228228
/*
229229
** Compute name changes from P->M
230230
*/
231
- find_filename_changes(pid, mid, &nChng, &aChng, debugFlag ? "P->M" : 0);
231
+ find_filename_changes(pid, mid, 0, &nChng, &aChng, debugFlag ? "P->M" : 0);
232232
if( nChng ){
233233
if( nChng>4 ) db_multi_exec("CREATE INDEX fv_fnp ON fv(fnp)");
234234
for(i=0; i<nChng; i++){
235235
db_multi_exec(
236236
"UPDATE fv SET fnm=(SELECT name FROM filename WHERE fnid=%d)"
237237
--- src/merge.c
+++ src/merge.c
@@ -196,19 +196,19 @@
196 );
197
198 /*
199 ** Compute name changes from P->V
200 */
201 find_filename_changes(vid, pid, &nChng, &aChng, debugFlag ? "P->V" : 0);
202 if( nChng ){
203 for(i=0; i<nChng; i++){
204 char *z;
205 z = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]);
206 db_multi_exec(
207 "UPDATE fv SET fnp=%Q, fnm=%Q"
208 " WHERE fn=(SELECT name FROM filename WHERE fnid=%d)",
209 z, z, aChng[i*2]
210 );
211 free(z);
212 }
213 fossil_free(aChng);
214 db_multi_exec("UPDATE fv SET fnm=fnp WHERE fnp!=fn");
@@ -226,11 +226,11 @@
226 );
227
228 /*
229 ** Compute name changes from P->M
230 */
231 find_filename_changes(pid, mid, &nChng, &aChng, debugFlag ? "P->M" : 0);
232 if( nChng ){
233 if( nChng>4 ) db_multi_exec("CREATE INDEX fv_fnp ON fv(fnp)");
234 for(i=0; i<nChng; i++){
235 db_multi_exec(
236 "UPDATE fv SET fnm=(SELECT name FROM filename WHERE fnid=%d)"
237
--- src/merge.c
+++ src/merge.c
@@ -196,19 +196,19 @@
196 );
197
198 /*
199 ** Compute name changes from P->V
200 */
201 find_filename_changes(pid, vid, 0, &nChng, &aChng, debugFlag ? "P->V" : 0);
202 if( nChng ){
203 for(i=0; i<nChng; i++){
204 char *z;
205 z = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]);
206 db_multi_exec(
207 "UPDATE fv SET fnp=%Q, fnm=%Q"
208 " WHERE fn=(SELECT name FROM filename WHERE fnid=%d)",
209 z, z, aChng[i*2+1]
210 );
211 free(z);
212 }
213 fossil_free(aChng);
214 db_multi_exec("UPDATE fv SET fnm=fnp WHERE fnp!=fn");
@@ -226,11 +226,11 @@
226 );
227
228 /*
229 ** Compute name changes from P->M
230 */
231 find_filename_changes(pid, mid, 0, &nChng, &aChng, debugFlag ? "P->M" : 0);
232 if( nChng ){
233 if( nChng>4 ) db_multi_exec("CREATE INDEX fv_fnp ON fv(fnp)");
234 for(i=0; i<nChng; i++){
235 db_multi_exec(
236 "UPDATE fv SET fnm=(SELECT name FROM filename WHERE fnid=%d)"
237
+47 -19
--- src/path.c
+++ src/path.c
@@ -116,11 +116,16 @@
116116
** Elements of the path can be traversed by following the PathNode.u.pTo
117117
** pointer chain.
118118
**
119119
** Return NULL if no path is found.
120120
*/
121
-PathNode *path_shortest(int iFrom, int iTo, int directOnly){
121
+PathNode *path_shortest(
122
+ int iFrom, /* Path starts here */
123
+ int iTo, /* Path ends here */
124
+ int directOnly, /* No merge links if true */
125
+ int oneWayOnly /* Parent->child only if true */
126
+){
122127
Stmt s;
123128
PathNode *pPrev;
124129
PathNode *p;
125130
126131
path_reset();
@@ -127,11 +132,15 @@
127132
path.pStart = path_new_node(iFrom, 0, 0);
128133
if( iTo==iFrom ){
129134
path.pEnd = path.pStart;
130135
return path.pStart;
131136
}
132
- if( directOnly ){
137
+ if( oneWayOnly ){
138
+ db_prepare(&s,
139
+ "SELECT cid, 1 FROM plink WHERE pid=:pid "
140
+ );
141
+ }else if( directOnly ){
133142
db_prepare(&s,
134143
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
135144
"UNION ALL "
136145
"SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
137146
);
@@ -193,17 +202,19 @@
193202
int iFrom;
194203
int iTo;
195204
PathNode *p;
196205
int n;
197206
int directOnly;
207
+ int oneWay;
198208
199209
db_find_and_open_repository(0,0);
200210
directOnly = find_option("no-merge",0,0)!=0;
211
+ oneWay = find_option("one-way",0,0)!=0;
201212
if( g.argc!=4 ) usage("VERSION1 VERSION2");
202213
iFrom = name_to_rid(g.argv[2]);
203214
iTo = name_to_rid(g.argv[3]);
204
- p = path_shortest(iFrom, iTo, directOnly);
215
+ p = path_shortest(iFrom, iTo, directOnly, oneWay);
205216
if( p==0 ){
206217
fossil_fatal("no path from %s to %s", g.argv[1], g.argv[2]);
207218
}
208219
for(n=1, p=path.pStart; p; p=p->u.pTo, n++){
209220
char *z;
@@ -350,10 +361,11 @@
350361
** infrastructure.
351362
*/
352363
void find_filename_changes(
353364
int iFrom, /* Ancestor check-in */
354365
int iTo, /* Recent check-in */
366
+ int revOk, /* Ok to move backwards (child->parent) if true */
355367
int *pnChng, /* Number of name changes along the path */
356368
int **aiChng, /* Name changes */
357369
const char *zDebug /* Generate trace output if no NULL */
358370
){
359371
PathNode *p; /* For looping over path from iFrom to iTo */
@@ -366,34 +378,40 @@
366378
367379
*pnChng = 0;
368380
*aiChng = 0;
369381
if( iFrom==iTo ) return;
370382
path_reset();
371
- p = path_shortest(iFrom, iTo, 1);
383
+ p = path_shortest(iFrom, iTo, 1, revOk==0);
372384
if( p==0 ) return;
373385
path_reverse_path();
374386
db_prepare(&q1,
375
- "SELECT pfnid, fnid FROM mlink WHERE mid=:mid AND pfnid>0"
387
+ "SELECT pfnid, fnid FROM mlink"
388
+ " WHERE mid=:mid AND (pfnid>0 OR fid==0)"
389
+ " ORDER BY pfnid"
376390
);
377391
for(p=path.pStart; p; p=p->u.pTo){
378392
int fnid, pfnid;
379393
if( !p->fromIsParent && (p->u.pTo==0 || p->u.pTo->fromIsParent) ){
380394
/* Skip nodes where the parent is not on the path */
381395
continue;
382396
}
383397
db_bind_int(&q1, ":mid", p->rid);
384398
while( db_step(&q1)==SQLITE_ROW ){
385
- if( p->fromIsParent ){
386
- fnid = db_column_int(&q1, 1);
387
- pfnid = db_column_int(&q1, 0);
388
- }else{
389
- fnid = db_column_int(&q1, 0);
390
- pfnid = db_column_int(&q1, 1);
399
+ fnid = db_column_int(&q1, 1);
400
+ pfnid = db_column_int(&q1, 0);
401
+ if( pfnid==0 ){
402
+ pfnid = fnid;
403
+ fnid = 0;
404
+ }
405
+ if( !p->fromIsParent ){
406
+ int t = fnid;
407
+ fnid = pfnid;
408
+ pfnid = t;
391409
}
392410
if( zDebug ){
393
- fossil_print("%s at %d %.10z: %d[%z] -> %d[%z]\n",
394
- zDebug, p->rid,
411
+ fossil_print("%s at %d%s %.10z: %d[%z] -> %d[%z]\n",
412
+ zDebug, p->rid, p->fromIsParent ? ">" : "<",
395413
db_text(0, "SELECT uuid FROM blob WHERE rid=%d", p->rid),
396414
pfnid,
397415
db_text(0, "SELECT name FROM filename WHERE fnid=%d", pfnid),
398416
fnid,
399417
db_text(0, "SELECT name FROM filename WHERE fnid=%d", fnid));
@@ -402,28 +420,32 @@
402420
if( pChng->curName==pfnid ){
403421
pChng->newName = fnid;
404422
break;
405423
}
406424
}
407
- if( pChng==0 ){
425
+ if( pChng==0 && fnid>0 ){
408426
pChng = fossil_malloc( sizeof(*pChng) );
409427
pChng->pNext = pAll;
410428
pAll = pChng;
411429
pChng->origName = pfnid;
412430
pChng->curName = pfnid;
413431
pChng->newName = fnid;
414432
nChng++;
415433
}
416434
}
417
- for(pChng=pAll; pChng; pChng=pChng->pNext) pChng->curName = pChng->newName;
435
+ for(pChng=pAll; pChng; pChng=pChng->pNext){
436
+ pChng->curName = pChng->newName;
437
+ }
418438
db_reset(&q1);
419439
}
420440
db_finalize(&q1);
421441
if( nChng ){
422
- *pnChng = nChng;
423442
aChng = *aiChng = fossil_malloc( nChng*2*sizeof(int) );
424
- for(pChng=pAll, i=0; pChng; pChng=pChng->pNext, i+=2){
443
+ for(pChng=pAll, i=0; pChng; pChng=pChng->pNext){
444
+ if( pChng->newName==0 ) continue;
445
+ if( pChng->origName==0 ) continue;
446
+ if( pChng->newName==pChng->origName ) continue;
425447
aChng[i] = pChng->origName;
426448
aChng[i+1] = pChng->newName;
427449
if( zDebug ){
428450
fossil_print("%s summary %d[%z] -> %d[%z]\n",
429451
zDebug,
@@ -430,11 +452,13 @@
430452
aChng[i],
431453
db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i]),
432454
aChng[i+1],
433455
db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i+1]));
434456
}
457
+ i += 2;
435458
}
459
+ *pnChng = i/2;
436460
while( pAll ){
437461
pChng = pAll;
438462
pAll = pAll->pNext;
439463
fossil_free(pChng);
440464
}
@@ -442,27 +466,31 @@
442466
}
443467
444468
/*
445469
** COMMAND: test-name-changes
446470
**
447
-** Usage: %fossil test-name-changes VERSION1 VERSION2
471
+** Usage: %fossil test-name-changes [--debug] VERSION1 VERSION2
448472
**
449473
** Show all filename changes that occur going from VERSION1 to VERSION2
450474
*/
451475
void test_name_change(void){
452476
int iFrom;
453477
int iTo;
454478
int *aChng;
455479
int nChng;
456480
int i;
481
+ const char *zDebug = 0;
482
+ int revOk = 0;
457483
458484
db_find_and_open_repository(0,0);
485
+ zDebug = find_option("debug",0,0)!=0 ? "debug" : 0;
486
+ revOk = find_option("bidirectional",0,0)!=0;
459487
if( g.argc<4 ) usage("VERSION1 VERSION2");
460488
while( g.argc>=4 ){
461489
iFrom = name_to_rid(g.argv[2]);
462490
iTo = name_to_rid(g.argv[3]);
463
- find_filename_changes(iFrom, iTo, &nChng, &aChng, 0);
491
+ find_filename_changes(iFrom, iTo, revOk, &nChng, &aChng, zDebug);
464492
fossil_print("------ Changes for (%d) %s -> (%d) %s\n",
465493
iFrom, g.argv[2], iTo, g.argv[3]);
466494
for(i=0; i<nChng; i++){
467495
char *zFrom, *zTo;
468496
469497
--- src/path.c
+++ src/path.c
@@ -116,11 +116,16 @@
116 ** Elements of the path can be traversed by following the PathNode.u.pTo
117 ** pointer chain.
118 **
119 ** Return NULL if no path is found.
120 */
121 PathNode *path_shortest(int iFrom, int iTo, int directOnly){
 
 
 
 
 
122 Stmt s;
123 PathNode *pPrev;
124 PathNode *p;
125
126 path_reset();
@@ -127,11 +132,15 @@
127 path.pStart = path_new_node(iFrom, 0, 0);
128 if( iTo==iFrom ){
129 path.pEnd = path.pStart;
130 return path.pStart;
131 }
132 if( directOnly ){
 
 
 
 
133 db_prepare(&s,
134 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
135 "UNION ALL "
136 "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
137 );
@@ -193,17 +202,19 @@
193 int iFrom;
194 int iTo;
195 PathNode *p;
196 int n;
197 int directOnly;
 
198
199 db_find_and_open_repository(0,0);
200 directOnly = find_option("no-merge",0,0)!=0;
 
201 if( g.argc!=4 ) usage("VERSION1 VERSION2");
202 iFrom = name_to_rid(g.argv[2]);
203 iTo = name_to_rid(g.argv[3]);
204 p = path_shortest(iFrom, iTo, directOnly);
205 if( p==0 ){
206 fossil_fatal("no path from %s to %s", g.argv[1], g.argv[2]);
207 }
208 for(n=1, p=path.pStart; p; p=p->u.pTo, n++){
209 char *z;
@@ -350,10 +361,11 @@
350 ** infrastructure.
351 */
352 void find_filename_changes(
353 int iFrom, /* Ancestor check-in */
354 int iTo, /* Recent check-in */
 
355 int *pnChng, /* Number of name changes along the path */
356 int **aiChng, /* Name changes */
357 const char *zDebug /* Generate trace output if no NULL */
358 ){
359 PathNode *p; /* For looping over path from iFrom to iTo */
@@ -366,34 +378,40 @@
366
367 *pnChng = 0;
368 *aiChng = 0;
369 if( iFrom==iTo ) return;
370 path_reset();
371 p = path_shortest(iFrom, iTo, 1);
372 if( p==0 ) return;
373 path_reverse_path();
374 db_prepare(&q1,
375 "SELECT pfnid, fnid FROM mlink WHERE mid=:mid AND pfnid>0"
 
 
376 );
377 for(p=path.pStart; p; p=p->u.pTo){
378 int fnid, pfnid;
379 if( !p->fromIsParent && (p->u.pTo==0 || p->u.pTo->fromIsParent) ){
380 /* Skip nodes where the parent is not on the path */
381 continue;
382 }
383 db_bind_int(&q1, ":mid", p->rid);
384 while( db_step(&q1)==SQLITE_ROW ){
385 if( p->fromIsParent ){
386 fnid = db_column_int(&q1, 1);
387 pfnid = db_column_int(&q1, 0);
388 }else{
389 fnid = db_column_int(&q1, 0);
390 pfnid = db_column_int(&q1, 1);
 
 
 
 
391 }
392 if( zDebug ){
393 fossil_print("%s at %d %.10z: %d[%z] -> %d[%z]\n",
394 zDebug, p->rid,
395 db_text(0, "SELECT uuid FROM blob WHERE rid=%d", p->rid),
396 pfnid,
397 db_text(0, "SELECT name FROM filename WHERE fnid=%d", pfnid),
398 fnid,
399 db_text(0, "SELECT name FROM filename WHERE fnid=%d", fnid));
@@ -402,28 +420,32 @@
402 if( pChng->curName==pfnid ){
403 pChng->newName = fnid;
404 break;
405 }
406 }
407 if( pChng==0 ){
408 pChng = fossil_malloc( sizeof(*pChng) );
409 pChng->pNext = pAll;
410 pAll = pChng;
411 pChng->origName = pfnid;
412 pChng->curName = pfnid;
413 pChng->newName = fnid;
414 nChng++;
415 }
416 }
417 for(pChng=pAll; pChng; pChng=pChng->pNext) pChng->curName = pChng->newName;
 
 
418 db_reset(&q1);
419 }
420 db_finalize(&q1);
421 if( nChng ){
422 *pnChng = nChng;
423 aChng = *aiChng = fossil_malloc( nChng*2*sizeof(int) );
424 for(pChng=pAll, i=0; pChng; pChng=pChng->pNext, i+=2){
 
 
 
425 aChng[i] = pChng->origName;
426 aChng[i+1] = pChng->newName;
427 if( zDebug ){
428 fossil_print("%s summary %d[%z] -> %d[%z]\n",
429 zDebug,
@@ -430,11 +452,13 @@
430 aChng[i],
431 db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i]),
432 aChng[i+1],
433 db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i+1]));
434 }
 
435 }
 
436 while( pAll ){
437 pChng = pAll;
438 pAll = pAll->pNext;
439 fossil_free(pChng);
440 }
@@ -442,27 +466,31 @@
442 }
443
444 /*
445 ** COMMAND: test-name-changes
446 **
447 ** Usage: %fossil test-name-changes VERSION1 VERSION2
448 **
449 ** Show all filename changes that occur going from VERSION1 to VERSION2
450 */
451 void test_name_change(void){
452 int iFrom;
453 int iTo;
454 int *aChng;
455 int nChng;
456 int i;
 
 
457
458 db_find_and_open_repository(0,0);
 
 
459 if( g.argc<4 ) usage("VERSION1 VERSION2");
460 while( g.argc>=4 ){
461 iFrom = name_to_rid(g.argv[2]);
462 iTo = name_to_rid(g.argv[3]);
463 find_filename_changes(iFrom, iTo, &nChng, &aChng, 0);
464 fossil_print("------ Changes for (%d) %s -> (%d) %s\n",
465 iFrom, g.argv[2], iTo, g.argv[3]);
466 for(i=0; i<nChng; i++){
467 char *zFrom, *zTo;
468
469
--- src/path.c
+++ src/path.c
@@ -116,11 +116,16 @@
116 ** Elements of the path can be traversed by following the PathNode.u.pTo
117 ** pointer chain.
118 **
119 ** Return NULL if no path is found.
120 */
121 PathNode *path_shortest(
122 int iFrom, /* Path starts here */
123 int iTo, /* Path ends here */
124 int directOnly, /* No merge links if true */
125 int oneWayOnly /* Parent->child only if true */
126 ){
127 Stmt s;
128 PathNode *pPrev;
129 PathNode *p;
130
131 path_reset();
@@ -127,11 +132,15 @@
132 path.pStart = path_new_node(iFrom, 0, 0);
133 if( iTo==iFrom ){
134 path.pEnd = path.pStart;
135 return path.pStart;
136 }
137 if( oneWayOnly ){
138 db_prepare(&s,
139 "SELECT cid, 1 FROM plink WHERE pid=:pid "
140 );
141 }else if( directOnly ){
142 db_prepare(&s,
143 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
144 "UNION ALL "
145 "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
146 );
@@ -193,17 +202,19 @@
202 int iFrom;
203 int iTo;
204 PathNode *p;
205 int n;
206 int directOnly;
207 int oneWay;
208
209 db_find_and_open_repository(0,0);
210 directOnly = find_option("no-merge",0,0)!=0;
211 oneWay = find_option("one-way",0,0)!=0;
212 if( g.argc!=4 ) usage("VERSION1 VERSION2");
213 iFrom = name_to_rid(g.argv[2]);
214 iTo = name_to_rid(g.argv[3]);
215 p = path_shortest(iFrom, iTo, directOnly, oneWay);
216 if( p==0 ){
217 fossil_fatal("no path from %s to %s", g.argv[1], g.argv[2]);
218 }
219 for(n=1, p=path.pStart; p; p=p->u.pTo, n++){
220 char *z;
@@ -350,10 +361,11 @@
361 ** infrastructure.
362 */
363 void find_filename_changes(
364 int iFrom, /* Ancestor check-in */
365 int iTo, /* Recent check-in */
366 int revOk, /* Ok to move backwards (child->parent) if true */
367 int *pnChng, /* Number of name changes along the path */
368 int **aiChng, /* Name changes */
369 const char *zDebug /* Generate trace output if no NULL */
370 ){
371 PathNode *p; /* For looping over path from iFrom to iTo */
@@ -366,34 +378,40 @@
378
379 *pnChng = 0;
380 *aiChng = 0;
381 if( iFrom==iTo ) return;
382 path_reset();
383 p = path_shortest(iFrom, iTo, 1, revOk==0);
384 if( p==0 ) return;
385 path_reverse_path();
386 db_prepare(&q1,
387 "SELECT pfnid, fnid FROM mlink"
388 " WHERE mid=:mid AND (pfnid>0 OR fid==0)"
389 " ORDER BY pfnid"
390 );
391 for(p=path.pStart; p; p=p->u.pTo){
392 int fnid, pfnid;
393 if( !p->fromIsParent && (p->u.pTo==0 || p->u.pTo->fromIsParent) ){
394 /* Skip nodes where the parent is not on the path */
395 continue;
396 }
397 db_bind_int(&q1, ":mid", p->rid);
398 while( db_step(&q1)==SQLITE_ROW ){
399 fnid = db_column_int(&q1, 1);
400 pfnid = db_column_int(&q1, 0);
401 if( pfnid==0 ){
402 pfnid = fnid;
403 fnid = 0;
404 }
405 if( !p->fromIsParent ){
406 int t = fnid;
407 fnid = pfnid;
408 pfnid = t;
409 }
410 if( zDebug ){
411 fossil_print("%s at %d%s %.10z: %d[%z] -> %d[%z]\n",
412 zDebug, p->rid, p->fromIsParent ? ">" : "<",
413 db_text(0, "SELECT uuid FROM blob WHERE rid=%d", p->rid),
414 pfnid,
415 db_text(0, "SELECT name FROM filename WHERE fnid=%d", pfnid),
416 fnid,
417 db_text(0, "SELECT name FROM filename WHERE fnid=%d", fnid));
@@ -402,28 +420,32 @@
420 if( pChng->curName==pfnid ){
421 pChng->newName = fnid;
422 break;
423 }
424 }
425 if( pChng==0 && fnid>0 ){
426 pChng = fossil_malloc( sizeof(*pChng) );
427 pChng->pNext = pAll;
428 pAll = pChng;
429 pChng->origName = pfnid;
430 pChng->curName = pfnid;
431 pChng->newName = fnid;
432 nChng++;
433 }
434 }
435 for(pChng=pAll; pChng; pChng=pChng->pNext){
436 pChng->curName = pChng->newName;
437 }
438 db_reset(&q1);
439 }
440 db_finalize(&q1);
441 if( nChng ){
 
442 aChng = *aiChng = fossil_malloc( nChng*2*sizeof(int) );
443 for(pChng=pAll, i=0; pChng; pChng=pChng->pNext){
444 if( pChng->newName==0 ) continue;
445 if( pChng->origName==0 ) continue;
446 if( pChng->newName==pChng->origName ) continue;
447 aChng[i] = pChng->origName;
448 aChng[i+1] = pChng->newName;
449 if( zDebug ){
450 fossil_print("%s summary %d[%z] -> %d[%z]\n",
451 zDebug,
@@ -430,11 +452,13 @@
452 aChng[i],
453 db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i]),
454 aChng[i+1],
455 db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i+1]));
456 }
457 i += 2;
458 }
459 *pnChng = i/2;
460 while( pAll ){
461 pChng = pAll;
462 pAll = pAll->pNext;
463 fossil_free(pChng);
464 }
@@ -442,27 +466,31 @@
466 }
467
468 /*
469 ** COMMAND: test-name-changes
470 **
471 ** Usage: %fossil test-name-changes [--debug] VERSION1 VERSION2
472 **
473 ** Show all filename changes that occur going from VERSION1 to VERSION2
474 */
475 void test_name_change(void){
476 int iFrom;
477 int iTo;
478 int *aChng;
479 int nChng;
480 int i;
481 const char *zDebug = 0;
482 int revOk = 0;
483
484 db_find_and_open_repository(0,0);
485 zDebug = find_option("debug",0,0)!=0 ? "debug" : 0;
486 revOk = find_option("bidirectional",0,0)!=0;
487 if( g.argc<4 ) usage("VERSION1 VERSION2");
488 while( g.argc>=4 ){
489 iFrom = name_to_rid(g.argv[2]);
490 iTo = name_to_rid(g.argv[3]);
491 find_filename_changes(iFrom, iTo, revOk, &nChng, &aChng, zDebug);
492 fossil_print("------ Changes for (%d) %s -> (%d) %s\n",
493 iFrom, g.argv[2], iTo, g.argv[3]);
494 for(i=0; i<nChng; i++){
495 char *zFrom, *zTo;
496
497
+13 -5
--- src/timeline.c
+++ src/timeline.c
@@ -402,36 +402,44 @@
402402
db_prepare(&fchngQuery,
403403
"SELECT (pid==0) AS isnew,"
404404
" (fid==0) AS isdel,"
405405
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
406406
" (SELECT uuid FROM blob WHERE rid=fid),"
407
- " (SELECT uuid FROM blob WHERE rid=pid)"
407
+ " (SELECT uuid FROM blob WHERE rid=pid),"
408
+ " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
408409
" FROM mlink"
409
- " WHERE mid=:mid AND pid!=fid"
410
+ " WHERE mid=:mid AND (pid!=fid OR pfnid>0)"
410411
" ORDER BY 3 /*sort*/"
411412
);
412413
fchngQueryInit = 1;
413414
}
414415
db_bind_int(&fchngQuery, ":mid", rid);
415416
while( db_step(&fchngQuery)==SQLITE_ROW ){
416417
const char *zFilename = db_column_text(&fchngQuery, 2);
417418
int isNew = db_column_int(&fchngQuery, 0);
418419
int isDel = db_column_int(&fchngQuery, 1);
420
+ const char *zOldName = db_column_text(&fchngQuery, 5);
419421
const char *zOld = db_column_text(&fchngQuery, 4);
420422
const char *zNew = db_column_text(&fchngQuery, 3);
421423
if( !inUl ){
422424
@ <ul class="filelist">
423425
inUl = 1;
424426
}
425427
if( isNew ){
426428
@ <li> %h(zFilename) (new file) &nbsp;
427429
@ <a href="%s(g.zTop)/artifact/%S(zNew)" target="diffwindow">[view]
428
- @ </a></li>
429430
}else if( isDel ){
430431
@ <li> %h(zFilename) (deleted)</li>
432
+ }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
433
+ @ <li> %h(zOldName) &rarr; %h(zFilename)
434
+ @ <a href="%s(g.zTop)/artifact/%S(zNew)" target="diffwindow">[view]
431435
}else{
432
- @ <li> %h(zFilename) &nbsp;
436
+ if( zOldName!=0 ){
437
+ @ <li> %h(zOldName) &rarr; %h(zFilename)
438
+ }else{
439
+ @ <li> %h(zFilename) &nbsp;
440
+ }
433441
@ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)"
434442
@ target="diffwindow">[diff]</a></li>
435443
}
436444
}
437445
db_reset(&fchngQuery);
@@ -928,11 +936,11 @@
928936
PathNode *p = 0;
929937
const char *zFrom = 0;
930938
const char *zTo = 0;
931939
932940
if( from_rid && to_rid ){
933
- p = path_shortest(from_rid, to_rid, noMerge);
941
+ p = path_shortest(from_rid, to_rid, noMerge, 0);
934942
zFrom = P("from");
935943
zTo = P("to");
936944
}else{
937945
if( path_common_ancestor(me_rid, you_rid) ){
938946
p = path_first();
939947
--- src/timeline.c
+++ src/timeline.c
@@ -402,36 +402,44 @@
402 db_prepare(&fchngQuery,
403 "SELECT (pid==0) AS isnew,"
404 " (fid==0) AS isdel,"
405 " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
406 " (SELECT uuid FROM blob WHERE rid=fid),"
407 " (SELECT uuid FROM blob WHERE rid=pid)"
 
408 " FROM mlink"
409 " WHERE mid=:mid AND pid!=fid"
410 " ORDER BY 3 /*sort*/"
411 );
412 fchngQueryInit = 1;
413 }
414 db_bind_int(&fchngQuery, ":mid", rid);
415 while( db_step(&fchngQuery)==SQLITE_ROW ){
416 const char *zFilename = db_column_text(&fchngQuery, 2);
417 int isNew = db_column_int(&fchngQuery, 0);
418 int isDel = db_column_int(&fchngQuery, 1);
 
419 const char *zOld = db_column_text(&fchngQuery, 4);
420 const char *zNew = db_column_text(&fchngQuery, 3);
421 if( !inUl ){
422 @ <ul class="filelist">
423 inUl = 1;
424 }
425 if( isNew ){
426 @ <li> %h(zFilename) (new file) &nbsp;
427 @ <a href="%s(g.zTop)/artifact/%S(zNew)" target="diffwindow">[view]
428 @ </a></li>
429 }else if( isDel ){
430 @ <li> %h(zFilename) (deleted)</li>
 
 
 
431 }else{
432 @ <li> %h(zFilename) &nbsp;
 
 
 
 
433 @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)"
434 @ target="diffwindow">[diff]</a></li>
435 }
436 }
437 db_reset(&fchngQuery);
@@ -928,11 +936,11 @@
928 PathNode *p = 0;
929 const char *zFrom = 0;
930 const char *zTo = 0;
931
932 if( from_rid && to_rid ){
933 p = path_shortest(from_rid, to_rid, noMerge);
934 zFrom = P("from");
935 zTo = P("to");
936 }else{
937 if( path_common_ancestor(me_rid, you_rid) ){
938 p = path_first();
939
--- src/timeline.c
+++ src/timeline.c
@@ -402,36 +402,44 @@
402 db_prepare(&fchngQuery,
403 "SELECT (pid==0) AS isnew,"
404 " (fid==0) AS isdel,"
405 " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
406 " (SELECT uuid FROM blob WHERE rid=fid),"
407 " (SELECT uuid FROM blob WHERE rid=pid),"
408 " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
409 " FROM mlink"
410 " WHERE mid=:mid AND (pid!=fid OR pfnid>0)"
411 " ORDER BY 3 /*sort*/"
412 );
413 fchngQueryInit = 1;
414 }
415 db_bind_int(&fchngQuery, ":mid", rid);
416 while( db_step(&fchngQuery)==SQLITE_ROW ){
417 const char *zFilename = db_column_text(&fchngQuery, 2);
418 int isNew = db_column_int(&fchngQuery, 0);
419 int isDel = db_column_int(&fchngQuery, 1);
420 const char *zOldName = db_column_text(&fchngQuery, 5);
421 const char *zOld = db_column_text(&fchngQuery, 4);
422 const char *zNew = db_column_text(&fchngQuery, 3);
423 if( !inUl ){
424 @ <ul class="filelist">
425 inUl = 1;
426 }
427 if( isNew ){
428 @ <li> %h(zFilename) (new file) &nbsp;
429 @ <a href="%s(g.zTop)/artifact/%S(zNew)" target="diffwindow">[view]
 
430 }else if( isDel ){
431 @ <li> %h(zFilename) (deleted)</li>
432 }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
433 @ <li> %h(zOldName) &rarr; %h(zFilename)
434 @ <a href="%s(g.zTop)/artifact/%S(zNew)" target="diffwindow">[view]
435 }else{
436 if( zOldName!=0 ){
437 @ <li> %h(zOldName) &rarr; %h(zFilename)
438 }else{
439 @ <li> %h(zFilename) &nbsp;
440 }
441 @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)"
442 @ target="diffwindow">[diff]</a></li>
443 }
444 }
445 db_reset(&fchngQuery);
@@ -928,11 +936,11 @@
936 PathNode *p = 0;
937 const char *zFrom = 0;
938 const char *zTo = 0;
939
940 if( from_rid && to_rid ){
941 p = path_shortest(from_rid, to_rid, noMerge, 0);
942 zFrom = P("from");
943 zTo = P("to");
944 }else{
945 if( path_common_ancestor(me_rid, you_rid) ){
946 p = path_first();
947
+1 -1
--- src/update.c
+++ src/update.c
@@ -223,11 +223,11 @@
223223
);
224224
225225
/* Compute file name changes on V->T. Record name changes in files that
226226
** have changed locally.
227227
*/
228
- find_filename_changes(vid, tid, &nChng, &aChng, debugFlag ? "V->T": 0);
228
+ find_filename_changes(vid, tid, 1, &nChng, &aChng, debugFlag ? "V->T": 0);
229229
if( nChng ){
230230
for(i=0; i<nChng; i++){
231231
db_multi_exec(
232232
"UPDATE fv"
233233
" SET fnt=(SELECT name FROM filename WHERE fnid=%d)"
234234
--- src/update.c
+++ src/update.c
@@ -223,11 +223,11 @@
223 );
224
225 /* Compute file name changes on V->T. Record name changes in files that
226 ** have changed locally.
227 */
228 find_filename_changes(vid, tid, &nChng, &aChng, debugFlag ? "V->T": 0);
229 if( nChng ){
230 for(i=0; i<nChng; i++){
231 db_multi_exec(
232 "UPDATE fv"
233 " SET fnt=(SELECT name FROM filename WHERE fnid=%d)"
234
--- src/update.c
+++ src/update.c
@@ -223,11 +223,11 @@
223 );
224
225 /* Compute file name changes on V->T. Record name changes in files that
226 ** have changed locally.
227 */
228 find_filename_changes(vid, tid, 1, &nChng, &aChng, debugFlag ? "V->T": 0);
229 if( nChng ){
230 for(i=0; i<nChng; i++){
231 db_multi_exec(
232 "UPDATE fv"
233 " SET fnt=(SELECT name FROM filename WHERE fnid=%d)"
234
--- test/release-checklist.wiki
+++ test/release-checklist.wiki
@@ -13,10 +13,16 @@
1313
<li><p>
1414
Click on each of the links in in the
1515
[./graph-test-1.wiki] document and verify that all graphs are
1616
rendered correctly.
1717
18
+<li><p>
19
+Verify correct name-change tracking behavior (no net changes) for:
20
+<blockquote><b>
21
+fossil test-name-changes --debug b120bc8b262ac 374920b20944b
22
+</b></blockquote>
23
+
1824
<li><p>
1925
Compile for all of the following platforms:
2026
<ol type="a">
2127
<li> Linux x86
2228
<li> Linux x86_64
2329
--- test/release-checklist.wiki
+++ test/release-checklist.wiki
@@ -13,10 +13,16 @@
13 <li><p>
14 Click on each of the links in in the
15 [./graph-test-1.wiki] document and verify that all graphs are
16 rendered correctly.
17
 
 
 
 
 
 
18 <li><p>
19 Compile for all of the following platforms:
20 <ol type="a">
21 <li> Linux x86
22 <li> Linux x86_64
23
--- test/release-checklist.wiki
+++ test/release-checklist.wiki
@@ -13,10 +13,16 @@
13 <li><p>
14 Click on each of the links in in the
15 [./graph-test-1.wiki] document and verify that all graphs are
16 rendered correctly.
17
18 <li><p>
19 Verify correct name-change tracking behavior (no net changes) for:
20 <blockquote><b>
21 fossil test-name-changes --debug b120bc8b262ac 374920b20944b
22 </b></blockquote>
23
24 <li><p>
25 Compile for all of the following platforms:
26 <ol type="a">
27 <li> Linux x86
28 <li> Linux x86_64
29

Keyboard Shortcuts

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