Buscar en DuckDuckGo (en toda la Web)

Mostrando entradas con la etiqueta Programas / Utilidades. Mostrar todas las entradas
Mostrando entradas con la etiqueta Programas / Utilidades. Mostrar todas las entradas

Recuperación de archivos borrados en Windows.

Utilidad para recuperar archivos borrados accidentalmente (bastante bueno, simple y portable).

http://www.piriform.com/recuva

Referencia rápida de Git.

Original de : http://rogerdudler.github.io/git-guide/index.es.html

 

Crear un repositorio nuevo


Crea un directorio nuevo. Métete en el y ejecuta:
git init
Esto crea un nuevo directorio (.git) con la información necesaria para git.

Hacer checkout a un repositorio


Crea una copia local del repositorio ejecutando:
git clone /path/to/repository

Si utilizas un servidor remoto, ejecuta:
git clone username@host:/path/to/repository

Flujo de trabajo



Tu repositorio local esta compuesto por tres "árboles" administrados por git.
- El primero es tu Directorio de trabajo que contiene tus archivos.
- El segundo es el Index que actúa como una zona intermedia.
- El último es el HEAD que apunta al último commit realizado.


add & commit


Puedes registrar cambios (añadirlos al Index) ejecutando:
git add <filename>
git add .

Este es el primer paso en el flujo de trabajo básico.
Para hacer commit a estos cambios usa
git commit -m "Commit message"
Ahora el archivo esta incluído en el HEAD, pero aún no en tu repositorio remoto.

Envío de cambios


Tus cambios están ahora en el HEAD de tu copia local.
Para enviar estos cambios a tu repositorio remoto ejecuta:
git push origin master  (Reemplaza master por la rama a la que quieres enviar tus cambios.)

Si no has clonado un repositorio ya existente y quieres conectar tu repositorio local a un repositorio remoto,ejecuta:
git remote add origin <server>
Ahora podrás subir tus cambios al repositorio remoto seleccionado.

Ramas


Las ramas son utilizadas para desarrollar funcionalidades aisladas unas de otras.
La rama master es la rama "por defecto" cuando creas un repositorio.
Crea nuevas ramas durante el desarrollo y fusiónalas a la rama principal cuando termines.

Crea una nueva rama llamada "feature_x" y cámbiate a ella ejecutando:
git checkout -b feature_x

Vuelve a la rama principal
git checkout master

y borra la rama
git branch -d feature_x

Una rama nueva no estará disponible para los demás a menos que subas (push) la rama a tu repositorio remoto
git push origin <branch>


actualiza & fusiona


Para actualizar tu repositorio local al commit más nuevo, ejecuta:
git pull
en tu directorio de trabajo para bajar y fusionar los cambios remotos.
Para fusionar otra rama a tu rama activa (por ejemplo master), utiliza
git merge <branch>
en ambos casos git intentará fusionar automáticamente los cambios. Desafortunadamente, no siempre será posible y se podrán producir conflictos.
Tú eres responsable de fusionar esos conflictos manualmente al editar los archivos mostrados por git.
Después de modificarlos, necesitas marcarlos como fusionados con
git add <filename>
Antes de fusionar los cambios, puedes revisarlos usando
git diff <source_branch> <target_branch>

Etiquetas


Se recomienda crear etiquetas para cada nueva versión publicada de un software.
Este concepto no es nuevo, ya que estaba disponible en SVN. Puedes crear una nueva etiqueta llamada 1.0.0 ejecutando :
git tag 1.0.0 1b2e1d63ff
1b2e1d63ff se refiere a los 10 caracteres del commit id al cual quieres referirte con tu etiqueta. Puedes obtener el commit id con
git log
también puedes usar menos caracteres que el commit id, pero debe ser un valor único.

Reemplaza cambios locales


En caso de que hagas algo mal (lo que seguramente nunca suceda ;) puedes reemplazar cambios locales usando el comando
git checkout -- <filename>
Este comando reemplaza los cambios en tu directorio de trabajo con el último contenido de HEAD.
Los cambios que ya han sido agregados al Index, así como también los nuevos archivos, se mantendrán sin cambio.

Por otro lado, si quieres deshacer todos los cambios locales y commits, puedes traer la última versión del servidor y apuntar a tu copia local principal de esta forma
git fetch origin
git reset --hard origin/master



Trucos


Interfaz gráfica por defecto:
gitk
Colores especiales para la consola:
git config color.ui true
Mostrar sólo una línea por cada commit en la traza:
git config format.pretty oneline
Agregar archivos de forma interactiva:
git add -i



Acceder a cuenta de Gmail con MUTT

Para poder acceder a nuestra cuenta de Gmail con el cliente de correo mutt tan solo tenemos que realizar 3 pasos:


1.- Editar el fichero de configuración de mutt (.muttrc) y copiar las líneas siguientes.
Los comentarios explican el uso.

 _______________________________________________________________________________

#Fichero .muttrc

# Juego de caracteres de los mensajes que enviamos:
set send_charset = "utf-8"
set assumed_charset = "iso-8859-1"

# Asegurarse de que Vim sabe que Mutt es un cliente de correo electrónico
# y que queremos componer los mensajes usando UTF-8
# Si no tien vi entonces mutt leerá el contenido
# de la variable de entorno $EDITOR):
set editor = "vim -c 'set syntax=mail ft=mail enc=utf-8'"
set menu_scroll = "yes"

# Remitente de los mails:
set from = "usuario@gmail.com"
set realname = "Nombre Apellido"

# Configuraciones de servidor -->
# Configuraciones servidor IMAP:
set imap_user = "usuario@gmail.com"
set smtp_url = "smtp://usuario@smtp.gmail.com:587/"
# Opcional (no lo recomiendo porque queda almacenada la contraseña
# en texto plano):
 set imap_pass = "contraseña"
 set smtp_pass = "contraseña"
