git

Table of Contents

1. Git

1.2. Introductory resources

1.2.1. Guía rápida

1.2.1.1. Ciclo básico de desarrollo
git clone <url del repositorio> # Descargar el repositorio (sólo una vez, al principio)

git pull # Pillar lo que ha cambiado desde la última vez
<modificar un archivo>
git add <archivo>
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 .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
1.2.1.2. Deshaciendo cosas
  • git reset HEAD <archivo> deshace git add <archivo>
  • 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 -- <archivo> 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 <hash del commit> Cambia a un commit anterior para ver
    cambios.
  • git revert <hash del commit> DESHACE y BORRA todos los cambios a
    partir del commit indicado. git reset --hard esencialmente revierte
    al último commit
  • git reset --hard <hash del commit> 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
1.2.1.3. He subido archivos binarios al git y tarda 15min en clonarse
1.2.1.4. reset vs checkout
  • Situación inicial
object master
object HEAD
e138c7e -> 72625a3
72625a3 -> 13b2cbe
13b2cbe -> 75cdf49
master --|> 75cdf49
HEAD --|>  master

git_reset_checkout1.png

  • git reset 13b2cbe
object master
object HEAD
e138c7e -> 72625a3
72625a3 -> 13b2cbe
13b2cbe -> 75cdf49
master --|> 13b2cbe
HEAD --|>  master

git_reset_checkout2.png

  • git checkout 13b2cbe (Produce detached HEAD)
object master
object HEAD
e138c7e -> 72625a3
72625a3 -> 13b2cbe
13b2cbe -> 75cdf49
master --|> 75cdf49
HEAD --|>  13b2cbe

git_reset_checkout3.png

DETACHED HEAD se soluciona simplemente con: git checkout <rama>

1.2.1.5. 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
1.2.1.6. Arreglando desastres
  • git push origin HEAD:<branch> cuando estamos en detached HEAD y
    queremos hacer un commit. Me ha pasado cuando hago
    git checkout <commit antiguo>; git merge origin <branch>; 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 <branch> porque
    seguimos trabajando en detached HEAD
1.2.1.7. 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í)

1.2.2. https://git-scm.com/docs/giteveryday → basic commands split by roles

Git users can broadly be grouped into four categories for the purposes of describing here a small set of useful command for everyday Git.

  • Individual Developer (Standalone) commands are essential for anybody who makes a commit, even for somebody who works alone.
    «Invividual Developer (Standalone) Always open a branch for an Individual Developer because a failing git push (because a git pull is needed) is scary»
  • If you work with other people, you will need commands listed in the Individual Developer (Participant) section as well.
  • People who play the Integrator role need to learn some more commands in addition to the above.
  • Repository Administration commands are for system administrators who are responsible for the care and feeding of Git repositories.

1.5. Git is simply too hard |> Changelog

How do I delete a branch?

and then I have to ask them:

Well, what do you want to do? Do you wanna delete a local branch, and then just get it recreated when you pull again from the same remote? Or delete the remote tracking branch? Or delete the remote branch?

1.6. What’s wrong with Git? A conceptual design analysis | the morning paper

Fred Brooks described conceptual integrity as “the most important consideration in system design” and gave three principles upon which it is based:

  • propriety – a product should have only the functions (concepts) essential to its purpose and no more, and
  • generality a single function (concept) should be usable in many ways.

The authors add a fourth:

  • consistency – requiring for example that actions behave in a similar way irrespective of the arguments they are presented with or the states in which they are invoked.

1.7. lazygit

1.7.1. 15 Lazygit Features In Under 15 Minutes - YouTube

  • Move between panels with h,l/←,→ and move inside each panel with j,k/↑,↓
  • Files panel>Toggle stage whole file with SPC
  • When the files are staged, commit with c, C if you want a multiline commit
  • g to reset: soft, mixed and hard
  • a to toggle stage all files
  • RET to path stage line by line with SPC, or with visual line select using v and then SPC (v toggles between visual line and normal mode)
  • Cycle between unstaged and staged lines/hunks with TAB
  • d to delete line in unstaged panel, d to unstage line in staged panel
  • RET on a branch to see its commits (git log on the side)
  • p/P on a branch to pull/Push
  • RET on a commit to see its changes (diff of each file)
  • Cherry pick a commit from a branch with c in the “Local Branches/Remotes/Tags” panel and paste it ont the “Commits/Reflog” panel with v
  • s to stage a file, S stage more selectively
  • d to reset a file (discard changes)
  • D to nuke working tree, discard untracked files, and soft/hard reset

1.7.4. squash

No puedes cambiar el contenido del commit, con lo que se queda con un wip

1.8. Tortoise Git

TortoiseGit – TortoiseGit – Documentation – TortoiseGit – Windows Shell Interface to Git
https://tortoisegit.org/docs/tortoisegit/
https://tortoisegit.org/about/

https://apps.kde.org/dolphin_plugins/

1.9. Tricks

1.10. Changelog

A changelog is a kind of summary of commits

1.12. Pre-commit hooks

1.12.2. Pre-commit que luego hace un commit

Es posible que te empieze a generar commits infinitos si pones git commit en el propio git commit
https://stackoverflow.com/questions/3284292/can-a-git-hook-automatically-add-files-to-the-commit

1.13. Archivos binarios con git

1.13.1. How to manage binary assets with Git | Opensource.com

1.13.2. Git LFS, git-annex

https://git-lfs.github.com/ https://git-annex.branchable.com/ → quizás más interesante que git-lfs

1.13.3. Limpar contraseñas y binarios de repos

1.13.3.1. Ejecutarlo
alias bfg='docker run -it -v $PWD:/pwd -v $HOME/.local/share/linuxbrew:/home/linuxbrew --entrypoint bfg linuxbrew/brew'
bfg --replace-text /pwd/replace /pwd
sudo chown -R julian:julian .git # Ejecutarlo con docker te cambia los permisos de .git
bfg --delete-files 'script.cpython-38.pyc' /pwd

1.13.4. Sparse Checkout

git clone --depth 1 --no-checkout --filter=blob:none https://github.com/ryanoasis/nerd-fonts
echo 'patched-fonts/FiraCode' >> .git/info/sparse-checkout && git config core.sparseCheckout true && \
  git checkout master -- patched-fonts/FiraMono

1.14. Credenciales en git

https://github.com/lu0/syncthing-config/blob/master/pre-commit → alerta cuando comiteas código que no debes
Para pillar todo lo que hay en .env y pasarlo como credencial:

cat .env | awk -F = '{$1=""; print $0}' | sed -Ez 's/\n+/\n/g' | sed 's/^ //' | tr '\n' '|' | copy
#!/bin/bash

sensitive="apikey|password|urUniqueID"

flags=$(git diff -U0 --no-ext-diff --staged | grep -E -i --count "$sensitive")
if [ "$flags" -ne "0" ]; then
   echo "WARNING! You are attempting to commit sensitive data from:"
   git diff --no-ext-diff --staged --name-only -i -G "$sensitive" | sed 's/^/\t*/'
   echo -e "\nPlease review and unstage relevant hunks of those files with"
   echo -e "\tgit reset --patch"
   echo -e "\nCommit using the '--no-verify' option to ignore this warning (not recommended)\n\n"
   echo -e "Sensitive matches found:"
   git diff --no-ext-diff --staged | grep -E -i "$sensitive"
   exit 1
fi

1.15. Rebase vs never rebase

  • Rebase:
  • Not Rebase:
    git is an historical archive of how the code was at a given moment of time, so rebasing is destroying that history
  • You only Git Merge?!? feat Theo : DevHour #1 - YouTube
    • Rebasing creates source code states that never existed, since you take some change and reapplying them on top of a different history. For example git bisect doesn’t work with this
  • Should You Squash Merge or Merge Commit? - Wait, so why don’t you like rebasing?
    Fundamentally, I dislike rebasing because of it’s possibly destructive nature. Sure, there are also a number of proponents of rebasing - usually spouting pithy advice such as “It’s not destructive, if you use Git right”.
    Git is already hard enough to use with a very poor and inconsistent developer experience that leads to too many mistakes. Telling developers to just “use Git right” when rebasing could result in you overwriting a team members work feels somewhat thoughtless
    Finally, merge conflicts during a rebase result in some of the worst developer experience imaginable. Each conflict will be represented one commit at a time ad nauseam. This is confusing and an easy way to pick the wrong side of the conflict. Reversing a rebase is difficult. Merge conflicts during a merge are presented all at once
    Discussion: https://www.reddit.com/r/programming/comments/whav9l/should_you_squash_merge_or_merge_commit/
  • SQLite Doesn’t Use Git
    • Fossil: Rebase Considered Harmful
      1. Rebasing is dangerous
      2. Rebase provides no new capabilities
        1. A rebase is just a merge with historical references omitted
        2. Rebase does not actually provide better feature-branch diffs
      3. Rebase encourages siloed development
      4. Rebase causes timestamp confusion
      5. Rebase misrepresents the project history
      6. Collapsing check-ins throws away valuable information
        1. Individual check-ins support mutual understanding
        2. Bisecting works better on small check-ins
        3. Multiple check-ins require multiple check-in comments
        4. Cherry-picks work better with small check-ins
        5. Back-outs also work better with small check-ins
      7. Cherry-pick merges work better than rebase
      8. Summary and conclusion
        Rebasing is an anti-pattern. It is dishonest. It deliberately omits historical information. It causes problems for collaboration. And it has no offsetting benefits.
        For these reasons, rebase is intentionally and deliberately omitted from the design of Fossil.
  • Squash, Merge, or Rebase?
    squash.jpeg

    • Rebase rewrites history on top of a branch. This provides a linear history, meaning context is lost of where a feature branched off. You may also have to force push changes (since you are rewriting history) if you have already pushed to a remote.
    • Merge will create a merge commit that joins two branches together. With the fast-forward-only flag ff-only, git will attempt to merge without a merge commit, but this isn’t possible if the branches have diverged (i.e., there has been a commit to the parent branch that’s not on the feature branch).
    • Squash + Merge acts like merge but creates a single new squashed commit that encompasses all commits in the feature branch.

    I use rebase. Rebase retains a linear commit history, which is important for rollbacks. In addition, rebase is the most flexible workflow – larger and more difficult merges can be tough to do with a squash and merge. Interactive rebase has a bit of a steeper learning curve, but with practice, it can work in all scenarios. Squash and merge is OK for smaller changes, but it might be smarter to break large feature branches into multiple logical commits. This is useful for cherry-picking commits to other branches or repositories.

  • Git team workflows: merge or rebase? | Atlassian Git Tutorial
    Rebase as team policy is a different thing than rebase as cleanup.
    • Rebase as cleanup, even when sharing your feature branch
      • You’re developing locally and have not shared your work even if you have pushed it. Rebase is fine
      • Your code is ready for review. You create a pull request, others are reviewing your work and are potentially fetching it into their fork for local review. You should not rebase
        You should create ’rework’ commits and update your feature branch. This helps with traceability in the pull request, and prevents the accidental history breakage.
      • Review is done and ready to be integrated into the target branch. Given that other developers won’t be fetch-merging, you can rebase now
    • Rebase as a team policy
      • ↑ Code history remains flat and readable. Clean, clear commit messages are documentation, do not to pollute history
      • ↑ Manipulating a single commit is easy (e.g. reverting them).
      • ↓ Squashing the feature down to a handful of commits can hide context, unless you keep around the historical branch with the entire development history.
      • ↓ Rebasing doesn’t play well with pull requests, because you can’t see what minor changes someone made if they rebased (never rebase during a pull request).
      • ↓ Rebasing can be dangerous and is prone to team work breakage
        This can be mitigated by doing the rebase/squash on a copy of the feature branch
      • It’s more work: Using rebase to keep your feature branch updated requires that you resolve similar conflicts again and again.
        You can reuse recorded resolutions (rerere) sometimes, but merges win here: Just solve the conflicts one time, and you’re set.
      • you need to force push at some point. If people haven’t set git push.default ⇒ updates to all branches having the same name, both locally and remotely, and that is dreadful to deal with.

NOTE: When history is rewritten in a shared branch touched by multiple developers breakage happens.

1.16. Git alternatives

1.16.1. Pijul

  • Commutation
    In Pijul, independent changes can be applied in any order without changing the result or the version’s identifier. This makes Pijul significantly simpler than workflows using git rebase or hg transplant. Pijul has a branch-like feature called “channels”, but these are not as important as in other systems. For example, so-called feature branches are often just changes in Pijul. Keeping your history clean is the default.
  • Merge correctness
    Pijul guarantees a number of strong properties on merges. The most important one is that the order between lines is always preserved. This is unlike 3-way merge, which may sometimes shuffle lines around. When the order is unknown (for example in the case of concurrent edits), this is a conflict, which contrasts with systems with “automatic” or “no conflicts” merges.
  • First-class conflicts
    In Pijul, conflicts are not modelled as a “failure to merge”, but rather as the standard case. Specifically, conflicts happen between two changes, and are solved by one change. The resolution change solves the conflict between the same two changes, no matter if other changes have been made concurrently. Once solved, conflicts never come back.
  • Partial clones
    Commutation makes it possible to clone only a small subset of a repository: indeed, one can only apply the changes related to that subset. Working on a partial clone produces changes that can readily be sent to the large repository.

1.17. Firmar commits / sign commits

gpg --list-secret-keys --keyid-format=long
# sec   algorithm_or_number/61690A4ABCDFE59C
gpg --armor --export 61690A4ABCDFE59C | copy
git config --global commit.gpgsign
git config --global user.signingkey 61690A4ABCDFE59C
export GPG_TTY=$(tty) # Put it in your .bashrc/.zshrc

1.18. Git Workflows

1.18.2. Versioning

1.18.2.4. Designing a version

1.18.3. Git commit style

1.18.3.3. Conventional Commits, Commitizen, Auto Changelog
pip install -U commitizen
pip install pre-commit
1.18.3.5. https://whatthecommit.com/ → anti commit style

1.18.4. Things I wish Git had: Commit groups

1.18.4.1. Things I wish Git had: Commit groups
  1. Create a merge commit with –no-ff
    • ↑ extremely versatile and scale well, especially for complicated workflows with multiple maintainers, each responsible for different part of the code
    • ↓ probably overkill for small groups ⇒ potential problems
    • ↓ Complicated to see concurrent changes to the code, entangled graph
    • ↓ complicated to answer questions such as:
      • “which features were released over the given time period?”
      • “what was the state of main as of a given date?”.
    • ↓ harder to revert changes (implies reverting multiple commits)

    GitFlow considered harmful | End of Line Blog

  2. Squash and merge
    • ↑ very legible history (linear)
    • ↑ easier to revert a feature (git revert one commit)
    • ↓ squashing irrevocably loses context, especially if branch has been deleted
  3. Rebase and merge
    • ↑ linear history with multiple commits
    • ↓ harder to revert changes: typically you want to operate on a feature level there as in Squash and merge
    • git commits have to be meaningful to use this approach
  4. Rebase, group and merge

    You draw a couple of shapes, you group them together, and then you can apply transformations to the entire group at once, operating on it as if it were an atomic thing. But when need arises, you can “ungroup” it and look deeper.
    That’s because sometimes there’s a need to have a “high-level” view of things, and sometimes you need to delve deeper. Each of these needs is valid. Each is prompted by different circumstances that we all encounter.

1.18.5. A successful Git branching model (Git Flow)

In the beggining, it was Git Flow. Then it was considered harmful

1.18.6. GitFlow considered harmful | End of Line Blog

1.18.7. Please stop recommending Git Flow! – George Stocker

1.18.9. Monorepo

1.18.9.1. Tools for monorepo management - packages linking, versioning, publishing : Python
1.18.9.2. Google Research uses one repo

1.18.10. Multiple repo management

Submodules aren’t more straightforward? There is a git submodule foreach command

1.18.10.1. mu-repo

1.18.11. Merge Window

2. How the development process works — The Linux Kernel documentation
At the beginning of each development cycle, the “merge window” is said to be open. The merge window lasts for approximately two weeks.
Over the next six to ten weeks, only patches which fix problems should be submitted to the mainline. On occasion a more significant change will be allowed, but such occasions are rare
(An occasional exception is made for drivers for previously-unsupported hardware; if they touch no in-tree code, they cannot cause regressions and should be safe to add at any time)

1.23. Cambiarme a un setup de git con wip, squash, worktree y zsh, + lazygit   project someday_20230330

La idea es hacer un montón de commits en local y luego juntarlos antes de subirlos

alias gwip='git commit -a -m "work in progress - fixup"'

Things I wish Git had: Commit groups → Un poco relaccionado con todo esto
-—

  1. Commit en local al principio
  2. Hacer commits que tengan wip para que los vea en zsh
  3. Squash de todos ellos antes de subirlos
    1. Suele pasar que tienes cambios en local (el repo no está limpio) → hacer un gsp git rebase -i HEAD~N donde N son los commits que te indica zsh
  4. A veces la lías con squash → reflog para hacer un reset a como estabas antes
  5. Utilizar Git Worktrees para poder trabajar en varias ramas a la vez, o guardar marcas en distintos archivos en distintas ramas

1.23.1. “Git’s Best And Most Unknown Feature” Worktrees

Te permite tener un directorio por cada rama
https://youtu.be/2uEqYw-N8uE

git clone --bare <repo>
git worktree add [<path>] <branch>
git worktree list
git worktree remove <branch> # Does not remove if you have unstaged changes

https://github.com/ThePrimeagen/git-worktree.nvim

1.23.3. Arhcivos comunes

Puedo utilizar lo de Crear un sistema de gestión de paquetes comunes a varios venv, jdupes/ostree para estos mismos archivos comunes, e incluso para el propio entorno virtual que al final va a ser el mismo lo ejecute donde lo ejecute (asumiendo que utilizo zpy por ejemplo)

1.23.3.1. Añadir hooks para copiar archivos comunes

