Git Commands

git config --global user.name "yourname"
git config --global email "email"

Identify yourself


Git init
Initialised a git repository in our local folder. This is to make sure that when we push it to the remote git. Whatever is inside this folder is push into the remote repository. Vice versa for local pull.
ls -a 
to check

git status
check the status of your repository

git add <name of file>
Step one of attempting to send to repository
This is to
Chaining is allowed.
Use touch <filename> to create a file
Use git add -A to add everything or git add . 

git commit -m "your changes notes here"
Step two of attempting to send to repository
use git commit -a to commit everything

git log
History of commits made

git checkout <hash>
To rollback to the previous commit
use git log to find the hash
use branch name as hashto be able to roll back to another branch


git branch <branchname>
To create a copy for experimental purposes/changes that not sure if to commit
using git branch  will list the branches

git merge <branchname>
Merge my branch with the master


GITHUB Commands

This is for collaboration between multiple people to work on the same repositories.

git config --global credential.helper store
To set up credential

git remote -v
List out the list

git remote add <githubplace> <link to repo>
To set up an remote
githubplace can be anything

git push -u <githubplace> <branchname>
Ensure that a local repository exist first.
Push a file to a remote server under master branch,
- to backup
- Allow other people to clone

git pull <githubplace> master
To update the changes made by other user

git checkout -b <branchname>
Creates a new branch

git show <commitid>
show the git commit id

Git clone <link>
Do not clone to an existing repository
Use fork for open sources code and clone your fork
Click on "pull request" to request to change original code




PRO GIT (Chap 1-3)

A guide for retards - says TA

Getting started - Version Control

A system that records changes to a file or set of files over time so that we can recall specific version later

- Revert selected files back to prev state
- Revert entire project to prev state
- Compare changes over time
- See who last modified something that might be causing a probelm
- Who introduce a issue, when 
etc..

Local Version Control Systems

- Prevent error when copying files to another directory
- Previous VCS tools is called RCS
   - Keep patch sets on disk
   - Recreate what any file look like at a point in time by adding patches

Centralised version control systems

- CVCS
- To help with collaboration with developers
- Have a server that contains all version files
- Clients check out files from that central place

Advantages
- Everyone knows what everyone else is doing
- Admins have control on who can do what
- Easier to adminster compared to dealing with a local database

Disadvantages
- If server goes down, no one can collaborate or save anything
- If harddisk on central become corrupted and no proper backup, all files lost except things on local

Distributed version control system

- DVCS
- Client fully mirror the repository and its histroy
- If server dies, client repo can be copy back up to restore (clone_
- Collabe with ppl simulataneously within same projects
- Set up several types of workflow that are not possible in CVCS

A short history

- Linux used to use a DVC called bitkeeper
- Bitkeeper become not free in 2005
- Linus, creator of Linux, decided to make new system

System goals:
- Speed
- Simple
- Strong support for non linear development (thousand of parallel branches)
- Fully distributed
- Able to handle large projects efficiently

Thus git is borned

Getting started - What is git?

- Git stores and thinks about information in way different to others VCS
- Same interface

Snapshot, not differences


Differences between git and other VCS
- The way it think about it's data
- Other system store info as a list of file based changes (Delta based version control)
- git thinks of data as a series of snapshots or minature filesystem
- git takes a picture of what files look like at that moment and store a reference to that snapshot
- git thinks about its data like a stream of snapshots


Nearly every operation is local

- Git operation only need local files and resources
Even to see changes introduce between current version of file and file a month ago
- There is little you can do if you are offline on off VPN

Git has Integrity

- Everything in git is checksummed before stored
- Impossible to change contents of file or directory without git knowing
- No lost of information in transit or file corruption without git being able to detect
- git uses SHA-1 hash for checksumming

Git generally only adds data

- only add data to git database
- Hard to undo anything or erase
- Difficult to lose repo
- We can experiment our code without worries

The three states

- Modified: Change file but not commited to database
- Staged: Marked a modified file in its current version to go into next commit snapshot
- Committed: data is safely stored in your local database

Git workflow:
1. Modified files in working tree
2. Selectively stage just those changes to be part of next commit which adds only those changes to staging area
3. Do a commit, takes every files in staging area and stores that snapshot permanently into git directory

If a file is in git director, it is commited
If it is modified and added to staging area, it is staged
If it was changed since it was checked out but has not been stage, it is modified


Getting started - The command Line and install guide


- All git commands is run using CL

Install guide: here
Git config: here

Git help:
$ git help <verb>
$ git <verb> --help
$ man git-<verb>
$ git help config
$ git add -h
usage: git add [<options>] [--] <pathspec>...

-n, --dry-run dry run
-v, --verbose be verbose

-i, --interactive interactive picking
-p, --patch select hunks interactively
-e, --edit edit current diff and apply
-f, --force allow adding otherwise ignored files
-u, --update update tracked files
--renormalize renormalize EOL of tracked files (implies -u)
-N, --intent-to-add record only the fact that the path will be added later
-A, --all add changes from all tracked and untracked files
--ignore-removal ignore paths removed in the working tree (same as --no-all)
--refresh don't add, only refresh the index
--ignore-errors just skip files which cannot be added because of errors
--ignore-missing check if - even missing - files are ignored in dry run
--chmod (+|-)x override the executable bit of the listed files


Git Basics - Getting a repo

1. Local directory that is not under version control
2. Clone existing

Initialising a repo in existing directory

- Go to the directory for the repo in local

for Linux:
$ cd /home/user/my_project
for macOS:
$ cd /Users/user/my_project
for Windows:
$ cd /c/user/my_project
and type:
$ git init

- This creates a subdirectory named .git
- Contains all repo files
- Nothing is tracked yet

- Do intial commit

$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'

Cloning existing Repo

- git clone <url>
$ git clone https://github.com/libgit2/libgit2
- Clone repo into a director named other than libgit2
$ git clone https://github.com/libgit2/libgit2 mylibgit

GIT Basics - Recording Changes to the Repo

- Files can either be tracked/Untracked
- Tracked files can be unmodified/modified/staged
- Cloned repo files are all tracked and unmodified

Check status of files

- git status
- Check the status of the directory

Clean working director:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Untracked file exist:
$ echo 'My Project' > README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)

README

nothing added to commit but untracked files present (use "git add" to track)

Readme is the untracekd file.

Tracking new files

- git add

Tracking Readme file
$ git add README

Checking status of Readme file
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)

new file: README

Changes to be committed heading show that it is staged

Staging modified files

If a git status look like this:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file: README

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: CONTRIBUTING.md

- A tracked file has been modified but not yet stage
- Use git add to add it and run git status again
$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file: README
modified: CONTRIBUTING.md
If we modifed the contributing file again, have to run git add again to stage latest version

Short status

$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt

?? = new files that are not tracked
A = new files in staging area 
M = modified
MM = modified, staged and modified again

Ignoring files

- Files that do not want git to auto add or even show being untracked
- Create file listing patterns to match using .gitignore

Rules:
1) Blank lines or lines with # are ignored
2) Standard glob pattern work 
3) Start pattern with a forward slash (/) to avoid recusivitiy
4) End pattern with (/) to specify directory
5) negate a pattern by using (!)
6) glob patterns are similiar to regex

Viewing staged and unstaged changes

- git diff
- shows exact lines added and removed
- use (git diff -- staged) to show staged changes to last commit

Committing changes

- Unstaged files can't be committed
- Use git commit
- Using -m flag can specify commit message
example
$ git commit -m "Story 182: Fix benchmarks for speed"

Skipping the staging area

- add the -a flag to git commit to auto stage every file tracked 
- Skips the git add

Removing files

- git rm
- also removes it from working directory
- git rm stages the file removal
- Use the -f to force remove if the file is in staging area

Moving Files

- git mv file_from file_to

Git Basics - Viewing the commit history

- git log
- Shows commits in reverse chrono
- Most recent show first
- Date, email and author's name
- Adding -p show difference in patch
Table 2. Common options to git log
OptionDescription
-p
Show the patch introduced with each commit.
--stat
Show statistics for files modified in each commit.
--shortstat
Display only the changed/insertions/deletions line from the --stat command.
--name-only
Show the list of files modified after the commit information.
--name-status
Show the list of files affected with added/modified/deleted information as well.
--abbrev-commit
Show only the first few characters of the SHA-1 checksum instead of all 40.
--relative-date
Display the date in a relative format (for example, “2 weeks ago”) instead of using the full date format.
--graph
Display an ASCII graph of the branch and merge history beside the log output.
--pretty
Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own format).
--oneline
Shorthand for --pretty=oneline --abbrev-commit used together.
- using  --stat option shows the abbreviated stats for each commit
- using --pretty change log output to formats other than default
Pretty option:
1) oneline
2) short
3) full
4) fuller

Others:
OptionDescription of Output
%H
Commit hash
%h
Abbreviated commit hash
%T
Tree hash
%t
Abbreviated tree hash
%P
Parent hashes
%p
Abbreviated parent hashes
%an
Author name
%ae
Author email
%ad
Author date (format respects the --date=option)
%ar
Author date, relative
%cn
Committer name
%ce
Committer email
%cd
Committer date
%cr
Committer date, relative
%s
Subject

Limiting Log output

- show only subset of commits
- using -<n> ,where n is number of commits to be shown
-  using --since = date or --until=date
- using --author 

Git basics - Undoing things

- git commit --amend
- To redo the commit
- Do this after adding a new file

