Skip to content

Commit db37d8f

Browse files
committed
git push request should go to storage provider even in case of delete branch or tag
1 parent bd7c555 commit db37d8f

File tree

1 file changed

+82
-84
lines changed

1 file changed

+82
-84
lines changed

cmd/git-remote-gitopia/gitopia.go

Lines changed: 82 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,12 @@ func (h *GitopiaHandler) Push(remote *core.Remote, refsToPush []core.RefToPush)
263263
remoteURL := fmt.Sprintf("%v/%v.git", gitServerHost, h.remoteRepository.Id)
264264
lfsURL := remoteURL // Use same URL for LFS
265265

266-
var pushRefspecs []string
267-
var deleteBranches, deleteTags []string
266+
var allRefspecs []string
268267
var setBranches []gitopiatypes.MsgMultiSetBranch_Branch
269268
var setTags []gitopiatypes.MsgMultiSetTag_Tag
269+
var deleteBranches, deleteTags []string
270270
isForce := false
271-
var res []string // To return the refs that were processed
271+
var res []string
272272
var packfileCid string
273273

274274
packfileRes, err := h.storageClient.RepositoryPackfile(context.Background(), &storagetypes.QueryRepositoryPackfileRequest{
@@ -278,21 +278,24 @@ func (h *GitopiaHandler) Push(remote *core.Remote, refsToPush []core.RefToPush)
278278
packfileCid = packfileRes.Packfile.Cid
279279
}
280280

281-
// --- First Pass: Collect refspecs and deletions ---
281+
// --- First Pass: Collect all refspecs and metadata ---
282282
for _, ref := range refsToPush {
283283
if ref.Local == "" { // This is a delete operation
284+
var refNameToDelete string
284285
if strings.HasPrefix(ref.Remote, branchPrefix) {
285-
remoteBranchName := strings.TrimPrefix(ref.Remote, branchPrefix)
286-
if remoteBranchName == h.remoteRepository.DefaultBranch {
287-
return nil, fmt.Errorf("fatal: cannot delete default branch, %v", remoteBranchName)
288-
}
289-
deleteBranches = append(deleteBranches, remoteBranchName)
290-
res = append(res, ref.Remote)
286+
refNameToDelete = strings.TrimPrefix(ref.Remote, branchPrefix)
287+
deleteBranches = append(deleteBranches, refNameToDelete)
291288
} else if strings.HasPrefix(ref.Remote, tagPrefix) {
292-
remoteTagName := strings.TrimPrefix(ref.Remote, tagPrefix)
293-
deleteTags = append(deleteTags, remoteTagName)
294-
res = append(res, ref.Remote)
289+
refNameToDelete = strings.TrimPrefix(ref.Remote, tagPrefix)
290+
deleteTags = append(deleteTags, refNameToDelete)
291+
} else {
292+
continue // Skip unknown ref types
295293
}
294+
295+
// Add to the list of commands for the git server
296+
// The syntax for delete is ":<refname>"
297+
allRefspecs = append(allRefspecs, ":"+ref.Remote)
298+
res = append(res, ref.Remote)
296299
continue
297300
}
298301

@@ -303,57 +306,10 @@ func (h *GitopiaHandler) Push(remote *core.Remote, refsToPush []core.RefToPush)
303306
isForce = true
304307
}
305308

306-
pushRefspecs = append(pushRefspecs, fmt.Sprintf("%s:%s", ref.Local, ref.Remote))
307-
}
308-
309-
// --- Execute a single Git Push if there's anything to push ---
310-
if len(pushRefspecs) > 0 {
311-
if h.wallet.Type() == wallet.LEDGER {
312-
remote.Logger.Println("Please sign the git server request on your ledger device.")
313-
}
314-
315-
data := []byte("test")
316-
signature, err := h.wallet.SignData(data)
317-
if err != nil {
318-
return nil, errors.Wrap(err, "error signing data")
319-
}
320-
credential := fmt.Sprintf("%s:%s", h.wallet.Address(), signature)
321-
322-
args := []string{
323-
"-c", fmt.Sprintf("http.extraheader=Authorization: Basic %s", base64.StdEncoding.EncodeToString([]byte(credential))),
324-
"-c", "credential.helper=",
325-
"-c", "credential.helper=gitopia",
326-
"-c", fmt.Sprintf("lfs.url=%s", lfsURL),
327-
"push",
328-
"--no-verify", // Keep this to prevent the double-hook call
329-
remoteURL,
330-
}
331-
332-
// Add all refspecs to the command
333-
args = append(args, pushRefspecs...)
309+
// Add to the list of commands for the git server
310+
allRefspecs = append(allRefspecs, fmt.Sprintf("%s:%s", ref.Local, ref.Remote))
334311

335-
if isForce {
336-
args = append(args, "--force")
337-
}
338-
339-
cmd := core.GitCommand("git", args...)
340-
if err := cmd.Run(); err != nil {
341-
return nil, errors.Wrap(err, "error pushing to remote repository")
342-
}
343-
}
344-
345-
// --- Second Pass: Collect metadata for Gitopia transaction ---
346-
for _, ref := range refsToPush {
347-
if ref.Local == "" {
348-
continue // Deletes already handled
349-
}
350-
351-
localRef := ref.Local
352-
if strings.HasPrefix(localRef, "+") {
353-
localRef = strings.TrimPrefix(localRef, "+")
354-
}
355-
356-
// Update ref on gitopia
312+
// Collect metadata for the blockchain transaction
357313
if strings.HasPrefix(localRef, branchPrefix) {
358314
localCommitHash, err := remote.Repo.ResolveRevision(plumbing.Revision(localRef))
359315
if err != nil {
@@ -391,34 +347,70 @@ func (h *GitopiaHandler) Push(remote *core.Remote, refsToPush []core.RefToPush)
391347
}
392348

393349
res = append(res, ref.Remote)
394-
} else {
395-
return nil, fmt.Errorf("fatal: invalid refspec, %v", ref)
396350
}
397351
}
398352

