Skip to content

igp7/git

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 

Repository files navigation

Git

Indice

Configuración inicial

Git trae una herramienta llamada git config que te permite obtener y establecer variables de configuración, que controlan el aspecto y funcionamiento de Git. Existen tres contextos de configuración:

  • --global: Las configuraciones globales están disponibles para el usuario actual para todos los proyectos y se almacenan en ~/.gitconfig o ~/.config/git/config. Puedes hacer que git lea y escriba desde Global pasando la opción --global. Por ejemplo:

    # Create a global config
    $ git config --global user.name "Global User"
  • --system: Estas variables están disponibles para cada usuario del sistema y se almacenan en [path]/etc/gitconfig. Puedes hacer que git lea y escriba desde System pasando --system como opción. También requiere que tengas permisos de administración. Por ejemplo:

    # Create a system config
    $ sudo git config --system user.name "System User"
  • --local: Las configuraciones locales están disponibles sólo para el repositorio actual. Puede hacer que git lea y escriba desde Local pasando la opción --local. Por ejemplo:

    # Create a local specific config
    $ git config --local user.name "Local User"

Nota: Si no se especifica ningún nivel, local es nivel por defecto . Además, es importante recordar que cada nivel anula los valores del nivel anterior. Prioridad:

Local > Global > Sistema

Nota: Cada uno de los contextos tiene su propio archivo de configuración. Los archivos de configuración de Git son de texto plano, por lo que también puedes ajustar manualmente los valores de configuración, editando directamente los archivos correspondientes y escribiendo en ellos con la sintaxis correspondiente; pero suele ser más sencillo hacerlo siempre a través del comando git config.

  • Visualizar configuración: Si quieres comprobar tu configuración, listando todas las propiedades que Git ha configurado.

    $ git config --list

    Nota: También puedes comprobar qué valor cree Git que tiene una clave específica ejecutando git config {clave}.

    $ git config user.name
  • Visualizar origen de configuración: Si quieres comprobar tu configuración, listando todas las propiedades que Git ha configurado y en que nivel.

    git config --list --show-origin
  • Identidad: Para establecer tu nombre de usuario y dirección de correo electrónico en Git.

    $ git config --global user.name "<name>"
    $ git config --global user.email <mail>

    Nota: La opción --global, permite a Git usar siempre esta información para todo lo que hagas en ese sistema.

  • Editor: Puedes elegir el editor de texto por defecto que se utilizará cuando Git necesite que introduzcas un mensaje. Si no indicas nada, Git usa el editor por defecto de tu sistema, que generalmente es Vi o Vim.

    $ git config --global core.editor <name editor>
  • Manejar finales de línea: Establece el modo en que Git maneja los finales de línea y así evitar posibles errores entre distintos sistemas operativos por el modo que realizan los finales de linea. Toma un solo argumento.

    # En Linux y Mac
    $ git config --global core.autocrlf input
    
    # En Windows
    $ git config --global core.autocrlf true
  • Herramienta de diferencias: Para configurar es la herramienta de diferencias por defecto, usada para resolver conflictos de unión (merge).

    $ git config --global merge.tool <name herramienta>

    Nota: Git acepta kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, y opendiff como herramientas válidas.

  • Colores en la línea de comandos: Git permite la coloración útil de la salida de línea de comando.

    $ git config --global color.ui auto
  • Visualizacion de caracteres "inusuales": Para que git muestre correctamente caracteres que considera "inusuales", por ejemplo la ñ.

    # Activar para todos los repositorios
    $ git config --global core.quotepath off
  • Nombre de la rama principal: Establecer el nombre de la rama inicial cuando se crea el repositorio.

    $ git config --global init.defaultBranch [name-rama]

    o atraves del fichero de configuración ~/.gitconfig:

    [init]
    defaultBranch = [name-rama]
    

Nota: Mas información sobre configuración de git aquí.

Conexión SSH

Github

Generar una nueva clave SSH
  1. Abre la Terminal.
  2. Pega el siguiente texto, que sustituye tu dirección de correo electrónico en GitHub.
ssh-keygen -t rsa -b 4096 -C "[email protected]"

Esto crea una nueva clave ssh usando el correo electrónico proporcionado como etiqueta.

Generating public/private rsa key pair.

  1. Cuando se te indique "Ingresar un archivo donde guardar la clave", presiona Intro. Al hacerlo aceptas la ubicación predeterminada del archivo.

    Enter a file in which to save the key (/home/you/.ssh/id_rsa): [Press enter]

  2. Donde se indica, escribe una contraseña segura. Para obtener más información, consulta "Trabajar con frases de contraseña de la clave SSH".

    Enter passphrase (empty for no passphrase): [Type a passphrase]

    Enter same passphrase again: [Type passphrase again]

Agregar tu clave SSH al ssh-agent

Antes de agregar una nueva clave SSH al ssh-agent para gestionar tus claves, debes haber comprobado las claves SSH existentes y generado una nueva clave SSH.

  1. Inicia el agente SSH en segundo plano.
eval "$(ssh-agent -s)"
  1. Agrega tu llave privada SSH al ssh-agent. Si creaste tu llave con un nombre distinto, o si estás agregando una llave existente que tiene un nombre distinto, reemplaza id_rsa en el comando con el nombre de tu archivo de llave privada.
ssh-add ~/.ssh/id_rsa
  1. Agrega la clave SSH a tu cuenta de GitHub

Creación y obtención de un repositorio Git

Puedes obtener un proyecto Git de dos maneras. La primera toma un proyecto o directorio existente y lo importa en Git. La segunda clona un repositorio Git existente desde otro servidor.

  • Crear un repositorio: Si estás empezando el seguimiento en Git de un proyecto existente, necesitas ir al directorio del proyecto y escribir:

    $ git init

    Esto crea un nuevo subdirectorio llamado. git que contiene todos los archivos necesarios del repositorio —un esqueleto de un repositorio Git.

  • Clonar un repositorio existente: Para obtener una copia de un repositorio Git existente, se usa:

    $ git clone <url>

    Si se quiere cambiar el nombre del repositorio usa el siguiente comando:

    $ git clone <url> <name-nuevo>

    Para realizar un clone superficial con un historial truncado al número de confirmaciones especificado. Implica --single-branch a menos que se indique --no-single-branch para obtener los historiales cercanos a las puntas de todas las ramas. Si quiere clonar submódulos de forma superficial, pase también --shallow-submodules, (Util para CI):

    $ git clone <url> --depth <depth>
  • Clonar un repositorio con submodulos: Con --recursive en el comando git clone, se inicializará y actualizará automáticamente cada submódulo en el repositorio.

    $ git clone --recursive [URL]

Guardado de cambios en el repositorio

Cada archivo de tu directorio de trabajo puede estar en uno de estos dos estados: bajo seguimiento (tracked), o sin seguimiento (untracked). Los archivos bajo seguimiento son aquellos que existían en la última instantánea; pueden estar sin modificaciones, modificados, o preparados. Los archivos sin seguimiento son todos los demás (cualquier archivo de tu directorio que no estuviese en tu última instantánea ni está en tu área de preparación). La primera vez que clonas un repositorio, todos tus archivos estarán bajo seguimiento y sin modificaciones, ya que los acabas de copiar y no has modificado nada.

  • Comprobando el estado de tus archivos: Herramienta para determinar el estado de los archivos.

    $ git status
  • Seguimiento de nuevos archivos: Para empezar el seguimiento de un nuevo archivo.

    $ git add <name-archivo>

    Para añadir todos los archivos puedes usar:

    $ git add *

    Si modificas un archivo después de a ver realizado git add será necesario añadir otra vez el fichero con git add para que la modificación pueda ser incluida en el commit. Se recomienda hacer siempre git add antes de un commit.

  • Ignorar archivos: A través de un archivo llamado .gitignore, puedes listas los patrones de nombres de archivos o directorios que deseas que sean ignorados. He aquí un archivo .gitignore de ejemplo:

    *.[oa]
    *~
    <name_directorio>/

    La primera línea le dice a Git que ignore cualquier archivo cuyo nombre termine en .o o .a (archivos objeto que suelen ser producto de la compilación de código). La segunda línea le dice a Git que ignore todos los archivos que terminan en tilde (~), usada por muchos editores de texto, como Emacs, para marcar archivos temporales. La ultima línea le dice a Git que ignore un directorio concreto. Las reglas para los patrones que pueden ser incluidos en el archivo .gitignore son:

    • Las líneas en blanco, o que comienzan por #, son ignoradas.
    • Puedes usar patrones glob estándar (expresiones regulares simplificadas que pueden ser usadas por las shells).
    • Puedes indicar un directorio añadiendo una barra hacia delante (/) al final.
    • Puedes negar un patrón añadiendo una exclamación (!) al principio.
  • Ver los cambios preparados y no preparados: Para visualizar exactamente las líneas añadidas y eliminadas en los archivos, usamos:

    $ git diff
  • Confirmación de cambios: Cuando tienes los archivos preparados para realizar una confirmación, se usa:

    $ git commit -m "<texto del commit>"

    Nota: Si quieres saltarte el área de preparación, Git proporciona un atajo. Pasar la opción -a al comando git commit hace que Git prepare todo archivo que estuviese en seguimiento antes de la confirmación, permitiéndote obviar toda la parte de git add.

    $ git commit -a -m "<texto del commit>"
  • Commits verificados firmados con PGP:

    $ git commit -S -m your commit message
  • Eliminar archivos: Para eliminar un archivo de Git, debes eliminarlo de tus archivos bajo seguimiento (más concretamente, debes eliminarlo de tu área de preparación), y después confirmar.

    $ git rm <name archivo>

    Si ya habías modificado el archivo y lo tenías en el área de preparación, deberás forzar su eliminación con la opción -f.

    $ git rm -f <name archivo>

    Para mantener el archivo en tu disco duro, pero interrumpir su seguimiento por parte de Git. Esto resulta particularmente útil cuando olvidaste añadir algo a tu archivo .gitignore y lo añadiste accidentalmente, como un archivo de log enorme, o un montón de archivos .a. Para hacer esto, usa la opción --cached:

    $ git rm --cached readme.txt

    Nota: El comando git rm acepta archivos, directorios, y patrones glob. Es decir, que podrías hacer algo así:

    $ git rm log/\*.log
  • Renombrar archivos: Git no se da cuenta explícitamente del cambio de nombre de un archivo, pero permite realizar un renombramiento de forma rápida:

    $ git mv <file_from> <file_to>

Histórico de confirmaciones

Después de haber hecho varias confirmaciones, o si has clonado un repositorio que ya tenía un histórico de confirmaciones, probablemente quieras mirar atrás para ver qué modificaciones se han llevado a cabo. La herramienta más básica y potente para hacer esto es:

$ git log

Para poder ver los ficheros modificados en cada commit del histórico de confirmaciones:

$ git log --stat

Visualizar el historial de forma minimalista:

$ git log --graph --oneline --decorate --all

Una de las opciones más útiles es -p, que muestra las diferencias introducidas en cada confirmación. También puedes usar la opción -2, que hace que se muestren únicamente las dos últimas entradas del histórico:

$ git log -p -<número de ultimas entradas a mostrar>

Las opciones temporales como --since (desde) y --until (hasta) muestran las entradas desde una fecha o hasta una fecha. El formato de las fechas acepta varios tipos, como una fecha concreta (“2008-01-15”), o relativa, como “2 years 1 day 3 minutes ago” (“hace 2 años, 1 día y 3 minutos”).

$ git log --since=<2.weeks> o <"2008-10-01">

También puedes filtrar la lista para que muestre sólo aquellas confirmaciones que cumplen ciertos criterios. La opción --author te permite filtrar por autor, y --grep te permite buscar palabras clave entre los mensajes de confirmación. (Ten en cuenta que si quieres aplicar ambas opciones simultáneamente, tienes que añadir --all-match, o el comando mostrará las confirmaciones que cumplan cualquiera de las dos, no necesariamente las dos a la vez.).

$ git log --all-match --author=<name autor> --grep="<texto a buscar en los commit>"

Para visualizar información de un commit concreto se usa:

$ git show [commit]

Deshacer cosas

Ésta es una de las pocas áreas de Git que pueden provocar que pierdas datos si haces las cosas incorrectamente.

Reset

$ git reset [mode] [commit]

Esta forma restablece la cabeza (HEAD) de rama actual a [commit] y posiblemente actualiza el índice (estableciéndolo al árbol de [commit]) y el área de trabajo dependiendo de [mode]. Si se omite [modo], el valor por defecto es --mixed. El [modo] debe ser uno de los siguientes:

  • Soft: Elimina el commit y devuelve los ficheros confirmados en dicho commit a área de preparación.
    $ git reset --soft [commit]
  • Mixed: Elimina el commit y devuelve los ficheros confirmados en dicho commit a área de trabajo.
    $ git reset --mixed [commit]
    o
    $ git reset [commit]
  • Hard: Elimina el commit y los cambios realizados en los ficheros modificados del dicho commit desaparecen.
    $ git reset --hard [commit]

Casos de uso

  • Modificar la última confirmación: Si quieres volver a hacer la confirmación par añadir algún cambio en un archivo que se te ha olvidado, puedes usar:

     $ git commit --amend

    Este comando utiliza lo que haya en tu área de preparación para la confirmación. Si no has hecho ningún cambio desde la última confirmación (por ejemplo, si ejecutas este comando justo después de tu confirmación anterior), esta instantánea será exactamente igual, y lo único que cambiarás será el mensaje de confirmación. Por ejemplo, si confirmas y luego te das cuenta de que se te olvidó preparar los cambios en uno de los archivos que querías añadir, puedes hacer algo así:

    $ git commit -m 'initial commit'
    $ git add forgotten_file
    $ git commit --amend

    Estos tres comandos acabarán convirtiéndose en una única confirmación y la segunda confirmación reemplazará los resultados de la primera.

  • Deshaciendo la preparación de un archivo: Cuando quieres sacar un archivo del área de preparación.

    $ git reset HEAD <archivo>
  • Resetear un fichero a su estado en e repositorio: Cuando quieres resetear un fichero a su estado en el área de repositorio:

    $ git checkout <fichero>

Restore

  • git restore restablece el archivo a su contenido anterior, perdiendo los cambios que realizaras.

Casos de uso

  • Eliminar uno ficheros de la zona staged:
$ git restore --stage [fichero]

Repositorios remotos

Los repositorios remotos son versiones de tu proyecto que se encuentran alojados en Internet o en algún punto de la red. Puedes tener varios, cada uno de los cuales puede ser de sólo lectura, o de lectura/escritura, según los permisos que tengas. Colaborar con otros implica gestionar estos repositorios remotos, y mandar (push) y recibir (pull) datos de ellos cuando necesites compartir cosas.

  • Mostrando repositorios remotos: Mostrar los repositorios remotos configurados. Si has clonado tu repositorio, deberías ver por lo menos "origin" (es el nombre predeterminado que le da Git al servidor del que clonast). área de preparación.

    $ git remote

    También puedes añadir la opción -v, que muestra la URL asociada a cada repositorio remoto:

    $ git remote -v
  • Añadir repositorios remotos: Para añadir un nuevo repositorio Git remoto, asignándole un nombre con el que referenciarlo fácilmente.

    $ git remote add [nombre] [url]

    Ahora puedes usar la cadena [nombre] en la línea de comandos, en lugar de toda la URL. Para recuperar toda la información del repositorio, puedes ejecutar:

    $ git fetch [nombre]
  • Recibir de tus repositorios remotos: Para recuperar todos los datos de los repositorios remotos puedes ejecutar:

    $ git fetch [remote-name]

    Si clonas un repositorio, el comando añade automáticamente ese repositorio remoto con el nombre de "origin". Por tanto, git fetch origin recupera toda la información enviada a ese servidor desde que lo clonaste (o desde la última vez que ejecutaste fetch). Es importante tener en cuenta que el comando fetch sólo recupera la información y la pone en tu repositorio local (no la une automáticamente con tu trabajo ni modifica aquello en lo que estás trabajando). Tendrás que unir ambos manualmente a posteriori. Si has configurado una rama para seguir otra rama remota, puedes recuperar y unir automáticamente la rama remota con tu rama actual con el comando:

    $ git pull [remote-name]

    Por defecto, el comando git clone automáticamente configura tu rama local maestra para que siga la rama remota maestra del servidor del cual clonaste (asumiendo que el repositorio remoto tiene una rama maestra). Al ejecutar git pull, por lo general se recupera la información del servidor del que clonaste, y automáticamente se intenta unir con el código con el que estás trabajando actualmente.

    Nota: La diferencias entre git fetch y git pull es que git fetch solo trae la información del repositorio remoto sin llegar a fusionar los cambios en la rama local. Mientras git pull trae la información y la fusiona en la rama local.

  • Envió a repositorios remotos: Enviar el estado de tu repositorio a un repositorio remoto.

    $ git push [nombre-remoto] [nombre-rama]

    Por ejemplo: Si quieres enviar tu rama maestra (master) a tu servidor origen (origin), ejecutarías esto para enviar tu trabajo al servidor:

    $ git push origin master

    Este comando funciona únicamente si has clonado de un servidor en el que tienes permiso de escritura, y nadie ha enviado información mientras tanto. Si tú y otra persona clonáis a la vez, y él envía su información y luego envías tú la tuya, tu envío será rechazado. Tendrás que bajarte primero su trabajo e incorporarlo en el tuyo para que se te permita hacer un envío.

  • Inspeccionar un repositorio remoto: Para ver más información acerca de un repositorio remoto en particular.

    $ git remote show [nombre]

    Esto lista la URL del repositorio remoto, así como información sobre las ramas bajo seguimiento. Este comando te recuerda que, si estás en la rama maestra y ejecutas git pull, automáticamente unirá los cambios a la rama maestra del remoto después de haber recuperado todas las referencias remotas. También lista todas las referencias remotas que ha recibido.

  • Renombrar repositorios remotos: Para renombrar una referencia a un repositorio remoto.

    $ git remote rename [nombre actual] [nuevo nombre]
  • Eliminar repositorios remotos: Para eliminar una referencia, has movido el servidor o ya no estás usando un determinado mirror, o quizás un contribuidor ha dejado de contribuir.

    $ git remote rm [nombre]
  • Cambiar la URL de un remoto: Para cambia una URL de un repositorio remoto existente.

