summaryrefslogtreecommitdiff
path: root/internal/sync/git_operations.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/sync/git_operations.go')
-rw-r--r--internal/sync/git_operations.go52
1 files changed, 42 insertions, 10 deletions
diff --git a/internal/sync/git_operations.go b/internal/sync/git_operations.go
index 62a530b..6619349 100644
--- a/internal/sync/git_operations.go
+++ b/internal/sync/git_operations.go
@@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"fmt"
+ "net/url"
"os/exec"
"regexp"
"strings"
@@ -245,23 +246,19 @@ func getAllUniqueBranches(output []byte) []string {
// createSSHBareRepository creates a bare repository on an SSH server
func createSSHBareRepository(sshHost, repoPath string) error {
- // Extract user@host and path components
- parts := strings.Split(sshHost, ":")
- if len(parts) != 2 {
- return fmt.Errorf("invalid SSH host format: %s", sshHost)
+ userHost, sshArgs, basePath, err := parseSSHLocation(sshHost)
+ if err != nil {
+ return err
}
- userHost := parts[0]
- basePath := parts[1]
-
// Full path to the repository
- fullRepoPath := fmt.Sprintf("%s/%s.git", basePath, repoPath)
+ fullRepoPath := strings.TrimRight(basePath, "/") + "/" + repoPath + ".git"
fmt.Printf("Creating bare repository at %s:%s\n", userHost, fullRepoPath)
// Create the repository directory and initialize as bare
- commands := fmt.Sprintf("mkdir -p %s && cd %s && git init --bare", fullRepoPath, fullRepoPath)
- cmd := exec.Command("ssh", userHost, commands)
+ commands := fmt.Sprintf("mkdir -p %q && cd %q && git init --bare", fullRepoPath, fullRepoPath)
+ cmd := exec.Command("ssh", append(sshArgs, commands)...)
output, err := cmd.CombinedOutput()
if err != nil {
@@ -272,6 +269,41 @@ func createSSHBareRepository(sshHost, repoPath string) error {
return nil
}
+func parseSSHLocation(sshHost string) (string, []string, string, error) {
+ if strings.HasPrefix(sshHost, "ssh://") {
+ parsed, err := url.Parse(sshHost)
+ if err != nil {
+ return "", nil, "", fmt.Errorf("invalid SSH host format: %w", err)
+ }
+
+ host := parsed.Hostname()
+ if host == "" || parsed.Path == "" {
+ return "", nil, "", fmt.Errorf("invalid SSH host format: %s", sshHost)
+ }
+
+ userHost := host
+ if parsed.User != nil && parsed.User.Username() != "" {
+ userHost = parsed.User.Username() + "@" + host
+ }
+
+ sshArgs := make([]string, 0, 3)
+ if port := parsed.Port(); port != "" {
+ sshArgs = append(sshArgs, "-p", port)
+ }
+ sshArgs = append(sshArgs, userHost)
+
+ return userHost, sshArgs, parsed.Path, nil
+ }
+
+ parts := strings.SplitN(sshHost, ":", 2)
+ if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
+ return "", nil, "", fmt.Errorf("invalid SSH host format: %s", sshHost)
+ }
+
+ userHost := parts[0]
+ return userHost, []string{userHost}, parts[1], nil
+}
+
// pushBranchWithBackupSupport pushes a branch to a remote, creating SSH repos if needed
func pushBranchWithBackupSupport(repoPath, remoteName, branch string, remoteHasBranch bool, org *config.Organization) error {
cmd := gitCommand(repoPath, "push", remoteName, branch, "--tags")