diff --git a/book/B-embedding-git/1-embedding-git.asc b/book/B-embedding-git/1-embedding-git.asc index d1845f15..4e34b822 100644 --- a/book/B-embedding-git/1-embedding-git.asc +++ b/book/B-embedding-git/1-embedding-git.asc @@ -1,10 +1,10 @@ [appendix] -== Embedding Git in your Applications +== Integrando Git en tus Aplicaciones -If your application is for developers, chances are good that it could benefit from integration with source control. -Even non-developer applications, such as document editors, could potentially benefit from version-control features, and Git's model works very well for many different scenarios. +Si tu aplicación es para desarrolladores, es muy probable que pueda beneficiarse de la integración con el control de código fuente. +Incluso las aplicaciones que no sean para desarrolladores, tales como editores de documentos, podrían beneficiarse de las características de control de versiones, y el modelo de Git funciona muy bien para muchos escenarios diferentes. -If you need to integrate Git with your application, you have essentially three choices: spawning a shell and using the Git command-line tool; Libgit2; and JGit. +Si necesitas integrar Git con tu aplicación, tienes básicamente tres opciones: generar un shell y usar la herramienta de línea de comandos de Git; Libgit2; y JGit. include::sections/command-line.asc[] diff --git a/book/B-embedding-git/sections/command-line.asc b/book/B-embedding-git/sections/command-line.asc index 01d53691..741b1d42 100644 --- a/book/B-embedding-git/sections/command-line.asc +++ b/book/B-embedding-git/sections/command-line.asc @@ -1,16 +1,16 @@ -=== Command-line Git +=== Git mediante Línea de Comandos -One option is to spawn a shell process and use the Git command-line tool to do the work. -This has the benefit of being canonical, and all of Git's features are supported. -This also happens to be fairly easy, as most runtime environments have a relatively simple facility for invoking a process with command-line arguments. -However, this approach does have some downsides. +Una opción es generar un proceso shell y utilizar la herramienta de línea de comandos de Git para hacer el trabajo. +Esto tiene la ventaja de ser canónico, y todas las características de Git estan soportadas. +Esto también resulta ser bastante fácil, ya que la mayoría de los entornos de ejecución tienen una forma relativamente sencilla para invocar un proceso con argumentos de la línea de comandos. +Sin embargo, este enfoque tiene algunas desventajas. -One is that all the output is in plain text. -This means that you'll have to parse Git's occasionally-changing output format to read progress and result information, which can be inefficient and error-prone. +Una es que toda la salida es un texto plano. +Esto significa que tendrás que analizar el formato de salida cambiante de Git para leer la información de progreso y de resultado, lo que puede ser ineficiente y propenso a errores. -Another is the lack of error recovery. -If a repository is corrupted somehow, or the user has a malformed configuration value, Git will simply refuse to perform many operations. +Otra es la falta de recuperación de errores. +Si un repositorio está dañado de alguna manera, o el usuario tiene un valor de configuración con formato incorrecto, Git simplemente se negará a realizar muchas operaciones. -Yet another is process management. -Git requires you to maintain a shell environment on a separate process, which can add unwanted complexity. -Trying to coordinate many of these processes (especially when potentially accessing the same repository from several processes) can be quite a challenge. +Otra más es la gestión de procesos. +Git requiere que mantengas un entorno de shell en un proceso separado, lo que puede añadir complejidad no deseada. +Tratar de coordinar muchos de estos procesos (especialmente cuando se accede potencialmente el mismo repositorio de varios procesos) puede ser todo un reto. diff --git a/book/B-embedding-git/sections/jgit.asc b/book/B-embedding-git/sections/jgit.asc index fa0111aa..50b7777e 100644 --- a/book/B-embedding-git/sections/jgit.asc +++ b/book/B-embedding-git/sections/jgit.asc @@ -1,14 +1,14 @@ === JGit (((jgit)))(((java))) -If you want to use Git from within a Java program, there is a fully featured Git library called JGit. -JGit is a relatively full-featured implementation of Git written natively in Java, and is widely used in the Java community. -The JGit project is under the Eclipse umbrella, and its home can be found at http://www.eclipse.org/jgit[]. +Si deseas utilizar Git desde dentro de un programa Java, hay una biblioteca Git completamente funcional llamada JGit. +JGit es una implementación relativamente completa de Git escrita de forma nativa en Java, y que se utiliza ampliamente en la comunidad Java. +El proyecto JGit está bajo el paraguas de Eclipse, y su "casa" puede encontrarse en http://www.eclipse.org/jgit[]. ==== Getting Set Up -There are a number of ways to connect your project with JGit and start writing code against it. -Probably the easiest is to use Maven – the integration is accomplished by adding the following snippet to the `` tag in your pom.xml file: +Hay varias formas de conectar tu proyecto con JGit y empezar a escribir código usando éste. +Probablemente la más fácil sea utilizar Maven -la integración se consigue añadiendo el siguiente fragmento a la etiqueta `` en tu archivo pom.xml: [source,xml] ---- @@ -19,11 +19,11 @@ Probably the easiest is to use Maven – the integration is accomplished by addi ---- -The `version` will most likely have advanced by the time you read this; check http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit[] for updated repository information. -Once this step is done, Maven will automatically acquire and use the JGit libraries that you'll need. +La `version` es bastante probable que habrá avanzado para el momento en que leas esto; comprueba http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit[] para obtener información actualizada del repositorio. +Una vez que se realiza este paso, Maven automáticamente adquirirá y utilizará las bibliotecas JGit que necesites. -If you would rather manage the binary dependencies yourself, pre-built JGit binaries are available from http://www.eclipse.org/jgit/download[]. -You can build them into your project by running a command like this: +Si prefieres gestionar las dependencias binarias tú mismo, binarios JGit pre-construidos están disponibles en http://www.eclipse.org/jgit/download[]. +Puedes construirlos en tu proyecto ejecutando un comando como el siguiente: [source,console] ---- @@ -31,13 +31,13 @@ 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 ---- -==== Plumbing +==== Fontanería -JGit has two basic levels of API: plumbing and porcelain. -The terminology for these comes from Git itself, and JGit is divided into roughly the same kinds of areas: porcelain APIs are a friendly front-end for common user-level actions (the sorts of things a normal user would use the Git command-line tool for), while the plumbing APIs are for interacting with low-level repository objects directly. +JGit tiene dos niveles básicos de la API: fontanería y porcelana. +La terminología de éstos proviene de Git, y JGit se divide en más o menos los mismos tipos de áreas: las API de porcelana son un front-end amigable para las acciones comunes a nivel de usuario (el tipo de cosas para las que un usuario normal utilizaría la herramienta de línea de comandos de Git), mientras que las API de fontanería son para interactuar directamente a bajo nivel con los objetos del repositorio. -The starting point for most JGit sessions is the `Repository` class, and the first thing you'll want to do is create an instance of it. -For a filesystem-based repository (yes, JGit allows for other storage models), this is accomplished using `FileRepositoryBuilder`: +El punto de partida para la mayoría de las sesiones JGit es la clase `Repository`, y la primera cosa que querrás hacer es crear una instancia de la misma. +Para un repositorio basado en sistema de archivos (sí, JGit permite otros modelos de almacenamiento), esto se logra utilizando `FileRepositoryBuilder`: [source,java] ---- @@ -51,11 +51,10 @@ Repository existingRepo = new FileRepositoryBuilder() .build(); ---- -The builder has a fluent API for providing all the things it needs to find a Git repository, whether or not your program knows exactly where it's located. -It can use environment variables (`.readEnvironment()`), start from a place in the working directory and search (`.setWorkTree(…).findGitDir()`), or just open a known `.git` directory as above. +El constructor tiene una API fluida para proporcionar todo lo que necesitas para encontrar un repositorio Git, tanto si tu programa sabe exactamente donde se encuentra como si no. +Puede utilizar variables de entorno ((`.readEnvironment()`), empezar a partir de un lugar en el directorio de trabajo y buscar (`.setWorkTree(…).findGitDir()`), o simplemente abrir un directorio `.git` conocido como más arriba. -Once you have a `Repository` instance, you can do all sorts of things with it. -Here's a quick sampling: +Una vez que tengas una instancia `Repository`, se pueden hacer todo tipo de cosas con ella. He aquí una muestra rápida: [source,java] ---- @@ -87,37 +86,37 @@ Config cfg = repo.getConfig(); String name = cfg.getString("user", null, "name"); ---- -There's quite a bit going on here, so let's go through it one section at a time. +Hay bastantes cosas que suceden aquí, así que vamos a examinarlo sección a sección. -The first line gets a pointer to the `master` reference. -JGit automatically grabs the _actual_ master ref, which lives at `refs/heads/master`, and returns an object that lets you fetch information about the reference. -You can get the name (`.getName()`), and either the target object of a direct reference (`.getObjectId()`) or the reference pointed to by a symbolic ref (`.getTarget()`). -Ref objects are also used to represent tag refs and objects, so you can ask if the tag is ``peeled,'' meaning that it points to the final target of a (potentially long) string of tag objects. +La primera línea consigue un puntero a la referencia `master`. +JGit obtiene automáticamente la referencia master _real_, que reside en `refs/heads/master`, y devuelve un objeto que te permite obtener información acerca de la referencia. +Puedes obtener el nombre (`.getName()`), y también el objeto destino de una referencia directa (`.getObjectId()`) o la referencia a la que apunta mediante una referencia simbólica (`.getTarget()`). +Los objetos Ref también se utilizan para representar referencias a etiquetas y objetos, por lo que puedes preguntar si la etiqueta está ''pelada'', lo que significa que apunta al objetivo final de una (potencialmente larga) cadena de texto de objetos etiqueta. -The second line gets the target of the `master` reference, which is returned as an ObjectId instance. -ObjectId represents the SHA-1 hash of an object, which might or might not exist in Git's object database. -The third line is similar, but shows how JGit handles the rev-parse syntax (for more on this, see <<_branch_references>>); you can pass any object specifier that Git understands, and JGit will return either a valid ObjectId for that object, or `null`. +La segunda línea obtiene el destino de la referencia `master`, que se devuelve como una instancia ObjectId. +ObjectId representa el hash SHA-1 de un objeto, que podría o no existir en la base de datos de objetos de Git. +La tercera línea es similar, pero muestra cómo maneja JGit la sintaxis rev-parse (para más información sobre esto, consulta <<_branch_references>>); puedes pasar cualquier especificador de objeto que Git entienda, y JGit devolverá una ObjectId válida para ese objeto, o `null`. -The next two lines show how to load the raw contents of an object. -In this example, we call `ObjectLoader.copyTo()` to stream the contents of the object directly to stdout, but ObjectLoader also has methods to read the type and size of an object, as well as return it as a byte array. -For large objects (where `.isLarge()` returns `true`), you can call `.openStream()` to get an InputStream-like object that can read the raw object data without pulling it all into memory at once. +Las dos líneas siguientes muestran cómo cargar el contenido en bruto de un objeto. +En este ejemplo, llamamos a `ObjectLoader.copyTo()` para transmitir el contenido del objeto directamente a la salida estándar, pero ObjectLoader también tiene métodos para leer el tipo y el tamaño de un objeto, así como devoverlo como un array de bytes. +Para objetos grandes (donde `.isLarge()` devuelve true), puedes llamar a `.openStream()` para obtener un objeto similar a InputStream del cual puedes leer los datos del objeto en bruto si almacenarlo en memoria en seguida. -The next few lines show what it takes to create a new branch. -We create a RefUpdate instance, configure some parameters, and call `.update()` to trigger the change. -Directly following this is the code to delete that same branch. -Note that `.setForceUpdate(true)` is required for this to work; otherwise the `.delete()` call will return `REJECTED`, and nothing will happen. +Las siguientes líneas muestran lo que se necesita para crear una nueva rama. +Creamos una instancia RefUpdate, configuramos algunos parámetros, y llamamos a `.update()` para activar el cambio. +Inmediatamente después de esto está el código para eliminar esa misma rama. +Ten en cuenta que se requiere `.setForceUpdate(true)` para que esto funcione; de lo contrario la llamada `.delete()` devolverá `REJECTED`, y no pasará nada. -The last example shows how to fetch the `user.name` value from the Git configuration files. -This Config instance uses the repository we opened earlier for local configuration, but will automatically detect the global and system configuration files and read values from them as well. +El último ejemplo muestra cómo buscar el valor `user.name` a partir de los archivos de configuración de Git. +Este ejemplo de configuración utiliza el repositorio que abrimos anteriormente para la configuración local, pero detectará automáticamente los archivos de configuración global y del sistema y leerá los valores de ellos también. -This is only a small sampling of the full plumbing API; there are many more methods and classes available. -Also not shown here is the way JGit handles errors, which is through the use of exceptions. -JGit APIs sometimes throw standard Java exceptions (such as `IOException`), but there are a host of JGit-specific exception types that are provided as well (such as `NoRemoteRepositoryException`, `CorruptObjectException`, and `NoMergeBaseException`). +Ésta es sólo una pequeña muestra de la API de fontanería completa; hay muchos más métodos y clases disponibles. +Tampoco se muestra aquí la forma en la que JGit maneja los errores, que es a través del uso de excepciones. +La API de JGit a veces lanza excepciones Java estándar (como `IOException`), pero también hay una gran cantidad de tipos de excepciones específicas de JGit que se proporcionan (tales como `NoRemoteRepositoryException`, `CorruptObjectException`, y `NoMergeBaseException`). -==== Porcelain +==== Porcelana -The plumbing APIs are rather complete, but it can be cumbersome to string them together to achieve common goals, like adding a file to the index, or making a new commit. -JGit provides a higher-level set of APIs to help out with this, and the entry point to these APIs is the `Git` class: +Las APIs de fontanería son bastante completas, pero puede ser engorroso encadenarlas juntas para alcanzar objetivos comunes, como la adición de un archivo en el index, o hacer un nuevo commit. +JGit proporciona un conjunto de APIs de más alto nivel para facilitar esto, y el punto de entrada a estas APIs es la clase `Git`: [source,java] ---- @@ -126,8 +125,8 @@ Repository repo; Git git = new Git(repo); ---- -The Git class has a nice set of high-level _builder_-style methods that can be used to construct some pretty complex behavior. -Let's take a look at an example – doing something like `git ls-remote`: +La clase Git tiene un buen conjunto de métodos estilo _builder_ de alto nivel que se pueden utilizar para construir un comportamiento bastante complejo. +Echemos un vistazo a un ejemplo - haciendo algo como `git ls-remote`: [source,java] ---- @@ -143,18 +142,17 @@ for (Ref ref : remoteRefs) { } ---- -This is a common pattern with the Git class; the methods return a command object that lets you chain method calls to set parameters, which are executed when you call `.call()`. -In this case, we're asking the `origin` remote for tags, but not heads. -Also notice the use of a `CredentialsProvider` object for authentication. +Este es un patrón común con la clase Git; los métodos devuelven un objeto de comando que te permite encadenar llamadas a métodos para establecer los parámetros, que se ejecutan cuando se llama `.call()`. +En este caso, estamos solicitando las etiquetas del repositorio remoto `origin`, pero no las cabezas (heads). +Observa también el uso de un objeto `CredentialsProvider` para la autenticación. -Many other commands are available through the Git class, including but not limited to `add`, `blame`, `commit`, `clean`, `push`, `rebase`, `revert`, and `reset`. +Muchos otros comandos están disponibles a través de la clase Git, incluyendo, aunque no limitado, a `add`, `blame`, `commit`, `clean`, `push`, `rebase`, `revert`, y `reset`. -==== Further Reading +==== Otras Lecturas -This is only a small sampling of JGit's full capabilities. -If you're interested and want to learn more, here's where to look for information and inspiration: +Esta es sólo una pequeña muestra de todas las posibilidades de JGit. +Si estás interesado y deseas aprender más, aquí tienes dónde buscar información e inspiración: -* The official JGit API documentation is available online at http://download.eclipse.org/jgit/docs/latest/apidocs[]. - These are standard Javadoc, so your favorite JVM IDE will be able to install them locally, as well. -* The JGit Cookbook at https://github.com/centic9/jgit-cookbook[] has many examples of how to do specific tasks with JGit. -* There are several good resources pointed out at http://stackoverflow.com/questions/6861881[]. +* La documentación API oficial de JGit está disponible en línea en http://download.eclipse.org/jgit/docs/latest/apidocs[]. Estos son Javadoc estándar, por lo que tu IDE JVM favorito será capaz de instalarlos de forma local, también. +* El "libro de cocina" de JGit en https://github.com/centic9/jgit-cookbook[] tiene muchos ejemplos de cómo realizar tareas específicas con JGit. +* Hay varios buenos recursos indicados en http://stackoverflow.com/questions/6861881[]. diff --git a/book/B-embedding-git/sections/libgit2.asc b/book/B-embedding-git/sections/libgit2.asc index 58b57189..7d2c7761 100644 --- a/book/B-embedding-git/sections/libgit2.asc +++ b/book/B-embedding-git/sections/libgit2.asc @@ -1,12 +1,11 @@ === Libgit2 (((libgit2)))(((C))) -Another option at your disposal is to use Libgit2. -Libgit2 is a dependency-free implementation of Git, with a focus on having a nice API for use within other programs. -You can find it at http://libgit2.github.com[]. +Otra opción a tu disposición es utilizar Libgit2. +Libgit2 es una implementación de Git libre de dependencias, con un enfoque en tener una buena API para su uso dentro de otros programas. Puedes encontrarla en http://libgit2.github.com[]. -First, let's take a look at what the C API looks like. -Here's a whirlwind tour: +En primer lugar, echemos un vistazo a la apariencia de la API C. +He aquí una gira relámpago: [source,c] ----- @@ -30,31 +29,31 @@ git_commit_free(commit); git_repository_free(repo); ----- -The first couple of lines open a Git repository. -The `git_repository` type represents a handle to a repository with a cache in memory. -This is the simplest method, for when you know the exact path to a repository's working directory or `.git` folder. -There's also the `git_repository_open_ext` which includes options for searching, `git_clone` and friends for making a local clone of a remote repository, and `git_repository_init` for creating an entirely new repository. +El primer par de líneas abre un repositorio Git. +El tipo `git_repository` representa un identificador a un repositorio con una caché en memoria. +Éste es el método más simple, para cuando se conoce la ruta exacta al directorio de trabajo de un repositorio o carpeta `.git`. +También está el `git_repository_open_ext` que incluye opciones para buscar, `git_clone` y compañía para hacer un clon local de un repositorio remoto, y `git_repository_init` para la creación de un repositorio completamente nuevo. -The second chunk of code uses rev-parse syntax (see <<_branch_references>> for more on this) to get the commit that HEAD eventually points to. -The type returned is a `git_object` pointer, which represents something that exists in the Git object database for a repository. -`git_object` is actually a ``parent'' type for several different kinds of objects; the memory layout for each of the ``child'' types is the same as for `git_object`, so you can safely cast to the right one. -In this case, `git_object_type(commit)` would return `GIT_OBJ_COMMIT`, so it's safe to cast to a `git_commit` pointer. +El segundo fragmento de código utiliza la sintaxis rev-parse (ver <<_branch_references>> para más información) para obtener el commit al HEAD finalmente apunta. +El tipo devuelto es un puntero `git_object`, lo que representa algo que existe en la base de datos de objetos de Git para un repositorio. +`git_object` es en realidad un tipo ''padre'' de varios tipos diferentes de objetos; el diseño de memoria para cada uno de los tipos ''hijo'' es el mismo que para `git_object`, por lo que puedes hacer casting de forma segura hacia la derecha. +En este caso, `git_object_type (commit)` devolvería `GIT_OBJ_COMMIT`, así que es seguro hacer casting a un puntero `git_commit`. -The next chunk shows how to access the commit's properties. -The last line here uses a `git_oid` type; this is Libgit2's representation for a SHA-1 hash. +El siguiente fragmento muestra cómo acceder a las propiedades del commit. +La última línea aquí utiliza un tipo `git_oid`; esta es la representación de Libgit2 para un hash SHA-1. -From this sample, a couple of patterns have started to emerge: +De esta muestra, un par de patrones han comenzado a surgir: -* If you declare a pointer and pass a reference to it into a Libgit2 call, that call will probably return an integer error code. - A `0` value indicates success; anything less is an error. -* If Libgit2 populates a pointer for you, you're responsible for freeing it. -* If Libgit2 returns a `const` pointer from a call, you don't have to free it, but it will become invalid when the object it belongs to is freed. -* Writing C is a bit painful. +* Si se declara un puntero y se pasa una referencia a él en una llamada Libgit2, la llamada devolverá probablemente un código de error entero. + Un valor `0` indica éxito; cualquier otra cosa es un error. +* Si Libgit2 rellena un puntero para tí, eres responsable de liberarlo. +* Si Libgit2 devuelve un puntero `const` desde una llamada, no tienes que liberarlo, pero no será válido cuando el objeto al que pertenece sea liberado. +* Escribir C es un poco doloroso. (((Ruby))) -That last one means it isn't very probable that you'll be writing C when using Libgit2. -Fortunately, there are a number of language-specific bindings available that make it fairly easy to work with Git repositories from your specific language and environment. -Let's take a look at the above example written using the Ruby bindings for Libgit2, which are named Rugged, and can be found at https://github.com/libgit2/rugged[]. +Esto último significa que no es muy probable que estés escribiendo C cuando utilices Libgit2. +Afortunadamente, hay una serie de vínculos específicos del lenguaje disponibles que hacen que sea bastante fácil trabajar con repositorios Git desde su entorno y lenguaje específico. +Echemos un vistazo al ejemplo anterior escrito utilizando los vínculos de Ruby para Libgit2, que llevan el nombre Rugged, y se puede encontrar en https://github.com/libgit2/rugged[]. [source,ruby] ---- @@ -65,10 +64,10 @@ puts "#{commit.author[:name]} <#{commit.author[:email]}>" tree = commit.tree ---- -As you can see, the code is much less cluttered. -Firstly, Rugged uses exceptions; it can raise things like `ConfigError` or `ObjectError` to signal error conditions. -Secondly, there's no explicit freeing of resources, since Ruby is garbage-collected. -Let's take a look at a slightly more complicated example: crafting a commit from scratch +Como se puede ver, el código es mucho menos desordenado. +En primer lugar, Rugged utiliza excepciones; puede elevar cosas como `ConfigError` o `ObjectError` para indicar condiciones de error. +En segundo lugar, no hay liberación explícita de los recursos, ya que Ruby es recolector de basura. +Echemos un vistazo a un ejemplo un poco más complicado: la elaboración de un commit desde cero [source,ruby] ---- @@ -95,29 +94,29 @@ commit_id = Rugged::Commit.create(repo, commit = repo.lookup(commit_id) # <8> ---- -<1> Create a new blob, which contains the contents of a new file. -<2> Populate the index with the head commit's tree, and add the new file at the path `newfile.txt`. -<3> This creates a new tree in the ODB, and uses it for the new commit. -<4> We use the same signature for both the author and committer fields. -<5> The commit message. -<6> When creating a commit, you have to specify the new commit's parents. - This uses the tip of HEAD for the single parent. -<7> Rugged (and Libgit2) can optionally update a reference when making a commit. -<8> The return value is the SHA-1 hash of a new commit object, which you can then use to get a `Commit` object. +<1> Se crea un nuevo blob, que contiene el contenido de un nuevo archivo. +<2> Se rellena el index con el árbol de head commit, y añadimos el nuevo archivo a la ruta `newfile.txt`. +<3> Esto crea un nuevo árbol en la ODB, y lo utiliza para un nuevo commit. +<4> Utilizamos la misma firma, tanto para los campos del autor como del confirmador. +<5> El mensaje del commit. +<6> Al crear un commit, tienes que especificar los nuevos padres del commit. + Éste utiliza la punta de HEAD para un padre único. +<7> Rugged (y Libgit2) pueden actualizar opcionalmente una referencia al hacer un commit. +<8> El valor de retorno es el hash SHA-1 de un nuevo objeto commit, que luego se puede utilizar para obtener un objeto `Commit`. -The Ruby code is nice and clean, but since Libgit2 is doing the heavy lifting, this code will run pretty fast, too. -If you're not a rubyist, we touch on some other bindings in <<_libgit2_bindings>>. +El código en Ruby es bonito y limpio, pero ya que Libgit2 está haciendo el trabajo pesado, este código se ejecutará bastante rápido, también. +Si no eres un rubyista, tocamos algunos otros vínculos en <<_libgit2_bindings>>. -==== Advanced Functionality +==== Funcionalidad Avanzada -Libgit2 has a couple of capabilities that are outside the scope of core Git. -One example is pluggability: Libgit2 allows you to provide custom ``backends'' for several types of operation, so you can store things in a different way than stock Git does. -Libgit2 allows custom backends for configuration, ref storage, and the object database, among other things. +Libgit2 tiene un par de capacidades que están fuera del ámbito del núcleo de Git. +Un ejemplo es la conectividad: Libgit2 te permite proporcionar ''backends'' a medida para varios tipos de operaciones, por lo que puedes almacenar las cosas de una manera diferente a como hace el Git original. +Libgit2 permite backends personalizados para la configuración, el almacenamieno de referencias, y la base de datos de objetos, entre otras cosas. -Let's take a look at how this works. -The code below is borrowed from the set of backend examples provided by the Libgit2 team (which can be found at https://github.com/libgit2/libgit2-backends[]). -Here's how a custom backend for the object database is set up: +Echemos un vistazo a cómo funciona esto. +El código siguiente se ha tomado del conjunto de ejemplos de backend proporcionados por el equipo de Libgit2 (que se puede encontrar en https://github.com/libgit2/libgit2-backends[]). +Así es como se configura un backend personalizado para una base de datos de objetos: [source,c] ---- @@ -134,16 +133,16 @@ error = git_repository_open(&repo, "some-path"); error = git_repository_set_odb(odb); // <4> ---- -_(Note that errors are captured, but not handled. We hope your code is better than ours.)_ +_(Ten en cuenta que los errores son capturados, pero no tratados. Esperamos que tu código sea mejor que el nuestro.)_ -<1> Initialize an empty object database (ODB) ``frontend,'' which will act as a container for the ``backends'' which are the ones doing the real work. -<2> Initialize a custom ODB backend. -<3> Add the backend to the frontend. -<4> Open a repository, and set it to use our ODB to look up objects. +<1> Se inicializa un ''frontend'' a una base de datos de objetos (ODB), que actuará como contenedor de los ''backends'', que son los que hacen el trabajo real. +<2> Se inicializa un backend ODB personalizado. +<3> Se añade el backend al frontend. +<4> Se abre un repositorio, y se configura para que use nuestra ODB para buscar objetos. -But what is this `git_odb_backend_mine` thing? -Well, that's the constructor for your own ODB implementation, and you can do whatever you want in there, so long as you fill in the `git_odb_backend` structure properly. -Here's what it _could_ look like: +Pero, ¿qué es esta cosa `git_odb_backend_mine`? +Bien, ese es el constructor para tu propia implementación ODB, y puedes hacer lo que quieras allí, siempre y cuando rellenes en el `git_odb_backend` la estructura correctamente. +A esto es a lo que _podría_ parecerse: [source,c] ---- @@ -173,41 +172,40 @@ int git_odb_backend_mine(git_odb_backend **backend_out, /*…*/) } ---- -The subtlest constraint here is that `my_backend_struct`'s first member must be a `git_odb_backend` structure; this ensures that the memory layout is what the Libgit2 code expects it to be. -The rest of it is arbitrary; this structure can be as large or small as you need it to be. +La restricción más sutil aquí es que el primer miembro de `my_backend_struct` debe ser una estructura `git_odb_backend`; esto asegura que la disposición de memoria sea la que el código Libgit2 espera. +El resto es arbitrario; esta estructura puede ser tan grande o tan pequeña como necesites que sea. -The initialization function allocates some memory for the structure, sets up the custom context, and then fills in the members of the `parent` structure that it supports. -Take a look at the `include/git2/sys/odb_backend.h` file in the Libgit2 source for a complete set of call signatures; your particular use case will help determine which of these you'll want to support. +La función de inicialización reserva memoria para la estructura, establece el contexto personalizado, y luego rellena los miembros de la estructura `parent` que soporta. +Echa un vistazo al archivo `include/git2/sys/odb_backend.h` en el código fuente de Libgit2 para un conjunto completo de llamadas; tu caso de uso particular te ayudará a determinar cuál de éstas querrás soportar. [[_libgit2_bindings]] -==== Other Bindings - -Libgit2 has bindings for many languages. -Here we show a small example using a few of the more complete bindings packages as of this writing; libraries exist for many other languages, including C++, Go, Node.js, Erlang, and the JVM, all in various stages of maturity. -The official collection of bindings can be found by browsing the repositories at https://github.com/libgit2[]. -The code we'll write will return the commit message from the commit eventually pointed to by HEAD (sort of like `git log -1`). +==== Otros Vínculos (Bindings) +Libgit2 tiene vínculos para muchos lenguajes. +A continuación mostramos un pequeño ejemplo que usa algunos de los paquetes de vínculos más completos a fecha de este escrito; existen bibliotecas para muchos otros idiomas, incluyendo C++, Go, Node.js, Erlang, y la JVM, todos en diferentes etapas de madurez. +La colección oficial de vínculos se puede encontrar navegando por los repositorios en https://github.com/libgit2[]. +El código que escribiremos devolverá el mensaje del commit finalmente apuntado por HEAD (algo así como `git log -1`). ===== LibGit2Sharp (((.NET)))(((C#)))(((Mono))) -If you're writing a .NET or Mono application, LibGit2Sharp (https://github.com/libgit2/libgit2sharp[]) is what you're looking for. -The bindings are written in C#, and great care has been taken to wrap the raw Libgit2 calls with native-feeling CLR APIs. -Here's what our example program looks like: +Si estás escribiendo una aplicación .NET o Mono, LibGit2Sharp (https://github.com/libgit2/libgit2sharp[]) es lo que estás buscando. +Los vínculos están escritos en C#, y se ha tenido gran cuidado de envolver las llamadas a Libgit2 crudo con APIs CLR de apariencia nativa. +Esta es la apariencia de nuestro programa de ejemplo: [source,csharp] ----- new Repository(@"C:\path\to\repo").Head.Tip.Message; ----- -For desktop Windows applications, there's even a NuGet package that will help you get started quickly. +Para las aplicaciones de escritorio de Windows, incluso hay un paquete NuGet que le ayudará a empezar rápidamente. ===== objective-git (((Apple)))(((Objective-C)))(((Cocoa))) -If your application is running on an Apple platform, you're likely using Objective-C as your implementation language. -Objective-Git (https://github.com/libgit2/objective-git[]) is the name of the Libgit2 bindings for that environment. -The example program looks like this: +Si la aplicación se ejecuta en una plataforma de Apple, es muy probable que use Objective-C como su lenguaje de implementación. +Objective-Git (https://github.com/libgit2/objective-git[]) es el nombre de los vínculos Libgit2 para ese entorno. +El programa de ejemplo es el siguiente: [source,objc] ----- @@ -216,14 +214,14 @@ GTRepository *repo = NSString *msg = [[[repo headReferenceWithError:NULL] resolvedTarget] message]; ----- -Objective-git is fully interoperable with Swift, so don't fear if you've left Objective-C behind. +Objective-git es totalmente interoperable con Swift, así que no temas, si has dejado atrás Objective-C. ===== pygit2 (((Python))) -The bindings for Libgit2 in Python are called Pygit2, and can be found at http://www.pygit2.org/[]. -Our example program: +Los vínculos para Libgit2 en Python se llaman Pygit2, y se pueden encontrar en http://www.pygit2.org/[]. +Nuestro programa de ejemplo: [source,python] ---- @@ -234,8 +232,8 @@ pygit2.Repository("/path/to/repo") # open repository ---- -==== Further Reading +==== Otras Lecturas + +Por supuesto, un tratamiento completo de las capacidades de Libgit2 está fuera del alcance de este libro.Si deseas más información sobre Libgit2 en sí mismo, hay documentación de la API en https://libgit2.github.com/libgit2[], y un conjunto de guías en https://libgit2.github.com/docs[]. -Of course, a full treatment of Libgit2's capabilities is outside the scope of this book. -If you want more information on Libgit2 itself, there's API documentation at https://libgit2.github.com/libgit2[], and a set of guides at https://libgit2.github.com/docs[]. -For the other bindings, check the bundled README and tests; there are often small tutorials and pointers to further reading there. +Para otros vínculos (bindings), comprobar el README incorporado y los tests; a menudo hay pequeños tutoriales y enlaces a otras lecturas allí. diff --git a/status.json b/status.json index cd36b2fb..b84eceab 100644 --- a/status.json +++ b/status.json @@ -116,10 +116,10 @@ "sections/zsh.asc": 0 }, "B-embedding-git": { - "1-embedding-git.asc": 0, - "sections/command-line.asc": 0, - "sections/jgit.asc": 0, - "sections/libgit2.asc": 0 + "1-embedding-git.asc": 100, + "sections/command-line.asc": 100, + "sections/jgit.asc": 100, + "sections/libgit2.asc": 100 }, "C-git-commands": { "1-git-commands.asc": 0