2016-04-20 95 views
6

Ho usato Git pesantemente per circa 7 anni. Qualche giorno fa ho trovato un comportamento che mi ha sorpreso. Ho trovato git log, git blame e git bisect per mostrare questo strano comportamento. A friend fammi sapere del flag --full-history su git log che ha risolto il mio problema. Voglio sapere, per la mia istruzione, se esiste una soluzione equivalente per git blame e git bisect.Git: Equivalente di `--full-history` per` git bisect` e `git blame`

Sentitevi liberi di vedere il problema da soli con questo repo: https://dl.dropboxusercontent.com/u/1927707/problematic_repo.7z

Qui è il suo registro:

$ git log --graph 
* commit b7a8d7aa001d06eb7491ab5fb447a8dd3aa421a8 
| Author: Ram Rachum <[email protected]> 
| Date: Tue Apr 19 17:45:01 2016 +0300 
| 
|  adding more to some-file 
| 
* commit 0aa833916e908ea93902a6c4c227f9a884a1bcef 
|\ Merge: 2413945 3068c7d 
| | Author: Ram Rachum <[email protected]> 
| | Date: Tue Apr 19 17:44:31 2016 +0300 
| | 
| |  Merge branch 'master' into development 
| | 
| * commit 3068c7d2548f1798b6840f73b13a649937339f28 
| | Author: Ram Rachum <[email protected]> 
| | Date: Tue Apr 19 16:02:27 2016 +0300 
| | 
| |  Adding sugar to coffee 
| | 
* | commit 24139451ab954b1f0a9ef616775a3dba0ac81669 
|/ Author: Ram Rachum <[email protected]> 
| Date: Tue Apr 19 16:01:28 2016 +0300 
| 
|  Creating some-file 
| 
* commit cf02fbbc40104cd02eea4c7c6f134ef1fd7b5661 
    Author: Ram Rachum <[email protected]> 
    Date: Tue Apr 19 16:00:47 2016 +0300 

     Create coffee 

Nel primo commit, è stato aggiunto il file coffee. Nel commit 3068c7d, ho aggiunto una riga "zucchero" al file coffee. Ma poi ho unito questo ramo nel ramo development e in questa unione è stato commesso un errore e la riga "zucchero" è stata rimossa, lasciando coffee vuoto. Quindi un altro commit b7a8d7a, apportando una modifica non correlata, è stato aggiunto per buona misura.

Ora sto guardando il mio caffè e non trovo zucchero. Ricordo distintamente di aggiungere zucchero al mio caffè. Corro git log coffee, ed ottengo questo output:

$ git log coffee 
commit cf02fbbc40104cd02eea4c7c6f134ef1fd7b5661 
Author: Ram Rachum <[email protected]> 
Date: Tue Apr 19 16:00:47 2016 +0300 

    Create coffee 

Questo è tutto. git log non mostra né il mio commit originale che ha aggiunto lo zucchero, né l'unione che lo ha rimosso. Due commit molto rilevanti che mancano.

Sono stato frustrato per circa un'ora da questo problema, perché è successo in un enorme repo aziendale, dove i commit sono molto più difficili da trovare manualmente.

Ho anche provato a utilizzare git bisect e git blame per bloccare i due commit, ma entrambi questi strumenti ignoravano i due commit. git bisect mi ha indirizzato al commit sbagliato dopo aver completato tutte le azioni git bisect bad e git bisect good.

Poi, come ho detto all'inizio, un amico mi ha segnalato verso la bandiera --full-history:

$ git log --full-history --graph coffee     
* commit 0aa833916e908ea93902a6c4c227f9a884a1bcef  
|\ Merge: cf02fbb 3068c7d        
| | Author: Ram Rachum <[email protected]>     
| | Date: Tue Apr 19 17:44:31 2016 +0300    
| |              
| |  Merge branch 'master' into development   
| |              
| * commit 3068c7d2548f1798b6840f73b13a649937339f28  
|/ Author: Ram Rachum <[email protected]>     
| Date: Tue Apr 19 16:02:27 2016 +0300    
|              
|  Adding sugar to coffee       
|              
* commit cf02fbbc40104cd02eea4c7c6f134ef1fd7b5661  
    Author: Ram Rachum <[email protected]>     
    Date: Tue Apr 19 16:00:47 2016 +0300    

     Create coffee          

Questo mi rende felice perché mostra i due commit rilevanti, quello di zucchero aggiungendo e l'unione che ha rimosso esso. Quindi il mio problema è risolto. Ma mi piacerebbe davvero sapere come si comportano anche git bisect e git blame. Qualcuno capita di saperlo?

+0

'git blame' può ben permettere' --full-storia 'direttamente qui (lo proverei sul tuo repository ma non posso decomprimere un file 7zip). Bisect potrebbe rifiutarsi di toccare le unioni poiché le gestisce da sé. In generale non si vedono queste cose perché 'git rev-list' salta un sacco di fusioni: vedere la discussione della documentazione su TREESAME e unire la gestione (e in che modo --full-history lo altera). – torek

+0

@torek L'ho provato ora, 'blame' sembra accettare la bandiera ma sembra che non cambi nulla. Provando entrambi git blame --full-history' e 'git blame --full-history --reverse' non hanno mostrato risultati. Per quanto riguarda l'impossibilità di aprire archivi 7z, qui è in zip: https://dl.dropboxusercontent.com/u/1927707/foo.zip –

+0

@torek Anche provato 'git blame --reverse HEAD ^^^ .. HEAD --full-history coffee', ancora senza ottenere nulla. –

risposta

0

Interessante. Dal momento che la linea non è presente, git blame inizia in modo non utile. Per quanto la documentazione per git blame note:

Il rapporto non ti dice nulla su linee che sono state eliminati o sostituiti; è necessario utilizzare uno strumento come git diff o l'interfaccia "piccone" brevemente menzionata nel seguente paragrafo.

In questo caso potremmo correre git log -SSugar per trovare dove è andato a:

$ git log --pretty=oneline -SSugar 
3068c7d2548f1798b6840f73b13a649937339f28 Adding sugar to coffee 

ma git blame non immediatamente aiutarci a trovare dove è andato fuori. (E come hai appena scoperto, se vogliamo trovare quella linea quando menzioniamo i file, potremmo aver bisogno di --full-history, poiché l'aggiunta di percorsi per limitare i commit git log prenderà in considerazione, causa anche la semplificazione della storia potando ogni albero di commit per contenere solo . i file citati e quindi utilizzando il codice che TREESAME)

Partendo dalla nota bene giri, possiamo ora provare --reverse [Edit: ho notato 3068c7d2548f1798b6840f73b13a649937339f28 == master e effettivamente utilizzate master qui, probabilmente dovuto utilizzare il SHA-1 direttamente]:

$ git blame --reverse master..HEAD coffee 
^3068c7d (Ram Rachum 2016-04-19 16:02:27 +0300 1) Sugar 

Questo sembra implicare che 3068c7d è l'ultimo giro in cui è presente la linea, quindi deve essere eliminato in alcuni o tutti i bambini lungo questo particolare percorso, il che è vero:

$ git log --oneline --graph --decorate --all 
* b7a8d7a (HEAD -> development) adding more to some-file 
* 0aa8339 Merge branch 'master' into development 
|\ 
| * 3068c7d (master) Adding sugar to coffee 
* | 2413945 Creating some-file 
|/ 
* cf02fbb Create coffee 

C'è solo un commit che è un figlio di 3068c7d qui, vale a dire 0aa8339, quindi:

$ git show -m 0aa8339 
commit 0aa833916e908ea93902a6c4c227f9a884a1bcef (from 3068c7d2548f1798b6840f73b1 
Merge: 2413945 3068c7d 
Author: Ram Rachum <[email protected]> 
Date: Tue Apr 19 17:44:31 2016 +0300 

    Merge branch 'master' into development 

diff --git a/coffee b/coffee 
index 4d0f160..e69de29 100644 
--- a/coffee 
+++ b/coffee 
@@ -1 +0,0 @@ 
-Sugar 
diff --git a/some-file b/some-file 
new file mode 100644 
index 0000000..e69de29 

(abbiamo bisogno di ottenere -m git per confrontare l'unione contro entrambi i genitori). E questo lo trova, in un modo leggermente indiretto.


(Nel frattempo, sembra che ci sia alcuna cura per il problema bisect. Beh, diverso da "evitare fonde male" ...)

+0

Grazie per la tua risposta! Il mio errore con '--reverse' non stava usando il commit di sinistra corretto. Aggiornamento –

+0

: Ho provato a utilizzare "colpa" ora per un caso simile, ma in cui il vecchio commit ha rimosso le righe esistenti prima e l'unione le ha reiterate per errore. 'blame' non è riuscito a mostrare l'unione che ha erroneamente riaggiunto le righe, anche quando ho usato' --full-history' e '--full-history --reverse branch..other_branch'. Qualche idea del perché? –

+0

Non sono proprio sicuro: non uso 'git blame' tanto tanto. In generale, però, sia che si stia procedendo in avanti o all'indietro, confronta (le righe di un file in) ogni commit prima/dopo, preso a coppie, per vedere se una linea è stata cambiata o rimossa. Alla linea viene quindi assegnato l'ID del commit corrispondente della coppia.Questo metodo non funziona (e non può) funziona molto bene attraverso le unioni poiché esistono più abbinamenti. – torek