$ git remote set-url [remoto existente] [nueva URL]
  • Un nombre de remoto existente. Por ejemplo, origin o upstream son dos de las opciones comunes.
  • Una nueva URL para el remoto. Por ejemplo:
    • Si estás actualizando para usar HTTPS, tu URL puede verse como:
      https://github.com/USERNAME/REPOSITORY.git
      
    • Si estás actualizando para usar SSH, tu URL puede verse como:
      [email protected]:USERNAME/REPOSITORY.git
      
  • Comprobar existencia de repositorio remoto: Comprueba que el nombre del remoto es correcto.
$ git remote set-url sofake [URL repositorio remoto]

Ramas

Una rama Git es simplemente un apuntador móvil apuntando a una de las confirmaciones. La rama por defecto de Git es la rama master. Con la primera confirmación de cambios que realicemos, se creará esta rama principal master apuntando a dicha confirmación. En cada confirmación de cambios que realicemos, la rama irá avanzando automáticamente. Y la rama master apuntará siempre a la última confirmación realizada.

  • Mostrar ramas: Para mostrar las ramas almacenadas en el repositorio.

    $ git branch

    Para ver la última confirmación de cambios en cada rama.

    $ git branch -v
  • Crear ramas: Para crear ramas nuevas.

    $ git branch [name-rama]
  • Eliminar ramas: Para eliminar ramas.

    $ git branch -d [name-rama]
  • Eliminar ramas de forma forzosa: Cuando la rama que estás borrando cumple alguna de las siguientes condiciones, si los commits de esa rama no están fusionados con la rama 'master' o si los commits en esa rama no son empujados a un repositorio remoto. Git no te permitirá borrar esa rama con la opcion -d.

    $ git branch -D [name-rama]
  • Renombrar una rama: Renombrar una rama existente.

    $ git branch -M [name-rama]
  • Recuperar una rama borrada: Cuando eliminas una rama, Git muestra el SHA1 de esa rama. Haciendo uso de ese SH1 se puede restaurar la rama borrada.

    $ git checkout [name-rama] [SHA1-SUM]
  • Cambiar de rama: Para cambiar entre ramas.

    $ git checkout [name-rama]
  • Fusionar ramas: Para fusionar dos ramas, nos posicionamos sobre la rama a la que queremos incorporar las confirmaciones de otra rama y ejecutamos el siguiente comando:

    $ git merge [rama de donde se traen las confirmaciones]
  • Reorganización: Con la reorganización puedes coger todos los cambios confirmados en una rama, y replicarlos sobre otra. Esto ayuda a que el desarrollo del proyecto parezca lineal y más fácil de seguir. Para realizar la reorganización te posicionas sobre la rama donde están las confirmaciones que quieres volcar sobre otra rama y ejecutas el siguiente comando:

    $ git rebase [rama donde se quieren volcar las confirmaciones para reorganizar]

    Después, te posicionas sobre la rama donde has volcado las confirmaciones y realizas un merge con la rama de donde trajiste las confirmaciones.

    $ git merge [rama donde estaban las confirmaciones para reorganizar]

Ramas remotas

Las ramas remotas son referencias al estado de ramas en tus repositorios remotos. Son ramas locales que no puedes mover; se mueven automáticamente cuando estableces comunicaciones en la red. Las ramas remotas funcionan como marcadores, para recordarte en qué estado se encontraban tus repositorios remotos la última vez que conectaste con ellos.

  • Publicar en ramas remotas: Tus ramas locales no se sincronizan automáticamente con los remotos en los que escribes. Sino que tienes que llevar (push) expresamente, cada vez, al remoto las ramas que desees compartir.

    $ git push [name-remoto] [name-rama-local]

    También puedes utilizar publicar una rama local con otro nombre en la rama en remoto, mediante el siguiente comando.

    $ git push [name-remoto] [name-rama-local]:[name-rama-remoto]
  • Seguimiento a las ramas remotas: Las ramas de seguimiento son ramas locales que tienen una relación directa con alguna rama remota. Si estás en una rama de seguimiento y tecleas el comando git push, Git sabe automáticamente a qué servidor y a qué rama ha de llevar los contenidos. Igualmente, tecleando git pull mientras estamos en una de esas ramas, recupera (fetch) todas las referencias remotas y las consolida (merge) automáticamente en la correspondiente rama remota.

    • Relacionar rama existente en local con rama remota: Para realizar el seguimiento entre una rama ya creada en local y una rama en remoto se usa el siguiente comando:
      $ git branch --set-upstream-to=[name-remoto]/[name-rama-remoto] [name-rama-local]
    • Crear una rama nueva en local y relacionarla con rama remota: Para realizar el seguimiento entre una rama nueva sin crear en local y una rama en remoto se usa el siguiente comando:
      $ git checkout --track [name-remote]/[name-rama-remota]
      Para preparar una rama local con un nombre distinto a la del remoto, puedes utilizar:
      $ git checkout -b [name-rama-nueva-local] [nombre-remoto]/[rama-remoto]
  • Borrar ramas remotas: Puedes borrar una rama remota utilizando el siguiente comando:

    $ git push [nombre-remoto] :[rama-remoto]

Etiquetas

