Learn Git

based on boot.dev

res (git docs, github docs)

Setup

bootdev-cli    man git

sudo apt install software-properties-common
sudo add-apt-repository ppa:git-core/ppa

high-level "porcelain" (status, add, commit, push, pull, log), low-level "plumbing" (apply, commit-tree, hash-object)

git config get user.name
           set --global user.name "github_username_here"
           get user.email
           set --global user.email "email@example.com"

           set --global init.defaultBranch master

Repositorios

git init    .git
git status    (untracked, staged, commited)
git add <path-to-file | pattern>
git commit -m "message"    git commit --amend -m "message fixed" # change last message
git log # commit history (made by, when, changes)    git --no-pager log -n 10
    5ba786fcc93e8092831c01e71444b9baa2228a4f
    5ba786f

Internals

SHA-1 cryptographic hash function, each is unique.

It's Just Files All the Way Down

Git is made up of objects that are stored in the .git/objects directory. A commit is just a type of object.

$ git log -n 1
commit 48f83eb4423f12f0624c4c302d13c52524e47251 ...
$ ls -la .git/objects/
total 120
...
drwxrwxr-x  2 torvalds torvalds 4096 Nov 24 18:46 48/f83eb4423f12f0624c4c302d13c52524e47251 # commit object file
drwxrwxr-x  2 torvalds torvalds 4096 Nov 24 17:43 info
drwxrwxr-x  2 torvalds torvalds 4096 Nov 24 17:43 pack
cat gibberish text    xxd .git/objects/48/f83eb4423f12f0624c4c302d13c52524e47251
00000000: 7801 ad8f 316e c420 1000 53f3 0afa 28d6  x...1n. ..S...(.
000000a0: c972 7f5e fbbd 75b2 f905 f0fa 55c9       .r.^..u.....U.
git cat-file -p 48f83eb4423f12f0624c4c302d13c52524e47251
tree c738060e92ead69f2f7084beaf35eb879d4a1cc1                            # tree object
parent 6333f514cd3e6e36389afb0b2e43bc92a9b3d490

Git stores dirs as trees, and files as blobs # content

git cat-file -p c738060e92ead69f2f7084beaf35eb879d4a1cc1
...
100644 blob 25526ca9bd40499bd9d227ba78e0c1bb85ee81d2	README.md
git cat-file -p 25526ca9bd40499bd9d227ba78e0c1bb85ee81d2
Readme file content

Git stores an entire snapshot of files on a per-commit level. This was a surprise to me! I always assumed each commit only stored the changes made in that commit.

Optimizations: compresses and packs files, deduplicates files that are the same across different commits.

Configuración

git config set --global user.name "ThePrimeagen"
git config set --global user.email "the.primeagen@aol.com"
git config list --local
cat .git/config
git config get KEY    set --append    unset --all (duplicates)    remove-section
system: /etc/gitconfig  global: ~/.gitconfig  local: .git/config  worktree: .git/config.worktree

Ramas

A branch is just a named pointer to a specific commit. The branch's last commit is the tip of the branch.

         G - H    lanes_branch (A, B, G, H)
        /
  A - B - C - D   main
    \
     E - F        primes_branch
git branch
           my_new_branch
           -m oldname newname
git switch
           -c my_new_branch
git checkout # old way
git log
        --decorate=
                   short
                   full # show refs
                   no
        --oneline
.git/refs/heads # heads or tips of branches

Merge

Git combines both branches by creating a new commit that has both histories as parents.

              # merge commit
  A - B - C - F    main
     \     /
      D - E        other_branch
switch to main
git log --oneline --graph --all --parents
git merge other_branch

merge base, best common ancestor, replay from

types of merge:
               fast-forward (feature_b has all commits that base_b has
               no merge commit created)
git branch -d add_classics

Rebase

Conozca la forma más avanzada de integrar cambios de una rama en otra.

Reset

Aprenda a deshacer cambios utilizando el comando reset.

Remoto

Configure un repositorio remoto y aprenda a subir (push) y descargar (pull) cambios.

GitHub

Aprenda a usar Git con GitHub, el servicio de alojamiento de repositorios más popular.

.gitignore

Entienda cómo utilizar un archivo .gitignore para excluir archivos y directorios del seguimiento de Git.