# En caso de no poner los dos valores anteriores, se nos pedirá ingresar
# la contraseña al enviar o recibir mails.
set folder = "imaps://imap.gmail.com:993"
# Ponemos el Inbox
set spoolfile = "+INBOX"
# Ponemos la carpeta de borradores (debe llamarse igual que en la web):
set postponed = "+[Gmail]/Borradores"
# Guardamos los mails en Enviados:
set record = "imaps://imap.gmail.com:993/[Gmail]/Enviados"

# Ajustes para la conexión IMAP:
set mail_check=100
set imap_keepalive=300

# Buzones extra que queremos comprobar.
mailboxes "+[Gmail]/Spam"
mailboxes "+[Gmail]/Papelera"

# Ordenamos los mensajes en orden inverso.
set sort=reverse-threads
set sort_aux= last-date-received


# Crear los directorios para no obtener errores,
 #'mkdir -p ~/.mutt/cache/{bodies,headers}':
set message_cachedir = "~/.mutt/cache/bodies"
set header_cache = "~/.mutt/cache/headers"

# El siguiente archivo debe existir y contiene la firma, que va al pie de cada
# mail que escribamos:
set signature = ".mutt/.firma"


# Iluminar con colores, obtenido de:
# http://aperiodic.net/phil/configs/mutt/colors
#
 #-*- muttrc -*-
#
# Color settings for mutt.
#----------------------------------------------------------------------------------------------------------------------------

# Default color definitions
color normal     white         default
color hdrdefault green         default
color quoted     green         default
color quoted1    yellow        default
color quoted2    red           default
color signature  cyan          default
color indicator  brightyellow  red
color error      brightred     default
color status     brightwhite   blue
color tree     brightmagenta default
color tilde     blue          default
color attachment brightyellow  default
color markers     brightred     default
color message    white         default
color search     brightwhite   magenta
color bold       brightyellow  default

# Color definitions when on a mono screen
mono bold      bold
mono underline underline
mono indicator reverse
mono error     bold

# Colors for items in the reader
color header brightyellow default "^(From|Subject):"
color header brightcyan   default ^To:
color header brightcyan   default ^Cc:
mono  header bold                 "^(From|Subject):"

# Many of these formulas were stolen from Jeremy Blosser
# These would be much simpler if colors were additive.

# regular new messages
color index black         white   "~N !~T !~F !~p !~P"
# regular tagged messages
color index black         cyan    "~T !~F !~p !~P"
# regular flagged messages
color index black         red     "~F !~p !~P"
# messages to me
color index yellow        default "~p !~N !~T !~F !~P"
color index brightyellow  white   "~p ~N !~T !~F !~P"
color index yellow        cyan    "~p ~T !~F !~P"
color index yellow        red     "~p ~F !~P"
# messages from me
color index green         default "~P !~N !~T !~F"
color index green         white   "~P ~N !~T !~F"
color index green         cyan    "~P ~T !~F"
color index green         red     "~P ~F"
# messages which mention my name in the body
color index yellow        default "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
color index brightyellow  white   "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
color index yellow        cyan    "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
color index yellow        red     "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
# messages which are in reference to my mails
color index magenta       default "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
color index magenta       white   "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
color index magenta       cyan    "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
color index magenta       red     "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
# messages to root, etc.
color index cyan          default "~C \"(root|postmaster|abuse|mailer-daemon)@\" !~N !~P !~p"
color index cyan          white   "~C \"(root|postmaster|abuse|mailer-daemon)@\" ~N !~P !~p"
# big messages
color index brightred     default "!~N ~z 102400-"
color index brightred     cyan    "~T !~F !~p !~P ~z 102400-"
color index brightred     white   "~N ~z 102400-"

# deleted messages
color index red           default "!~N ~D"
color index red           white   "~N ~D"


# Highlights inside the body of a message.

# Attribution lines
color body magenta default "\\* [^<]+ <[^>]+> \\[[^]]+\\]:"
color body magenta default "(^|[^[:alnum:]])on [a-z0-9 ,]+( at [a-z0-9:,. +-]+)? wrote:"

# URLs
color body brightyellow default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"

# email addresses
color body brightmagenta default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"

# PGP messages
color  body            brightyellow    default "^gpg: Good signature .*"
color  body            white           default "^gpg: "
color  body            brightwhite     red     "^gpg: BAD signature from.*"
mono   body            bold                    "^gpg: Good signature"
mono   body            bold                    "^gpg: BAD signature from.*"

# Various smilies and the like
color body brightwhite default "<[Gg]>"                            # <g>
color body brightwhite default "<[Bb][Gg]>"                        # <bg>
color body brightwhite default " [;:]-*[})>{(<|]"                  # :-) etc...
# *bold*
color body brightblue  default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
mono  body bold                "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
# _underline_
color body brightblue  default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
mono  body underline           "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
# /italic/  (Sometimes gets directory names)
#color body brightblue  default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
#mono  body underline           "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"

# Border lines.
color body blue default "( *[-+=#*~_]){6,}"
#-----------------------------------------------------------------------------------------------------------------------

#Visualizar  los ficheros html y no su código fuente.
auto_view text/html

_______________________________________________________________________________________

2.- Crear un fichero llamado .firma donde poner el texto que queremos que aparezca al final de cada mensaje que enviemos. Por ejemplo:

Saludos de Usuario

Jefe de ............ y .........

3.- Crear un fichero llamado .mailcap. Este fichero sirve para poder visualizar correctamente los ficheros de email en formato html mediante el uso de w3m. Su contenido será:

text/html;                      w3m %s; nametemplate=%s.html
text/html;                      w3m -dump %s; nametemplate=%s.html; copiousoutput




Tutorial Basico de SUBVERSION

 

 

Minireceta: tutorial básico de SVN / subversion

 

A continuación una pequeña minireceta sobre cómo crear un pequeño repositorio de subversión en un sistema remoto, donde alojar tus pequeños proyectos de software o webs.

Este sistema te permitirá tener siempre online una copia actualizada tu código y evitar el tener que llevar .tar.gzs de las últimas versiones de un ordenador a otro. También puede servir como repositorio, en un entorno laboral, de webs, scripts o código de cualquier tipo.

 

Instalar subversion

 

Es tan sencillo como instalar el paquete correspondiente vía apt-get o yum

# apt-get install subversion subversion-tools 

# yum install subversion

Ahora debemos optar entre 2 opciones:


1.- Levantamos el daemon de svnserve y creamos un repositorio global en el servidor para todos los usuarios (repositorio por defecto). Esto implica que la gestión de los usuarios se realizará a nivel de servidor (por ejemplo en un fichero de usuarios).

2.- Dejamos que cada usuario aloje sus proyectos en uno o varios repositorios propios en su HOME. Esto sólo necesita acceso SSH abierto en el servidor.

 

Crear repositorio por defecto (SVN)

 

Si vamos a ejecutar subversión sin SSH, directamente contra el servidor svn, necesitaremos un script de parada y arranque y un repositorio por defecto. Creamos el siguiente script:

# cat /etc/init.d/svnserve
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: svnserve
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start:
# Default-Stop:
# X-Interactive: true
# Short-Description: Start/stop svnserve
### END INIT INFO

test -f /usr/bin/svnserve || exit 0

### Podemos cambiar el puerto en el que escuchar:
OPTIONS="-d -r /var/svn/ --listen-port=3690"

case "$1" in
start)
echo -n "Starting subversion daemon:"
echo -n " svnserve"
start-stop-daemon --start --quiet --oknodo --user root --exec /usr/bin/svnserve -- $OPTIONS
echo "."

;;
stop)
echo -n "Stopping subversion daemon:"
echo -n " svnserve"
start-stop-daemon --stop --quiet --oknodo --exec /usr/bin/svnserve
echo "."
;;
reload)
;;
force-reload)
$0 restart
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: /etc/init.d/subversion {start|stop|reload|restart}"
exit 1
;;
esac

exit 0

Damos permisos de ejecución:

# chmod +x /etc/init.d/svnserve

Ahora lo introducimos en el arranque de la máquina:

Debian: # update-rc.d svnserve defaults

CentOS: # ntsysv

También debemos definir y crear el repositorio por defecto para el daemon que corre en memoria, y modificar los permisos de acceso autenticado (auth-access → permitimos escritura), anónimo (anon-access → no permitimos el accesos) y los usuarios/passwords de autenticación en fichero aparte:

# svnadmin create /var/svn/

# egrep -v "^#|^$" /var/svn/conf/svnserve.conf
[general]
auth-access = write
anon-access = none
password-db = passwd

# cat /var/svn/conf/passwd
[users]
miusuario = elpassword

Como luego veremos, nada impide que vía SSH cada usuario pueda tener sus propios repositorios adicionales.

Finalmente, arrancamos el servicio SVN:

# /etc/init.d/svnserve start

En algunos tutoriales se aconseja crear los siguientes directorios base:

# svn mkdir file:///var/svn/trunk -m "Crear trunk"
# svn mkdir file:///var/svn/tags -m "Crear tags"
# svn mkdir file:///var/svn/branches -m "Crear branches"

La ventaja de este sistema es que podemos dar acceso a múltiples usuarios gracias al fichero de passwords, así como dar acceso anónimo de sólo lectura.

 

Crear repositorios individuales para los usuario (SVN+SSH)

 

Podemos utilizar SVN por SSH si queremos un acceso “personal” a un repositorio a través de nuestra cuenta de trabajo de un servidor o host Linux sin necesitar acceso administrativo (siempre y cuando tenga instalado el paquete de subversion). Normalmente es la forma más utilizada para usuarios individuales (no trabajo en grupo) que quieren guardar sus proyectos o ficheros en un repositorio para evitar el traspaso de ficheros entre diferentes equipos de trabajo (ejemplo: tener la misma copia de código en casa o en el trabajo).

En el caso de utilizar SVN por ssh, no necesitamos arrancar el daemon ni crear este repositorio por defecto. En ese caso, crearemos uno o varios repositorios para nuestro usuario, ubicado donde queramos en el PATH, por ejemplo en /home/usuario/svn:

Si necesitamos acceso de múltiples usuarios vía SSH, lo mejor es crear un usuario común (no nuestro usuario personal) que alojará el/los repositorios.

En el caso de SVN+SSH se nos presentan 2 opciones relativas a la organización de los repositorios:



1.- Crear un único repositorio del que colgarán todos los proyectos:

Creamos un directorio único en el servidor (por ejemplo /home/usuario/svn), creado con “svnadmin create”, el cual alojará todos los proyectos. La raíz del repositorio será dicho directorio, para todos los proyectos. La ventaja de este sistema es la simplicidad del “setup”.

La desventaja de este sistema es que las revisiones del repositorio son comunes a todos los proyectos; es decir, si en un repositorio con 3 proyectos hacemos commit en cada proyecto, la revisión aumenta en 3, no es específica para cada proyecto.

Además, borrar un proyecto es “complicado”: implica regenerar el repositorio a partir de un dump con filtro extraído con “svndumpfilter exclude” (ver reposadmin.maint.filtering).


2.- Crear múltiples repositorios (un repositorio para cada proyecto):

Creamos un directorio único en el servidor (por ejemplo /home/usuario/svn), y dentro de dicho directorio creamos un repositorio para cada proyecto (con “svnadmin create nombreproyecto”). La raíz del repositorio ya no será /home/usuario/svn sino /home/usuario/svn/PROYECTO, según el proyecto con el que queramos trabajar.

La ventaja de este sistema es que cada proyecto tiene su propio sistema de revisiones, y sus propios tags y branches. También, el borrado de los proyectos (repositorios) es muy fácil y simple.

Yo personalmente me decanto por esta opción aunque veremos las 2.

La opción elegida sólo cambia la forma de CREAR EL REPOSITORIO y de hacer LA SUBIDA INICIAL DEL PROYECTO y la DESCARGA INICIAL DEL PROYECTO (digamos que los primeros 10 minutos de uso del repositorio). Después, el uso diario y regular de SVN es igual en ambas opciones.

 

Crear un único repositorio donde alojar todos los proyectos

 

Creamos el repositorio en el servidor:

$ mkdir /home/usuario/svn/

$ svnadmin create /home/usuario/svn

Una vez hecho esto, vía SSH podemos ya acceder al repositorio referenciándolo como:

$ export SVNROOT="svn+ssh://usuario@server.com/home/usuario/svn/"

De nuevo, se recomienda crear los siguientes subdirectorios:

$ svn mkdir file:///home/usuario/svn/trunk -m "Crear trunk"
$ svn mkdir file:///home/usuario/svn/tags -m "Crear tags"
$ svn mkdir file:///home/usuario/svn/branches -m "Crear branches"

 

Repositorio único: Subir por primera vez un proyecto al repositorio

 

Sea un directorio de código fuente denominado “miproyecto”. Nos situamos en el directorio padre de “miproyecto” y ejecutamos uno de los siguientes comandos:

$ svn import miproyecto svn://server.sromero.org/var/svn/miproyecto
$ svn import miproyecto svn+ssh://server.sromero.org/home/sromero/svn/miproyecto
$ svn import miproyecto ${SVNROOT}/miproyecto
$ svn import miproyecto ${SVNROOT}/miproyecto -m "Upload inicial del proyecto"

Al comando le decimos que importe un directorio específico (svn import miproyecto) y le decimos que lo haga sobre el SVNROOT añadiendo además el subdirectorio del repositorio que alojará el proyecto (miproyecto también en este caso). Esto permite tener múltiples proyectos en cada repositorio, gracias a este path “final” sobre el SVNROOT.

Se nos solicitará entonces la introducción de una línea de texto para “resumir” en qué consiste el cambio realizado. Todos los cambios en el repositorio tienen que tener este “summary” que luego podemos recuperar con “log”.

Como se puede ver en el último ejemplo, podemos agregar el resumen para el log en la línea de comandos (en modo no interactivo) con -m “Upload inicial del proyecto”.

 

Repositorio único: Descargar una copia del proyecto desde el repositorio

 

Una vez un repositorio está en un proyecto, podemos “descargar” una copia ya controlada por SVN. De hecho, deberíamos desechar (de momento renombrar) el directorio de proyecto original y trabajar con la copia versionada.

Nos situamos en el directorio de trabajo “padre” y (una vez renombrado el directorio original si existe) ejecutamos lo siguiente (una u otra opción según si tenemos definida o no la variable):

$ svn checkout svn://server.sromero.org/var/svn/miproyecto
$ svn checkout ${SVNROOT}/miproyecto

Esto descargará el proyecto “SVNROOT/miproyecto” recreando el directorio “miproyecto” en el directorio actual.

 

Usar un repositorio para cada proyecto

 

Esta puede ser la opción más habitual si no queremos mezclar revisiones y si queremos poder borrar un proyecto concreto.

 

Múltiples repositorios: creando los repositorios

 

  • Creamos un directorio común del que colgarán todos los repositorios (proyectos). Por ejemplo: /home/usuario/svn/.
  • Creamos un repositorio por cada proyecto, con “svnadmin create /home/usuario/svn/proyecto”.
  • Preparamos cada proyecto para su subida, creando los subdirectorios trunk, branches y tags. Esta subida implicará un SVNROOT diferente para cada proyecto.
  • Subimos cada proyecto a su propio repositorio.
  • Ya podemos trabajar con los proyectos. Para esto ya no hará falta definir un SVNROOT diferente por proyecto ya que los directorios ocultos .svn de cada proyecto guardan esta información:

Empezamos creando el directorio común en el servidor SVN:

$ mkdir /home/usuario/svn/

Para cada proyecto a alojar hay después que crear su repositorio en el servidor SVN:

$ svnadmin create /home/usuario/svn/proyecto1 
$ svnadmin create /home/usuario/svn/proyecto2

 

Múltiples repositorios: Subir por primera vez proyectos al repositorio

 

Supongamos que tenemos en nuestro sistema 2 proyectos bajo /home/usuario/code y queremos alojarlos en el servidor de SVN.

Primero preparamos el proyecto1, creando los 3 subdirectorios trunk, branches y tags:

 

  • trunk → contiene el código fuente del proyecto.
  • branches → donde se pueden crear ramas del proyecto.
  • tags → donde se pueden alojar “snapshots” del código fuente en un momento dado.

 

$ cd /home/usuario/code/
$ cd proyecto1
$ mkdir trunk
$ mv * trunk
$ mkdir branches
$ mkdir tags

Una vez estructurado el directorio del proyecto, lo subimos al repositorio:

$ export SVNROOT="svn+ssh://server.sromero.org/home/sromero/svn/proyecto1"
$ svn import proyecto1 ${SVNROOT}/ -m "Agregamos proyecto1 a su propio repositorio"

Nótese que ahora el SVNROOT incluye el subdirectorio “proyecto1”, al contrario que en el caso de múltiples proyectos en un único repositorio.

Repetimos a continuación el proceso para nuestro segundo proyecto:

$ cd /home/usuario/code/
$ cd proyecto2
$ mkdir trunk
$ mv * trunk
$ mkdir branches
$ mkdir tags
$ export SVNROOT="svn+ssh://server.sromero.org/home/sromero/svn/proyecto2"
$ svn import proyecto1 ${SVNROOT}/ -m "Agregamos proyecto2 a su propio repositorio"

 

Múltiples repositorios: Descargar por primera vez el proyecto del repositorio

 

Importamos el proyecto “subversionado”, renombrando el directorio original y haciendo un checkout:

$ cd /home/usuario/code/
$ export SVNROOT="svn+ssh://server.sromero.org/home/sromero/svn/proyecto1"
$ mv proyecto1 proyecto1.orig
$ svn checkout $SVNROOT proyecto1

