GitCookbook - henk52/knowledgesharing GitHub Wiki

Introduction

  • foxtrot merge

References

Vocabulary

  • branch: basically a reference?
  • commit id: is a checksum, that represents:
    • Content
    • Author
    • Date
    • Log
    • Previous commit id
    • Every commit is unique

    • Every commit id is unique

    • Commit never changes

  • fast-forward: when no merge is required, the references (head, branch) are simply moved to the newer commit object(id) (25:00)
  • origin/bugfix vs. origin bugfix
    • origin/bugfix: refers to the reference, by that name, in this repo
    • origin bugfix: refers to bugfix in the the origin repo
  • references:
    • branch
    • tag
    • commit id
    • remote branch
  • Staging area: aka index, aka cache

Installation

support multiple repo-users on same device

See: Multiple-github-accounts-on-the-same-computer

  • Generate an SSH-key ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa_MY_USER, follow the prompts and decide a name, e.g. id_rsa_doe_company.
  • Copy the SSH public-key to GitHub from ~/.ssh/id_rsa_doe_company.pub and tell ssh about the key: ssh-add ~/.ssh/id_rsa_doe_company.
  • Create the configuration file in: ~/.ssh/config with the content shown below:
  • Add your remote:
    • git remote add origin git@<github-doe-company>:<username>/<reponame>.git
    • or change using git remote set-url origin git@<github-doe-company>:<username>/<reponame>.git
  • To clone a new repo
    • git clone git@<github-doe-company>:<username>/<reponame>.git

~/.ssh/config

Host github-doe-company
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_doe_company

git push/clone hangs

Was it my ISP that was the problem???

configure git globally

  • git config --global -e
[push]
  default = simple

[alias]
    a = add
    # Amend the previous commit
    amend = commit --amend --reset-author --verbose
    # Commit and show diff in editor too
    ci = commit --verbose
    co = checkout
    up = pull --ff-only
    st = status
    # Show status for current sub-directory only
    s = status -- .
    # List all branches (locally and remote)
    br = branch -a
    # Remove branch
    rmbr = branch -d
    # Remvoe remote branch (locally)
    rmrbr = branch -d -r
    # Remvoe remote branch (locally)
    rmrbr = branch -d -r
    # Show the staged/cached/indexed changes
    idiff = diff --cached
    # Show info about tree objects
    ls = ls-tree HEAD
    # Show info about all tree objects
    list = ls-tree --full-tree -r HEAD
    pick = cherry-pick

    unstash = stash pop
    # Unapply the changes recorded in the most resent stash
    stash-unapply = !git stash show -p | git apply -R

    # Show summary info about a commit
    s = show --name-only --pretty=fuller

    # Create a Work In Progress commit (alternative to stash)
    wip = commit --all -m WIP

    # Show commits that have not been pushed yet
    # sc:  show commits (ahead)
    # scg: show commits (ahead) graph
    sc = log '@{upstream}'..HEAD --oneline --decorate
    scg = log '@{upstream}'..HEAD --oneline --decorate --graph
    # The same but with full commit messages
    # scl:  show commits (ahead) long
    # sclg: show commits (ahead) long graph
    scl = log '@{upstream}'..HEAD --decorate
    sclg = log '@{upstream}'..HEAD --decorate --graph

    # Single-line or short log of everything
    slog = log --graph --format=oneline --all
    # Single-line or short branch log
    blog = log --graph --format=oneline
    # Single-line or short log of everything with more info
    hist = log --pretty=format:\"%C(auto)%h %ad |%d %s [%Cblue%an%Creset]\" --graph --date=local --all
    # Single-line or short branch log with more info
    bhist = log --pretty=format:\"%C(auto)%h %ad |%d %s [%Cblue%an%Creset]\" --graph --date=local

    # prune orphan commits / housekeeping
    prune = gc --prune=now --aggressive
    oldest-ancestor = !zsh -c 'diff --old-line-format= --new-line-format= <(git rev-list --first-parent \"${1:-master}\") <(git rev-list --first-parent \"${2:-HEAD}\") | head -1' -

[color]
    # Show colour on terminals
    ui = auto

[log]
    # abbreviate commit hashes
    abbrevCommit = true
    # show tags, branches, etc. in logs
    decorate = short

[push]
    # The default as of git 2.0, and the safest for beginners :)
    default = simple

[rerere]
    # Record conflict resolutions
    enabled = true

