Inicio > Git, Java > JGit usando Git desde Java – Parte 2

JGit usando Git desde Java – Parte 2

28 noviembre, 2012 Deja un comentario Go to comments

Continuando con JGit, en este post voy a mostrarles como utilizar el API para hacer inspección en el historial de las revisiones del depósito. Los ejemplos los hago siguiendo en la branch stable-2.0 del proyecto EGit.

  • git log

Al ejecutar este comando tenemos:

El API JGit ofrece la clase Git, que permite instanciar sobre un depósito, objetos que representan los comandos básicos para interactuar con él: Comando de agregración (método add), de fusión (método merge), commit, y también para mostrar el historial (método log).

En el caso del método log, éste retorna un objeto de la clase LogCommand. El método call permite ejecutar un git log básico. Esto retorna la lista con todos los commits encapsualdos en objetos de la clase RevCommit. Esta clase permite tener información sobre el autor del commit, el mensaje, el id, etc…

Git git = new Git(repository);
Iterable<RevCommit> log = git.log().call();
for (Iterator<RevCommit> iterator = log.iterator(); iterator.hasNext();) {
____RevCommit rev = iterator.next();
____System.out.println("-------------------------------");
____System.out.println(rev.getId());
____System.out.println(rev.getAuthorIdent().getName());
____System.out.println(rev.getFullMessage());
}

-------------------------------
Thu Jun 14 00:52:27 CEST 2012
Matthias Sohn
Prepare post 2.0.0.201206130900-r builds
Change-Id: Iaf5a3122829a93c4d9243178d68ce8cecd80a120
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-------------------------------
Wed Jun 13 15:46:40 CEST 2012
Matthias Sohn
EGit v2.0.0.201206130900-r
Change-Id: I44ce41bbd0615ca3c744ff1a6f7bd09f2d5eb87d
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-------------------------------
Wed Jun 13 15:05:55 CEST 2012
Robin Stocker
[stagingView] Don't show other warnings when commit is not allowed
If a commit is not allowed (e.g. in conflicts state), the author and
committer text fields are set to empty. This lead to the status of the
commit message component to be not OK, and a warning was shown: "Invalid
committer specified".
Instead of the warning about the committer, we now show the message why
committing is not allowed at the moment. This message can be further
improved later to help the user, e.g. "Please resolve conflicts and then
commit".
Change-Id: I54ba78ee11d375cddf4d8475059153781b8380a3
Signed-off-by: Robin Stocker <robin@nibor.org>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-------------------------------
Wed Jun 13 10:26:33 CEST 2012
Matthias Sohn
Update documentation for EGit 2.0
Change-Id: I1c11bd7a7f0e4922dfce4d7300bc18dcd12508a4
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
*******
  • git log –since=”6 months ago” –author=”Stocker”

El comando git log nos devuelve todo el histórico. Por eso los filtros son importantes para reducir los resultados obtenidos. Los filtros permiten indicar un intervalo de tiempo o incluso un autor específico, como en el comando que vamos a ejecutar:

En JGit, la clase RevWalk representa un objeto que puede visitar los diferentes commits de un depósito. Lo que es verdaderamente interesante con esta clase es que tiene un método que permite establecer los diferentes filtros que queremos aplicar sobre el historial del depósito. Simplemente basta con instanciar un conjunto de objetos de que hereden de la clase RevFilter, como AuthorRevFilter o CommitTimeRevFilter, que son los filtros que usaremos para buscar los commits del autor con apellido Stocker en los últimos 6 meses. El código es el siguiente:

RevWalk walk = new RevWalk(repository);
walk.markStart(walk.parseCommit(repository.resolve("HEAD")));
List<RevFilter> filters = new ArrayList<RevFilter>();
// FILTRO DE AUTOR
filters.add(AuthorRevFilter.create("Stocker"));
// FILTRO DE TIEMPO
GregorianCalendar calendar = new GregorianCalendar();
calendar.add(Calendar.MONTH, -6);
filters.add(CommitTimeRevFilter.between(calendar.getTime(), new Date()));
// COMBINACION DE FILTROS EN MODO AND
walk.setRevFilter(AndRevFilter.create(filters));


for (Iterator<RevCommit> iterator = walk.iterator(); iterator.hasNext();) {
____RevCommit rev = iterator.next();
____System.out.println("-------------------------------");
____System.out.println(rev.getName());
____System.out.println(rev.getAuthorIdent().getName());
____System.out.println(new Date(Long.valueOf(String.valueOf(rev.getCommitTime())) * 1000));
____System.out.println(rev.getShortMessage());
}
walk.release();
wa
lk.reset();

