A raíz de los problemas técnicos que me he ido encontrando por el camino para conseguir confirmar el borrador de la declaración de la renta usando mi certificado digital, he hecho un resumen de los pasos que he ido dando para ello.
Por lo tanto, partimos de que tenemos ya instalado en el navegador (en mi caso, Firefox 4) nuestro certificado digital proporcionado por la FNMT. Además, se supone que ya hemos hecho la solicitud del borrador de la declaración de la renta, y estamos ya en el paso en que queremos enviar la confirmación. Por lo tanto, se supone que ya tendremos instalado en el navegador el certificado FNMT Clase 2 CA - FNMT, proporcionado automáticamente al entrar en la web de la Agencia Tributaria. En caso de no tenerlo instalado, se puede descargar aquí y luego importarlo en Firefox.
Pues bien, lo primero que necesitamos es instalar 2 certificados necesarios para realizar trámites en la web de la Agencia Tributaria. Son los siguientes:

En esta web oficial podéis encontrar estos y otros certificados.
A continuación, hay que editar la configuración de los certificados en Firefox. Para ello, abrimos el administrador de certificados, marcamos los 3 certificados y le damos a editar confianza. Marcamos las 3 casillas.

También hay que configurar un parámetro de Firefox para permitir la ejecución de scripts. Para ello, abrimos el menú de configuración poniendo en la barra de direcciones about:config. Una vez dentro, escribimos signed y hacemos doble clic sobre el único resultado que nos sale. Si nos fijamos en el campo Valor, ahora debería estar a true. Después de esto, reiniciamos Firefox.
Por último, nos dirigimos a la pantalla de entrada para confirmar el borrador, iniciando sesión mediante nuestro certificado digital, y realizamos todos los pasos necesarios.

El último paso será enviar la confirmación, en el que nuevamente, nos pedirá que escribamos una contraseña maestra para realizar la firma digital. Lo dejamos en blanco y le damos a aceptar. Listo.

Partimos de un disco duro en formato VMDK con Windows XP instalado.
Lo primero, como siempre, será guardar una copia por si acaso ocurriera algo. Por ejemplo, exportando la máquina.
A partir de la versión 4 de VirtualBox, ya es posible redimensionar los discos duros. Pero sólo si:
VBoxManage clonehd --format VDI winxp.vmdk winxp.vdi
VBoxManage modifyhd winxp.vdi --resize tamaño_en_megabytesPor último, sólo falta redimensionar la partición de Windows XP, usando GParted, por ejemplo.

Un sistema de control de versiones (SCV) es un software que nos permite llevar un historial de las distintas versiones por las que va atravesando el desarrollo de un producto, normalmente, software. Existen multitud de herramientas ahí afuera, aunque si hay que elegir alguna, Subversion es con diferencia la más usada. Por ahora.
Subversion es un SCV centralizado. Esto quiere decir que requiere de un servidor donde alojar el repositorio del proyecto, y al que los distintos desarrolladores acceden para recuperar o actualizar los cambios del producto en desarrollo. El esquema de un SCV centralizado sería el siguiente:

