################################################################################



              ┏━╸╻╺┳╸         ╻ ╻┏━┓┏━┓╻┏ ┏━┓╻ ╻┏━┓┏━┓
              ┃╺┓┃ ┃    ╺━╸   ┃╻┃┃ ┃┣┳┛┣┻┓┗━┓┣━┫┃ ┃┣━┛
              ┗━┛╹ ╹          ┗┻┛┗━┛╹┗╸╹ ╹┗━┛╹ ╹┗━┛╹  



                        27. September 2022
                          Pranger Stefan

################################################################################



              ┏━┓┏━┓┏━┓╺┳┓┏┳┓┏━┓┏━┓   
              ┣┳┛┃ ┃┣━┫ ┃┃┃┃┃┣━┫┣━┛   
              ╹┗╸┗━┛╹ ╹╺┻┛╹ ╹╹ ╹╹     
              
              

            - git basics, what is git capable of
            - what do to in what situations
            - project management
              - pull requests and feature branches
              - bug tracking
              - continuous integration
            - git gadgets (grep, bisect, etc.)  
################################################################################



              ┏┳┓┏━┓╻┏┓╻   ┏━┓┏━┓╻┏┓╻╺┳╸┏━┓
              ┃┃┃┣━┫┃┃┗┫   ┣━┛┃ ┃┃┃┗┫ ┃ ┗━┓
              ╹ ╹╹ ╹╹╹ ╹   ╹  ┗━┛╹╹ ╹ ╹ ┗━┛



            - Staging Area and 
            - Interactive Rebasing for well crafted commits,

            - Merging and Rebasing,

            - Pull Request workflow and
             
            - Git as inspection tool.



              
################################################################################



              ┏━╸╻╺┳╸   ┏┓ ┏━┓┏━┓╻┏━╸┏━┓
              ┃╺┓┃ ┃    ┣┻┓┣━┫┗━┓┃┃  ┗━┓
              ┗━┛╹ ╹    ┗━┛╹ ╹┗━┛╹┗━╸┗━┛



            - _distributed_ version control
            - staging area
              - git add, git reset, etc. instead of only commiting
            - branching
              - "killer feature"
            - content-addressable filesystem













################################################################################



              ┏━╸╻╺┳╸   ╻┏┓╻╻╺┳╸
              ┃╺┓┃ ┃    ┃┃┗┫┃ ┃ 
              ┗━┛╹ ╹    ╹╹ ╹╹ ╹ 



            Create or clone a repository via
            - $ git init
            - $ git clone

            Basic configuration:
            - $ git config --global user.name "Foo Bar"
            - $ git config --global user.email foobar@example.com

################################################################################



              ┏━┓╺┳╸┏━┓┏━╸╻┏┓╻┏━╸   ┏━┓┏━┓┏━╸┏━┓
              ┗━┓ ┃ ┣━┫┃╺┓┃┃┗┫┃╺┓   ┣━┫┣┳┛┣╸ ┣━┫
              ┗━┛ ╹ ╹ ╹┗━┛╹╹ ╹┗━┛   ╹ ╹╹┗╸┗━╸╹ ╹



            - first main difference to SVN
            - advantage of git

            Files can be: 

           ┌─────────┐   ┌──────────┐   ┌────────┐   ┌──────┐   ┌────────┐
           │Untracked│   │Unmodified│   │Modified│   │Staged│   │Commited│
           └─────────┘   └──────────┘   └────────┘   └──────┘   └────────┘

            Git manages these states as:

                       ┌─────────────────┐           ┌─────┐      ┌────┐
                       │Working Directory│           │Index│      │HEAD│
                       └─────────────────┘           └─────┘      └────┘
                         Your Sandbox               The proposed  The next 
                                                    next commit   parent  
################################################################################



              ┏━┓╺┳╸┏━┓┏━╸╻┏┓╻┏━╸   ┏━┓┏━┓┏━╸┏━┓
              ┗━┓ ┃ ┣━┫┃╺┓┃┃┗┫┃╺┓   ┣━┫┣┳┛┣╸ ┣━┫
              ┗━┛ ╹ ╹ ╹┗━┛╹╹ ╹┗━┛   ╹ ╹╹┗╸┗━╸╹ ╹



            - git add
            - git add --patch (-p) 
             - add individual lines (hunks) to commits
             - "interactive staging"
             - very useful to craft commits that are easy to understand
            - git restore --staged/--worktree
            - git reset --soft/--mixed/--hard
            - git rm --cached 
