1. Una guida dettagliata a Git per principianti

Oggi parleremo di un sistema di controllo della versione, ovvero Git.

Non puoi davvero essere un programmatore a tutti gli effetti senza conoscere e comprendere questo strumento. Ovviamente, non devi tenere a mente tutti i comandi e le funzionalità di Git per essere impiegato continuamente. Devi conoscere una serie di comandi che ti aiuteranno a capire tutto ciò che sta accadendo.

Nozioni di base su Git

Git è un sistema di controllo della versione distribuito per il nostro codice. Perchè ne abbiamo bisogno? I team hanno bisogno di un qualche tipo di sistema per gestire il proprio lavoro. È necessario per tenere traccia dei cambiamenti che si verificano nel tempo.

Cioè, dobbiamo essere in grado di vedere passo dopo passo quali file sono cambiati e come. Ciò è particolarmente importante quando si esamina cosa è cambiato nel contesto di una singola attività, rendendo possibile annullare le modifiche.

Immaginiamo la seguente situazione: abbiamo un codice funzionante, tutto è buono, ma poi decidiamo di migliorare o modificare qualcosa. Non è un grosso problema, ma il nostro "miglioramento" ha rotto metà delle funzionalità del programma e ha reso impossibile il lavoro. E ora? Senza Git, dovresti sederti e pensare per ore, cercando di ricordare com'era originariamente tutto. Ma con Git, eseguiamo semplicemente il rollback del commit e basta.

O se ci sono due sviluppatori che apportano le proprie modifiche al codice contemporaneamente? Senza Git, copiano i file di codice originali e li modificano separatamente. Arriva un momento in cui entrambi vogliono aggiungere le loro modifiche alla directory principale. Cosa fai in questo caso?

Non ci saranno problemi di questo tipo se usi Git.

Installazione di Git

Installiamo Java sul tuo computer Questo processo differisce leggermente per i diversi sistemi operativi.

Installazione su Windows

Come al solito, devi scaricare ed eseguire un file exe. Qui è tutto semplice: fai clic sul primo link di Google , esegui l'installazione e il gioco è fatto. Per fare ciò, utilizzeremo la console bash fornita da Windows.

Su Windows, devi eseguire Git Bash. Ecco come appare nel menu Start:

Ora questo è un prompt dei comandi con cui puoi lavorare.

Per evitare di dover andare ogni volta nella cartella con il progetto per poter aprire Git lì, puoi aprire il prompt dei comandi nella cartella del progetto con il tasto destro del mouse con il percorso di cui abbiamo bisogno:

Installazione su Linux

Di solito Git fa parte delle distribuzioni Linux ed è già installato, poiché è uno strumento originariamente scritto per lo sviluppo del kernel Linux. Ma ci sono situazioni in cui non lo è. Per verificare, devi aprire un terminale e scrivere: git --version. Se ottieni una risposta comprensibile, non è necessario installare nulla.

Apri un terminale e installa. Per Ubuntu, devi scrivere: sudo apt-get install git. E questo è tutto: ora puoi usare Git in qualsiasi terminale.

Installazione su macOS

Anche qui devi prima verificare se Git è già presente (vedi sopra, come su Linux).

Se non ce l'hai, il modo più semplice per ottenerlo è scaricare l'ultima versione . Se Xcode è installato, Git verrà sicuramente installato automaticamente.

Impostazioni Git

Git ha le impostazioni utente per l'utente che invierà il lavoro. Questo ha senso ed è necessario, perché Git prende queste informazioni per il campo Autore quando viene creato un commit.

Imposta un nome utente e una password per tutti i tuoi progetti eseguendo i seguenti comandi:

git config --global user.name "Ivan Ivanov" git config --global user.email ivan.ivanov@gmail.com

Se devi cambiare l'autore per un progetto specifico (per un progetto personale, ad esempio), puoi rimuovere "--global". Questo ci darà quanto segue:

git config user.name "Ivan Ivanov" git config user.email ivan.ivanov@gmail.com

Un po' di teoria

Per approfondire l'argomento, dovremmo presentarti alcune nuove parole e azioni... Altrimenti, non ci sarà nulla di cui parlare. Naturalmente, questo è un gergo che ci viene dall'inglese, quindi aggiungerò le traduzioni tra parentesi.

