git, una puesta en marcha rápida

Git es un software que permite realizar un control de versiones de nuestro código, de manera distribuida.

Publico mis «notas» por si sirven de resumen rápido, agradeciendo cualquier correción.

#1 Instalación de Git

instalación (binaria) de Git usando un repositorio Debian/Ubuntu:

sudo apt install git

O bien descargando la última versión de su web (código fuente)

https://git-scm.com/download

Descomprimiendola y compilándola.

Y si git ya está instalado en tu sistema:

git clone git://git.kernel.org/pub/scm/git/git.git

#2 Configuración de Git

Existen numerosos manuales y tutoriales de git. Aquí por ejemplo puedes encontrar una explicación más detallada de lo que voy a hacer.

Git permite configurarse para todo el sistema (git config –system), para cada usuario (git config –global) o para cada proyecto.

Configuraré git para mi usuario introduciendo:

git config --global user.name "Mi nombre"
git config --global user.email micorreo@server.es

con estos dos comandos editamos el fichero de configuración de git a nivel de usuario que se encuentra en:
/home/usuario/.gitconfig
Configuramos un editor de texto:
git config --global core.editor nano
Y una utilidad para resolver los conflictos que puedan surgir en las versiones del código.

git config --global merge.tool vimdiff

#3 Uso de Git

Para comenzar se pueden dar dos escenarios:

  1. Queremos clonar un proyecto existente en un repositorio público para contribuir o modificarlo, o tener una copia local para simplemente compilarlo.
  2. Tenemos que poner bajo el control de git un proyecto propio.

Empecemos por éste último: Creemos un repositorio para un proyecto.

En nuestro home crearemos un directorio que albergará todos nuestros proyectos de programación, y dentro de él una carpeta para nuestro primer proyecto (directorio de trabajo):

mkdir ~/programacion
cd ~/programacion
mkdir ~/proyecto1
cd ~/proyecto1

En nuestro directorio podemos tener o no código: El repositorio se puede inicializar de todas formas.

git init

Ejecutamos el comando prestando atención y chequeando que estamos dentro del directorio del proyecto. El mensaje de confirmación nos corrobora que se ha creado un directorio .git en el que estarán los archivos necesarios para llevar el control de versiones del proyecto1.

Le decimos a git qué archivos tiene que controlar. Por facilidad controlaremos todos los archivos que albergue el directorio del proyecto utilizando un .

git add .

Otras posibilides para marcar los ficheros a controlar podrían ser seleccionar por extensión o por nombre utilizando comodines como *

Si ejecutamos un commit nos devolverá un mensaje en el que nos indica que está utilizando la rama principal, que es el primer commit que se realiza y que no ha enviado nada.

git commit -m 'inicio vacio'

El parámetro -m nos permite enviar un mensaje con el commit. Para más info de los parámetros del commit o cualquier otra opción de git se puede consultar su documentación:

git help commit

Prueba: Creamos un fichero en nuestro directorio, p.e. README y procedemos a realizar un commit:

git add .
git commit -m 'Archivo README'

Git nos confirma la inserción en el control de versiones. Los siguientes archivos de nueva creación no se incluyen automáticamente en el control de versiones. Los hay que marcar tal y como hemos hecho con el primero, mediante el comando git add.

NOTA: Conviene tener claro el esquema de funcionamiento de git. A grandes rasgos lo resumimos en:

  1. Añadimos al control de git los archivos de nuestro directorio de trabajo que deseamos con el comando git add (luego hablaremos más sobre ello).
  2. Preparamos los archivos que hemos modificado, curiosamente también con git add. Es decir, tenemos que indicar de los archivos que hemos marcado en el proceso 1, cuales queremos que se «preparen» y pasen el área de preparación para poder realizar la copia sobre ellos. Podemos decirle que queremos añadir todos al control de git y que todos se preparen para su copia con el comando git add . (con un punto que indica todos).
  3. Mediante el git commit realizamos las instantáneas a los archivos que se encuentran en el área de preparación. Esto hace que confirmemos la copia efectiva en nuestro repositorio y que los archivos desaparezcan del área de preparación.

#4 Uso de Git (II)

Estudiemos ahora el caso 1, cómo crear un repositorio local para un código que ya existe en un repositorio remoto: Por ejemplo, quiero en mi equipo el último código fuente de pyenv, en este caso para compilarlo sin más, y lo voy a clonar con git, lo que me garantiza que contaré en mi sistema con las últimas mejoras de este desarrollo (versión) que permite albergar varios entornos de python.

Igual que he creado un directorio para albergar mis proyectos, he creado otro para clonar un repositorio ya existente:

mkdir ~/programacion_tools
cd ~/programacion_tools

Una vez dentro del directorio hago un clonado utilizando la url del repositorio de pyenv en github:

git clone https://github.com/pyenv/pyenv

Esto me crea un directorio llamado pyenv, dentro de ~/programacion_tools. Podría haberle puesto otro nombre p.e. pyenv_local:

git clone https://github.com/pyenv/pyenv pyenv_local

Igual que en caso de mi repositorio local, git crea un subdirectorio llamado .git en el que se almacena en local el control de versiones.

Para chequear el estado de los archivos, si han sufrido modificaciones, utilizamos:

git status

Con repetir la instrucción git clone dentro del directorio actualizaré el código del pyenv.

#5 Uso básico de Git (III)

Una vez creado el repositorio y sabiendo que le tenemos que decir a git que archivos controlar, fijémonos en que git add sirve tanto para añadir archivos al control de versiones, como también para prepararlo y que en el próximo git commit se actualicen.

Git status nos proporcionará la situación de nuestros archivos: Si están añadidos, si no lo están. Si están añadidos pero no preparados (staged) para ser transmitidos. Si están preparados…

Anotemos este comando para pasar un/os archivos de preparados a no preparados

git reset HEAD nombrearchivo

¿Y si en mi directorio de trabajo tengo archivos y carpetas que no deseo incluir en las instantáneas de git?

Para eso tenemos varios mecanismos. Expliquemos .gitignore –> Es un un fichero en el que podemos crear exclusiones de ficheros y directorios de nuestro espacio de trabajo que git nos excluirá de su control:

nano ~/.gitignore
*.[oat]
*~
LOGS/

Colocando este fichero en nuestro directorio de trabajo, git no sincronizará los ficheros con extensión o ni con extensión .a ni con extensión .t. Tampoco los temporales ~. Además nos excluirá el subdirectorio completo LOGS. Todo esto es un ejemplo.

Si hemos creado el fichero antes del primer commit, se aplicará según su contenido. Ahora bien, si alguno de los ficheros excluidos ha sido versionado por git, habrá que borrarlo del repositorio o de lo contrario git segirá versionándolo. Esto se hace así:

git rm --cached nombrefichero.ext
echo nombrefichero.ext >> ~/.gitignore
git commit -m 'ignorado el fichero nombrefichero.ext'

El comando git rm con el parámetro –cached borra el fichero del repositorio. A continuación se añade la exclusión (también se podría haber editado el fichero con nano) y posteriormente se hace de nuevo la imagen con el commit. A partir de aquí los ficheros excluidos no se añadirán al repositorio.

Además del fichero .gitignore, que es la manera formal para no versionear ni distribuir en repositorios colaborados, es posible excluir ficheros de manera global y también de manera personal. Ésta última forma editando el fichero .git/info/exclude

+ información sobre .gitignore y sus patrones en https://www.atlassian.com/git/tutorials/gitignore

#6 Uso básico de Git

Recordemos que hay que añadir los archivos que queremos versionar o eliminar aquellos que no interesa controlar en el repositorio.

Una vez añadidos, los cambios realizados en nuestro directorio de trabajo no se preparan automáticamente para su confirmación (stage) sino que utilizamos la misma instrucción add que es polivalente:

git add .

De esta manera con el . añadimos todos los archivos y preparamos todos los archivos (staged) excepto los excluidos como vimos anteriormente. Obviamente estamos simplificando la operativa de esta manera.

git commit -m 'Cambios xxxxxxx'

La confirmación y la copia al repositorio viene con el comando commit. Si no añadimos un mensaje con el parámetro -m, se nos mostrará un mensaje en el que se nos pedirá que lo añadamos.

NOTA: Un atajo para no tener que preparar los archivos cada vez que queramos respaldar cambios:

git commit -a -m 'Confirmación sin staged'

El parámetro -a nos da velocidad y nos ahorra preparar (stage) los archivos que han sufrido cambios. Git automáticamente los confirmará y versionará.

Sobre la eliminación hemos hablado ya, y la resumimos en tres situaciones:

a) Sacar un archivo del repositorio pero no eliminarlo del área de trabajo.

git rm --cached ARCHIVO

La habíamos visto antes y es necesaria cuando queremos excluir del versioneado un archivo. Para que .gitignore funcione lo hay que sacar del repositorio.

b) Sacar un archivo del repositorio y eliminarlo del área de trabajo.

git rm --cached ARCHIVO

rm ARCHIVO

o bien directamente con una sola instrucción de git:

git rm ARCHIVO

Si eliminamos el archivo del directorio de trabajo git status nos avisará que ha sido borrado y nos dará dos opciones:

Recuperarlo:

git checkout ARCHIVO

Confirmar el borrado:

git add ARCHIVO

o

git rm ARCHIVO

#6 Log

Visualizar los cambios realizados (confirmaciones):

git log

Ídem con detalle