################################################################################



              ┏━┓╺┳╸┏━┓┏━╸╻┏┓╻┏━╸   ┏━┓┏━┓┏━╸┏━┓
              ┗━┓ ┃ ┣━┫┃╺┓┃┃┗┫┃╺┓   ┣━┫┣┳┛┣╸ ┣━┫
              ┗━┛ ╹ ╹ ╹┗━┛╹╹ ╹┗━┛   ╹ ╹╹┗╸┗━╸╹ ╹



            Check your modifications or what you are about to commit
            - git diff / git diff --staged

            Should help to have a clean process of commiting changes
            Finalizing step: git commit

            What if I messed up my current commit?
            - $ git commit --amend
################################################################################



              ┏━╸╻╺┳╸   ┏━┓┏┓  ┏┓┏━╸┏━╸╺┳╸┏━┓
              ┃╺┓┃ ┃    ┃ ┃┣┻┓  ┃┣╸ ┃   ┃ ┗━┓
              ┗━┛╹ ╹    ┗━┛┗━┛┗━┛┗━╸┗━╸ ╹ ┗━┛

        ┌────────────────┐    ┌──────────────────────┐main.c┌────┐
        │commit (b3aacfe)│───>│tree (think directory)│─────>│blob│ 
        └────────────────┘    └──────────────────────┘      └────┘
                | parent                              \
                v                                      \
        ┌────────────────┐    ┌──────────────────────┐  \
    ┌──>│commit (a21fh1a)│───>│         tree         │   \
    |   └────────────────┘    └──────────────────────┘    \
 ┌───┐                            /       |        \       \
 │tag│                        main.c    config.h  main.h    \
 └───┘                          /         |          \       \
                             ┌────┐     ┌────┐      ┌────┐<--° 
                             │blob│     │blob│<-┐   │blob│   | 
                             └────┘     └────┘   \  └────┘   |
                                                 └───────────┘
################################################################################



              ┏━┓┏━╸╻ ╻╻┏━┓╻┏━┓┏┓╻   ┏━┓┏━╸╻  ┏━╸┏━╸╺┳╸╻┏━┓┏┓╻
              ┣┳┛┣╸ ┃┏┛┃┗━┓┃┃ ┃┃┗┫   ┗━┓┣╸ ┃  ┣╸ ┃   ┃ ┃┃ ┃┃┗┫
              ╹┗╸┗━╸┗┛ ╹┗━┛╹┗━┛╹ ╹   ┗━┛┗━╸┗━╸┗━╸┗━╸ ╹ ╹┗━┛╹ ╹

        ┌────────────────┐ 
        │commit (b3aacfe)│
        └────────────────┘ 

            - $ git show <commit-ish> -- <glob-pattern>

            - commits are referencable via
              - their SHA1
              - HEAD
              - tags/branchnames
            
            - Syntax:
              - HEAD~<n> // select the n-th ancestor of HEAD
              - <commit-ish>..<commit-ish>

            - HEAD-history:
              - HEAD@{<n>}

################################################################################



              ┏┓ ┏━┓┏━┓┏┓╻┏━╸╻ ╻╻┏┓╻┏━╸
              ┣┻┓┣┳┛┣━┫┃┗┫┃  ┣━┫┃┃┗┫┃╺┓
              ┗━┛╹┗╸╹ ╹╹ ╹┗━╸╹ ╹╹╹ ╹┗━┛
              


            - git's "killer feature" 

            - A new branch is essentially just opening a new history
              (i.e. no copying involved!)

            - Highly encouraged to use many (shortlived) branches 

            Create a new branch with 
            - $ git switch --create/-c <branch-name>

################################################################################



              ┏┓ ┏━┓┏━┓┏┓╻┏━╸╻ ╻╻┏┓╻┏━╸
              ┣┻┓┣┳┛┣━┫┃┗┫┃  ┣━┫┃┃┗┫┃╺┓
              ┗━┛╹┗╸╹ ╹╹ ╹┗━╸╹ ╹╹╹ ╹┗━┛



            Switching between branches with
            - $ git switch <branch-name>
            - $ git switch - 

            Cannot switch if that would overwrite modifications

            Untracked files will simply "move along"
           
            Delete or rename a branch: 
            - $ git branch -d <branch-name>
            - $ git branch -m <oldbranch> <newbranch>
################################################################################



              ┏━╸╻╺┳╸   ┏━┓╺┳╸┏━┓┏━┓╻ ╻
              ┃╺┓┃ ┃    ┗━┓ ┃ ┣━┫┗━┓┣━┫
              ┗━┛╹ ╹    ┗━┛ ╹ ╹ ╹┗━┛╹ ╹



            Very helpful to quickly safe modifications 

            - $ git stash push --message/-m "..."
            - $ git stash list 
            - $ git stash apply/pop


################################################################################



              ┏━╸╻╺┳╸   ┏━┓╺┳╸┏━┓┏━┓╻ ╻
              ┃╺┓┃ ┃    ┗━┓ ┃ ┣━┫┗━┓┣━┫
              ┗━┛╹ ╹    ┗━┛ ╹ ╹ ╹┗━┛╹ ╹



              $ git stash push -m "WIP some frontend feature"
              $ git switch stable
              ...
              $ git commit
              $ git switch frontend_feature
              $ git stash pop
################################################################################



              ╻┏┓╻╺┳╸┏━╸┏━┓┏━┓┏━╸╺┳╸╻╻ ╻┏━╸   ┏━┓┏━╸┏┓ ┏━┓┏━┓╻┏┓╻┏━╸
              ┃┃┗┫ ┃ ┣╸ ┣┳┛┣━┫┃   ┃ ┃┃┏┛┣╸    ┣┳┛┣╸ ┣┻┓┣━┫┗━┓┃┃┗┫┃╺┓
              ╹╹ ╹ ╹ ┗━╸╹┗╸╹ ╹┗━╸ ╹ ╹┗┛ ┗━╸   ╹┗╸┗━╸┗━┛╹ ╹┗━┛╹╹ ╹┗━┛



            - $ git rebase -i <commit-ish>

            Can be used to cleanup commit history
            
            - allows to basically change the history of your commits
            - each project should have a guideline
              - small feature may for example be _squashed_ together 
              - WIP- or unnecessary commits can be removed 
              - remove _checkpoint commits_
               -> $ git rebase -i my_current_feature@{24.hours.ago}~1

################################################################################



              ╻┏┓╻╺┳╸┏━╸┏━┓┏━┓┏━╸╺┳╸╻╻ ╻┏━╸   ┏━┓┏━╸┏┓ ┏━┓┏━┓╻┏┓╻┏━╸   
              ┃┃┗┫ ┃ ┣╸ ┣┳┛┣━┫┃   ┃ ┃┃┏┛┣╸    ┣┳┛┣╸ ┣┻┓┣━┫┗━┓┃┃┗┫┃╺┓   
              ╹╹ ╹ ╹ ┗━╸╹┗╸╹ ╹┗━╸ ╹ ╹┗┛ ┗━╸   ╹┗╸┗━╸┗━┛╹ ╹┗━┛╹╹ ╹┗━┛   


            
            # Commands:
            # p, pick <commit> = use commit
            # r, reword <commit> = use commit, but edit the commit message
            # e, edit <commit> = use commit, but stop for amending
            # s, squash <commit> = use commit, but meld into previous commit
            # f, fixup <commit> = like "squash", but discard this commit's log message
            ...
            #
            # These lines can be re-ordered; they are executed from top to bottom.
            #
            # If you remove a line here THAT COMMIT WILL BE LOST.
            
################################################################################



              ┏━┓┏━╸┏┳┓┏━┓╺┳╸┏━╸┏━┓
              ┣┳┛┣╸ ┃┃┃┃ ┃ ┃ ┣╸ ┗━┓
              ╹┗╸┗━╸╹ ╹┗━┛ ╹ ┗━╸┗━┛



            Remote server to share code base

            - Gets setup with $ git clone 
            - $ git remote add <name> <url>

            - $ git fetch
            - $ git pull <remote> <branch>
            - $ git push <remote> <branch>
################################################################################



              ┏┳┓┏━╸┏━┓┏━╸╻┏┓╻┏━╸
              ┃┃┃┣╸ ┣┳┛┃╺┓┃┃┗┫┃╺┓
              ╹ ╹┗━╸╹┗╸┗━┛╹╹ ╹┗━┛



            Multiple parallel workflows are encouraged 
             -> unavoidable conflicts 
 
            - Project guideline on how to handle conflicts
           
            - For more advanced usage:
              - $ git rerere
              - different merging strategies
						 

