Non c'è una soluzione perfetta ma puoi avvicinarti, forse abbastanza vicino.
Assicurarsi di iniziare con un albero di lavoro pulito e un indice (vedere require_clean_work_tree
in git-sh-setup
).
Per ogni ramo candidato $branch
che potrebbero essere elimina-grado:
- trovare la sua destinazione di unione (presumibilmente
merge_target=$(git config --get branch.${branch}.merge)
). Controlla il target di fusione.
- Unire con
--no-commit
; oppure nel passaggio 1, controlla con --detach
in modo da ottenere un commit che puoi abbandonare, se l'unione ha esito positivo.
- Verificare se git pensa che l'unione sia riuscita e, in tal caso, se l'albero attuale corrisponde all'albero precedente, cioè non ha apportato alcuna modifica. Se riesci a testare le corrispondenze esatte e se permetti il commit (via
--detach
), puoi fare questo ultimo test in modo molto semplice, senza alcuna differenza: esegui sia git rev-parse HEAD^{tree}
e git rev-parse HEAD^^{tree}
e vedi se producono lo stesso hash. Se non si consente il commit, è ancora possibile git diff
il commit corrente (HEAD
) contro l'unione proposta. Se è necessario rimuovere un po 'di rumore dal diff (ad esempio, i file di configurazione che non dovrebbero essere, ma sono comunque nei commit), questo ti dà un posto dove farlo.
- Reset (
git merge --abort; git reset --hard HEAD; git clean -f
o simile, a seconda di come si è deciso di implementare i passaggi 1-3). Questo è solo lo scopo di rendere il tuo albero di lavoro e l'indice di nuovo pulito, per il prossimo passaggio.
- Se l'unione nel passaggio 3 ha funzionato e non ha apportato modifiche, è possibile eliminare il ramo locale. Altrimenti, tienilo.
In sostanza, questo è "effettivamente fare l'unione e vedere cosa succede", solo completamente automatizzato.
Questa notazione sembra un po 'strano, ma è solo HEAD^
-il primo genitore del HEAD
-followed da ^{tree}
. Le ortografie alternative potrebbero essere più facili da leggere: HEAD~1^{tree}
o ${merge_target}^tree
, dove ${merge_target}
è il ramo che hai controllato al passaggio 1. Si noti che questo presuppone l'unione riuscita. Il risultato dell'unione è nello stato di uscita di git merge
: zero significa riuscito, non zero significa non riuscito e necessita di assistenza manuale, presumibilmente a causa di un conflitto di unione.
Ti aspetti davvero di avere molti rami locali attorno ai quali non ci sono cambiamenti rispetto al master? Questo non implica che qualcuno abbia creato un ramo e non abbia fatto nulla con esso? –
Il processo è: creo un ramo locale, apporto le modifiche, lo spingo in remoto, invio un PR, il PR viene unito a uno squash in master, faccio avanzare rapidamente il mio master locale e ... il mio ramo locale rimane non diviso ('git branch -d' non lo elimina), ma non ha modifiche rispetto al master (' git diff branch_name' non ha risultati). Quindi, se avessi fatto 10 PR, avrò 10 filiali locali non raggruppate senza modifiche. – Claudiu
Non mi piace questo flusso di lavoro. Perché non basta uccidere il ramo dopo averlo fuso in 'master'? –