(Vía http://progit.org/book/)
El principal inconveniente de este esquema es que dependemos al 100% de la integridad del servidor. Un corte de conexión atrasaría el desarrollo del producto durante un tiempo. La pérdida de datos supondría la pérdida de todo el historial de desarrollo (algo que se podría evitar con copias de seguridad, claro).
Git es otro SCV, aunque a diferencia de Subversion, Git es un sistema de control de versiones distribuido.
En un SCV distribuido, el historial del proyecto no se aloja sólo en el servidor. En lugar de esto, cada desarrollador tiene su propia copia de todo el historial. Además, la existencia de un servidor donde alojar el historial se convierte en algo opcional. El esquema de un SCV sería el siguiente:

(Vía http://progit.org/book/)
Como se ve en el diagrama, el flujo de trabajo es diferente del que había con un sistema centralizado. Ahora, cada desarrollador dispone de una copia completa del repositorio, pudiendo además recuperar/actualizar los cambios entre dos o más repositorios. Además, cada desarrollador envía los commits a su propio repositorio local, con lo que puede trabajar sin necesidad de estar conectado.
Git nació en 2005 como un proyecto liderado por Linus Torvalds, creador del núcleo Linux. Entre sus objetivos estaba el de crear un SCV rápido y seguro que permitiera un desarrollo distribuido del kernel de linux. Hoy en día, son muchos los que colaboran en el desarrollo de esta gran herramienta, haciendo que Git se haya convertido en los últimos años en uno de los SCV más usados, gracias en otras cosas a github.
Entre las principales ventajas de Git están la rapidez, la eficiencia, la seguridad y sobre todo la flexibilidad. Aunque quizá ésta última pueda convertirse al principio en un inconveniente.
Y bueno, después de toda esta introducción y cúmulo de piropos, vamos al grano: voy a mostrar algunos de los principales comandos que puedes usar en Git.
Comenzando con Git
Recordemos que en Git se trabaja con un repositorio local. Para crearlo, sólo tendremos que situarnos en el directorio del proyecto y poner:
git init
Con eso, ya tendremos el repositorio creado y nuestro proyecto bajo revisión. A diferencia de Subversion, git sólo crea un directorio oculto (.git/) en la raíz del directorio. A partir de aquí, ya podremos enviar commits y movernos a través del historial.
Lo primero que tendremos que hacer será añadir todos los archivos de nuestro proyecto al repositorio recién creado, ya que éste inicialmente estará vacío. Por lo tanto, para añadir todos los archivos del proyecto hacemos:
git add *
Con esto, Git añade los archivos a una especie de almacén llamado index. El index es algo así como una agenda donde se van apuntando los archivos que se añaden y se borran en el repositorio.
Para ver el estado actual del repositorio ponemos:
git status
Y para grabar definitivamente los cambios en el repositorio hacemos el clásico:
git commit -am "primer commit"
Para ver el historial de commits que hemos hecho ponemos:
git log
Aunque existe una herramienta visual que nos permite ver el historial de una forma mucho más cómoda: gitk. En Ubuntu se puede instalar desde los repositorios.
A continuación voy a hablar un poco de los branches (ramas). En Git podemos trabajar con múltiples versiones de nuestro proyecto, lo que nos permite separar la versión principal de desarrollo, master, de las versiones más inestables o en pruebas. A diferencia de Subversion, Git está diseñado para trabajar con múltiples branches de una forma natural y sencilla, ofreciendo una amplia gama de comandos para manipularlos.
Para crear un nuevo branch de nuestro proyecto, al que llamaremos “experimental”, sólo hay que hacer:
git branch experimental
Si a continuación ponemos:
git branch
Git nos indicará que estamos actualmente en la rama “experimental”. A partir de ahora, todos los cambios y commits que hagamos se irán almacenando en esta rama del proyecto, sin afectar a la versión estable de desarrollo (master), teniendo, por tanto, dos líneas de desarrollo diferentes e independientes. Aunque podríamos tener muchas más.
Una vez que decidamos incluir en la versión estable todos los cambios introducidos en la versión experimental, sólo habrá que hacer una fusión de ambas ramas. Para ello, usaremos el comando merge.
Para hacer un merge de la rama experimental con la master, primero nos cambiamos a la rama master:
git checkout master
y a continuación, la fusionamos con la rama experimental:
git merge experimental
A partir de este momento, ambas ramas vuelven a ser exactamente iguales. Si queremos cambiarnos de nuevo a la versión experimental, ponemos:
git checkout experimental
Y si por contra, preferimos eliminarla:
git branch -d experimental

Y por último, para no extenderme demasiado con este artículo, ahí van dos magníficas referencias para aprender a manejar este potente sistema de control de versiones:
Ah! Y por si os resulta útil, ahí va una chuleta con los principales comandos que he ido usando con el tiempo:
[Actualización] Una versión más reciente de la chuleta la puedes encontrar en mi cuenta de Github: https://github.com/srus/taller-git/Configuración de git # Para configuración específica del proyecto, quitar --global # configuración del nombre git config --global user.name "John Doe" # configuración del email git config --global user.email johndoe@example.com # para activar el color en los diff git config --global color.diff auto
Configuración de un repositorio privado (acceso SSH) # situarse en el directorio del proyecto y poner: git clone --bare /home/usuario/proyecto/.git /home/usuario/repositorio/nombre-proyecto # ya tenemos un repositorio remoto # eliminar el proyecto y bajarse una copia del repositorio remoto git clone usuario@maquina:repositorio/nombre-proyecto/
gitignore (para ignorar archivos en git) Los archivos sólo se ignoran si previamente no se han añadido al index, es decir, deben aparecer como "Untracked files".
ejemplo de archivo .gitignore # Ignorar los siguientes archivos proyecto/archivo1.txt proyecto/archivo2.txt # Ignorar archivos ocultos de Eclipse .classpath .project # No ignorar este archivo !.gitignore # Ignorar un directorio completo directorio/*
Comandos generales en git # inicializar repositorio git init # commit sobre el repositorio local git commit -am "mensaje del commit" # estado del repositorio local git status # Añadir nuevos archivos al index git add * # Eliminar archivos del index git rm file1 file2 # Actualizar el index con los archivos eliminados. # Evita tener que hacer git rm file1 file2 file3 ... git add -u # diferencias entre versiones git diff --cached # traer los cambios de todas las ramas remotas, sin actualizar ninguna rama local git fetch # comparar los cambios entre una rama local y una remota git diff rama_local rama_remota # efectuar los cambios en la rama local actual git merge rama_remota # actualizar (fetch + merge) la rama actual del repo local con la rama remota "experimental" # (origin almacena la dirección del repositorio desde donde se hizo el clone) git pull origin experimental # o bien simplemente usar: git pull # Ejemplo: # actualizar la rama actual del repositorio local con los últimos cambios # de la rama "master" del repositorio remoto git pull usuario@maquina:/ruta/al/repositorio master # info del repositorio git config -l # info del repositorio remoto git remote show origin # "congelar" y poner los cambios actuales a salvo, sin hacer commit, para volver más tarde a ellos git stash # recuperar los cambios git stash apply # limpiar el stash git stash clear
Manejando ramas # crear un branch local git branch nuevo_branch # cambiar a otro branch git checkout nombre_branch # crear un branch y cambiarse a este inmediatamente git checkout -b nuevo_branch # crear un branch que apunte a uno remoto git branch nuevo_branch origin/nombre_branch # crear un branch que apunte a uno remoto y cambiarse a este inmediatamente git checkout -b nuevo_branch origin/nombre_branch # fusionar un branch con el actual git merge nuevo_branch # crear una rama remota o actualizarla: git push origin nuevo_branch # debe existir también una rama local "nuevo_branch" # listar los branch locales git branch # listar los branch remotos git branch -r # listar todos los branch git branch -a # eliminar un branch git branch -d nombre_branch # eliminar un branch remoto (en el repositorio remoto) git push origin :nombre_branch # eliminar un remote-tracking branch (origin/nombre_branch) git branch -r -d origin/nombre_branch # hacer que un branch local haga un seguimiento de una rama remota, # de forma que los push/pull sean más simples: ahora sólo sería # necesario hacer "git pull" o "git push" git branch --track nuevo_branch origin/nuevo_branch
Eliminación de archivos / Volviendo atrás # descartar cambios en un archivo y volver a la última versión git checkout -- ruta_archivo # volver a una versión concreta de un archivo git checkout HASH -- ruta_archivo # modificar un antiguo commit (se modifica sólo ese commit): git revert HASH # Descartar todos los cambios (eliminando/añadiendo archivos) y # volver a un estado concreto del proyecto: # ¡Cuidado! ¡Esto elimina todos los commits hechos! # No aplicarlo en commits anteriores a un git-push, ya que # no podremos hacer push sobre el repositorio remoto. git reset --hard HASH # Para forzar el push en el repositorio remoto (NO RECOMENDABLE): git push origin +master # recuperar commits eliminados: git reflog # una vez identificado el commit a recuperar, hacer: git reset --hard HASH # Por defecto, reflog almacena los commits de los últimos 90 días. # A partir de esa fecha, git-gc eliminará los commits de más de 90 días. # Para modificar la duración, hacemos: git config --add gc.reflogexpire [ 30.days | 30.minutes | 30.seconds ]
Manipulando commits # Modificar el último commit git commit --amend # Unir varios commits en uno. Se usa 'squash' para unir el commit con el anterior. # ¡¡Sólo en el caso de no haber hecho ya un push al repositorio remoto!! git rebase -i HASH
Git y Subversion (git-svn) # commit git svn dcommit # Subir nuevo proyecto con subversion svn import project http://host_name/svn_dir/repository_name/project -m "First Import" # inicializar git-svn git svn init http://host_name/svn_dir/repository_name/project # recuperar la versión git svn fetch -rREVISION # Hasta aquí, los pasos para iniciar un proyecto # actualizar proyecto local git svn rebase