399-
var msg []sdk.Msg
353+
// --- Execute a single Git Push if there's anything to do ---
354+
if len(allRefspecs) > 0 {
355+
if h.wallet.Type() == wallet.LEDGER {
356+
remote.Logger.Println("Please sign the git server request on your ledger device.")
357+
}
400358

401-
// Approve packfile update
402-
packfileUpdateProposalRes, err := h.storageClient.PackfileUpdateProposal(context.Background(), &storagetypes.QueryPackfileUpdateProposalRequest{
403-
RepositoryId: h.remoteRepository.Id,
404-
User: h.wallet.Address(),
405-
})
406-
if err != nil {
407-
return nil, err
408-
}
409-
msg = append(msg, storagetypes.NewMsgApproveRepositoryPackfileUpdate(h.wallet.Address(), packfileUpdateProposalRes.PackfileUpdateProposal.Id))
359+
data := []byte("test")
360+
signature, err := h.wallet.SignData(data)
361+
if err != nil {
362+
return nil, errors.Wrap(err, "error signing data")
363+
}
364+
credential := fmt.Sprintf("%s:%s", h.wallet.Address(), signature)
410365

411-
lfsObjectUpdateProposalRes, err := h.storageClient.LFSObjectUpdateProposalsByRepositoryId(context.Background(), &storagetypes.QueryLFSObjectUpdateProposalsByRepositoryIdRequest{
412-
RepositoryId: h.remoteRepository.Id,
413-
User: h.wallet.Address(),
414-
})
415-
if err != nil {
416-
return nil, err
366+
args := []string{
367+
"-c", fmt.Sprintf("http.extraheader=Authorization: Basic %s", base64.StdEncoding.EncodeToString([]byte(credential))),
368+
"-c", "credential.helper=",
369+
"-c", "credential.helper=gitopia",
370+
"-c", fmt.Sprintf("lfs.url=%s", lfsURL),
371+
"push",
372+
"--no-verify", // Keep this to prevent the double-hook call
373+
remoteURL,
374+
}
375+
376+
args = append(args, allRefspecs...)
377+
378+
if isForce {
379+
args = append(args, "--force")
380+
}
381+
382+
cmd := core.GitCommand("git", args...)
383+
if err := cmd.Run(); err != nil {
384+
return nil, errors.Wrap(err, "error pushing to remote repository")
385+
}
417386
}
418387

419-
// Approve LFS object update
420-
for _, lfsObjectUpdateProposal := range lfsObjectUpdateProposalRes.LfsObjectProposals {
421-
msg = append(msg, storagetypes.NewMsgApproveLFSObjectUpdate(h.wallet.Address(), lfsObjectUpdateProposal.Id))
388+
var msg []sdk.Msg
389+
390+
// Only try to approve packfile/LFS updates if we actually pushed something.
391+
if len(allRefspecs) > 0 {
392+
// Approve packfile update
393+
packfileUpdateProposalRes, err := h.storageClient.PackfileUpdateProposal(context.Background(), &storagetypes.QueryPackfileUpdateProposalRequest{
394+
RepositoryId: h.remoteRepository.Id,
395+
User: h.wallet.Address(),
396+
})
397+
if err != nil {
398+
return nil, err
399+
}
400+
msg = append(msg, storagetypes.NewMsgApproveRepositoryPackfileUpdate(h.wallet.Address(), packfileUpdateProposalRes.PackfileUpdateProposal.Id))
401+
402+
lfsObjectUpdateProposalRes, err := h.storageClient.LFSObjectUpdateProposalsByRepositoryId(context.Background(), &storagetypes.QueryLFSObjectUpdateProposalsByRepositoryIdRequest{
403+
RepositoryId: h.remoteRepository.Id,
404+
User: h.wallet.Address(),
405+
})
406+
if err != nil {
407+
return nil, err
408+
}
409+
410+
// Approve LFS object update
411+
for _, lfsObjectUpdateProposal := range lfsObjectUpdateProposalRes.LfsObjectProposals {
412+
msg = append(msg, storagetypes.NewMsgApproveLFSObjectUpdate(h.wallet.Address(), lfsObjectUpdateProposal.Id))
413+
}
422414
}
423415

424416
if len(setBranches) > 0 {
@@ -446,6 +438,12 @@ func (h *GitopiaHandler) Push(remote *core.Remote, refsToPush []core.RefToPush)
446438
}, deleteTags))
447439
}
448440

441+
// Make sure we don't send an empty transaction
442+
if len(msg) == 0 {
443+
remote.Logger.Println("Nothing to update on Gitopia.")
444+
return res, nil
445+
}
446+
449447
if h.wallet.Type() == wallet.LEDGER {
450448
remote.Logger.Println("Please sign the gitopia transaction on your ledger device.")
451449
}

0 commit comments

Comments
 (0)