Y lo mismo para el otro proyecto:

mv proyecto2 proyecto2.orig
svn checkout $SVNROOT proyecto2

Ahora ya podríamos trabajar con normalidad dentro de cualquiera de los 2 proyectos (svn update, svn commit, etc), y cada uno de ellos estará alojado dentro de su propio repositorio sin compartir estructuras de SVN con otros proyectos.

 

Múltiples repositorios: Borrado de un proyecto del repositorio

 

El borrado de un proyecto, se realizará en el servidor con un simple:

$ rm -rf /home/usuario/svn/elproyecto

(sin afectar así al resto de proyectos, y pudiendo volver a generarlo de nuevo con un “svnadmin create” si fuera necesario).

 

Múltiples repositorios: Import y checkout inicial masivo

 

Veamos un pequeño “script” que subirá al repositorio todos los proyectos que tenemos bajo un mismo directorio:

En el servidor SVN:

cd /home/usuario/svn

for PROJECT in proyecto1 proyecto2 proyecto3 proyecto4;
do
svnadmin create $PROJECT
done

En nuestro equipo de trabajo:

cd /home/usuario/prog/code

for PROJECT in proyecto1 proyecto2 proyecto3 proyecto4;
do
export SVNROOT="svn+ssh://user@myserver.org/home/usuario/svn/${PROJECT}/"
cd ${PROJECT}
mkdir trunk
mv * trunk
mkdir tags
mkdir branches
cd ..
svn import $PROJECT ${SVNROOT} -m "Agregamos proyecto al repositorio"
done

Con esto hemos subido los diferentes proyectos al servidor SVN, cada uno en un repositorio diferente bajo la misma ruta.

Ahora tenemos que descargarnos los proyectos “subversionados” para trabajar con ellos en lugar de usar los directorios de código fuente originales (que no contienen el directorio oculto .svn):

cd /home/usuario/prog/code

for PROJECT in proyecto1 proyecto2 proyecto3 proyecto4;
do
# Movemos el directorio original como .orig
if [ -e $PROJECT ]; then mv $PROJECT ${PROJECT}.orig ; fi

export SVNROOT="svn+ssh://user@myserver.org/home/usuario/svn/${PROJECT}/"

svn checkout $SVNROOT $PROJECT
done

Esta operación es la misma que tendremos que realizar en otros equipos (ej: en casa) donde guardemos copia de estos proyectos, para tenerlos versionados y apuntando al repositorio desde este momento.

Un apunte final sobre el comando mv del script importador:

 mv * trunk 

Este comando no movera archivos ocultos a trunk/ si tu proyecto los tiene. En ese caso, se puede usar:

(shopt -s dotglob; mv -- * ..)

(con los paréntesis)

 

Usar subversion

 

 

Referenciar el repositorio:

 

La referencia del repositorio puede ser svn: o svn+ssh: :

 

  • SVN puerto por defecto:
svn://server.sromero.org/var/svn/
  • SVN puerto modificado:
svn://server.sromero.org:puerto/var/svn/
  • SVN via SSH puerto estándar:
Repositorio único: svn+ssh://server.sromero.org/home/usuario/svn/
Múltiples repositorios: svn+ssh://server.sromero.org/home/usuario/svn/nombre_proyecto
  • SVN via SSH puerto o usuario modificados:
Repositorio único: svn+ssh://server.sromero.org/home/usuario/svn/
Repositorio único: svn+ssh://usuario@server.sromero.org/home/usuario/svn/
Múltiples repositorios: svn+ssh://usuario@server.sromero.org/home/usuario/svn/nombre_proyecto

export SVN_SSH="ssh -p 24"
Repositorio único: svn+ssh://usuario@server.sromero.org/home/usuario/svn/
Múltiples repositorios: svn+ssh://usuario@server.sromero.org/home/usuario/svn/nombre_proyecto

 

En ocasiones puede ser útil declarar este valor en un “export SVNROOT” para usarlo después en las llamadas a svn.

SVN/SSH no nos pedirá password si utilizamos autenticación sin password por clave pública/privada. En el caso de SSH, en ocasiones se crea un usuario específico “svn” para que sea dueño específico del repositorio.

 

Subir cambios al repositorio

 

Cuando hacemos cambios en el código, debemos de subirlos al repositorio (hacer un commit de los cambios). Hay quien hace commit cada vez que hace un cambio acotado (para que gracias al comentario del commit podamos saber qué cambios se realizan cada vez), y hay quien hace un commit al final de largas sesiones de trabajo.

Una vez hayamos decidido hacer el commit, y estando dentro del directorio de trabajo del proyecto, ejecutamos:

$ svn commit
$ svn commit fichero_o_directorio
$ svn commit -m "Resumen de cambios"

Nótese que no necesitamos especificar el SVNROOT porque viene ya “pregrabado” en el directorio que hemos descargado (directorio oculto .svn).

 

Descargar cambios desde el repositorio

 

Si otros compañeros han subido cambios o bien queremos descargar en casa los cambios realizados en el trabajo, podemos hacer un update sobre nuestra copia local (que en algún momento fue descargada con checkout).

$ svn update
$ svn update fichero_o_directorio

 

Agregar/Crear/Mover/Borrar ficheros o directorios al proyecto

 

En SVN tenemos que “añadir” al repositorio los ficheros NUEVOS que creemos localmente, para que sean también subidos/descargados con los checkouts/updates. También hay que eliminar ficheros remotamente si queremos borrarlos localmente.

$ svn add fichero_o_directorio
$ svn mkdir nuevo-dir
$ svn move file_dir1 file_dir2
$ svn delete fichero_o_directorio

 

Ver las diferencias de nuestra copia respecto al repositorio

 

Si hemos hecho cambios en nuestra copia local “descargada”; podemos ver un diff de dichos cambios con:

$ svn diff
$ svn diff fichero_o_directorio

$ svn diff | less
$ svn diff | vim -

 

Descartar nuestros cambios locales

 

