~~stoggle_buttons~~ ====== Links ====== * [[https://git-scm.com/doc|Documentación]] (incluye el manual) y [[https://git-scm.com/book/en/v2|manual]] * [[https://ohshitgit.com/|Oh Shit, Git!?!]] * [[https://github.com/k88hudson/git-flight-rules|Flight rules for Git]] * [[https://github.com/larsbrinkhoff/fearless-git|fearless-git: Rewrite Git History Like There's No Tomorrow]] * [[https://dhwthompson.com/2019/my-favourite-git-commit|My favourite git commit]] * [[https://github.com/src-d/hercules|hercules]] Estadísticas avanzadas de git (hay hacer ''%%alias labours="python3 -m labours"%%'' porque por defecto pilla el python2, y luego también se les olvida el pipe:. Funciona con versiones antiguas de python (3.6, 3.7), si no te tienes que compilar tú tus paquetes con dependencias binarias * ''%%hercules --burndown --burndown-people file://$PWD | labours -m overwrites-matrix%%'' * [[https://github.com/augmentable-dev/askgit]] Queries sql contra git * [[https://www.linuxuprising.com/2019/11/forgit-interactive-git-commands-with.html|forgit]] git + fzf * [[https://github.com/git-learning-game/git-hydra|game about learning git]] ====== Guía rápida ====== ===== Ciclo básico de desarrollo ===== git clone # Descargar el repositorio (sólo una vez, al principio) git pull # Pillar lo que ha cambiado desde la última vez git add git add * # añadir todo lo que se ha modificado git commit -m "He cambiado esto y esto otro" git push # Sube los cambios al servidor ''git log'' sirve para ver los commits pasados. Se puede filtrar por usuario, no mostrar los merges, filtrar por fecha, grepear, ... ''%%git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"%%'' para que se vea bonito, ''git lg -p'' para ver el diff de cada commit * Configurar ''user.name, user.email, core.editor'' * Configurar [[https://help.github.com/articles/dealing-with-line-endings|.gitattributes]] para los saltos de línea * ''git ls-files %%--%%deleted | xargs git add'' añadir sólo archivos borrados * ''git diff %%--%%no-index A B'' para diff con estilos de git ===== Deshaciendo cosas ===== * ''git reset HEAD '' deshace ''git add '' * ''git reset HEAD'' deshace todos los ''git add'' que hayamos hecho * ''git commit %%--%%amend'' antes de ''git push'' enmienda el commit que hemos hecho * ''git checkout %%--%% '' BORRA los cambios (locales) del archivo sin commitear y lo reemplaza con la versión que hay en el repositorio * ''git stash'' Descarta los cambios locales, pero los guarda para más tarde con ''git stash pop'' * ''git reset %%--%%hard'' Resetea el repositorio local, BORRA y reemplaza para que el repositorio local se quede igual que el remoto * ''git checkout '' Cambia a un commit anterior para ver cambios. * ''git revert '' DESHACE y BORRA todos los cambios a partir del commit indicado. ''git reset %%--%%hard'' esencialmente revierte al último commit * ''git reset %%--%%hard '' resetea todo a ese commit, por si tienes algunos commits que no quieres subir * ''git revert %%--%%no-commit master~9..master'' revierte los últimos 9 commits de master ===== He subido archivos binarios al git y tarda 15min en clonarse ===== [[https://medium.com/@buzaa/why-you-should-not-push-binary-files-to-git-and-what-to-do-if-you-do-29f34692cef0]] * ''%%git filter-branch --tree-filter "rm -r -f " HEAD%%'' * Forzar el push ===== reset vs checkout ===== Situación inicial object master object HEAD e138c7e -> 72625a3 72625a3 -> 13b2cbe 13b2cbe -> 75cdf49 master --|> 75cdf49 HEAD --|> master ''git reset 13b2cbe'' object master object HEAD e138c7e -> 72625a3 72625a3 -> 13b2cbe 13b2cbe -> 75cdf49 master --|> 13b2cbe HEAD --|> master ''git checkout 13b2cbe'' (Produce detached HEAD) object master object HEAD e138c7e -> 72625a3 72625a3 -> 13b2cbe 13b2cbe -> 75cdf49 master --|> 75cdf49 HEAD --|> 13b2cbe DETACHED HEAD se soluciona simplemente con: ''git checkout '' ===== Borrando cosas ===== * ''git push origin %%--%%delete branch'' elimina ''origin/branch'' (remoto) * ''git push %%--%%delete origin mytag'' lo elimina en remoto, y ''git tag rm mytag'' en local ===== Arreglando desastres ===== * ''git push origin HEAD:'' cuando estamos en detached HEAD y queremos hacer un commit. Me ha pasado cuando hago ''git checkout ; git merge origin ; git push # FALLA'', en vez de hacer ''git revert'' porque había muchos commits en medio. **Después habrá que hacer ''git pull; git checkout ''** porque seguimos trabajando en detached HEAD ===== Evitando desastres ===== * Antes de hacer un rebase de new_feature contra una rama old_feature, que partió de una rama estable como master, hay que hacer primero un rebase de old_feature contra master, por que si divergen las historias, hay conflictos * Una alternativa sería mergear de new_feature con old_feature, pero si la rama está desactualizada, git sabe qué commits tiene que coger? (Creo que sí) ====== Git en profundidad ====== ===== git add ===== ===== git commit ===== * Commit con el mismo mensaje que el anterior: ''%%git commit -C HEAD%%'' * ''%%--amend%%'' para enmendar un commit anterior ===== git log ===== * ''%%git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"%%'' * ''git log %%--%%abbrev-commit %%--%%name-only'' muestra hash abreviado y nombre de archivos cambiados ''%%git log --pretty=format%%'' ^ Opción ^ Descripción ^ | ''%H/%h'' | Commit largo/abreviado | | ''%an/%ae'' | Author name/email | | ''%ad/ar'' | Author date/relative date | | ''%s'' | Subject (commit message) | | ''%n'' | Salto de línea | Las ''a'' se pueden cambiar por ''c'' para mostrar el commiter name y demás. Commiter es el que hace el commit y author el que escribe el código. Normalmente coincide, pero al hacer una Pull Request difiere (ya que sólo los que trabajan en el proyecto pueden hacer commits al repositorio principal) * Soporta fechas con ''%%--date=[local|short]%%'' * strftime con ''%%--date=format[-local]:"%Y-%m-%d %H:%M:%S"%%'' * ''--graph'' para que se vean las ramas separarse y juntarse ==== filtros ==== * ''%%--[since|after], --[until|before]%%'' * ''%% --author, --committer%%'' * ''%% --grep -> el mensaje matchea. Acepta argumentos de grep como -E, pero van antes de --grep%%'' * ''%% -S -> los commits han eliminado o añadido código que matchea%%'' * ''%% -G -> lo mismo con regex%%'' * ''%% -L :func:script.py -> Dentro de script.py, cambios hechos a la función/clase func%%'' * ''%% -L ,:script.py -> Dentro de script.py, cambios hechos a as líneas entre y %%'' ==== Buscar archivos en el histórico ==== === Por nombre de archivo === git log --all --full-history -- "**/thefile.*" git lg -S"#+transclude" -p -- . ":\!path/to/file" === Por línea === [[https://stackoverflow.com/questions/1337320/how-to-grep-git-commit-diffs-or-contents-for-a-certain-word/1340245#1340245]] git grep $(git rev-list --all) git grep $(git rev-list --all -- lib/util) -- lib/util # Buscar en un subárbol git log -S git log -G ===== git merge ===== * [[https://howchoo.com/git/git-merge-conflicts-rebase-ours-theirs|Estrategias de merge]] ===== git grep ===== git grep -n # Saca el número de línea y es clickable en vscode git grep buscar -- "*.py" # los "" son necesarios, si no falla git grep -i task -- './*' ':(exclude)*.md # Buscar excluyendo los .md ===== cherry picking y diff apply ===== * git cherry-pick **no aplica sólo un commit**, sino que mueve el HEAD hacia ese commit (lo que puede provocar conflicto de merge aunque en el commit específico que coges no haya dichos conflictos) * La alternativa es [[https://stackoverflow.com/questions/12320863/how-do-you-take-a-git-diff-file-and-apply-it-to-a-local-branch-that-is-a-copy-o|diff-apply]] ''%%git diff d892531 815a3b5 | git apply%%'' ===== Información ===== * ''git show-branch (|-r|-a)'' Muestra todas las ramas locales|remotas|todas * ''git blame '' Muestra quién ha escrito cada línea de ===== Configuración ===== - ''/etc/gitconfig %%-> --%%system %%--%%system-wide'' - ''~/.gitconfig or ~/.config/git/config %%-> --%%global'' - ''repo/.git/config %%-> --%%local'' ==== .gitignore ==== * Es un archivo para hacer una lista de los archivos que **no** se tienen que seguir (track), es decir, git ignorará esos archivos y no se añadiran incluso tras hacer ''git add *'' * ''git add -f '' fuerza añadir el archivo incluso si está ignorado en ''.gitignore'' * ''%%git config --local core.excludesfile hidden/.gitignore_local%%'' ===== remotes ===== ''git branch %%--%%set-upstream-to=origin/master master'' enlaza origin/master con tu master local, de manera que no hay que hacer ''git push origin master'' o ''git pull origin master'' ==== Crear un repositorio ==== server:$ git init --bare --shared local:$ git clone ==== Submódulos de git ==== * ''%%git submodule update --init%%'' * ''cd'' al repo y ''git pull'' para coger el último cambio * ''git submodule update'' para quedarte up to date con el repo original ===== Herramientas ===== ==== diff ==== ''git diff '' Si sólo ponemos un commit y no tenemos ningún unstaged changes/untracked files, entonces ''git diff '' es lo mismo que ''git diff HEAD'' [[https://stackoverflow.com/questions/31454603/order-of-commit-arguments-in-git-diff]] ==== stash ==== git stash git stash list; git stash apply @stash{2}; git stash pop # aplica el primero git stash --keep-index (stash sin checkout a la rama) --include-untracked (-u) git stash branch # Nueva rama para el stash git stash push -m "mensaje de stash" -- ==== patchs, interactivo ==== git add -i # abre modo interactivo # patch -> ciertas partes del código, añadir ciertas líneas git add --patch git checkout --patch git stash push --patch ==== grep ==== git grep -n (número de línea) -c (contar ocurrencias) -p (en qué parte del código) -- ==== rev-list ==== git rev-list .. # Saca todos la lista de commits de inicio a final ====== Git Standards ====== * [[https://nvie.com/posts/a-successful-git-branching-model/|A successful Git branching model]] * [[https://www.conventionalcommits.org/|Conventional Commits]] * [[https://commitizen-tools.github.io/commitizen/|Commitizen]] -> Generar [[https://keepachangelog.com|Changelogs]] en base a Conventional Commits * [[https://semver.org/]]