################################################################################



              ┏┳┓┏━╸┏━┓┏━╸╻┏┓╻┏━╸         ┏━╸┏━╸
              ┃┃┃┣╸ ┣┳┛┃╺┓┃┃┗┫┃╺┓   ╺━╸   ┣╸ ┣╸ 
              ╹ ╹┗━╸╹┗╸┗━┛╹╹ ╹┗━┛         ╹  ╹  



            - _fast-forward_ merge possible if HEAD direct ancestor
            - This allows for a clean, linear history on stable branches
              - helps with git blame, git bisect, git rebase -i

            ┌─────────────────────────────────────────────────────────────┐
            │[spranger@gitWorkshop/stagingArea] git merge more_int_changes│
            │Updating eff74ed..a2c365a                                    │
            │Fast-forward                                                 │
            │ testfile1 | 4 ++--                                          │
            │  1 file changed, 2 insertions(+), 2 deletions(-)            │
            └─────────────────────────────────────────────────────────────┘

            - --ff, --no-ff, --ff-only
################################################################################



              ┏━┓┏━╸┏┓ ┏━┓┏━┓╻┏┓╻┏━╸   
              ┣┳┛┣╸ ┣┻┓┣━┫┗━┓┃┃┗┫┃╺┓   
              ╹┗╸┗━╸┗━┛╹ ╹┗━┛╹╹ ╹┗━┛   



            Allows to move bases of branches (and more)
            
            - Most common usage: Update the base of your branch if outdated
            - Common strategy to _always_ ensure fast-forward merges
            - Very helpful in complicated branching settings

            Important Note:
              ┌─────────────────────────────────────────────────────────┐
              │Do not rebase commits that exist outside your repository │
              │             and that people (may) have based work on.   │
              └─────────────────────────────────────────────────────────┘
################################################################################



              ┏━╸┏━┓┏┓╻┏━╸╻  ╻┏━╸╺┳╸┏━┓
              ┃  ┃ ┃┃┗┫┣╸ ┃  ┃┃   ┃ ┗━┓
              ┗━╸┗━┛╹ ╹╹  ┗━╸╹┗━╸ ╹ ┗━┛



            Git tracks (per hunk-) conflicts over three files:
              - base/common
              - ours
              - theirs

            - $ git config --global merge.conflictstyle diff3
              - Often helpful to have common state 


################################################################################



							┏━╸┏━┓┏┓╻┏━╸╻  ╻┏━╸╺┳╸┏━┓
							┃  ┃ ┃┃┗┫┣╸ ┃  ┃┃   ┃ ┗━┓
							┗━╸┗━┛╹ ╹╹  ┗━╸╹┗━╸ ╹ ┗━┛

            ┌────────────────────────┐ ┌────────────────────────┐
            │ #include <algorithms>  │ │ int main() {           │  				 
            │ <<<<<<< HEAD           │ │   int a = 5;           │   				 
            │  #include <sstream>    │ │ <<<<<<< HEAD           │   				 
            │ ||||||| 9275968        │ │   int b = 4;           │  				 
            │ =======                │ │ ||||||| 9275968        │ 				 
            │ #include <string>      │ │   int b = 8;           │ 				 
            │>>>>>>> new_feature     │ │ =======                │                                
            └────────────────────────┘ │   int b = 9;           │ 
                                       │ >>>>>>> new_feature    │
                                       └────────────────────────┘
						- Conflict markers appear in the file itself
						- Simplest way to handle: 
							-> directly modify the file	
            - Git difftool for visual conflict resolving
################################################################################



              ╺┳╸┏━╸┏━┓┏┳┓   ╻ ╻┏━┓┏━┓╻┏ ┏━╸╻  ┏━┓╻ ╻┏━┓
               ┃ ┣╸ ┣━┫┃┃┃   ┃╻┃┃ ┃┣┳┛┣┻┓┣╸ ┃  ┃ ┃┃╻┃┗━┓
               ╹ ┗━╸╹ ╹╹ ╹   ┗┻┛┗━┛╹┗╸╹ ╹╹  ┗━╸┗━┛┗┻┛┗━┛

            

            Team Workflows:
            - Merge vs. Rebase
              - Only fast-forward?
              - Keep merge commits?
           
            Branching Strategies: 
            - Main - Development - Feature branches - Stable branches
            - Main - Feature branches
            - etc.