Es posible en algún momento que hayamos hecho cambios en algún fichero de nuestra copia local y queramos deshacerlos para empezar de cero con los datos que hay en el repositorio. En ese caso no es necesario realizar un checkout de nuevo, podemos hacer un:

$ svn revert fichero_o_directorio

O bien, si queremos revertir todos los cambios (.) o los de un directorio:

$ svn revert --recursive .
$ svn revert --recursive directorio

 

Ver historico de un fichero o del proyecto

 

Lo siguiente muestra todo el registro de cambios de un proyecto:

$ svn log
$ svn log fichero_o_directorio

 

Ver estado del proyecto

 

El siguiente comando proporciona un listado de nuevos ficheros, ficheros modificados, y ficheros a borrar en el próximo commit.

$ svn status

Resulta también muy útil para conocer si en el directorio actual hay ficheros sin versionar (a los que falta hacerle el svn add), porque estos aparecen con el prefijo ?:

$ touch new_file
$ svn status
? new_file

 

Flags opcionales para el comando "svn"

 

Si no estamos usando svn+ssh, puede ser interesante especificar user/pass en línea de comandos:

--username sromero --password XXXXXX

También, para el checkout y para el update, puede ser útil la opción –force.

Con –force podríamos hacer un checkout de un proyecto recién subido al repositorio con un import sobre el directorio “inicial” sin renombrarlo. Es decir, podríamos subir una web al repositorio y hacer un checkout –force en el directorio de la web para “descargar la copia remota” y crear las estructuras .svn sin tener que renombrar el directorio y hacer el checkout (que cortaría la web mientras hacemos el mv + checkout).

 

Mover un repositorio ya existente

 

Para mover un repositorio se puede usar switch:

$ svn switch --relocate old-url new-url

 

Tags y branches de proyectos

 

En subversion tenemos disponibles las siguientes funcionalidades:

  • tags → “Snapshot” (foto ó backup) del código (trunk) en un momento dado, para marcar dicho momento en el tiempo del código como un estado concreto (por ejemplo: versión 0.1.0), o para hacer una copia del código antes de realizar alguna acción “invasiva” y de la que podríamos querer volver atrás. Los tags nos permiten así empaquetar el código en versiones específicas o bien volver atrás después de un cambio que no ha salido bien y que no se puede deshacer ya con un revert porque ha tenido commits al repositorio. Los tags son “versiones sólo lectura” del código.
  • branches → “Ramas” del código. Es decir, “versiones paralelas” del código que otro equipo de desarrollo pueda querer explorar. Son parecidos a los tags, salvo que pueden modificarse. Por ejemplo, podríamos hacer un branch del código para que otro equipo de desarrollo pruebe a implementar soporte en nuestro programa para otro Sistema Operativo, y que si el desarrollo llega a buen puerto, se haga un “merge” de esta rama con el trunk.

Para crear un tag o un branch, lo haríamos con el comando “svn copy

$ svn copy trunk tags/0.1.0 -m "Version 0.1.0 del proyecto"
$ svn commit -m "Version 0.1.0" tags/

$ svn copy trunk tags/0.1.0-antes-de-probar-SDL -m "Snapshot antes de probar SDL"
$ svn commit -m "Snapshot antes de probar SDL" tags/

$ svn copy trunk branches/soporte-android -m "Creamos branch pruebas Android"
$ svn commit -m "Branch pruebas de soporte para Android" branches/

También podemos crear un tag o branch no desde la rama de trunk sino desde nuestra copia local (directorio del proyecto), es decir, con cambios aún no subidos al repositorio:

$ svn copy miproyecto ${SVNROOT}/tags/android-funcional -m "Tag con codigo Android Funcional"

Para borrar un tag o un branch, lo haríamos con “svn delete”:

$ svn delete tags/0.1.0-antes-de-probar-SDL -m "Eliminamos el tag: SDL implementado OK"
$ svn commit -m "Borrado tag 0.1.0-antes-de-probar-SDL"

$ svn delete branches/soporte-android
$ svn commit -m "Se borra la rama de soporte para Android"

En realidad, físicamente no se borra el código, sólo se marca el repositorio de forma que ya no “exista” en cuanto a actualizaciones. No obstante, podemos recuperar cualquier número de revisión en cualquier momento con:

$ svn copy ${SVNROOT}/branches/rama-android@15 \
${SVNROOT}/branches/rama-android \
-m "Restaurando revision 15"

Podemos obtener un listado de tags o branches del proyecto con svn list (para restaurar revisiones puede sernos útil también svn log, svn info y svn status).

$ svn list ${SVNROOT}/tags 
0.1.0/

Y podemos hacer un checkout de un release concreto con:

$ svn checkout ${SVNROOT}/tags/0.1.0 

Una de las pegas de los tags es que son parte del proyecto por lo que cada vez que hagamos checkouts o updates nos los vamos a descargar en ~/proyecto/tags . Si queremos evitar esto, podemos hacer checkout sólo del raíz del repositorio (no recursivamente, -N) y actualizar sólo el trunk:

$ svn checkout $SVNROOT -N PROYECTO
$ svn update PROYECTO/trunk

De esta forma sólo descargamos el trunk, y no tags ni branches, por lo que no desperdiciamos espacio en disco local.

 

Trabajando con ramas (branches)

 

Existen diferentes políticas al respecto de cómo trabajar con el código y las ramas.

Quizá la más extendida es trabajar sobre la rama principal (trunk) y cada cierto tiempo crear una rama denominada “estable”. El proyecto se continúa después sobre la rama principal y la estable sólo se modificará (durante el tiempo de vida de dicha versión) para corregir bugs (que también se deberán corregir en el trunk si le afectan); las nuevas características o funcionalidades sólo se implementarán en la rama principal.

Así, podemos crear una nueva rama y trabajar sólo sobre ella así:

$ svn info ${SVNROOT}/trunk | grep Revision
# (anotamos el numero de revision actual "REVISION_ACTUAL")