Unstaging a stage file

- git reset HEAD <file> 
- use to unstage
- in case add wrong file to stage

Unmodifying a Modified file

- git checkout --<file>
- Discard changes in working directory

Git Basics - Working with remotes

- Managing remote repo
- Hosted online or network
- Collaboration
- pulling data to and from them to share work

Showing remotes

- git remote
- list all the remotes the repo is connected
- Clone repo will have origin
- specifying -v show url

Adding remote repo

- git remote add <shortname> <url>
- origin is like a short name
- can use the shortname to fetch
- git fetch pb
- this will fetch info not in repo yet

Fetching and pulling from remotes

- git fetch <remote>
- pulls down all data from remote project
- References all the branches from that remote
- git pill also auto fetch and merge remote branch to current

Pushing to remotes

- git push origin master
- Pushing code to origin at branch master
- Works if cloned from server with access
- Must fetch other people work first before pushing

Inspect a remote

- git remote show <remote>
- info about a particular remote
- list url

Renaming and removing remotes

- git remote rename <oldname> <newname>
- Changes all remote tracking branch names

Git Basics - Tagging

- Marks stages

Listing your tags

-git tag 
- list tags

Creating tags

- Tags are lightweight/annotated
- Tags are like branch and do not change
- It is a pointer to a commit
- They are checkedsummed
- Contain tagger name, email and date

Annotated Tag

- specify -a flag
- git launches editor to type message

Lightweight tag

- Commit checksum stored in file
- Do not use any -a, -s, -m option

Sharing tag

- git push origin <tagname>
- transfer tags to remote
- similiar to sharing remote branches

Deleting tags

- git tag -d <tagname>
- Delete tag on local
- Remove the tag from the local rather than local

Checking out Tags

- git checkout
- View version of files a tag is pointting to.
- Puts repo in detached head state

Git Alisa

here


Git branching - branches in a nutshell

- Diverge from main line of development and continue to do work
- Do not mess code 
- Switching between branches is very fast
- stores a series of snapshots
- pointer to snap shop of content created
- object contain author names and email

Creating a new branch

- git branch <branchname>
- Creates a new pointer to move around
- HEAD is a special pointer that you are currently on
- git log can see where branch pointers are pointing

Switching Branches

- git checkout <branchname>
- This moves HEAD to point to the <branchname> branch
- git commiting will move the HEAD forward but master branch will still point to the original commit where git checkout was last ran
- git checkout master
to go back to master branch

Git branching - Basic Branching and Merging

Merging the branch:
- Do some work on website
- Create a branch for a new user story you're working on
- DO some work on the branch

There will be a critical issue and need to hotfix:
- Switch to production branch
- Create branch to add hotfix
- After tested, merge the hotfic branch and push to production
- Switch back to original user story and continue working

Basic Branching

- commits already on master
- New branch was created with -b switch
this is short for:
git branch newbranch
git checkout newbranch

- Switching back to master branch reverts the changes done
- git wont let you switch branch if your current directory or staging area has uncommited changes that conflict with the branch you are checking out
-Commit all the changes
git checkout master
= this switch back to master branch
- git resets director to look like it did the last time you commited on that branch

git merge <branchname>
= merge the branch with the current branch
e.g
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)

- git just move pointer forward because there is no divergent work to merge together, this is called fastforward

- git branch -d hotfix
= deletes the branch hotfix
- files changed in hotfix should not be the same as files in other branches

Basic merging

- Assume issue 53 on branch iss53 is complete and ready to be merge into master
- Checkout the branch 
- merge
e.g 
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)

- this is different from hotfix as the commit on the branch is not a direct ancestor of the branch we are merging in
- git does a 3 way merge, use two snapshots pointed to by the branch tips and common ancestor of the two
- git creates a new snapshot that results from the 3 way mege and auto creates a new commit
- this is merge commit
- it has more than one parent
- delete the branch once the branch has been merged

Basic merge conflicts

- sometimes process does not go smoothly
- same part of the same file is changed
- git cant merge cleanly
e.g of merge conflict
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
- git has paused the process for you to resolve the conflict
- run git status to see which files are unmerge at any point after merge conflict

e.g conflict in file
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
- HEAD (master branch) is the top part of that block (above ======)
- Version in the branch is everything at the bottom
- Resolve conflict either choose one side or the other or merge contents yourself

e.g solving merge conflict
<div id="footer">
please contact us at email.support@github.com
</div>
- Replacing the entire block
- <<<<<<, ======== and >>>>>>>> lines have been removed
- run git add one each file to mark as resolved
- git mergetool
= using a graphical tool to resolve issues, fires an appropriate visual merge tool
- git uses opendiff in default(mac)
-git ask if merge successful after exit mergetool
- git status to see if conflict is resolve
- git commit to finalise merge commit

Git branching - Branch management