Git tiene la habilidad de etiquetar (tag) puntos específicos en la historia como importantes. Generalmente la gente usa esta funcionalidad para marcar puntos donde se ha lanzado alguna versión (v1.0, y así sucesivamente).

  • Listar etiquetas: Listar las etiquetas disponibles en orden alfabético, el orden en el que aparecen no es realmente importante.

    $ git tag

    También se puede buscar etiquetas de acuerdo a un patrón en particular. Por ejemplo, si solo estás interesado en la serie 1.4.2:

    $ git tag -l 'v1.4.2.*'
  • Crear etiquetas: Git usa dos tipos principales de etiquetas: ligeras y anotadas. Una etiqueta ligera es muy parecida a una rama que no cambia (un puntero a una confirmación específica). Sin embargo, las etiquetas anotadas son almacenadas como objetos completos en la base de datos de Git. Tienen suma de comprobación; contienen el nombre del etiquetador, correo electrónico y fecha; tienen mensaje de etiquetado; y pueden estar firmadas y verificadas con GNU Privacy Guard (GPG).

    • Etiquetas anotadas: Las etiquetas anotadas son almacenadas como objetos completos en la base de datos de Git.

      $ git tag -a [version (v1.2)] -m 'mensaje'
    • Etiquetas firmadas: Puedes firmar tus etiquetas con GPG, siempre que tengas una clave privada, lo único que debes hacer es usar -s en vez de -a:

      $ git tag -s [version (v1.2)] -m 'mensaje'
    • Etiquetas ligeras: Es básicamente la suma de comprobación de la confirmación almacenada en un archivo (ninguna otra información es guardada).

      $ git tag [version (v1.2)]
    • Verificar etiquetas: Para verificar una etiqueta firmada, se utiliza GPG para verificar la firma. Necesitas la clave pública del autor de la firma en tu llavero para que funcione correctamente.

      $ git tag -v [tag-name]
  • Etiquetar un commit anterior: Para etiquetar una confirmación especifica la suma de comprobación de la confirmación (o una parte de la misma) al final del comando:

    $ git tag -a [tag-name] -m 'mensaje' [encabezado (9fceb02)]
  • Enviar etiquetas al servidor: Enviarlas explícitamente a un servidor compartido después de haberlas creado.

    $ git push [nombre-remoto] [tagname]

    Para transferir todas las etiquetas que no estén ya en el servidor remoto.

    $ git push origin --tags

Submodulos

Los submódulos permiten mantener un repositorio de Git como un subdirectorio de otro repositorio de Git. Esto permite clonar otro repositorio en un proyecto y mantener sus commits separados.

  • Agregar nuevo submódulo: Permite Agregar un repositorio de Git existente como un submódulo del repositorio en el que estamos trabajando. Para agregar un nuevo submódulo, se utiliza el comando git submodule add con la URL del proyecto que desea empezar a rastrear.

    $ git submodule add [URL] [PATH]

    Por defecto, los submódulos agregarán el subproyecto a un directorio llamado igual que el repositorio y añadiran un nuevo archivo .gitmodules. Este es un archivo de configuración que almacena la asignación entre la URL del proyecto y el subdirectorio local en el que lo ha insertado:

    [submodule "[name_submodule]"]
       path = [directorio_submodule]
       url = [URL]
    

    Si tiene múltiples submódulos, tendrá múltiples entradas en este archivo. Es importante tener en cuenta que este archivo está controlado por la versión con sus otros archivos, como su archivo .gitignore.

    Nota: Puede sobrescribir el valor de la URL localmente usar git config submodule.[name_submodule].url PRIVATE_URL para su propio uso.

  • Clonar un repositorio con submodulos: Con --recursive en el comando git clone, se inicializará y actualizará automáticamente cada submódulo en el repositorio.

    $ git clone --recursive [URL]
  • Actualizar todos los submódulos: Git permite buscar todos los submódulos y actualizar todos los submodulos automaticamente.

    git submodule update --remote [nombre_submodulo] # [nombre_submodulo] opcional

Comandos Avanzados

Cherry-pick

El comando git cherry-pick permite copiar uno o varios commints y pegarlos en otra rama. Para ello hay que posicionarse en la rama a la que se quiere traer el o los commits.

$ git checkout [rama]
$ git cherry-pick [commit/s]

Opciones:

  • -n: Permite traer los cambios realizados en el commits o commits selecionados y deja esos cambios en el area de preparacion, sin crear un nuevo commit o commits.
$ git cherry-pick -n [commit] [commit]

Stash

Con stash se toma el estado actual del directorio de trabajo – que es, tus archivos controlados por la versión modificados y cambios almacenados – y lo guarda en una pila de cambios sin terminar que puedes volver a usar en cualquier momento.

  • Crear un punto de guardado: Permite crear el estado actual del directorio de trabajo.
    $ git stash
  • Visualizar puntos de guardado almacenados: Para visualizar los puntos de guardados que forman la pila:
    $ git stash list
  • Retornar a estado guardado: Existen dos formas de volver al estado del directorio de trabajo almacenado en en la pila de puntos de guardado:
    • apply: Devuelve el punto de guardado almacenado sin eliminarlo de la pila de guardado.
      $ git stash apply stash@{[id]}
    • pop: Devuelve el punto de guardado almacenado y lo elimina de la pila de guardado.
      $ git stash pop stash@{[id]}
  • Eliminar punto de guardado: Para eliminar un punto de guardado.
    $ git stash drop stash@{[id]}
  • Crear una rama desde un punto de guardado: Crear una nueva rama desde un punto de guardado, verifica el “commit” en el que estaba cuando se realizo el guardado rápido, recrea el trabajo allí, y luego arroja el guardado rápido si la entrada se realiza con éxito.
    $ git stash branch [rama]

Bisect

El comando bisect hace una búsqueda binaria a través de su historial de commits para ayudarte a identificar lo más rápidamente posible qué commit introdujo un problema. Para comenzar la busqueda del commit que introdujo el error, primero hay que ejecuta git bisect start para para comenzar la busqueda, y luego usar git bisect bad para decirle al sistema que el “commit” actual está roto. Entonces, debes decir a bisect cuándo fue el último estado bueno conocido, usando git bisect good [good_commit]:

$ git bisect start
$ git bisect bad [bad_commit] # Por ejemplo el commit HEAD
$ git bisect good [good_commit]

