Git Setup e Sincronizzazione Avanzata: Guida Completa per Repository Management
Git è il cuore dello sviluppo moderno, ma una configurazione corretta e strategie di sincronizzazione efficaci sono essenziali per un workflow produttivo. Questa guida pratica ti accompagna dalla configurazione iniziale agli script di automazione avanzati.
Cosa imparerai in questa guida
- Configurazione Git Completa: Setup username/email globale e locale
- Autenticazione Sicura: Generazione e configurazione token per GitHub/GitLab
- Sincronizzazione Repository: Clonazione e setup su sistemi Linux
- Gestione Conflitti: Come forzare il repository remoto sovrascrivendo modifiche locali
- Automazione Avanzata: Script Bash e PowerShell per sincronizzazione automatica
- Best Practices: Strategie per repository multipli e team workflow
Indice della Guida
- Configurazione Git: Username e Email
- Autenticazione con Token su Linux
- Sincronizzazione Repository
- Gestione Conflitti e Force Sync
- Script di Automazione Bash
- Script di Automazione PowerShell
- Schedulazione e Monitoring
- Troubleshooting Comune
Configurazione Git: Username e Email
Setup Globale di Base
La configurazione globale di Git è il punto di partenza per qualsiasi workflow. Questi comandi imposteranno le informazioni utilizzate per tutti i repository sul sistema.
1
2
3
4
5
6
|
# Configurazione identità globale (obbligatorio)
git config --global user.name "Il Tuo Nome Completo"
git config --global user.email "tua.email@esempio.com"
# Verifica configurazione
git config --global --list | grep user
|
Configurazione Email
Importante: Usa l’email associata al tuo account GitHub/GitLab per collegare correttamente i commit al tuo profilo e abilitare le statistiche di contribuzione.
Configurazioni Globali Avanzate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# Editor di default per commit message
git config --global core.editor "nano" # Nano (semplice)
git config --global core.editor "vim" # Vim (avanzato)
git config --global core.editor "code --wait" # VS Code
# Comportamento line endings (importante per cross-platform)
git config --global core.autocrlf input # Linux/macOS
git config --global core.autocrlf true # Windows
# Configurazione colori per output più leggibile
git config --global color.ui auto
# Strategia di merge default
git config --global pull.rebase false # Merge (default)
git config --global pull.rebase true # Rebase automatico
# Push behavior sicuro
git config --global push.default simple
# Credenziali helper (memorizza credenziali)
git config --global credential.helper store # Store permanente
git config --global credential.helper cache # Cache temporanea (15min default)
|
Configurazione Specifica per Repository
Per progetti con requisiti diversi, puoi sovrascrivere la configurazione globale:
1
2
3
4
5
6
7
8
9
|
# Naviga nella directory del repository
cd /path/to/your/repository
# Configurazione locale (sovrascrive quella globale)
git config --local user.name "Nome Specifico Progetto"
git config --local user.email "email.progetto@azienda.com"
# Verifica configurazioni attive per il repository
git config --list --show-origin
|
Visualizzazione e Gestione Configurazioni
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# Mostra tutte le configurazioni
git config --list
# Configurazioni solo globali
git config --global --list
# Configurazioni solo locali
git config --local --list
# Verifica valore specifico
git config user.name
git config user.email
# Rimuovi configurazione specifica
git config --global --unset user.name
git config --local --unset user.email
# Modifica configurazione con editor
git config --global --edit
|
Autenticazione con Token su Linux
Generazione Token GitHub
Dal 2021, GitHub richiede l’autenticazione tramite Personal Access Token (PAT) invece delle password.
Deprecazione Password
GitHub ha deprecato l’autenticazione tramite password per le operazioni Git. È obbligatorio utilizzare Personal Access Token o chiavi SSH.
Creazione Token su GitHub
-
Accedi a GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
-
Genera nuovo token:
1
2
3
4
5
6
7
|
Name: Git Operations - [Nome Macchina/Progetto]
Expiration: 90 days (consigliato per sicurezza)
Scopes richiesti:
✓ repo (accesso completo ai repository)
✓ workflow (per GitHub Actions, se necessario)
✓ write:packages (per GitHub Packages, se necessario)
|
-
Copia il token (visibile solo una volta!)
Configurazione Token su Linux
1
2
3
4
5
6
7
8
9
10
11
|
# Metodo 1: Configurazione nel URL del remote
git remote set-url origin https://username:YOUR_TOKEN@github.com/username/repository.git
# Metodo 2: Store credential helper (più sicuro)
git config --global credential.helper store
# Al prossimo push/pull, inserisci:
# Username: il_tuo_username
# Password: YOUR_TOKEN
# Verifica configurazione remote
git remote -v
|
Generazione Token GitLab
Per GitLab il processo è simile ma leggermente diverso:
Creazione Token su GitLab
-
Accedi a GitLab → User Settings → Access Tokens
-
Crea Personal Access Token:
1
2
3
4
5
6
7
|
Name: Git Operations - [Descrizione]
Expiration date: [Data scadenza]
Scopes richiesti:
✓ read_repository
✓ write_repository
✓ api (se usi GitLab API)
|
Configurazione Token GitLab su Linux
1
2
3
4
5
|
# Configurazione URL con token
git remote set-url origin https://oauth2:YOUR_GITLAB_TOKEN@gitlab.com/username/repository.git
# Oppure con username specifico
git remote set-url origin https://username:YOUR_GITLAB_TOKEN@gitlab.com/username/repository.git
|
Gestione Sicura dei Token
1
2
3
4
5
6
7
8
9
10
11
12
|
# Memorizza credenziali in file sicuro
git config --global credential.helper 'store --file ~/.git-credentials'
# Imposta permessi sicuri al file
chmod 600 ~/.git-credentials
# Oppure usa credential helper con cache temporanea
git config --global credential.helper 'cache --timeout=3600' # 1 ora
# Per rimuovere credenziali memorizzate
git config --global --unset credential.helper
rm ~/.git-credentials
|
Sicurezza Token
- Mai hardcodare token nei file di configurazione del progetto
- Usa scadenze ragionevoli (30-90 giorni)
- Rigenera periodicamente i token
- Revoca immediatamente token compromessi
- Considera l’uso di SSH keys per ambienti di produzione
Sincronizzazione Repository
Clonazione Repository con Token
1
2
3
4
5
6
7
8
9
|
# Clonazione HTTPS con token incorporato
git clone https://username:TOKEN@github.com/username/repository.git
# Clonazione standard (richiederà credenziali)
git clone https://github.com/username/repository.git
cd repository
# Configura remote con token (dopo clonazione standard)
git remote set-url origin https://username:TOKEN@github.com/username/repository.git
|
Setup Repository Esistente
Se hai già un repository locale da sincronizzare:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# Naviga nella directory del progetto
cd /path/to/existing/project
# Inizializza repository Git
git init
# Aggiungi remote origin
git remote add origin https://username:TOKEN@github.com/username/repository.git
# Verifica connessione
git remote -v
# Primo push (se repository remoto vuoto)
git add .
git commit -m "Initial commit"
git branch -M main
git push -u origin main
|
Sincronizzazione con Repository Esistente
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# Se il repository remoto ha già contenuti
git remote add origin https://username:TOKEN@github.com/username/repository.git
# Fetch del contenuto remoto
git fetch origin
# Merge con contenuto remoto (attenzione ai conflitti)
git merge origin/main --allow-unrelated-histories
# Oppure reset per sovrascrivere completamente il locale
git reset --hard origin/main
# Push delle modifiche future
git push -u origin main
|
Gestione Conflitti e Force Sync
Ignorare Modifiche Locali e Forzare Repository Remoto
Spesso è necessario sovrascrivere completamente le modifiche locali con quelle del repository remoto:
1
2
3
4
5
6
7
8
9
10
11
12
|
# Metodo 1: Reset Hard (perdita totale delle modifiche locali)
git fetch origin
git reset --hard origin/main
git clean -fd # Rimuove file untracked
# Metodo 2: Stash e Pull
git stash push -m "Backup modifiche locali prima del force sync"
git pull --force origin main
# Metodo 3: Force Pull completo
git fetch --all
git reset --hard origin/main
|
Force Sync con Backup delle Modifiche
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# Backup delle modifiche locali prima del force sync
git stash push -m "Backup $(date '+%Y-%m-%d %H:%M:%S')"
# Force sync dal remoto
git fetch origin
git reset --hard origin/main
git clean -fd
# Verifica stash (per eventuale recupero)
git stash list
# Per ripristinare le modifiche salvate (se necessario)
# git stash pop stash@{0}
|
Sovrascrivere Branch Specifico
1
2
3
4
5
6
7
8
9
10
11
12
|
# Force sync di un branch specifico
git checkout branch-name
git fetch origin
git reset --hard origin/branch-name
# Oppure per tutti i branch
git fetch --all
for branch in $(git branch -r | grep -v '\->'); do
git checkout ${branch#origin/}
git reset --hard $branch
done
git checkout main
|
Attenzione Force Operations
Le operazioni di force sync eliminano permanentemente le modifiche locali non committate. Usa sempre backup o stash prima di eseguire queste operazioni.
Ripristino di Sicurezza
1
2
3
4
5
6
7
8
|
# Se hai fatto un errore, puoi recuperare usando reflog
git reflog # Mostra la storia delle operazioni
# Ripristina a stato precedente
git reset --hard HEAD@{n} # dove n è il numero dall'reflog
# Oppure crea un branch di backup prima del force sync
git branch backup-$(date +%Y%m%d-%H%M%S)
|
Script di Automazione Bash
Script Base per Sincronizzazione
Crea uno script bash completo per automatizzare la sincronizzazione:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#!/bin/bash
# git_sync.sh - Script automazione sincronizzazione Git
# Utilizzo: ./git_sync.sh [directory_repo] [branch]
# Configurazione
REPO_DIR="${1:-$(pwd)}"
BRANCH="${2:-main}"
LOG_FILE="$HOME/git_sync.log"
MAX_LOG_SIZE=10485760 # 10MB
# Colori per output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Funzione logging
log_message() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "${timestamp} - $1" | tee -a "$LOG_FILE"
}
# Funzione rotazione log
rotate_log() {
if [[ -f "$LOG_FILE" ]] && [[ $(stat -c%s "$LOG_FILE") -gt $MAX_LOG_SIZE ]]; then
mv "$LOG_FILE" "${LOG_FILE}.old"
log_message "Log rotated - previous log saved as ${LOG_FILE}.old"
fi
}
# Controllo directory repository
check_repository() {
if [[ ! -d "$REPO_DIR/.git" ]]; then
log_message "${RED}ERROR: $REPO_DIR non è una directory Git valida${NC}"
exit 1
fi
}
# Backup modifiche locali
backup_local_changes() {
cd "$REPO_DIR" || exit 1
if ! git diff-index --quiet HEAD --; then
log_message "${YELLOW}Backup modifiche locali non committate...${NC}"
git stash push -m "Auto-backup $(date '+%Y-%m-%d %H:%M:%S')" 2>/dev/null
if [[ $? -eq 0 ]]; then
log_message "${GREEN}Modifiche locali salvate in stash${NC}"
else
log_message "${RED}Errore durante il backup delle modifiche locali${NC}"
fi
fi
}
# Sincronizzazione repository
sync_repository() {
cd "$REPO_DIR" || exit 1
log_message "${BLUE}Inizio sincronizzazione repository: $REPO_DIR${NC}"
# Fetch ultimo contenuto
log_message "Fetch da remote..."
if git fetch origin 2>>"$LOG_FILE"; then
log_message "${GREEN}Fetch completato con successo${NC}"
else
log_message "${RED}Errore durante fetch${NC}"
return 1
fi
# Checkout branch target
log_message "Checkout branch: $BRANCH"
if git checkout "$BRANCH" 2>>"$LOG_FILE"; then
log_message "${GREEN}Checkout completato${NC}"
else
log_message "${RED}Errore durante checkout di $BRANCH${NC}"
return 1
fi
# Force sync con remote
log_message "Force sync con origin/$BRANCH..."
if git reset --hard "origin/$BRANCH" 2>>"$LOG_FILE"; then
log_message "${GREEN}Force sync completato${NC}"
else
log_message "${RED}Errore durante force sync${NC}"
return 1
fi
# Pulizia file untracked
log_message "Pulizia file untracked..."
git clean -fd 2>>"$LOG_FILE"
# Informazioni finali
local current_commit=$(git rev-parse --short HEAD)
local commit_message=$(git log -1 --pretty=format:'%s')
log_message "${GREEN}Sincronizzazione completata${NC}"
log_message "Commit corrente: $current_commit - $commit_message"
return 0
}
# Controllo connettività
check_connectivity() {
cd "$REPO_DIR" || exit 1
log_message "Controllo connettività remote..."
if git ls-remote --exit-code origin HEAD >/dev/null 2>&1; then
log_message "${GREEN}Connettività OK${NC}"
return 0
else
log_message "${RED}Errore di connettività al repository remote${NC}"
return 1
fi
}
# Funzione principale
main() {
rotate_log
log_message "${BLUE}=== Avvio Git Sync Script ===${NC}"
check_repository
if ! check_connectivity; then
log_message "${RED}Script terminato per errore di connettività${NC}"
exit 1
fi
backup_local_changes
if sync_repository; then
log_message "${GREEN}=== Sincronizzazione completata con successo ===${NC}"
exit 0
else
log_message "${RED}=== Sincronizzazione fallita ===${NC}"
exit 1
fi
}
# Esecuzione script
main "$@"
|
Script Avanzato Multi-Repository
Per gestire multipli repository:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#!/bin/bash
# multi_git_sync.sh - Sincronizzazione multipli repository
# Configurazione via file JSON o array
# File configurazione repository
CONFIG_FILE="$HOME/.git_sync_config"
# Crea file configurazione se non esiste
create_config() {
if [[ ! -f "$CONFIG_FILE" ]]; then
cat > "$CONFIG_FILE" << 'EOF'
# Configurazione Git Sync - Un repository per riga
# Formato: /path/to/repo:branch_name:description
/home/user/project1:main:Progetto principale
/home/user/project2:development:Progetto di sviluppo
/var/www/website:master:Sito web aziendale
EOF
echo "File configurazione creato: $CONFIG_FILE"
echo "Modifica il file e riesegui lo script"
exit 0
fi
}
# Sincronizzazione multipla
sync_all_repositories() {
local success_count=0
local error_count=0
while IFS=':' read -r repo_path branch description; do
# Skip linee vuote e commenti
[[ -z "$repo_path" ]] || [[ "$repo_path" =~ ^#.*$ ]] && continue
echo "=================================="
echo "Repository: $description"
echo "Path: $repo_path"
echo "Branch: $branch"
echo "=================================="
if ./git_sync.sh "$repo_path" "$branch"; then
((success_count++))
echo "✓ $description - OK"
else
((error_count++))
echo "✗ $description - ERROR"
fi
echo ""
sleep 2 # Pausa tra repository
done < "$CONFIG_FILE"
echo "=================================="
echo "RIEPILOGO SINCRONIZZAZIONE:"
echo "Successi: $success_count"
echo "Errori: $error_count"
echo "=================================="
}
# Esecuzione
create_config
sync_all_repositories
|
Utilizzo Script Bash
1
2
3
4
5
6
7
8
9
10
11
|
# Rendi eseguibile lo script
chmod +x git_sync.sh
chmod +x multi_git_sync.sh
# Utilizzo base
./git_sync.sh # Repository corrente, branch main
./git_sync.sh /path/to/repo # Repository specifico, branch main
./git_sync.sh /path/to/repo development # Repository e branch specifici
# Sincronizzazione multipla
./multi_git_sync.sh
|
Script di Automazione PowerShell
Script Base PowerShell
Ecco l’equivalente PowerShell per sistemi Windows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
# GitSync.ps1 - Script PowerShell per sincronizzazione Git
param(
[Parameter(Position=0)]
[string]$RepositoryPath = (Get-Location).Path,
[Parameter(Position=1)]
[string]$Branch = "main",
[switch]$Verbose
)
# Configurazione
$LogFile = Join-Path $env:USERPROFILE "git_sync.log"
$MaxLogSize = 10MB
# Colori per output
enum LogLevel {
Info
Warning
Error
Success
}
# Funzione logging
function Write-LogMessage {
param(
[string]$Message,
[LogLevel]$Level = [LogLevel]::Info
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "$timestamp - $Message"
# Colori console
$color = switch($Level) {
"Info" { "White" }
"Warning" { "Yellow" }
"Error" { "Red" }
"Success" { "Green" }
}
Write-Host $logEntry -ForegroundColor $color
Add-Content -Path $LogFile -Value $logEntry
}
# Rotazione log
function Invoke-LogRotation {
if (Test-Path $LogFile) {
$logSize = (Get-Item $LogFile).Length
if ($logSize -gt $MaxLogSize) {
$oldLogFile = "${LogFile}.old"
Move-Item -Path $LogFile -Destination $oldLogFile -Force
Write-LogMessage "Log rotated - previous log saved as $oldLogFile" -Level Success
}
}
}
# Controllo repository Git
function Test-GitRepository {
param([string]$Path)
if (-not (Test-Path (Join-Path $Path ".git"))) {
Write-LogMessage "ERROR: $Path is not a valid Git repository" -Level Error
return $false
}
return $true
}
# Backup modifiche locali
function Backup-LocalChanges {
param([string]$RepoPath)
Push-Location $RepoPath
try {
# Controlla se ci sono modifiche non committate
$status = git status --porcelain 2>$null
if ($status) {
Write-LogMessage "Backing up uncommitted local changes..." -Level Warning
$stashMessage = "Auto-backup $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
git stash push -m $stashMessage 2>$null
if ($LASTEXITCODE -eq 0) {
Write-LogMessage "Local changes saved to stash" -Level Success
} else {
Write-LogMessage "Error backing up local changes" -Level Error
}
}
}
finally {
Pop-Location
}
}
# Controllo connettività
function Test-GitConnectivity {
param([string]$RepoPath)
Push-Location $RepoPath
try {
Write-LogMessage "Testing remote connectivity..."
$null = git ls-remote --exit-code origin HEAD 2>$null
if ($LASTEXITCODE -eq 0) {
Write-LogMessage "Connectivity OK" -Level Success
return $true
} else {
Write-LogMessage "Remote connectivity error" -Level Error
return $false
}
}
finally {
Pop-Location
}
}
# Sincronizzazione repository
function Sync-GitRepository {
param(
[string]$RepoPath,
[string]$TargetBranch
)
Push-Location $RepoPath
try {
Write-LogMessage "Starting repository sync: $RepoPath" -Level Info
# Fetch
Write-LogMessage "Fetching from remote..."
git fetch origin 2>>$LogFile
if ($LASTEXITCODE -ne 0) {
Write-LogMessage "Error during fetch" -Level Error
return $false
}
Write-LogMessage "Fetch completed successfully" -Level Success
# Checkout branch
Write-LogMessage "Checking out branch: $TargetBranch"
git checkout $TargetBranch 2>>$LogFile
if ($LASTEXITCODE -ne 0) {
Write-LogMessage "Error checking out $TargetBranch" -Level Error
return $false
}
Write-LogMessage "Checkout completed" -Level Success
# Force sync
Write-LogMessage "Force syncing with origin/$TargetBranch..."
git reset --hard "origin/$TargetBranch" 2>>$LogFile
if ($LASTEXITCODE -ne 0) {
Write-LogMessage "Error during force sync" -Level Error
return $false
}
Write-LogMessage "Force sync completed" -Level Success
# Clean untracked files
Write-LogMessage "Cleaning untracked files..."
git clean -fd 2>>$LogFile
# Final info
$currentCommit = git rev-parse --short HEAD
$commitMessage = git log -1 --pretty=format:'%s'
Write-LogMessage "Sync completed successfully" -Level Success
Write-LogMessage "Current commit: $currentCommit - $commitMessage" -Level Info
return $true
}
finally {
Pop-Location
}
}
# Funzione principale
function Main {
try {
Invoke-LogRotation
Write-LogMessage "=== Starting Git Sync Script ===" -Level Info
# Controlli preliminari
if (-not (Test-GitRepository -Path $RepositoryPath)) {
exit 1
}
if (-not (Test-GitConnectivity -Path $RepositoryPath)) {
Write-LogMessage "Script terminated due to connectivity error" -Level Error
exit 1
}
# Backup e sincronizzazione
Backup-LocalChanges -RepoPath $RepositoryPath
if (Sync-GitRepository -RepoPath $RepositoryPath -TargetBranch $Branch) {
Write-LogMessage "=== Synchronization completed successfully ===" -Level Success
exit 0
} else {
Write-LogMessage "=== Synchronization failed ===" -Level Error
exit 1
}
}
catch {
Write-LogMessage "Unexpected error: $($_.Exception.Message)" -Level Error
exit 1
}
}
# Esecuzione script
Main
|
Script Multi-Repository PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# MultiGitSync.ps1 - Gestione multipli repository
param(
[string]$ConfigFile = (Join-Path $env:USERPROFILE ".git_sync_config.json")
)
# Struttura configurazione
class GitRepository {
[string]$Path
[string]$Branch
[string]$Description
[bool]$Enabled = $true
}
# Crea file configurazione predefinito
function New-DefaultConfig {
param([string]$ConfigPath)
$defaultConfig = @(
[GitRepository]@{
Path = "C:\Projects\WebSite"
Branch = "main"
Description = "Sito web principale"
Enabled = $true
},
[GitRepository]@{
Path = "C:\Projects\API"
Branch = "development"
Description = "API Backend"
Enabled = $true
}
)
$defaultConfig | ConvertTo-Json -Depth 2 | Set-Content $ConfigPath
Write-Host "Configuration file created: $ConfigPath" -ForegroundColor Green
Write-Host "Edit the file and run the script again" -ForegroundColor Yellow
}
# Carica configurazione
function Get-RepositoryConfig {
param([string]$ConfigPath)
if (-not (Test-Path $ConfigPath)) {
New-DefaultConfig -ConfigPath $ConfigPath
return $null
}
try {
$config = Get-Content $ConfigPath | ConvertFrom-Json
return $config | ForEach-Object {
[GitRepository]@{
Path = $_.Path
Branch = $_.Branch
Description = $_.Description
Enabled = $_.Enabled
}
}
}
catch {
Write-Host "Error loading config file: $($_.Exception.Message)" -ForegroundColor Red
return $null
}
}
# Sincronizzazione multipla
function Sync-AllRepositories {
param([GitRepository[]]$Repositories)
$successCount = 0
$errorCount = 0
foreach ($repo in $Repositories) {
if (-not $repo.Enabled) {
Write-Host "Skipping disabled repository: $($repo.Description)" -ForegroundColor Gray
continue
}
Write-Host "=================================="
Write-Host "Repository: $($repo.Description)" -ForegroundColor Cyan
Write-Host "Path: $($repo.Path)" -ForegroundColor White
Write-Host "Branch: $($repo.Branch)" -ForegroundColor White
Write-Host "=================================="
# Esegui script principale
try {
$result = & ".\GitSync.ps1" -RepositoryPath $repo.Path -Branch $repo.Branch
if ($LASTEXITCODE -eq 0) {
$successCount++
Write-Host "✓ $($repo.Description) - OK" -ForegroundColor Green
} else {
$errorCount++
Write-Host "✗ $($repo.Description) - ERROR" -ForegroundColor Red
}
}
catch {
$errorCount++
Write-Host "✗ $($repo.Description) - EXCEPTION: $($_.Exception.Message)" -ForegroundColor Red
}
Write-Host ""
Start-Sleep -Seconds 2 # Pausa tra repository
}
# Riepilogo finale
Write-Host "=================================="
Write-Host "SYNC SUMMARY:" -ForegroundColor Yellow
Write-Host "Successes: $successCount" -ForegroundColor Green
Write-Host "Errors: $errorCount" -ForegroundColor Red
Write-Host "=================================="
}
# Funzione principale
function Main {
$repositories = Get-RepositoryConfig -ConfigPath $ConfigFile
if ($null -eq $repositories) {
exit 1
}
Sync-AllRepositories -Repositories $repositories
}
# Esecuzione
Main
|
Utilizzo Script PowerShell
1
2
3
4
5
6
7
8
9
10
11
|
# Esecuzione script singolo
.\GitSync.ps1 # Repository corrente, branch main
.\GitSync.ps1 -RepositoryPath "C:\Projects\Web" # Repository specifico
.\GitSync.ps1 "C:\Projects\Web" "development" # Repository e branch specifici
# Sincronizzazione multipla
.\MultiGitSync.ps1
.\MultiGitSync.ps1 -ConfigFile "custom_config.json"
# Con output verboso
.\GitSync.ps1 -Verbose -RepositoryPath "C:\Projects\Web"
|
Schedulazione e Monitoring
Schedulazione con Cron (Linux)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# Modifica crontab
crontab -e
# Esempi di schedulazione:
# Ogni ora
0 * * * * /home/user/scripts/git_sync.sh /home/user/project >> /dev/null 2>&1
# Ogni giorno alle 8:00 e 18:00
0 8,18 * * * /home/user/scripts/git_sync.sh /home/user/project
# Ogni lunedì alle 9:00 (sincronizzazione settimanale completa)
0 9 * * 1 /home/user/scripts/multi_git_sync.sh
# Ogni 30 minuti durante l'orario lavorativo (9-18)
*/30 9-18 * * 1-5 /home/user/scripts/git_sync.sh /var/www/website
# Verifica crontab attivo
crontab -l
# Log cron (per debug)
grep CRON /var/log/syslog
|
Schedulazione con Task Scheduler (Windows)
Crea un task con PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# CreateScheduledTask.ps1 - Crea task schedulato
$TaskName = "GitAutoSync"
$ScriptPath = "C:\Scripts\GitSync.ps1"
$WorkingDirectory = "C:\Scripts"
# Azione del task
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -File `"$ScriptPath`"" -WorkingDirectory $WorkingDirectory
# Trigger (ogni 2 ore dalle 8:00 alle 18:00)
$Trigger = New-ScheduledTaskTrigger -Daily -At "08:00AM" -RepetitionInterval (New-TimeSpan -Hours 2) -RepetitionDuration (New-TimeSpan -Hours 10)
# Impostazioni
$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
# Registra il task
Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Settings $Settings -Description "Automatic Git repository synchronization"
Write-Host "Scheduled task '$TaskName' created successfully" -ForegroundColor Green
# Per gestire il task:
# Get-ScheduledTask -TaskName $TaskName
# Start-ScheduledTask -TaskName $TaskName
# Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
|
Monitoring e Alerting
Script per monitorare i log e inviare notifiche:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#!/bin/bash
# git_monitor.sh - Monitoring e alerting
LOG_FILE="$HOME/git_sync.log"
ALERT_EMAIL="admin@esempio.com"
ERROR_THRESHOLD=3 # Alert dopo 3 errori consecutivi
# Conta errori recenti
check_recent_errors() {
local recent_errors=$(tail -100 "$LOG_FILE" | grep -c "ERROR\|failed")
echo $recent_errors
}
# Invia alert email
send_alert() {
local subject="Git Sync Alert - Errori rilevati"
local body="Rilevati errori multipli nella sincronizzazione Git.\n\nUltimi log:\n$(tail -20 "$LOG_FILE")"
echo -e "$body" | mail -s "$subject" "$ALERT_EMAIL"
}
# Controllo e alert
main() {
local error_count=$(check_recent_errors)
if [[ $error_count -ge $ERROR_THRESHOLD ]]; then
echo "ALERT: Rilevati $error_count errori recenti"
send_alert
else
echo "Status OK: $error_count errori negli ultimi 100 log entries"
fi
}
main
|
Troubleshooting Comune
Problemi di Autenticazione
1
2
3
4
5
6
7
8
9
10
11
12
|
# Verifica configurazione credenziali
git config --list | grep credential
# Test autenticazione
git ls-remote origin
# Reset credenziali (se problematiche)
git config --global --unset credential.helper
rm ~/.git-credentials
# Riconfigurazione da zero
git config --global credential.helper store
|
Problemi di Connettività
1
2
3
4
5
6
7
8
9
10
11
12
|
# Test connessione HTTPS
curl -I https://github.com
# Test connessione specifica repository
git ls-remote https://github.com/username/repo.git
# Verifica proxy (se applicabile)
git config --global http.proxy http://proxy:port
git config --global https.proxy https://proxy:port
# Debug verbose
GIT_CURL_VERBOSE=1 git fetch origin
|
Problemi con Force Sync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# Se force sync fallisce, controlla:
# 1. Permessi file
ls -la .git/
sudo chown -R $USER:$USER .git/
# 2. Lock files
rm -f .git/index.lock
rm -f .git/refs/heads/*.lock
# 3. Corrupted repository
git fsck --full
git gc --aggressive
# 4. Reset completo come ultima risorsa
git fetch origin
git reset --hard origin/main
git clean -fxd # Attenzione: rimuove tutto
|
Debug Script Automazione
1
2
3
4
5
6
7
8
9
10
11
|
# Debug bash script
bash -x ./git_sync.sh
# Debug con più dettagli
set -x # Aggiungi all'inizio dello script
set +x # Disabilita debug
# Log dettagliato PowerShell
# Aggiungi nel script:
$VerbosePreference = "Continue"
Write-Verbose "Debug message"
|
Risorse Aggiuntive
La padronanza di questi strumenti e tecniche ti renderà molto più produttivo nella gestione dei repository Git, sia in progetti individuali che in team complessi! 🚀