Quali parole e azioni?

  • repository git
  • commettere
  • ramo
  • unire
  • conflitti
  • tiro
  • spingere
  • come ignorare alcuni file (.gitignore)

E così via.

Stati in Git

Git ha diverse statue che devono essere comprese e ricordate:

  • non tracciato
  • modificata
  • messo in scena
  • impegnato

Come dovresti capirlo?

Questi sono gli stati che si applicano ai file che contengono il nostro codice. In altre parole, il loro ciclo di vita di solito si presenta così:

  • Un file creato ma non ancora aggiunto al repository ha lo stato "non tracciato".
  • Quando apportiamo modifiche ai file che sono già stati aggiunti al repository Git, il loro stato è "modificato".
  • Tra i file che abbiamo modificato, selezioniamo quelli di cui abbiamo bisogno (ad esempio, non abbiamo bisogno di classi compilate) e queste classi vengono modificate nello stato "messo in scena".
  • Un commit viene creato da file preparati nello stato a fasi e va nel repository Git. Successivamente, non ci sono file con lo stato "messo in scena". Ma potrebbero esserci ancora file il cui stato è "modificato".

Ecco come appare:

Cos'è un impegno?

Un commit è l'evento principale quando si tratta di controllo della versione. Contiene tutte le modifiche apportate dall'inizio del commit. I commit sono collegati tra loro come un elenco collegato singolarmente.

Nello specifico, c'è un primo commit. Quando viene creato il secondo commit, esso (il secondo) sa cosa viene dopo il primo. E in questo modo, le informazioni possono essere monitorate.

Un commit ha anche le proprie informazioni, i cosiddetti metadati:

  • l'identificatore univoco del commit, che può essere utilizzato per trovarlo
  • il nome dell'autore del commit, che lo ha creato
  • la data di creazione del commit
  • un commento che descrive cosa è stato fatto durante il commit

Ecco come appare:

Cos'è un ramo?

Un ramo è un puntatore a qualche commit. Poiché un commit sa quale commit lo precede, quando un ramo punta a un commit, anche tutti i commit precedenti si applicano ad esso.

Di conseguenza, potremmo dire che puoi avere tutti i rami che vuoi che puntano allo stesso commit.

Il lavoro avviene nei rami, quindi quando viene creato un nuovo commit, il ramo sposta il suo puntatore sul commit più recente.

Iniziare con Git

Puoi lavorare sia con un repository locale che con uno remoto.

Per esercitarti con i comandi richiesti, puoi limitarti al repository locale. Memorizza solo tutte le informazioni del progetto localmente nella cartella .git.

Se stiamo parlando del repository remoto, tutte le informazioni sono archiviate da qualche parte sul server remoto: solo una copia del progetto è archiviata localmente. Le modifiche apportate alla tua copia locale possono essere inviate (git push) al repository remoto.

Nella nostra discussione qui e sotto, stiamo parlando di lavorare con Git nella console. Naturalmente, puoi utilizzare una sorta di soluzione basata su GUI (ad esempio, IntelliJ IDEA), ma prima dovresti capire quali comandi vengono eseguiti e cosa significano.

Lavorare con Git in un repository locale

Per creare un repository locale, devi scrivere:

git init

Questo creerà una cartella .git nascosta nella directory corrente della console.

La cartella .git memorizza tutte le informazioni sul repository Git. Non cancellarlo ;)

Successivamente, i file vengono aggiunti al progetto e ad essi viene assegnato lo stato "Non tracciato". Per controllare lo stato attuale del tuo lavoro, scrivi questo:

stato git

Siamo nel ramo principale e qui rimarremo fino a quando non passeremo a un altro ramo.

Questo mostra quali file sono stati modificati ma non sono ancora stati aggiunti allo stato "messo in scena". Per aggiungerli allo stato "staged", devi scrivere "git add". Abbiamo alcune opzioni qui, ad esempio:

  • git add -A — aggiunge tutti i file allo stato "staged".
  • git aggiungi . — aggiungi tutti i file da questa cartella e da tutte le sottocartelle. Essenzialmente uguale al precedente;
  • git add <file name> — aggiunge un file specifico. Qui puoi usare espressioni regolari per aggiungere file secondo uno schema. Ad esempio, git add *.java: significa che vuoi aggiungere solo file con estensione java.

