dernière version

This commit is contained in:
2025-08-15 08:19:27 +02:00
parent 98724cd42f
commit df5f970aa0
2 changed files with 172 additions and 16 deletions

View File

@@ -87,6 +87,17 @@ CompilerEndIf
#GOutCopy = 402
#GOutClose = 403
; --- Bouton "Restaurer fichier…" dans la fenêtre principale ---
#GRestoreFile = 36
; --- Fenêtre de restauration dun fichier vers un commit ---
#WRestore = 500
#GRestList = 501
#GRestOK = 502
#GRestCancel = 503
#GRestInfo = 504
; ====== Structures ======
Structure GitCall
args.s
@@ -135,6 +146,8 @@ Declare.i UpdateGuide(repoDir$, List rows.FileRow(), branch$, remote$)
Declare.s GetLocalConfig(repoDir$, key$)
Declare.i IsGitRepo(dir$)
Declare.i UpdateGuide(repoDir$, List rows.FileRow(), branch$, remote$)
Declare.i OpenRestoreFileWindow(repoDir$, List rows.FileRow())
Declare.i RestoreFileFromCommit(repoDir$, file$, commit$)
; ====== Utils ======
Procedure.s TrimNewlines(text$)
@@ -901,6 +914,139 @@ Procedure.i IsGitRepo(dir$)
ProcedureReturn isRepo
EndProcedure
; Restaure un fichier à létat dun commit précis
; - Essaye 'git restore --source <commit> -- <file>'
; - Fallback 'git checkout <commit> -- <file>' (pour Git anciens)
Procedure.i RestoreFileFromCommit(repoDir$, file$, commit$)
Protected gc.GitCall
gc\workdir = repoDir$
gc\args = "restore --source " + Chr(34) + commit$ + Chr(34) + " -- " + Chr(34) + file$ + Chr(34)
If #EnableDebug
Debug "[RestoreFile] " + gc\args + " (wd=" + repoDir$ + ")"
EndIf
If RunGit(@gc) = 0
MessageRequester("Restaurer", "Le fichier a été restauré depuis le commit " + commit$ + ".", #PB_MessageRequester_Info)
ProcedureReturn 1
EndIf
; Fallback pour compatibilité
gc\args = "checkout " + Chr(34) + commit$ + Chr(34) + " -- " + Chr(34) + file$ + Chr(34)
If RunGit(@gc) = 0
MessageRequester("Restaurer", "Le fichier a été restauré (fallback checkout) depuis " + commit$ + ".", #PB_MessageRequester_Info)
ProcedureReturn 1
EndIf
MessageRequester("Restaurer", "Échec : " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
ProcedureReturn 0
EndProcedure
; Ouvre une fenêtre listant les commits du fichier sélectionné,
; puis restaure le fichier vers le commit choisi.
Procedure.i OpenRestoreFileWindow(repoDir$, List rows.FileRow())
Protected idx.i = GetGadgetState(#GListStatus)
If idx < 0
MessageRequester("Restaurer", "Sélectionnez d'abord un fichier dans la liste.", #PB_MessageRequester_Info)
ProcedureReturn 0
EndIf
; Récupère le chemin du fichier choisi dans rows()
Protected j.i = 0, target$
ForEach rows()
If j = idx
target$ = rows()\file
Break
EndIf
j + 1
Next
If target$ = ""
MessageRequester("Restaurer", "Aucun fichier sélectionné.", #PB_MessageRequester_Info)
ProcedureReturn 0
EndIf
; Récupère lhistorique des commits de ce fichier (50 derniers)
Protected gc.GitCall, out$, line$, n.i, i.i
gc\workdir = repoDir$
gc\args = "log --date=short --pretty=format:%h%x09%ad%x09%s -n 50 -- " + Chr(34) + target$ + Chr(34)
If RunGit(@gc) <> 0
MessageRequester("Restaurer", "Échec du log : " + #LF$ + TrimNewlines(gc\errors), #PB_MessageRequester_Error)
ProcedureReturn 0
EndIf
out$ = gc\output
If Trim(out$) = ""
MessageRequester("Restaurer", "Aucun commit trouvé pour ce fichier.", #PB_MessageRequester_Info)
ProcedureReturn 0
EndIf
; Prépare une liste parallèle des hash pour retrouver le commit sélectionné
NewList hashes.s()
; Fenêtre de sélection
If OpenWindow(#WRestore, 0, 0, 760, 420, "Restaurer : " + target$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(#GRestInfo, 10, 10, 740, 22, "Choisissez le commit vers lequel restaurer le fichier.")
ListIconGadget(#GRestList, 10, 40, 740, 330, "Commit", 100, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#GRestList, 1, "Date", 90)
AddGadgetColumn(#GRestList, 2, "Message", 520)
ButtonGadget(#GRestOK, 540, 380, 100, 28, "Restaurer")
ButtonGadget(#GRestCancel, 650, 380, 100, 28, "Annuler")
; Remplit la liste
n = CountString(out$, #LF$) + 1
For i = 1 To n
line$ = StringField(out$, i, #LF$)
If Trim(line$) <> ""
; Format: %h<TAB>%ad<TAB>%s
Protected h$ = StringField(line$, 1, #TAB$)
Protected d$ = StringField(line$, 2, #TAB$)
Protected s$ = StringField(line$, 3, #TAB$)
AddGadgetItem(#GRestList, -1, h$ + #LF$ + d$ + #LF$ + s$)
AddElement(hashes()) : hashes() = h$
EndIf
Next
; Boucle fenêtre
Repeat
Protected ev.i = WaitWindowEvent()
If ev = #PB_Event_Gadget
Select EventGadget()
Case #GRestOK
idx = GetGadgetState(#GRestList)
If idx < 0
MessageRequester("Restaurer", "Sélectionnez un commit.", #PB_MessageRequester_Warning)
Else
; Récupère le hash à lindex idx
j = 0
Protected chosen$
ForEach hashes()
If j = idx : chosen$ = hashes() : Break : EndIf
j + 1
Next
If chosen$ <> ""
If RestoreFileFromCommit(repoDir$, target$, chosen$)
CloseWindow(#WRestore)
ProcedureReturn 1
EndIf
EndIf
EndIf
Case #GRestCancel
CloseWindow(#WRestore)
ProcedureReturn 0
EndSelect
EndIf
Until ev = #PB_Event_CloseWindow
ProcedureReturn 0
EndIf
ProcedureReturn 0
EndProcedure
; Met à jour le panneau "Guide" avec un pas-à-pas adapté
; - Inclut létape “Init repo” si le dossier nest pas encore un dépôt
@@ -1005,14 +1151,15 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
Protected remote$ = "", branch$ = ""
LoadPrefs(prefsPath$, remote$, branch$)
If OpenWindow(#GWindow, 0, 0, 820, 640, "PBIDE-GitTool — Git (mode simplifié)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
; On élargit légèrement pour caser le nouveau bouton
If OpenWindow(#GWindow, 0, 0, 900, 640, "PBIDE-GitTool — Git (mode simplifié)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(#GLabelRepo, 10, 12, 60, 22, "Dépôt :")
StringGadget(#GStringRepo, 80, 10, 620, 24, repoDir$)
ButtonGadget(#GButtonBrowse, 710, 10, 100, 24, "Parcourir…")
StringGadget(#GStringRepo, 80, 10, 720, 24, repoDir$)
ButtonGadget(#GButtonBrowse, 810, 10, 80, 24, "Parcourir…")
; Liste avec cases à cocher
ListIconGadget(#GListStatus, 10, 46, 800, 300, "Statut", 180, #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#GListStatus, 1, "Fichier", 600)
ListIconGadget(#GListStatus, 10, 46, 880, 300, "Statut", 180, #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#GListStatus, 1, "Fichier", 680)
; Ligne actions liste
ButtonGadget(#GRefresh, 10, 352, 90, 26, "Rafraîchir")
@@ -1021,8 +1168,8 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
ButtonGadget(#GExclude, 310, 352, 90, 26, "Exclure")
ButtonGadget(#GIncludeAll, 410, 352, 110, 26, "Tout inclure")
ButtonGadget(#GExcludeAll, 530, 352, 110, 26, "Tout exclure")
ButtonGadget(#GDiff, 650, 352, 70, 26, "Diff…")
ButtonGadget(#GAdvanced, 730, 352, 80, 26, "Avancé…")
ButtonGadget(#GDiff, 650, 352, 80, 26, "Diff…")
ButtonGadget(#GRestoreFile,740, 352, 150, 26, "Restaurer fichier…")
; Zone commit / push
TextGadget(#GLabelMsg, 10, 388, 100, 22, "Message :")
@@ -1035,6 +1182,7 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
TextGadget(#GLabelBranch, 350, 418, 60, 22, "Branche :")
ComboBoxGadget(#GComboBranch, 410, 416, 170, 24)
ButtonGadget(#GSavePrefs, 590, 416, 220, 24, "Sauver défauts")
ButtonGadget(#GAdvanced, 820, 416, 70, 24, "Avancé…")
ButtonGadget(#GCommit, 10, 450, 120, 30, "Add + Commit")
ButtonGadget(#GPush, 140, 450, 120, 30, "Push")
@@ -1043,14 +1191,12 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
ButtonGadget(#GMakeIgnore, 580, 450, 230, 30, "Créer .gitignore (recommandé)")
; Panneau Guide
EditorGadget(#GGuide, 10, 490, 800, 140)
;DisableGadget(#GGuide, 1)
EditorGadget(#GGuide, 10, 490, 880, 140)
DisableGadget(#GGuide, 1)
; Infobulles
GadgetToolTip(#GListStatus, "Cochez pour inclure un fichier dans le prochain commit. Double-cliquez pour sélectionner, bouton 'Diff…' pour le détail.")
; Infobulles utiles
GadgetToolTip(#GRestoreFile, "Restaurer le fichier sélectionné à un commit précis (historique).")
GadgetToolTip(#GDiff, "Afficher les différences du fichier sélectionné.")
GadgetToolTip(#GConfig, "Configurer user.name et user.email localement pour ce dépôt.")
GadgetToolTip(#GMakeIgnore, "Créer un .gitignore avec des règles recommandées pour PureBasic.")
; Branches
NewList branchItems.s()
@@ -1071,6 +1217,7 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
Select ev
Case #PB_Event_Gadget
Select EventGadget()
Case #GButtonBrowse
Protected newDir$ = PathRequester("Choisir le répertoire du dépôt", repoDir$)
If newDir$ <> ""
@@ -1133,6 +1280,16 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
repoDir$ = GetGadgetText(#GStringRepo)
OpenDiffWindow(repoDir$, rows())
Case #GRestoreFile
repoDir$ = GetGadgetText(#GStringRepo)
If OpenRestoreFileWindow(repoDir$, rows())
; Après restauration : rafraîchir létat
ClearList(rows())
LoadStatusRows(repoDir$, rows())
FillStatusList(rows())
UpdateGuide(repoDir$, rows(), GetGadgetText(#GComboBranch), GetGadgetText(#GStringRemote))
EndIf
Case #GAdvanced
repoDir$ = GetGadgetText(#GStringRepo)
OpenAdvancedWindow(repoDir$)
@@ -1160,7 +1317,6 @@ Procedure.i OpenGUI(initialDir$, prefsPath$)
Case #GMakeIgnore
repoDir$ = GetGadgetText(#GStringRepo)
If MakeDefaultGitignore(repoDir$)
; optionnel : refresh
ClearList(rows())
LoadStatusRows(repoDir$, rows())
FillStatusList(rows())
@@ -1412,8 +1568,8 @@ Else
EndIf
; IDE Options = PureBasic 6.21 (Windows - x64)
; CursorPosition = 212
; FirstLine = 181
; CursorPosition = 1370
; FirstLine = 1329
; Folding = -------
; EnableXP
; DPIAware