A continuación git calcula el commit que se encuentra en la mitad entre el commit bad y el good, para que se pueda comprobar si en ese commit se encuentra el error que se busca. Si el error esta presente en el commit hay que introducir git bisect bad o git bisect good en caso de no estar presente el error. Este proceso se realizara hasta encontrar el primer commit en donde esta presente el error. Cuando haya terminado, se debe ejecutar git bisect reset para reiniciar el HEAD a donde estaba antes de comenzar, o terminará en un estado raro:

$ git bisect reset

Nota: Con un script que retornare 0 si el proyecto está bien u otro número si el proyecto está mal, se puede automatizar completamente git bisect. En primer lugar, se indica el alcance de la bisectriz, proporcionando los “commits” malos y buenos. Se puede hacer enumerándolos con el comando bisect start, listando primero el “commit” malo conocido y segundo el “commit” bueno conocido:

$ git bisect start [bad_commit] [good_commit]
$ git bisect run test-error.sh

Esto ejecuta automáticamente test-error.sh en cada “commit” de “check-out” hasta que Git encuentre el primer “commit” roto. También se puede ejecutar algo como make o make tests o lo que sea que ejecute pruebas automatizadas.

Blame

Con git blame se muestra qué commit fue el último en modificar cada línea de cualquier archivo y por quién.

$ git blame [archivo]

Ademas, con la opcion -L se puede limitar la salida con una linea inicial y una final:

$ git blame -L [linea_inicial],[linea_final] [archivo]

El primer campo que muestra la salida es el SHA-1 parcial del “commit” que modificó esa línea. Los siguientes dos campos son valores extraídos del “commit” - el nombre del autor y la fecha del commit - así se puede ver de manera sencilla quién modificó esa línea y cuándo. Tras estos viene el número de línea y el contenido del archivo.

Reflog

Una de las cosas que Git hace en segundo plano, mientras estás trabajando, es mantener un “reflog” - un log de a dónde se apuntan las referencias del HEAD y la rama en los últimos meses.

$ git reflog

# Ejemplo de salida
734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd HEAD@{2}: commit: added some blame and merge stuff
1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
95df984 HEAD@{4}: commit: # This is a combination of two commits.
1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD

Cada vez que el HEAD de la rama es actualizada por cualquier razón, Git guarda esa información en este historial temporal. Y es así como se puede especificar commits antiguos con esta información. Si se quiere ver el quinto valor anterior a tu HEAD en el repositorio, se puede usar la referencia @{n} que se ve en la salida de reflog:

$ git show HEAD@{5}

También se puede utilizar esta sintaxis para ver dónde se encontraba una rama dada una cierta cantidad de tiempo. Por ejemplo, para ver dónde se encontraba la rama master ayer, se puede utilizar

$ git show master@{yesterday}

Esto muestra a dónde apuntaba tu rama el día de ayer. Esta técnica solo funciona para información que permanece en tu reflog, por lo que no se puede utilizar para ver commits que son anteriores a los que aparecen en él.

Nota: Es importante notar que la información de reflog es estríctamente local, es un log de lo que se ha hecho en el repositorio local. Las referencias no serán las mismas en otra copia del repositorio; y justo después de que se ha inicializado el repositorio, se tendrá un reflog vacío, dado que no ha ocurrido ninguna actividad todavía en el mismo. Utilizar git show HEAD@{2.months.ago} funcionará solo si se clonó el proyecto hace al menos dos meses - si se clonó hace cinco minutos, no se obtendrán resultados.

Caso de uso

Se ha realizado un git reset --hard HEAD~3 y se han pedido algunos commits que no querías perder. Con git reflog se puede observar cual es la referencia previa del HEAD a dicho reset para volver a ese punto utilizando git reset --hard HEAD@{[id_deseado]}, así se volvería al estado anterior al primer git reset.

Guiás

Cambiar direcciones URL remotas de SSH a HTTPS

  1. Abre la Terminal.
  2. Cambiar el directorio de trabajo actual en tu proyecto local.
  3. Enumerar tus remotos existentes a fin de obtener el nombre de los remotos que deseas cambiar.
git remote -v
  1. Cambiar tu URL remota de SSH a HTTPS con el comando git remote set-url.
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
  1. Verificar que la URL remota ha cambiado.
git remote -v
# Verify new remote URL
> origin  https://github.com/USERNAME/REPOSITORY.git (fetch)
> origin  https://github.com/USERNAME/REPOSITORY.git (push)

La próxima vez que ejecutes git, git pull o git push en el repositorio remoto, se te pedirá el nombre de usuario y la contraseña de GitHub.

  1. Si tienes habilitada la autenticación de dos factores, debes crear un token de acceso personal para usar en lugar de tu contraseña de GitHub.
  2. Puedes utilizar un ayudante de credenciales para que Git recuerde tu nombre de usuario y contraseña cada vez que se comunique con GitHub.

Cambiar direcciones URL remotas de HTTPS a SSH

  1. Abre la Terminal.
  2. Cambiar el directorio de trabajo actual en tu proyecto local.
  3. Enumerar tus remotos existentes a fin de obtener el nombre de los remotos que deseas cambiar.
$ git remote -v
> origin  https://github.com/USERNAME/REPOSITORY.git (fetch)
> origin  https://github.com/USERNAME/REPOSITORY.git (push)
  1. Cambiar tu URL remota de HTTPS a SSH con el comando git remote set-url.
$ git remote set-url origin [email protected]:USERNAME/REPOSITORY.git
  1. Verificar que la URL remota ha cambiado.
$ git remote -v
# Verify new remote URL
> origin  [email protected]:USERNAME/REPOSITORY.git (fetch)
> origin  [email protected]:USERNAME/REPOSITORY.git (push)