Le prime due opzioni sono chiaramente semplici. Le cose si fanno più interessanti con l'ultima aggiunta, quindi scriviamo:

git aggiungi *.txt

Per verificare lo stato, utilizziamo il comando a noi già noto:

stato git

Qui puoi vedere che l'espressione regolare ha funzionato correttamente: test_resource.txt ora ha lo stato "staged".

E infine, l'ultima fase per lavorare con un repository locale (ce n'è un'altra quando si lavora con il repository remoto ;)) — creando un nuovo commit:

git commit -m "tutti i file txt sono stati aggiunti al progetto"

Il prossimo è un ottimo comando per guardare la cronologia dei commit su un ramo. Facciamone uso:

registro git

Qui puoi vedere che abbiamo creato il nostro primo commit e include il testo che abbiamo fornito sulla riga di comando. È molto importante capire che questo testo dovrebbe spiegare nel modo più accurato possibile ciò che è stato fatto durante questo commit. Questo ci aiuterà molte volte in futuro.

Un lettore curioso che non si è ancora addormentato potrebbe chiedersi cosa sia successo al file GitTest.java. Scopriamolo subito. Per farlo utilizziamo:

stato git

Come puoi vedere, è ancora "non tracciato" e sta aspettando dietro le quinte. Ma cosa succede se non vogliamo aggiungerlo affatto al progetto? A volte succede.

Per rendere le cose più interessanti, proviamo ora a modificare il nostro file test_resource.txt. Aggiungiamo del testo lì e controlliamo lo stato:

stato git

Qui puoi vedere chiaramente la differenza tra gli stati "non tracciati" e "modificati".

GitTest.java è "non tracciato", mentre test_resource.txt è "modificato".

Ora che abbiamo i file nello stato modificato, possiamo esaminare le modifiche apportate ad essi. Questo può essere fatto usando il seguente comando:

git diff

Cioè, puoi vedere chiaramente qui cosa ho aggiunto al nostro file di testo: ciao mondo!

Aggiungiamo le nostre modifiche al file di testo e creiamo un commit:

git add test_resource.txt
git commit -m “ha aggiunto la parola ciao! a test_resource.txt”

Per vedere tutti i commit, scrivi:

registro git

Come puoi vedere, ora abbiamo due commit.

Aggiungeremo GitTest.java allo stesso modo. Nessun commento qui, solo comandi:

git aggiungi GitTest.java
git commit -m "aggiunto GitTest.java"
stato git

Lavorare con .gitignore

Chiaramente, vogliamo solo mantenere il codice sorgente da solo, e nient'altro, nel repository. Quindi cos'altro potrebbe esserci? Come minimo, classi compilate e/o file generati dagli ambienti di sviluppo.

Per dire a Git di ignorarli, dobbiamo creare un file speciale. Fai questo: crea un file chiamato .gitignore nella root del progetto. Ogni riga in questo file rappresenta un modello da ignorare.

In questo esempio, il file .gitignore avrà questo aspetto:

*.class
target/
*.iml
.idea/

Diamo un'occhiata:

  • La prima riga è ignorare tutti i file con estensione .class
  • La seconda riga è ignorare la cartella "target" e tutto ciò che contiene
  • La terza riga consiste nell'ignorare tutti i file con estensione .iml
  • La quarta riga è ignorare la cartella .idea

Proviamo ad usare un esempio. Per vedere come funziona, aggiungiamo il GitTest.class compilato al progetto e controlliamo lo stato del progetto:

stato git

Chiaramente, non vogliamo in qualche modo aggiungere accidentalmente la classe compilata al progetto (usando git add -A). Per fare ciò, crea un file .gitignore e aggiungi tutto ciò che è stato descritto in precedenza:

Ora usiamo un commit per aggiungere il file .gitignore al progetto:

git aggiungi .gitignore
git commit -m "aggiunto file .gitignore"

E ora il momento della verità: abbiamo una classe compilata GitTest.class che è "non tracciata", che non volevamo aggiungere al repository Git.

Ora dovremmo vedere gli effetti del file .gitignore:

stato git

Perfetto! .gitignore +1 :)

Lavorare con i rami

Naturalmente, lavorare in un solo ramo è scomodo per gli sviluppatori solitari, ed è impossibile quando c'è più di una persona in un team. Questo è il motivo per cui abbiamo filiali.

Un ramo è solo un puntatore mobile ai commit.

In questa parte, esploreremo il lavoro in diversi rami: come unire le modifiche da un ramo all'altro, quali conflitti possono sorgere e molto altro.

Per vedere un elenco di tutti i rami presenti nel repository e capire in quale ci si trova, è necessario scrivere:

ramo git -a

Puoi vedere che abbiamo solo un ramo principale. L'asterisco davanti indica che ci siamo dentro. A proposito, puoi anche usare il comando "git status" per scoprire in quale ramo ci troviamo.

Quindi ci sono diverse opzioni per creare rami (potrebbero essercene di più - questi sono quelli che uso io):

  • creare una nuova filiale in base a quella in cui ci troviamo (99% dei casi)
  • creare un branch sulla base di un commit specifico (1% dei casi)

Creiamo un ramo basato su un commit specifico

Faremo affidamento sull'identificatore univoco del commit. Per trovarlo scriviamo:

registro git

Abbiamo evidenziato il commit con il commento "added hello world..." Il suo identificatore univoco è 6c44e53d06228f888f2f454d3cb8c1c976dd73f8. Vogliamo creare un ramo di "sviluppo" che parta da questo commit. Per farlo scriviamo:

git checkout -b sviluppo 6c44e53d06228f888f2f454d3cb8c1c976dd73f8

Viene creato un ramo con solo i primi due commit dal ramo principale. Per verificarlo, per prima cosa ci assicuriamo di passare a un ramo diverso e osserviamo il numero di commit lì:

stato git
registro git

E come previsto, abbiamo due commit. A proposito, ecco un punto interessante: non esiste ancora un file .gitignore in questo ramo, quindi il nostro file compilato (GitTest.class) è ora evidenziato con lo stato "non tracciato".

Ora possiamo rivedere nuovamente i nostri rami scrivendo questo:

ramo git -a

Puoi vedere che ci sono due rami: "master" e "development". Attualmente siamo in fase di sviluppo.

Creiamo un ramo basato su quello attuale

Il secondo modo per creare un ramo è crearlo da un altro. Vogliamo creare un ramo basato sul ramo principale. Innanzitutto, dobbiamo passare ad esso e il passaggio successivo è crearne uno nuovo. Diamo un'occhiata:

  • git checkout master — passa al ramo master
  • git status — verifica che ci troviamo effettivamente nel ramo master

Qui puoi vedere che siamo passati al ramo master, il file .gitignore è attivo e la classe compilata non è più evidenziata come "non tracciata".

Ora creiamo un nuovo ramo basato sul ramo master:

git checkout -b feature/update-txt-files

Se non sei sicuro che questo ramo sia lo stesso di "master", puoi facilmente verificare eseguendo "git log" e osservando tutti i commit. Dovrebbero essercene quattro.

Risoluzione del conflitto

Prima di esplorare cos'è un conflitto, dobbiamo parlare della fusione di un ramo in un altro.

Questa immagine mostra il processo di fusione di un ramo in un altro:

Qui abbiamo un ramo principale. Ad un certo punto, viene creato un ramo secondario dal ramo principale e quindi modificato. Una volta terminato il lavoro, dobbiamo unire un ramo nell'altro.

Nel nostro esempio, abbiamo creato il ramo feature/update-txt-files. Come indicato dal nome del ramo, stiamo aggiornando il testo.

Ora dobbiamo creare un nuovo commit per questo lavoro:

git aggiungi *.txt
git commit -m "file txt aggiornati"
registro git

Ora, se vogliamo unire il ramo feature/update-txt-files in master, dobbiamo andare su master e scrivere "git merge feature/update-txt-files":

master di git checkout
funzione git merge/aggiornamento-txt-file
registro git

Di conseguenza, il ramo master ora include anche il commit che è stato aggiunto a feature/update-txt-files.

Questa funzionalità è stata aggiunta, quindi puoi eliminare un ramo di funzionalità. Per farlo scriviamo:

