Git
Chapters ▾ 2nd Edition

A2.3 Appendix B: Vključevanje Git-a v vašo aplikacijo - JGit

JGit

Če želite uporabljati Git znotraj programa Java, je na voljo lastnosti polna knjižnica Git imenovana JGit. JGit je relativno lastnosti polna implementacija Git-a napisanega izvorno v Javi in je široko uporabljena v skupnosti Java. Projekt JGit je pod okriljem Eclipse in njegov dom je moč najti na http://www.eclipse.org/jgit.

Nastavitve

Na voljo je število načinov za povezavo vašega projekta z JGit in začetkom pisanja kode pod njim. Verjetno najenostavnejši je uporaba Maven-a - integracija je dosežena z dodajanjem sledečih odrezkov znački `<dependencies>`v vaši datoteki pom.xml:

<dependency>
    <groupId>org.eclipse.jgit</groupId>
    <artifactId>org.eclipse.jgit</artifactId>
    <version>3.5.0.201409260305-r</version>
</dependency>

version se bo najverjetneje povečevala tekom časa, ko to berete; preverite http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit za nalaganje informaij repozitorija. Ko je to enkrat narejeno bo Maven avtomatično zahteval in uporabljal knjižnice JGit, ki jih boste potrebovali.

Če bi raje upravljali binarne odvisnosti sami, so vnaprej zgrajene zagonske datoteke JGit na voljo iz http://www.eclipse.org/jgit/download. Zgradite jih lahko v vaš projekt s pogonom ukaza sledeče:

javac -cp .:org.eclipse.jgit-3.5.0.201409260305-r.jar App.java
java -cp .:org.eclipse.jgit-3.5.0.201409260305-r.jar App

Vodovod

JGit ima dva osnovna nivoja API-ja: vodovod in keramika. Terminologija za to dvoje prihaja iz samega Git-a in JGit je razdeljen v groben iste vrste področij: porcelan API-ji so prijazno ospredje za pogoste akcije na nivoju uporabnika (vrsta stvari, ki bi jih običajni uporabnik uporabil za orodje ukazne vrstice Git) medtem ko vodovod API-ji so za interakcijo z objekti repozitorija nižjega nivoja direktno.

Začetna točka za večino sej JGit je razred Repository in prva stvar, ki jo boste želeli narediti, da ustvarite instanco iz njega. Za repositorij na osnovi datotečnega sistema (da, JGit omoogoča ostale modele shranjevanja) je to urejeno z uporabo FileRepositoryBuilder:

// Create a new repository
Repository newlyCreatedRepo = FileRepositoryBuilder.create(
    new File("/tmp/new_repo/.git"));
newlyCreatedRepo.create();

// Open an existing repository
Repository existingRepo = new FileRepositoryBuilder()
    .setGitDir(new File("my_repo/.git"))
    .build();

Graditelj ima učinkovit API za ponujanje vseh stvari, ki jih potrebuje, da najde repozitorij Git, bodisi ali ne vaš program točno ve, kje je lociran. Uporablja lahko spremenljivke okolja (.readEnvironment()), začne iz mesta v delovnem direktoriju in išče (.setWorkTree(…).findGitDir()), ali pa samo odpre znani direktorij .git kot zgoraj.

Enkrat ko imate instanco Repository, lahko z njim naredite vse vrste stvari. Tu je hitro vzorčenje:

// Get a reference
Ref master = repo.getRef("master");

// Get the object the reference points to
ObjectId masterTip = master.getObjectId();

// Rev-parse
ObjectId obj = repo.resolve("HEAD^{tree}");

// Load raw object contents
ObjectLoader loader = repo.open(masterTip);
loader.copyTo(System.out);

// Create a branch
RefUpdate createBranch1 = repo.updateRef("refs/heads/branch1");
createBranch1.setNewObjectId(masterTip);
createBranch1.update();

// Delete a branch
RefUpdate deleteBranch1 = repo.updateRef("refs/heads/branch1");
deleteBranch1.setForceUpdate(true);
deleteBranch1.delete();

// Config
Config cfg = repo.getConfig();
String name = cfg.getString("user", null, "name");

Tu se kar veliko dogaja, torej pojdimo skozi po eno sekcijo na enkrat.