Archivos de configuración, credenciales, etc
Cada vez que abres una rama quieres que sean siempre los mismos y si eso cambiarlos para probar una cosa rápidamente y luego volver a la versión normal
Se puede implementar con links simbólicos a las carpetas necesarias, y luego tener un atajo rápido para poder editarlas sin cambiar las del resto por si quieres probar una cosa rápidamente, y luego volver a correr los links simbólicos
cd credentials && ln -s ../credentials/* .

1.23.4. Añadir múltiples ramas en git worktree

echo -e "master\nrelease\ndevelop" | xargs -I _ git worktree add _

1.24. Git Alternatives

1.26. Github Alternatives

1.26.2. Edward Loveall - Let’s Make Sure Github Doesn’t Become the only Option

https://www.reddit.com/r/programming/comments/135set8/lets_make_sure_github_doesnt_become_the_only/

git and GitHub’s symbiosis are holding us back as an industry.

GitHub is what most people use because it makes the complexities of git easier. git remains dominant despite it being complex because it’s not in the interest of GitHub and most of GitHub’s competitors to support anything else.

Other version control software exists that doesn’t need a separate company to make the code accessible from the web or makes dealing with conflicts easier. We as an industry cannot benefit from these alternatives if we continue to use GitHub this heavily.

1.27. Tools for Git Analysis

1.28. Git en profundidad

1.28.1. git add

1.28.2. git commit

  • Commit con el mismo mensaje que el anterior: git commit -C HEAD
  • --amend para enmendar un commit anterior

1.28.3. 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
  • https://devhints.io/git-log-format
  • git --no-pager lg --no-color -S 18:15 -p
    • --no-pager elimina el paginado estilo less
    • --no-color quita los caracteres de escape para los colores

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
1.28.3.1. filtros
  • --[since|after], --[until|before]
  • --author, --committer
  • --grep <mensaje> → el mensaje matchea. Acepta argumentos de grep como -E, pero van antes de –grep
  • -S <codigo> → los commits han eliminado o añadido código que matchea
  • -G <regex> → lo mismo con regex
  • -L :func:script.py → Dentro de script.py, cambios hechos a la función/clase func
  • -L <start>,<end>:script.py → Dentro de script.py, cambios hechos a as líneas entre <start> y <end>
  • git log --author='^(?!Adam|Jon).*$' --perl-regexp Regexp de perl para filtrar todos los commits de los usuarios que no son Adam ni Jon, con negative lookahead
    https://stackoverflow.com/questions/4259996/how-can-i-view-a-git-log-of-just-one-users-commits
1.28.3.2. Buscar archivos en el histórico
  1. Por nombre de archivo
    git log --all --full-history -- "**/thefile.*"
    git branch -a --contains 55d2069 # Para ver en qué rama está
    
    git lg -S"#+transclude" -p -- . ":\!path/to/file"
    
  2. Por línea

    https://stackoverflow.com/questions/1337320/how-to-grep-git-commit-diffs-or-contents-for-a-certain-word/1340245#1340245

      git grep <regexp> $(git rev-list --all)
      git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util # Buscar en un subárbol
    
      git log -S<string>
      git log -G<regex>
    

1.28.4. git merge

1.28.5. 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
  git grep -i task -- './*' ':!*.md' # Buscar excluyendo los .md

1.28.6. 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 diff-apply git diff d892531 815a3b5 | git apply

1.28.7. On undoing, fixing, or removing commits in git

git rebase --rebase-merges --onto SHA^ SHA

1.28.8. Información

  • git show-branch (|-r|-a) Muestra todas las ramas
    locales|remotas|todas
  • git blame <archivo> Muestra quién ha escrito cada línea de <archivo>

1.28.9. Configuración

  1. /etc/gitconfig -> --system --system-wide
  2. ~/.gitconfig or ~/.config/git/config -> --global
  3. repo/.git/config -> --local
1.28.9.1. .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 <archivo> fuerza añadir el archivo incluso si está
    ignorado en .gitignore
  • git config --local core.excludesfile hidden/.gitignore_local

1.28.10. 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

1.28.10.1. Crear un repositorio
server:$ git init --bare --shared
local:$ git clone <repo url>
  1. Resetear un repositorio bare
    git update-ref HEAD <hash del commit>
    # Para borrar lo que queda colgando
    git gc
    git prune
    
1.28.10.2. Submódulos de git
  • git submodule add <url>
  • 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

1.28.11. Herramientas

1.28.11.1. diff

git diff <x> <x+∆x> Si sólo ponemos un commit y no tenemos ningún
unstaged changes/untracked files, entonces git diff <x> es lo mismo
que git diff <x> HEAD
https://stackoverflow.com/questions/31454603/order-of-commit-arguments-in-git-diff

1.28.11.2. 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 <branch> # Nueva rama para el stash
  git stash push -m "mensaje de stash" -- <pathspec>
1.28.11.3. 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
1.28.11.4. grep
git grep -n (número de línea) -c (contar ocurrencias) -p (en qué parte del código) <regex> -- <pathspec>
1.28.11.5. rev-list
git rev-list <inicio>..<final> # Saca todos la lista de commits de inicio a final

Author: Julian Lopez Carballal

Created: 2024-09-16 Mon 06:59