<aside> 💡 I also created my own git which is documented here.

</aside>

Introduction

We have three kinds of Version Control System:

Git Workflow

In git we are working with three different areas:

Untitled

Basic Git

# Git wants to know who it should write as the committer of changes etc.
git config --global user.name "John Doe"
git config --global user.email "[email protected]"
git config --local user.name "Repo-level Username"          
git config --local user.email "[email protected]" 
# --global -> User level git config stored in <user-home>/.gitconfig for e.g. ~/.gitconfig
# --local -> repo level config stored in repo's main dir under .git/config

# Sometimes Git needs you to edit a file it creates e.g. the message of a commit you create. As default, Git is configured with VIM but can be changed
# Configuring a different editor
git config --global core.editor nano
git config --global core.editor notepad
git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
git config --global core.editor "atom --wait"
git config --global core.editor "code --wait"

# It's possible to make aliases of frequently used commands this is often done to make a command shorter, or to add default flags
# You can set up aliases as such
git config --global alias.lol 'log --oneline --graph --all'

# General Structure of changing the config
git config --local <setting> <value>

# SSH authentication
# Step 1: run `ssh-keygen` to generate a SSH key pair which generates public/private keys named `id_rsa.pub`/`id_rsa`, respectively in `%USERPROFILE%/.ssh/`
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# Step 2: The public key `id_rsa.pub` needs to be uploaded to your repo server and then SSH authentication for that device is enables.

# Cloning a repository
git clone <https://github.com/praqma-training/git-katas.git>      # Clone this repository to your current working directory

# Initializing an empty git repository.
git init            # Initialize an empty git repository under current directory.

# See local changes
git status                  # Show the working tree status
git diff                    # Show changes current working directory (not yet staged)
git diff --cached           # Show changes currently staged for commit

# Staging area (before a commit)
git add myfile.txt          # Add myfile.txt to stage
git add .                   # Add entire working directory to stage
git reset <file>                        # Unstage a staged file leaving in working directory without losing any changes.
git reset --soft [commit_hash]          # resets the current branch to <commit>. Does not touch the staging area or the working tree at all.
                                        # --hard mode would discard all changes.

# Make a commit (Taking a snapshot)
git commit                              # Make a new commit with the changes in your staging area. This will open an editor for a commit message.
git commit -m "I love documentation"    # Make a new commit with a commit message from the command line
git commit -a                           # Make a new commit and automatically "add" changes from all known files
git commit -am "I still do!"            # A combination of the above
git commit --amend                      # Re-do the commit message of the previous commit (don't do this after pushing!)
                                        #   We _never_ change "public history"

# See history
git log             # Show commit logs
git log --oneline   # Formats commits to a single line (shorthand for --pretty=oneline  --abbrev-commit )
git log --graph     # Show a graph commits and branches
git log --pretty=fuller     # To see commit log details with author and committer details, if any different.
git log --follow <file>     # List the history of a file beyond renames
git log branch2..branch1    # Show commits reachable from branch1 but not from branch2

# Working with Branches
git branch my-branch       # Create a new branch called my-branch
git switch my-branch     # Switch to a different branch to work on it
git switch -c my-branch  # Create a new branch called my-branch AND switch to it
git branch -d my-branch    # Delete branch my-branch that has been merged with master
git branch -D my-branch    # Forcefully delete a branch my-branch that hasn't been merged to master

# Merging
git merge master         # Merge the master branch into your currently checked out branch.
git rebase master        # Rebase current branch on top of master branch

# Deferring
git stash                               # Stash (store temporarily) changes in working branch and enable checkingout a new branch
git stash list                          # List stored stashes.
git stash apply <stash>                 # Apply given <stash>, or if none given the latest from stash list.

# Working with Remotes
git remote              # Show your current remotes
git remote -v           # Show your current remotes and their URLs
git push                # Publish your commits to the upstream master of your currently checked out branch
git push -u origin my-branch  # Push newly created branch to remote repo setting up to track remote branch from origin.
                              # No need to specify remote branch name, for e.g., when doing a 'git pull' on that branch.
git pull                # Pull changes from the remote to your currently checked out branch

# Re/moving files under version control
git rm <path/to/the/file>                 # remove file and stage the change to be committed.
git mv <source/file> <destination/file>   # move/rename file and stage the change to be committed.

Seven rules of a great Git commit message

A well-crafted Git commit message is the best way to communicate context about a change to fellow developers (and indeed to their future selves).

A diff will tell you what changed, but only the commit message can properly tell you why.

In order to create a useful revision history, teams should first agree on a commit message convention that defines at least the following three things:

Separate subject from body with a blank line

Limit the subject line to 50 characters