-------------------------------
fb56f56b8b124deee0a21db1db26d3c96ab57f59
Robin Stocker
Wed Jun 13 15:05:55 CEST 2012
[stagingView] Don't show other warnings when commit is not allowed
-------------------------------
f0d77b4e01d6e8f50b4c897288c1a73c165d4a32
Robin Stocker
Mon Jun 04 22:38:14 CEST 2012
[repoView] Release RevWalks used in label provider
-------------------------------
a781598a482eff97cbb02c985a78e7841e79b7be
Robin Stocker
Sun Jun 03 21:46:07 CEST 2012
[historyView] Fix tooltip position on Ref hover
-------------------------------
c4089bf8f6474ce32c2c4b2697e25b3f3428ae01
Robin Stocker
Thu May 31 22:58:19 CEST 2012
[historyView] Use jface.text framework for ref tooltips
  • git diff entre commits

Si nos damos cuenta, la información que retorna el comando git log, sólo nos indica quién y cuándo se hizo un commit, pero no nos dice cuáles fueron los cambios. Esta información obviamente puede tener una gran relevancia. La siguiente figura, muestra los cambios hechos en el ultimo commit registrado sobre la branch 2.0-stable, usando la interfaz grafica de gitk.

Vamos a listar estos archivos desde Java. Para eso, vamos a suponer que mientras recorremos una lista de revisiones, tenemos dos revisiones consecutivas que llamaremos oldRevision y newRevision. Lo primero que debemos hacer es recuperar el tree de cada revisión, es decir la representación del estado de los archivos tras el commit. Los tree los guardamos en objetos de la clase CanonicalTreeParser que nos permitiran recorrerlos.

private static void listDiffs(Repository repository, RevCommit oldRevision, RevCommit newRevision) throws GitAPIException, IncorrectObjectTypeException, IOException {
____ObjectReader reader = repository.newObjectReader();
____CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
____oldTreeIter.reset(reader, oldRevision.getTree());
____CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
____newTreeIter.reset(reader, newRevision.getTree());
____getDiffEntries(repository, newTreeIter, oldTreeIter);
}

El método getDiffEntries sera en encargado de hacer la comparación entre los dos trees recuperados. Para ello, volvemos a servirnos de la clase Git, que nos permite instanciar un objeto DiffCommand. el código es el siguiente:

private static void getDiffEntries(Repository repository, CanonicalTreeParser newTreeIter, CanonicalTreeParser oldTreeIter) throws GitAPIException, IOException {
____Git git = new Git(repository);
____List<DiffEntry> diffs= git.diff()
____.setNewTree(newTreeIter).setOldTree(oldTreeIter).call();

____for(DiffEntry diff : diffs) {
________System.out.println(diff.toString());
____}
}

La salida del programa concuerda con los archivos que muestra la figura anterior, en el cuadro de abajo a la derecha:

DiffEntry[MODIFY org.eclipse.egit-feature/feature.xml]
DiffEntry[MODIFY org.eclipse.egit-feature/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.core.test/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.core.test/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.core/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.core/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.doc/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.doc/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.import-feature/feature.xml]
DiffEntry[MODIFY org.eclipse.egit.import-feature/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.import/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.import/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.mylyn-feature/feature.xml]
DiffEntry[MODIFY org.eclipse.egit.mylyn-feature/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.mylyn.ui.test/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.mylyn.ui.test/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.mylyn.ui/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.psf-feature/feature.xml]
DiffEntry[MODIFY org.eclipse.egit.psf-feature/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.repository/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.source-feature/feature.xml]
DiffEntry[MODIFY org.eclipse.egit.source-feature/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.target/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.target/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.ui.test/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.ui.test/pom.xml]
DiffEntry[MODIFY org.eclipse.egit.ui/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit.ui/pom.xml]
DiffEntry[MODIFY org.eclipse.egit/META-INF/MANIFEST.MF]
DiffEntry[MODIFY org.eclipse.egit/pom.xml]
DiffEntry[MODIFY pom.xml]

Si desean ver el código completo para ejecutar el git diff, hacer clic aquí.

Categorías:Git, Java Etiquetas: , , , ,
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Hype Driven Development

coz' geeks love new stuff !

My experiments with SCRUM

Site to discuss Agile (Scrum, XP, etc) concepts and ideas.

CommitStrip

Mi propia cheatsheet...

Chris Aniszczyk's (zx) diatribe

work. life. open source. diatribes.

GermanTrevi

repositorio de mi mente...

A %d blogueros les gusta esto: