@@ -148,24 +148,61 @@ func (p *Publisher) Push(ctx context.Context, updates []Update, expected map[str |
| 148 |
} |
148 |
} |
| 149 |
defer pack.Close() |
149 |
defer pack.Close() |
| 150 |
packAdded := false |
150 |
packAdded := false |
|
|
151 |
refsPublishedEarly := false |
| 151 |
if pack != nil && pack.Objects > 0 { |
152 |
if pack != nil && pack.Objects > 0 { |
| 152 |
packName := "pack-" + pack.Hash + ".pack" |
153 |
looseObjects, useLoose, looseErr := p.Git.SmallLooseObjects(ctx, pack, 64, 8<<20) |
| 153 |
indexName := "pack-" + pack.Hash + ".idx" |
154 |
if looseErr != nil { |
| 154 |
p.progress("uploading %s (%d objects)", packName, pack.Objects) |
155 |
return Result{}, looseErr |
| 155 |
if err := runParallel( |
156 |
} |
| 156 |
func() error { |
157 |
if useLoose { |
| 157 |
return p.Store.PutFile(ctx, path.Join("objects/pack", packName), pack.PackPath, "application/x-git-packed-objects", immutableCache) |
158 |
p.progress("uploading %d loose objects", len(looseObjects)) |
| 158 |
}, |
159 |
publications := make([]func() error, 0, len(looseObjects)+len(resolved)) |
| 159 |
func() error { |
160 |
for _, object := range looseObjects { |
| 160 |
return p.Store.PutFile(ctx, path.Join("objects/pack", indexName), pack.IndexPath, "application/x-git-packed-objects-toc", immutableCache) |
161 |
object := object |
| 161 |
}, |
162 |
publications = append(publications, func() error { |
| 162 |
); err != nil { |
163 |
return p.Store.PutFile(ctx, path.Join("objects", object.OID[:2], object.OID[2:]), object.Path, "application/x-git-loose-object", immutableCache) |
| 163 |
return Result{}, err |
164 |
}) |
|
|
165 |
} |
|
|
166 |
// Individual ref files are not used for discovery by dumb HTTP; publish |
|
|
167 |
// them in the same wave and update the authoritative info/refs only |
|
|
168 |
// after every object and ref write has succeeded. |
|
|
169 |
for _, update := range resolved { |
|
|
170 |
update := update |
|
|
171 |
if update.OldOID == update.NewOID { |
|
|
172 |
continue |
|
|
173 |
} |
|
|
174 |
if update.NewOID == "" { |
|
|
175 |
publications = append(publications, func() error { return p.Store.Delete(ctx, update.Dst) }) |
|
|
176 |
} else { |
|
|
177 |
publications = append(publications, func() error { |
|
|
178 |
return p.Store.Put(ctx, update.Dst, []byte(update.NewOID+"\n"), "text/plain; charset=utf-8", mutableCache) |
|
|
179 |
}) |
|
|
180 |
} |
|
|
181 |
} |
|
|
182 |
if err := runParallel(publications...); err != nil { |
|
|
183 |
return Result{}, err |
|
|
184 |
} |
|
|
185 |
refsPublishedEarly = true |
|
|
186 |
result.PackObjects = pack.Objects |
|
|
187 |
} else { |
|
|
188 |
packName := "pack-" + pack.Hash + ".pack" |
|
|
189 |
indexName := "pack-" + pack.Hash + ".idx" |
|
|
190 |
p.progress("uploading %s (%d objects)", packName, pack.Objects) |
|
|
191 |
if err := runParallel( |
|
|
192 |
func() error { |
|
|
193 |
return p.Store.PutFile(ctx, path.Join("objects/pack", packName), pack.PackPath, "application/x-git-packed-objects", immutableCache) |
|
|
194 |
}, |
|
|
195 |
func() error { |
|
|
196 |
return p.Store.PutFile(ctx, path.Join("objects/pack", indexName), pack.IndexPath, "application/x-git-packed-objects-toc", immutableCache) |
|
|
197 |
}, |
|
|
198 |
); err != nil { |
|
|
199 |
return Result{}, err |
|
|
200 |
} |
|
|
201 |
metadata.Packs[packName] = struct{}{} |
|
|
202 |
result.PackName = packName |
|
|
203 |
result.PackObjects = pack.Objects |
|
|
204 |
packAdded = true |
| 164 |
} |
205 |
} |
| 165 |
metadata.Packs[packName] = struct{}{} |
|
|
| 166 |
result.PackName = packName |
|
|
| 167 |
result.PackObjects = pack.Objects |
|
|
| 168 |
packAdded = true |
|
|
| 169 |
} |
206 |
} |
| 170 |
|
207 |
|
| 171 |
previousHead := metadata.Head |
208 |
previousHead := metadata.Head |
@@ -203,18 +240,20 @@ func (p *Publisher) Push(ctx context.Context, updates []Update, expected map[str |
| 203 |
return p.Store.Put(ctx, "objects/info/packs", renderPackList(metadata.Packs), "text/plain; charset=utf-8", mutableCache) |
240 |
return p.Store.Put(ctx, "objects/info/packs", renderPackList(metadata.Packs), "text/plain; charset=utf-8", mutableCache) |
| 204 |
}) |
241 |
}) |
| 205 |
} |
242 |
} |
| 206 |
for _, update := range resolved { |
243 |
if !refsPublishedEarly { |
| 207 |
update := update |
244 |
for _, update := range resolved { |
| 208 |
if update.OldOID == update.NewOID { |
245 |
update := update |
| 209 |
continue |
246 |
if update.OldOID == update.NewOID { |
| 210 |
} |
247 |
continue |
| 211 |
if update.NewOID == "" { |
248 |
} |
| 212 |
publications = append(publications, func() error { return p.Store.Delete(ctx, update.Dst) }) |
249 |
if update.NewOID == "" { |
| 213 |
continue |
250 |
publications = append(publications, func() error { return p.Store.Delete(ctx, update.Dst) }) |
|
|
251 |
continue |
|
|
252 |
} |
|
|
253 |
publications = append(publications, func() error { |
|
|
254 |
return p.Store.Put(ctx, update.Dst, []byte(update.NewOID+"\n"), "text/plain; charset=utf-8", mutableCache) |
|
|
255 |
}) |
| 214 |
} |
256 |
} |
| 215 |
publications = append(publications, func() error { |
|
|
| 216 |
return p.Store.Put(ctx, update.Dst, []byte(update.NewOID+"\n"), "text/plain; charset=utf-8", mutableCache) |
|
|
| 217 |
}) |
|
|
| 218 |
} |
257 |
} |
| 219 |
if metadata.Head != "" && metadata.Head != previousHead { |
258 |
if metadata.Head != "" && metadata.Head != previousHead { |
| 220 |
publications = append(publications, func() error { |
259 |
publications = append(publications, func() error { |