$ svn copy ${SVNROOT}/trunk ${SVNROOT}/branches/stable-1.0 \
-m "Rama estable LA_REVISION_ACTUAL"

Ahora configuramos nuestra copia local como la nueva rama:

svn switch --relocate ${SVNROOT}/trunk ${SVNROOT}/branches/stable-1.0

En este momento, podemos trabajar con nuestra copia local y ya no estaremos trabajando con el trunk sino con “stable-1.0”.

$ svn info | grep URL
$ svn update
# (hacemos cambios)
$ svn commit -m "Bug corregido en blah"

Estos pasos servirán incluso si tenemos cambios en nuestra copia local que todavía no hemos subido al trunk, porque hemos decidido que estén en la nueva rama y no en el trunk.


Convertir nuestra rama en la rama principal

También podemos haber querido crear una rama para explorar una alternativa al código (por ejemplo, cambiar de GTK a QT) y que los cambios hayan tenido éxito y queramos convertir esta rama en la versión principal:

Un primer método es borrar el trunk y convertir el código de nuestra rama en el trunk:

$ svn delete ${SVNSERVER}/trunk
$ svn move ${SVNSERVER}/branches/programa-con-qt ${SNVSERVER}/trunk
$ svn switch --relocate ${SVNSERVER}/branches/programa-con-qt ${SVNSERVER}/trunk


Hacer merge de los cambios de nuestra rama con la principal

El merge de una rama al trunk se realiza con:

$ svn merge -r XXX:YYY $SVNROOT/branches/la-rama
$ svn commit -m "Realizado merge de la-rama (XXX:YYY) al trunk"

Siendo XXX la revisión en la cual nació la rama y YYY la revisión actual del trunk.

Para obtener estos datos, podemos:

# hacer un checkout del trunk y de la rama en otro directorio:
$ cd ..
$ mkdir temp
$ cd temp
$ svn checkout $SVNSERVER/trunk trunk
$ svn checkout $SVNSERVER/branches/la-rama la-rama
$ cd la-rama

# encontrar la revisión donde se creó la rama (XXX):
$ cd la-rama
$ svn log --stop-on-copy

# encontrar la revisión actual del trunk ("At revision YYY"):
$ cd ..
$ cd trunk
$ svn update

Esto realizará un merge del código de la-rama sobre el trunk. Si hubiera conflictos de edición de ficheros (puede haberlos), los arreglamos localmente y hacemos un commit para subirlos:

$ vim fichero_que_da_conflictos.c
$ svn commit -m "Merge de
$ svn commit -m "Realizado merge de la-rama (XXX:YYY) al trunk"

 

Borrar un repositorio ya existente en el servidor

 

Simplemente, ejecutampos lo siguiente en el repositorio:

# TODO EL ARBOL DE PROYECTOS/REPOSITORIOS
$ rm -rf /home/sromero/svn/

# UN REPOSITORIO CONCRETO:
$ rm -rf /home/sromero/svn/PROYECTO/

Para volver a tenerlo operativo habría que seguir de nuevo el proceso de creación (mkdir, svnadmin create, editar conf/svnserve.conf, e importar en él proyectos).

 

Operativa inicial con SVN (cómo subir un proyecto)

 

Según si vamos a crear un repositorio común para todos los proyectos, o si vamos a crear un repositorio por cada proyecto, los comandos exactos son ligeramente diferentes (ver las correspondientes secciones al principio de este documento), pero generalizando, son:


1.- Crear el/los repositorios en el servidor.

2.- Establecer variables de entorno (SVNROOT y SVN_SSH si necesitamos cambiar el puerto).

3.- Preparar los directorios de nuestro proyecto (en el caso de múltiples repositorios, crear directorios trunk/branches/tags).

4.- Subir nuestro proyecto o web al repositorio.

5.- Renombrar el directorio antiguo.

6.- Descargar el mismo directorio pero con el control de versiones.

7.- Revisar que la descarga es correcta y que no faltan ficheros.

8.- “Archivar” (guardar, borrar) el directorio de código antiguo.

 

Operativa regular (trabajar con un proyecto)

 

A partir de ahora, debemos trabajar sobre el directorio de trabajo creado acordándonos de realizar “svn add” de nuevos ficheros, “svn delete” de ficheros que borremos, y de hacer los commits para subir nuestro trabajo y updates para recuperar el trabajo de los demás.

 

Aplicación práctica: ficheros específicos del HOME en SVN

 

Una cosa habitual para las personas que trabajamos con varios PCs (portátil, sobremesa casa, trabajo…) es tener gran cantidad de ficheros de configuración comunes entre todos ellos: .vimrc, .bashrc, .tmux.conf, así como directorios de notas, documentación, etc… En esos casos, cada vez que hacemos una mejora en uno de los ficheros, tenemos que distribuirlo manualmente a los otros equipos (vía correo, scp, o llavero USB).

 

En este ejemplo, vamos a mantener una copia selectiva de ficheros de nuestro HOME en un repositorio privado online de subversion, de forma que con un simple svn update (incluso podría ser automatizado en el login de nuestro usuario) podamos actualizar nuestro HOME local con las últimas copias de dichos ficheros. No sólo eso, sino que nos protege contra borrados accidentales de ficheros (podemos recuperarlos con un svn update) o para encontrar cambios en los ficheros que hayan producido algún problema (volviendo a revisiones anteriores, etc).

 

NOTA: nunca debemos subir ficheros con datos sensibles en cualquier caso, como una clave SSH, si no confiamos en la seguridad de dicho servidor.

 

Por ejemplo: estamos en el trabajo, encontramos una opción fantástica para el fichero .vimrc, la añadimos, hacemos un svn commit -m “Nueva opcion vimrc”, y luego en casa sólo hay que hacer svn update (o bien, como he dicho, ponerlo de forma automática en el arranque o el login del usuario).

 

Para montar este sistema, primero creamos el repositorio en el servidor:

 

$ svnadmin create /home/usuario/svn/home

 

