Git Workshop

CodeHub Bristol

13 October 2016

Katja Durrani

David Moody

Fundamental Git Workflow

also called Index

Lifecycle of a File

= Index!

(also --cached)

Basic commands


git init              # initiate a git repository inside the current project

git add .             # add all files in the working directory to the staging area

git commit -m "message"    # commit all the files in the staging area           

git commit -a -m "message"     # this combines adding all TRACKED files to the 
                               # staging area and committing them       

git rm                        # remove a file from the Index and from disk
                              # might need -f flag, if file has been changed
                              
git rm --cached               # remove a file only from the staging area/index,
                              # not from disk

git add -A                    # add everything in the working directory, including 
                              # deletion of files, to the staging area

git add -p                    # Add patches of code individually 
                              # ("Stage this hunk [y,n,q,a,d,/,e,?]?")

git status                    # show staged, tracked and untracked files

# Also consider starting a .gitignore file, or perhaps you have a default .gitignore 
# file ready

The HEAD

HEAD is a reference to the current commit.

 

This can be either indirectly through a symbolic reference (for example refs/heads/master) pointing to the commit at the tip of a branch

 

-- or it can point directly to a commit. In that case the HEAD is in detached state. 

What does this mean?

git diff HEAD..HEAD~5

Finding your way round

  • Log
  • Diff

Git log


git log --oneline     # info on each commit abbreviated to one line

git log -n 4          # display only the last 4 commits

git log --all --graph --decorate --oneline      # nice graphical display of all 
                                                # branches and their heads
                                                # put it in an alias!

Git diff


git diff                 # show what's in WORKING DIRECTORY compared to INDEX

git diff --cached        # what's in INDEX compared to HEAD

git diff HEAD            # what's in WORKING DIRECTORY + INDEX compared to HEAD

git diff HEAD~3..HEAD   # shows diffs that are in the right hand commit 
                         # compared to the commit on the left

You can set a difftool (like meld, kdiff3) in the config, then use 'difftool' in your command instead of 'diff' to open it

untracked

modified

staged

git diff

git diff --cached

HEAD

git diff HEAD

= last commit

Git diff

Undoing changes

  • Revert
  • Reset
  • Using Reflog

Revert <commit>

=> undo the changes

introduced by that

commit, by doing the

reverse (creates extra

commit)

Reset <commit>

untracked

modified

staged

=> go back to the state things where at that commit;

depending on flags,

the Index and/or modified files are kept

Use reset when you want to make changes to your most recent commit:


git reset --soft HEAD^     # leaves the working directory and Index as it is
                           # but sets HEAD back by one commit

# If you want to correct your last commit you can also do this:
git commit --amend -m "<new message>"

You can also reset to several commits earlier (for example, create a branch from commits, set master to earlier stage)


git branch topic/wip   
git reset --hard HEAD~3  
git checkout topic/wip 

Undo a merge like this:

 


git reset --hard ORIG_HEAD 

What if I have accidentally dropped a commit?


git reflog

Use Reflog


git checkout HEAD@{11}

# to check what is in a commit 
git show HEAD@{11}

Moving things around

  • Branch
  • Merge
  • Rebase
  • Cherry-pick
  • Stash

Branches


git branch my_branch <start-point>
git checkout my_branch

# Shorter
git checkout -b my_branch




You can branch off from a different commit or branch than you are on!


git merge feature

# Delete the feature branch
git branch -d feature

Merging - Fast-forward

Merging - Three-way merge

Text

Rebasing!

Rebasing allows us to keep a linear history of a project. 


git rebase <new-base>

Move the current branch’s commits to the tip of <new-base>, which can be either a branch name or a commit ID.

Rebasing

Perform an interactive rebase and select actions for each commit.


git rebase --continue          # Continue a rebase after amending a commit.

git rebase --abort         # Abandon the current interactive rebase and return the 
                           # repository to its former state.

Continue or abort an interactive rebase


git rebase -i <new-base>

Interactive rebasing allows you to edit, move around, add and delete commits very flexibly

If we want to apply just a single commit to our current branch we can cherry-pick! It's also possible to cherry-pick a number of commits at once.

Cherry-pick


git cherry-pick <commit>

Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. 

Stash


git stash <save> -m "message"
git pop                            # to apply and remove from stack
git stash --keep-index             # keep Index intact
git stash -u                       # include untracked files!
git stash list                     # list all stashes

# ... hack hack hack ...
$ git stash
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git stash pop
# ... continue hacking ...

# ... hack hack hack ...
git checkout -b my_wip
git commit -a -m "WIP"
git checkout master
# edit emergency fix
git commit -a -m "Fix in a hurry"
git checkout my_wip
git reset --soft HEAD^
# ... continue hacking ...

Stash example

Interrupted workflow to make a hotfix, the traditional way

Using stashing

Working with Remotes

  • Clone
  • Remote
  • Fetch
  • Pull
  • Push

git remote -v

git remote add upstream https://github.com/user/repo.git

Check what remotes are present, add a remote


git fetch origin <newbranch>
git checkout -b <newbranch> origin/<newbranch>

How to fetch a recently added branch from the remote

If upstream and your local branch have diverged, do this:


git pull --rebase

Never use git push -f  !

Now to the interactive part..

git clone https://github.com/CodeHubOrg/gitworkshop.git

What is your favourite Git command?

Some useful links

Tutorials

Git-it  https://github.com/jlord/git-it

Pro Git book https://git-scm.com/book/en/v2

Ry's Git tutorial http://rypress.com/tutorials/git/index


Tips and Tricks

David's Dot files (check gitconfig and bashrc!)

https://github.com/davidxmoody/dotfiles/tree/master/dotfiles

Git-Fu by Jeff Schomay http://slides.com/jschomay/git-fu#/

Oh, shit, git http://ohshitgit.com/

Git tips http://www.integralist.co.uk/posts/git-tips.html


Just beautiful 'The sound of the source' https://github.audio/

CodeHub Git Workshop Oct 2016

By Katja Durrani

CodeHub Git Workshop Oct 2016

At Momentum Offices

  • 1,337