Fossil SCM

fossil-scm / tools / exportbundle.sh
Blame History Raw 177 lines
1
#!/bin/sh
2
# This is a very, very prototype proof-of-concept tool to generate 'push
3
# requests'. It diffs two repositories (currently only local ones) and
4
# generates a bundle which contains all the artifacts needed to
5
# reproduce a particular artifact.
6
#
7
# The intended workflow is: user says 'I want to make a bundle to update
8
# OLD.fossil to checkin X of NEW.fossil'; the tool walks the checkin tree
9
# of NEW.fossil to figure out what checkins are necessary to reproduce X;
10
# then it removes all the checkins which are present in OLD.fossil; then
11
# it emits the bundle.
12
#
13
# To import, simple clone oldrepo (or not, if you're feeling brave);
14
# then fossil import --incremental the bundle.
15
16
set -e
17
18
oldrepo=$1
19
newrepo=$2
20
artifact=$3
21
22
ridlist=ridlist
23
24
fossil sqlite3 >$ridlist <<-EOF
25
26
ATTACH DATABASE "$newrepo" AS new;
27
ATTACH DATABASE "$oldrepo" AS old;
28
29
-- Map of parent -> child checkin artifacts. This contains our checkin graph.
30
31
CREATE TEMPORARY VIEW newcheckinmap AS
32
SELECT
33
child.uuid AS child,
34
child.rid AS rid,
35
parent.uuid AS parent,
36
parent.rid AS parentrid,
37
plink.mtime AS mtime
38
FROM
39
new.plink,
40
new.blob AS parent,
41
new.blob AS child
42
WHERE
43
(child.rid = plink.cid)
44
AND (parent.rid = plink.pid);
45
46
CREATE TEMPORARY VIEW oldcheckinmap AS
47
SELECT
48
child.uuid AS child,
49
child.rid AS rid,
50
parent.uuid AS parent,
51
parent.rid AS parentrid,
52
plink.mtime AS mtime
53
FROM
54
old.plink,
55
old.blob AS parent,
56
old.blob AS child
57
WHERE
58
(child.rid = plink.cid)
59
AND (parent.rid = plink.pid);
60
61
-- Create sets of all checkins.
62
63
CREATE TEMPORARY VIEW newcheckins AS
64
SELECT
65
blob.uuid AS id,
66
blob.rid AS rid
67
FROM
68
new.blob, new.event
69
ON
70
blob.rid = event.objid
71
WHERE
72
event.type = "ci";
73
74
CREATE TEMPORARY VIEW oldcheckins AS
75
SELECT
76
blob.uuid AS id,
77
blob.rid AS rid
78
FROM
79
old.blob, old.event
80
ON
81
blob.rid = event.objid
82
WHERE
83
event.type = "ci";
84
85
-- Now create maps of checkin->file artifacts.
86
87
CREATE TEMPORARY VIEW newfiles AS
88
SELECT
89
checkin.uuid AS checkin,
90
file.uuid AS file,
91
file.rid AS rid
92
FROM
93
new.mlink,
94
new.blob AS checkin,
95
new.blob AS file
96
WHERE
97
(checkin.rid = mlink.mid)
98
AND (file.rid = mlink.fid);
99
100
-- Walk the tree and figure out what checkins need to go into the bundle.
101
102
CREATE TEMPORARY VIEW desiredcheckins AS
103
WITH RECURSIVE
104
ancestors(id, mtime) AS (
105
SELECT child AS id, mtime
106
FROM newcheckinmap
107
WHERE child LIKE "$artifact%"
108
UNION
109
SELECT
110
newcheckinmap.parent AS id,
111
newcheckinmap.mtime
112
FROM
113
newcheckinmap, ancestors
114
ON
115
newcheckinmap.child = ancestors.id
116
WHERE
117
-- Filter to only include checkins which *aren't* in oldrepo.
118
NOT EXISTS(SELECT * FROM oldcheckinmap WHERE
119
oldcheckinmap.child = newcheckinmap.parent)
120
ORDER BY
121
newcheckinmap.mtime DESC
122
)
123
SELECT * FROM ancestors;
124
125
-- Now we know what checkins are going in the bundle, figure out which
126
-- files get included.
127
128
CREATE TEMPORARY VIEW desiredfiles AS
129
SELECT
130
newfiles.file AS id
131
FROM
132
newfiles,
133
desiredcheckins
134
WHERE
135
newfiles.checkin = desiredcheckins.id;
136
137
-- Because this prototype is using the git exporter to create bundles, and the
138
-- exporter's ability to select artifacts is based on having a list of rids to
139
-- ignore, we have to emit a list of all rids in newrepo which don't correspond
140
-- to the list above.
141
142
CREATE TEMPORARY VIEW skipcheckinrids AS
143
SELECT
144
"c" || newcheckins.rid AS msg,
145
newcheckins.rid AS rid,
146
newcheckins.id AS id
147
FROM
148
newcheckins LEFT JOIN desiredcheckins
149
ON
150
desiredcheckins.id = newcheckins.id
151
WHERE
152
desiredcheckins.id IS NULL
153
ORDER BY
154
rid ASC;
155
156
CREATE TEMPORARY VIEW skipfilerids AS
157
SELECT
158
"b" || newfiles.rid AS msg,
159
newfiles.rid AS rid,
160
newfiles.file AS id
161
FROM
162
newfiles, skipcheckinrids
163
WHERE
164
newfiles.checkin = skipcheckinrids.id
165
ORDER BY
166
rid ASC;
167
168
SELECT msg FROM skipfilerids
169
UNION
170
SELECT msg FROM skipcheckinrids;
171
172
EOF
173
174
#cat $ridlist
175
fossil export --git --import-marks $ridlist $newrepo
176
177

Keyboard Shortcuts

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