Difference between revisions of "Git, lo Básico"
(38 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
==Contexto== | ==Contexto== | ||
===Definiciones=== | |||
<dl> | |||
<dt>Repositorio, ''repository'' o repo</dt> | |||
<dd>Es el repositorio local, sobre el cual se trabaja.</dd> | |||
<dt>''Remote'' o remoto</dt> | |||
<dd>Es el repositorio remoto en el cual se suben cambios y otros usuarios pueden obtener.</dd> | |||
</dl> | |||
===Los Estados de los archivos=== | ===Los Estados de los archivos=== | ||
Line 20: | Line 28: | ||
==Instalar Git== | ==Instalar Git== | ||
=== | ===Obtener Git=== | ||
Git se puede instalar desde diferentes fuentes, [http://git-scm.com/downloads esta] es la oficial. Desde ahí se pueden descargar los comandos y clientes gráficos. | Git se puede instalar desde diferentes fuentes, [http://git-scm.com/downloads esta] es la oficial. Desde ahí se pueden descargar los comandos y clientes gráficos. | ||
Line 33: | Line 41: | ||
* <code>~/.gitconfig</code> contiene configuración para el usuario actual | * <code>~/.gitconfig</code> contiene configuración para el usuario actual | ||
* <code>.git/config</code> contiene configuración para el repositorio en el que se está trabajando actualmente | * <code>.git/config</code> contiene configuración para el repositorio en el que se está trabajando actualmente | ||
A continuación algunas configuraciones básicas pero existen más configuraciones no documentadas aquí: | |||
====Configuración Personal==== | ====Configuración Personal==== | ||
Esta información se usa a la hora de hacer ''commits''. | Esta información se usa a la hora de hacer ''commits''. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git config --global user.name "John Flat" # Setea el nombre del usuario | git config --global user.name "John Flat" # Setea el nombre del usuario | ||
git config --global user.email john.flat@empresa.com # Setea el mail del usuario | git config --global user.email john.flat@empresa.com # Setea el mail del usuario | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 43: | Line 53: | ||
====Configuración Ambiente de Trabajo==== | ====Configuración Ambiente de Trabajo==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git config --global core.editor emacs # Setea el editor por defecto | git config --global core.editor emacs # Setea el editor por defecto | ||
git config --global merge.tool vimdiff # Setea el visualizador de diferencias | git config --global merge.tool vimdiff # Setea el visualizador de diferencias | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 49: | Line 59: | ||
====Revisar configuraciones==== | ====Revisar configuraciones==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git config --list # Lista todas las configuraciones, pueden repetirse si se repiten en varios archivos de configuración | git config --list # Lista todas las configuraciones, pueden repetirse si se repiten en varios archivos de configuración | ||
git config {key} # Muestra el valor de una variable en específico | git config {key} # Muestra el valor de una variable en específico | ||
git config user.name # Muestra el valor del nombre de usuario guardado en la configuración | git config user.name # Muestra el valor del nombre de usuario guardado en la configuración | ||
</syntaxhighlight> | |||
====Configurar autocompletación en Terminal==== | |||
Necesario para SO Macintosh (Ubuntu viene por defecto). | |||
1. Agregar el archivo '''git-completion.bash''' al home. | |||
'''Descargar:'''<br> | |||
Opción 1 (github.com): https://github.com/git/git/blob/master/contrib/completion/git-completion.bash <br> | |||
Opción 2 (Wiki): [[Media:Git-completion.bash.zip | Git-completion.bash version 2.0 ]] | |||
2. Modificar el archivo '''.profile''' por terminal. | |||
<syntaxhighlight lang="bash"> | |||
vim ~/.profile | |||
</syntaxhighlight> | |||
3. Persionamos la letra '''i''' y agregamos '''source ~/git-completion.bash''' al principio del archivo. | |||
<syntaxhighlight lang="bash"> | |||
source ~/git-completion.bash | |||
# MacPorts Installer addition on 2014-03-26_at_11:37:57: adding an appropriate PATH variable for use with MacPorts. | |||
export PATH=/opt/local/bin:/opt/local/sbin:$PATH | |||
# Finished adapting your PATH environment variable for use with MacPorts. | |||
</syntaxhighlight> | |||
4. Por último presionamos la tecla '''esc''', a continuación ''':''' y '''wq''' para guardar el archivo. | |||
===Instalar en un servidor=== | |||
Instalar en un servidor es sencillo conceptualmente. Hay que permitir acceso a un directorio con un proyecto Git. El directorio es igual al que hay en un proyecto localmente. También hay que definir para cada usuario si puede hacer ''pull'' y ''push''. Para esto, una forma sencilla de hacerlo es usando acceso SSH (aunque existen otra formas, ver ''[http://gitolite.com/3-server-usage/git-server.html setting up your own git server]''), de esta forma también se le puede dar permiso al usuario de lectura y escritura. | |||
Para crear el repositorio hay que ingresar al servidor remoto y ejecutar algunos comandos. Lo siguiente es un ejemplo, la ubicación y el nombre del proyecto pueden cambiar. Por convención se usa el nombre de la carpeta del proyecto con ''.git''. El comando <code>--bare</code>, al inicializar el proyecto, indica que se crea sin la estructura de directorio de trabajo, este directorio queda con archivos como los que quedan adentro de la carpeta .git de un repositorio de trabajo local. | |||
<syntaxhighlight lang="bash"> | |||
cd /opt/git # Se navega a la ubicación donde se quiere dejar el repositorio | |||
mkdir project.git # Se crea una carpeta donde va a quedar el repositorio | |||
cd project.git # Se ingresa a la carpeta del proyecto | |||
git --bare init # Se inicializa el proyecto | |||
</syntaxhighlight> | |||
Lo mismo del código anterior se puede lograr así: | |||
<syntaxhighlight lang="bash"> | |||
cd /opt/git # Se navega a la ubicación donde se quiere dejar el repositorio | |||
git --bare init project.git # Se crea el directorio del proyecto y se inicializa | |||
</syntaxhighlight> | |||
Para obtener el repositorio el usuario puede hacer: | |||
<syntaxhighlight lang="bash"> | |||
git clone usuario@servidor.com:/directorio/donde/esta/el/proyecto | |||
# Alternativa | |||
# Se recomienda usar la opción --recursive para hacer que se obtengan los submódulos necesarios | |||
# Para aprender más https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.okuz4kial | |||
git clone --recursive usuario@servidor.com:/directorio/donde/esta/el/proyecto | |||
</syntaxhighlight> | |||
Si se desea hacer usuarios que solo puedan interactuar con Git en este servidor, es buena idea dejar que solo usen un ''shell'' desarrollado para este propósito. Esto significa que no pueden moverse a través de los directorios, crear archivos, ver archivos y más. Para esto, hay que editar el archivo <code>/etc/passwd</code> (en Ubuntu por ejemplo), en el usuario que solo va a usar Git, pasar de esto: | |||
<syntaxhighlight lang="bash"> | |||
nombreUsuario:x:1000:1000::/home/nombreUsuario:/bin/sh | |||
</syntaxhighlight> | |||
a esto: | |||
<syntaxhighlight lang="bash"> | |||
nombreUsuario:x:1000:1000::/home/nombreUsuario:/usr/bin/git-shell | |||
</syntaxhighlight> | |||
Para más información de cómo interactuar con el servidor remoto, ver [[Git, Branching]], la sección de ''remotes''. | |||
== Instalar gitk == | |||
===Mac OS X 10.10=== | |||
<syntaxhighlight lang="bash"> | |||
sudo port install git k | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 73: | Line 153: | ||
===Empezar un proyecto con Git=== | ===Empezar un proyecto con Git=== | ||
Se crea un directorio nuevo, se navega hacia él y se inicializa Git. | Se crea un directorio nuevo, se navega hacia él y se inicializa Git. Para las siguientes opciones se asume que se empieza en el mismo directorio en donde se quiere crear el repositorio. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# Opción 1 – larga | |||
mkdir nuevoProyecto # Crear nuevo directorio | mkdir nuevoProyecto # Crear nuevo directorio | ||
cd nuevoProyecto # Navegar a directorio | cd nuevoProyecto # Navegar a directorio | ||
git init # Inicializar Git | git init # Inicializar Git | ||
touch x # Crea un archivo "x" vacío | |||
git add x # Se pasa "x" al staging area, es decir, se prepara para el commit | # Opción 2 – corta | ||
git init nuevoProyecto | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="bash"> | |||
# A estas alturas el directorio está listo, se puede usar | |||
# A continuación un ejemplo muy básico que crea un archivo y lo agrega al repositorio | |||
touch x # Crea un archivo "x" vacío | |||
git add x # Se pasa "x" al staging area, es decir, se prepara para el commit | |||
git commit -m 'Commit inicial, solo un archivo en blanco' # Se hace el commit y queda guardado localmente | git commit -m 'Commit inicial, solo un archivo en blanco' # Se hace el commit y queda guardado localmente | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 86: | Line 176: | ||
Se navega al directorio donde está el proyecto exitente y se inicializa Git. | Se navega al directorio donde está el proyecto exitente y se inicializa Git. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd proyectoExistente # Se navega al proyecto existente | cd proyectoExistente # Se navega al proyecto existente | ||
git init # Inicializar Git | git init # Inicializar Git | ||
git add archivoExistente # Se pasa "archivoExistente" al staging area, es decir, se prepara para el commit | git add archivoExistente # Se pasa "archivoExistente" al staging area, es decir, se prepara para el commit | ||
git commit -m 'Commit inicial, se agrega archivo existente' # Se hace el commit y queda guardado localmente | git commit -m 'Commit inicial, se agrega archivo existente' # Se hace el commit y queda guardado localmente | ||
Line 95: | Line 185: | ||
Se obtiene una copia del repositorio y se guarda en una carpeta con el nombre del repositorio. | Se obtiene una copia del repositorio y se guarda en una carpeta con el nombre del repositorio. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git clone [url] # Forma genérica | git clone [url] # Forma genérica | ||
git clone /path/to/repository # Obtener copia localmente | git clone /path/to/repository # Obtener copia localmente | ||
git clone username@host:/path/to/repository # Obtener copia remotamente | git clone username@host:/path/to/repository # Obtener copia remotamente | ||
# Alternativa | |||
# Se recomienda usar la opción --recursive para hacer que se obtengan los submódulos necesarios | |||
# Para aprender más https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.okuz4kial | |||
git clone --recursive [url] # Forma genérica | |||
git clone --recursive /path/to/repository # Obtener copia localmente | |||
git clone --recursive username@host:/path/to/repository # Obtener copia remotamente | |||
</syntaxhighlight> | </syntaxhighlight> | ||
==Ignorar archivos== | ==Ignorar archivos== | ||
===.gitignore=== | |||
Git puede ignorar algunos archivos, esto se hace manualmente editando (creando) el archivo ''.gitignore''. A continuación un ejemplo de este archivo: | Git puede ignorar algunos archivos, esto se hace manualmente editando (creando) el archivo ''.gitignore''. A continuación un ejemplo de este archivo: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 116: | Line 215: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | ===Asumir que algún archivo no ha cambiado=== | ||
El siguiente comando hace que Git no tome en cuenta los cambios del archivo en cuestión. | |||
<syntaxhighlight lang="bash"> | |||
git update-index --assume-unchanged archivoParaNoTomarEnCuenta | |||
</syntaxhighlight> | |||
Para deshacer esto: | |||
<syntaxhighlight lang="bash"> | |||
git update-index --no-assume-unchanged archivoParaNoTomarEnCuenta | |||
</syntaxhighlight> | |||
==Git Local== | |||
===Proceso de guardado de archivos (commit)=== | |||
Para hacer un ''commit'' hay que hacer los siguientes pasos: | |||
# Agregar (o modificar) archivos (por ejemplo usando un editor de texto) | |||
# Avisarle a git que tiene que llevar a cabo los cambios, por ejemplo agregando un archivo (<code>git add archivoNuevo</code>) | |||
# Hacer el ''commit'', git commit -m <nowiki>'texto del commit'</nowiki> | |||
Se puede hacer el commit así: | |||
<syntaxhighlight lang="bash"> | |||
touch archivoNuevo # Se agrega un nuevo archivo al directorio de trabajo | |||
git add archivoNuevo # Se agrega el archivo a Git | |||
git commit # Se realiza el commit | |||
# No se le entrega mensaje, con lo que se abre el editor de texto configurado | |||
</syntaxhighlight> | |||
O | |||
<syntaxhighlight lang="bash"> | |||
touch archivoNuevo # Se agrega un nuevo archivo al directorio de trabajo | |||
git add archivoNuevo # Se agrega el archivo a Git | |||
git commit -m 'texto del commit' # Se realiza el commit | |||
# Se escribe el mensaje directamente y no se abre un editor de texto | |||
</syntaxhighlight> | |||
Siempre es necesario incluir un mensaje en el ''commit'' ya que esto permite revisar el historial de lo que se haya hecho antes. De esta forma se puede tener una imagen bastante clara de la evolución del proyecto. | |||
===Hacer un ''commit'' viendo las diferencias en los archivos=== | |||
Lo siguiente muestra el editor de texto para agregar un mensaje, en los comentarios muestra los archivos modificados (comportamiento por defecto) y adicionalmente muestra las diferencias en los archivos (<code>-v</code>). | |||
<syntaxhighlight lang="bash"> | |||
git commit -v | |||
</syntaxhighlight> | |||
===Track nuevos archivos=== | ===Track nuevos archivos=== | ||
Se dice que un archivo está siendo ''tracked'' cuando Git lo toma en cuenta. Para esto se ejecuta lo siguiente: | Se dice que un archivo está siendo ''tracked'' cuando Git lo toma en cuenta. Para esto se ejecuta lo siguiente: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
touch archivoNuevo # Se crea nuevo archivo vacío | touch archivoNuevo # Se crea nuevo archivo vacío | ||
git add archivoNuevo # Se hace que Git lo agregue | git add archivoNuevo # Se hace que Git lo agregue | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 129: | Line 268: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
echo nuevaLinea >> archivoYaEnGit # Se le agrega la línea nuevaLinea a un archivo que ya estaba en Git | echo nuevaLinea >> archivoYaEnGit # Se le agrega la línea nuevaLinea a un archivo que ya estaba en Git | ||
git add archivoYaEnGit # Se pasa archivo al staging area | git add archivoYaEnGit # Se pasa archivo al staging area | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 139: | Line 278: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
mv archivoViejoNombre archivoNuevoNombre # Se mueve el archivo usando un comando del sistema operativo | mv archivoViejoNombre archivoNuevoNombre # Se mueve el archivo usando un comando del sistema operativo | ||
git rm archivoViejoNombre # Se borra de Git el del nombre viejo | git rm archivoViejoNombre # Se borra de Git el del nombre viejo | ||
git add archivoNuevoNombre # Se agrega el del nombre nuevo | git add archivoNuevoNombre # Se agrega el del nombre nuevo | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 149: | Line 288: | ||
Esta operación reemplaza los siguientes comandos: | Esta operación reemplaza los siguientes comandos: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
rm archivoABorrar # Borra el archivo usando un comando del sistema operativo | rm archivoABorrar # Borra el archivo usando un comando del sistema operativo | ||
git rm archivoABorrar # Le avisa a Git que el archivo va a ser eliminado en el próximo commit | git rm archivoABorrar # Le avisa a Git que el archivo va a ser eliminado en el próximo commit | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 166: | Line 305: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git checkout -- archivoAResetear | git checkout -- archivoAResetear | ||
</syntaxhighlight> | |||
===Revertir cambios en el directorio de trabajo=== | |||
<syntaxhighlight lang="bash"> | |||
git reset --hard # Deshace cambios del staging area y del directorio de trabajo | |||
git clean -f -d # Quita archivos no ''trackeados'' | |||
git clean -f -x -d # CUIDADO! Quita archivos no ''trackeados'' PERO ADEMÁS quita archivos ignorados (.gitignore) | |||
</syntaxhighlight> | |||
Fuente: [http://stackoverflow.com/questions/1090309/git-undo-all-working-dir-changes-including-new-files stackoverflow] | |||
===Revertir cambios de ''commit''=== | |||
Suponiendo que el Git se encuentra en el siguiente estado: | |||
<syntaxhighlight lang="text"> | |||
(F) | |||
A-B-C | |||
↑ | |||
master | |||
A, B y C son commits. F es el estado del directorio de trabajo. C es el último commit. | |||
</syntaxhighlight> | |||
Se pueden hacer algunos comandos para deshacer ''commits'': | |||
<ul> | |||
<li> Borrar el ''commit'' definitivamente: | |||
<syntaxhighlight lang="bash"> | |||
git reset --hard HEAD~1 | |||
</syntaxhighlight> | |||
El estado de Git queda así: | |||
<syntaxhighlight lang="text"> | |||
(F) | |||
A-B | |||
↑ | |||
master | |||
</syntaxhighlight> | |||
</li> | |||
<li> Borrar el ''commit'' pero mantener los cambios hechos en archivos hasta antes del ''commit'': | |||
<syntaxhighlight lang="bash"> | |||
git reset HEAD~1 | |||
</syntaxhighlight> | |||
El estado de Git queda así: | |||
<syntaxhighlight lang="text"> | |||
(F) | |||
A-B-C | |||
↑ | |||
master | |||
</syntaxhighlight> | |||
</li> | |||
<li> Borrar el ''commit'' pero mantener los cambios hechos en archivos hasta antes del ''commit'' '''y''' manteniendo el index (''staging area''): | |||
<syntaxhighlight lang="bash"> | |||
git reset --soft HEAD~1 | |||
</syntaxhighlight> | |||
El estado de Git queda así: | |||
<syntaxhighlight lang="text"> | |||
(F) | |||
A-B-C | |||
↑ | |||
master | |||
</syntaxhighlight> | |||
</li> | |||
</ul> | |||
Fuente: [http://stackoverflow.com/a/6866485 stackoverflow] | |||
Nota: Para resucitar un commit muerto ver la nota en la fuente. | |||
===Hacer cambios al útlimo ''commit'' con ''--amend''=== | |||
Si hay algún archivo que debería haber hecho parte del ''commit'' anterior, se puede agregar con <code>git commit --amend</code>. Un ejemplo de cómo funciona esto: | |||
<syntaxhighlight lang="bash"> | |||
git commit -m 'primer commit' # Commit inicial | |||
touch nuevoArchivo # Se agrega nuevo archivo al directorio | |||
git add nuevoArchivo # Se le avisa a Git que hay un nuevo archivo que trackear | |||
git commit --amend # Se actualiza el último commit, debería abrir el editor de texto por defecto | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 179: | Line 391: | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git status | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 199: | Line 411: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git status | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 234: | Line 446: | ||
En ''archivoA'' se agregaron dos líneas con el mismo contenido, el nombre del archivo. En ''archivoB'' se agregó una línea con el nombre del archivo. | En ''archivoA'' se agregaron dos líneas con el mismo contenido, el nombre del archivo. En ''archivoB'' se agregó una línea con el nombre del archivo. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
git diff | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 271: | Line 483: | ||
;--author | ;--author | ||
:Se le proporciona a Git el autor para la búsqueda | :Se le proporciona a Git el autor para la búsqueda | ||
;--stat | |||
:Se muestran los archivos modificados. | |||
==Git Remoto== | |||
Para poder colaborar en un proyecto, se necesitan servidores remotos, ''remotes''. | |||
===Crear nuevo proyecto a partir de un remote=== | |||
El siguiente comando crea una carpeta con el proyecto obtenido desde una fuente externa, crea la carpeta .git y obtiene los archivos del proyecto. | |||
<syntaxhighlight lang="bash"> | |||
git clone username@host:/path/to/repository # Obtener copia remotamente | |||
# Alternativa | |||
# Se recomienda usar la opción --recursive para hacer que se obtengan los submódulos necesarios | |||
# Para aprender más https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.okuz4kial | |||
git clone --recursive username@host:/path/to/repository # Obtener copia remotamente | |||
</syntaxhighlight> | |||
===Agregar remote=== | |||
El siguiente comando agrega un ''remote'' al proyecto Git actual, esto solo asocia un ''remote'' al proyecto pero no obtiene los archivos. nombreReferencia es un nombre arbitratio que se le da al remote para referenciarlo. | |||
<syntaxhighlight lang="bash"> | |||
git remote add nombreReferencia username@host:/path/to/nombreRepositorio | |||
</syntaxhighlight> | |||
===Obtener archivos de remote=== | |||
El siguiente comando obtiene los archivos desde un ''remote'' ya agregado '''pero''' no los deja en el directorio de trabajo, quedan "escondidos" en la base de datos de Git. | |||
<syntaxhighlight lang="bash"> | |||
git fetch nombreReferencia | |||
</syntaxhighlight> | |||
===Mezclar lo obtenido en el directorio actual=== | |||
Este comando mezcla la rama de nombreReferencia al directorio actual ([http://stackoverflow.com/questions/3419658/understanding-git-fetch-then-merge más info en stackoverflow]). | |||
<syntaxhighlight lang="bash"> | |||
git merge nombreReferencia/rama | |||
</syntaxhighlight> | |||
===Obtener y Mezclar (merge) archivos de remote=== | |||
Se obtienen los archivos y luego se mezclan con lo que hay en el directorio de trabajo. | |||
<syntaxhighlight lang="bash"> | |||
git pull nombreReferencia HEAD # Si no especifico HEAD me pide una versión | |||
</syntaxhighlight> | |||
===Subir cambios a remote=== | |||
Se suben los cambios al ''remote'' origin en la branch (rama) master. | |||
<syntaxhighlight lang="bash"> | |||
git push origin master | |||
</syntaxhighlight> | |||
===Listar remotes=== | |||
<div class="toccolours mw-collapsible mw-collapsed"> | |||
Listar remotos | |||
<div class="mw-collapsible-content"> | |||
<syntaxhighlight lang="bash"> | |||
git diff | |||
</syntaxhighlight> | |||
Resultado: | |||
<syntaxhighlight lang="bash"> | |||
origin | |||
ticgit | |||
</syntaxhighlight> | |||
</div></div> | |||
<div class="toccolours mw-collapsible mw-collapsed"> | |||
Listar remotos con URLs | |||
<div class="mw-collapsible-content"> | |||
<syntaxhighlight lang="bash"> | |||
git remote -v | |||
</syntaxhighlight> | |||
Resultado: | |||
<syntaxhighlight lang="bash"> | |||
origin /gitExample2/../gitExample (fetch) | |||
origin /gitExample2/../gitExample (push) | |||
ticgit git://github.com/schacon/ticgit.git (fetch) | |||
ticgit git://github.com/schacon/ticgit.git (push) | |||
</syntaxhighlight> | |||
</div></div> | |||
===Obtener información de un remote=== | |||
Con este comando se obtiene la información del ''remote'' y de las ''branches'' (ramas) que se están ''tracking''. | |||
<syntaxhighlight lang="bash"> | |||
git remote show ticgit | |||
</syntaxhighlight> | |||
===Renombre remote=== | |||
<syntaxhighlight lang="bash"> | |||
git remote rename nombreViejo nombreNuevo | |||
</syntaxhighlight> | |||
===Quitar remote=== | |||
<syntaxhighlight lang="bash"> | |||
git remote rm remoteName | |||
</syntaxhighlight> | |||
===Cambiar el remote=== | |||
Para cambiar el remote de un proyecto lo primero es situarse en el directorio con git del proyecto y ejecutar: | |||
<syntaxhighlight lang="bash"> | |||
git remote -v | |||
# Con este comando se verifica el remote que se esta utilizando y entrega como resultado algo así: | |||
# usuario@oficina1.cl:/git/proyecto (fetch) -> hace referencia al remote desde donde se sacan los archivos (pull) | |||
# usuario@oficina1.cl:/git/proyecto (push) -> hace referencia al remote hacia donde se envían los archivos (push) | |||
</syntaxhighlight> | |||
Luego para cambiar el remote se ejecuta: | |||
<syntaxhighlight lang="bash"> | |||
git remote set-url origin usuario@nuevoRemote:/git/proyecto | |||
# Para comprobar que el cambio se ha hecho de manera exitosa se puede volver a ejecutar git remote -v y/o se puede hacer un pull/push | |||
</syntaxhighlight> | |||
==Otras páginas utiles adentro del Wiki== | |||
* [[Git, Branching]], ''branching'' es una forma de llevar el desarrollo por diferentes caminos sin que se pisen entre ellos. | |||
* [[Git, Tagging]], el ''tagging'' sirve para referenciar diferentes ''commits'' en el tiempo. | |||
* [[Git, Stashing]], el ''stashing'' sirve para limpiar las modificaciones actuales en el espacio de trabajo y guardarlas temporalmente fuera de vista. Se pueden recuperar luego. | |||
==Links útiles== | |||
* [http://git-scm.com/book/en/Git-Basics-Tips-and-Tricks#Auto-Completion Hacer que Git autocomplete] | |||
* [http://git-scm.com/book/en/Git-Basics-Tips-and-Tricks#Git-Aliases Hacer alias para comandos] | |||
==Más información== | ==Más información== | ||
* [https://na1.salesforce.com/help/pdfs/en/salesforce_git_developer_cheatsheet.pdf Git Cheat Sheet] | * [https://na1.salesforce.com/help/pdfs/en/salesforce_git_developer_cheatsheet.pdf Git Cheat Sheet] | ||
* [http://ndpsoftware.com/git-cheatsheet.html Git Cheatsheet • NDP Software] | |||
* [http://git-scm.com/book/en/ Libro Oficial] | * [http://git-scm.com/book/en/ Libro Oficial] | ||
* [http://rogerdudler.github.io/git-guide/ git - the simple guide] | * [http://rogerdudler.github.io/git-guide/ git - the simple guide] | ||
[[Category:Git]] | [[Category:Git]] |
Latest revision as of 18:06, 22 July 2018
Contexto
Definiciones
- Repositorio, repository o repo
- Es el repositorio local, sobre el cual se trabaja.
- Remote o remoto
- Es el repositorio remoto en el cual se suben cambios y otros usuarios pueden obtener.
Los Estados de los archivos
Los archivos adentro de una carpeta que usa Git pueden estar tracked o no, esto significa que están asociados al control de versión o no. Los archivos tracked pueden estar en uno de tres estados:
- Commited ("Comprometido")
- El archivos ya quedó guardado en la base de datos local.
- Modified (Modificado)
- El archivo se ha modificado pero no se ha commited (comprometido) aún.
- Staged ("En Escenario")
- Se ha marcado el archivo para agregarlo al próximo commit.
Un flujo común de Git
- Se obtiene el proyecto desde un directorio de git
- Se modifican archivos
- Se preparan para el commit, se hacen staged
- Se hace el commit
Instalar Git
Obtener Git
Git se puede instalar desde diferentes fuentes, esta es la oficial. Desde ahí se pueden descargar los comandos y clientes gráficos.
Además hay más programas en Internet que se pueden usar para trabajar con Git. Por ejemplo NetBeans lo soporta.
Nota: Es posible que Git ya esté instalado en el sistema. Si se reinstala podría causar algún conflicto. Revisar si está instalado, si la función instalada es suficiente no hacer nada, sino buscar la forma de instalar la versión deseada.
Configuración
Antes de empezar a usar Git se configuran algunas variables para el uso de un usuario. Estas variables se usan para guardar en los repositorios información de quien hace el commit y configurar cosas como el editor a usar. Quedan almacenadas en uno de tres directorios, ordenados por relevancia siendo más relevante el último:
/etc/gitconfig
contiene configuración para todos los usuarios del sistema en todos los repositorios~/.gitconfig
contiene configuración para el usuario actual.git/config
contiene configuración para el repositorio en el que se está trabajando actualmente
A continuación algunas configuraciones básicas pero existen más configuraciones no documentadas aquí:
Configuración Personal
Esta información se usa a la hora de hacer commits.
git config --global user.name "John Flat" # Setea el nombre del usuario
git config --global user.email john.flat@empresa.com # Setea el mail del usuario
Configuración Ambiente de Trabajo
git config --global core.editor emacs # Setea el editor por defecto
git config --global merge.tool vimdiff # Setea el visualizador de diferencias
Revisar configuraciones
git config --list # Lista todas las configuraciones, pueden repetirse si se repiten en varios archivos de configuración
git config {key} # Muestra el valor de una variable en específico
git config user.name # Muestra el valor del nombre de usuario guardado en la configuración
Configurar autocompletación en Terminal
Necesario para SO Macintosh (Ubuntu viene por defecto).
1. Agregar el archivo git-completion.bash al home.
Descargar:
Opción 1 (github.com): https://github.com/git/git/blob/master/contrib/completion/git-completion.bash
Opción 2 (Wiki): Git-completion.bash version 2.0
2. Modificar el archivo .profile por terminal.
vim ~/.profile
3. Persionamos la letra i y agregamos source ~/git-completion.bash al principio del archivo.
source ~/git-completion.bash
# MacPorts Installer addition on 2014-03-26_at_11:37:57: adding an appropriate PATH variable for use with MacPorts.
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
# Finished adapting your PATH environment variable for use with MacPorts.
4. Por último presionamos la tecla esc, a continuación : y wq para guardar el archivo.
Instalar en un servidor
Instalar en un servidor es sencillo conceptualmente. Hay que permitir acceso a un directorio con un proyecto Git. El directorio es igual al que hay en un proyecto localmente. También hay que definir para cada usuario si puede hacer pull y push. Para esto, una forma sencilla de hacerlo es usando acceso SSH (aunque existen otra formas, ver setting up your own git server), de esta forma también se le puede dar permiso al usuario de lectura y escritura.
Para crear el repositorio hay que ingresar al servidor remoto y ejecutar algunos comandos. Lo siguiente es un ejemplo, la ubicación y el nombre del proyecto pueden cambiar. Por convención se usa el nombre de la carpeta del proyecto con .git. El comando --bare
, al inicializar el proyecto, indica que se crea sin la estructura de directorio de trabajo, este directorio queda con archivos como los que quedan adentro de la carpeta .git de un repositorio de trabajo local.
cd /opt/git # Se navega a la ubicación donde se quiere dejar el repositorio
mkdir project.git # Se crea una carpeta donde va a quedar el repositorio
cd project.git # Se ingresa a la carpeta del proyecto
git --bare init # Se inicializa el proyecto
Lo mismo del código anterior se puede lograr así:
cd /opt/git # Se navega a la ubicación donde se quiere dejar el repositorio
git --bare init project.git # Se crea el directorio del proyecto y se inicializa
Para obtener el repositorio el usuario puede hacer:
git clone usuario@servidor.com:/directorio/donde/esta/el/proyecto
# Alternativa
# Se recomienda usar la opción --recursive para hacer que se obtengan los submódulos necesarios
# Para aprender más https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.okuz4kial
git clone --recursive usuario@servidor.com:/directorio/donde/esta/el/proyecto
Si se desea hacer usuarios que solo puedan interactuar con Git en este servidor, es buena idea dejar que solo usen un shell desarrollado para este propósito. Esto significa que no pueden moverse a través de los directorios, crear archivos, ver archivos y más. Para esto, hay que editar el archivo /etc/passwd
(en Ubuntu por ejemplo), en el usuario que solo va a usar Git, pasar de esto:
nombreUsuario:x:1000:1000::/home/nombreUsuario:/bin/sh
a esto:
nombreUsuario:x:1000:1000::/home/nombreUsuario:/usr/bin/git-shell
Para más información de cómo interactuar con el servidor remoto, ver Git, Branching, la sección de remotes.
Instalar gitk
Mac OS X 10.10
sudo port install git k
Comandos de Ayuda
Tres formas de obtener ayuda sobre un <verb> (verbo), es decir una acción de Git:
git help <verb>
git <verb> --help
man git-<verb>
Ejemplo de ayuda
git help config
git config --help
man git-config
Crear Repositorios
Formas de hacer que un proyecto tenga manejo de versiones usando Git. Todas las formas incluyen un directorio .git que guarda la información de versiones.
Empezar un proyecto con Git
Se crea un directorio nuevo, se navega hacia él y se inicializa Git. Para las siguientes opciones se asume que se empieza en el mismo directorio en donde se quiere crear el repositorio.
# Opción 1 – larga
mkdir nuevoProyecto # Crear nuevo directorio
cd nuevoProyecto # Navegar a directorio
git init # Inicializar Git
# Opción 2 – corta
git init nuevoProyecto
# A estas alturas el directorio está listo, se puede usar
# A continuación un ejemplo muy básico que crea un archivo y lo agrega al repositorio
touch x # Crea un archivo "x" vacío
git add x # Se pasa "x" al staging area, es decir, se prepara para el commit
git commit -m 'Commit inicial, solo un archivo en blanco' # Se hace el commit y queda guardado localmente
Agregar Git a un proyecto existente
Se navega al directorio donde está el proyecto exitente y se inicializa Git.
cd proyectoExistente # Se navega al proyecto existente
git init # Inicializar Git
git add archivoExistente # Se pasa "archivoExistente" al staging area, es decir, se prepara para el commit
git commit -m 'Commit inicial, se agrega archivo existente' # Se hace el commit y queda guardado localmente
Obtener un proyecto desde una fuente existente
Se obtiene una copia del repositorio y se guarda en una carpeta con el nombre del repositorio.
git clone [url] # Forma genérica
git clone /path/to/repository # Obtener copia localmente
git clone username@host:/path/to/repository # Obtener copia remotamente
# Alternativa
# Se recomienda usar la opción --recursive para hacer que se obtengan los submódulos necesarios
# Para aprender más https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.okuz4kial
git clone --recursive [url] # Forma genérica
git clone --recursive /path/to/repository # Obtener copia localmente
git clone --recursive username@host:/path/to/repository # Obtener copia remotamente
Ignorar archivos
.gitignore
Git puede ignorar algunos archivos, esto se hace manualmente editando (creando) el archivo .gitignore. A continuación un ejemplo de este archivo:
# Esto es un comentario que empieza con '#'
# Omitir todos los archivos que terminan con .log
*.log
# Pero track super.log usando la negación
!super.log
# Ignorar la carpeta LOG, si existe una carpeta LOG adentro de otra carpeta no se va a ignorar
/LOG
# Ignorar todos los archivos en la carpeta error
error/
# Ignorar los archivos .txt adentro de la carpeta media
media/*.txt
Asumir que algún archivo no ha cambiado
El siguiente comando hace que Git no tome en cuenta los cambios del archivo en cuestión.
git update-index --assume-unchanged archivoParaNoTomarEnCuenta
Para deshacer esto:
git update-index --no-assume-unchanged archivoParaNoTomarEnCuenta
Git Local
Proceso de guardado de archivos (commit)
Para hacer un commit hay que hacer los siguientes pasos:
- Agregar (o modificar) archivos (por ejemplo usando un editor de texto)
- Avisarle a git que tiene que llevar a cabo los cambios, por ejemplo agregando un archivo (
git add archivoNuevo
) - Hacer el commit, git commit -m 'texto del commit'
Se puede hacer el commit así:
touch archivoNuevo # Se agrega un nuevo archivo al directorio de trabajo
git add archivoNuevo # Se agrega el archivo a Git
git commit # Se realiza el commit
# No se le entrega mensaje, con lo que se abre el editor de texto configurado
O
touch archivoNuevo # Se agrega un nuevo archivo al directorio de trabajo
git add archivoNuevo # Se agrega el archivo a Git
git commit -m 'texto del commit' # Se realiza el commit
# Se escribe el mensaje directamente y no se abre un editor de texto
Siempre es necesario incluir un mensaje en el commit ya que esto permite revisar el historial de lo que se haya hecho antes. De esta forma se puede tener una imagen bastante clara de la evolución del proyecto.
Hacer un commit viendo las diferencias en los archivos
Lo siguiente muestra el editor de texto para agregar un mensaje, en los comentarios muestra los archivos modificados (comportamiento por defecto) y adicionalmente muestra las diferencias en los archivos (-v
).
git commit -v
Track nuevos archivos
Se dice que un archivo está siendo tracked cuando Git lo toma en cuenta. Para esto se ejecuta lo siguiente:
touch archivoNuevo # Se crea nuevo archivo vacío
git add archivoNuevo # Se hace que Git lo agregue
Agregar archivos al staging area
Los archivos modificados no pasan directamente al siguiente commit, hay que pasarlos al staging area antes. El comando es el mismo que para agregar archivos nuevos.
echo nuevaLinea >> archivoYaEnGit # Se le agrega la línea nuevaLinea a un archivo que ya estaba en Git
git add archivoYaEnGit # Se pasa archivo al staging area
Mover (o renombrar) Archivos
git mv archivoViejoNombre archivoNuevoNombre # También se puede mover adentro de un directorio
Esta operación reemplaza los siguientes comandos:
mv archivoViejoNombre archivoNuevoNombre # Se mueve el archivo usando un comando del sistema operativo
git rm archivoViejoNombre # Se borra de Git el del nombre viejo
git add archivoNuevoNombre # Se agrega el del nombre nuevo
Borrar archivos
git rm archivoABorrar
Esta operación reemplaza los siguientes comandos:
rm archivoABorrar # Borra el archivo usando un comando del sistema operativo
git rm archivoABorrar # Le avisa a Git que el archivo va a ser eliminado en el próximo commit
Borrar archivos en el staging area
git rm --cached archivoNoStaging
Quitar archivos del staging area
git reset HEAD archivoNoStaging
Revertir cambios de archivo
git checkout -- archivoAResetear
Revertir cambios en el directorio de trabajo
git reset --hard # Deshace cambios del staging area y del directorio de trabajo
git clean -f -d # Quita archivos no ''trackeados''
git clean -f -x -d # CUIDADO! Quita archivos no ''trackeados'' PERO ADEMÁS quita archivos ignorados (.gitignore)
Fuente: stackoverflow
Revertir cambios de commit
Suponiendo que el Git se encuentra en el siguiente estado:
(F)
A-B-C
↑
master
A, B y C son commits. F es el estado del directorio de trabajo. C es el último commit.
Se pueden hacer algunos comandos para deshacer commits:
- Borrar el commit definitivamente:
git reset --hard HEAD~1
El estado de Git queda así:
(F) A-B ↑ master
- Borrar el commit pero mantener los cambios hechos en archivos hasta antes del commit:
git reset HEAD~1
El estado de Git queda así:
(F) A-B-C ↑ master
- Borrar el commit pero mantener los cambios hechos en archivos hasta antes del commit y manteniendo el index (staging area):
git reset --soft HEAD~1
El estado de Git queda así:
(F) A-B-C ↑ master
Fuente: stackoverflow
Nota: Para resucitar un commit muerto ver la nota en la fuente.
Hacer cambios al útlimo commit con --amend
Si hay algún archivo que debería haber hecho parte del commit anterior, se puede agregar con git commit --amend
. Un ejemplo de cómo funciona esto:
git commit -m 'primer commit' # Commit inicial
touch nuevoArchivo # Se agrega nuevo archivo al directorio
git add nuevoArchivo # Se le avisa a Git que hay un nuevo archivo que trackear
git commit --amend # Se actualiza el último commit, debería abrir el editor de texto por defecto
Estado de Archivos
Para saber el estado de los archivos existen dos comandos posibles: git status
y git diff
.
git status
Muestra información del estado de los archivos que han cambiado. Puede mostrar archivos untracked, staged y modified. No muestra información de archivos que no han cambiado desde el último commit.
git status: ejemplo sin cambios
git status
Resultado:
# On branch master
nothing to commit (working directory clean)
git status: ejemplo de diferentes estados
En el siguiente ejemplo, archivoA y archivoB ya están siendo tracked y ya hicieron parte del commit anterior; ambos fueron modificados. archivoA no se agregó al staging area por lo que no va a hacer parte del commit. archivoB se agregó al staging area y se va a guardar en el próximo commit.
archivoC es un archivo nuevo que se va a guardar en el próximo commit y archivoD es un archivo nuevo no tracked por Git.
git status
Resultado:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: archivoB
# new file: archivoC
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: archivoA
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# archivoD
git diff
git diff
se usa para ver las diferencias que han tenido los archivos y no solo saber si han cambiado o no. git diff
por si sólo muestra las diferencias en archivos que no están en el staging area. Para mostrar los cambios en los archivos que están en el staging area hay que usar el commando con la opción --staged: git diff --staged
(para versiones anteriores a 1.6.1 cambiar --staged por --cached).
git diff: ejemplo
En archivoA se agregaron dos líneas con el mismo contenido, el nombre del archivo. En archivoB se agregó una línea con el nombre del archivo.
git diff
Resultado:
diff --git a/archivoA b/archivoA
index 7898192..c065858 100644
--- a/archivoA
+++ b/archivoA
@@ -1 +1,2 @@
-a
+archivoA
+archivoA
diff --git a/archivoB b/archivoB
index 6178079..df239cf 100644
--- a/archivoB
+++ b/archivoB
@@ -1 +1 @@
-b
+archivoB
Historial
Para ver el historial se usa el comando git log
. Se puede usar con varios parámetros para obtener un output más preciso. Para obtener más información ver este link o usar git help log
.
Algunos parámetros:
- -(n)
- (n) es la cantidad de commits a mostrar (ej:
git log -3
) - --since, --after
- Se le entrega un valor de fecha y muestra commits solamente a partir de cierta fecha (ej:
git log --since=2.weeks
) - --until, --before
- Se le entrega un valor de fecha y muestra commits solamente desde cierta fecha (ej:
git log --until=2.weeks
) - --author
- Se le proporciona a Git el autor para la búsqueda
- --stat
- Se muestran los archivos modificados.
Git Remoto
Para poder colaborar en un proyecto, se necesitan servidores remotos, remotes.
Crear nuevo proyecto a partir de un remote
El siguiente comando crea una carpeta con el proyecto obtenido desde una fuente externa, crea la carpeta .git y obtiene los archivos del proyecto.
git clone username@host:/path/to/repository # Obtener copia remotamente
# Alternativa
# Se recomienda usar la opción --recursive para hacer que se obtengan los submódulos necesarios
# Para aprender más https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.okuz4kial
git clone --recursive username@host:/path/to/repository # Obtener copia remotamente
Agregar remote
El siguiente comando agrega un remote al proyecto Git actual, esto solo asocia un remote al proyecto pero no obtiene los archivos. nombreReferencia es un nombre arbitratio que se le da al remote para referenciarlo.
git remote add nombreReferencia username@host:/path/to/nombreRepositorio
Obtener archivos de remote
El siguiente comando obtiene los archivos desde un remote ya agregado pero no los deja en el directorio de trabajo, quedan "escondidos" en la base de datos de Git.
git fetch nombreReferencia
Mezclar lo obtenido en el directorio actual
Este comando mezcla la rama de nombreReferencia al directorio actual (más info en stackoverflow).
git merge nombreReferencia/rama
Obtener y Mezclar (merge) archivos de remote
Se obtienen los archivos y luego se mezclan con lo que hay en el directorio de trabajo.
git pull nombreReferencia HEAD # Si no especifico HEAD me pide una versión
Subir cambios a remote
Se suben los cambios al remote origin en la branch (rama) master.
git push origin master
Listar remotes
Listar remotos
git diff
Resultado:
origin
ticgit
Listar remotos con URLs
git remote -v
Resultado:
origin /gitExample2/../gitExample (fetch)
origin /gitExample2/../gitExample (push)
ticgit git://github.com/schacon/ticgit.git (fetch)
ticgit git://github.com/schacon/ticgit.git (push)
Obtener información de un remote
Con este comando se obtiene la información del remote y de las branches (ramas) que se están tracking.
git remote show ticgit
Renombre remote
git remote rename nombreViejo nombreNuevo
Quitar remote
git remote rm remoteName
Cambiar el remote
Para cambiar el remote de un proyecto lo primero es situarse en el directorio con git del proyecto y ejecutar:
git remote -v
# Con este comando se verifica el remote que se esta utilizando y entrega como resultado algo así:
# usuario@oficina1.cl:/git/proyecto (fetch) -> hace referencia al remote desde donde se sacan los archivos (pull)
# usuario@oficina1.cl:/git/proyecto (push) -> hace referencia al remote hacia donde se envían los archivos (push)
Luego para cambiar el remote se ejecuta:
git remote set-url origin usuario@nuevoRemote:/git/proyecto
# Para comprobar que el cambio se ha hecho de manera exitosa se puede volver a ejecutar git remote -v y/o se puede hacer un pull/push
Otras páginas utiles adentro del Wiki
- Git, Branching, branching es una forma de llevar el desarrollo por diferentes caminos sin que se pisen entre ellos.
- Git, Tagging, el tagging sirve para referenciar diferentes commits en el tiempo.
- Git, Stashing, el stashing sirve para limpiar las modificaciones actuales en el espacio de trabajo y guardarlas temporalmente fuera de vista. Se pueden recuperar luego.