################################################################################



              ┏━╸┏━┓╻  ╻  ┏━┓┏┓ ┏━┓┏━┓┏━┓╺┳╸╻┏━┓┏┓╻
              ┃  ┃ ┃┃  ┃  ┣━┫┣┻┓┃ ┃┣┳┛┣━┫ ┃ ┃┃ ┃┃┗┫
              ┗━╸┗━┛┗━╸┗━╸╹ ╹┗━┛┗━┛╹┗╸╹ ╹ ╹ ╹┗━┛╹ ╹



            Git usage in the bigger picture.

            - Issue tracking,
            - Pull Request handling,
            - Assigning work,
            - Milestones, Projects, etc.

            Example frontends:
            - GitHub
            - Gitlab
            - Gitea
            - Gogs

################################################################################



              ╻┏━┓┏━┓╻ ╻┏━╸   ╺┳╸┏━┓┏━┓┏━╸╻┏ ┏━╸┏━┓
              ┃┗━┓┗━┓┃ ┃┣╸     ┃ ┣┳┛┣━┫┃  ┣┻┓┣╸ ┣┳┛
              ╹┗━┛┗━┛┗━┛┗━╸    ╹ ╹┗╸╹ ╹┗━╸╹ ╹┗━╸╹┗╸



            - Note-tacking,
            - feature requests,
            - track bug reports from clients.

            - Use labels to categorize 
              - bug, good-first-issue, enhancement, etc.
            - Associate milestones and assignees

            An issue should eventually be turned into a pull request (PR).
################################################################################



              ┏━┓╻ ╻╻  ╻     ┏━┓┏━╸┏━┓╻ ╻┏━╸┏━┓╺┳╸┏━┓
              ┣━┛┃ ┃┃  ┃     ┣┳┛┣╸ ┃┓┃┃ ┃┣╸ ┗━┓ ┃ ┗━┓
              ╹  ┗━┛┗━╸┗━╸   ╹┗╸┗━╸┗┻┛┗━┛┗━╸┗━┛ ╹ ┗━┛



            At the heart of your team's workflow

            - Accompanies a branch
            - Gives the team
              - a plattform to discuss progress,
              - the branches history and
              - a list of all introduces changes.

            Project lead can review and ask for changes one a line-by-line basis

            Basis for Continuous Integration 
################################################################################



              ┏━╸┏━┓┏┓╻╻ ╻┏━╸┏┓╻╺┳╸╻┏━┓┏┓╻┏━┓╻     ┏━╸┏━┓┏┳┓┏┳┓╻╺┳╸┏━┓
              ┃  ┃ ┃┃┗┫┃┏┛┣╸ ┃┗┫ ┃ ┃┃ ┃┃┗┫┣━┫┃     ┃  ┃ ┃┃┃┃┃┃┃┃ ┃ ┗━┓
              ┗━╸┗━┛╹ ╹┗┛ ┗━╸╹ ╹ ╹ ╹┗━┛╹ ╹╹ ╹┗━╸   ┗━╸┗━┛╹ ╹╹ ╹╹ ╹ ┗━┛



            Syntax:
              ┌─────────────────────────────────────┐
              │<type>[optional scope]: <description>│
              │                                     │
              │[optional body]                      │
              │                                     │
              │[optional footer(s)]                 │
              └─────────────────────────────────────┘

            - They enable
              - automated CHANGELOGs and, 
              - automated semantic version bump and
            - greatly help with readability.
################################################################################



              ┏━╸┏━┓┏┓╻╻ ╻┏━╸┏┓╻╺┳╸╻┏━┓┏┓╻┏━┓╻     ┏━╸┏━┓┏┳┓┏┳┓╻╺┳╸┏━┓
              ┃  ┃ ┃┃┗┫┃┏┛┣╸ ┃┗┫ ┃ ┃┃ ┃┃┗┫┣━┫┃     ┃  ┃ ┃┃┃┃┃┃┃┃ ┃ ┗━┓
              ┗━╸┗━┛╹ ╹┗┛ ┗━╸╹ ╹ ╹ ╹┗━┛╹ ╹╹ ╹┗━╸   ┗━╸┗━┛╹ ╹╹ ╹╹ ╹ ┗━┛



            ┌──────────────────────────────────────────────────────────┐
            │feat: allow provided config object to extend other configs│
            │                                                          │
            │BREAKING CHANGE: `extends` key in config file is now      │
            │used for extending other config files                     │
            └──────────────────────────────────────────────────────────┘
