|
Size: 28850
Comment:
|
Size: 28413
Comment: proofreading
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 37: | Line 37: |
| Ovviamente anche i VCS Distribuiti hanno i loro difetti, il problema più importante che ho riscontrato è il gran numero di ''conflitti'. Questo perché con i VCS Centralizzati un commit è di solito rifiutato se conflitta con la copia del server. Invece con i VCS distrubuiti, chiunque può eseguire un commit nel suo repo, e conflitta solo quando viene ''pushato'' (il termine "push" verrà spiegato in seguito). | Ovviamente anche i VCS Distribuiti hanno i loro difetti, il problema più importante che ho riscontrato è il gran numero di ''conflitti'. Questo perché con i VCS Centralizzati un commit è di solito rifiutato se determina un conflitto con la copia del server. Invece con i VCS distrubuiti, chiunque può eseguire un commit nel suo repo, e il conflitto avviene solo quando viene ''pushato'' (il termine "push" verrà spiegato in seguito). |
| Line 43: | Line 43: |
| Un ''oggetto'' git può essere un ''blob'', un ''tree'', ''commit'' o ''tag''. Guardiamoli uno alla volta: | Un ''oggetto'' git può essere un ''blob'', un ''tree'', ''commit'' o ''tag''. Esaminiamoli uno alla volta: |
| Line 46: | Line 46: |
| * Un '''tree''' è come una cartella, fa referenza ad altri tree e/o blob. Immaginalo come una cartella con file e sottocartelle al suo interno. * Un '''commit''' è una referenza ad un singolo tree, e contiene anche altre meta-informazioni, come il timestamp, l'autore (nome ed email) che ha apportato le modifiche e un puntatore al commit precedente. Generalmente, quando si usa git, si fa riferimento solo ai commit. |
* Un '''tree''' è come una cartella, fa referenza ad altri tree e/o blob. Si può immaginarlo come una cartella con file e sottocartelle al suo interno. * Un '''commit''' è un riferimento ad un singolo tree, e contiene anche altre meta-informazioni, come il timestamp, l'autore (nome ed email) che ha apportato le modifiche e un puntatore al commit precedente. Generalmente, quando si usa git, si fa riferimento solo ai commit. |
| Line 75: | Line 75: |
| Questo comando creerà la cartella {{{hello-2.6/}}}. Adessim entriamo nella cartella ed iniziamo a giocare con ''git'' :) | Questo comando creerà la cartella {{{hello-2.6/}}}. Adesso entriamo nella cartella ed iniziamo a giocare con ''git'' :) |
| Line 85: | Line 85: |
| L'opzione {{{--global}}} fa in modo che il cambiamento sia globale, ad esempio per ogni repository git sul tuo computer lui scrivere le informazioni in {{{~/.gitconfig}}}. Controlla questo file, dopo che avrai eseguito questi due comandi. Vedrai le informazioni che hai fornito. L'username e l'e-mail possono anche essere cambiate in base al repository: in questo caso, puoi farlo dopo aver creato il repository, e senza l'opzione {{{--global}}}. Senza {{{--global}}}, lui inserirà le informazioni localmente in {{{./.git/config}}}. |
L'opzione {{{--global}}} fa in modo che il cambiamento sia globale, ad esempio per ogni repository git sul tuo computer lui scrive le informazioni in {{{~/.gitconfig}}}. Controlla questo file, dopo che avrai eseguito questi due comandi. Vedrai le informazioni che hai fornito. L'username e l'e-mail possono anche essere cambiate in base al repository: in questo caso, puoi farlo dopo aver creato il repository, e senza l'opzione {{{--global}}}. Senza {{{--global}}}, le informazioni verranno inserite localmente in {{{./.git/config}}}. |
| Line 95: | Line 95: |
| Line 101: | Line 102: |
| {{{git init}}} semplicemente crea una cartella {{{.git/}}}, come alcuni valori di default. Per vedere lo stato di un repository, lancia: | {{{git init}}} semplicemente crea una cartella {{{.git/}}}, con alcuni valori di default. Per vedere lo stato di un repository, lancia: |
| Line 107: | Line 108: |
| Ti mostrarà i file monitorati e non, e lo stato dell'index. In più, ti mostrerà in qualche ''branch'' sei (spiegerò i branch più tardi). | Tale comando mostra i file monitorati e non, e lo stato dell'index. In più, ti mostrerà in qualche ''branch'' sei (spiegherò i branch più tardi). |
| Line 119: | Line 120: |
| Noi possiamo ancora rimuovere file o cartelle dall'index, senza lasciare tracce nella cronologia. Facciamolo! rimuoviamo il file We could still remove things from the index, without leaving traces in the repository history. Let's do it! Let's remove {{{AUTHORS}}} dall'index e rimettiamo nello stato di "non tracciato" |
Possiamo ancora rimuovere file o cartelle dall'index, senza lasciare tracce nella cronologia. Facciamolo! rimuoviamo il file {{{AUTHORS}}} dall'index e rimettiamo nello stato di "non tracciato" |
| Line 136: | Line 136: |
| Questo comando aprirà il tuo {{{$EDITOR}}} (il mio è {{{nano}}}, controlla il tuo), dove tu dovrai scrivere un messaggio di commit. Se tu non ne scrivi uno, il commit verrà annullato (si, tu '''devi''' inserire un messaggio di commit) | Questo comando aprirà il proprio {{{$EDITOR}}} (il mio è {{{nano}}}, controlla il tuo), in cui va scritto un messaggio di commit. Se non ne scrivi uno, il commit verrà annullato (si, tu '''devi''' inserire un messaggio di commit) |
| Line 145: | Line 145: |
| Ti verrà mostrato il committer(l'autore del commit, con le informazioni inserite prima), il timestamp, e l'hash del commit. | Ti verrà mostrato il committer (l'autore del commit, con le informazioni inserite prima), il timestamp, e l'hash del commit. |
| Line 153: | Line 154: |
| Aprirà automaticamente {{{$PAGER}}} e mostrerà il contenuto del tuo ultimo commit. {{{git show}}} accetta anche un hash come argomento. Il mio commit ha hash: 11aab8486d20490b16b1b7d847e1cb1e4f7aa2fe . Che è differente dal uno dei tuoi. Non è necessario scrivere l'hash completo --normalmente bastano i primi 7,8 caratteri. Quindi possiamo lanciare: | Aprirà automaticamente {{{$PAGER}}} e mostrerà il contenuto del tuo ultimo commit. {{{git show}}} accetta anche un hash come argomento. Il mio commit ha hash: 11aab8486d20490b16b1b7d847e1cb1e4f7aa2fe . Che è differente da quello dei tuoi. Non è necessario scrivere l'hash completo: normalmente bastano i primi 7,8 caratteri. Quindi possiamo lanciare: |
| Line 159: | Line 160: |
| {{{git}}} supporta anche un numero di nomi simbolici, ma non verranno spiegati ora in quanto credo non siano argomenti "di base" da poter essere spiegati in questa sessione (Sto parlando di {{{HEAD}}}, {{{HEAD^}}}, {{{HEAD~2}}} e così via) Quindi, abbiamo rimosso {{{AUTHORS}}} dal nostro repository... poveracci! nessun merito al loro lavoro! Correggiamo No credit for their work! possiamo correggere questo problema: |
{{{git}}} supporta anche un numero di nomi simbolici, ma non verranno spiegati ora in quanto credo non siano argomenti "di base" da poter essere spiegati in questa sessione (sto parlando di {{{HEAD}}}, {{{HEAD^}}}, {{{HEAD~2}}} e così via). Quindi, abbiamo rimosso {{{AUTHORS}}} dal nostro repository... poveracci! nessun merito al loro lavoro! Possiamo correggere questo problema: |
| Line 170: | Line 171: |
| Ora, abbiamo bisogno di moficare alcuni file, guarda le differenze, e commitale. Prima pretendiamo che abbiamo scritto un pezzo di codice. | Ora, abbiamo bisogno di moficare alcuni file, guardare le differenze, e commitarle. Prima fingiamo di aver scritto un pezzo di codice. |
| Line 174: | Line 175: |
| Ora, {{{git status}}}. Vedrai le prime due linee indicate con ''modified''(modificato). Puoi vedere le differenze che hai introdotto: | Ora, {{{git status}}}. Vedrai le prime due linee indicate con ''modified''(modificato). Per vedere le differenze introdotte: |
| Line 182: | Line 183: |
| Se sei felice con quste modifiche, committiamo!. If you're happy with the diff, let's commit it. È possibile lanciare {{{git add}}} uno per uno e committare {{{git commit}}} oppure usare soltanto: |
Se queste modifiche vanno bene, committiamo! È possibile lanciare {{{git add}}} uno per uno e committare {{{git commit}}} oppure usare soltanto: |
| Line 190: | Line 189: |
| L'argomento {{{-a}}} aggiungerà tutto all'index ( ma solo i file tracciati, quelli non tracciati non saranno toccati. Vedrai: | L'argomento {{{-a}}} aggiungerà tutto all'index (ma solo i file tracciati, quelli non tracciati non saranno toccati). Vedrai: |
| Line 197: | Line 196: |
| ''master'' è il branch in cui siamo ora. La stringa dopo di quello è l'hash del commit --puoi usarla in molti comandi ({{{git show <commit>}}}, {{{git log <commit>}}}, etc). E dopo, vi è il messaggio di commit e le statistiche dei cambiamenti apportati (diffstats). | ''master'' è il branch in cui siamo ora. La stringa dopo di quello è l'hash del commit, puoi usarla in molti comandi ({{{git show <commit>}}}, {{{git log <commit>}}}, etc). E dopo, vi è il messaggio di commit e le statistiche dei cambiamenti apportati (diffstats). |
| Line 203: | Line 202: |
| Pensa al repository git come ad un fiume. Ad un certo punto, lo sviluppo può divergere dal "flusso principale" e rimanere solo lì, oppure Think of your git repository as a river. At a certain point, development can diverge from the ''main flow'' and it can stay on its own, oppure unirsi di nuovo al fiume originale. Ora il nostro ''master'' è ''il fiume principale''. |
Pensa al repository git come ad un fiume. Ad un certo punto, lo sviluppo può divergere dal "flusso principale" e rimanere solo lì, oppure unirsi di nuovo al fiume originale. Ora il nostro ''master'' è ''il fiume principale''. |
| Line 249: | Line 247: |
| Puoi usare un'interfaccia grafica ( come ad esempio ''gitg'' o ''gitk''), o qualcosa da linea di comando ({{{git show-branch}}}) Per vedere come i due branch sono divergenti. Visto che le gui sono facili da usare, useremo la riga di comando :D) | Puoi usare un'interfaccia grafica ( come ad esempio ''gitg'' o ''gitk''), o qualcosa da linea di comando ({{{git show-branch}}}) Per vedere come i due branch sono divergenti. Visto che le gui sono facili da usare, useremo la riga di comando :D |
| Line 255: | Line 253: |
| Vedrai che i due branch hanno un commit inziale in comune, ma apparte questo hanno commit differenti. Quindi uniamo i cambiamenti di "debian" in "master" | Vedrai che i due branch hanno un commit inziale in comune, ma a parte questo hanno commit differenti. Quindi uniamo i cambiamenti di "debian" in "master" |
| Line 271: | Line 269: |
| Sarebbe utile lanciare {{{git mergetool}}} dopo il merge, per risolvere i conflitti. Userà uno dei possibili programmi per gestire i conflitti. Non voglio entrare nei dettagli --in ogni caso è sempre meglio risolvere i conflitti manualmente. | Sarebbe utile lanciare {{{git mergetool}}} dopo il merge, per risolvere i conflitti. Userà uno dei possibili programmi per gestire i conflitti. Non voglio entrare nei dettagli, in ogni caso è sempre meglio risolvere i conflitti manualmente. |
| Line 318: | Line 316: |
| Suppomiamo che io trovi qualcosa che non mi piace nel mio {{{git log}}}. Per esempio diciamo che è il (mio) commit 2ba81dfaeb919e6a0c634be54fe363b11487d65a , quello con cui ho aggiunto la cartella {{{debian/}}} directory. Ricordati che gli hash sono diffenti per ciascuna persona, quindi guarda i log per vedere il tuo. | Supponiamo che io trovi qualcosa che non mi piace nel mio {{{git log}}}. Per esempio diciamo che è il (mio) commit 2ba81dfaeb919e6a0c634be54fe363b11487d65a, quello con cui ho aggiunto la cartella {{{debian/}}}. Ricordati che gli hash sono diffenti per ciascuna persona, quindi guarda i log per vedere il tuo. |
| Line 328: | Line 326: |
| {{{$EDITOR}}} (''nano'', ''vim'', ecc) si aprirà di nuovo. C'è un messaggio di default; puoi lasciarlo così com'è, o spiegare (in un modo migliore) perchè stai ripristinano i cambiamenti. Per semplicità lasciamolo intantto. Salva il messaggio ed esci dall'editor |
{{{$EDITOR}}} (''nano'', ''vim'', ecc) si aprirà di nuovo. C'è un messaggio di default; puoi lasciarlo così com'è, o spiegare (in un modo migliore) perchè stai ripristinano i cambiamenti. Per semplicità lasciamolo intatto. Salva il messaggio ed esci dall'editor. |
| Line 340: | Line 338: |
| Questo significa che anche il rispristino è un commit. Con un Committer, un Autore, un Timestamp ed un Hash. Potresti anche ripristinare un ripristino ( ma è meglio non farlo ) '''NOTA:''' Ripristinare un merge non è semplice. Devi specificare anche il commit superiore. Documentati sull'opzione {{{-m}}} di {{{git revert}}}. Che ha anche qualche brutto effetto collaterale (IMHO), quindi non fare nessun merge se non sei assolutamente sicuro di poterlo fare. |
Questo significa che anche il rispristino è un commit. Con un Committer, un Autore, un Timestamp ed un Hash. Potresti anche ripristinare un ripristino (ma è meglio non farlo). '''NOTA:''' Ripristinare un merge non è semplice. Devi specificare anche il commit superiore. Documentati sull'opzione {{{-m}}} di {{{git revert}}}. Che ha anche qualche brutto effetto collaterale (IMHO), quindi non fare nessun merge se non sei assolutamente sicuro di poterlo fare. |
| Line 350: | Line 348: |
| Ho preparato un repository online per i sorgenti di GNU Hello che stiamo usando. Questo è normalmente quello che trovarete per i progetti esistenti: un repository online. Puoi copiare i loro contenuti (clonarli), usa il comando {{{git clone}}}. Quindi cloniamo il repository, (ah, prima di fare ciò esci dalla cartella {{{hello-2.6/}}}): | Ho preparato un repository online per i sorgenti di GNU Hello che stiamo usando. Questo è normalmente quello che trovarete per i progetti esistenti: un repository online. Puoi copiare i loro contenuti (clonarli), usa il comando {{{git clone}}}. Quindi cloniamo il repository, (ah, prima di farlo esci dalla cartella {{{hello-2.6/}}}): |
| Line 369: | Line 367: |
| È un repository pulito, ma è stato preso dal web. Se fosse stato un vero repository, probabilmente non avrebbe mostrato solo un commit o solo un branch. Ora, vediamo l'indirizzo del repository. Puoi ottenere o impostare l'indirizzo da dove prendere il repository con {{{git remote}}}. C'è il ''remote''di default, chiamato ''origin''. È anche dove '''i push''' hanno luogo. Diamo un'occhiata: |
È un repository pulito, ma è stato preso dal web. Se fosse stato un vero repository, probabilmente non avrebbe mostrato solo un commit o solo un branch. Ora, vediamo l'indirizzo del repository. Puoi ottenere o impostare l'indirizzo da dove prendere il repository con {{{git remote}}}. C'è il ''remote'' di default, chiamato ''origin''. È anche dove '''i push''' hanno luogo. Diamo un'occhiata: |
| Line 384: | Line 382: |
| Significa che stiamo syncronizzando dal "Fetch URL", e stiamo pushando dal "Push URL". Questi non devono per forza combaciare. Ad esempio, diciamo che tu stai conservano la versione patchata di un software da qualche parte: puoi recuperarla dal tuo upstream,e pusharla sulla tua posizione. | Significa che stiamo sincronizzando dal "Fetch URL", e stiamo pushando dal "Push URL". Questi non devono per forza combaciare. Ad esempio, diciamo che tu stai conservando la versione patchata di un software da qualche parte: puoi recuperarla dal tuo upstream, e pusharla sulla tua posizione. |
| Line 387: | Line 385: |
| La sintassti è la seguente | La sintassi è la seguente |
| Line 392: | Line 390: |
| Di solito, se vuoi pushare un repository, hai bisogno di usare un url `git+ssh://` o `ssh://`. Un url `git://git.[...]` normalmente non ti permette di pushare. (Per ssere onesti, io non ho mai visto uno che permette di usarlo, ma è meglio dire "è meglio non farlo di norma" che "non farlo"'). | Di solito, se vuoi pushare un repository, hai bisogno di usare un url `git+ssh://` o `ssh://`. Un url `git://git.[...]` normalmente non ti permette di pushare. (Per essere onesti, io non ho mai visto uno che permette di usarlo, ma è meglio dire "è meglio non farlo di norma" che "non farlo"'). |
| Line 398: | Line 396: |
| DOMANDA: Un oggetto tree del commit contiene l'intero tree del progetto o solo i file cambiati. | DOMANDA: Un oggetto tree del commit contiene l'intero tree del progetto o solo i file cambiati? |
| Line 412: | Line 410: |
| RISPOSTA: Si, è coservata li. DOMANDA: il push fallisce se ci sono alcune conflitti? Se è così questo pro può essere un contro perchè un repository considiso (se usato) sarà sempre in uno stato di lavoro. |
RISPOSTA: Si, è conservata li. DOMANDA: Il push fallisce se ci sono conflitti? Se è così questo pro può essere un contro perchè un repository condiviso (se usato) sarà sempre in uno stato di lavoro. |
| Line 418: | Line 416: |
| Per quanto riguarda "i repository consivisi che funzionano sempre", i VCS centralizzati risolvono i conflitti, ma loro lo fanno in modo automatico. Questo porta però a cretture erronee --git, invece, è un tracciatore di contenuti (come dice la parola) "stupido", quindi chiede aiuto ogni volta che ne ha bisogno. Quind, mentre SVN corregge automaticamente glo errori per te, (anche se tu non sai realmente cosa accade nel repository) in git il push fallisce, e tu gestisci i conflitti localmente (e dopo ripushi). DOMANDA: E quindi c'è bisogno solo della cartella {{{.git}}} per ricreare il repository << qual'è il comando per ricrearla? RISPOSTA: Devi solo lanciare {{{git clone}}} dalla directory. Se tu hai, per esempio, {{{.git/}}} per alcuni progetti -- basta rinominarli a {{{project.git}}}, e dopo lanciare "git clone project.git" -- ti ritrovare con la cartella {{{project/}}} con tutto al suo interno. La rinominazione rende tutto più semplice, basta solo fare {{{git clone .git myotherdir}}} (e tutto diventerà {{{myotherdir/}}}) |
Per quanto riguarda "i repository condivisi che funzionano sempre", i VCS centralizzati risolvono i conflitti, ma loro lo fanno in modo automatico. Questo porta però a soluzioni erronee --git, invece, è un tracciatore di contenuti (come dice la parola) "stupido", quindi chiede aiuto ogni volta che ne ha bisogno. Quindi, mentre SVN corregge automaticamente gli errori per te, (anche se tu non sai realmente cosa accade nel repository) in git il push fallisce, e tu gestisci i conflitti localmente (e dopo ripushi). DOMANDA: E quindi c'è bisogno solo della cartella {{{.git}}} per ricreare il repository; qual'è il comando per ricrearla? RISPOSTA: Devi solo lanciare {{{git clone}}} dalla directory. Se tu hai, per esempio, {{{.git/}}} di alcuni progetti -- basta rinominarli a {{{project.git}}}, e dopo lanciare "git clone project.git": ti ritroverai con la cartella {{{project/}}} con tutto al suo interno. La rinominazione rende tutto più semplice, basta solo fare {{{git clone .git myotherdir}}} (e tutto diventerà {{{myotherdir/}}}) |
| Line 430: | Line 427: |
| RISPOSTA: Per ottenere un'informazione specifica puoi usare {{{git config --get}}}. Quindi, {{{git config --global --get user.name}}}. Puoi anche vedere tutte le informazioni con {{{git config -l}}}e puoi modificarle con {{{git config}}}, oppure aprendo con un editor {{~/.gitconfig}}} o {{{./.git/config}}} (o ovunque tu voglia modificare le impostazioni globali o locali) | RISPOSTA: Per ottenere un'informazione specifica puoi usare {{{git config --get}}}. Quindi, {{{git config --global --get user.name}}}. Puoi anche vedere tutte le informazioni con {{{git config -l}}} e puoi modificarle con {{{git config}}}, oppure aprendo con un editor {{~/.gitconfig}}} o {{{./.git/config}}} (o ovunque tu voglia modificare le impostazioni globali o locali). |
| Line 434: | Line 431: |
| RISPOSTA: Si, puoi avere un config seprato per repo, basta evitare l'opzione {{{--global}}}. Ma la questione si apre per altre risposte: Credo che la questione sia circa {{{git filter-branch}}}. Il committer git è incorporato nelogetto Commit (ricorda, ho detto che ha anche metadati). Quindi, quando cambi committer, non puoi lasciare lo stesso hash, esso deve cambiare. Quindi argomenti avanzati come filter-branch (che ti permette di riscrivere la cronologia di un repository), non deve mai essere usato su repository pubblico, perchè significa chreare tonnellate di conflitti because that will mean tons of conflicts, e mal di testa. Tuttavia, è interessante vede come una persone può temporaneamente sovrascrivere l'utente e l'-email configurati. git commit può leggere alcune variabili di embiente: {{{GIT_COMMITTER_NAME}}}, {{{GIT_COMMITTER_EMAIL}}}, {{{GIT_AUTHOR_NAME}}} e {{{GIT_AUTHOR_EMAIL}}}. Queste, se impostate, sovrascriveranno quello che c'è in git config. In generale, per ogni variabile di configurazione, git controllerà, |
RISPOSTA: Si, puoi avere un config separato per repo, basta evitare l'opzione {{{--global}}}. Ma la questione si apre per altre risposte: Credo che la questione sia circa {{{git filter-branch}}}. Il committer git è incorporato nell'oggetto Commit (ricorda, ho detto che ha anche metadati). Quindi, quando cambi committer, non puoi lasciare lo stesso hash, esso deve cambiare. Quindi argomenti avanzati come filter-branch (che ti permette di riscrivere la cronologia di un repository), non deveono mai essere usati su repository pubblico, perchè significa creare tonnellate di conflitti e mal di testa. Tuttavia, è interessante vede come una persone può temporaneamente sovrascrivere l'utente e l'email configurati. git commit può leggere alcune variabili di ambiente: {{{GIT_COMMITTER_NAME}}}, {{{GIT_COMMITTER_EMAIL}}}, {{{GIT_AUTHOR_NAME}}} e {{{GIT_AUTHOR_EMAIL}}}. Queste, se impostate, sovrascriveranno quello che c'è in git config. In generale, per ogni variabile di configurazione, git controllerà, |
| Line 439: | Line 436: |
| {{{~/.gitconfig}}} -> {{{./.git/config}}} -> variabile d'ambiente, se esiste Se configuri qualcosa in {{{./.git/config}}} , questa sovrascriverà quella globale. Se tu configuriuna variabile d'ambiente GIT_* , sovrascriverà anche tutte le altre. |
{{{~/.gitconfig}}} -> {{{./.git/config}}} -> variabile d'ambiente, se esiste. Se configuri qualcosa in {{{./.git/config}}} , questa sovrascriverà quella globale. Se tu configuri una variabile d'ambiente GIT_* , sovrascriverà anche tutte le altre. |
| Line 445: | Line 442: |
| DOMANDA: Come posso ottenere la lista dei file cambiati? git log mostra l'autore, il timestamp, il commento ma io non ho bisogno del contenuto dei file (Ho solo bosogno della loro lista). RISPOSTA: La lista dei file cambiati con ogni file cambiato può essere visto con {{{git log --raw}}}. Ogni comando git ha molte opzioni, e le pagine man sono normalmente tue amiche. Per esempio, è possibile combinare {{{git log}}} con {{{--raw}}} e {{{--pretty}}}, per ottenere un output più carino che usando solo {{{--raw}}} |
DOMANDA: Come posso ottenere la lista dei file cambiati? git log mostra l'autore, il timestamp, il commento ma io non ho bisogno del contenuto dei file (Ho solo bisogno del loro elenco). RISPOSTA: L'elenco dei file modificati può essere visto con {{{git log --raw}}}. Ogni comando git ha molte opzioni, e le pagine man sono normalmente tue amiche. Per esempio, è possibile combinare {{{git log}}} con {{{--raw}}} e {{{--pretty}}}, per ottenere un output più carino che usando solo {{{--raw}}} |
| Line 451: | Line 448: |
| Questo non è "l'uso di base", tuttavia puoi usare una GUI, Io uso gitg avvolte. DOMANDA: Git preserva i permessi dei file di cui tiene traccia o of the managed files o devo usare degli stratagemmi? RISPOSTA: Se preserva i permessi, ma ti notifica anche quando questi vengono cambiati, un commit, ad esempio, può anche consistere solo di un cambio di permessi. |
Questo non è "l'uso di base", tuttavia puoi usare una GUI, Io uso gitg a volte. DOMANDA: Git preserva i permessi dei file di cui tiene traccia o devo usare degli stratagemmi? RISPOSTA: Preserva i permessi, ma ti notifica anche quando questi vengono cambiati, un commit, ad esempio, può anche consistere solo di un cambio di permessi. |
| Line 459: | Line 456: |
| RISPOSTA: Questo è perchè il primo commitm dove abbiamo importato tutto. Di norma è meglio che farecommit "atomici" (volevo dire che questo è solo un buon metodo). Quindi di solito, non dovresti vedere un output così grosso, ad ogni modo, non dovresti avere molti problemi con questo :) | RISPOSTA: Questo è perchè il primo commit dove abbiamo importato tutto. Di norma è meglio che fare commit "atomici" (volevo dire che questo è solo un buon metodo). Quindi di solito, non dovresti vedere un output così grosso, ad ogni modo, non dovresti avere molti problemi con questo :) |
| Line 465: | Line 462: |
| DOMANDA: C'è un modo per semplificare: {{{git add}}} + {{{git commit -m}}} ? O devo lanciarli uno ad uno? | DOMANDA: C'è un modo per semplificare: {{{git add}}} + {{{git commit -m}}} ? O devo lanciarli uno ad uno? |
| Line 473: | Line 470: |
| DOMANDA: ad esempio io ho una applicazione web sotto git e voglio distribuirla con/senza cartella git. Qual'è il miglio modo per farlo. RISPOSTA: La stessa risposta di prima: impostare esplicitamente {{{core.worktree}}} in {{{./.git/config}}} ad una path differente. |
DOMANDA: Ad esempio io ho una applicazione web sotto git e voglio distribuirla con/senza cartella git. Qual'è il miglio modo per farlo? RISPOSTA: La stessa risposta di prima: impostare esplicitamente {{{core.worktree}}} in {{{./.git/config}}} ad un percorso differente. |
| Line 479: | Line 476: |
| RISPOSTA: Si, come ho detto prima, abbiamo toccato un .gitignore vuoto all'interno di una cartella vuoto per fare in modo che git la tracci. | RISPOSTA: Si, come ho detto prima, abbiamo creato con touch un .gitignore vuoto all'interno di una cartella vuota per fare in modo che git la tracci. |
| Line 483: | Line 480: |
| RISPOSTA: Se non succede niente i ripristino non è avvenuto. | RISPOSTA: Se non succede niente il ripristino non è avvenuto. |
| Line 501: | Line 498: |
| DOMANDA: C'è una rettifica sulla questione git+ssh, è opposto a ssh (???) RISPOSTA: Si, c'è una differenza anche qui. Io non ho un caso d'uso tra le mani. Tranne i tecnicismi del protocollo usatp e cosa supporta il server. Non mi viene in mente nessuna differenza dal punto di vista dell'utente. |
DOMANDA: C'è una rettifica sulla questione git+ssh, è opposto a ssh (???) RISPOSTA: Si, c'è una differenza anche qui. Io non ho un caso d'uso tra le mani. Tranne i tecnicismi del protocollo usato e cosa supporta il server. Non mi viene in mente nessuna differenza dal punto di vista dell'utente. |
| Line 507: | Line 504: |
| RISPOSTA: {{{--depth}}} specifica quando cronologia ottenere da un repository. Significa che, per esempio, sei interessato solo alla cronologia recente di un grande progetto ed ha anche le sue limitazioni: per esempio, non puoi clonarlo, o pushare da/dentro di lui. Devo essere onesto, non ho mai usato {{{--depth}}}. Ho solo letto di questa opzione agli inizi, quando ho iniziato a studiare git. | RISPOSTA: {{{--depth}}} specifica quanta cronologia ottenere da un repository. Significa che, per esempio, sei interessato solo alla cronologia recente di un grande progetto ed ha anche le sue limitazioni: per esempio, non puoi clonarlo, o pushare da/dentro di lui. Devo essere onesto, non ho mai usato {{{--depth}}}. Ho solo letto di questa opzione agli inizi, quando ho iniziato a studiare git. |
Translation(s): English - Italiano
Contents
Usare Git
Seminario online tenuto da David Paleino per Debian Women, 25-Nov-2010
Questa è una guida introduttiva all'uso di git. Verranno spiegate le basi per capire il suo funzionamento e il suo uso.
Requisiti
In questa guida si presume che:
si conosca l'uso di base della linea di comando e l'utilizzo di un editor di testo a scelta (emacs, vim, gedit, kate, etc.);
Requisiti tecnici:
Introduzione
Cos'è git? Git è un sistema di Controllo di versione distribuito. La parte importante è Controllo di versione -- significa che è un programma che permette di tenere traccia dei cambiamenti dei file e comparare le differenti "versioni", e fare anche un'altra cosa fantastica, come tornare indietro a precedenti versioni di un certo file.
Git viene usato da molti progetti software moderni, quindi è bene conoscere almeno un po' del suo funzionamento. Non c'è bisogno di andare molto nei dettagli, verrà spiegato solo il suo funzionamento di base e il suo uso generale.
Teoria
sistema di controllo di versione''Distribuito''
Noi abbiamo analizzato git come Sistema di Controllo di Versione, ma git è un VCS Distribuito. Distribuito è un dettaglio dell'architettura di git, che ha alcuni pro e alcuni contro. Ci sono altri "sistemi VCS famosi, come CVS e SVN, chiamati VCS Centralizzati; questi hanno bisogno di avere una connessione al server centrale, per conservare tutti i dati e per eseguire molte operazioni. Pensa al comando log: SVN ha bisogno di connettersi al server e scaricare i dati. Con i Ovviamente anche i VCS Distribuiti hanno i loro difetti, il problema più importante che ho riscontrato è il gran numero di
VCS Distribuiti (e git è uno di questi) ciò non avviene: ogni copia del repository è una copia completa. Questo significa che le operazione sono più veloci, e che soprattutto puoi usare git sul tuo computer locale, senza avere un server.
Il modello di immagazzinamento di git
Ogni oggetto all'interno di un repository git è identificato da una stringa univoca. Questa è chiamata hash. Normalmente è una somma SHA1 di alcune proprietà di cui parleremo più tardi.
Un oggetto git può essere un blob, un tree, commit o tag. Esaminiamoli uno alla volta:
Un blob è un oggetto git su cui sono conservati i dati. Questo è generalmente un file su disco.
Un tree è come una cartella, fa referenza ad altri tree e/o blob. Si può immaginarlo come una cartella con file e sottocartelle al suo interno.
Un commit è un riferimento ad un singolo tree, e contiene anche altre meta-informazioni, come il timestamp, l'autore (nome ed email) che ha apportato le modifiche e un puntatore al commit precedente. Generalmente, quando si usa git, si fa riferimento solo ai commit.
Un tag è solo un modo per segnare un commit come se fosse in un certo modo speciale. Generalmente, i tag vengono usati per segnare commit con i numeri di versione, release e così via.
Se pensiamo al modello di immagazzinamento di git, distinguiamo una "area di lavoro", un "index" e un "repository":
L' area di lavoro è composta dai file presenti nella nostra cartella git
L' index e repository, invece, sono contenuti all'interno di ./.git/ -- qui è dove tutti i repository git risiedono, ed è sufficiente per ricreare il contenuto delle cartelle. Andando oltre, possiamo dire che l' index è come una temporanea area di sosta, dove tu puoi aggiungere i file prima di eseguire il commit. Una volta che il commit è stato eseguito, il contenuto andrà all'interno del repository, e l'azione compiuta verrà conservata nella sua cronologia, se tu non esegui il commit, puoi rimuovere i file dall'index senza lasciare traccia nella cronologia del repository.
Pratica
Creare un repository
Per la parte pratica, ho voluto usare un progetto reale, anzichè creare qualche repository. Ho scelto di usare "GNU Hello", scaricalo da http://ftp.gnu.org/gnu/hello/hello-2.6.tar.gz. Noi creeremo un repository da questo codice sorgente.
Scarichiamo il tarball:
$ wget http://ftp.gnu.org/gnu/hello/hello-2.6.tar.gz
Una volta fatto, spacchettiamolo:
$ tar zxvf hello-2.6.tar.gz
Questo comando creerà la cartella hello-2.6/. Adesso entriamo nella cartella ed iniziamo a giocare con git
Prima di tutto, abbiamo bisogno di configurare il nostro username e la nostra e-mail. Queste informazioni verranno usate nei nostri commit, e saranno visibili nella cronologia del repository. Per fare ciò, usiamo git config. In particolare, visto che siamo dei principianti, vogliamo settare username ed e-mail in modo globale. Quindi lanciamo i comandi:
$ git config --global user.name "Debian Woman Attendant" $ git config --global user.email "attendant@debian.org"
Naturalmente usa i tuoi dati
L'opzione --global fa in modo che il cambiamento sia globale, ad esempio per ogni repository git sul tuo computer lui scrive le informazioni in ~/.gitconfig. Controlla questo file, dopo che avrai eseguito questi due comandi. Vedrai le informazioni che hai fornito.
L'username e l'e-mail possono anche essere cambiate in base al repository: in questo caso, puoi farlo dopo aver creato il repository, e senza l'opzione --global. Senza --global, le informazioni verranno inserite localmente in ./.git/config.
Abbiamo impostato l'username e l'e-mail. Ora, abbiamo bisogno di creare il repository git. Quindi abbiamo una cartella hello-2.6/: entriamoci ed lanciamo:
$ git init
Il risultato sarà qualcosa di simile:
Initialized empty Git repository in /tmp/dw/hello-2.6/.git/
git init semplicemente crea una cartella .git/, con alcuni valori di default. Per vedere lo stato di un repository, lancia:
$ git status
Tale comando mostra i file monitorati e non, e lo stato dell'index. In più, ti mostrerà in qualche branch sei (spiegherò i branch più tardi).
Indexing
Non abbiamo ancora nulla nel repository. Quindi aggiungiamo il codice sorgente:
$ git add .
Il "." è una sintassi dei sistemi Unix-like -- significa "cartella corrente". Quindi in questo modo aggiungiamo tutto il contenuto. Ora, controlla git status di nuovo. Vedrai che qualcosa è cambiato. Quello che vedi ora è lo stato di index.
Possiamo ancora rimuovere file o cartelle dall'index, senza lasciare tracce nella cronologia. Facciamolo! rimuoviamo il file AUTHORS dall'index e rimettiamo nello stato di "non tracciato"
$ git rm --cached AUTHORS
Ora dai di nuovo uno sguardo a git status. Vedrai Changes to be committed(cambiamenti che devono essere committati) (l'index) e Untracked files (file non tracciati).
Committing
Ora vogliamo committarei file nell'index: questo creerà un commit, con un hash, e verrà conservato nella cronologia del repository. Lanciamo:
$ git commit
Questo comando aprirà il proprio $EDITOR (il mio è nano, controlla il tuo), in cui va scritto un messaggio di commit. Se non ne scrivi uno, il commit verrà annullato (si, tu devi inserire un messaggio di commit)
Chiamiamolo "Commit iniziale". Ora, lancia di nuovo git status . I file dall'index sono spariti! Sono stati committati all'interno del repository, e il log è stato conservato.
Puoi vedere i log con:
$ git log
Ti verrà mostrato il committer (l'autore del commit, con le informazioni inserite prima), il timestamp, e l'hash del commit.
Puoi anche vedere l'ultimo commit con:
$ git show
Aprirà automaticamente $PAGER e mostrerà il contenuto del tuo ultimo commit. git show accetta anche un hash come argomento. Il mio commit ha hash: 11aab8486d20490b16b1b7d847e1cb1e4f7aa2fe . Che è differente da quello dei tuoi. Non è necessario scrivere l'hash completo: normalmente bastano i primi 7,8 caratteri. Quindi possiamo lanciare:
$ git show 11aab848
git supporta anche un numero di nomi simbolici, ma non verranno spiegati ora in quanto credo non siano argomenti "di base" da poter essere spiegati in questa sessione (sto parlando di HEAD, HEAD^, HEAD~2 e così via).
Quindi, abbiamo rimosso AUTHORS dal nostro repository... poveracci! nessun merito al loro lavoro! Possiamo correggere questo problema:
$ git add AUTHORS $ git commit -m 'Also add AUTHORS'
-m è una scorciatoia per il messagio -- evita così di aprire $EDITOR
Ora, abbiamo bisogno di moficare alcuni file, guardare le differenze, e commitarle. Prima fingiamo di aver scritto un pezzo di codice.
Aggiungiamo il nostro nome al file AUTHORS
E aggiungiamo anche qualcosa a "?ChangeLog". Quello che vuoi, è solo un esempio.
Ora, git status. Vedrai le prime due linee indicate con modified(modificato). Per vedere le differenze introdotte:
$ git diff
(Opzionalmente, git diff filename mostrerà solo le differenze in quel file.)
Se queste modifiche vanno bene, committiamo! È possibile lanciare git add uno per uno e committare git commit oppure usare soltanto:
$ git commit -a -m "Messaggio a piacere"
L'argomento -a aggiungerà tutto all'index (ma solo i file tracciati, quelli non tracciati non saranno toccati). Vedrai:
[master 3295347] Messaggio a piacere 2 files changed, 5 insertions(+), 0 deletions(-)
master è il branch in cui siamo ora. La stringa dopo di quello è l'hash del commit, puoi usarla in molti comandi (git show <commit>, git log <commit>, etc). E dopo, vi è il messaggio di commit e le statistiche dei cambiamenti apportati (diffstats).
Branching
Cos'è un branch?
Pensa al repository git come ad un fiume. Ad un certo punto, lo sviluppo può divergere dal "flusso principale" e rimanere solo lì, oppure unirsi di nuovo al fiume originale. Ora il nostro master è il fiume principale.
Creiamo un branch, chiamiamolo debian:
$ git branch debian
Per cambiare a questo nuovo branch lancia:
$ git checkout debian
Una scorciatoia per entrambi i comandi è:
$ git checkout -b debian
Ok, ora siamo nel branch debian. Per controllare se è vero, esegui git branch, senza argomenti. Ti mostrerà i branch locali, e un * anteposto ti mostrerò quello in cui sei ora.
Per tornare indietro al branch principale, esegui: git checkout master.
Ma per il momento rimarremo sul branch debian: *debian. All'interno di questo branch faremo il lavoro di pacchettizzazione.
Quindi, creiamo una cartella debian/. Se la cartella è vuota, git status non la mostrerà, è il comportamento previsto: git non tiene traccia delle cartelle vuote. Per ingannarlo a fare queto puoi aggiungere un file vuoto alla cartella. Io normalmente aggiungo un .gitignore (è un file speciale usato da git), per lasciargli tracciare una cartella vuota. Quindi eseguiamo questo:
$ mkdir debian $ touch debian/.gitignore
Ora git status mostrerà la non-tracciata debian/. Aggiungila e committala.
Ora torniamo al branch master
$ git checkout master
Ora vogliamo far divergere questi due branch, per simulare un branch reale: cambia tutti i file che vuoi, e committa i cambiamenti.
Puoi usare un'interfaccia grafica ( come ad esempio gitg o gitk), o qualcosa da linea di comando (git show-branch) Per vedere come i due branch sono divergenti. Visto che le gui sono facili da usare, useremo la riga di comando
$ git show-branch
Vedrai che i due branch hanno un commit inziale in comune, ma a parte questo hanno commit differenti. Quindi uniamo i cambiamenti di "debian" in "master"
$ git merge debian
Vedrai qualcosa come:
Merge made by recursive. 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 debian/.gitignore
E ora ci saranno dei "conflitti". Se in debian abbiamo cambiato uno dei file cambiati prima del merge, questi potrebbero andare in conflitto. Sarebbe utile lanciare git mergetool dopo il merge, per risolvere i conflitti. Userà uno dei possibili programmi per gestire i conflitti. Non voglio entrare nei dettagli, in ogni caso è sempre meglio risolvere i conflitti manualmente.
Abbiamo unito debian in master. Ora vediamo i log, dovresti vedere qualcosa come:
commit cdfd20167aa05f74f4785ef7aa03355d51add5b3
Merge: 7e9ff3a 2ba81df
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:45:28 2010 +0100
Merge branch 'debian'
commit 7e9ff3a18dc114b4ce1e1a96f1dd3ecd696f064d
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:43:49 2010 +0100
New author
commit 2ba81dfaeb919e6a0c634be54fe363b11487d65a
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:42:42 2010 +0100
add debian/
commit 3295347b1dbd7b5925dca7fcc6858af51a710ada
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:32:55 2010 +0100
Some message
commit f6aa148a5ce1331de6d17e770a8efbb98ad32344
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:11:57 2010 +0100
Also add AUTHORS
commit 11aab8486d20490b16b1b7d847e1cb1e4f7aa2fe
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:03:42 2010 +0100
Initial commit
Ripristino
L'ultima cosa che voglio spiegare per quanto riguarda la parte della guida in locale è git revert.
Supponiamo che io trovi qualcosa che non mi piace nel mio git log. Per esempio diciamo che è il (mio) commit 2ba81dfaeb919e6a0c634be54fe363b11487d65a, quello con cui ho aggiunto la cartella debian/. Ricordati che gli hash sono diffenti per ciascuna persona, quindi guarda i log per vedere il tuo.
Dunque, non mi piace. Cosa dovrei fare ora? Posso usare il comando git revert.
Questo comando prende semplicemente il cambiamento (diff) da un commit, e lo applica al contrario, e lascia i conflitti, se ce ne sono, proviamolo:
$ git revert 2ba81dfaeb919e6a0c634be54fe363b11487d65a
$EDITOR (nano, vim, ecc) si aprirà di nuovo. C'è un messaggio di default; puoi lasciarlo così com'è, o spiegare (in un modo migliore) perchè stai ripristinano i cambiamenti. Per semplicità lasciamolo intatto. Salva il messaggio ed esci dall'editor.
Vedrai:
Finished one revert. [master 37ce99f] Revert "add debian/" 0 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 debian/.gitignore
Questo significa che anche il rispristino è un commit. Con un Committer, un Autore, un Timestamp ed un Hash. Potresti anche ripristinare un ripristino (ma è meglio non farlo).
NOTA: Ripristinare un merge non è semplice. Devi specificare anche il commit superiore. Documentati sull'opzione -m di git revert. Che ha anche qualche brutto effetto collaterale (IMHO), quindi non fare nessun merge se non sei assolutamente sicuro di poterlo fare.
Processo Distribuito
Git è un VCS distribuito, è una parete fondamentale. Ti permette di condividere il tuo lavoro, il tuo sviluppo, con altre persone quindi mettiamo da parte il repository.
Clonare e Pushare
Ho preparato un repository online per i sorgenti di GNU Hello che stiamo usando. Questo è normalmente quello che trovarete per i progetti esistenti: un repository online. Puoi copiare i loro contenuti (clonarli), usa il comando git clone. Quindi cloniamo il repository, (ah, prima di farlo esci dalla cartella hello-2.6/):
$ git clone git://gitorious.org/debian-women/hello.git
Vedrai qualcosa come:
Cloning into hello... remote: Counting objects: 263, done. remote: Compressing objects: 33% (54/16Receiving objects: 6% (16/263), 52.00 remote: Compressing objects: 50% Receiving objects: 9% (24/263), 108.00 KiB |remote: Compressing objReceiving objects: 10% (27/263), 108.00 KiB | 93 KiB/s remote: Compressing objects: 100% (161/161), done. remote: Total 263 (delta 101), reused 263 (delta 101) Receiving objects: 100% (263/263), 626.93 KiB | 120 KiB/s, done. Resolving deltas: 100% (101/101), done.
Ora, entra in hello/, e inizia a curiosare un po' con git log, git show...
È un repository pulito, ma è stato preso dal web. Se fosse stato un vero repository, probabilmente non avrebbe mostrato solo un commit o solo un branch.
Ora, vediamo l'indirizzo del repository. Puoi ottenere o impostare l'indirizzo da dove prendere il repository con git remote. C'è il remote di default, chiamato origin. È anche dove i push hanno luogo. Diamo un'occhiata:
$ git remote show origin
Per ora, curiamoci solo di queste due linee:
Fetch URL: git://gitorious.org/debian-women/hello.git Push URL: git://gitorious.org/debian-women/hello.git
Significa che stiamo sincronizzando dal "Fetch URL", e stiamo pushando dal "Push URL". Questi non devono per forza combaciare. Ad esempio, diciamo che tu stai conservando la versione patchata di un software da qualche parte: puoi recuperarla dal tuo upstream, e pusharla sulla tua posizione.
Possiamo aggiungere un remote evitando di rimuovere il tuo lavoro precedente. Per questo, è possibile usare git remote add. La sintassi è la seguente
git remote add <remote_name> <remote_url>
Di solito, se vuoi pushare un repository, hai bisogno di usare un url git+ssh:// o ssh://. Un url git://git.[...] normalmente non ti permette di pushare. (Per essere onesti, io non ho mai visto uno che permette di usarlo, ma è meglio dire "è meglio non farlo di norma" che "non farlo"').
git remote add è utile quando stai creando un nuovo repository, ovvero quando non devi clonare da nessuna parte.
Domanda e Risposte
DOMANDA: Un oggetto tree del commit contiene l'intero tree del progetto o solo i file cambiati?
RISPOSTA: Un oggetto tree del commit rappresenta l'intero repository ad un certo punto del tempo, quindi contiene le referenze dell'intero progetto
DOMANDA: Gli oggetti vanno nell'index con: git commit?
RISPOSTA: No, git commit creata un commit che viene inserito nel repository. Ne ho parlato prima, ma questa immagine spiega meglio il concetto: http://osteele.com/images/2008/git-transport.png.
DOMANDA: Se ricopio i file senza la cartella .git perdo tutta la cronologia?
RISPOSTA: Si, la cartella .git è l'unica che contiene l'intera cronologia. E una persone ha bisogno dell'intera cartella .git per ricreare il repository .
DOMANDA: L'index è presenta nella cartella .git?
RISPOSTA: Si, è conservata li.
DOMANDA: Il push fallisce se ci sono conflitti? Se è così questo pro può essere un contro perchè un repository condiviso (se usato) sarà sempre in uno stato di lavoro.
RISPOSTA: Si, il push fallisce. Ho detto prima che un grande numero di conflitti è un problema nei VCS distribuiti, ma git ti permette di risolverli e pushare.
Per quanto riguarda "i repository condivisi che funzionano sempre", i VCS centralizzati risolvono i conflitti, ma loro lo fanno in modo automatico. Questo porta però a soluzioni erronee --git, invece, è un tracciatore di contenuti (come dice la parola) "stupido", quindi chiede aiuto ogni volta che ne ha bisogno.
Quindi, mentre SVN corregge automaticamente gli errori per te, (anche se tu non sai realmente cosa accade nel repository) in git il push fallisce, e tu gestisci i conflitti localmente (e dopo ripushi).
DOMANDA: E quindi c'è bisogno solo della cartella .git per ricreare il repository; qual'è il comando per ricrearla?
RISPOSTA: Devi solo lanciare git clone dalla directory. Se tu hai, per esempio, .git/ di alcuni progetti -- basta rinominarli a project.git, e dopo lanciare "git clone project.git": ti ritroverai con la cartella project/ con tutto al suo interno. La rinominazione rende tutto più semplice, basta solo fare git clone .git myotherdir (e tutto diventerà myotherdir/)
DOMANDA: come posso trovare i settaggi correnti per l'username e l'e-mail globale? (Voglio solo conoscere le informazioni prima di cambiarle
) ~/.gitconfig ?
RISPOSTA: Per ottenere un'informazione specifica puoi usare git config --get. Quindi, git config --global --get user.name. Puoi anche vedere tutte le informazioni con git config -l e puoi modificarle con git config, oppure aprendo con un editor } o ./.git/config (o ovunque tu voglia modificare le impostazioni globali o locali).
DOMANDA: Posso patchare il valore di user.name, ecc all'interno dei file gestiti da git?
RISPOSTA: Si, puoi avere un config separato per repo, basta evitare l'opzione --global. Ma la questione si apre per altre risposte: Credo che la questione sia circa git filter-branch. Il committer git è incorporato nell'oggetto Commit (ricorda, ho detto che ha anche metadati). Quindi, quando cambi committer, non puoi lasciare lo stesso hash, esso deve cambiare. Quindi argomenti avanzati come filter-branch (che ti permette di riscrivere la cronologia di un repository), non deveono mai essere usati su repository pubblico, perchè significa creare tonnellate di conflitti e mal di testa.
Tuttavia, è interessante vede come una persone può temporaneamente sovrascrivere l'utente e l'email configurati. git commit può leggere alcune variabili di ambiente: GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, GIT_AUTHOR_NAME e GIT_AUTHOR_EMAIL. Queste, se impostate, sovrascriveranno quello che c'è in git config. In generale, per ogni variabile di configurazione, git controllerà, in ordine:
~/.gitconfig -> ./.git/config -> variabile d'ambiente, se esiste.
Se configuri qualcosa in ./.git/config , questa sovrascriverà quella globale. Se tu configuri una variabile d'ambiente GIT_* , sovrascriverà anche tutte le altre.
./.git/config estende ~/.gitconfig. Significa che non si deve copiare tutto il contenuto dalla configurazione globale.
DOMANDA: Come posso ottenere la lista dei file cambiati? git log mostra l'autore, il timestamp, il commento ma io non ho bisogno del contenuto dei file (Ho solo bisogno del loro elenco).
RISPOSTA: L'elenco dei file modificati può essere visto con git log --raw. Ogni comando git ha molte opzioni, e le pagine man sono normalmente tue amiche. Per esempio, è possibile combinare git log con --raw e --pretty, per ottenere un output più carino che usando solo --raw
Lo stesso per git show: possiamo formattare il risultato con --pretty
Questo non è "l'uso di base", tuttavia puoi usare una GUI, Io uso gitg a volte.
DOMANDA: Git preserva i permessi dei file di cui tiene traccia o devo usare degli stratagemmi?
RISPOSTA: Preserva i permessi, ma ti notifica anche quando questi vengono cambiati, un commit, ad esempio, può anche consistere solo di un cambio di permessi.
DOMANDA: git show mostra un file enorme. Nessun commento su questo?
RISPOSTA: Questo è perchè il primo commit dove abbiamo importato tutto. Di norma è meglio che fare commit "atomici" (volevo dire che questo è solo un buon metodo). Quindi di solito, non dovresti vedere un output così grosso, ad ogni modo, non dovresti avere molti problemi con questo
DOMANDA: Posso solo copiare la cartella sul mio webserver e lasciare che gli altri la clonino su http://myserver/hello-2.6 ?
RISPOSTA: Solo se non hai bisogno dei file attuali in quella cartella, ma di solito è meglio condividere solo la cartella .git con il nome project.git. Questo viene di solito chiamato "bare repository".
DOMANDA: C'è un modo per semplificare: git add + git commit -m ? O devo lanciarli uno ad uno?
RISPOSTA: Si c'è. Se vuoi committare tutti i file puoi usare l'opzione -a di git commit. Quindi, git commit -a -m "Messagio" committera tutto quello già tracciato.
DOMANDA: Una delle cose che mi sembrano strane è avere il repository come parte dell'area di lavoro. È più semplice avere un repo in una cartella differente? O dove creare repository addizionali?
RISPOSTA: Puoi, ma è un po' più complicato di così. Leggi la manpage di git-config nella sezione core.worktree.
DOMANDA: Ad esempio io ho una applicazione web sotto git e voglio distribuirla con/senza cartella git. Qual'è il miglio modo per farlo?
RISPOSTA: La stessa risposta di prima: impostare esplicitamente core.worktree in ./.git/config ad un percorso differente.
DOMANDA: Ho creato una cartella vuota (test1) ma git status non visualizza niente, quindi ho fatto echo test > test1/testfile e l'output di git status mi restituisce # test1/ ma nessun testfile. È un comportamento aspettato?
RISPOSTA: Si, come ho detto prima, abbiamo creato con touch un .gitignore vuoto all'interno di una cartella vuota per fare in modo che git la tracci.
DOMANDA: Cosa succede se ripristino un cambiamento, in un branch che non è lo stesso che hai estratto?
RISPOSTA: Se non succede niente il ripristino non è avvenuto.
DOMANDA: Se prendo un branch, faccio il merge, ma voglio ripstinarlo, come trovo l'hash?
RISPOSTA: git log è la soluzione.
DOMANDA: l'opzione clone, clona solo il branch master... o anche gli altri?
RISPOSTA: git clone clona solo il branch master. Significa che, gli altri branch verranno recuperati, ma nessun branch locale verrà creato per loro. Per correggere questo problema, solitamento lancio questo comando per ogni branch che mi interessa.
$ git checkout -b mybranch -t origin/mybranch
(-t origin/mybranch significa "traccia mybranch da origin")
DOMANDA: c'è differenza tra git+ssh:// e git:// ?
RISPOSTA: Si c'è. git:// è un "protocollo stupido", e non supporta l'autenticazione. Quindi nel primo caso, questo protocollo viene incapsulato in SSH -- un po' come svn+ssh:// o cvs+ssh:// o altri. Nel secondo caso, stai usando il protocollo git direttamente, senza supporto per l'autenticazione.
DOMANDA: C'è una rettifica sulla questione git+ssh, è opposto a ssh (???)
RISPOSTA: Si, c'è una differenza anche qui. Io non ho un caso d'uso tra le mani. Tranne i tecnicismi del protocollo usato e cosa supporta il server. Non mi viene in mente nessuna differenza dal punto di vista dell'utente.
DOMANDA: Quali sono le limitazione di un repo git in locale clonato con --depth 1, sarò comunque in grado di cambiare branch e avrà effetto su un'età più limitata per quanto riguarda la cronologia e git pull?
RISPOSTA: --depth specifica quanta cronologia ottenere da un repository. Significa che, per esempio, sei interessato solo alla cronologia recente di un grande progetto ed ha anche le sue limitazioni: per esempio, non puoi clonarlo, o pushare da/dentro di lui. Devo essere onesto, non ho mai usato --depth. Ho solo letto di questa opzione agli inizi, quando ho iniziato a studiare git.
