diff --git a/GitUpdateChecker.exe b/GitUpdateChecker.exe index 644b672..dc7d6ca 100644 Binary files a/GitUpdateChecker.exe and b/GitUpdateChecker.exe differ diff --git a/config.go b/config.go index 36dd105..6b5b02d 100644 --- a/config.go +++ b/config.go @@ -38,15 +38,11 @@ func loadConfig() ([]RepoConfig, SelfUpdateConfig, error) { case strings.HasPrefix(section, "repo:"): name := strings.TrimPrefix(section, "repo:") if kv["url"] != "" && kv["path"] != "" { - branch := kv["branch"] - if branch == "" { - branch = "master" - } repos = append(repos, RepoConfig{ Name: name, URL: kv["url"], Path: kv["path"], - Branch: branch, + Branch: kv["branch"], // vide = auto-détection }) } case section == "self-update": diff --git a/git.go b/git.go index b2bef9e..45d601a 100644 --- a/git.go +++ b/git.go @@ -75,11 +75,39 @@ func checkRemoteOffline(stderr string) bool { return false } +// detectDefaultBranch détecte la branche par défaut d'un remote via ls-remote --symref HEAD. +// Retourne "main", "master", etc. ou "" si indétectable. +func detectDefaultBranch(urlOrRemote string, cwd string) string { + _, out, _ := runGit([]string{"ls-remote", "--symref", urlOrRemote, "HEAD"}, cwd, 15*time.Second) + // Format attendu : "ref: refs/heads/main\tHEAD" + for _, line := range strings.Split(out, "\n") { + if strings.HasPrefix(line, "ref: refs/heads/") { + parts := strings.Fields(line) + if len(parts) >= 2 { + return strings.TrimPrefix(parts[0], "ref: refs/heads/") + } + } + } + return "" +} + func checkRepo(cfg RepoConfig) RepoResult { res := RepoResult{Name: cfg.Name, URL: cfg.URL, Branch: cfg.Branch} local := absRepoPath(cfg.Path) res.Path = local + // Détecter la branche si non spécifiée dans la config + branch := cfg.Branch + if branch == "" { + detected := detectDefaultBranch(cfg.URL, "") + if detected != "" { + branch = detected + } else { + branch = "master" + } + res.Branch = branch + } + if _, err := os.Stat(filepath.Join(local, ".git")); os.IsNotExist(err) { // Vérifier que le dépôt distant existe avant de proposer le clone code, _, stderr := runGit([]string{"ls-remote", "--exit-code", cfg.URL}, "", 15*time.Second) @@ -110,7 +138,6 @@ func checkRepo(cfg RepoConfig) RepoResult { } // Vérification rapide du remote via ls-remote (timeout court) - branch := cfg.Branch code, lsOut, stderr := runGit([]string{"ls-remote", "origin", "refs/heads/" + branch}, local, 15*time.Second) if code != 0 { if checkRemoteOffline(stderr) { @@ -130,9 +157,27 @@ func checkRepo(cfg RepoConfig) RepoResult { remoteHash = parts[0] } } + // Si la branche n'existe pas sur le remote, détecter la branche par défaut if remoteHash == "" { - res.Error = fmt.Sprintf("Branche '%s' introuvable sur le remote", branch) - return res + detected := detectDefaultBranch("origin", local) + if detected == "" || detected == branch { + res.Error = fmt.Sprintf("Branche '%s' introuvable sur le remote", branch) + return res + } + logInfo(fmt.Sprintf("[%s] Branche '%s' introuvable, utilisation de '%s'", cfg.Name, branch, detected)) + branch = detected + res.Branch = detected + _, lsOut, _ = runGit([]string{"ls-remote", "origin", "refs/heads/" + branch}, local, 15*time.Second) + if lsOut != "" { + parts := strings.Fields(lsOut) + if len(parts) > 0 { + remoteHash = parts[0] + } + } + if remoteHash == "" { + res.Error = fmt.Sprintf("Branche '%s' introuvable sur le remote", branch) + return res + } } // Comparer les hashs @@ -355,7 +400,8 @@ func runGitWithProgress(parent context.Context, args []string, cwd string, timeo } // doCloneWithProgress clone un dépôt avec suivi de progression. -func doCloneWithProgress(ctx context.Context, cfg RepoConfig, cb ProgressCallback) error { +// branch est la branche à checkout (détectée ou configurée). +func doCloneWithProgress(ctx context.Context, cfg RepoConfig, branch string, cb ProgressCallback) error { local := absRepoPath(cfg.Path) if err := os.MkdirAll(filepath.Dir(local), 0755); err != nil { return err @@ -364,9 +410,13 @@ func doCloneWithProgress(ctx context.Context, cfg RepoConfig, cb ProgressCallbac // Si le dossier n'existe pas ou est vide, clone classique avec progression entries, _ := os.ReadDir(local) if len(entries) == 0 { + args := []string{"clone", "--progress"} + if branch != "" { + args = append(args, "-b", branch) + } + args = append(args, cfg.URL, local) code, _, stderr := runGitWithProgress( - ctx, []string{"clone", "--progress", cfg.URL, local}, - "", 2*time.Hour, cb, + ctx, args, "", 2*time.Hour, cb, ) if code != 0 { return fmt.Errorf("%s", stderr) @@ -393,7 +443,6 @@ func doCloneWithProgress(ctx context.Context, cfg RepoConfig, cb ProgressCallbac return fmt.Errorf("fetch: %s", stderr) } - branch := cfg.Branch code, _, stderr = runGit([]string{"checkout", "origin/" + branch, "-b", branch}, local, 30*time.Second) if code != 0 { code, _, stderr = runGit([]string{"checkout", branch}, local, 30*time.Second) diff --git a/gui.go b/gui.go index f3d7f65..f3aba50 100644 --- a/gui.go +++ b/gui.go @@ -617,7 +617,7 @@ func (a *App) doAction() { go func() { var err error if res.NeedsClone { - err = doCloneWithProgress(ctx, cfg, cb) + err = doCloneWithProgress(ctx, cfg, res.Branch, cb) } else { if res.LocalChanges > 0 { err = doCheckout(res) @@ -666,7 +666,7 @@ func (a *App) updateAll() { go func() { var err error if res.NeedsClone { - err = doCloneWithProgress(ctx, cfg, cb) + err = doCloneWithProgress(ctx, cfg, res.Branch, cb) } else { if res.LocalChanges > 0 { err = doCheckout(res) diff --git a/main.go b/main.go index 0a2ef93..6ad9113 100644 --- a/main.go +++ b/main.go @@ -9,7 +9,7 @@ import ( "github.com/lxn/walk" ) -const VERSION = "0.7.8" +const VERSION = "0.7.9" func exeDir() string { exe, err := os.Executable() diff --git a/version.txt b/version.txt index e7c7d3c..972ef76 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.7.8 +0.7.9