Fossil SCM

Add logic to process "parent" tags. Add the "reparent" command used to create an appropriate parent tag to cause a check-in to be reparented.

drh 2016-05-17 00:46 UTC trunk
Commit 5c5a364d5e106d9c38b37d1b9b25ed023e829498
3 files changed +1 -2 +125 -45 +57
+1 -2
--- src/import.c
+++ src/import.c
@@ -925,12 +925,11 @@
925925
/*
926926
** Returns the UUID for the RID, or NULL if not found.
927927
** The returned string is allocated via db_text() and must be
928928
** free()d by the caller.
929929
*/
930
-char * rid_to_uuid(int rid)
931
-{
930
+char *rid_to_uuid(int rid){
932931
return db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
933932
}
934933
935934
#define SVN_UNKNOWN 0
936935
#define SVN_TRUNK 1
937936
--- src/import.c
+++ src/import.c
@@ -925,12 +925,11 @@
925 /*
926 ** Returns the UUID for the RID, or NULL if not found.
927 ** The returned string is allocated via db_text() and must be
928 ** free()d by the caller.
929 */
930 char * rid_to_uuid(int rid)
931 {
932 return db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
933 }
934
935 #define SVN_UNKNOWN 0
936 #define SVN_TRUNK 1
937
--- src/import.c
+++ src/import.c
@@ -925,12 +925,11 @@
925 /*
926 ** Returns the UUID for the RID, or NULL if not found.
927 ** The returned string is allocated via db_text() and must be
928 ** free()d by the caller.
929 */
930 char *rid_to_uuid(int rid){
 
931 return db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
932 }
933
934 #define SVN_UNKNOWN 0
935 #define SVN_TRUNK 1
936
+125 -45
--- src/manifest.c
+++ src/manifest.c
@@ -1542,14 +1542,126 @@
15421542
if( pmid<=0 ) continue;
15431543
add_mlink(pmid, 0, mid, pChild, 0);
15441544
}
15451545
}
15461546
}
1547
+
1548
+/*
1549
+** For a check-in with RID "rid" that has nParent parent check-ins given
1550
+** by the UUIDs in azParent[], create all appropriate plink and mlink table
1551
+** entries.
1552
+**
1553
+** The primary parent is the first UUID on the azParent[] list.
1554
+**
1555
+** Return the RID of the primary parent.
1556
+*/
1557
+static int manifest_add_checkin_linkages(
1558
+ int rid, /* The RID of the check-in */
1559
+ Manifest *p, /* Manifest for this check-in */
1560
+ int nParent, /* Number of parents for this check-in */
1561
+ char **azParent /* UUIDs for each parent */
1562
+){
1563
+ int i;
1564
+ int parentid = 0;
1565
+ char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
1566
+ Stmt q;
1567
+
1568
+ if( p->zBaseline ){
1569
+ sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
1570
+ uuid_to_rid(p->zBaseline,1));
1571
+ }else{
1572
+ sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
1573
+ }
1574
+ for(i=0; i<nParent; i++){
1575
+ int pid = uuid_to_rid(azParent[i], 1);
1576
+ db_multi_exec(
1577
+ "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1578
+ "VALUES(%d, %d, %d, %.17g, %s)",
1579
+ pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1580
+ if( i==0 ) parentid = pid;
1581
+ }
1582
+ add_mlink(parentid, 0, rid, p, 1);
1583
+ if( nParent>1 ){
1584
+ /* Change MLINK.PID from 0 to -1 for files that are added by merge. */
1585
+ db_multi_exec(
1586
+ "UPDATE mlink SET pid=-1"
1587
+ " WHERE mid=%d"
1588
+ " AND pid=0"
1589
+ " AND fnid IN "
1590
+ " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
1591
+ " HAVING count(*)<%d)",
1592
+ rid, rid, nParent
1593
+ );
1594
+ }
1595
+ db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid);
1596
+ while( db_step(&q)==SQLITE_ROW ){
1597
+ int cid = db_column_int(&q, 0);
1598
+ int isprim = db_column_int(&q, 1);
1599
+ add_mlink(rid, p, cid, 0, isprim);
1600
+ }
1601
+ db_finalize(&q);
1602
+ if( nParent==0 ){
1603
+ /* For root files (files without parents) add mlink entries
1604
+ ** showing all content as new. */
1605
+ int isPublic = !content_is_private(rid);
1606
+ for(i=0; i<p->nFile; i++){
1607
+ add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1608
+ isPublic, 1, manifest_file_mperm(&p->aFile[i]));
1609
+ }
1610
+ }
1611
+ return parentid;
1612
+}
1613
+
1614
+/*
1615
+** There exists a "parent" tag against checkin rid that has value zValue.
1616
+** If value is well-formed (meaning that is is a list of UUIDs), then use
1617
+** zValue to reparent check-in rid.
1618
+*/
1619
+void manifest_reparent_checkin(int rid, const char *zValue){
1620
+ int nParent;
1621
+ char *zCopy = 0;
1622
+ char **azParent = 0;
1623
+ Manifest *p = 0;
1624
+ int i;
1625
+ int n = (int)strlen(zValue);
1626
+ nParent = (n+1)/(UUID_SIZE+1);
1627
+ if( nParent*(UUID_SIZE+1) - 1 !=n ) return;
1628
+ if( nParent<1 ) return;
1629
+ zCopy = fossil_strdup(zValue);
1630
+ azParent = fossil_malloc( sizeof(azParent[0])*nParent );
1631
+ for(i=0; i<nParent; i++){
1632
+ azParent[i] = &zCopy[i*(UUID_SIZE+1)];
1633
+ if( i<nParent-1 && azParent[i][UUID_SIZE]!=' ' ) break;
1634
+ azParent[i][UUID_SIZE] = 0;
1635
+ if( !validate16(azParent[i],UUID_SIZE) ) break;
1636
+ }
1637
+ if( i==nParent
1638
+ && !db_exists("SELECT 1 FROM plink WHERE cid=%d AND pid=%d",
1639
+ rid, uuid_to_rid(azParent[0],0))
1640
+ ){
1641
+ p = manifest_get(rid, CFTYPE_MANIFEST, 0);
1642
+ }
1643
+ if( p!=0 ){
1644
+ db_multi_exec(
1645
+ "DELETE FROM plink WHERE cid=%d;"
1646
+ "DELETE FROM mlink WHERE mid=%d;",
1647
+ rid, rid
1648
+ );
1649
+ manifest_add_checkin_linkages(rid,p,nParent,azParent);
1650
+ }
1651
+ manifest_destroy(p);
1652
+ fossil_free(azParent);
1653
+ fossil_free(zCopy);
1654
+}
15471655
15481656
/*
15491657
** Setup to do multiple manifest_crosslink() calls.
1550
-** This is only required if processing ticket changes.
1658
+**
1659
+** This routine creates TEMP tables for holding information for
1660
+** processing that must be deferred until all artifacts have been
1661
+** seen at least once. The deferred processing is accomplished
1662
+** by the call to manifest_crosslink_end().
15511663
*/
15521664
void manifest_crosslink_begin(void){
15531665
assert( manifest_crosslink_busy==0 );
15541666
manifest_crosslink_busy = 1;
15551667
db_begin_transaction();
@@ -1592,10 +1704,21 @@
15921704
rc = xfer_run_common_script();
15931705
if( rc==TH_OK ){
15941706
zScript = xfer_ticket_code();
15951707
}
15961708
}
1709
+ db_prepare(&q,
1710
+ "SELECT rid, value FROM tagxref"
1711
+ " WHERE tagid=%d AND tagtype=1",
1712
+ TAG_PARENT
1713
+ );
1714
+ while( db_step(&q)==SQLITE_ROW ){
1715
+ int rid = db_column_int(&q,0);
1716
+ const char *zValue = db_column_text(&q,1);
1717
+ manifest_reparent_checkin(rid, zValue);
1718
+ }
1719
+ db_finalize(&q);
15971720
db_prepare(&q, "SELECT uuid FROM pending_tkt");
15981721
while( db_step(&q)==SQLITE_ROW ){
15991722
const char *zUuid = db_column_text(&q, 0);
16001723
ticket_rebuild_entry(zUuid);
16011724
if( permitHooks && rc==TH_OK ){
@@ -1837,54 +1960,11 @@
18371960
zScript = xfer_commit_code();
18381961
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
18391962
}
18401963
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
18411964
char *zCom;
1842
- char zBaseId[30];
1843
- if( p->zBaseline ){
1844
- sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
1845
- uuid_to_rid(p->zBaseline,1));
1846
- }else{
1847
- sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
1848
- }
1849
- for(i=0; i<p->nParent; i++){
1850
- int pid = uuid_to_rid(p->azParent[i], 1);
1851
- db_multi_exec(
1852
- "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1853
- "VALUES(%d, %d, %d, %.17g, %s)",
1854
- pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1855
- if( i==0 ) parentid = pid;
1856
- }
1857
- add_mlink(parentid, 0, rid, p, 1);
1858
- if( p->nParent>1 ){
1859
- /* Change MLINK.PID from 0 to -1 for files that are added by merge. */
1860
- db_multi_exec(
1861
- "UPDATE mlink SET pid=-1"
1862
- " WHERE mid=%d"
1863
- " AND pid=0"
1864
- " AND fnid IN "
1865
- " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
1866
- " HAVING count(*)<%d)",
1867
- rid, rid, p->nParent
1868
- );
1869
- }
1870
- db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid);
1871
- while( db_step(&q)==SQLITE_ROW ){
1872
- int cid = db_column_int(&q, 0);
1873
- int isprim = db_column_int(&q, 1);
1874
- add_mlink(rid, p, cid, 0, isprim);
1875
- }
1876
- db_finalize(&q);
1877
- if( p->nParent==0 ){
1878
- /* For root files (files without parents) add mlink entries
1879
- ** showing all content as new. */
1880
- int isPublic = !content_is_private(rid);
1881
- for(i=0; i<p->nFile; i++){
1882
- add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1883
- isPublic, 1, manifest_file_mperm(&p->aFile[i]));
1884
- }
1885
- }
1965
+ parentid = manifest_add_checkin_linkages(rid,p,p->nParent,p->azParent);
18861966
search_doc_touch('c', rid, 0);
18871967
db_multi_exec(
18881968
"REPLACE INTO event(type,mtime,objid,user,comment,"
18891969
"bgcolor,euser,ecomment,omtime)"
18901970
"VALUES('ci',"
18911971
--- src/manifest.c
+++ src/manifest.c
@@ -1542,14 +1542,126 @@
1542 if( pmid<=0 ) continue;
1543 add_mlink(pmid, 0, mid, pChild, 0);
1544 }
1545 }
1546 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1547
1548 /*
1549 ** Setup to do multiple manifest_crosslink() calls.
1550 ** This is only required if processing ticket changes.
 
 
 
 
1551 */
1552 void manifest_crosslink_begin(void){
1553 assert( manifest_crosslink_busy==0 );
1554 manifest_crosslink_busy = 1;
1555 db_begin_transaction();
@@ -1592,10 +1704,21 @@
1592 rc = xfer_run_common_script();
1593 if( rc==TH_OK ){
1594 zScript = xfer_ticket_code();
1595 }
1596 }
 
 
 
 
 
 
 
 
 
 
 