git log -p

Ídem (las últimas n confirmaciones):

git log -n

donde n es un número no un parámetro.

Otra forma de ver el log gráficamente es utilizando el programa gitk (u otros).

7# GIT SERVER para Synology

Synology facilita toda la información de configuración necesaria en este enlace: https://www.synology.com/es-es/knowledgebase/DSM/help/Git/git

Unos pocos comentarios al respecto y algún cambio que he introducido para no tener que usar la shell git-shell y así usar directamente git en nuestra shell habitual:

Panel de control >> Terminal

Hay que habilitar el acceso por ssh que es la forma en la que conectaremos con nuestros repositorios. Lo recomendable si vamos a tener acceso externo al servidor es cambiar el puerto por defecto de ssh, el 22. En su defecto podemos mapear desde nuestro router un puerto externo diferente vinculándolo al 22 y a la ip local del servidor nas. También se pueden utilizar los servicios de Acceso Externo de la nas. Trabajando en una red local suficientemente asegurada se puede mantener el puerto 22 sin ningún problema.

Una vez instalado el paquete Git Server, utilizamos un usuario existente en la nas o creamos uno específico p.e. git

En Panel de control >> usuario creamos el usuario git

Lanzamos Git Server desde el listado de programas y permitimos el acceso al usuario git. En el enlace anterior se explica perfectamente el funcionamiento a nivel de seguridad de esta configuración. (Este paso no sería imprescindible)

Por todo ello tendremos que crear el repositorio con un usario administrador de la NAS (admin), tal y como se explica en ese tutorial.

Y por otro lado accederemos a ese repositorio con el mismo usuario. Todo ello desde la línea de comandos de nuestro GNU/Linux o utilizando las aplicaciones correspondientes en otros sistemas operativos.

***Es probable que se tenga que asignar permisos de administrador al usuario git.

Configurar repositorio con admin:

ssh admin@ipservidor -p puertoservidor

ls -la nos devolverá el directorio entre el que se encuentras carpeta o carpetas con el nombre volume1, volume2, volumex, es decir los volúmenes de almacenamiento que tiene nuestro NAS. En la configuración más básica sólo tendrá 1.

Suponemos que utilizaremos el /volume1 y aquí creamos la carpeta raíz que contendrá todos nuestros repositorios.

cd /volume1
mkdir git
cd git

Es necesario dar permisos al usuario git en este directorio para la creación de los diferentes respositorios.

sudo chown git:root /volume1/git

NOTA: Problablemente tengas que utilizar sudo. La nueva carpeta nos la creará con permisos para root y limitados para los usuarios.
Estos permisos se cambiarán con chmod y chown para poder realizar los siguientes pasos, según cómo queramos crear los repos, porque incluso al realizar un git init con la opción –shared Git modificará los permisos del nuevo repositorio para hacerlo accesible al grupo de usuarios.

NOTA2: Hay que tener en cuenta que se pueden iniciar repositorios de dos maneras diferentes. Esto implica que además de un cambio en la estructura física del repositorio, podemos decir que la creación de un repo con git init –bare frente al git init usado hasta ahora implica que estamos ante un repositorio para compartir frente a un repositorio de trabajo. Dentro de mis necesidades el repositorio de trabajo lo utilizo en mi equipo de desarrollo, mientras que para mantener las copias de las versiones en el repositorio remoto (en la Nas) se adapta mejor la filosofía del repositorio compartido y creado con –bare. Por lo tanto crearemos un repositorio bare.

NOTA3: Si queremos utilizar las funciones estándar de backup que incorpora el nas, la carpeta git debe crearse como carpeta compartida o bien crearla dentro de una carpeta compartida. De esta manera será accesible por la aplicación de copia de seguridad.

¿Cómo crear el repositorio compartido en el servidor 1 – camino largo?

Podría haber más de una estrategia. Para mí la más lógica es crearlo con contenido, es decir, copiar el repositorio git local de mi ordenador al servidor y compartirlo con git init –bare.

Nos dirigimos al directorio de nuestro equipo en el que está nuestro proyecto, p.e. ~/programación/proyecto1. Dentro de él hay un directorio .git, que es nuestro repositorio local (previamente mediante git init lo hemos creado y realizado un commit).  Hacemos un clonado del repositorio sin carpeta de trabajo (opción –bare). Manualmente se puede hacer copiando la carpeta .git

git clone --bare ~/programacion/proyecto1 ~/programacion/proyecto1bare.git

Copiamos el contenido del nuevo repositorio en el directorio git recién creado en el servidor.

scp -rP puerto ~/proyectosgit/proyecto1bare.git git@ipservidor:/volume1/git

Accedemos mediante ssh al servidor y situándonos dentro del repositorio copiado:

cd /volume1/git/proyecto1bare.git

Iniciamos el respositorio con la opción –shared que garantiza permisos de escritura para los usuarios.

git init --bare --shared

Aunque una vez copiado el repo en el servidor estaría funcional, esta última instrucción es necesaria para reiniciarlo.

Acceder al repositorio con nuestro usuario git

Podemos clonar el repo del servidor de nuevo a nuestro equipo, a nuestra carpeta de proyectos ~/programacion/  y ejecutamos:

git clone ssh://git@ipservidor:puerto/volume1/git/proyecto1bare.git

Nos creará un nuevo repositorio local y nuestro área de trabajo dentro de la nueva carpeta proyecto1bare

Pero quizá sea más práctico regresar a nuestro repositorio local inicial y luego añadirle «un origen» el repositorio remoto

cd ~/programacion/proyecto1
git remote add origin ssh://git@ipservidor:puerto/volume1/git/proyecto1bare.git

Y realizar un pull para sincronizar:

git pull origin master

Recuperamos la información del repositorio remoto que copiará los datos también a nuestro directorio de trabajo.

NOTA: Se puede comprobar antes y después con git remote -v cómo el repositorio local pasa de ser independiente a tener un origen.

¿Cómo crear el repositorio compartido en el servidor 1 – camino rápido?

Partiendo de nuestro repositorio local (y si no lo tenemos lo creamos ejecutando en la carpeta raiz del proyecto la instrucción git init y luego realizando un commit para que el repo local no esté vacío) creamos previamente en el servidor git la conocida carpeta en la que guardaremos el repo y lo iniciamos con la opción –bare:

cd /volume1/git
mkdir proyecto1bare.git
cd proyecto1bare.git
git init --bare --shared

A partir de aquí añadimos un origen remoto al repositorio local y luego le lanzamos el push que subirá los archivos al repositorio remoto:

cd ~/programacion/proyecto1
git remote add origin ssh://git@ipservidor:puerto/volume1/git/proyecto1bare.git
git push origin master

COMMIT al repositorio remoto

Llegados a este nivel de conocimiento sabemos que los ficheros que añadamos y preparemos en nuestro directorio de trabajo de nuestro equipo, cuando ejecutemos la instrucción

git commit -m 'mensaje'

Serán versionados a nuestro repositorio local, clonado o al que hayamos añadido un origen a posteriori, y no serán transmitidos al directorio remoto hasta que lo hagamos explicitamente. La subida de la imagen al repositorio remoto se hace con:

git push origin master

Un push al server definido por origin indicándole la rama, por defecto master.

NOTA: Si creamos un repositorio remoto vacío, un repositorio local al que le añadimos como origen el remoto y lanzamos un push no funcionará ya que no hay creada la rama master. Una opción sencilla para inicializar los repositorios podría ser crear un fichero README o LEEME prepararlo y confirmarlo en el repo local, abriendo así la rama master y a continuación el push al repositorio remoto que abrirá la rama master (origin/master). Para más investigación de cómo empezar totalmente en vacío: https://bit-booster.com/doing-git-wrong/2017/01/02/git-init-empty/

NOTA: Para conocer la url del repositorio remoto:

git remote -v

+Enlaces de interés:

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

https://swcarpentry.github.io/git-novice/09-conflict/ –> Interesante para resolver conflictos de edición.

NOTA

+info sobre git y sobre la creación de servidores git en GNU/Linux

https://git-scm.com/book/es/v2/Git-en-el-Servidor-Configurando-el-servidor

NOTA: LF vs CRLF

https://stackoverflow.com/questions/5834014/lf-will-be-replaced-by-crlf-in-git-what-is-that-and-is-it-important

+info: Finales de línea archivos texto

https://docs.github.com/es/github/using-git/configuring-git-to-handle-line-endings

NOTA: Eliminar archivos de los repositorios ELIMINAR

Elimina del stage un archivo o carpeta

git reset HEAD nombre_de_archivo

Elimina todos del stage

git reset HEAD .

Elimina archivo confirmado con commit pero no del área de trabajo (físicamente del directorio)

git rm --cached nombre_archivo

Lo mismo pero eliminando directorio:

git rm -r --cached nombre_directorio

Eliminando –cached también se borra del directorio de trabajo

CONFIRMAR ELIMINACIÓN

git commit -m 'Archivos_eliminados_nom_archivo'

ACTUALIZACIÓN REPOSITORIO REMOTO

Realizando un push general o a la rama concreta en la que se está trabajando

RECUPERACIÓN DE FICHEROS DESDE EL COMMIT LOCAL

git log–oneline  –> para elegir el commit

git checkout [numero del commit] [nombre del fichero]

Un asterisco recuperará el commit completo

Etiquetas:,

Añadir un comentario

Tu dirección de correo electrónico no será publicada.