################################################################################



              ┏┳┓╻┏━┓┏━╸┏━╸╻  ╻  ┏━┓┏┓╻┏━╸┏━┓╻ ╻┏━┓
              ┃┃┃┃┗━┓┃  ┣╸ ┃  ┃  ┣━┫┃┗┫┣╸ ┃ ┃┃ ┃┗━┓
              ╹ ╹╹┗━┛┗━╸┗━╸┗━╸┗━╸╹ ╹╹ ╹┗━╸┗━┛┗━┛┗━┛



            - Protect master branch
            - Repository setting for PRs help with team workflow
              - e.g. can be set to create merge commits.
################################################################################



              ┏━┓┏┓╻┏━┓╻  ╻ ╻┏━┓╻┏━┓         ╻┏┓╻┏━┓┏━┓┏━╸┏━╸╺┳╸╻┏━┓┏┓╻
              ┣━┫┃┗┫┣━┫┃  ┗┳┛┗━┓┃┗━┓   ╺━╸   ┃┃┗┫┗━┓┣━┛┣╸ ┃   ┃ ┃┃ ┃┃┗┫
              ╹ ╹╹ ╹╹ ╹┗━╸ ╹ ┗━┛╹┗━┛         ╹╹ ╹┗━┛╹  ┗━╸┗━╸ ╹ ╹┗━┛╹ ╹



            - Search through: code, modifications, commits or commit messages.
            - Look at history of lines of code
            - Binary search for bugs
            - List of most recent changes

            


################################################################################



              ┏━╸╻╺┳╸   ╻  ┏━┓┏━╸
              ┃╺┓┃ ┃    ┃  ┃ ┃┃╺┓
              ┗━┛╹ ╹    ┗━╸┗━┛┗━┛



            - $ git log
              - --patch, --after, --since, --before, --committer
              - -S"<search-pattern>"           // code
              - -L <start>,<end>:<filename>    // history of lines of code
              - -L :<function-name>:<filename> // history of a function
              - --grep "<search-pattern>"      // commit messages

            - $ git log --oneline
            - $ git log --graph

################################################################################



              ┏━╸╻╺┳╸   ┏┓ ╻  ┏━┓┏┳┓┏━╸
              ┃╺┓┃ ┃    ┣┻┓┃  ┣━┫┃┃┃┣╸ 
              ┗━┛╹ ╹    ┗━┛┗━╸╹ ╹╹ ╹┗━╸

						
						
						- $ git blame <filename>
            ┌────────────────────────────────────────────────────────────────┐
            │[spranger@gitWorkshop/stagingArea] git blame testfile1          │
            │2 days ago      Stefan  ^3b4a655│  1 │ #include <stdio.h>       │
            │                                │  2 │ #include <algorithms>    │
            │a day ago       Stefan  08b88afb│  3 │ #include <sstream>       │
            │2 days ago      Stefan  ^3b4a655│  4 │                          │
            │                                │  5 │ int main() {             │
            │3 hours ago     Stefan  a2c365ad│  6 │   int a = 1;             │
            │                                │  7 │   int b = 2;             │
            │2 days ago      Stefan  ^3b4a655│  8 │                          │
            │2 days ago      Stefan  a0bd6d8c│  9 │                          │
            │                                │ 10 │   return a+b;            │
            │2 days ago      Stefan  ^3b4a655│ 11 │ }                        │
            └────────────────────────────────────────────────────────────────┘



    


################################################################################



              ┏━╸╻╺┳╸   ┏━╸┏━┓┏━╸┏━┓
              ┃╺┓┃ ┃    ┃╺┓┣┳┛┣╸ ┣━┛
              ┗━┛╹ ╹    ┗━┛╹┗╸┗━╸╹  



            Powerful tool to search for code snippets

            - $ git grep "<search-pattern>"
              - -A <n>, -B <n>, -C <n>
              - --show-function/-p
              - --function-context/-W