1597 db_prepare(&q, "SELECT uuid FROM pending_tkt");
1598 while( db_step(&q)==SQLITE_ROW ){
1599 const char *zUuid = db_column_text(&q, 0);
1600 ticket_rebuild_entry(zUuid);
1601 if( permitHooks && rc==TH_OK ){
@@ -1837,54 +1960,11 @@
1837 zScript = xfer_commit_code();
1838 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1839 }
1840 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
1841 char *zCom;
1842 char zBaseId[30];
1843 if( p->zBaseline ){
1844 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
1845 uuid_to_rid(p->zBaseline,1));
1846 }else{
1847 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
1848 }
1849 for(i=0; i<p->nParent; i++){
1850 int pid = uuid_to_rid(p->azParent[i], 1);
1851 db_multi_exec(
1852 "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1853 "VALUES(%d, %d, %d, %.17g, %s)",
1854 pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1855 if( i==0 ) parentid = pid;
1856 }
1857 add_mlink(parentid, 0, rid, p, 1);
1858 if( p->nParent>1 ){
1859 /* Change MLINK.PID from 0 to -1 for files that are added by merge. */
1860 db_multi_exec(
1861 "UPDATE mlink SET pid=-1"
1862 " WHERE mid=%d"
1863 " AND pid=0"
1864 " AND fnid IN "
1865 " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
1866 " HAVING count(*)<%d)",
1867 rid, rid, p->nParent
1868 );
1869 }
1870 db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid);
1871 while( db_step(&q)==SQLITE_ROW ){
1872 int cid = db_column_int(&q, 0);
1873 int isprim = db_column_int(&q, 1);
1874 add_mlink(rid, p, cid, 0, isprim);
1875 }
1876 db_finalize(&q);
1877 if( p->nParent==0 ){
1878 /* For root files (files without parents) add mlink entries
1879 ** showing all content as new. */
1880 int isPublic = !content_is_private(rid);
1881 for(i=0; i<p->nFile; i++){
1882 add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1883 isPublic, 1, manifest_file_mperm(&p->aFile[i]));
1884 }
1885 }
1886 search_doc_touch('c', rid, 0);
1887 db_multi_exec(
1888 "REPLACE INTO event(type,mtime,objid,user,comment,"
1889 "bgcolor,euser,ecomment,omtime)"
1890 "VALUES('ci',"
1891
--- src/manifest.c
+++ src/manifest.c
@@ -1542,14 +1542,126 @@
1542 if( pmid<=0 ) continue;
1543 add_mlink(pmid, 0, mid, pChild, 0);
1544 }
1545 }
1546 }
1547
1548 /*
1549 ** For a check-in with RID "rid" that has nParent parent check-ins given
1550 ** by the UUIDs in azParent[], create all appropriate plink and mlink table
1551 ** entries.
1552 **
1553 ** The primary parent is the first UUID on the azParent[] list.
1554 **
1555 ** Return the RID of the primary parent.
1556 */
1557 static int manifest_add_checkin_linkages(
1558 int rid, /* The RID of the check-in */
1559 Manifest *p, /* Manifest for this check-in */
1560 int nParent, /* Number of parents for this check-in */
1561 char **azParent /* UUIDs for each parent */
1562 ){
1563 int i;
1564 int parentid = 0;
1565 char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
1566 Stmt q;
1567
1568 if( p->zBaseline ){
1569 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d",
1570 uuid_to_rid(p->zBaseline,1));
1571 }else{
1572 sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL");
1573 }
1574 for(i=0; i<nParent; i++){
1575 int pid = uuid_to_rid(azParent[i], 1);
1576 db_multi_exec(
1577 "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
1578 "VALUES(%d, %d, %d, %.17g, %s)",
1579 pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
1580 if( i==0 ) parentid = pid;
1581 }
1582 add_mlink(parentid, 0, rid, p, 1);
1583 if( nParent>1 ){
1584 /* Change MLINK.PID from 0 to -1 for files that are added by merge. */
1585 db_multi_exec(
1586 "UPDATE mlink SET pid=-1"
1587 " WHERE mid=%d"
1588 " AND pid=0"
1589 " AND fnid IN "
1590 " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
1591 " HAVING count(*)<%d)",
1592 rid, rid, nParent
1593 );
1594 }
1595 db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid);
1596 while( db_step(&q)==SQLITE_ROW ){
1597 int cid = db_column_int(&q, 0);
1598 int isprim = db_column_int(&q, 1);
1599 add_mlink(rid, p, cid, 0, isprim);
1600 }
1601 db_finalize(&q);
1602 if( nParent==0 ){
1603 /* For root files (files without parents) add mlink entries
1604 ** showing all content as new. */
1605 int isPublic = !content_is_private(rid);
1606 for(i=0; i<p->nFile; i++){
1607 add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0,
1608 isPublic, 1, manifest_file_mperm(&p->aFile[i]));
1609 }
1610 }
1611 return parentid;
1612 }
1613
1614 /*
1615 ** There exists a "parent" tag against checkin rid that has value zValue.
1616 ** If value is well-formed (meaning that is is a list of UUIDs), then use
1617 ** zValue to reparent check-in rid.
1618 */
1619 void manifest_reparent_checkin(int rid, const char *zValue){
1620 int nParent;
1621 char *zCopy = 0;
1622 char **azParent = 0;
1623 Manifest *p = 0;
1624 int i;
1625 int n = (int)strlen(zValue);
1626 nParent = (n+1)/(UUID_SIZE+1);
1627 if( nParent*(UUID_SIZE+1) - 1 !=n ) return;
1628 if( nParent<1 ) return;
1629 zCopy = fossil_strdup(zValue);
1630 azParent = fossil_malloc( sizeof(azParent[0])*nParent );
1631 for(i=0; i<nParent; i++){
1632 azParent[i] = &zCopy[i*(UUID_SIZE+1)];
1633 if( i<nParent-1 && azParent[i][UUID_SIZE]!=' ' ) break;
1634 azParent[i][UUID_SIZE] = 0;
1635 if( !validate16(azParent[i],UUID_SIZE) ) break;
1636 }
1637 if( i==nParent
1638 && !db_exists("SELECT 1 FROM plink WHERE cid=%d AND pid=%d",
1639 rid, uuid_to_rid(azParent[0],0))
1640 ){
1641 p = manifest_get(rid, CFTYPE_MANIFEST, 0);
1642 }
1643 if( p!=0 ){
1644 db_multi_exec(
1645 "DELETE FROM plink WHERE cid=%d;"
1646 "DELETE FROM mlink WHERE mid=%d;",
1647 rid, rid
1648 );
1649 manifest_add_checkin_linkages(rid,p,nParent,azParent);
1650 }
1651 manifest_destroy(p);
1652 fossil_free(azParent);
1653 fossil_free(zCopy);
1654 }
1655
1656 /*
1657 ** Setup to do multiple manifest_crosslink() calls.
1658 **
1659 ** This routine creates TEMP tables for holding information for
1660 ** processing that must be deferred until all artifacts have been
1661 ** seen at least once. The deferred processing is accomplished
1662 ** by the call to manifest_crosslink_end().
1663 */
1664 void manifest_crosslink_begin(void){
1665 assert( manifest_crosslink_busy==0 );
1666 manifest_crosslink_busy = 1;
1667 db_begin_transaction();
@@ -1592,10 +1704,21 @@
1704 rc = xfer_run_common_script();
1705 if( rc==TH_OK ){
1706 zScript = xfer_ticket_code();
1707 }
1708 }
1709 db_prepare(&q,
1710 "SELECT rid, value FROM tagxref"
1711 " WHERE tagid=%d AND tagtype=1",
1712 TAG_PARENT
1713 );
1714 while( db_step(&q)==SQLITE_ROW ){
1715 int rid = db_column_int(&q,0);
1716 const char *zValue = db_column_text(&q,1);
1717 manifest_reparent_checkin(rid, zValue);
1718 }
1719 db_finalize(&q);
1720 db_prepare(&q, "SELECT uuid FROM pending_tkt");
1721 while( db_step(&q)==SQLITE_ROW ){
1722 const char *zUuid = db_column_text(&q, 0);
1723 ticket_rebuild_entry(zUuid);
1724 if( permitHooks && rc==TH_OK ){
@@ -1837,54 +1960,11 @@
1960 zScript = xfer_commit_code();
1961 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1962 }
1963 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
1964 char *zCom;
1965 parentid = manifest_add_checkin_linkages(rid,p,p->nParent,p->azParent);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1966 search_doc_touch('c', rid, 0);
1967 db_multi_exec(
1968 "REPLACE INTO event(type,mtime,objid,user,comment,"
1969 "bgcolor,euser,ecomment,omtime)"
1970 "VALUES('ci',"
1971
+57
--- src/tag.c
+++ src/tag.c
@@ -148,10 +148,13 @@
148148
return id;
149149
}
150150
151151
/*
152152
** Insert a tag into the database.
153
+**
154
+** Also translate zTag into a tagid and return the tagid. (In other words
155
+** if zTag is "bgcolor" then return TAG_BGCOLOR.)
153156
*/
154157
int tag_insert(
155158
const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
156159
int tagtype, /* 0:cancel 1:singleton 2:propagated */
157160
const char *zValue, /* Value if the tag is really a property */
@@ -228,10 +231,13 @@
228231
" SET mtime=julianday(%Q),"
229232
" omtime=coalesce(omtime,mtime)"
230233
" WHERE objid=%d",
231234
zValue, rid);
232235
}
236
+ if( tagid==TAG_PARENT && tagtype==1 ){
237
+ manifest_reparent_checkin(rid, zValue);
238
+ }
233239
if( tagtype==1 ) tagtype = 0;
234240
tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
235241
return tagid;
236242
}
237243
@@ -546,10 +552,61 @@
546552
return;
547553
548554
tag_cmd_usage:
549555
usage("add|cancel|find|list ...");
550556
}
557
+
558
+/*
559
+** COMMAND: reparent*
560
+**
561
+** Usage: %fossil reparent [OPTIONS] CHECK-IN PARENT ....
562
+**
563
+** Create a "parent" tag that causes CHECK-IN to be interpreted as a
564
+** child of PARENT. If multiple PARENTs are listed, then the first is
565
+** the primary parent and others are merge ancestors.
566
+**
567
+** This is an experts-only command. It is used to patch of a repository
568
+** that has been damaged by a shun or that has been pieced together from
569
+** two or more separate repositories. You should never need to reparent
570
+** during normal operations.
571
+**
572
+** Reparenting is accomplished by adding a parent tag. So to undo the
573
+** reparenting operation, simply delete the tag.
574
+**
575
+** --test Make database entries but do not add the tag artifact.
576
+** So the reparent operation will be undone by the next
577
+** "fossil rebuild" command.
578
+*/
579
+void reparent_cmd(void){
580
+ int bTest = find_option("test","",0)!=0;
581
+ int rid;
582
+ int i;
583
+ Blob value;
584
+ char *zUuid;
585
+
586
+ db_find_and_open_repository(0, 0);
587
+ verify_all_options();
588
+ if( g.argc<4 ){
589
+ usage("reparent [OPTIONS] PARENT ...");
590
+ }
591
+ rid = name_to_typed_rid(g.argv[2], "ci");
592
+ blob_init(&value, 0, 0);
593
+ for(i=3; i<g.argc; i++){
594
+ int pid = name_to_typed_rid(g.argv[i], "ci");
595
+ if( i>3 ) blob_append(&value, " ", 1);
596
+ zUuid = rid_to_uuid(pid);
597
+ blob_append(&value, zUuid, UUID_SIZE);
598
+ fossil_free(zUuid);
599
+ }
600
+ if( bTest ){
601
+ tag_insert("parent", 1, blob_str(&value), -1, 0.0, rid);
602
+ }else{
603
+ zUuid = rid_to_uuid(rid);
604
+ tag_add_artifact("+","parent",zUuid,blob_str(&value),1,0,0);
605
+ }
606
+}
607
+
551608
552609
/*
553610
** WEBPAGE: taglist
554611
**
555612
** List all non-propagating symbolic tags.
556613
--- src/tag.c
+++ src/tag.c
@@ -148,10 +148,13 @@
148 return id;
149 }
150
151 /*
152 ** Insert a tag into the database.
 
 
 
153 */
154 int tag_insert(
155 const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
156 int tagtype, /* 0:cancel 1:singleton 2:propagated */
157 const char *zValue, /* Value if the tag is really a property */
@@ -228,10 +231,13 @@
228 " SET mtime=julianday(%Q),"
229 " omtime=coalesce(omtime,mtime)"
230 " WHERE objid=%d",
231 zValue, rid);
232 }
 
 
 
