git
En esta guia, encontraras las opciones más comunes de uso de git. Tiene el proposito de ser sólo una referencia rápida sin mayor explicación que la mínima necesaria de cada comando.
Configuraciones iniciales de git
Setting up name and e-mail address
git config --global user.name "Your Name"
git config --global user.email "your_email@whatever.com"
Installation Options line endings
git config --global core.autocrlf input
git config --global core.safecrlf true
Create a repository
git init
Add the page to the repository
git add hello.html
git commit -m "First Commit
Check the status of the repository
git status
Adding changes
git add hello.html
git status
git add a.html
git add b.html
git commit -m "Changes for a and b"
git add c.html
git commit -m "Unrelated change to c"
git add
Note: The current directory (‘.’) will be our file to add. This is the most convenient way to add all the changes to the files of the current directory and its folders. But since it adds everything, it is a good idea to check the status prior to doing an add ., to make sure you don’t add any file that should not be added.
Committing changes
git commit
If you omit the -m flag from the command line, git will pop you into the editor of your choice from the list (in order of priority):
History
git log
One line history
git log --pretty=oneline
Controlling the display of entries
git log --pretty=oneline --max-count=2
git log --pretty=oneline --since='5 minutes ago'
git log --pretty=oneline --until='5 minutes ago'
git log --pretty=oneline --author=<your name>
git log --pretty=oneline --all
Getting fancy
git log --all --pretty=format:"%h %cd %s (%an)" --since='7 days ago'
The ultimate format of the log
git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
--pretty="..." defines the output format.
%h is the abbreviated hash of the commit
%d commit decorations (e.g. branch heads or tags)
%ad is the commit date
%s is the comment
%an is the name of the author
--graph tells git to display the commit tree in the form of an ASCII graph layout
--date=short keeps the date format short and nice
Other tools
gitk
Common aliases
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global alias.hist 'log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short'
git config --global alias.type 'cat-file -t'
git config --global alias.dump 'cat-file -p'
Add the following to the .gitconfig file in your $HOME directory.
[alias]
co = checkout
ci = commit
st = status
br = branch
hist = log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
type = cat-file -t
dump = cat-file -p
Type and Dump
git cat-file
Command aliases (optional)
If your shell supports aliases, or shortcuts, you can add aliases on this level, too. I use:
alias gs='git status '
alias ga='git add '
alias gb='git branch '
alias gc='git commit'
alias gd='git diff'
alias go='git checkout '
alias gk='gitk --all&'
alias gx='gitx --all'
alias got='git '
alias get='git '
Getting hashes for the previous versions
git hist
git checkout
cat hello.html
########################################################################
Git tiene tres principales estados donde los archivos pueden residir:
- Commited.- El directorio de git o repositorio almacena los metadatos y objetos de la DBs
para tu proyecto. Esta es la parte más importante de git y la cual se copia cuando clonas
un repositorio de otra computadora. - Modified.- Se ha cambiado el archivo pero no se ha hecho commit en la DBs.
- Staged.-Significa que el archivo se ha marcado como modificado en la versión actual para
ser enviado en la siguiente "commit snapshot"
El flujo básico de trabajo de git es similar a:
- Modificas los archivos en tu directorio local.
- Pones en stage los archivos, agregando los snapshots de ellos en la "staging area".
- Haces "commit", lo cual toma los archivos que existen en la "staging area" y almacena
los snapshots permanentemente en tu directorio de git
Si una versión particular de un archivo esta en el directorio de git, se considera
Commited. Si está moficado pero ha sido agregado al "staging area", está "Staged". Y si
este fue cambiado desde la ulyima vez que se le hizo un "checked out" pero no está
"Staged", entonces está "Modified"
Los Archivos de configuración pueden estar en tres lugares distintos.
- /etc/gitconfig : Contiene valores para todos los usuarios en el sistema y todos sus
repositorios. Para escribir/leer se debe usar
git config --system
- ~/.gitconfig Especifico por usuario, para leer/escribir en el se debe usar
git config --global
- En el directorio de git existe el archivo .git/config o en cualquier repositorio.
Cualquier nivel sobreescribe los valores en el nivel previo
Obtener la ayuda
$ git help
$ git --help
$ man git-
Ver la configuración actual
Todos los valores
$ git config --list
Un valor especifico
$ git config user.name
Configurar tu identidad
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
Configurar tu editor
$ git config --global core.editor emacs
por default usa vi or vim que son los del sistema.
Configurar tu herramienta de diff
$ git config --global merge.tool vimdiff
git acepta:
- kdiff3
- tkdiff
- meld
- xxdiff
- emerge
- vimdiff
- gvimdiff
- ecmerge
- opendiff
Color
$ git config --global color.ui true
Git Basics
Obtener un repositorio de git
Inicializar un repositorio en un directorio existente: [master] (Ver más abajo clonar)
$ git init
esto crea un subdirectorio llamado .git y la estructura del repositorio. Pero ningun
archivo del proyecto está siendo rastreado. (directorio vacio)
Si se requiere iniciar controlando archivos existentes (contrario a usar un directorio
vacio) probablemente se quiera iniciar a rastrear ciertos archivos y hacer un
commit inicial. Para ello se puede usar los siguientes commandos.
$ git add *.c
$ git add README
$ git commit -m 'initial project version'
Clonar un repositorio existente
$ git clone [url]
ejemplo:
$ git clone git://github.com/schacon/grit.git
Si se requiere clonar un repositorio en un directorio con un nombre diferente se puede
hacer con:
$ git clone git://github.com/schacon/grit.git mygrit
NOTA.- Esto es util cuando se está trabajando con diferentes versiones o con parches de
un sistema.
Git puede usar diferentes protocolos de trasnferencia, como por ejemplo:
- git://
- http(s)://
- user@server:/path.git
Checar el estatus de los archivos
$ git status
Seguir nuevos archivos
$ git add [FILE]
Una vez agregado el seguimiento a un nuevo archivo este aparece como "staged"
Seguir archivos modificados
$ git add [MODIFIED_FILE]
Una vez realizado esto el archivo queda "staged" y está listo para el siguiente commit
Si se olvidó, realizar un cambio es necesario modificar el archivo y volver a ejecutar
$ git add [MODIFIED_FILE]
Ignorar archivos
En el directorio del repositorio maestro existe el archivo .gitignore, el contenido del
mismo es similar a:
*.[oa] # ignora archivos que finalizan en .o [objeto] o .a [archivo]
*~ # ignora todos los archivos que terminan con una tilde (~)
*.pyc # ignora los archivos que finalizan en .pyc
*.zip
*.swp
*.diff
*.log
*.tmp
*.pid
# a comment - this is ignored
*.a # no .a files
!lib.a # but do track lib.a, even though you're ignoring .a files above
/TODO # only ignore the root TODO file, not subdir/TODO
build/ # ignore all files in the build/ directory
doc/*.txt # ignore doc/notes.txt, but not doc/server/arch.txt
.gitignore # ignora el archivo .gitignore
La primer linea ignora archivos que finalizan en .o [objeto] o .a [archivo], la segunda
línea ignora todos los archivos que terminan con una tilde (~).
NOTA.- Es buena idea configurarlo de inicio, para evitar accidentalmente anexar archivos en
el commit.
La reglas para los patrones en este archivo son:
- Lineas en blanco o que inicien con # se ignoran.
- Los "glob" estandar funcionan (*, [abc], ? o [0-9])
- Se pueden finalizar patrones con una diagonal (/) para especificar un directorio.
- Se puede negar un patron si se inicia con un signo de exclamación (!)
Ver los cambios "staged" o "unstaged"
Para ver los cambios que aún no han sido "staged"
$ git diff
Para ver que es lo que está "staged" y será enviado en el siguiente commit
$ git diff --cached
Enviar ("commiting") los cambios
Después de poner los cambios en "staged",
Nota.- si se desea cambiar el editor se debe usar git config --global core.editor [command]
$ git diff --check
$ git commit
El mensaje que aparece es una linea en blanco y el mensaje por default es para recordar que
se está cambiando, para un mejor recordatorio se puede anexar los cambios del diff se
puede usar:
$ git diff --check
$ git commit -v
Si se usa la opcion -m se puede anexar la descripción en la linea de comandos.
$ git diff --check
$ git commit -m "Story 182: Fix benchmarks for speed"
El comando $ git diff --check es para verificar los espacios
Saltandose la Area "Staging"
$ git commit -a -m 'added new benchmarks'
Esto sólo funciona para los archivos que ya estan en seguimiento.
Borrando archivos
Borrar archivos del Area "Staging"
$ rm [file]
$ git status
Después para borrarlo del Area "Staging"
$ git rm [file]
$ git status
La siguiente vez que se hace el commit el archivo desaparecerá y ya no tendrá seguimiento.
Si se requiere forzar el borrado, ya que se modificó y se anexo al indice
$ rm [file]
$ git rm -f [file]
$ git status
NOTA.- Si se requiere trabajar con el archivo pero borrarlo del Area "Staging"
$ git rm --cached [file]
NOTA.- es posible usar patrones, directorios o archivos al comando git rm, ejemplo:
$ git rm log/\*.log
La diagonal invertida antes del *. es necesaria porque git tiene su propia expansión de
nombres de archivos adicionales a la expansión del shell.
Para borrar los archivos que terminan con ~ se debe usar
$ git rm \*~
Moviendo archivos (35/285)
$ git mv file_from file_to
Esto es similar a hacer:
$ mv file_from file_to
$ git rm file_from
$ git add file_to
Viendo la historia de los commits
Para ver todos los logs
$ git log
Para desplegar la información del log pero con la salida del diff despues de cada entrada.
$ git log -p -2
Para abreviar las estadísticas
$ git log --stat
Para cambiar la salida del log existen otras opciones
$ git log --pretty=oneline
las opciones que se pueden usar son:
- format:
- full
- fuller
- medium
- oneline
- raw
- short
La más interesante es format, ya que permite especificar que datos desplegar, ejemplo:
$ git log --pretty=format:"%h - %an, %ar : %s"
Los formatos que puede aceptar son:
Option |
Description of Output |
%H |
Commit hash |
%h |
Abbreviated commit hash |
%T |
Tree hash |
%t |
Abbreviated tree hash |
%P |
Parent hashes |
%p |
Abbreviated parent hashes |
%an |
Author name |
%ae |
Author e-mail |
%ad |
Author date (format respects the --date= option) |
%ar |
Author date, relative |
%cn |
Committer name |
%ce |
Committer email |
%cd |
Committer date |
%cr |
Committer date, relative |
%s |
Subject |
Otro comando util para usar ya sea con oneline o format es --graph
$ git log --pretty=oneline --graph
$ git log --pretty=format:"%h %s" --graph
Estas son algunas de las opciones que acepta la opción de logs.
Option |
Description |
-p |
Show the patch introduced with each commit. |
--stat |
Show statistics for files modified in each commit. |
--shortstat |
Display only the changed/insertions/deletions line from the --stat command. |
--name-only |
Show the list of files modified after the commit information. |
--name-status |
Show the list of files affected with added/modified/deleted information as well. |
--abbrev-commit |
Show only the first few characters of the SHA-1 checksum instead of all 40. |
--relative-date |
Display the date in a relative format (for example, “2 weeks ago”) instead of using the full date format. |
--graph |
Display an ASCII graph of the branch and merge history beside the log output. |
--pretty |
Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own format). |
Para limitar la salida del log, adicional a la opcion de -<n>
$ git log --since=2.weeks
Se puede especificar la fecha de distintas formas como por ejemplo (“2016-01-15”) o una fecha relativa como “2 years 1 day 3 minutes ago”. La opción --author puede filtrar por un autor en especifico y con la opcion --grep busca una cadena en los mensajes de commits Para ambas opciones se puede usar la opción --all-match tambien se le puede pasar un [path] para poder hacer un filtro sobre cierto directorio o nombre de archivo y se separa con doble --.
Las opciones más comunes de filtros son:
Option |
Description |
-(n) |
Show only the last n commits |
--since, --after |
Limit the commits to those made after the specified date. |
--until, --before |
Limit the commits to those made before the specified date. |
--author |
Only show commits in which the author entry matches the specified string. |
--committer |
Only show commits in which the committer entry matches the specified string. |
Ejemplo:
$ git log --pretty="%h - %s" --author=knel --since="2014-07-10" --before="2014-07-12" \ --no-merges -- aaddons/
Deshaciendo cosas
Cambiando el último commit
$ git commit --amend
Por ejemplo, si se omitio un archivo en el 'initial commit' se puede hacer lo siguiente:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
Si se cambiaron dos archivos pero se agregaron usando un git add * y se quería hacer dos cambios en su lugar. Para sacar el archivo del staging area, se puede usar:
$ git reset HEAD [file]
Si se quiere descartar los cambios que se han realizado a un archivo en particular se puede usar:
$ git checkout -- benchmarks.rb
Trabajando con repositorios remotos
Para visualizar los servidores remotos que están configurados con git clone:
$ git remote
Se puede usar la opción -v para ver la URL ligada.
$ git remote -v
De todos los repositorios se puede hacer un pull pero unicamente de aquellos que usen ssh seran a los unicos a los que se les pueda hacer un push.
Agregar repositorios remotos
$ git remote add [shortname] [url]
Esto agrega un repositorio remoto con tal vez el mismo contenido del directorio, pero que puede estar desarrollando otra persona en una rama (branch) diferente. Por eso se usa el shortname, para identificarlo.
Trayendo y jalando de los repositorios remotos.
Por ejemplo, para hacer un pull toda la información que tiene un shortname, pero que no tienes en el repositorio se puede usar. Para despues hacer el merge de la información.
$ git fetch [shortname]
o $ git fetch [remote-name]
Con esto no se hacen los merges en automático, si se quiere hacer ambas operaciones se usa
$ git pull
Pushing a los repositorios remotos.
$ git push [remote-name] [branch-name]
Ejemplo:
$ git push origin master
Inspeccionar un repositorio remoto
$ git remote show [remote-name]
Remover y renombrar un repositorio remoto
$ git remote rename [shortnameorigin] [shortnamefinal]
$ git remote -v
Para borrar una referencia
$ git remote rm [shortname]
$ git remote -v
Etiquetado
Listar etiquetas
$ git tag
Buscar etiquetas
$ git tag -l 'v1.4.2.*'
Creando etiquetas
Etiquetas Anotadas
$ git tag -a v1.4 -m 'my version 1.4'
o
$ git tag -a v1.4
Para visualizarlas
$ git show v1.4
Firmar etiquetas con GPG, asumiendo que tengas una llave privada.
$ git tag -s v1.5 -m 'my signed 1.5 tag'
Etiquetas ligeras
$ git tag v1.4-lw
Verificar etiquetas, usa GPG y la clave publica
$ git tag -v v1.4.2.1
Etiquetas tardias.
Si se olvidó etiquetar algo se puede usar:
$ git tag -a v1.2 9fceb02
Compartir etiquetas.
por default no se exportan al repositorio
$ git push origin v1.5
Enviar muchas etiquetas al repositorio que no existan ahí.
$ git push origin --tags
Tips and Tricks
Autocompletar
cat /etc/bash_completion.d/git-prompt
Git Aliases
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.unstage 'reset HEAD --'
$ git config --global alias.visual "!gitk"
Branching
Visualizar las ramas.
$ git branch
$ git branch -v
$ git branch -a
Crear una nueva rama
$ git branch [name]
Cambiarse a una rama existente
$ git checkout [name]
Branching y Merging
Crear una rama y cambiarse al mismo tiempo.
$ git checkout -b iss53
Combinar
$ git merge [name]
Borrar las ramas.
NOTA.- Esto se realiza cuando el master y el hotfix apuntan al mismo punto, y ya no es necesario conservarlos.
$ git branch -d hotfix
O un borrado forzado
$ git branch -D hotfix
Merge básico
$ git checkout master
$ git merge iss53
Si existe un problema lo va a marcar y se puede visualizar con un git status. Se debe editar el archivo y donde se marca el conflicto se debe borrar, las marcas y dejar el código correcto. Posterior se ejecuta un git add [archivo]
Para borrar las ramas es importante ejecutar
$ git branch --merged
NOTA.- La lista presenta el nombre de cada rama seguido de un *, y si no se presenta el signo es una buena señal de que se puede borrar con git branch -d
Para ver aquellas ramas que no se les ha hecho el merged
$ git branch --no-merged
Ejemplo (64-69):
$ git checkout -b iss53
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
$ git checkout master
$ git checkout -b 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
$ git checkout master
$ git merge hotfix
$ git branch -d hotfix
$ git checkout iss53
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
$ git checkout master
$ git merge iss53
$ git status
$ git mergetool
$ git status
$ git commit
$ git branch -d iss53
$ git checkout develop
$ git branch aeco_point_of_sale_0.0
$ git checkout aeco_point_of_sale_0.0
$ git add .
$ git com -m "[NEW] AECO Point of sales" #$ git tag -a aeco_point_of_sale_v0.0.0 -m '[aeco_point_of_sale][0.0.0]'
$ git checkout develop
$ git merge --no-ff aeco_point_of_sale_0.0
#$ git tag -a v0.0.0 -m "aeco_point_of_sale" ###No se si antes o después se crea
$ git push origin develop:develop ###duda si se crea uno nuevo
$ git push origin --tags
Ramas remotas
Actualizar a lo que está en el server.
$ git fetch origin
Pushing
Si se tiene un branch local y se desea que otros trabajen con el.
$ git push [remote] [branch]
Ejemplo:
$ git push origin serverfix
o
$ git push origin serverfix:awesomebranch
Esto es útil si se quiere que la rama en el servidor tenga un nombre diferente
Ramas remotas
Para trabajar con una rama remota creando una rama local
$ git checkout -b serverfix origin/serverfix
Rastreo de ramas remotas
Es útil si sólo se desea hacer un git pull, en lugar de un checkout en especifico, cuando alguien hace un cambio y se desea obtener.
$ git checkout --track origin/serverfix
Para configurar una rama local con un nombre diferente a la remota.
$ git checkout -b sf origin/serverfix
Borrado de ramas remotas.
$ git push [remotename] :[branch]
ejemplo:
$ git push origin :serverfix
Rebasing (cambio de base) [81]
Se recomienda sólo hacerlo local.
$ git checkout experiment
$ git rebase master
$ git rebase --onto master server client
Servidores git
Protocolo Local (Permisos de archivos)
Clonar:
$ git clone /opt/git/project.git
o mejor:$ git clone file:///opt/git/project.git
Agregar un repositorio local a un projecto de git, como si fuera en red:
$ git remote add local_proj /opt/git/project.git
Protocolo SSH
Clonar:
$ git clone ssh://user@server:project.git
o (se asume se usa ssh) $ git clone user@server:project.git
Protocolo git (Puerto: 9418, Sin seguridad)
Protocolo HTTP/S
Configurar:
$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
Clonar:
$ git clone http://example.com/gitproject.git
Configurar Push usando WebDAV
https://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt
Poniendo git en el servidor
Crear un repositorio desnudo
$ git clone --bare my_project my_project.git
Poner el repositorio desnudo en el servidor.
$ scp -r my_project.git user@git.example.com:/opt/git
Clonar el repositorio
$ git clone user@git.example.com:/opt/git/my_project.git
Asignar permisos al servidor
$ ssh user@git.example.com
$ cd /opt/git/my_project.git
$ git init --bare --shared
Configuraciones pequeñas
- crear un usuario git en el servidor
- Solicitar a cada usuario que necesite acceso de escritura su llave publica de SSH
- Agregar cada llave al archivo ~/.ssh/authorized_keys del usuario git.
Otra solución puede ser usando un LDAP centralizado.
Generar la llave publica SSH
$ ssh-keygen
$ mail ~/.ssh/id_rsa.pub
Más información:
http://github.com/guides/providing-your-ssh-key
Configurando el servidor
$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh
$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git --bare init
Configuración inicial usando un cliente.
#on Johns computer
$ cd myproject
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@gitserver:/opt/git/project.git
$ git push origin master
Clonar el repositorio por otros usuarios.
$ git clone git@gitserver:/opt/git/project.git
$ vim README
$ git commit -am 'fix for the README file'
$ git push origin master
Restringir shell al usuario git
$ sudo vim /etc/passwd
cambiar
~ git:x:1000:1000::/home/git:/bin/sh
a
~ git:x:1000:1000::/home/git:/usr/bin/git-shell
Acceso publico
5.2.3 Private Managed Team [135] Importante
Si se quiere sólo poner un commit en el master
$ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf
Si se quiere obtener la última version (esto requiere que se hayan puesto tags)
$ git describe master
5.3.8 Preparing a Release
Crear la version
$ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
$ ls *.tar.gz
v1.6.2-rc1-20-g8c5b85c.tar.gz
o si se quiere un zip
$ git archive master --prefix='project/' --format=zip > `git describe master`.zip
$ git show HEAD@{2}
$ git show master@{yesterday}
with master..experiment — that means “all commits reachable by experiment that aren’t reachable by master
$ git log master..experiment
The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them.
$ git log master...experiment
Staging interactive
$ git add -i
STASHING
Para trabajar en algo y regresar al estado original sin necesidad de hacer commit se puede usar
$ git stash
listar
$ git stash list
Regresar al stash
$ git stash apply
Borrar
$ git stash drop stash@{0}
Crear una rama de un stash
$ git stash branch testchanges
Reescribiendo la historia
Cambiar el último commit (después de agregar archivos o sólo texto)
$ git commit --amend
NOTA.- No usar si ya se ha hecho un push. (mismo caso que el rebase)
Cambiar multiples mensajes de commit
$ git rebase -i HEAD~3
$ git log --pretty=format:"%h %s" HEAD~3..HEAD
Cambiar un e-mail globalmente.
$ git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="schacon@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
Debugging
$ git blame -L 12,22 simplegit.rb
$ git blame -C -L 141,153 GITPackUpload.m
$ git bisect start
$ git bisect bad
$ git bisect good v1.0
Submodulos.
Agregar un submodulo externo
$ git submodule add git://github.com/chneukirchen/rack.git rack
Clonar un proyecto con submodulos
$ git clone git://github.com/schacon/myproject.git
$ git submodule init
$ git submodule update
$ git diff
$ git submodule update
fetch
checkout con rama
modificacion
merge
local
push
merge remoto
Referencias:
- Git How-to
- He olvidado de donde saqué la mayoria de los ejemplos, pero si algún dia las localizo o si alguien encuentra la referencias favor de avisar para darle el crédito a quien corresponda.