v0.7.5 - Miroir depot git et detection fichiers non suivis

Changements :
- Detection des fichiers non suivis (untracked) dans chaque depot
- Affichage "X fichier(s) en trop" dans le statut
- Popup de confirmation listant les fichiers avant suppression (git clean -fd)
- Suppression auto des fichiers en trop via "Tout mettre a jour"
- Verification du depot distant via git ls-remote avant de proposer le clone
- Affichage "Depot introuvable" si l'URL pointe vers un repo inexistant

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 10:34:40 +01:00
parent db57cfacaf
commit 55663e3a19
5 changed files with 94 additions and 16 deletions

65
gui.go
View File

@@ -46,6 +46,12 @@ func (it *RepoItem) statusText() string {
}
msg += fmt.Sprintf("%d modif. locale(s)", r.LocalChanges)
}
if r.UntrackedFiles > 0 {
if msg != "" {
msg += ", "
}
msg += fmt.Sprintf("%d fichier(s) en trop", r.UntrackedFiles)
}
if msg == "" {
return "À jour"
}
@@ -195,7 +201,7 @@ func (m *RepoModel) hasUpdates() bool {
defer m.mu.RUnlock()
for _, it := range m.items {
r := it.result
if !r.Pending && r.Error == "" && !r.Offline && (r.NewCommits > 0 || r.LocalChanges > 0 || r.NeedsClone) {
if !r.Pending && r.Error == "" && !r.Offline && (r.NewCommits > 0 || r.LocalChanges > 0 || r.UntrackedFiles > 0 || r.NeedsClone) {
return true
}
}
@@ -430,6 +436,12 @@ func logLineForResult(r RepoResult) string {
}
msg += fmt.Sprintf("%d modif. locale(s)", r.LocalChanges)
}
if r.UntrackedFiles > 0 {
if msg != "" {
msg += ", "
}
msg += fmt.Sprintf("%d fichier(s) en trop", r.UntrackedFiles)
}
return msg
}
@@ -450,6 +462,41 @@ func (a *App) recheckOne(idx int) {
}()
}
// proposeClean affiche un popup listant les fichiers non suivis et propose de les supprimer.
func (a *App) proposeClean(idx int, res RepoResult) {
// Construire la liste des fichiers (max 30 affichés)
list := ""
for i, f := range res.UntrackedList {
if i >= 30 {
list += fmt.Sprintf("\n... et %d autre(s)", len(res.UntrackedList)-30)
break
}
list += "\n - " + f
}
msg := fmt.Sprintf("[%s] %d fichier(s) non suivi(s) détecté(s) :%s\n\nSupprimer ces fichiers ?",
res.Name, res.UntrackedFiles, list)
ans := walk.MsgBox(a.mw, "Fichiers en trop", msg, walk.MsgBoxYesNo|walk.MsgBoxIconQuestion)
if ans == walk.DlgCmdYes {
a.appendLog(fmt.Sprintf("[%s] Nettoyage de %d fichier(s)...", res.Name, res.UntrackedFiles))
go func() {
err := doClean(res)
a.mw.Synchronize(func() {
if err != nil {
a.appendLog(fmt.Sprintf("[%s] Erreur nettoyage: %v", res.Name, err))
logError(fmt.Sprintf("[%s] clean: %v", res.Name, err))
} else {
a.appendLog(fmt.Sprintf("[%s] %d fichier(s) supprimé(s)", res.Name, res.UntrackedFiles))
logInfo(fmt.Sprintf("[%s] %d fichier(s) supprimé(s)", res.Name, res.UntrackedFiles))
}
a.recheckOne(idx)
})
}()
} else {
a.recheckOne(idx)
}
}
// ── Progression ───────────────────────────────────────────────────────────────
// makeProgressCB crée un callback de progression pour la ligne row du tableau.
@@ -487,7 +534,7 @@ func (a *App) onSelectionChanged() {
if res.NeedsClone {
a.btnAction.SetText("Cloner")
a.btnAction.SetEnabled(true)
} else if res.NewCommits > 0 || res.LocalChanges > 0 {
} else if res.NewCommits > 0 || res.LocalChanges > 0 || res.UntrackedFiles > 0 {
a.btnAction.SetText("Mettre à jour")
a.btnAction.SetEnabled(true)
} else {
@@ -503,6 +550,12 @@ func (a *App) doAction() {
}
cfg := a.reposConfig[idx]
// Si uniquement des fichiers en trop, proposer directement le nettoyage
if res.UntrackedFiles > 0 && res.NewCommits == 0 && res.LocalChanges == 0 && !res.NeedsClone {
a.proposeClean(idx, res)
return
}
a.btnAction.SetEnabled(false)
a.appendLog(fmt.Sprintf("[%s] Mise à jour en cours...", res.Name))
@@ -529,6 +582,11 @@ func (a *App) doAction() {
a.appendLog(fmt.Sprintf("[%s] Mise à jour OK", res.Name))
logInfo(fmt.Sprintf("[%s] Mise à jour OK", res.Name))
}
// Si des fichiers en trop après la mise à jour, proposer le nettoyage
if res.UntrackedFiles > 0 {
a.proposeClean(idx, res)
return
}
// Re-vérifier uniquement ce dépôt, pas tous
a.recheckOne(idx)
})
@@ -559,6 +617,9 @@ func (a *App) updateAll() {
if err == nil && res.NewCommits > 0 {
err = doPullWithProgress(res, cb)
}
if err == nil && res.UntrackedFiles > 0 {
err = doClean(res)
}
}
a.mw.Synchronize(func() {
if err != nil {