Prva vrstica dobi kazalec na referenco master. JGit avtomatično vzame dejanski master ref, ki domuje v refs/heads/master in vrne objekt, ki vam omogoča ujeti informacije o referenci. Dobite lahko ime (getName()) in bodisi tarčo objekta direktne reference (.getObjectId()) ali referenco, ki kaže na simbolični ref (.getTarget()). Objekti ref so tudi uporabljeni, da predstavljajo reference značk in objektov, tako da lahko vprašate, če je značka “peeled” - olupljena, kar pomeni, da kaže na končno tarčo (potencialno dolgega) niza objektov značke.

Druga vrstica dobi tarčo reference master, ki je vrnjena kot instanca ObjectId. ObjectId predstavlja SHA-1 razpršitev objekta, ki lahko ali ne obstaja v podatkovni bazi objekta Git. Tretja vrstica je podobna, vendar prikazuje kako JGit upravlja s sintakso rev-parse (za več o tem, glejte Branch References); lahko podate katerokoli določilo objekta, ki ga Git razume in JGit bo vrnil bodisi veljavni ObjectId za ta objekt ali null.

Naslednji dve vrstici prikazujeta kako naložiti golo vsebino objekta. V tem primeru kličemo ObjectLoader.copyTo(), da pretok vsebine objekta direktno v stdout, vendar ObjectLoader ima tudi metode za pisanje tipa in velikosti objekta kot tudi vrne bajtno polje. Za velike objekte (kjer .isLarge() vrne true), lahko kličete .openStream(), da dobite InputStream-u podoben objekt, ki lahko prebere surovi objekt podatkov brez, da potegne vse v spomin naenkrat.

Naslednjih nekaj vrstic prikazuje, kaj vzame, da ustvari novo vejo. Ustvarimo instanco RefUpdate, nastavimo nekaj parametrov in kličemo .update(), da sprožimo spremembo. Direktno temu kar sledi, je koda za izbris te iste veje. Pomnite, da je .setForceUpdate(true) obvezen, da to deluje; drugače bo .delete() klic vrnil REJECTED in nič se ne bo zgodilo.

Zadnji primer prikazuje, kako ujeti user.name vrednost iz nastavitvenih datotek Git. Instanca Config uporablja repozitorij, ki smo ga odprli prej za lokalne nastavitve vendar bo avtomatično odkril globalne in sistemske nastavitvene datoteke in prebral vrednosti tudi iz njih.

To je samo majhen primer celotnega vodovodnega API-ja; na voljo je veliko več metod in razredov. Tudi kar ni prikazano tu, je način, kako JGit upravlja z napakami, kar je skozi uporabo izjem. API-ji JGit-a včasih vržejo standardne Java izjeme (kot je IOException), vendar so gostitelji JGIT določenih tipov izjem, ki so tudi ponujene (kot so NoRemoteRepositoryException, CorruptObjectException in NoMergeBaseException).

Porcelan

API-ji vodovoda so nekoliko zaključeni, vendar jih je lahko težavno nizati skupaj, da se doseže skupne cilje, kot je dodajanje datoteke indeks-u ali ustvarjanje novega pošiljanja. JGit ponuja skupek višje-nivojskih API-jev, da vam pri tem pomaga in vnosna točka tem API-je je razred Git:

Repository repo;
// construct repo...
Git git = new Git(repo);

Razred Git ima lep skupek visoko-nivojskih builder-stilskih metod, ki so lahko uporabljene za konstrukcijo nekega lepega kompleksnega obnašanja. Poglejmo primer - narediti nekaj kot je git ls-remote:

CredentialsProvider cp = new UsernamePasswordCredentialsProvider("username", "p4ssw0rd");
Collection<Ref> remoteRefs = git.lsRemote()
    .setCredentialsProvider(cp)
    .setRemote("origin")
    .setTags(true)
    .setHeads(false)
    .call();
for (Ref ref : remoteRefs) {
    System.out.println(ref.getName() + " -> " + ref.getObjectId().name());
}

To je pogosti vzorec z razredom Git; metode vrnejo ukaz objektov, ki vam omogoča verižiti klice metod, da nastavijo parametre, ki so izvršene, ko kličete .call(). V tem primeru sprašujemo daljavo origin za oznage, vendar ne glave. Opazite tudi uporabo objekta CredentialsProvider za overitev.

Mnogi ostali ukazi so na voljo preko razreda Git, vključno vendar ne omejeno na add, blame, commit, clean, push, rebase, revert in reset.

Nadaljnje branje

To je samo majhen primer JGit-ove polne zmožnosti. Če vas zanima in želite izvedeti več, poglejte tu za informacije in inspiracijo: