v0.7.9 - Auto-detection branche par defaut du remote
Changements : - Detection automatique de la branche par defaut (main/master) via git ls-remote --symref HEAD - Plus besoin de specifier branch dans config.ini si le remote utilise main - Clone avec la bonne branche detectee (-b) - Fallback sur master si la detection echoue Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -38,15 +38,11 @@ func loadConfig() ([]RepoConfig, SelfUpdateConfig, error) {
|
|||||||
case strings.HasPrefix(section, "repo:"):
|
case strings.HasPrefix(section, "repo:"):
|
||||||
name := strings.TrimPrefix(section, "repo:")
|
name := strings.TrimPrefix(section, "repo:")
|
||||||
if kv["url"] != "" && kv["path"] != "" {
|
if kv["url"] != "" && kv["path"] != "" {
|
||||||
branch := kv["branch"]
|
|
||||||
if branch == "" {
|
|
||||||
branch = "master"
|
|
||||||
}
|
|
||||||
repos = append(repos, RepoConfig{
|
repos = append(repos, RepoConfig{
|
||||||
Name: name,
|
Name: name,
|
||||||
URL: kv["url"],
|
URL: kv["url"],
|
||||||
Path: kv["path"],
|
Path: kv["path"],
|
||||||
Branch: branch,
|
Branch: kv["branch"], // vide = auto-détection
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case section == "self-update":
|
case section == "self-update":
|
||||||
|
|||||||
63
git.go
63
git.go
@@ -75,11 +75,39 @@ func checkRemoteOffline(stderr string) bool {
|
|||||||
return false
|
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 {
|
func checkRepo(cfg RepoConfig) RepoResult {
|
||||||
res := RepoResult{Name: cfg.Name, URL: cfg.URL, Branch: cfg.Branch}
|
res := RepoResult{Name: cfg.Name, URL: cfg.URL, Branch: cfg.Branch}
|
||||||
local := absRepoPath(cfg.Path)
|
local := absRepoPath(cfg.Path)
|
||||||
res.Path = local
|
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) {
|
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
|
// 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)
|
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)
|
// 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)
|
code, lsOut, stderr := runGit([]string{"ls-remote", "origin", "refs/heads/" + branch}, local, 15*time.Second)
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
if checkRemoteOffline(stderr) {
|
if checkRemoteOffline(stderr) {
|
||||||
@@ -130,9 +157,27 @@ func checkRepo(cfg RepoConfig) RepoResult {
|
|||||||
remoteHash = parts[0]
|
remoteHash = parts[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Si la branche n'existe pas sur le remote, détecter la branche par défaut
|
||||||
if remoteHash == "" {
|
if remoteHash == "" {
|
||||||
res.Error = fmt.Sprintf("Branche '%s' introuvable sur le remote", branch)
|
detected := detectDefaultBranch("origin", local)
|
||||||
return res
|
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
|
// 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.
|
// 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)
|
local := absRepoPath(cfg.Path)
|
||||||
if err := os.MkdirAll(filepath.Dir(local), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(local), 0755); err != nil {
|
||||||
return err
|
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
|
// Si le dossier n'existe pas ou est vide, clone classique avec progression
|
||||||
entries, _ := os.ReadDir(local)
|
entries, _ := os.ReadDir(local)
|
||||||
if len(entries) == 0 {
|
if len(entries) == 0 {
|
||||||
|
args := []string{"clone", "--progress"}
|
||||||
|
if branch != "" {
|
||||||
|
args = append(args, "-b", branch)
|
||||||
|
}
|
||||||
|
args = append(args, cfg.URL, local)
|
||||||
code, _, stderr := runGitWithProgress(
|
code, _, stderr := runGitWithProgress(
|
||||||
ctx, []string{"clone", "--progress", cfg.URL, local},
|
ctx, args, "", 2*time.Hour, cb,
|
||||||
"", 2*time.Hour, cb,
|
|
||||||
)
|
)
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return fmt.Errorf("%s", stderr)
|
return fmt.Errorf("%s", stderr)
|
||||||
@@ -393,7 +443,6 @@ func doCloneWithProgress(ctx context.Context, cfg RepoConfig, cb ProgressCallbac
|
|||||||
return fmt.Errorf("fetch: %s", stderr)
|
return fmt.Errorf("fetch: %s", stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
branch := cfg.Branch
|
|
||||||
code, _, stderr = runGit([]string{"checkout", "origin/" + branch, "-b", branch}, local, 30*time.Second)
|
code, _, stderr = runGit([]string{"checkout", "origin/" + branch, "-b", branch}, local, 30*time.Second)
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
code, _, stderr = runGit([]string{"checkout", branch}, local, 30*time.Second)
|
code, _, stderr = runGit([]string{"checkout", branch}, local, 30*time.Second)
|
||||||
|
|||||||
4
gui.go
4
gui.go
@@ -617,7 +617,7 @@ func (a *App) doAction() {
|
|||||||
go func() {
|
go func() {
|
||||||
var err error
|
var err error
|
||||||
if res.NeedsClone {
|
if res.NeedsClone {
|
||||||
err = doCloneWithProgress(ctx, cfg, cb)
|
err = doCloneWithProgress(ctx, cfg, res.Branch, cb)
|
||||||
} else {
|
} else {
|
||||||
if res.LocalChanges > 0 {
|
if res.LocalChanges > 0 {
|
||||||
err = doCheckout(res)
|
err = doCheckout(res)
|
||||||
@@ -666,7 +666,7 @@ func (a *App) updateAll() {
|
|||||||
go func() {
|
go func() {
|
||||||
var err error
|
var err error
|
||||||
if res.NeedsClone {
|
if res.NeedsClone {
|
||||||
err = doCloneWithProgress(ctx, cfg, cb)
|
err = doCloneWithProgress(ctx, cfg, res.Branch, cb)
|
||||||
} else {
|
} else {
|
||||||
if res.LocalChanges > 0 {
|
if res.LocalChanges > 0 {
|
||||||
err = doCheckout(res)
|
err = doCheckout(res)
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/lxn/walk"
|
"github.com/lxn/walk"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "0.7.8"
|
const VERSION = "0.7.9"
|
||||||
|
|
||||||
func exeDir() string {
|
func exeDir() string {
|
||||||
exe, err := os.Executable()
|
exe, err := os.Executable()
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0.7.8
|
0.7.9
|
||||||
|
|||||||
Reference in New Issue
Block a user