233 if( tagtype==1 ) tagtype = 0;
234 tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
235 return tagid;
236 }
237
@@ -546,10 +552,61 @@
546 return;
547
548 tag_cmd_usage:
549 usage("add|cancel|find|list ...");
550 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
552 /*
553 ** WEBPAGE: taglist
554 **
555 ** List all non-propagating symbolic tags.
556
--- src/tag.c
+++ src/tag.c
@@ -148,10 +148,13 @@
148 return id;
149 }
150
151 /*
152 ** Insert a tag into the database.
153 **
154 ** Also translate zTag into a tagid and return the tagid. (In other words
155 ** if zTag is "bgcolor" then return TAG_BGCOLOR.)
156 */
157 int tag_insert(
158 const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
159 int tagtype, /* 0:cancel 1:singleton 2:propagated */
160 const char *zValue, /* Value if the tag is really a property */
@@ -228,10 +231,13 @@
231 " SET mtime=julianday(%Q),"
232 " omtime=coalesce(omtime,mtime)"
233 " WHERE objid=%d",
234 zValue, rid);
235 }
236 if( tagid==TAG_PARENT && tagtype==1 ){
237 manifest_reparent_checkin(rid, zValue);
238 }
239 if( tagtype==1 ) tagtype = 0;
240 tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
241 return tagid;
242 }
243
@@ -546,10 +552,61 @@
552 return;
553
554 tag_cmd_usage:
555 usage("add|cancel|find|list ...");
556 }
557
558 /*
559 ** COMMAND: reparent*
560 **
561 ** Usage: %fossil reparent [OPTIONS] CHECK-IN PARENT ....
562 **
563 ** Create a "parent" tag that causes CHECK-IN to be interpreted as a
564 ** child of PARENT. If multiple PARENTs are listed, then the first is
565 ** the primary parent and others are merge ancestors.
566 **
567 ** This is an experts-only command. It is used to patch of a repository
568 ** that has been damaged by a shun or that has been pieced together from
569 ** two or more separate repositories. You should never need to reparent
570 ** during normal operations.
571 **
572 ** Reparenting is accomplished by adding a parent tag. So to undo the
573 ** reparenting operation, simply delete the tag.
574 **
575 ** --test Make database entries but do not add the tag artifact.
576 ** So the reparent operation will be undone by the next
577 ** "fossil rebuild" command.
578 */
579 void reparent_cmd(void){
580 int bTest = find_option("test","",0)!=0;
581 int rid;
582 int i;
583 Blob value;
584 char *zUuid;
585
586 db_find_and_open_repository(0, 0);
587 verify_all_options();
588 if( g.argc<4 ){
589 usage("reparent [OPTIONS] PARENT ...");
590 }
591 rid = name_to_typed_rid(g.argv[2], "ci");
592 blob_init(&value, 0, 0);
593 for(i=3; i<g.argc; i++){
594 int pid = name_to_typed_rid(g.argv[i], "ci");
595 if( i>3 ) blob_append(&value, " ", 1);
596 zUuid = rid_to_uuid(pid);
597 blob_append(&value, zUuid, UUID_SIZE);
598 fossil_free(zUuid);
599 }
600 if( bTest ){
601 tag_insert("parent", 1, blob_str(&value), -1, 0.0, rid);
602 }else{
603 zUuid = rid_to_uuid(rid);
604 tag_add_artifact("+","parent",zUuid,blob_str(&value),1,0,0);
605 }
606 }
607
608
609 /*
610 ** WEBPAGE: taglist
611 **
612 ** List all non-propagating symbolic tags.
613

Keyboard Shortcuts

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