Skip to content

Instantly share code, notes, and snippets.

@isao
Last active August 29, 2015 14:22
Show Gist options
  • Save isao/b234a961c9995270576d to your computer and use it in GitHub Desktop.
Save isao/b234a961c9995270576d to your computer and use it in GitHub Desktop.
git intro brown bag reveal.js slide deck

Git Intro

June 9, 2015

Isao Yagi <[email protected]>

A Brief History

Early version control

  • local
  • file at a time
  • locks

Note: RCS, SCCS. Conceptually they're patching tools.

2nd generation

  • central server
  • multi-file
  • merge before commit

Note: SVN, TFS: Conceptually they're meta filesystems. Path-based branching.

3rd generation

  • distributed
  • change sets
  • commit before merge

Note: Git, Darcs, Bz, Hg.

Because they're distributed...

  • Developer's changes are kept distinct from the merge(s) they had to do to get there.
  • DVCs handle more complex histories, new merging (and re-merging) scenarios, finding common ancestor...
  • DVCs deal with whole trees. Path names are independent of the "branch".

Under the hood

Conceptual Model

Git history is a directed acyclic graph (DAG) of changes, whose nodes have globally unique identifiers.

It all made sense after I realized git is a graph manipulation tool. --paraphrased from somebody on twitter

Note: Apologies if that sounds like gibberish. There's a video of someone explaining git with tinker toys that is awesome. A good presenter would have included diagrams at least, but I'll cover the terms you will see in the docs.

Implementation

  • the repo is a graph (DAG)
  • the nodes are commit objects
  • commit objects contain these objects:
    • a tree object
      • blob object(s)
      • possibly other tree object(s)

Note: tree object stores file paths, file names, permissions. Blobs contain data. Each object is referenced internally by a SHA hash. The git repo uses the filesystem as a database. Hashes used for filenames.

Git Commit Object

A Commit object consist of:

  • a pointer to it's parent(s) SHA(s)
  • a message
  • the name/email/timestamp for author & committer
  • a tree object containing blob(s) and/or tree(s)

A commit id is the SHA hash of this data. Other things point to commits, like tags, branches, or refs (i.e. head).

Note: We can assume no commit in any repo anywhere in the world will have the same SHA, with a very very high degree of certainty. Carl Sagan number magnitude. We also have near perfect data integrity guarentees.

Git Blob Object

A lame party trick for geeks:

% mkdir foo && cd foo
% echo isao > ANY_FILENAME
% git init
% git add .
% ls .git/objects/2b/c2dbdb05e12bd7344b96329c5e89188b812a82

How do I know the name of that file?

Note: Answer 2bc2dbdb05e12bd7344b96329c5e89188b812a82 is the SHA hash of the blob isao 5<null>LF. Git is content-addressable-- it accesses data by it's contents. Peek in .git.

Setting Up

Setting Up: You

The name and email you commit as are NOT automatically related to MRGIT repo authentication.

Please do not skip this step!

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

Note: you can omit the --global flag for per-repo configs.

Setting up: Auth

Mac users:

git config --global credential.helper osxkeychain

Windows users: replace osxkeychain with cache, or store. Best is install wincred.

Note: store is most convenient, but keeps your password in clear text.

Setting up: Editor

You should teach git to use your editor of choice.

Try:

git config --global --edit

If you can edit the configs and are happy with this, you're done. Otherwise please Google "setting up git editor X", where X is the text editor of your choice.

Setting up: Line endings

Mac:

git config core.autocrlf input

Windows:

git config core.autocrlf false

Setting up: other

Everyone:

git config --global push.default simple 
git config --global core.whitespace cr-at-eol

Windows users:

git config --global core.filemode false
git config --global core.ignorecase true

Note: push simple is the default in git 2.0.

Setting up: bonus

To type git lf instead of git log --graph --stat --decorate put this in your .gitconfig:

[alias]
    lf = log --graph --stat --decorate

Bonus points for:

  • mergetool
  • difftool

Windows Users

  • Use git-bash for all pulling and merging.
  • Do not use VS for merging of any kind.

Get started

Get started: commands

Fetching: clone, fetch, pull

Getting info: status, log, diff

Manipulating: checkout, add, commit, merge

Publishing: push (this is the only command that sends changes to MRGIT)

Note: by fetching I mean getting stuff from a remote. By manipulating, I mean modifying your local repo. By publishing, I mean sharing your changes with MRGIT.

Get started: terms

remote is a repo that is not local.

origin is the default name of the remote you cloned from. In our case it points to MRGIT.

tracking branch refers to the local (hidden) representation of a branch on a remote. i.e. origin/master. These are updated when you fetch or pull.

You can compare and merge with the tracking branches, but they don't magically keep up to date with MRGIT.

Note: when you do a git fetch, you update the hidden tracking branches. When you see messages about "X commits ahead of" or "behind" a tracking branch, it's using info from the last fetch.

Fetching

Fetching: Clone

git clone http://tfsmr:8080/tfs/IEB/MRGIT/_git/...

% git clone http://tfsmr:8080/tfs/IEB/MRGIT/_git/ReachClient
Cloning into 'ReachClient'...
Username for 'http://tfsmr:8080': [email protected]
Password for 'http://[email protected]@tfsmr:8080': 
remote: 
remote:                    fTfs   
remote:                  fSSSSSSSs
remote:                fSSSSSSSSSS
remote: TSSf         fSSSSSSSSSSSS
remote: SSSSSF     fSSSSSSST SSSSS
remote: SSfSSSSSsfSSSSSSSt   SSSSS
remote: SS  tSSSSSSSSSs      SSSSS
remote: SS   fSSSSSSST       SSSSS
remote: SS fSSSSSFSSSSSSf    SSSSS
remote: SSSSSST    FSSSSSSFt SSSSS
remote: SSSSt        FSSSSSSSSSSSS
remote:                FSSSSSSSSSS
remote:                  FSSSSSSs
remote:                    FSFs    (TM)
remote: 
remote:  Microsoft (R) Visual Studio (R) Team Foundation Server
remote: 
Receiving objects: 100% (150854/150854), 766.01 MiB | 56.63 MiB/s, done.
Resolving deltas: 100% (85690/85690), done.
Checking connectivity... done.
Checking out files: 100% (12181/12181), done.

(Cloning Tip)

Use --depth if you do not need the full history, in CI, or on a slow connection.

git clone --depth=99 http://tfsmr:8080/tfs/...

Fetching: Pull

This command does two things, a fetch and a merge.

git pull

Info

Info

Which branch am I on?

git branch

What are the remote branches?

git branch -r

Info

What are my local changes?

git status

Info

What's the history?

git log
git log --oneline
git log --oneline --decorate

Pseudo GUI:

git log --graph --stat --decorate

Also, remember there is a web interface.

Info: halp

git help <command>
git <command> -h

Pretty much any scenario involving git has a blog post or a Stack Overflow question.

Manipulating

Manipulating: Checkout

Unlike other VCSs, checkout in git is not a network operation. It changes your repo to reflect some node in the commit graph.

git checkout ST1234_supa_feecha

Create a new branch and check it out:

git checkout -b TS1234_feecha_part1

Always work from a branch. Never commit to master.

Note: detached head.

Manipulating: Checkout

Checkout will also copy the contents of a file or files as of some point in the commit graph, to your working directory.

git checkout origin/<branchname> -- path/to/file
git checkout <some SHA> -- path/to/file
git checkout -- path/to/file

Branch Naming

Start with a two letter type, followed by a work item number.

  • STnnnnn Story
  • TSnnnnn Task
  • BGnnnnn Bug

Note: can also use underscores and friendlier test to distinguish your branch from the 1600+ branches on MRGIT right now.

Manipulating: Edit, Add

Edit stuff. Add as you go.

git add <path/or/glob>
git add -A

If you continue to modify a file you added, you'll need to add it again to include the changes.

Manipulating: Commit

Commit stuff you added, bring up editor:

git commit

Add modified files, bring up editor:

git commit -a

Commit with message (don't bring up editor):

git commit -m

On Commit Messages...

Must:

  • Include #nnn for related work items, where nnn is the item number.
  • Subject line 80 characters max.

Should:

  • More datailed description, starting after a blank line

Note: I usually put the work item at the end of the first line because the hash character in the first column is treated as a comment by git when using an editor for commit messages.

  • Do not commit to master, issue a pull request from your branch onto master.

Manipulating: Updating master

Update master and the remote tracking branches.

git checkout master
git pull origin master
git pull

Manipulating: Updating branch

Update your branch with changes from master.

git checkout <branchname>
git merge master

Manipulating: Merging branch

Update your branch with changes from another branch.

git checkout <story branch name>
git merge <task branch name>

Or use the web interface...

Manipulating: delete a local branch

git branch -d <branchname>
git branch -D <branchname>

OH NOES!

Don't panic.

OH NOES!

Undo uncommitted changes:

git reset --hard

Or

git checkout -- some/path/

OH NOES!

Redo last commit:

git commit --amend

Undo last commit:

git reset --hard head^

OH NOES!

Completely reset a branch to the way it exists on MRGIT:

git reset --hard origin/master
git reset --hard origin/branchname 

Publishing

Publishing: pushing

git checkout <branchname>

These do the same thing:

git push origin <branchname>:<dest branchname>
git push origin <branchname>
git push

Publishing: merging to master

Issue a pull request. Get it reviewed.

http://tfsmr:8080/tfs/IEB/MRGIT/_git/ReachClient/pullrequests

  • click "New Pull Request"
  • Select your branch in "Review changes in" field
  • Select destination branch in "relative to" field. i.e. master or story branch.

Publishing: delete a remote branch

You can also do this after a the pull request.

git push origin :<branchname>

Resources

References

Note: I used these sites in compiling this presentation, because they came up in a web search of particular topics-- not neccessarily because they're canonical or generally usefull YMMV.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Git Intro - Jun 8, 2015</title>
<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
<meta name="author" content="Hakim El Hattab">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/white.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Git Intro</h1>
<p>June 9, 2015</p>
<p>Isao Yagi &lt;[email protected]&gt;</p>
</section>
<section>
<div>Knock knock.</div>
<div class="fragment">Who's there?</div>
<div class="fragment">Git. </div>
<div class="fragment">Git who? </div>
<div class="fragment">Sorry, 'who' is not a git command - did you mean 'show'?</div>
</section>
<section
data-markdown="./git-brownbag.md"
data-separator="^\n\n\n"
data-separator-vertical="^\n\n"
data-separator-notes="^Note:"
data-charset="utf8">
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
transition: 'slide', // none/fade/slide/convex/concave/zoom
// Optional reveal.js plugins
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment