Istället för en introduktion
Hallå! Idag ska vi prata om ett versionskontrollsystem, nämligen Git. Du har inget med programmering att göra om du inte kan/förstår Git. Men det fina är att du inte behöver ha alla Git-kommandon och funktioner i huvudet för att vara kontinuerligt anställd. Du behöver känna till en uppsättning kommandon som hjälper dig att förstå allt som händer.Grunderna i Git
Git är ett distribuerat versionskontrollsystem för vår kod. Varför behöver vi det? Distribuerade team behöver något slags system för att hantera sitt arbete. Det behövs för att spåra förändringar som sker över tid. Det vill säga att vi måste kunna se steg för steg vilka filer som har ändrats och hur. Detta är särskilt viktigt när du undersöker vad som har förändrats i samband med en enskild uppgift, vilket gör det möjligt att återställa ändringarna.Installerar Git
Låt oss installera Java på din dator.Installerar på Windows
Som vanligt måste du ladda ner och köra en exe-fil. Allt är enkelt här: klicka på den första Google-länken , utför installationen och det är allt. För att göra detta kommer vi att använda bash-konsolen som tillhandahålls av Windows. På Windows måste du köra Git Bash. Så här ser det ut i Start-menyn: Nu är det här en kommandotolk som du kan arbeta med. För att undvika att behöva gå till mappen med projektet varje gång för att öppna Git där, kan du öppna kommandotolken i projektmappen med höger musknapp med sökvägen vi behöver:Installerar på Linux
Vanligtvis är Git en del av Linux-distributioner och är redan installerat, eftersom det är ett verktyg som ursprungligen skrevs för Linux-kärnutveckling. Men det finns situationer när det inte är det. För att kontrollera måste du öppna en terminal och skriva: git --version. Om du får ett begripligt svar behöver ingenting installeras. Öppna en terminal och installera Git på Ubuntu . Jag arbetar på Ubuntu, så jag kan berätta vad du ska skriva för det: sudo apt-get install git.Installerar på macOS
Även här måste du först kontrollera om Git redan finns där. Om du inte har det är det enklaste sättet att få det att ladda ner den senaste versionen här . Om Xcode är installerat kommer Git definitivt att installeras automatiskt.Git-inställningar
Git har användarinställningar för användaren som ska skicka in arbete. Detta är vettigt och är nödvändigt, eftersom Git tar denna information för fältet Author när en commit skapas. Ställ in ett användarnamn och lösenord för alla dina projekt genom att köra följande kommandon:
git config --global user.name "Ivan Ivanov"
git config --global user.email ivan.ivanov@gmail.com
Om du behöver ändra författaren för ett specifikt projekt kan du ta bort "--global". Detta kommer att ge oss följande:
git config user.name "Ivan Ivanov"
git config user.email ivan.ivanov@gmail.com
Lite teori...
För att dyka in i ämnet bör vi introducera dig för några nya ord och handlingar...- git repository
- begå
- gren
- sammanfoga
- konflikter
- dra
- skjuta på
- hur man ignorerar vissa filer (.gitignore)
Status i Git
Git har flera statyer som måste förstås och komma ihåg:- ospårad
- ändrad
- iscensatt
- engagerad
Hur ska du förstå detta?
Dessa är statusar som gäller för filerna som innehåller vår kod:- En fil som har skapats men ännu inte lagts till i förvaret har statusen "ospårad".
- När vi gör ändringar i filer som redan har lagts till i Git-förvaret, är deras status "modifierad".
- Bland filerna som vi har ändrat väljer vi de som vi behöver, och dessa klasser ändras till "stadium"-status.
- En commit skapas från förberedda filer i stegvis tillstånd och går in i Git-förvaret. Efter det finns det inga filer med statusen "iscenesatt". Men det kan fortfarande finnas filer vars status är "modifierad".
Vad är ett åtagande?
En commit är huvudhändelsen när det kommer till versionskontroll. Den innehåller alla ändringar som gjorts sedan commit började. Commits är länkade ihop som en enkellänkad lista. Mer specifikt: Det finns en första commit. När den andra commit skapas vet den vad som kommer efter den första. Och på detta sätt kan information spåras. En commit har också sin egen information, så kallad metadata:- commits unika identifierare, som kan användas för att hitta den
- namnet på uppdragets författare, som skapade det
- det datum då åtagandet skapades
- en kommentar som beskriver vad som gjordes under commit
Vad är en gren?
En gren är en pekare till någon commit. Eftersom en commit vet vilken commit som föregår den, när en gren pekar på en commit, gäller alla de tidigare commits också för den. Följaktligen kan vi säga att du kan ha så många grenar du vill som pekar på samma commit. Arbete sker i grenar, så när en ny commit skapas, flyttar grenen sin pekare till den senaste commit.Komma igång med Git
Du kan arbeta med ett lokalt arkiv ensamt såväl som med ett fjärranslutet. För att öva de nödvändiga kommandona kan du begränsa dig till det lokala förrådet. Den lagrar bara all information om projektet lokalt i .git-mappen. Om vi pratar om fjärrförvaret, så lagras all information någonstans på fjärrservern: endast en kopia av projektet lagras lokalt. Ändringar som görs i din lokala kopia kan skickas (git push) till fjärrförvaret. I vår diskussion här och nedan pratar vi om att arbeta med Git i konsolen. Naturligtvis kan du använda någon form av GUI-baserad lösning (till exempel IntelliJ IDEA), men först bör du ta reda på vilka kommandon som körs och vad de betyder.Arbeta med Git i ett lokalt arkiv
Därefter föreslår jag att du följer med och utför alla steg som jag gjorde när du läste artikeln. Detta kommer att förbättra din förståelse och behärskning av materialet. Nåväl, god aptit! :) För att skapa ett lokalt arkiv måste du skriva:
git init
Detta kommer att skapa en .git-mapp i konsolens nuvarande katalog. .git-mappen lagrar all information om Git-förvaret. Ta inte bort det ;) Därefter läggs filer till i projektet och de tilldelas statusen "Ospårade". För att kontrollera aktuell status för ditt arbete, skriv detta:
git status
Vi är i mastergrenen, och här kommer vi att vara kvar tills vi byter till en annan gren. Detta visar vilka filer som har ändrats men som ännu inte har lagts till i "scensatt" status. För att lägga till dem till "stadium"-statusen måste du skriva "git add". Vi har några alternativ här, till exempel:
- git add -A — lägg till alla filer till statusen "stadium".
- git add . — lägg till alla filer från den här mappen och alla undermappar. I huvudsak är detta samma som den föregående
- git add <filnamn> — lägger till en specifik fil. Här kan du använda reguljära uttryck för att lägga till filer enligt något mönster. Till exempel, git add *.java: Detta betyder att du bara vill lägga till filer med java-tillägget.
git add *.txt
För att kontrollera status använder vi kommandot som vi redan känner till:
git status
Här kan du se att det reguljära uttrycket har fungerat korrekt: test_resource.txt har nu statusen "stadium". Och slutligen, det sista steget för att arbeta med ett lokalt arkiv (det finns ett till när du arbetar med fjärrarkivet ;)) — skapa en ny commit:
git commit -m "all txt files were added to the project"
Nästa upp är ett bra kommando för att titta på commit-historiken på en gren. Låt oss använda det:
git log
Här kan du se att vi har skapat vår första commit och den innehåller texten som vi angav på kommandoraden. Det är mycket viktigt att förstå att den här texten så noggrant som möjligt ska förklara vad som gjordes under denna överenskommelse. Detta kommer att hjälpa oss många gånger i framtiden. En nyfiken läsare som ännu inte har somnat kanske undrar vad som hände med filen GitTest.java. Låt oss ta reda på det nu. För att göra detta använder vi:
git status
Som ni ser är den fortfarande "ospårad" och väntar i kulisserna. Men tänk om vi inte alls vill lägga till det i projektet? Ibland händer det. För att göra saker mer intressanta, låt oss nu försöka ändra vår test_resource.txt-fil. Låt oss lägga till lite text där och kontrollera statusen:
git status
Här kan du tydligt se skillnaden mellan "ospårad" och "modifierad" status. GitTest.java är "untracked", medan test_resource.txt är "modifierad". Nu när vi har filer i det modifierade tillståndet kan vi granska ändringarna som gjorts i dem. Detta kan göras med följande kommando:
git diff
Det vill säga du kan tydligt se här vad jag lagt till i vår textfil: hej värld! Låt oss lägga till våra ändringar i textfilen och skapa en commit:
git add test_resource.txt
git commit -m "added hello word! to test_resource.txt"
För att titta på alla åtaganden, skriv:
git log
Som du kan se har vi nu två commits. Vi lägger till GitTest.java på samma sätt. Inga kommentarer här, bara kommandon:
git add GitTest.java
git commit -m "added GitTest.java"
git status
Arbetar med .gitignore
Det är klart att vi bara vill behålla källkoden ensam, och inget annat, i förvaret. Så vad mer kan det finnas? Åtminstone kompilerade klasser och/eller filer genererade av utvecklingsmiljöer. För att säga åt Git att ignorera dem måste vi skapa en speciell fil. Gör så här: skapa en fil som heter .gitignore i projektets rot. Varje rad i den här filen representerar ett mönster att ignorera. I det här exemplet kommer .gitignore-filen att se ut så här:
```
*.class
target/
*.iml
.idea/
```
Låt oss ta en titt:
- Den första raden är att ignorera alla filer med tillägget .class
- Den andra raden är att ignorera mappen "mål" och allt den innehåller
- Den tredje raden är att ignorera alla filer med tillägget .iml
- Den fjärde raden är att ignorera mappen .idea
git status
Uppenbarligen vill vi inte på något sätt av misstag lägga till den kompilerade klassen till projektet (med git add -A). För att göra detta, skapa en .gitignore-fil och lägg till allt som beskrevs tidigare: Låt oss nu använda en commit för att lägga till .gitignore-filen till projektet:
git add .gitignore
git commit -m "added .gitignore file"
Och nu sanningens ögonblick: vi har en kompilerad klass GitTest.class som är "untracked", som vi inte ville lägga till i Git-förvaret. Nu bör vi se effekterna av .gitignore-filen:
git status
Perfekt! .gitignore +1 :)
Jobbar med grenar och så
Naturligtvis är det obekvämt att arbeta i bara en gren för ensamma utvecklare, och det är omöjligt när det finns mer än en person i ett team. Det är därför vi har filialer. Som jag sa tidigare är en gren bara en rörlig pekare till commits. I den här delen kommer vi att utforska att arbeta i olika grenar: hur man slår ihop förändringar från en gren till en annan, vilka konflikter som kan uppstå och mycket mer. För att se en lista över alla grenar i förvaret och förstå vilken du befinner dig i måste du skriva:
git branch -a
Du kan se att vi bara har en mastergren. Asterisken framför den indikerar att vi är i den. Förresten, du kan också använda kommandot "git status" för att ta reda på vilken gren vi befinner oss i. Sedan finns det flera alternativ för att skapa grenar (det kan finnas fler — det här är de som jag använder):
- skapa en ny filial baserat på den vi är i (99% av fallen)
- skapa en filial baserat på ett specifikt åtagande (1 % av fallen)
Låt oss skapa en gren baserat på en specifik commit
Vi förlitar oss på commitens unika identifierare. För att hitta den skriver vi:
git log
Jag har markerat commit med kommentaren "added hello world..." Dess unika identifierare är 6c44e53d06228f888f2f454d3cb8c1c976dd73f8. Jag vill skapa en "utvecklings"-gren som utgår från denna commit. För att göra detta skriver jag:
git checkout -b development 6c44e53d06228f888f2f454d3cb8c1c976dd73f8
En gren skapas med endast de två första commits från mastergrenen. För att verifiera detta ser vi först till att byta till en annan filial och tittar på antalet commits där:
git status
git log
Och som väntat har vi två åtaganden. Förresten, här är en intressant poäng: det finns ingen .gitignore-fil i den här grenen ännu, så vår kompilerade fil (GitTest.class) är nu markerad med statusen "ospårad". Nu kan vi granska våra filialer igen genom att skriva detta:
git branch -a
Du kan se att det finns två grenar: "master" och "development". Vi är för närvarande under utveckling.
Låt oss skapa en gren baserat på den nuvarande
Det andra sättet att skapa en gren är att skapa den från en annan. Jag vill skapa en gren baserad på mastergrenen. Först måste jag byta till det, och nästa steg är att skapa en ny. Låt oss ta en titt:- git checkout master — växla till mastergrenen
- git status — verifiera att vi faktiskt är i mastergrenen
git checkout -b feature/update-txt-files
Om du är osäker på om denna gren är samma som "master" kan du enkelt kontrollera genom att köra "git log" och titta på alla commits. Det borde vara fyra av dem.
Konfliktlösning
Innan vi utforskar vad en konflikt är måste vi prata om att slå samman en gren till en annan. Den här bilden skildrar processen att slå samman en gren till en annan: Här har vi en huvudgren. Vid något tillfälle skapas en sekundär gren från huvudgrenen och modifieras sedan. När arbetet är klart måste vi slå samman den ena grenen i den andra. Jag kommer inte att beskriva de olika funktionerna: I den här artikeln vill jag bara förmedla en allmän förståelse. Om du behöver detaljerna kan du leta upp dem själv. I vårt exempel skapade vi grenen feature/update-txt-files. Som framgår av filialens namn uppdaterar vi texten. Nu måste vi skapa en ny commit för detta arbete:
git add *.txt
git commit -m "updated txt files"
git log
Om vi nu vill slå samman grenen feature/update-txt-files till master, måste vi gå till master och skriva "git merge feature/update-txt-files":
git checkout master
git merge feature/update-txt-files
git log
Som ett resultat inkluderar mastergrenen nu även commit som lades till feature/update-txt-filer. Den här funktionen lades till så att du kan ta bort en funktionsgren. För att göra detta skriver vi:
git branch -D feature/update-txt-files
Allt är klart än så länge, eller hur? Låt oss komplicera situationen: låt oss nu säga att du måste ändra txt-filen igen. Men nu kommer den här filen att ändras i mastergrenen också. Det kommer med andra ord att förändras parallellt. Git kommer inte att kunna ta reda på vad vi ska göra när vi vill slå samman vår nya kod till mastergrenen. Nu går vi! Vi skapar en ny gren baserad på master, gör ändringar i text_resource.txt och skapar en commit för detta arbete:
git checkout -b feature/add-header
... we make changes to the file
git add *.txt
git commit -m "added header to txt"
Gå till huvudgrenen och uppdatera även denna textfil på samma rad som i funktionsgrenen:
git checkout master
… we updated test_resource.txt
git add test_resource.txt
git commit -m "added master header to txt"
Och nu den mest intressanta punkten: vi måste slå samman ändringar från grenen feature/add-header till master. Vi är i mastergrenen, så vi behöver bara skriva:
git merge feature/add-header
Men resultatet kommer att bli en konflikt i filen test_resource.txt: Här kan vi se att Git inte kunde bestämma på egen hand hur den här koden skulle slås samman. Det talar om för oss att vi måste lösa konflikten först och först sedan utföra åtagandet. OK. Vi öppnar filen med konflikten i en textredigerare och ser: För att förstå vad Git gjorde här måste vi komma ihåg vilka ändringar vi gjorde och var, och sedan jämföra:
- Ändringarna som fanns på den här raden i mastergrenen finns mellan "<<<<<<< HEAD" och "========".
- Ändringarna som fanns i grenen feature/add-header finns mellan "=======" och ">>>>>>> feature/add-header”.
git status
Vi kan övertyga oss själva om att detta är ett speciellt, ovanligt fall. Låt oss fortsätta:
git add *.txt
Du kanske märker att beskrivningen föreslår att du bara skriver "git commit". Låt oss försöka skriva det:
git commit
Och precis som det gjorde vi det — vi löste konflikten i konsolen. Naturligtvis kan detta göras lite lättare i integrerade utvecklingsmiljöer. Till exempel, i IntelliJ IDEA, är allt så väl inställt att du kan utföra alla nödvändiga åtgärder direkt inom det. Men IDE:er gör många saker "under huven", och vi förstår ofta inte exakt vad som händer där. Och när det inte finns någon förståelse kan problem uppstå.
Arbeta med fjärrlager
Det sista steget är att ta reda på några fler kommandon som behövs för att fungera med fjärrförvaret. Som jag sa, ett fjärrlager är någon plats där förvaret lagras och från vilket du kan klona det. Vilken typ av fjärrlager finns det? Exempel:-
GitHub är den största lagringsplattformen för repositories och samarbetsutveckling. Jag har redan beskrivit det i tidigare artiklar.
Följ mig på GitHub . Jag visar ofta upp mitt arbete där inom de områden som jag studerar för arbete. -
GitLab är ett webbaserat verktyg för DevOps- livscykeln med öppen källkod . Det är ett Git -baserat system för att hantera kodlager med sin egen wiki, buggspårningssystem , CI/CD-pipeline och andra funktioner.
Efter nyheten att Microsoft köpte GitHub, duplicerade vissa utvecklare sina projekt i GitLab. -
BitBucket är en webbtjänst för projekthosting och samarbetsutveckling baserad på Mercurial och Git versionskontrollsystem. En gång hade den en stor fördel gentemot GitHub genom att den erbjöd gratis privata arkiv. Förra året introducerade GitHub också denna möjlighet för alla gratis.
-
Och så vidare…
git clone https://github.com/romankh3/git-demo
Det finns nu en komplett lokal kopia av projektet. För att vara säker på att den lokala kopian av projektet är den senaste måste du dra projektet genom att skriva:
git pull
I vårt fall har ingenting i fjärrförvaret förändrats för närvarande, så svaret är: Redan uppdaterad. Men om jag gör några ändringar i fjärrlagret uppdateras det lokala efter att vi hämtat dem. Och slutligen är det sista kommandot att skicka data till fjärrförvaret. När vi har gjort något lokalt och vill skicka det till fjärrförvaret måste vi först skapa en ny commit lokalt. För att demonstrera detta, låt oss lägga till något annat till vår textfil: Något som är ganska vanligt för oss – vi skapar en commit för detta arbete:
git add test_resource.txt
git commit -m "prepared txt for pushing"
Kommandot för att skicka detta till fjärrförvaret är:
git push
Tja, det var allt jag ville säga. Tack för din uppmärksamhet. Följ mig på GitHub , där jag lägger upp olika coola exempelprojekt relaterade till mina personliga studier och arbete.
Användbar länk
- Officiell Git-dokumentation . Jag rekommenderar det som referens.
GO TO FULL VERSION