Generar una llave GPG

  1. Descarga e instala las herramientas de la línea de comando GPG para tu sistema operativo. Generalmente recomendamos instalar la versión más reciente para tu sistema operativo.
  2. Abre la Terminal.
  3. Genera un par de la llave GPG. Ya que existen varias versiones de GPG, puede que necesites consultar la página man relevante para encontrar el comando adecuado para la generación de llaves. Tu llave debe utilizar RSA.
  • Si estás usando una versión 2.1.17 o superior, copia el siguiente texto para generar un par de la llave GPG.
    $ gpg --full-generate-key
  • Si no estás usando la versión 2.1.17 ni una superior, el comando gpg --full-generate-key no funciona. Copia el siguiente texto y continúa con el paso 6.
    $ gpg --default-new-key-algo rsa4096 --gen-key
  1. En el prompt, especifica la clase de llave que quieres, o presiona Enter para aceptar el RSA y DSA predeterminado.
  2. Ingresa el tamaño de la llave que deseas. Tu llave debe ser de al menos 4096 bits.
  3. Ingresa el periodo de validez que deberá tener la llave. Presiona Enter para especificar la selección predeterminada, indicando que la llave no expira.
  4. Verifica que tus selecciones sean correctas.
  5. Ingresa tu información de ID de usuario.
  1. Escribe una contraseña segura.
  2. Utiliza el comando gpg --list-secret-keys --keyid-format LONG para enumerar las llaves GPG para las cuales tienes tanto una llave pública como privada. Se requiere una llave privada para registrar confirmaciones o etiquetas.
$ gpg --list-secret-keys --keyid-format LONG

Nota: Algunas instalaciones GPG en Linux pueden requerir que uses gpg2 --list-keys --keyid-format LONG para visualizar una lista de tus llaves existentes en su lugar. En este caso también deberás configurar Git para que use gpg2 by running git config --global gpg.program gpg2. 11. De la lista de llaves GPG, copia la ID de la llave GPG que quieres utilizar. En este ejemplo, el ID de la llave GPG es 3AA5C34371567BD2:

$ gpg --list-secret-keys --keyid-format LONG
/Users/hubot/.gnupg/secring.gpg
/------------------------------------
sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid                          Hubot
ssb   4096R/42B317FD4BA89E7A 2016-03-10
  1. Pega el siguiente texto sustituyendo el ID de la llave GPG que deseas usar. En este ejemplo, el ID de la llave GPG es 3AA5C34371567BD2:
$ gpg --armor --export 3AA5C34371567BD2
# Prints the GPG key ID, in ASCII armor format
  1. Copia tu llave GPG, comenzando con -----BEGIN PGP PUBLIC KEY BLOCK----- y terminando con -----END PGP PUBLIC KEY BLOCK-----.
  2. Agrega la llave GPG a tu cuenta de GitHub.

Informarle a Git acerca de tu llave GPG

Si estás usando una llave GPG que coincide con la identidad de la persona que confirma el cambio y con tu dirección de correo electrónico verificada asociada a tu GitHub cuenta, puedes comenzar a firmar confirmaciones y firmar etiquetas. Si tienes múltiples llaves GPG, le debes decir a Git cuál utilizar.

  1. Abre la Terminal.

  2. Utiliza el comando gpg --list-secret-keys --keyid-format LONG para enumerar las llaves GPG para las cuales tienes tanto una llave pública como privada. Se requiere una llave privada para registrar confirmaciones o etiquetas.

$ gpg --list-secret-keys --keyid-format LONG

Nota: Algunas instalaciones GPG en Linux pueden requerir que uses gpg2 --list-keys --keyid-format LONG para visualizar una lista de tus llaves existentes en su lugar. En este caso también deberás configurar Git para que use gpg2 by running git config --global gpg.program gpg2.

  1. De la lista de llaves GPG, copia la ID de la llave GPG que quieres utilizar. En este ejemplo, el ID de la llave GPG es 3AA5C34371567BD2:
  $ gpg --list-secret-keys --keyid-format LONG
  /Users/hubot/.gnupg/secring.gpg
  ------------------------------------
  sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
  uid                          Hubot
  ssb   4096R/42B317FD4BA89E7A 2016-03-10
  1. Para configurar tu llave de firma GPG en Git, pega el siguiente texto en sustitución de la ID de la llave GPG que quieras utilizar. En este ejemplo, el ID de la llave GPG es 3AA5C34371567BD2:
$ git config --global user.signingkey 3AA5C34371567BD2
  1. Para agregar tu llave GPG a tu perfil bash, pega el texto que aparece a continuación:
    $ test -r ~/.bash_profile && echo 'export GPG_TTY=$(tty)' >> ~/.bash_profile
    $ echo 'export GPG_TTY=$(tty)' >> ~/.profile
**Nota:** Si no tienes .bash_profile, este comando agrega tu llave GPG al .profile.

Asociar un correo electrónico con tu llave GPG

Tu llave GPG debe estar asociada con un correo electrónico verificado de GitHub que coincida con tu identidad de persona que confirma el cambio.

  1. Abre la Terminal.
  2. Utiliza el comando gpg --list-secret-keys --keyid-format LONG para enumerar las llaves GPG para las cuales tienes tanto una llave pública como privada. Se requiere una llave privada para registrar confirmaciones o etiquetas.
$ gpg --list-secret-keys --keyid-format LONG
**Nota:** Algunas instalaciones GPG en Linux pueden requerir que uses gpg2 --list-keys --keyid-format LONG para visualizar una lista de tus llaves existentes en su lugar. En este caso también deberás configurar Git para que use gpg2 by running git config --global gpg.program gpg2.
  1. De la lista de llaves GPG, copia la ID de la llave GPG que quieres utilizar. En este ejemplo, el ID de la llave GPG es 3AA5C34371567BD2:
  $ gpg --list-secret-keys --keyid-format LONG
  /Users/hubot/.gnupg/secring.gpg
  ------------------------------------
  sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
  uid                          Hubot
  ssb   4096R/42B317FD4BA89E7A 2016-03-10
  1. Escribe gpg --edit-key GPG key ID, sustituyendo la ID de la llave GPG que te gustaría usar. En el siguiente ejemplo, el ID de llave GPG es 3AA5C34371567BD2:
$ gpg --edit-key 3AA5C34371567BD2
  1. Escribe gpg> adduid para agregar los detalles de ID de usuario.
