Capítulo 3. Creación y mantenimiento del paquete

Tabla de contenidos

Adaptaciones previas al uso de Subversion
Creación de un esqueleto
Edición
Construcción preliminar
Inyección en el repositorio
Preparación de una primera versión
Construcción definitiva
Verificación
Envío al repositorio Debian
Actualización del paquete a una nueva versión del programa

En este capítulo, daré un ejemplo de un paquete razonablemente sencillo, pero completo: un emulador de SNES, conocido como ZSNES. Veremos todas las fases, desde que nos descargamos el código fuente hasta que tenemos el paquete instalado en nuestro sistema y funcionando. Existen muchas guías de creación de paquetes, pero en mi opinión la información se halla bastante fragmentada. De todas formas, el Ubuntu MOTU Team tiene excelentes introducciones acerca del tema en su wiki [5], y también hay una guía por parte de la comunidad Debian [4], aunque en mi opinión la de Ubuntu está más actualizada.

Para simplificar, describiré el proceso de forma secuencial. Sin embargo, lo normal es que sea iterativo, teniendo muchas revisiones intermedias del paquete hasta dejarlo listo para su distribución. Se ven aspectos más avanzados en el siguiente capítulo.

Adaptaciones previas al uso de Subversion

Creación de un esqueleto

Antes de poder introducir los ficheros fuente de nuestro paquete en el repositorio Subversion que previamente preparamos, hemos de crear una primera versión de nuestro paquete.

Tras descargar el código fuente de la página oficial a /tmp/packages/zsnes151src.tar.bz2, crearemos el esqueleto básico del paquete mediante dh_make, una de las muchas herramientas del paquete debhelper de ayuda. Ejecutaremos las siguientes órdenes en una terminal dentro del directorio /tmp/packages:

tar -xjf zsnes151src.tar.bz2
mv zsnes_1_51 zsnes-1.510
cd zsnes-1.510
dh_make -e tudireccion@decorreo -c GPL -s --createorig
      

La carpeta que hemos creado (zsnes-1.510) obedece al convenio seguido por Debian nombrepaquete-versionUpstream, donde la versión del programa original se entiende como una serie de números separados por puntos: así, zsnes-1.510 es más reciente que zsnes-1.6, y menos que zsnes-1.600.

Por otro lado, las opciones pasadas a dh_make son:

-e tudireccion@decorreo

Especifica nuestra dirección email como desarrollador del paquete. Se usa en el registro de cambios (de ahora en adelante el Changelog), y para realizar firmas digitales.

-c GPL

Indica que el código original sigue la General Public License. Otras opciones incluyen la LGPL, BSD o la licencia artística. En otro caso, se nos dejará un hueco (posteriormente veremos dónde) para que lo rellenemos con el texto de la licencia en cuestión.

-s

Existen varios tipos de paquete Debian: de un solo binario, de varios, bibliotecas, o paquetes que emplean CDBS (el resto usan únicamente debhelper). Aquí hemos decidido hacer un paquete de un solo binario, mediante debhelper. Después veremos también cómo hacer un paquete con CDBS.

--createorig

Creamos en el directorio padre un fichero zsnes_1.510.orig.tar.gz con el código fuente original, para poder comparar con la versión que usemos al construir el paquete y volcar las diferencias a un fichero diff.

Edición

Ya tenemos el esqueleto del paquete. Todos los ficheros específicos de él se hallan bajo el directorio /tmp/packages/zsnes-1.510/debian. Si examinamos dicho directorio, veremos que hay un gran número de ficheros. No utilizaremos los ejemplos incluidos, indicados por la extensión .ex, así que los retiraremos, junto con el fichero README.Debian, dado que no hay nada especial acerca de nuestro paquete:

rm debian/*.{ex,EX} debian/README.Debian

Iremos rellenando cada fichero de control en debian con los datos necesarios. Iremos detallando su sintaxis y semántica a lo largo de esta sección.

changelog

Éste es el registro de cambios de nuestro paquete. Aquí iremos indicando los cambios realizados a lo largo de cada versión del paquete, no del software original. Este fichero es el que nuestros usuarios leerán para ver qué hay de nuevo en cada versión del paquete.

Escribiremos nuestra primera entrada:

zsnes (1.510-0ubuntu1) gutsy; urgency=low

  * Versión inicial del paquete

 -- Antonio Garcia <nyoescape@gmail.com>  Fri, 19 Feb 2008 13:49:12 +0100

Vemos cómo la versión actual del paquete junto con su última fecha y autor del cambio se hallan codificados en el registro. También se tiene en cuenta la distribución (en nuestro caso gutsy, de Ubuntu), y la urgencia del cambio (por lo general baja, a menos que se trata de una vulnerabilidad de seguridad o algo del estilo).

Para una misma versión del software original, tendremos distintas versiones del paquete, separadas del número de versión original por un guión, como vemos aquí. En particular, los paquetes de Ubuntu [11] usan el esquema -XubuntuY, indicando que se trata de la Y-ésima versión del paquete de Ubuntu originado de la X-ésima versión del paquete Debian (0 si no proviene de un paquete Debian). Los números de versión de paquete comienzan por 1.

Nota

La razón de este esquema de versionado es para permitir una fácil integración con los paquetes Debian. Normalmente, la política de Ubuntu es sólo crear nuevos paquetes o versiones de éstos si el paquete Debian está anticuado o tiene algún problema. Así, si los de Debian sacan una nueva versión, como la -3, a partir de -2ubuntu3, se reflejará dicha información de forma correcta.

Así, para la próxima versión del paquete, sólo tendremos que añadir la entrada en cuestión al registro, y nuestros guiones de ayuda harán el resto del trabajo.

Nota

Mucho cuidado con el formato del registro, es muy rígido. El espaciado debe ser exactamente el mismo que en el ejemplo, como los dos espacios entre la dirección de correo y la fecha, o el espacio inicial al inicio de la misma línea.

compat

Para este fichero no hay que hacer nada: sólo contiene un número entero, indicando qué versión del paquete debhelper estamos usando.

control

Este fichero es muy importante: describe todos los paquetes que estamos definiendo y enuncia sus dependencias. El formato es también bastante rígido, pero muy simple. Utiliza una serie de campos delimitados por ':' y saltos de línea.

Por supuesto, no existe ninguna receta mágica que nos diga las dependencias de un programa cualquiera. Para ello, normalmente tendremos que examinar la documentación del desarrollador original, y/o el guión de compilación que utilice: como aquí usan las autotools, podríamos consultar src/configure.in. Una buena referencia respecto a las autotools es el Autobook [13].

Por suerte, los desarrolladores de ZSNES han incluido dichas dependencias en docs/install.txt, con lo que no tendremos que ir buscando en los guiones de compilación.

El fichero que usaremos será éste:

Source: zsnes
Section: games
Priority: optional
Maintainer: Antonio Garcia <nyoescape@gmail.com>
Build-Depends: cdbs, debhelper (>= 4.1.0), autotools-dev, fakeroot, 
  desktop-file-utils, g++ (>= 4), libsdl1.2-dev, nasm (>= 0.98), 
  zlib1g-dev (>= 1.2.3), libpng12-dev (>= 1.2), libncurses5-dev, 
  libgl1-mesa-dev
Standards-Version: 3.7.2

Package: zsnes
Architecture: i386
Depends: ${shlibs:Depends}
Description: Emulador de Super Nintendo
 Emulador de la consola Super Nintendo con más funciones disponibles.
 Permite guardar y cargar estados, grabar demostraciones, y aplicar
 diversos filtros. Tiene una compatiblidad inmejorable.

Nota

En éste y en cualquier otro fichero de control de Debian, no debemos olvidar poner un salto de línea justo al final del fichero.

Examinando el fichero de campo a campo, tenemos:

Source: zsnes

Indica que el paquete fuente del que derivan todos se llama "zsnes".

Section: games

Por la política de Debian [2], todo paquete se halla en alguna sección de las disponibles. Así indicamos qué tipo de aplicación es: un juego, un editor, etc.

Priority: optional

Indica la importancia del paquete: desde imprescindibles (required), pasando por importantes (important), estándar (standard), opcionales (optional), y extra (tienen conflicto con alguno de más prioridad).

Maintainer: Antonio Garcia <nyoescape@gmail.com>

Nombre y dirección de contacto del desarrollador del paquete.

Build-Depends: ...

Paquetes requeridos para poder compilar este paquete. Incluye las herramientas para paquetes Debian y las dependencias del propio programa.

Standards-Version: 3.7.2

Versión de la política de Debian que este documento sigue. Realmente se halla compuesta por varios documentos, todos situados bajo el directorio /usr/share/doc/debian-policy.

Package: zsnes

Nombre de uno de los paquetes binarios generados a partir del fuente. Aquí sólo hay uno y tiene el mismo nombre.

Architecture: i386

Arquitectura a la que va dirigida el paquete. Existe una gran variedad de valores, pero nos interesan sobre todo i386 (la IA-32 habitual), source (código fuente) y all (código sin una arquitectura definida, como programas Java, o guiones de algún lenguaje interpretado como Perl o Python).

Depends

Paquetes requeridos para que éste se instale y funcione correctamente. La variable ${shlib:Depends} incluye las dependencias deducidas de forma automática en cuanto a bibliotecas dinámicas se refiere.

Description

Incluye una descripción corta de una sola línea y otra más larga de varias líneas del contenido del paquete. Al igual que siempre, su formato es muy rígido: toda línea de la descripción larga comienza por un espacio, y líneas vacías únicamente añaden un punto ('.'). El campo termina tras la primera línea sin dicho espacio inicial.

Nota

Mucho cuidado con los acentos y demás en el nombre del desarrollador del paquete y otros campos: podrían causar problemas en el interior de la jaula chroot, que sólo tiene soporte para los caracteres ASCII de 7 bits.

copyright

Contiene la información relativa a la licencia del paquete y del programa original, junto con datos acerca de los autores originales, su copyright y de dónde descargamos el código fuente.

En este caso sólo tenemos que rellenar sin más los campos. No se fuerza ningún formato particular sobre el fichero. Es importante sustituir "Upstream Author(s)" por "Upstream Authors" y fijarnos en la información en docs/authors.txt del código fuente, o los verificadores de paquetes que veremos después darán avisos al respecto.

dirs

En este fichero listamos los directorios en que vamos a instalar algún fichero. Si no lo listamos aquí, dicho directorio no va a hallarse disponible durante la construcción del paquete, así que hay que tener cuidado. Las rutas deben de seguir el Filesystem Hierarchy Standard (FHS), disponible a través de la orden man hier desde cualquier terminal.

Algunas rutas importantes y sus contenidos son:

/bin

Ejecutables usados en modo monousuario. Normalmente realizan tareas de mantenimiento a bajo nivel, entre otras cosas. Instalados a través de paquetes Debian.

/boot

Configuración de GRUB, ficheros de imagen de los kernels disponibles, etc.

/dev

Árbol de directorios donde cada dispositivo conectado al sistema es un fichero.

/etc

Ficheros de configuración global (para todos los usuarios).

/home

Directorios de casa de cada usuario, con espacio para cada uno de ellos.

/mnt

Dispositivos externos montados temporalmente: particiones de Windows, CD, DVD, pendrives, etc.

/proc

Árbol de directorios con información del kernel en cada fichero: procesos en ejecución, dispositivos disponibles, etc.

/root

Directorio de casa del superusuario.

/sbin

Ejecutables para uso del superusuario.

/usr

Datos, programas y bibliotecas compartidos por todos los usuarios.

/usr/bin

Ejecutables para todos los usuarios, instalados a través de paquetes Debian.

/usr/lib

Bibliotecas para todos los usuarios, instalados a través de paquetes Debian.

/usr/local

Similar a /usr, pero para uso del administrador.

/usr/share

Datos compartidos por todos los usuarios.

/usr/share/man

Páginas de man disponibles. Toda página se halla dentro de una sección. En particular, la de zsnes estaría en la 1, tras ver las instrucciones disponibles a través de la orden man man.

Dado que tenemos que instalar el ejecutable para todos los usuarios y una página man, nuestro fichero dirs contendrá:

usr/bin
usr/share/man/man1
	  

Nota

En este fichero, las rutas no incluyen una barra inicial, como suelen hacer. Para ser más exactos, son rutas a crear dentro del área temporal de construcción del directorio debian/zsnes, donde colocaremos todos los ficheros tal y como se descomprimirán después bajo el directorio raíz, /.

rules

Aquí está el fichero más importante de todos. Es el que decide qué hay que hacer exactamente para compilar e instalar el paquete completo: documentación, binarios, guiones y ficheros de datos.

De todas formas, en términos generales, no es más que un makefile, si bien uno que puede hacerse muy complejo: el objetivo build compila, install instala dentro del área de construcción del paquete, y clean retira los ficheros generados durante la construcción. Esta última se halla bajo la ruta relativa debian/zsnes respecto del directorio principal del paquete.

Dado que escribir una y otra vez un makefile completo para muchas aplicaciones parecidas era una pérdida de tiempo, se han desarrollado diversos paquetes que factorizan cierta funcionalidad común, como instalar páginas man, tipos MIME, entradas de menú, y cosas del estilo: son los guiones del paquete debhelper. Prácticamente nadie hoy en día desarrolla sus paquetes sin estos guiones.

Algunos desarrolladores han decidido ir un paso más allá, y factorizar reglas para perfiles completos de aplicaciones. Así, si sabemos que se trata de una aplicación desarrollada a través de las autotools, sólo tendremos que aplicar dicho perfil, añadiendo las opciones oportunas que pasar a configure, por ejemplo. Esto es el Common Debian Build System (CDBS) [3], que usaremos en esta guía. Existen perfiles para aplicaciones Python, Perl, GNOME, KDE, Java (basadas en Ant), o incluso para aquellas con un simple makefile.

Por supuesto, para paquetes complicados, este sistema se queda corto, pero son minoría comparados con los demás. Además, no es sólo cuestión de simplicidad: factorizando la mayor proporción posible de reglas, blindaremos nuestro paquete ante cambios en la política de Debian en el futuro.

De todas formas, en general, la comunidad de desarrolladores se halla muy dividida entre usar o no CDBS: aunque factoriza mucha complejidad, resulta difícil de comprender y aprovechar en casos difíciles, a menos que seamos capaces de leer complejos ficheros makefile por nosotros mismos, dado que no existe mucha documentación detallada al respecto: para CDBS, el código es la mejor documentación.

Dado que resulta imposible entender bien CDBS si no se comprende antes el sistema tradicional, en esta sección explicaremos las dos alternativas. Comenzaremos por el sistema "tradicional" con los guiones de debhelper, y luego veremos cómo CDBS factoriza la mayor parte de estas reglas.

Reglas con debhelper

Partiendo del esqueleto que automáticamente nos ha creado dh_make, lo retocamos para este paquete en particular. Vamos a ver qué tal ha quedado, y luego explicaremos qué partes exactamente hemos cambiado, y por qué:

#!/usr/bin/make -f
# -*- makefile -*-

# This file was originally written by Joey Hess and Craig Small. As a
# special exception, when this file is copied by dh-make into a dh-make
# output file, you may use that output file without restriction.  This
# special exception was added by Craig Small in version 0.37 of dh-make.

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

# El código se halla en un subdirectorio, no en la raíz
SRCDIR = src
# Opciones a pasar a configure (--enable-release activa optimizaciones)
CONFIGURE_FLAGS = --disable-cpucheck --enable-release --with-x --with-opengl
# Opciones a usar en el compilador
CFLAGS = -Wall -g

ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
	CFLAGS += -O0
else
	CFLAGS += -O2
endif

configure: configure-stamp
configure-stamp:
	dh_testdir
	touch configure-stamp

build: build-stamp

build-stamp: configure-stamp 
	dh_testdir

	cd $(SRCDIR) && \
          force_arch=i586 ./configure $(CONFIGURE_FLAGS) --prefix=/usr
	$(MAKE) -C $(SRCDIR)

	touch $@

clean:
	dh_testdir
	dh_testroot
	rm -f build-stamp configure-stamp

	# Limpiamos también las herramientas internas usadas por ZSNES en su
	# compilación
	-$(MAKE) -C $(SRCDIR) clean tclean
	# Borramos los ficheros temporales generados por la compilación
	$(RM) $(SRCDIR)/tools/depbuild $(SRCDIR)/config.{log,status,h} $(SRCDIR)/Makefile

	dh_clean 

install: build
	dh_testdir
	dh_testroot
	dh_clean -k 
	dh_installdirs

	$(MAKE) -C $(SRCDIR) install DESTDIR=$(CURDIR)/debian/zsnes

# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.

# Build architecture-dependent files here.
binary-arch: build install
	dh_testdir
	dh_testroot
	dh_installchangelogs 
	dh_installdocs
	dh_installexamples
#	dh_install
#	dh_installmenu
#	dh_installdebconf	
#	dh_installlogrotate
#	dh_installemacsen
#	dh_installpam
#	dh_installmime
#	dh_python
#	dh_installinit
#	dh_installcron
#	dh_installinfo
	dh_installman $(SRCDIR)/linux/zsnes.1
	dh_link
	dh_strip
	dh_compress
	dh_fixperms
#	dh_perl
#	dh_makeshlibs
	dh_installdeb
	dh_shlibdeps
	dh_gencontrol
	dh_md5sums
	dh_builddeb

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

Aunque es bastante largo, conceptualmente es sencillo, gracias al uso de debhelper. Un par de cosas a destacar:

  1. Dado que nuestro código fuente se halla bajo un subdirectorio y no en el directorio raíz del paquete, añadimos una variable SRCDIR, cuyo valor tendremos en cuenta para realizar un cambio de directorio antes de cada orden de compilación.

  2. Por otro lado, CURDIR contiene la ruta del directorio raíz actual desde el cual se está construyendo el paquete. La ruta $(CURDIR)/debian/zsnes contiene un árbol de directorios que sigue el FHS, y se corresponde con los ficheros contenidos en el paquete zsnes.

  3. Bajo el objetivo de compilación build-stamp añadimos las órdenes requeridas para compilar: invocamos al guión configure con las opciones necesarias e iniciamos la compilación. La opción -C pasada a make hace el cambio de directorio antes de comenzar, justo como cd hace para las demás. Hay que hacerlo para cada orden y no al principio debido al hecho de que tras cada orden volvemos al directorio original, al restaurarse el estado anterior del shell.

  4. Repetimos el cambio en la invocación a make para los otros objetivos clean e install. Puede verse cómo se pasa la variable de entorno DESTDIR con la ruta al área de construcción para la instalación: evidentemente, el makefile debe de estar hecho para tener esto en cuenta. Tenemos la suerte para este paquete de que ya sea así: de lo contrario, tendríamos que adaptar dicho fichero, ¡y posiblemente el resto del programa!

  5. Por último, en el objetivo binary-arch tenemos una serie de llamadas a distintos guiones de debhelper. Comentaremos y descomentaremos según nos haga falta: así, por ejemplo, un programa escrito en Perl no necesita dh_link ni dh_strip, al no generar ejecutables.

    Hemos añadido un argumento a dh_installman con la página man que queremos que se instale. Al igual que con todo lo demás, si no hubiera una, tendríamos que crearla nosotros. Lo más usual en este caso es escribir un fichero SGML o XML DocBook y transformarlo a nroff (el formato de las páginas man) mediante docbook-to-man o una hoja de estilos XSLT, por ejemplo. Podríamos partir del ejemplo creado antes por dh_make>, zsnes.sgml.ex.

Un detalle importante: la mayoría de los guiones suponen que los ficheros bajo nuestro directorio debian siguen una serie de convenciones. Por ejemplo, dh_installdocs supone que existe algún fichero debian/zsnes.docs o debian/docs que liste la documentación a instalar. En este caso, aprovechamos la documentación que ya trae ZSNES, con lo que tendríamos esto en debian/docs:

docs/srcinfo.txt
docs/README.SVN
docs/opengl.txt
docs/stdards.txt
docs/authors.txt
docs/todo.txt
docs/install.txt
docs/thanks.txt
docs/support.txt
docs/README.LINUX
docs/readme.txt/about.txt
docs/readme.txt/faq.txt
docs/readme.txt/history.txt
docs/readme.txt/gui.txt
docs/readme.txt/advanced.txt
docs/readme.txt/index.txt
docs/readme.txt/games.txt
docs/readme.txt/netplay.txt
docs/readme.txt/readme.txt
docs/readme.txt/support.txt
docs/readme.htm/styles/release.css
docs/readme.htm/styles/print.css
docs/readme.htm/styles/jipcy.css
docs/readme.htm/styles/radio.css
docs/readme.htm/styles/corner.png
docs/readme.htm/styles/plaintxt.css
docs/readme.htm/styles/shared.css
docs/readme.htm/images/zsneslogo.png
docs/readme.htm/images/netplay.png
docs/readme.htm/images/quick.png
docs/readme.htm/images/saveslot.png
docs/readme.htm/images/cheat.png
docs/readme.htm/images/gui.png
docs/readme.htm/images/config.png
docs/readme.htm/images/game.png
docs/readme.htm/images/f1_menu.png
docs/readme.htm/images/misc.png
docs/readme.htm/netplay.htm
docs/readme.htm/about.htm
docs/readme.htm/games.htm
docs/readme.htm/advanced.htm
docs/readme.htm/gui.htm
docs/readme.htm/support.htm
docs/readme.htm/readme.htm
docs/readme.htm/history.htm
docs/readme.htm/license.htm
docs/readme.htm/faq.htm
docs/readme.htm/index.htm
docs/readme.1st

Nota

Hemos usado ya otro fichero más del mismo estilo: dirs es realmente el fichero que dh_installdirs utiliza, por ejemplo.

Reglas con CDBS

Ahora que ya sabemos cuál es la estructura real de un fichero de reglas, lo reescribiremos empleando CDBS:

#!/usr/bin/make -f
# -*- makefile -*-

DEB_SRCDIR = src

include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk

DEB_CONFIGURE_SCRIPT_ENV   += force_arch=i586
DEB_CONFIGURE_EXTRA_FLAGS   = --disable-cpucheck --with-x \
  --enable-release --with-opengl
DEB_INSTALL_MANPAGES_zsnes += $(DEB_SRCDIR)/linux/zsnes.1

Sorprendentemente, esto es todo: ocho líneas. Los dos include se ocupan de importar los conjuntos de reglas de apoyo para el uso interno de debhelper e implementar el soporte para el perfil de las autotools, respectivamente.

A continuación, pasamos las mismas opciones a configure que antes: pedimos que compile para Pentium o superior, que emplee aceleración 3D y un interfaz gráfico, optimice algo más de lo normal (

--enable-release

) y no intente autodetectar nuestra CPU. Finalmente, indicamos que instale la página man src/linux/zsnes.1 que incluye ZSNES.

Usaremos esta versión de debian/rules para realizar el resto del documento, aprovechando algunas funcionalidades adicionales que aporta. Sin embargo, internamente, es exactamente lo mismo de antes.

Construcción preliminar

Con todo listo, ya podemos construir el paquete. Situándonos en el directorio principal del paquete, /tmp/packages/zsnes-1.510, ejecutaremos:

dpkg-buildpackage -rfakeroot

Tras un cierto tiempo, nos preguntará la contraseña de nuestra clave privada para firmar el paquete de forma automática. Poco después, tendremos en /tmp/packages nuestra primera versión del paquete Debian, zsnes_1.510-0ubuntu1_i386.deb, junto con un fichero .dsc que describe el paquete fuente que también hemos construido, y un diff.gz con las diferencias respecto a las fuentes originales.

Inyección en el repositorio

Con nuestra primera versión del paquete lista, sólo nos queda inyectar el paquete en el repositorio Subversion. Nos situaremos en ~/packages y ejecutaremos:

svn-inject -c2 -o /tmp/packages/zsnes_1.510-0ubuntu1.dsc \
  file:///home/tunombredeusuario/.svnDebian

Tras un cierto tiempo, ya tendremos enviado al repositorio central nuestro paquete, y nuestra copia de trabajo habrá sido creada, con lo que no necesitaremos más /tmp/packages.

La opción -o evita que se guarde el código fuente en el repositorio, usando únicamente archivos tar.gz en el subdirectorio tarballs del directorio principal del repositorio, que no se hallará bajo control de versiones.

El repositorio creado tiene la siguiente estructura:

~/packages/tarballs

Contiene los ficheros tar.gz con las fuentes originales de nuestros paquetes.

~/packages/zsnes/build-area

Se trata del directorio destino en el que se depositarán todos los paquetes y demás ficheros que vayamos produciendo.

~/packages/zsnes/branches

Almacena las distintas ramas de desarrollo. Normalmente contendría las distintas versiones del código original, pero al usar tarballs, es prácticamente inútil en nuestro caso.

~/packages/zsnes/tags

Permite asociar números de versión con determinadas revisiones del repositorio. Posteriormente veremos cómo se usa.

~/packages/zsnes/trunk

Aquí se almacena la versión actual del paquete. Sólo almacenamos el directorio debian, para ahorrar la complejidad y tiempo de descarga necesario de otra forma.