Git
Chapters ▾ 2nd Edition

A2.3 Dodatek B: Vdelava Gita 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 Gita napisanega izvorno v Javi in je široko uporabljena v skupnosti Java. Projekt JGit je pod okriljem Eclipse in njegov dom je moč najti na https://www.eclipse.org/jgit/.

Nastavitve

Na voljo je število načinov za povezavo vašega projekta z JGit in začetkov pisanja kode z njim. Verjetno najenostavnejši je uporaba Mavena — 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 sčasoma najverjetneje povečala, ko to berete; preverite https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit za posodobljene informacije 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 na https://www.eclipse.org/jgit/download. Vgradite jih lahko v svoj projekt z naslednjim pogonom ukaza:

$ 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

Napeljava

JGit ima dva osnovna nivoja API-ja: napeljavo in keramiko. Terminologija za to dvoje prihaja iz samega Gita in JGit je v grobem razdeljen na iste vrste področij: API-ji keramike 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 so API-ji napeljave namenjeni neposredni interakciji z objekti repozitorija nižjega nivoja.

Začetna točka za večino sej JGit je razred Repository in prva stvar, ki jo boste želeli narediti, je ustvariti instanco iz njega. Za repozitorij na osnovi datotečnega sistema (da, JGit omogoč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, če vaš program točno ve ali pa ne, 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.

Ko imate enkrat instanco Repository, lahko z njo naredite vse vrste stvari. Tu je hiter primer:

// 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 dogaja kar veliko, torej pojdimo skozi razdelke po enega na enkrat.

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

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

Naslednji dve vrstici prikazujeta, kako naložiti golo vsebino objekta. V tem primeru kličemo ObjectLoader.copyTo(), da pretoči vsebine objekta neposredno 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 InputStreamu podoben objekt, ki lahko prebere surovi objekt podatkov, ne da povleče vse naenkrat v spomin.

Naslednjih nekaj vrstic prikazuje, kaj vzame, da ustvari novo vejo. Ustvarimo instanco RefUpdate, nastavimo nekaj parametrov in kličemo .update(), da sprožimo spremembo. Neposredno 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 pridobiti vrednost user.name iz nastavitvenih datotek Git. Instanca Config uporablja repozitorij, ki smo ga prej odprli 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 API-ja napeljave; na voljo je veliko več metod in razredov. Kar tu ni prikazano, je tudi način, kako JGit upravlja z napakami, kar je z uporabo izjem. API-ji JGita včasih vržejo standardne izjeme Java (kot je IOException), vendar je ponujena cela množica določenih tipov izjem JGIT (kot so NoRemoteRepositoryException, CorruptObjectException in NoMergeBaseException).

Keramika

API-ji napeljave so nekoliko zaključeni, vendar jih je lahko težavno nizati skupaj, da se dosežejo skupni cilji, kot je dodajanje datoteke indeksu ali ustvarjanje nove potrditve. JGit ponuja skupek višje nivojskih API-jev, da vam pri tem pomaga, in vnosna točka tem API-jem je razred Git:

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

Razred Git ima lep skupek visoko nivojskih metod v stilu gradnje, 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 objekt ukaza, ki vam omogoča verižiti klice metod, da nastavijo parametre, ki so izvedeni, ko kličete .call(). V tem primeru sprašujemo daljavo origin za oznake, vendar ne pa za glave. Bodite pozorni tudi na uporabo objekta za overjanje CredentialsProvider.

Mnogi ostali ukazi so na voljo preko razreda Git, vključno z add, blame, commit, clean, push, rebase, revert in reset, vendar niso omejeni le na te.

Nadaljnje branje

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

scroll-to-top