git branch -D feature/update-txt-files

Complichiamo la situazione: ora diciamo che è necessario modificare nuovamente il file txt. Ma ora questo file verrà modificato anche nel ramo principale. In altre parole, cambierà in parallelo. Git non sarà in grado di capire cosa fare quando vogliamo unire il nostro nuovo codice nel ramo master.

Creeremo un nuovo ramo basato su master, apporteremo modifiche a text_resource.txt e creeremo un commit per questo lavoro:

git checkout -b feature/add-header

... apportiamo modifiche al file

git aggiungi *.txt
git commit -m "intestazione aggiunta a txt"

Vai al ramo principale e aggiorna anche questo file di testo sulla stessa riga del ramo delle caratteristiche:

master di git checkout

… abbiamo aggiornato test_resource.txt

git add test_resource.txt
git commit -m "ha aggiunto l'intestazione principale a txt"

E ora il punto più interessante: dobbiamo unire le modifiche dal ramo feature/add-header a master. Siamo nel ramo master, quindi dobbiamo solo scrivere:

funzione git merge/add-header

Ma il risultato sarà un conflitto nel file test_resource.txt:

Qui possiamo vedere che Git non può decidere da solo come unire questo codice. Ci dice che dobbiamo prima risolvere il conflitto e solo dopo eseguire il commit.

OK. Apriamo il file con il conflitto in un editor di testo e vediamo:

Per capire cosa ha fatto Git qui, dobbiamo ricordare quali modifiche abbiamo apportato e dove, quindi confrontare:

  1. Le modifiche presenti su questa riga nel ramo principale si trovano tra "<<<<<<< HEAD" e "=======".
  2. Le modifiche apportate al ramo feature/add-header si trovano tra "=======" e ">>>>>>> feature/add-header".

Questo è il modo in cui Git ci dice che non è riuscito a capire come eseguire l'unione in questa posizione nel file. Ha diviso questa sezione in due parti dai diversi rami e ci invita a risolvere noi stessi il conflitto di fusione.

Abbastanza giusto. Decido coraggiosamente di rimuovere tutto, lasciando solo la parola "header":

Diamo un'occhiata allo stato delle modifiche. La descrizione sarà leggermente diversa. Piuttosto che uno stato "modificato", abbiamo "separato". Quindi avremmo potuto menzionare un quinto stato? Non credo sia necessario. Vediamo:

stato git

Possiamo convincerci che questo è un caso speciale, insolito. Continuiamo:

git aggiungi *.txt

Potresti notare che la descrizione suggerisce di scrivere solo "git commit". Proviamo a scrivere che:

git commit

E proprio così, l'abbiamo fatto: abbiamo risolto il conflitto nella console.

Naturalmente, questo può essere fatto un po' più facilmente in ambienti di sviluppo integrati. Ad esempio, in IntelliJ IDEA, tutto è impostato così bene che puoi eseguire tutte le azioni necessarie direttamente al suo interno. Ma gli IDE fanno molte cose "sotto il cofano" e spesso non capiamo cosa stia succedendo esattamente lì. E quando non c'è comprensione, possono sorgere problemi.

Lavorare con repository remoti

L'ultimo passo è capire alcuni altri comandi necessari per lavorare con il repository remoto.

Come ho detto, un repository remoto è un luogo in cui è archiviato il repository e da cui è possibile clonarlo.

Che tipo di repository remoti ci sono? Esempi:

  • GitHub è la più grande piattaforma di storage per repository e sviluppo collaborativo.
  • GitLab è uno strumento basato sul Web per il ciclo di vita DevOps con open source. È un sistema basato su Git per la gestione dei repository di codice con il proprio wiki, sistema di tracciamento dei bug, pipeline CI/CD e altre funzioni.
  • BitBucket è un servizio Web per l'hosting di progetti e lo sviluppo collaborativo basato sui sistemi di controllo della versione Mercurial e Git. Un tempo aveva un grande vantaggio rispetto a GitHub in quanto offriva repository privati ​​gratuiti. L'anno scorso, GitHub ha anche introdotto questa funzionalità gratuitamente a tutti.
  • E così via…

Quando si lavora con un repository remoto, la prima cosa da fare è clonare il progetto nel repository locale.

Per questo, abbiamo esportato il progetto che abbiamo realizzato localmente Ora tutti possono clonarlo per se stessi scrivendo:

clone di git https://github.com/romankh3/git-demo

Ora è disponibile una copia locale completa del progetto. Per essere sicuri che la copia locale del progetto sia la più recente, è necessario eseguire il pull del progetto scrivendo:

git tirare

Nel nostro caso, al momento non è cambiato nulla nel repository remoto, quindi la risposta è: Già aggiornato.

Ma se apportiamo modifiche al repository remoto, quello locale viene aggiornato dopo che le abbiamo estratte.

Infine, l'ultimo comando consiste nell'inviare i dati al repository remoto. Quando abbiamo fatto qualcosa in locale e vogliamo inviarlo al repository remoto, dobbiamo prima creare un nuovo commit in locale. Per dimostrarlo, aggiungiamo qualcos'altro al nostro file di testo:

Ora qualcosa di abbastanza comune per noi: creiamo un commit per questo lavoro:

git add test_resource.txt
git commit -m "txt preparato per il push"

Il comando per inviarlo al repository remoto è:

spingere git

Questo è tutto per ora!

Link utili

2. Come lavorare con Git in IntelliJ IDEA

In questa parte imparerai come lavorare con Git in IntelliJ IDEA.

Input richiesti:

  1. Leggi, segui e comprendi la parte precedente. Ciò contribuirà a garantire che tutto sia configurato e pronto per l'uso.
  2. Installa IntelliJ IDEA. Dovrebbe essere tutto in ordine qui :)
  3. Assegna un'ora per raggiungere la completa padronanza.

Lavoriamo con il progetto demo che ho usato per l'articolo su Git.

Clonare il progetto localmente

Ci sono due opzioni qui:

  1. Se hai già un account GitHub e vuoi inviare qualcosa in un secondo momento, è meglio eseguire il fork del progetto e clonare la tua copia. Puoi leggere come creare un fork in un altro articolo sotto il titolo Un esempio del flusso di lavoro del fork .
  2. Clona il repository e fai tutto localmente senza la possibilità di inviare tutto al server.

Per clonare un progetto da GitHub, devi copiare il link del progetto e passarlo a IntelliJ IDEA:

  1. Copia l'indirizzo del progetto:

  2. Apri IntelliJ IDEA e seleziona "Ottieni da controllo versione":

  3. Copia e incolla l'indirizzo del progetto:

  4. Verrà richiesto di creare un progetto IntelliJ IDEA. Accetta l'offerta:

  5. Poiché non esiste un sistema di compilazione, selezioniamo "Crea progetto da fonti esistenti":

  6. Successivamente vedrai questo bellissimo schermo:

Ora che abbiamo scoperto la clonazione, puoi dare un'occhiata in giro.

Primo sguardo a IntelliJ IDEA come interfaccia utente Git

Dai un'occhiata più da vicino al progetto clonato: puoi già ottenere molte informazioni sul sistema di controllo della versione.

Innanzitutto, abbiamo il riquadro Controllo versione nell'angolo in basso a sinistra. Qui puoi trovare tutte le modifiche locali e ottenere un elenco di commit (analogo a "git log").

Passiamo a una discussione di Log. C'è una certa visualizzazione che ci aiuta a capire esattamente come è proceduto lo sviluppo. Ad esempio, puoi vedere che è stato creato un nuovo ramo con un'intestazione aggiunta al commit txt, che è stato poi unito al ramo principale. Se fai clic su un commit, puoi vedere nell'angolo destro tutte le informazioni sul commit: tutte le sue modifiche e metadati.

Inoltre, puoi vedere i cambiamenti effettivi. Vediamo anche che lì è stato risolto un conflitto. IDEA presenta anche questo molto bene.

Se fai doppio clic sul file che è stato modificato durante questo commit, vedremo come è stato risolto il conflitto:

Notiamo che a sinistra ea destra abbiamo le due versioni dello stesso file che dovevano essere unite in una sola. E nel mezzo, abbiamo il risultato finale della fusione.

Quando un progetto ha molti rami, commit e utenti, devi cercare separatamente per ramo, utente e data:

Prima di iniziare, vale anche la pena spiegare come capire in quale ramo ci troviamo.

Nell'angolo in basso a destra c'è un pulsante con l'etichetta "Git: master". Qualunque cosa segua "Git:" è il ramo corrente. Se fai clic sul pulsante, puoi fare molte cose utili: passare a un altro ramo, crearne uno nuovo, rinominarne uno esistente e così via.

Lavorare con un repository

Tasti di scelta rapida utili

Per il lavoro futuro, è necessario ricordare alcuni tasti di scelta rapida molto utili:

  1. CTRL+T — Ottieni le ultime modifiche dal repository remoto (git pull).
  2. CTRL+K — Crea un commit / visualizza tutte le modifiche correnti. Ciò include sia i file non tracciati che quelli modificati (git commit).
  3. CTRL+MAIUSC+K — Questo è il comando per inviare le modifiche al repository remoto. Tutti i commit creati localmente e non ancora nel repository remoto verranno inviati (git push).
  4. ALT+CTRL+Z : ripristina le modifiche in un file specifico allo stato dell'ultimo commit creato nel repository locale. Se selezioni l'intero progetto nell'angolo in alto a sinistra, puoi ripristinare le modifiche in tutti i file.

Cosa vogliamo?

Per portare a termine il lavoro, dobbiamo padroneggiare uno scenario di base utilizzato ovunque.

L'obiettivo è implementare una nuova funzionalità in un ramo separato e quindi inviarla a un repository remoto (quindi devi anche creare una richiesta pull al ramo principale, ma questo va oltre lo scopo di questa lezione).

Cosa è necessario per fare questo?

  1. Ottieni tutte le modifiche correnti nel ramo principale (ad esempio, "master").

  2. Da questo ramo principale, crea un ramo separato per il tuo lavoro.

  3. Implementare la nuova funzionalità.

  4. Vai al ramo principale e controlla se ci sono stati nuovi cambiamenti mentre stavamo lavorando. In caso contrario, allora va tutto bene. Ma se ci sono state modifiche, allora facciamo quanto segue: andiamo al ramo di lavoro e ribasiamo le modifiche dal ramo principale al nostro. Se tutto va bene, allora fantastico. Ma è del tutto possibile che ci saranno conflitti. Si dà il caso che possano essere risolti in anticipo, senza perdere tempo nel repository remoto.

    Ti stai chiedendo perché dovresti farlo? È una buona educazione e impedisce che si verifichino conflitti dopo aver spinto il tuo ramo nel repository locale (c'è, ovviamente, la possibilità che si verifichino ancora conflitti, ma diventa molto più piccolo ).

  5. Invia le tue modifiche al repository remoto.

Come ottenere modifiche dal server remoto?

Abbiamo aggiunto una descrizione al README con un nuovo commit e vogliamo ottenere queste modifiche. Se sono state apportate modifiche sia nel repository locale che in quello remoto, allora siamo invitati a scegliere tra un merge e un rebase. Scegliamo di fonderci.

Digita CTRL+T :

Ora puoi vedere come è cambiato il README, cioè le modifiche dal repository remoto sono state inserite, e nell'angolo in basso a destra puoi vedere tutti i dettagli delle modifiche che sono arrivate dal server.

Crea un nuovo ramo basato su master

Tutto è semplice qui.

Vai nell'angolo in basso a destra e fai clic su Git: master . Seleziona + Nuovo ramo .

Lascia selezionata la casella di controllo Filiale Checkout e inserisci il nome della nuova filiale. Nel nostro caso: questo sarà readme-improver .

Git: master cambierà quindi in Git: readme-improver .

Simuliamo un lavoro parallelo

Affinché i conflitti appaiano, qualcuno deve crearli.

Modificheremo il README con un nuovo commit attraverso il browser, simulando così un lavoro parallelo. È come se qualcuno apportasse modifiche allo stesso file mentre ci stavamo lavorando. Il risultato sarà un conflitto. Rimuoveremo la parola "fully" dalla riga 10.

Implementa la nostra funzionalità

Il nostro compito è modificare il README e aggiungere una descrizione al nuovo articolo. Cioè, il lavoro in Git passa attraverso IntelliJ IDEA. Aggiungi questo:

Le modifiche sono fatte. Ora possiamo creare un commit. Premi CTRL+K , che ci dà:

Prima di creare un commit, dobbiamo dare un'occhiata da vicino a ciò che offre questa finestra.

Nella sezione Commit Message , scriviamo il testo associato al commit. Quindi per crearlo, dobbiamo fare clic su Commit .

Scriviamo che il README è cambiato e creiamo il commit. Viene visualizzato un avviso nell'angolo in basso a sinistra con il nome del commit:

Controlla se il ramo principale è cambiato

Abbiamo completato il nostro compito. Funziona. Abbiamo scritto test. Va tutto bene. Ma prima di eseguire il push al server, dobbiamo ancora verificare se nel frattempo sono state apportate modifiche al ramo principale. Come è potuto succedere? Abbastanza facilmente: qualcuno riceve un compito dopo di te e quel qualcuno lo completa più velocemente di quanto tu finisca il tuo compito.

Quindi dobbiamo andare al ramo principale. Per fare ciò, dobbiamo fare ciò che viene mostrato nell'angolo in basso a destra nello screenshot qui sotto:

Nel ramo principale, premi CTRL+T per ottenere le ultime modifiche dal server remoto. Guardando quali sono i cambiamenti, puoi facilmente vedere cosa è successo:

La parola "fully" è stata rimossa. Forse qualcuno del marketing ha deciso che non dovrebbe essere scritto così e ha dato agli sviluppatori il compito di aggiornarlo.

Ora abbiamo una copia locale dell'ultima versione del ramo principale. Torna a readme-improver .

Ora dobbiamo ribasare le modifiche dal ramo principale al nostro. Facciamo questo:

Se hai fatto tutto correttamente e mi hai seguito, il risultato dovrebbe mostrare un conflitto nel file README:

Qui abbiamo anche molte informazioni da capire e assimilare. Qui viene mostrato un elenco di file (nel nostro caso, un file) che presentano conflitti. Possiamo scegliere tra tre opzioni:

  1. accetta il tuo: accetta solo le modifiche da readme-improver.
  2. accetta i loro — accetta solo modifiche dal master.
  3. unisci: scegli tu stesso cosa vuoi conservare e cosa scartare.

Non è chiaro cosa sia cambiato. Se ci sono modifiche sono il ramo principale, devono essere necessarie lì, quindi non possiamo semplicemente accettare le nostre modifiche. Di conseguenza, selezioniamo merge :

Qui possiamo vedere che ci sono tre parti:

  1. Queste sono le modifiche da readme-improver.
  2. Il risultato unito. Per ora, è ciò che esisteva prima dei cambiamenti.
  3. Le modifiche dal ramo principale.

Dobbiamo produrre un risultato unito che soddisfi tutti. Esaminando ciò che è stato modificato PRIMA delle nostre modifiche, ci rendiamo conto che hanno semplicemente rimosso la parola "fully". Ok nessun problema! Ciò significa che lo rimuoveremo anche nel risultato unito e quindi aggiungeremo le nostre modifiche. Una volta corretto il risultato unito, possiamo fare clic su Applica .

Quindi verrà visualizzata una notifica che ci informa che il rebase è andato a buon fine:

Là! Abbiamo risolto il nostro primo conflitto tramite IntelliJ IDEA.

Invio delle modifiche al server remoto

Il passaggio successivo consiste nell'inviare le modifiche al server remoto e creare una richiesta pull. Per fare ciò, premi semplicemente CTRL+MAIUSC+K . Quindi otteniamo:

Sulla sinistra, ci sarà un elenco di commit che non sono stati inviati al repository remoto. Sulla destra ci saranno tutti i file che sono stati modificati. E questo è tutto! Premi Push e sperimenterai la felicità :)

Se il push ha esito positivo, vedrai una notifica come questa nell'angolo in basso a destra:

Bonus: creazione di una richiesta pull

Andiamo in un repository GitHub e vediamo che GitHub sa già cosa vogliamo:

Fai clic su Confronta ed estrai richiesta . Quindi fai clic su Crea richiesta pull . Poiché abbiamo risolto i conflitti in anticipo, ora quando creiamo una richiesta pull, possiamo unirla immediatamente:

Questo è tutto per ora!