/ / Ottieni un blob da un commit? - c, git, libgit2

Ottieni un blob da un commit? - c, git, libgit2

Sto cercando di capire come ottenere una lista di file e i loro rispettivi vecchi e nuovi blob per un singolo commit.

Diciamo che hai commit 1 che ha cambiato 3 file. Vorrei eseguire detta funzione e restituire 3 file insieme al loro vecchio blob e nuovo blob (supponendo che non siano binari).

L'unico modo per farlo sarebbe ottenere il commit e il commit precedente, risolvere i loro alberi, quindi fare una diff sugli alberi per scoprire cosa è diverso, e quindi ottenere il blob per ogni file differente?

risposte:

3 per risposta № 1

L'unico modo per farlo sarebbe ottenere il commit e il commit precedente, risolvere i loro alberi, quindi fare una diff sugli alberi per scoprire cosa è diverso, e quindi ottenere il blob per ogni file differente?

Sì, questo è il modo consigliato. "Vecchio" e "nuovo" le voci sono solo concetti che hanno senso quando si confrontano due TreeS.

Attenzione "vecchio" e "nuovo" non sono quei qualificatori espressivi. Come si può sbirciare nel intestazione diff, lo stato differenziale risultante di una voce può essere

  • GIT_DELTA_UNMODIFIED = 0, / ** nessuna modifica * /
  • GIT_DELTA_ADDED = 1, / ** la voce non esiste nella vecchia versione * /
  • GIT_DELTA_DELETED = 2, / ** la voce non esiste nella nuova versione * /
  • GIT_DELTA_MODIFIED = 3, / ** contenuto della voce cambiato tra vecchio e nuovo * /
  • GIT_DELTA_RENAMED = 4, / ** la voce è stata rinominata tra la vecchia e la nuova * /
  • GIT_DELTA_COPIED = 5, / ** la voce è stata copiata da un'altra vecchia voce * /
  • GIT_DELTA_IGNORED = 6, / ** la voce viene ignorata nel workdir * /
  • GIT_DELTA_UNTRACKED = 7, / ** la voce è elemento non tracciato in workdir * /
  • GIT_DELTA_TYPECHANGE = 8, / ** tipo di voce cambiato tra vecchio e nuovo * /

Il libgit2 test-Clar / diff / albero il file di test dovrebbe darti qualche esempio di utilizzo di questa funzione.

Aggiornare:

UN domanda simile (da te? ;-)) è stato generato nel tracker dei problemi di libgit2. La risposta di @arrbee si basa anche sull'utilizzo del git_diff_tree_to_tree() API.


0 per risposta № 2

Estrazione di SHA1 per revisioni precedenti e correnti

Considera l'output di git show --raw v1.8.1^0 nel repository di git.

commettere5d417842efeafb6e109db7574196901c4e95d273 Autore: Junio ​​C Hamano Data: lun 31 dicembre 14:24:22 2012 -0800  Git 1.8.1  Sottoscritto: Junio ​​C Hamano <gitster@pobox.com>  : 100644 100644 fec1a06 ... d6f9555 ... M Documentazione / RelNotes / 1.8.1.txt : 100644 100644 b0e8f02 ... 7a3f03b ... M Documentazione / git.txt : 100755 100755 b2dffc8 ... 72e37c9 ... M GIT-VERSION-GEN

Le ultime tre righe indicano i file modificaticon quel commit. Il primo SHA1 su una riga di modifica è il nome dell'oggetto della revisione precedente di un determinato file e il secondo è il blob nel commit denominato. Per esempio, GIT-VERSION-GEN in v1.8.1 hash a

$ git show v1.8.1 ^ 0: GIT-VERSION-GEN | git hash-object --stdin 72e37c9bfe3e897635f8c211569d9e6f5658a980

e il blob associato al suo commit padre è

$ git show v1.8.1 ^ 0 ~: GIT-VERSION-GEN | git hash-object --stdin b2dffc839f306123d544e8f536ee31a7574f1139

Nota: la documentazione per git rev-parse spiega

Come regola speciale, <rev>^0 significa il commit stesso e viene usato quando <rev> è il nome dell'oggetto di un oggetto tag che fa riferimento a un oggetto commit.

In questo caso, v1.8.1^0 significa il commit a quale tag v1.8.1 si riferisce.

Recupero di SHA1 per tutti i BLOB in un commit

Per ottenere nomi di oggetti per tutti i BLOB associati a un determinato commit, leggere l'output di git ls-tree, che assomiglia

$ git ls-tree -r v1.8.1 ^ 0 100644 blob 5e98806c6cc246acef5f539ae191710a0c06ad3f .gitattributes 100644 blob f702415c12c5a4a66180f7ffd697347e5343ac4a .gitignore 100644 blob c7e86183001a00ad2105765708b5b59852ef6640 .mailmap 100644 blob 536e55524db72bd2acf175208aef4f3dfc148d42 COPIA 100644 blob ddb030137d54ef3fb0ee01d973ec5cee4bb2b2b3 Documentazione / .gitattributes 100644 blob d62aebd848b2a44f977ad4d7c4b75b6ff72b2163 Documentazione / .gitignore 100644 blob 69f7e9b76c3f9b87b7951fb0df6a9720edadeb3e Documentazione / CodingGuidelines 100644 blob e53d333e5c08515af1e21d81c7daa365b12609a1 Documentazione / Makefile 100644 blob fea3f9935b7794ce86f04d22c9d68fb9d537167d Documentazione / RelNotes / 1.5.0.1.txt 100644 blob b061e50ff05b5e13211bb315e240974e898de32c Documentazione / RelNotes / 1.5.0.2.txt ...

-1 per risposta № 3

Usando solo i comandi Git, non si conoscono le particolari funzioni di libgit2 per accedere a queste informazioni, ma probabilmente lo si può capire.

È possibile ottenere un elenco di file di quali file sono stati modificati in un commit particolare utilizzando git show --stat COMMIT. In fondo c'è un elenco di percorsi di file che hannocambiato (più dettagli quante linee sono cambiate). Probabilmente puoi filtrare le cose da lì. Puoi usare ulteriormente la bella formattazione per rimuovere ancora più contenuti dall'output.

Una volta ottenuto il percorso del file, è possibile ottenere un blob di file utilizzando git show COMMIT:PATH. Si ottiene la versione precedente del file utilizzando git show COMMIT^:PATH.