Ahora ya en la parte cliente, creamos un directorio “home” ficticio, vacío, para subirlo al repositorio:

 

$ cd
$ mkdir home
$ export SVNROOT="svn+ssh://usuario@server.org/home/usuario/svn/home"
$ svn import home $SVNROOT -m "Creado homedir"
$ rm -rf ~/home

 

Finalmente, dentro de nuestro /home/usuario real, hacemos un checkout de “home” para que svn cree un directorio .svn de control en nuestro home.

 

$ cd /home/usuario
$ export SVNROOT="svn+ssh://usuario@server.org/home/usuario/svn/home"
$ svn checkout $SVNROOT . --force
Revisión obtenida: 0

 

Este checkout lo tenemos que realizar inicialmente en todos lo /home/usuario de los equipos donde queremos tener sincronizados los ficheros (por ejemplo, casa, trabajo, portátil)…

 

Ojo, –force sobreescribirá cualquier archivo ya existente, por lo que hay que revisar que no hayamos subido al SVN ninguno que no queramos tener idéntico entre los diferentes equipos (en cualquier caso, se recomienda hacer una copia previa a otro directorio “old” de los ficheros que se sobreescribirán la primera vez, por si acaso).

 

Desde este momento ya podemos subir ficheros a nuestro repositorio:

 

$ svn add .vimrc* .tmux.conf .gvimrc
A .vimrc
A .vimrc.common
A .tmux.conf
A .gvimrc

$ svn commit -m "Subidos ficheros iniciales"
Añadiendo .gvimrc
Añadiendo .tmux.conf
Añadiendo .vimrc
Añadiendo .vimrc.common
Transmitiendo contenido de archivos ..........
Commit de la revisión 1.

 

Con esto, cada vez que añadamos alguna funcionalidad nueva en el .vimrc, por ejemplo, en casa, podemos hacer un update en el trabajo y disfrutar de “contenidos sincronizados” sin andar enviando ficheros por correo o en unidades USB.

 

Simplemente tenemos que hacer un svn update en cada sitio para tener regularmente sincronizados los ficheros que tengamos en el repositorio.

 

# En otro sistema diferente, 
$ export SVNROOT="svn+ssh://sromero@server.sromero.org/home/sromero/svn/home"
$ svn update --force

 

Además de ficheros podemos añadir directorios completos con sus subdirectorios:

 

$ svn add docs
A docs/notas_subversion.txt
A docs/comandos_utiles.txt
A docs/tutorial_truecrypt.txt
(...)

$ svn commit -m "Subido directorio docs"

 

Si queremos añadir sólo algunos ficheros de un directorio (es decir, ficheros selectivamente, pero no todo el contenido), bastará con que agreguemos el directorio con –non-recursive y luego los ficheros individuales. Esto puede ser útil por ejemplo si tenemos un directorio que tiene algún fichero que DEBE de ser diferente en ambos sistemas:

 

$ ls -1 bin
haz_backup.sh
sistema_backup.py
wxmylauncher.py

$ svn add bin --non-recursive
A bin

$ svn add bin/sistema_backup.py bin/wxmylauncher.py
A bin/sistema_backup.py
A bin/wxmylauncher.py

$ svn commit -m "Subidos algunos ficheros de bin/"

 

De esta forma, los updates sólo actualizarán los 2 scripts que hemos marcado, y podemos tener así scripts con el mismo nombre pero distinto contenido en las diferentes máquinas.

 

Podemos habilitar un script para facilitarnos el “svn update” del home:

 

$ cat bin/update_home_svn.sh 
#!/bin/bash

# Update home directory from SVN
export SVNROOT="svn+ssh://usuario@server.org/home/usuario/svn/home"
cd $HOME
svn update

 

Siendo este script otro candidato a mantener en SVN (svn add bin/update_home_svn.sh + svn commit).

 

Etherpad - Editor web basado en la colaboración en tiempo real.

Permite a varios autores editar simultáneamente un documento de texto, y ver todos los participantes en las ediciones en tiempo real, con la capacidad de mostrar el texto de cada autor en diferente color. También hay una ventana de chat en la barra lateral para permitir la comunicación directa.

 

http://es.wikipedia.org/wiki/Etherpad

http://etherpad.org/

NGINX: una interesante alternativa a Apache.

Este antiguo servidor Web está ganando popularidad dentro del ámbito empresarial. NGINX es ahora el nuevo número dos de servidores Web, en gran parte porque es una alternativa rápida, ligera y de código abierto al todopoderoso Apache. He aquí el por qué atrae tanto la atención.

 

http://blog.desdelinux.net/nginx-una-interesante-alternativa-a-apache/

Cambiar codificaciones de caracteres de archivos. - iconv

iconv is a computer program and a standardized application programming interface (API) used to convert between different character encodings.

http://en.wikipedia.org/wiki/Iconv

 

Generador de instalaciones para programas Python ( y Windows)

py2Nsis is a Simple to Use, Nsis installers generator for python projects. It also make the setup.py for py2exe.

Nsis is a professional open source system to create Windows installers.

py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation.

py2Nsis combines the capabilities of these ones and generates directly a Windows installer with just a few information about your python code!

https://code.google.com/p/py2nsis/

Discos de arranque

We offer a boot disk for everything from MS-DOS 3.3 to Windows XP Professional. These disks can be used to setup a new hard drive, scan an existing hard drive for errors, install or re-install Windows, upgrade your PC's BIOS, run DOS utilities and much more.

Welcome to the all new AllBootDisks | AllBootDisks - Providing Free Boot Disk Downloads. MS-DOS to Windows XP.

Compresor de ejecutables - UPX

Compresor de ejecutables para distintas plataformas y tipos.

http://upx.sourceforge.net/

Ejecutar programas o archivos desde Delphi

To launch an application or execute a file in Win32 environment we will use the ShellExecute Windows API function. Check out the help on ShellExecute for full description of parameters and error codes returned.

http://delphi.about.com/od/windowsshellapi/a/executeprogram.htm