- git branch can list branches
- * charter indicates the branch that you have currently check out (the HEAD is pointing to)
- git branch -v
= shows the last commit on each branch
- --merged / --no-merged option to filter branches shown
- branches with no * is safe to delete with git branch -d if you have already merge it
- attempt to delete unmerge branches will fail
- -D will force delete

Git Branching - Workflows

Long running branches

- git use 3 way merge
- can have several branches that are open 
- can merge regularly from some to others
- many developers use code that is entirely stable in master branch
- paralllel branch to test stability
- merge only when stable
- this is to ensure that they do not introduce bugs
- branches are pointers to commits
- different branches can have different levels of stability

Topic Branches

- short lived branch for a single particular feature
- common to delete, merge and work on multiple branches
- use topic branch to incorporate features that is not yet confirmed that you want to include in your project
e.g dumbidea
- branches are local

Git branching - remote branches

- git ls-remote <remote>
= list of remote references
- git remote show <remote>
= more info on specific remote branch

-remote tracking branches are references to state of remote branches
- local references
- git moves for you when do any network communication
- Bookmarks
- sometimes after cloning from repo, someone might have update it
- git fetch <remote>
= fetch any data that do not have and updates local database
- moves the pointer to up to data position
- git fetch updates remote tracking branches

Pushing

- Sharing a branch
- local branches are not auto sync with remote
- git push <remote> <branchname>
= pushes the branch to the remote
git push <remote> <mybranch>:<repobranch_that_you_want_replace>
= changes the branch on the repo that is named differently/exist before
-git merge <remote>/<branchname>
= merge the work with my current working branch

e.g Wanting own serverfix branch to work on that is base off remote trackign branch
$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

Tracking branches

-Checking out a local branch from remote auto creats tracking branch
- local branch with direct relationship with remote branch
- on tracking branch, git pull will let git know which server to fetch from and which branch to merge
- cloning a repo auto gen a master branch that tracks <remote>/master
- git checkout --track  <remote>/<branch> tracks remote branch

e.g git create tracking branch
$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

e,g set up local branch with different name
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'
- sf will auto pull from origin/serverfix

e.g setting local branch to a remote branch that was just pull/ change upstream branch you are tracking
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
- use -vv option to git branch to see tracking branches that was set up

e.g Fetch from all remotes to total up to date ahead 
$ git fetch --all; git branch -vv

Pulling

- fit fetch will not modify working direcory
- just get data and let you merge urself
- git pull is a git fetch + git merge
- git pull look up what server and branch your current branch is tracking,
fetch from that server and try merge into that remote branch

Deleting remote branches

- use --delete option to git push

e.g deleting serverfix on remote
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
- [deleted] serverfix
- remove the pointer from the server
- you can recover if it is wrongly deleted

Git Branching - Rebaseing

- integrating one branch to another

The basic rebase

- merge is the easiest 3 way merge between two latest branch snapshots and the most recent common ancestor
- rebase can be use to take all changes on one branch and replay them on another branch

e.g Checkout experiement branch and rebase to master
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
- goes to common ancestor of two branchs (urs and to be rebase branch)
- get diff in commits of the branch you are on
- Save diff in temp files
- reset current branch to the same commit as the branch that is rebasing
- appluing each change in turn

e.g Go back to msater and fast forward merge
$ git checkout master
$ git merge experiment

- rebases makes cleaner history

Interesting rebases

e.g Merge client side changes to mainline for a release but hold off the server-side changes until it's tested further. => Take changes on client that aren't on server and replay them on you master branch but using the --onto option of git rebase:
$ git rebase --onto master server client

- takes client branch
- figures out patches since diverge from server branch
- replay patches in client as if based direclty of the master branch

e.g Fast forward master branch to include client branch changes
$ git checkout master
$ git merge client

e.g Pull in server branch: rebase server branch onto the master branch without having to check it out first by running 
$ git rebase master server
- checks out topic branch
- replace onto base branch

Rebasing server branch ontop of master branch
$ git checkout master
$ git merge server

Removing client and server branches 
$ git branch -d client
$ git branch -d server

Perils of rebasing

- Do not rebase commits that exist outside repo and that people may have based work on
- rebasing abandon existing commits and creates new one (duplicates)
- collab have to remerge their work and things will be messy if pull their work back to yours

Rebase when you rebase

- If someone done this, check patch-id to figure out which is yours
- git auto calculate checksum 
- Do not rebase commits that have been pushed publicly

Rebase only
- commits that pushed but no one based those commits from
- commits that have not left local

Rebased vs Merge

-Repo commit history is a record of what actually happen
-Commit history is also the story of how project was made
- Rebase and filter-branch is used to tell the story in the way that best for future readers
- Rebase local changes but haven shared before push them
- Never rebase anything pushed somewhere