[core]
    pager = less -i -S
    editor = vim
[init]
  defaultBranch = main

Command overview

  • add: add binary? to the repository.
  • branch: creates a branch with the given name
  • checkout: marks the given branch as the reference to advance/move with new commits.
    • move head to that commit id
    • and get the files related to the branch reference
  • commit: create a commit object of what has already been added.
    • and add labels: head and master(current branch?) to it
  • fetch
  • pull: actually a fetch + merge
  • push
  • rebase:
  • reset
  • reflog:
  • tag: is a reference, it doesn't move.

Overview

  • git branch -d PlaceInTime
    • delete the local branch
  • git branch -d -r origin/SOMETHING
    • delete the branch remot
  • git branch PlaceInTime eea3d0e
    • add the branch tag to the give id
  • git checkout master
    • Switch branch to master
  • git checkout PlaceInTime
    • Switch branch to PlaceInTime
  • git cherry-pick --abort
  • git clean -dxn
    • Show which files will be cleaned.
    • git clean -dxf
      • actually clean the files and dirs
  • git fetch
  • git info 45d42a3
    • get info on the commit id
  • git merge --abort
  • git pick 12c4ee6
  • git pull
  • git push
  • git push -f feature/ALPHA
  • git push -f origin feature/BETA
  • git push origin --delete DELTA
  • git rebase --abort
  • git rebase --continue
  • git rebase master
  • git show 45d42a3
  • git show --name-only 45d42a3
  • git slog
  • git stash
  • git stash drop
  • git stash show
  • git status
  • git unstash

checkout

  • -b: branch + checkout

commit

Commit message

  • subject(first line):
    • Max 50 characters
    • no '.' at the end
    • Formulate is for cherry-picking
      • e.g. Add firewood
      • Fix ax
  • empty line
  • Body
    • What is now different than before
    • What is the reason for the change?
    • Is there anything to watch out for/anything particularly remarkable?

TODO how to do that in VS Code?

output:

[master abbd4b3] Second commit
 1 file changed, 2 insertions(+)
  • master: branch reference
  • abbd4b3: commit object?
  • 'Second commit': The commit text

merge

  • git merge master

    • merge master into the current branch
  • git merge master bugfix

    • merge master into bugfix
  • git reset --hard HEAD^

    • go back to the commit before the head, and check it out.

rebase

  • the-dark-side-of-the-force-push

  • git rebase

  • 1 git status

    • Ensure everything is committed and pushed
  • 2 git checkout master

  • 3 git pull --ff-only

  • 4 git checkout MY_BRANCH

  • 5 git rebase master MY_BRANCH

  • 6 git status

  • 7 git push -f

reset

Parameters:

  • --hard : also checkout to this

Cookbook

operations

Re-add executability to a file

  1. git ls-files --stage
  2. git update-index --chmod=+x FILE_NAME
  3. git ls-files --stage

rebase recipe

  • Thou shall not rebase a public branch

  • merge to bring in large topic branches back into the master branch.

  • merge any time the branch is already public.

  • rebase when you want to add minor commits that are in master to a topic branch

  • rebase whenever you want to move commits from one branch to another.

  • git rebase --continue

    • It seems you have to do this after having updated the files you wanted to update/merge.
  • git rebase --skip

    • use fully the file that the rebase branch(the one we are trying to rebase on)
  • git rebase --abort

    • As if the rebase was never started
  • git rebase --onto newbase upstream branch

    • newbase: The new branch that is going to be the base.
    • upstream: The current base branch for the feature-branch 'branch'
      • upstream of the feature branch.(Parent of the feature branch)
    • branch: The feature branch.
  • git reset --hard ORIG_HEAD

    • undo a rebase operation
  • git rebase -i

    • Interactive, we get a text file to change, where all affected commits are listed.
  • git pull --rebase

  • git pull --rebase=preserve

  • git pull --rebase=interactive

Possible process??

  1. git checkout master
  2. git refresh
  3. git up
  4. git checkout FEATURE
  5. git rebase master

Git master class

  • Understanding and mastering git

Areas of git

  • working directory
  • staging area(index)
    • prep for putting files into git repo or take out of repo.
  • Git repository.

.git directory

  • config - configuration of the repository.
  • description
  • HEAD
  • objects - all files in the repository.

.git/objectes directory

  • git has its own files system, stored in the 'objects' directory.
  • All files are in the 'objects' directory(S4E3).
  • as such what is in here in not dependent on what you have in the source directory (the parent directory of .git)

Object types:

  • commit - store different version of the project
    • "wrapper" for the tree object(s5e2).
    • Consists of(s5e2)
      • Author name and e-mail
      • Commit description
      • Parent(optional) - parent commit
      • reference - to a tree object hash(the root tree)
    • has a hash like other git objects
    • git cat-file -p cdfdb0b
      • tree 3b95df0ac6365c72e9b0ff6c449645c87e6e1159
      • author someone [email protected] 1753422509 +0200
        • 1753422509 - epoc
        • +0200 - timezone
      • committer someone [email protected] 1753422509 +0200
      • EMPTY
      • Our very first commit in the project
  • tree - Store informations about directories
    • If there are no other tree objects pointing to a tree object, then it is the root directory(s4e24)
    • example of a lines in the tree object(s4e19)
      • 100644 blob 4400aae52a27341314f423095846b1f215a7cf08 first_file.txt
      • 040000 tree 1fed4f4230846b1f2728786968ac96969f69689e src
      • There is a tab between hash and filename
      • permissions, type, hash, name
        • Permission(s4e20)
          • 040000 - Directory
          • 100644 - Regular non-executable file
          • 100644 - Regular non-executable group-writable file
          • 100644 - Regular executable file
          • 120000 - Symbolic link
          • 160000 - Gitlink
  • blop - Here git store all files of any types, both text and binary files.
    • git blops do not contain information about filenames (s4e15)
      • the filename is stored in the trees(s4e17)
    • the blob contains the size and type information.
    • git generates SHA1 hash based on input+size+type(s4e16)
    • The blop contains for field: Object type, object length, \0, content of original(file)(s4e17)
    • echo "blob 11\0Hello Git" | shasum
      • this will show the same hash as git hash-object.
    • the objects are stored as compressed files.
  • annotated tag - persistent text pointers to specific commits

the four tracking statuses of files in git

(s5:e8)

  • untracked -
  • modified -
  • staged -
  • unmodified

Git low-level commands

  • for hash it seems to be enough to provide the first four characters.

  • git cat-file - read git objects

    • -p hash - content of the object
    • -s hash - size
    • -t hash - type
  • git checkout-index (s4e27)

    • -a - checks out all files in the index except for those with the skip-worktree bit set
  • git hash-object - create new object in git structure (Understand and master Git and Github, s4:e14)

    • -p hash - content of the object
    • -s hash - size
    • -t hash - type
      • blop
      • tree
      • commit
      • annotated tag
    • -w - write the hash object into the .git/objects
  • git ls-files - Show information about files in the index and the working tree

    • -s - list files in the staging area(s4e24)
  • git mktree -(s4e21)

  • git read-tree hash - will read the entire tree under that object and put into the stagin area(s4e25)

  • echo "Hello, Git" | git hash-object --stdin -w

    • write a file in the objectcs directory; sub-directory b7 and file .git/objects/b7/aec520dec0a7516c18eb4c68b64ae1eb9b5a5e
  • key in git equals the hash value

  • the hash of the file is used as the

    • folder name - two first bytes of the hash
    • filename - rest of the bytes of the hash
  • the hash function creates a fixed length hash from any variable length input

  • the same input will always create the same hash

  • git uses sha1 which is 160bit/40 hex decimal/80 bytes

  • max files in git: 2^160

  • two different files can produce the same hash; the probability is 1/320

Example of low level use

  • echo "Hello, Git" | git hash-object --stdin -w
  • echo "Second file in Git repository" > ../new-file.txt
  • git hash-object
  • Create tree object
    • find .git/objects/ -type f
    • vi ../temp-tree.txt
      • 100644 blob b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e file1.txt
      • 100644 blob 4400aae52a27341314f423095846b1f215a7cf08 file2.txt
    • cat ../temp-tree.txt | git mktree
      • return the hash of new object
  • read the tree into the staging area
    • git read-tree 3b95
    • git ls-files
      • file1.txt
      • file2.txt
    • git ls-files -s
      • 100644 b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e 0 file1.txt
      • 100644 4400aae52a27341314f423095846b1f215a7cf08 0 file2.txt
        • the '0' means there are no changes between the staged file and the object area.
  • move tree from staging area to working directory
    • git checkout-index -a
    • ls
      • file1.txt file2.txt

Main areas

TODO fille out.

⚠️ **GitHub.com Fallback** ⚠️