Il seguente comando shell dovrebbe fare quello che vuoi:
git log --all --not $(git rev-list --no-walk --exclude=refs/heads/mybranch --all)
Avvertenze
Se hai mybranch
verificato, il comando sopra non funzionerà. Questo perché anche i commit mybranch
sono raggiungibili HEAD
, quindi Git non considera i commit unici mybranch
. Per farlo funzionare quando mybranch
è stato estratto, è inoltre necessario aggiungere un'esclusione per HEAD
:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=HEAD \
--all)
Tuttavia, si dovrebbe non escludere HEAD
a meno che il mybranch
è stato estratto, altrimenti si rischia di mostrare commit che non sono esclusiva mybranch
.
Allo stesso modo, se si dispone di un ramo remoto denominato origin/mybranch
che corrisponde al mybranch
ramo locale , è necessario escluderlo:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=refs/remotes/origin/mybranch \
--all)
E se il ramo remoto è il ramo predefinito per il repository remoto (di solito è vero solo per origin/master
), dovrai anche escludere origin/HEAD
:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=refs/remotes/origin/mybranch \
--exclude=refs/remotes/origin/HEAD \
--all)
Se il ramo è stato estratto e c'è un ramo remoto e il ramo remoto è l'impostazione predefinita per il repository remoto, si finisce per escludere molto:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=HEAD
--exclude=refs/remotes/origin/mybranch \
--exclude=refs/remotes/origin/HEAD \
--all)
Spiegazione
Il git rev-list
comando è un comando di basso livello (idraulico) che accompagna le revisioni date e scarica gli identificatori SHA1 riscontrati. Pensalo equivalente a git log
tranne che mostra solo SHA1: nessun messaggio di registro, nessun nome di autore, nessun timestamp, nessuna di quelle cose "fantasiose".
L' --no-walk
opzione, come suggerisce il nome, impedisce git rev-list
di camminare sulla catena degli antenati. Quindi, se digiti git rev-list --no-walk mybranch
, stamperà solo un identificatore SHA1: l'identificatore del commit tip del mybranch
ramo.
Gli --exclude=refs/heads/mybranch --all
argomenti dicono git rev-list
di iniziare da ogni riferimento tranne che per refs/heads/mybranch
.
Quindi, quando corri git rev-list --no-walk --exclude=refs/heads/mybranch --all
, Git stampa l'identificatore SHA1 del commit tip di ogni ref tranne per refs/heads/mybranch
. Questi commit e i loro antenati sono i commit che non ti interessano, questi sono i commit che non vuoi vedere.
Gli altri commit sono quelli che vuoi vedere, quindi raccogliamo l'output di git rev-list --no-walk --exclude=refs/heads/mybranch --all
e diciamo a Git di mostrare tutto tranne quei commit e i loro antenati.
L' --no-walk
argomento è necessario per i repository di grandi dimensioni (ed è un'ottimizzazione per i repository di piccole dimensioni): senza di essa, Git dovrebbe stampare e la shell dovrebbe raccogliere (e archiviare in memoria) molti più identificatori di commit del necessario. Con un repository di grandi dimensioni, il numero di commit raccolti potrebbe facilmente superare il limite dell'argomento della riga di comando della shell.
Bug bug?
Mi sarei aspettato che funzionasse:
git log --all --not --exclude=refs/heads/mybranch --all
ma non lo fa. Immagino che questo sia un bug in Git, ma forse è intenzionale.