-
1. Začetek
- 1.1 O nadzoru različic
- 1.2 Kratka zgodovina Gita
- 1.3 Kaj je Git?
- 1.4 Ukazna vrstica
- 1.5 Namestitev Gita
- 1.6 Prva nastavitev Gita
- 1.7 Pridobivanje pomoči
- 1.8 Povzetek
-
2. Osnove Git
- 2.1 Pridobivanje repozitorija Git
- 2.2 Snemanje sprememb v repozitorij
- 2.3 Pregled zgodovine potrditev
- 2.4 Razveljavljanje stvari
- 2.5 Delo z daljavami
- 2.6 Označevanje
- 2.7 Aliasi Git
- 2.8 Povzetek
-
3. Veje Git
- 3.1 Veje na kratko
- 3.2 Osnove vej in združevanja
- 3.3 Upravljanje vej
- 3.4 Poteki dela z vejami
- 3.5 Oddaljene veje
- 3.6 Ponovno baziranje
- 3.7 Povzetek
-
4. Git na strežniku
- 4.1 Protokoli
- 4.2 Pridobitev Gita na strežniku
- 4.3 Generiranje vaših javnih ključev SSH
- 4.4 Nastavitev strežnika
- 4.5 Prikriti proces Git
- 4.6 Pametni HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Možnosti gostovanja pri tretjih ponudnikih
- 4.10 Povzetek
-
5. Porazdeljeni Git
- 5.1 Porazdeljeni poteki dela
- 5.2 Prispevek k projektu
- 5.3 Vzdrževanje projekta
- 5.4 Povzetek
-
6. GitHub
-
7. Orodja Git
- 7.1 Izbira revizije
- 7.2 Interaktivno pripravljanje
- 7.3 Shranjevanje na varno (angl. stashing) in čiščenje
- 7.4 Podpisovanje vašega dela
- 7.5 Iskanje
- 7.6 Prepisovanje zgodovine
- 7.7 Demistifikacija ponastavitve
- 7.8 Napredno združevanje
- 7.9 Rerere
- 7.10 Razhroščevanje z Gitom
- 7.11 Podmoduli
- 7.12 Povezovanje v pakete
- 7.13 Zamenjava
- 7.14 Shramba poverilnic
- 7.15 Povzetek
-
8. Prilagoditev Gita
- 8.1 Konfiguracija Git
- 8.2 Atributi Git
- 8.3 Kljuke Git
- 8.4 Primer pravilnika, ki ga uveljavlja Git
- 8.5 Povzetek
-
9. Git in ostali sistemi
- 9.1 Git kot odjemalec
- 9.2 Migracija na Git
- 9.3 Povzetek
-
10. Notranjost Gita
- 10.1 Napeljava in keramika
- 10.2 Objekti Git
- 10.3 Reference Git
- 10.4 Packfiles (datoteke zmanjšanih podatkov)
- 10.5 Refspec
- 10.6 Protokoli prenosa
- 10.7 Vzdrževanje in obnovitev podatkov
- 10.8 Spremenljivke okolja
- 10.9 Povzetek
-
A1. Dodatek A: Git v drugih okoljih
- A1.1 Grafični vmesniki
- A1.2 Git v Visual Studio
- A1.3 Git v Visual Studio Code
- A1.4 Git v IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git v Sublime Text
- A1.6 Git v Bashu
- A1.7 Git v Zsh
- A1.8 Git v Powershellu
- A1.9 Povzetek
-
A2. Dodatek B: Vdelava Gita v vašo aplikacijo
- A2.1 Git v ukazni vrstici
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Dodatek C: Ukazi Git
- A3.1 Nastavitev in konfiguracija
- A3.2 Pridobivanje in ustvarjanje projektov
- A3.3 Osnove posnetkov
- A3.4 Veje in združevanje
- A3.5 Deljenje in posodabljanje projektov
- A3.6 Pregled in primerjava
- A3.7 Razhroščevanje
- A3.8 Popravljanje
- A3.9 E-pošta
- A3.10 Zunanji sistemi
- A3.11 Administracija
- A3.12 Orodja za sisteme napeljave
A2.2 Dodatek B: Vdelava Gita v vašo aplikacijo - Libgit2
Libgit2
Druga možnost na vašem dosegu je uporabiti Libgit2. Libgit2 je neodvisna implementacija Gita s poudarkom imeti dober API za uporabo znotraj ostalih programov. Lahko ga najdete na https://libgit2.org.
Najprej poglejmo, kako je videti C API. Tu je vihravi ogled:
// Open a repository
git_repository *repo;
int error = git_repository_open(&repo, "/path/to/repository");
// Dereference HEAD to a commit
git_object *head_commit;
error = git_revparse_single(&head_commit, repo, "HEAD^{commit}");
git_commit *commit = (git_commit*)head_commit;
// Print some of the commit's properties
printf("%s", git_commit_message(commit));
const git_signature *author = git_commit_author(commit);
printf("%s <%s>\n", author->name, author->email);
const git_oid *tree_id = git_commit_tree_id(commit);
// Cleanup
git_commit_free(commit);
git_repository_free(repo);
Prvih nekaj vrstic odpre repozitorij Git.
Tip git_repository
predstavlja oprimek na repozitorij s predpomnilnikom v spominu.
To je najenostavnejša metoda, ko poznate točno pot do delovnega direktorija repozitorija ali direktorij .git
.
Obstaja tudi git_repository_open_ext
, ki vključuje možnosti za iskanje, git_clone
s prijatelji za izdelavo lokalnega klona oddaljenega repozitorija in git_repository_init
za izdelavo celotnega novega repozitorija.
Drug kos kode uporablja sintakso rev-parse (glejte razdelek Reference vej za več o tem), da dobi potrditev, na katero HEAD eventualno kaže.
Vrnjeni tip je kazalec git_object
, ki predstavlja nekaj, kar obstaja v objektni podatkovni bazi Gita za repozitorij.
git_object
je dejansko »nadrejeni« tip za nekaj različnih vrst objektov; postavitev spomina za vsakega od »podrejenih« tipov je enak za git_object
, tako da lahko varno oddate pravega.
V tem primeru bi git_object_type(commit)
vrnil GIT_OBJ_COMMIT
, torej je varno potrditi kazalec git_commit
.
Naslednji kos prikazuje dostop do lastnosti potrditve.
Zadnja vrstica tu uporablja tip git_oid
; to je predstavitev Libgit2 za zgoščeno vrednost SHA-1.
Iz tega primera se je začelo pojavljati nekaj vzorcev:
-
Če določite kazalec in podate referenco nanj v klicu Libgit2, bo ta klic verjetno vrnil kodo napake celega števila. Vrednost
0
kaže uspeh; karkoli manjšega je napaka. -
Če Libgit2 zapolni kazalec za vas, ste odgovorni za njegovo izpustitev.
-
Če Libgit2 iz klica vrne kazalec
const
, vam ga ni treba izpustiti, vendar bo postal neveljaven, ko je objekt, ki mu pripada, izpuščen. -
Pisanje C-ja je nekoliko mučno.
Zadnje pomeni, da ni zelo verjetno, da boste pisali C, ko uporabljate Libgit2. Na srečo je na voljo število jezikom specifičnih vezav, ki naredijo delo z repozitoriji Git iz vašega določenega jezika in okolja precej enostavno. Poglejmo zgornji primer napisan z vezavami Ruby za Libgit2, ki so poimenovane Rugged, in lahko jih najdete na https://github.com/libgit2/rugged.
repo = Rugged::Repository.new('path/to/repository')
commit = repo.head.target
puts commit.message
puts "#{commit.author[:name]} <#{commit.author[:email]}>"
tree = commit.tree
Kot lahko vidite, je koda veliko manj natrpana.
Najprej, Rugged uporablja izjeme; lahko vrne stvari, kot so ConfigError
ali ObjectError
za signalizacijo pogojev napak.
Drugič, ne obstaja nobena eksplicitna sprostitev virov, ker Ruby sprošča pomnilnik (angl. garbage collection).
Poglejmo nekoliko bolj zapleten primer: obdelovanje potrditve od začetka:
blob_id = repo.write("Blob contents", :blob) # (1)
index = repo.index
index.read_tree(repo.head.target.tree)
index.add(:path => 'newfile.txt', :oid => blob_id) # (2)
sig = {
:email => "bob@example.com",
:name => "Bob User",
:time => Time.now,
}
commit_id = Rugged::Commit.create(repo,
:tree => index.write_tree(repo), # (3)
:author => sig,
:committer => sig, # (4)
:message => "Add newfile.txt", # (5)
:parents => repo.empty? ? [] : [ repo.head.target ].compact, # (6)
:update_ref => 'HEAD', # (7)
)
commit = repo.lookup(commit_id) # (8)
-
Ustvarite novo zbirko binarnih podatkov (blob), ki vsebuje vsebino nove datoteke.
-
Zapolnite indeks z drevesom potrditve glave in dodajte novo datoteko v pot
newfile.txt
. -
To ustvari novo drevo v ODB in ga uporablja za novo potrditev.
-
Uporabljamo enak podpis tako za avtorja kot tudi za polja potrditve.
-
Sporočilo potrditve.
-
Ko se ustvarja potrditev, morate določiti nove nadrejene potrditve. To uporablja vrh HEAD-a za eno nadrejeno.
-
Rugged (in Libgit2) lahko opcijsko posodobi referenco, ko dela potrditev.
-
Vrnjena vrednost je zgoščena vrednost SHA-1 novega objekta potrditve, kar lahko potem uporabite, da dobite objekt
Commit
.
Koda Ruby je lepa in čista, vendar ker Libgit2 izvaja težka opravila, se bo ta koda tudi poganjala hitro. Če niste rubist, se bomo dotaknili nekaterih ostalih povezav v Ostale vezave.
Napredna funkcionalnost
Libgit2 ima nekaj zmožnosti, ki so izven obsega jedra Git. En primer je možnost vtičnikov: Libgit2 vam omogoča ponujati prilagojena »ozadja« za nekaj tipov operacij, tako da lahko shranite stvari na različne načine, kot jih počne goli Git. Libgit2 med drugimi stvarmi omogoča prilagojena ozadja za nastavitve, shranjevanje ref in objektno podatkovno bazo.
Poglejmo, kako to deluje. Koda spodaj je izposojena iz skupka primerov ozadja ponujenih s strani ekipe Libgit2 (kar je moč najti na https://github.com/libgit2/libgit2-backends). Tako se nastavi prilagojeno ozadje za objektno podatkovno bazo:
git_odb *odb;
int error = git_odb_new(&odb); // (1)
git_odb_backend *my_backend;
error = git_odb_backend_mine(&my_backend, /*…*/); // (2)
error = git_odb_add_backend(odb, my_backend, 1); // (3)
git_repository *repo;
error = git_repository_open(&repo, "some-path");
error = git_repository_set_odb(repo, odb); // (4)
Pomnite, da so napake zajete, vendar niso upravljane. Upamo, da je vaša koda boljša od naše.
-
Inicializacija »ospredja« prazne objektne podatkovne baze (ODB), ki se bo obnašalo kot kontejner za »ozadja«, ki pa so tista, ki delajo pravo delo.
-
Inicializacija prilagojenega ozadja ODB.
-
Dodajanje ozadja k ospredju.
-
Odpiranje repozitorija in njegova nastavitev, da uporablja našo ODB za iskanje objektov.
Vendar, kaj je ta stvar git_odb_backend_mine
?
Torej, to je konstruktor za vašo lastno ODB implementacijo in tam lahko naredite karkoli želite, dokler ustrezno zapolnjujete strukturo v git_odb_backend
.
Takole bi lahko bilo videti:
typedef struct {
git_odb_backend parent;
// Some other stuff
void *custom_context;
} my_backend_struct;
int git_odb_backend_mine(git_odb_backend **backend_out, /*…*/)
{
my_backend_struct *backend;
backend = calloc(1, sizeof (my_backend_struct));
backend->custom_context = …;
backend->parent.read = &my_backend__read;
backend->parent.read_prefix = &my_backend__read_prefix;
backend->parent.read_header = &my_backend__read_header;
// …
*backend_out = (git_odb_backend *) backend;
return GIT_SUCCESS;
}
Najsubtilnejša omejitev tu je, da mora biti prvi član my_backend_struct
struktura git_odb_backend
; to zagotavlja, da je postavitev spomina to, kar Libgit2 pričakuje, da je.
Preostanek je poljuben; ta struktura je lahko tako velika ali majhna, kakor jo potrebujete.
Funkcija inicializacije dodeli nekaj spomina za strukturo, nastavi kontekst po meri in nato zapolni člane strukture parent
, ki jo podpira.
Poglejmo datoteko include/git2/sys/odb_backend.h
v izvorni kodi Libgit2 za celoten skupek podpisov klica; določeni primer uporabe vam bo pomagal določiti, katerega od teh boste želeli podpirati.
Ostale vezave
Libgit2 ima vezave za mnogo jezikov.
Tu bomo pokazali majhen primer, ki uporablja nekaj od bolj celovitih vezav paketov od tega pisanja; knjižnice obstajajo za mnoge ostale jezike, vključno C++, Go, Node.js, Erlang in JVM, vse v različnih fazah zrelosti.
Uradno zbirko vezav se lahko najde z brskanjem po repozitorijih na https://github.com/libgit2.
Koda, ki jo boste pisali, bo vrnila potrditveno sporočilo iz potrditve, ki eventualno kaže na HEAD (neke vrste git log -1
).
LibGit2Sharp
Če pišete aplikacijo .NET ali Mono, je Libgit2Sharp (https://github.com/libgit2/libgit2sharp) to, kar iščete. Vezave so napisane v C# in veliko skrbnosti je bilo dane za ovitje surovih klicev Libgit2 s CLR API-ji, ki dajejo bolj domač občutek. Tako je videti naš primer programa:
new Repository(@"C:\path\to\repo").Head.Tip.Message;
Za namizne aplikacije Windows obstaja celo paket NuGet, ki vam bo pomagal hitro začeti.
objective-git
Če se vaša aplikacija poganja na platformi Apple, verjetno uporabljate objektni C kot vaš jezik implementacije. ObjectiveGit (https://github.com/libgit2/objective-git) je ime vezave Libgit2 za to okolje. Primer programa je videti takole:
GTRepository *repo =
[[GTRepository alloc] initWithURL:[NSURL fileURLWithPath: @"/path/to/repo"] error:NULL];
NSString *msg = [[[repo headReferenceWithError:NULL] resolvedTarget] message];
ObjectiveGit je polno interoperabilen s Swiftom, torej se ne bojte, če ste pustili objektni C zadaj.
pygit2
Vezave za Libgit2 v Pythonu so imenovane Pygit2 in lahko se jih najde na https://www.pygit2.org/. Naš primer programa:
pygit2.Repository("/path/to/repo") # open repository
.head # get the current branch
.peel(pygit2.Commit) # walk down to the commit
.message # read the message
Nadaljnje branje
Seveda je polno obravnavanje zmožnosti Libgit2 izven obsega te knjige.
Če želite več informacij o samem Libgit2, je na voljo dokumentacija API na https://libgit2.github.com/libgit2 in skupek vodnikov na https://libgit2.github.com/docs.
Za ostale povezave preverite zapakiran README
in teste; tam so pogostokrat na voljo majhni vodniki in kazalci k nadaljnjemu branju.