Domanda

Sto scrivendo una sceneggiatura che richiede di verificare se un commit particolare è un commit o meno di unione/ripristino, e mi chiedo se c'è un trucco GIT per questo.

Quello che mi è venuto in mente finora (e sicuramente non voglio dipendere dal messaggio di commit qui) è controllare HASH^2 E vedi se non ricevo un errore, c'è un modo migliore?

È stato utile?

Soluzione

Capire se qualcosa è unione è facile. Questo è tutto commit con più di un genitore. Per verificarlo, puoi farlo, ad esempio

$ git cat-file -p $commit_id

Se c'è più di una linea di "genitore" nell'output, hai trovato un fusione.

Per i ritorni non è così facile. Generalmente i ritorni sono solo commit normali che si applicano il diff di un precedente commit al contrario, rimuovendo efficacemente le modifiche introdotte. Altrimenti non c'è speciale.

Se è stato creato un ripristino con git revert $commit, Quindi Git di solito genera un messaggio di commit indicazione del ripristino e quale commit è tornato. Tuttavia, è del tutto possibile fare ritorni in altri modi o semplicemente cambiare il messaggio di commit di un commit generato da git revert.

Alla ricerca di coloro che sono stati generati un messaggio di commit potrebbe essere già un euristico abbastanza buono per quello che stai cercando di ottenere. In caso contrario, dovresti effettivamente guardare attraverso altri commessi, confrontando le loro differenze l'una con l'altra, la ricerca di una è l'esatta operazione inversa di un altro. Ma anche questa non è una buona soluzione. Spesso i ritorni sono leggermente diversi dal semplice inverso del commit che stanno tornando, ad esempio per accogliere le modifiche al codice che si sono verificate tra il commit e il ripristino.

Altri suggerimenti

Le seguenti istruzioni si scaricano solo i genitori hash. Meno filtraggio necessario ...

git show --no-patch --format="%P" <commit hash>

La risposta usando git cat-file sta usando un git "impianto idraulico" Comando, che è generalmente migliore per la costruzione di script poiché il formato di output non è probabile che cambi. Quelli che usano git show e git rev-parse potrebbe essere necessario cambiare nel tempo mentre stanno usando porcellana comandi.

La funzione bash che uso da molto tempo usi git rev-list:

gitismerge () {
    local sha="$1"
    msha=$(git rev-list -1 --merges ${sha}~1..${sha})
    [ -z "$msha" ] && return 1
    return 0
}

L'elenco dei comandi in porcellana/idraulica è disponibile nei documenti per il livello superiore idiota comando.

Questo codice utilizza Git-rev-list con uno specifico gitrevisioni Domanda ${sha}~1..${sha} In un modo che stampa il secondo genitore di SHA se esiste, o niente se non è presente, che è la definizione esatta di un commit di unione.

In particolare, SHA~1..SHA significa Includi commit che sono raggiungibili da SHA ma escludono quelli che sono raggiungibili SHA ~ 1, che è il primo genitore di SHA.

I risultati sono memorizzati in $ msha e testati per il vuoto usando bash [ -z "$msha" ] fallimento (restituendo 1) se vuoto o passando (restituendo 0) se non vuoto.

Un modo per testare un commit di unione:

$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT

Per quanto riguarda il ritorno di Git, sono d'accordo con @rafl che l'approccio più realistico è cercare il messaggio di ripristino del messaggio nel messaggio di commit; Se qualcuno lo cambiasse, rilevando, quindi sarebbe molto coinvolto.

Modo semplice per testare per unione di commit:

git show --summary HEAD | grep -q ^Merge:

Ciò restituirà 0 per commit di unione, 1 per commit non-merge. Sostituisci la testa dal tuo impegno desiderato per testare.

Esempio di utilizzo:

if git show --summary some-branch | grep -q ^Merge: ; then
    echo "some-branch is a merge"
fi

Ancora un altro modo per trovare i genitori di un commit:

git show -s --pretty=%p <commit>

Uso %P per hash completo. Questo stampano quanti genitori HEAD ha:

git show -s --pretty=%p HEAD | wc -w
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top