Repository navigation
How to pass the equivalent of git push -o <string>? #953
Copy link
Copy link
Open
Description
Activity
package main import ( "fmt" "os" "os/exec" "path/filepath" "strings" git "github.com/libgit2/git2go/v34" log "github.com/sirupsen/logrus" ) // createCredentialHelper creates a temporary credential helper script for git push. func createCredentialHelper(username, password string) (string, error) { // Create a temporary file for the credential helper script tmpDir := os.TempDir() scriptPath := filepath.Join(tmpDir, "git-credential-helper.sh") // Write a simple shell script to provide username and password scriptContent := fmt.Sprintf(`#!/bin/sh echo username=%s echo password=%s `, username, password) if err := os.WriteFile(scriptPath, []byte(scriptContent), 0700); err != nil { return "", fmt.Errorf("failed to write credential helper: %w", err) } return scriptPath, nil } // pushWithOptions performs a git push with the specified push options using the Git CLI. func pushWithOptions(repoPath, branchName, remoteName string, pushOptions []string, username, password string) error { // Create credential helper credHelperPath, err := createCredentialHelper(username, password) if err != nil { return err } defer os.Remove(credHelperPath) // Build the git push command args := []string{ "push", remoteName, "refs/heads/" + branchName, } for _, opt := range pushOptions { args = append(args, "-o", opt) } cmd := exec.Command("git", args...) cmd.Dir = repoPath cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_ASKPASS=%s", credHelperPath), "GIT_TERMINAL_PROMPT=0", // Disable interactive prompts ) // Capture output for logging output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("git push failed: %s\nOutput: %s", err, string(output)) } log.Infof("git push succeeded: %s", string(output)) return nil } func main() { // Initialize logging log.SetFormatter(&log.TextFormatter{}) log.SetLevel(log.InfoLevel) // Open the repository repoPath := "/home/ml/Projects/demo" repo, err := git.OpenRepository(repoPath) if err != nil { log.Fatalf("Failed to open repository: %v", err) } defer repo.Free() // Lookup or create the remote remoteName := "origin" remote, err := repo.Remotes.Lookup(remoteName) if err != nil { remote, err = repo.Remotes.Create(remoteName, repo.Path()) if err != nil { log.Fatalf("Failed to create remote: %v", err) } } defer remote.Free() // Get the current branch ref, err := repo.Head() if err != nil { log.Fatalf("Failed to get HEAD: %v", err) } defer ref.Free() branch := ref.Branch() branchName, err := branch.Name() if err != nil { log.Fatalf("Failed to get branch name: %v", err) } // Perform git push with push options pushOptions := []string{ "merge_request.create", // Add more options as needed, e.g., "merge_request.target=main" } username := "username" // Replace with actual username password := "pass" // Replace with actual password or token if err := pushWithOptions(repoPath, branchName, remoteName, pushOptions, username, password); err != nil { log.Fatalf("Push failed: %v", err) } log.Info("Push completed successfully") }
Metadata
Metadata
Assignees
Labels
No labels
On the Git CLI, I can use
git push -o <option>for examplegit push -o merge_request.createto supply string options withpushthat are then processed on the server by i.e. thepost-receivehook to perform additional actions, like create a pull request automatically after the push etc. See GitLab's options as an example.My failed attempt to recreate this with
git2go:Is there a way to do this?