################################################################################



              ┏━╸╻╺┳╸   ┏┓ ╻┏━┓┏━╸┏━╸╺┳╸
              ┃╺┓┃ ┃    ┣┻┓┃┗━┓┣╸ ┃   ┃ 
              ┗━┛╹ ╹    ┗━┛╹┗━┛┗━╸┗━╸ ╹ 



            Binary search to find commit that introduced a bug.

            ┌──────────────────────────────────────────┐
            │$ git bisect start                        │ 
            │$ git bisect bad <commit-ish>             │
            │$ git bisect good <commit-ish>            │
            └──────────────────────────────────────────┘
            
            ┌──────────────────────────────────────────┐
            │$ git bisect start HEAD HEAD~10 --        │
            │$ git bisect run make test                │
            │$ git bisect reset                        │
            └──────────────────────────────────────────┘
################################################################################



              ┏━┓┏━┓╺┳╸┏━╸╻ ╻╻┏┓╻┏━╸
              ┣━┛┣━┫ ┃ ┃  ┣━┫┃┃┗┫┃╺┓
              ╹  ╹ ╹ ╹ ┗━╸╹ ╹╹╹ ╹┗━┛


            
            - Revert already commited changes
            - Pick a range of commits from different branches
            - Turn a commit into a git-readable file
################################################################################



              ┏━╸╻╺┳╸   ┏━┓┏━╸╻ ╻┏━╸┏━┓╺┳╸
              ┃╺┓┃ ┃    ┣┳┛┣╸ ┃┏┛┣╸ ┣┳┛ ┃ 
              ┗━┛╹ ╹    ╹┗╸┗━╸┗┛ ┗━╸╹┗╸ ╹ 



            Revert commits via new commits

            - Should be used when the commits are already public 

            - $ git revert <commit-ish>.. 
################################################################################



              ┏━╸╻╺┳╸   ┏━╸╻ ╻┏━╸┏━┓┏━┓╻ ╻   ┏━┓╻┏━╸╻┏ 
              ┃╺┓┃ ┃    ┃  ┣━┫┣╸ ┣┳┛┣┳┛┗┳┛╺━╸┣━┛┃┃  ┣┻┓
              ┗━┛╹ ╹    ┗━╸╹ ╹┗━╸╹┗╸╹┗╸ ╹    ╹  ╹┗━╸╹ ╹



            Specify commits and apply them onto your HEAD

            - $ git cherry-pick <commit-ish>..

            - $ git cherry-pick ..master
              - essentially the same as $ git rebase master

            - Useful if e.g. a hotfix has been pushed to a stable branch
            - Might need to clean such commits before merging
            

################################################################################



              ┏━╸┏━┓┏━┓┏┳┓┏━┓╺┳╸   ┏━┓┏━┓╺┳╸┏━╸╻ ╻   ┏┓     ┏━┓┏━┓┏━┓╻  ╻ ╻
              ┣╸ ┃ ┃┣┳┛┃┃┃┣━┫ ┃ ╺━╸┣━┛┣━┫ ┃ ┃  ┣━┫   ┃╺╋╸   ┣━┫┣━┛┣━┛┃  ┗┳┛
              ╹  ┗━┛╹┗╸╹ ╹╹ ╹ ╹    ╹  ╹ ╹ ╹ ┗━╸╹ ╹   ┗━┛    ╹ ╹╹  ╹  ┗━╸ ╹ 



            In certain situations it might be sensible to send commits per mail

            - $ git format-patch -1 <commit-ish>
            - colleague does not need to checkout your branch

            - $ git apply <filename>
################################################################################



              ┏┳┓┏━┓┏━┓┏━╸   ┏━┓┏┓╻╺┳┓   ┏┳┓┏━┓┏━┓┏━╸
              ┃┃┃┃ ┃┣┳┛┣╸    ┣━┫┃┗┫ ┃┃   ┃┃┃┃ ┃┣┳┛┣╸ 
              ╹ ╹┗━┛╹┗╸┗━╸   ╹ ╹╹ ╹╺┻┛   ╹ ╹┗━┛╹┗╸┗━╸



            - git notes,
            - commit signing,
            - merge strategies,
            - git worktree,
            - refs,
            - git reflog,
            - porcelain commands and scripting,
            - the power of .gitconfig,
            - hooks on the server,
            - multiple remotes,
            - etc.