$ gpg> adduid
  1. Sigue las indicaciones para suminsitrar tu nombre real, dirección de correo electrónica o cualquier comentario. Puedes modificar tus entradas al elegir N, C o E. Para mantener tu dirección de correo electrónico como privada, utiliza tus direcciones de tipo no-reply proporcionadas por GitHub. Para obtener más información, consulta "Configurar la confirmación de tu dirección de correo electrónico."
  Real Name: Octocat
    Email address: [email protected]
    Comment: GitHub key
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
  1. Escribe O para guardar tus selecciones.
  2. Escribe la contraseña de tu llave.
  3. Escribe gpg --armor --export GPG key ID, sustituyendo la ID de la llave GPG que te gustaría usar. En el siguiente ejemplo, el ID de llave GPG es 3AA5C34371567BD2:
$ gpg --armor --export 3AA5C34371567BD2
# Prints the GPG key, in ASCII armor format
  1. Carga la llave GPG al agregarla a tu cuenta GitHub.

Eliminar clave GPG

  1. Para eliminar una clave GPG de GitHub, ve a https://github.com/settings/keys y en claves GPG, selecciona la que quieras y elimínala.
  2. Eliminar la clave GPG de la configuracion de Git:
git config --global --unset user.signingkey
  1. Desactivar globalmente la clave de firma GPG para los commits
git config --global commit.gpgsign false

Añadir co-autores en commints en la linea de comandos

  1. Recopila el nombre y dirección de correo electrónico de cada co-autor. Si alguien elige mantener su dirección de correo electrónico como privada, debes utilizar su correo de no-reply proporcionado por GitHub para proteger su privacidad.
  2. En la siguiente línea del mensaje de confirmación, escriba Co-authored-by: name <[email protected]> con información específica para cada coautor. Después de la información del co-autor, añada una comilla de cierre. Si está añadiendo varios co-autores, dé a cada co-autor su propia línea y Co-authored-by:. Consulta Creating a commit with multiple authors
$ git commit -m "Refactor usability tests.
>
>
Co-authored-by: name <[email protected]>
Co-authored-by: another-name <[email protected]>"

Migrar repositorio

Si quieres moverte de un servidor Git a otro como GitHub, GitLab, Bitbucket o cualquier otro servidor Git. Utiliza la opción --mirror para clonar tu repositorio Git con todo el historial, ramas y etiquetas en un directorio temporal:

$ git clone --mirror <OLD_REPO_URL> temp-dir

Vaya a ese directorio y cambie la antigua URL del repositorio por la nueva:

$ cd temp-dir
$ git remote set-url origin <NEW_REPO_URL>

Ejecuta git push con la opción --mirror para mover tu repositorio Git con todo el historial, ramas y etiquetas a otro repositorio:

$ git push --mirror origin

El directorio temporal puede ser borrado ahora y el repositorio puede ser clonado desde el nuevo servidor remoto usando el comando git clone normal:

$ cd ..
$ rm -rf temp-dir
$ git clone <NEW_REPO_URL>

Revisión de Pull Requests en local

Revisión desde la rama origen del Pull Requests

De esta forma se clona la rama origen desde la que se crea el Pull Requests. Este metodo permite visualizar en el Pull Requests los posibles commits añadidos a la rama mientras el Pull Requests permanece abierto. Pasos a seguir:

  1. Actualizar/Descargar rama de origen del Pull Requests a local:
git pull
  1. Posicionarse en la rama del origen del Pull Requests:
git checkout -b <BRANCH_NAME> origin/<BRANCH_NAME>

En este punto se realizaría la revisión y si se añadieran nuevos commits realizar un git push para que se reflejen los nuevos commits en el Pull Requests.

Nota: Tener cuidado de tener la rama siempre actualizada por si hay mas personas realizando cambios en la rama del Pull Requests.

Revisión desde una nueva rama a partir de Pull Requests

De esta forma se creara una rama nueva en local a partir de la rama origen del Pull Requests. Los commit creados en la nueva rama no se mostraran en el Pull Requests, para añadir los posibles nuevos commits se tendra que crear un nuevo Pull Requests desde la nueva rama creada en local. Pasos a seguir:

  1. Busca el número de la ID de la solicitud de extracción inactiva. Esta es la secuencia de dígitos inmediatamente después del título de la solicitud de extracción.

  2. En la terminal

    git fetch origin pull/<ID>/head:<BRANCH_NAME>
    • ID: ID (solo digitos) de la pull request.
    • BRANCH_NAME: Nombre a la nueva rama en local

En este punto, se puede hacer lo que se dese con esta rama. Se puedes ejecutar algunas pruebas locales o fusionar otras ramas en esta rama. Cuando se este listo, se puede subir la rama nueva:

git push origin <BRANCH_NAME>

Nota: Mas informacion aquí.

Estrategias de Merge (Git Merge vs Rebase vs Squash)

Squash

Imagina que tu rama de características tiene un gran número de commits, por ejemplo, 100s commits. En lugar de fusionar todas los commits individualmente desde la rama feature_branch a la rama master, hay una opción para sumar todas las confirmaciones en una sola. Esto se llama "squash commit" porque "aplasta" todos los commits individuales en un gran cambio. En lo que respecta a la historia de la rama master, la historia de la rama de feature_branch se perdería.

Podemos utilizar el siguiente comando para fusionar los commits de una rama con la rama master.

$ git merge --squash feature_branch

El diagrama muestra que tenemos 3 commits en la rama maestra. La rama feature que hemos creado tiene dos commits F1 y F2. Ahora tenemos que combinar todos los commits de la rama feature y de la rama master, como si sólo hubiera un commit en la rama master.

    Master - HEAD
           ^
           |
C1---C2---C3    F1 + F2
      \
      F1---F2
            ^
            |
      feature_branch

Después de la fusión de squash, la rama master se verá como se muestra a continuación. Una vez que la fusión de squash es exitosa, podemos eliminar la rama de feature_branch.

           Master - HEAD
                  ^
                  |
C1---C2---C3---F1 + F2

Referencias

  • Pro Git. Scott Chacon, Ben Straub. 2nd Edition (2014). Apress.

Licencia

Todo el contenido está bajo la licencia Creative Commons Attribution Non Commercial Share Alike 3.0 license.