[Semi OT] – Git + LaTeX: recupero versione precedente

  • Creatore
    Topic
  • #87411
    Liverpool
    Partecipante
      Up
      0
      Down
      ::


      Ammetto di essere un po’ OT, ma visto che qui c’è più di un esperto di Git e che io sono di coccio, prima di buttarmi alla cieca vorrei capire un po’ meglio come funziona.
      Voglio lavorare su un progetto costituito dal sorgente (s), il file di classe (c) e alcune immagini (i1) e (i2). Il problema è che strada facendo modificherò sia il sorgente sia il file di classe più volte e aggiungerò le immagini una alla volta. La mia domanda è: come faccio a tornare ad una versione precedente del sorgente in modo tale che anche il file di classe e le immagini siano le stesse che c’erano al momento del commit? Mi spiego con un esempio nel quale ogni riga corrisponde ad una versione differente e in ogni versione sono riportati i file che ho modificato e quindi aggiunto al commit.
      `
      1. (s) + (c)
      2. (s)
      3. (s) + (i1)
      4. (s) + (c)
      5. (s)
      6. (s) + (c) + (i2)
      7. (s)`
      Supponiamo che io voglia tornare alla versione 5. Io voglio che il file di classe e le immagini siano gli stessi che c’erano al momento di caricare la versione 6, cioè (c) della versione 4 e (i1) della versione 3. Come posso fare? Devo caricare in ogni commit (c) e (i1) anche se non li ho modificati?

      Grazie

    Visualizzazione 7 filoni di risposte
    • Autore
      Risposte
      • #87412
        Up
        0
        Down
        ::


        Non sono sicuro di aver capito bene la domanda: vuoi riportare l’intero repository al commit 5, e non un singolo file? In questo caso basta usare
        `git checkout hashdelcommit5`
        Se vuoi riportare un singolo file a quel commit
        `git checkout hashdelcommit5 — sorgente`
        come spiegato nella guida. Il primo comando in effetti non l’ho segnalato però può essere comodo.

        Noto solo ora di aver fatto un piccolo disastro nelle ultime modifiche alla guida: per i comandi in linea ho usato [tt]\textt{}[/tt], ma di conseguenza i doppi trattini nel PDF finale appaiono come un unico trattino. Devo sistemare questo problema

      • #87413
        Liverpool
        Partecipante
          Up
          0
          Down
          ::

          Elrond” post=86872Noto solo ora di aver fatto un piccolo disastro nelle ultime modifiche alla guida: per i comandi in linea ho usato [tt]\textt{}[/tt], ma di conseguenza i doppi trattini nel PDF finale appaiono come un unico trattino. Devo sistemare questo problema

          Apri e chiudi le graffe tra i due trattini.

          Sì, voglio tornare alla versione 5, ma nel commit 5 ho aggiunto solo (s), perché (c) non l’ho modificato. Quando torno indietro, Git capisce che deve prendere (c) dalla versione 4 e (i1) dalla versione 3?

          Ciao

        • #87414
          Up
          0
          Down
          ::

          Liverpool” post=86873

          Noto solo ora di aver fatto un piccolo disastro nelle ultime modifiche alla guida: per i comandi in linea ho usato [tt]\textt{}[/tt], ma di conseguenza i doppi trattini nel PDF finale appaiono come un unico trattino. Devo sistemare questo problema

          Apri e chiudi le graffe tra i due trattini.

          Grazie 🙂

          Liverpool” post=86873Sì, voglio tornare alla versione 5, ma nel commit 5 ho aggiunto solo (s), perché (c) non l’ho modificato. Quando torno indietro, Git capisce che deve prendere (c) dalla versione 4 e (i1) dalla versione 3?

          Sì, certo, ogni commit in git scatta una fotografia dell’intero repository, se tu gli dici di tornare al commit 5 con il primo comando che ti ho detto lui ripristina tutti i file presenti all’epoca, il file di classe apparirà come era stato modificato nel commit 4 e l’immagine1 nella commit 3.

          Però, una precisazione: ho provato ora e
          `git checkout hashdelcommit5`
          sembra che riporti realmente il repository indietro al commit 5, nel senso che i commit 6 e 7 spariscono dalla cronologia. Una cosa più prudente da fare è
          `git checkout -b nuovoramo hashdelcommit5`
          che crea un nuovo ramo a partire dal commit 5. Se invece vuoi rimanere sempre nello stesso ramo, mantenere la cronologia intatta e semplicemente ripristinare tutti i file
          `git checkout hashdelcommit5 — .`
          che è equivalente a dare un
          `git checkout hashdelcommit5 — sorgente classe immagine1 immagine`
          perché il punto è un alias della cartella corrente

        • #87415
          Liverpool
          Partecipante
            Up
            0
            Down
            ::

            Elrond” post=86874Sì, certo, ogni commit in git scatta una fotografia dell’intero repository, se tu gli dici di tornare al commit 5 con il primo comando che ti ho detto lui ripristina tutti i file presenti all’epoca, il file di classe apparirà come era stato modificato nel commit 4 e l’immagine1 nella commit 3.

            Allora mi sorge un dubbio: perché dobbiamo aggiungere i file nella staging area prima del [tt]commit[/tt] se comunque Git “scatta una fotografia dell’intero repository”?
            Forse il [tt]commit[/tt] aggiunge fisicamente una copia dei file aggiunti e un semplice riferimento per gli altri presenti nel repository basandosi non su ciò che c’è nella working directory, ma su ciò che è scritto nel suo database?

            Grazie. Ho visto che hai aggiunto l’elenco dei comandi alla fine.
            Ciao

          • #87416
            Up
            0
            Down
            ::

            Liverpool” post=86876

            Sì, certo, ogni commit in git scatta una fotografia dell’intero repository, se tu gli dici di tornare al commit 5 con il primo comando che ti ho detto lui ripristina tutti i file presenti all’epoca, il file di classe apparirà come era stato modificato nel commit 4 e l’immagine1 nella commit 3.

            Allora mi sorge un dubbio: perché dobbiamo aggiungere i file nella staging area prima del [tt]commit[/tt] se comunque Git “scatta una fotografia dell’intero repository”?

            Perché forse mi sono espresso male: il commit scatta una fotografia della staging area, e non qualsiasi file presente nella cartella di lavoro compresi quelli non aggiunti nella staging area. Tutti i file
            mai entrati nella staging area, come i file ignorati, non sono mai ricordati, se torni indietro nella cronologia, cambi ramo e operazioni simili, questi file ignorati rimangono sempre tali e quali. EDIT in realtà l’espressione “il commit scatta una fotografia della staging area” può essere ancora ambigua perché potrebbe far pensare che la fotografia contiene solo i file modificati: no, contiene tutti i file che fino a quel momento sono stati aggiunti al progetto con un [tt]git add[/tt] e poi non sono stati successivamente rimossi.

            Riferendomi a “intero repository” intendevo dire che un commit memorizza lo stato di tutti i file in blocco, in contrapposizione al funzionamento di CVS che ha una cronologia separata per ogni file. Vedi la prima critica qui: http://en.wikipedia.org/wiki/Concurrent_Versions_System#Criticism
            Esempio di Git: https://github.com/giordano/guidagit/commits/master per ogni commit puoi visitare tutti i file presenti all’epoca (pulsante “browse code”)
            Esempio di CVS: http://cvs.savannah.gnu.org/viewvc/auctex/auctex/ ogni file ha la sua revisione. Non so se sia possibile dire “fammi vedere tutti i file all’1 gennaio 2013”, a parte usando i tag (ma non è che uno può creare un tag per ogni commit…) (P.S. fortunatamente da qualche mese anche AUCTeX si è convertito a git).

            Il funzionamento dei vari VCS moderni è molto simile, così come comune è l’interfaccia utente: http://en.wikipedia.org/wiki/Comparison_of_revision_control_software#Basic_commands per ogni operazione, i nomi dei comandi scelti dai vari software sono al più due o tre. Quello che cambia sono le opzioni particolari utilizzate da ciascun comando, da questo punto di vista qualcuno dice che git ne ha troppe 😀 Comunque è impossibile negare che git sia il DVCS che ha avuto maggior successo (considerando i tre grandi git, mercurial, bazaar), qui per esempio c’è una statistica basata su tutti i progetti registrati su Ohloh (oltre mezzo milione): https://www.ohloh.net/repositories/compare Qui un’altra statistica basata sui pacchetti presenti in Debian (quasi 14 mila): http://upsilon.cc/~zack/stuff/vcs-usage/ oltre il 60% dei pacchetti sono mantenuti usando git, invece mercurial e bazaar raccolgono le briciole.

            In generale, i DVCS sono tremendamente utili, ti permettono di lavorare con maggiore libertà perché hai sempre la consapevolezza di poter tornare indietro a uno stato precedente e ti permettono addirittura lavorare contemporaneamente su due binari paralleli, tracciando tutti i cambiamenti compiuti. Dubito che sistemi di backup siano utili da questo punto di vista (per lo sviluppo collaborativo sono del tutto inutili). Sono fermamente convinto che anche gli utenti di *TeX, siano essi autori di documenti (soprattutto quelli più grossi e importanti) o sviluppatori di classi e pacchetti, possano trarre grande vantaggio dall’uso dei DVCS.

            Liverpool” post=86876Forse il [tt]commit[/tt] aggiunge fisicamente una copia dei file aggiunti e un semplice riferimento per gli altri presenti nel repository basandosi non su ciò che c’è nella working directory, ma su ciò che è scritto nel suo database?

            Con “gli altri presenti nel repository” intendi i file mai entrati nella staging area? In questo caso ti ho risposto sopra.

            Liverpool” post=86876Grazie. Ho visto che hai aggiunto l’elenco dei comandi alla fine.

            Grazie a te per l’idea, è davvero utile. Non c’avevo mai pensato, ma effettivamente mi è capitato più di una volta di ritornare a leggermi mezza guida per trovare un comando che sapevo essere presente, il riassuntino di tre pagine è molto comodo per questo!

          • #87417
            Up
            0
            Down
            ::

            Elrond” post=86874Però, una precisazione: ho provato ora e
            `git checkout hashdelcommit5`
            sembra che riporti realmente il repository indietro al commit 5, nel senso che i commit 6 e 7 spariscono dalla cronologia.

            Quei commit sembra che “spariscano” ma non vengono cancellati, in realtà. Per esempio, se prima ti trovavi nel branch master puoi fare semplicemente
            `git checkout master`
            per tornare dov’eri. In questo modo si può navigare comodamente tra la cronologia, senza fare modifiche (non si possono inserire delle modifiche tra due commit senza essere su un branch) e senza perdere nulla (e se uno non si fida può “taggare” il commit in cima :)).

            Liverpool” post=86867Supponiamo che io voglia tornare alla versione 5. Io voglio che il file di classe e le immagini siano gli stessi che c’erano al momento di caricare la versione 6, cioè (c) della versione 4 e (i1) della versione 3. Come posso fare? Devo caricare in ogni commit (c) e (i1) anche se non li ho modificati?

            Se vuoi tornare a una certa versione precedente cancellando del tutto i commit recenti, allora puoi usare
            `git reset –hard hashpuntodiripristino`
            ammesso però che tu non debba “pushare” su un server remoto, che potrebbe dare problemi. In quest’ultimo caso puoi usare [tt]git checkout[/tt] come scritto da Elrond.

          • #87418
            Liverpool
            Partecipante
              Up
              0
              Down
              ::


              Il comando che cercavo è
              `git checkout — .`Il motivo è che a volte mi può servire rimettere in funzione una vecchia versione che funzionava con un file di classe ormai superato, quindi mi serve riportare tutto indietro.
              Ho provato anche
              `git checkout
              ` ma il sistema me lo vieta.

              Ho visto anche il [tt]reset[/tt], ma non è quello che cerco perché cancella le versioni successive. Mi potete spiegare la differenza tra “soft”, “mixed” e “hard”? Perché npn l’ho capita. Grazie

            • #87419
              Up
              0
              Down
              ::

              Liverpool” post=86911Ho visto anche il [tt]reset[/tt], ma non è quello che cerco perché cancella le versioni successive. Mi potete spiegare la differenza tra “soft”, “mixed” e “hard”? Perché npn l’ho capita. Grazie

              La differenza è spiegata molto chiaramente qui:
              http://stackoverflow.com/a/3528483/2563992.

              Una tabellina che aiuta a visualizzare: 🙂
              http://genomewiki.ucsc.edu/index.php/Working_with_Git#.27git_reset_–.5Boption.5D_HEAD.27.

              Ciao

          Visualizzazione 7 filoni di risposte
          • Devi essere connesso per rispondere a questo topic.

          Go to top