Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Git: Your Best Friend, Ever

Git: Your Best Friend, Ever

A talk I gave for the WSU LUG to introduce developers (primarily EECS students) to source control with Git.

Created with https://github.com/hakimel/reveal.js.

GitHub repo: https://github.com/doingweb/git-your-best-friend-ever.

See the full interactive deck at http://doingweb.github.io/git-your-best-friend-ever.

Chris Antes

April 01, 2015
Tweet

More Decks by Chris Antes

Other Decks in Programming

Transcript

  1. LET'S CREATE A REPOSITORY! $ git init Initialized empty Git

    repository in .git/ The current directory becomes the working directory for the new Git repository.
  2. THE LIFECYCLE OF A FILE Adding a file: $ git

    status On branch master nothing to commit, working directory clean $ atom new­file.txt $ git status On branch master Untracked files: (use "git add ..." to include in what will be committed) new­file.txt nothing added to commit but untracked files present (use "git add" to track) $ git add new­file.txt $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage)
  3. THE LIFECYCLE OF A FILE Modifying a file: $ git

    status On branch master nothing to commit, working directory clean $ atom new­file.txt $ git status On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout ­­ ..." to discard changes in working directory) modified: new­file.txt no changes added to commit (use "git add" and/or "git commit ­a") $ git add new­file.txt $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage)
  4. THE LIFECYCLE OF A FILE Removing a file: $ git

    status On branch master nothing to commit, working directory clean $ git rm new­file.txt rm 'new­file.txt' $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) deleted: new­file.txt $ git commit ­­message="Removed the file." [master 0d229e7] Removed the file. 1 file changed, 2 deletions(­) delete mode 100644 new­file.txt $ git status On branch master
  5. AMENDING A COMMIT Redo commits with git commit ‐‐amend: $

    git log ­­oneline ­­max­count 2 0d229e7 Removed the file. 9bb1e7e Modified the file. $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) new file: cat­names.txt $ git commit ­­message="Needed soem cat names." [master 2e6c3b7] Needed soem cat names. 1 file changed, 1 insertion(+) create mode 100644 cat­names.txt $ git log ­­oneline ­­max­count 2 2e6c3b7 Needed soem cat names. 0d229e7 Removed the file. $ git commit ­­amend ­­message="Needed some cat names." Note that this changes history!
  6. .gitignore # We want these files in our working directory,

    but not in our repository. # Log files *.log # Build output directory build/ # Third­party packages node_modules Matching files not already in the repository are ignored: $ atom new­file­that­gets­ignored.log $ git status On branch master nothing to commit, working directory clean
  7. WHERE DO COMMITS GO? We can see the list of

    commits with git log: $ git log ­­oneline 1eb2ce2 Slides on other VCSs. Refinements to previous slides. 8516b87 Rewording Dropbox slide. 1377305 Using drop shadow to set off images. Adding autoprefixer to build. b1b1dc8 Slides about why you need version control. Styles for headings against background images. 2d05220 Bringing in the rest of the existing slides. ba54632 Updating Reveal.js to v3.0.0. Adding images. Using `slide` transition. 4d51b9b Adding slides. Reducing indentation to 2 spaces. Copying in custom theme. fe0ddab Initial, from `yo reveal`.
  8. WHERE DO COMMITS GO? Commits live in the key-value store

    (.git/objects directory): $ ls ­R .git/objects .git/objects: 1e 5e ce info pack .git/objects/1e: b98e70230c45fa1b61eab232ec1f66b29c8625 .git/objects/5e: 08bc4c2da476233573fc7c4793412cede36bfa .git/objects/ce: 013625030ba8dba906f756967f9e9ca394464a .git/objects/info: .git/objects/pack:
  9. WHAT'S IN A COMMIT? Let's go look at a raw

    commit! git cat‐file gets objects from the key-value store: $ git cat­file ­p 1eb2ce28cd1b6e89e9a9ed2f4681cb834a48fc87 tree 48b8b000be35eb9d739aa63b5556226405745e86 parent 8516b87e1307db03994c619693e2669a1d825608 author Chris Antes 1426921898 ­0700 committer Chris Antes 1426921898 ­0700 Slides on other VCSs. Refinements to previous slides.
  10. WHAT'S IN A COMMIT? Now let's get the commit's tree:

    $ git cat­file ­p 48b8b000be35eb9d739aa63b5556226405745e86 100644 blob 69fad358018d530235f8e43c483d3ce960616a32 .bowerrc 100644 blob d1d8a4176a416daffcfbfecdd3f35f24bd79fc7d .editorconfig 100644 blob 3518e7f29dcc2b195d7077d989efa3f6bd6cfbef .gitignore 100644 blob 855a9efe0a6aff5c442fbd1dc26a5af279d66b72 .jshintrc 100644 blob 41ea8d4c4629041d42e6f090e41dcd3d5eace1eb .yo­rc.json 100644 blob a62946614b7f1c3c43990b0cb39c2677060effc7 Gruntfile.coffee 100644 blob 6f7daeaa8cf04b03638ddd6509a2508efee2b5cd bower.json 040000 tree c38c7e40dc6b3671486d99d2cc3a15c4a36cd604 css 040000 tree fc4a211f73968d6efb124f296f70acd9610eb19a images 040000 tree 449df7430c1f8db1c0922d1fbc2ec99fb8ec3701 js 100644 blob 0eeb399333af39939d3c83691747f7cf30a002ee package.json 040000 tree b938f6a0fd291522d106549360c0a7facdaf1f30 slides 040000 tree e4eaa88c5ddd86fd4a6a95bf2769d36565863dd8 templates
  11. WHAT'S IN A COMMIT? Let's see what a blob looks

    like: $ git cat­file ­p 0eeb399333af39939d3c83691747f7cf30a002ee { "name": "git­your­best­friend­ever", "version": "0.0.0", "private": true, "devDependencies": { "grunt": "^0.4.5", "grunt­autoprefixer": "^2.2.0", "grunt­coffeelint": "0.0.13", "grunt­contrib­connect": "^0.9.0", "grunt­contrib­copy": "^0.7.0", "grunt­contrib­jshint": "^0.10.0", "grunt­contrib­sass": "^0.8.0", "grunt­contrib­watch": "^0.6.1", "load­grunt­tasks": "^1.0.0" }, "engines": { "node": ">=0.10.0",
  12. WHAT IS A BRANCH? They're just pointers (also known as

    refs)! v1.0 and master are branches:
  13. WHAT'S HEAD? HEAD is just a pointer to the current

    branch. $ git status On branch master nothing to commit, working directory clean $ cat .git/HEAD ref: refs/heads/master
  14. SWITCHING BRANCHES Switch branches with git checkout: $ git branch

    ­­list * master testing $ git checkout testing Switched to branch 'testing'
  15. CREATING BRANCHES Create new branches with git branch: $ git

    branch ­­list * master $ git branch new­feature $ git branch ­­list * master new­feature Use git checkout ‐b to branch and switch in one command: $ git branch ­­list * master $ git checkout ­b new­feature Switched to a new branch 'new­feature' $ git branch ­­list master * new­feature
  16. DELETING BRANCHES Delete branches with git branch ‐‐delete: $ git

    branch ­­list * master new­feature $ git branch ­­delete new­feature Deleted branch new­feature (was f3bc86a). $ git branch ­­list * master
  17. RENAMING BRANCHES Branches can be renamed with git branch ‐‐move:

    $ git branch ­­list master * new­feature $ git branch ­­move new­feature feature/starring­items $ git branch ­­list * feature/starring­items master
  18. CHANGING WHERE A BRANCH POINTS git reset changes where the

    HEAD branch points. And maybe some other stuff:
  19. TIME TRAVEL WITH git reset Resetting is useful when some

    commits should've been on a different branch: $ git status On branch master nothing to commit, working directory clean $ git log ­­oneline 4f00f1a Adding a few more cat names. 9abff09 Needed some cat names. 0d229e7 Removed the file. 9bb1e7e Modified the file. 015ba6c Added new file. $ git branch feature/cat­names $ git reset ­­hard HEAD~2 HEAD is now at 0d229e7 Removed the file. $ git checkout feature/cat­names Switched to branch 'feature/cat­names' $ git log ­­oneline 4f00f1a Adding a few more cat names. 9abff09 Needed some cat names. 0d229e7 Removed the file.
  20. MERGING BRANCHES Let's say we've just fixed a bug and

    we want to merge our fix into master:
  21. MERGING BRANCHES $ git checkout master Switched to branch 'master'

    $ git merge iss53 Merge made by the 'recursive' strategy. index.html | 1 + 1 file changed, 1 insertion(+)
  22. FAST-FORWARD MERGES $ git checkout master Switched to branch 'master'

    $ git merge hotfix Updating f42c576..3a0874c Fast­forward index.html | 2 ++ 1 file changed, 2 insertions(+)
  23. MERGE CONFLICTS HAPPEN Let's say I did some similar work

    on two branches that I now want to merge: $ git merge feature/cat­names Auto­merging cat­names.txt CONFLICT (add/add): Merge conflict in cat­names.txt Automatic merge failed; fix conflicts and then commit the result. $ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add ..." to mark resolution) both added: cat­names.txt no changes added to commit (use "git add" and/or "git commit ­a") So scary!
  24. MERGE CONFLICTS: NOT REALLY SO SCARY Here's what the conflicted

    file looks like: <<<<<<< HEAD Fluffy Socrates ======= Halo­Halo Chairman Meow >>>>>>> feature/cat­names Sadie Whiskers Simba The <<<<<<<, =======, and >>>>>>> lines denote where the conflict(s) are. The HEAD section is what our file (what we're merging into) has. The other section is what their file (what we're merging from) has. The rest of the file has been merged automatically.
  25. RESOLVING CONFLICTS Once we've manually merged our conflicted files, we

    use git add to tell Git that we've resolved the conflicts, then we resume the merge commit with git commit: $ git add cat­names.txt $ git commit [master b98a343] Merge branch 'feature/cat­names'
  26. REBASING Replay commits as if you had based them off

    of a different commit: $ git checkout experiment $ git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command
  27. SHARING YOUR COMMITS git push sends your commits to the

    in the upstream repository: tracked branch $ git push Counting objects: 20, done. Delta compression using up to 4 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (11/11), 276.23 KiB | 0 bytes/s, done. Total 11 (delta 5), reused 0 (delta 0) To [email protected]:doingweb/git­your­best­friend­ever.git 85c7fae..af42118 master ­> master
  28. PUSHING A NEW BRANCH Imagine we created a local branch

    and have now decided we want to track it, to make future pushes easier: $ git checkout ­b new­feature Switched to a new branch 'new­feature' $ git push fatal: The current branch new­feature has no upstream branch. To push the current branch and set the remote as upstream, use git push ­­set­upstream origin new­feature $ git push ­­set­upstream origin new­feature Total 0 (delta 0), reused 0 (delta 0) To [email protected]:doingweb/git­your­best­friend­ever.git * [new branch] new­feature ­> new­feature Branch new­feature set up to track remote branch new­feature from origin. $ git push Everything up­to­date
  29. PUBLIC PROJECTS ON GITHUB Contributing to public projects on GitHub

    and similar services usually goes something like: 1. Fork the upstream repository. 2. Clone your fork into your local workspace. 3. Create a branch for your changes. 4. Work! 5. Push back up to your fork. 6. Keep working and pushing until it's ready. 7. Squash your commits. 8. Open a pull request. 9. Participate in the discussion about your changes, and work through any issues that need to be addressed before it can be merged.
  30. TEAM PROJECTS ON GITHUB It's entirely up to the team

    how they work together, and there are a lot of combinations that work. Here's just one example for a small team: 1. Clone the repository into your local workspace. 2. Create a branch for your changes. 3. Work! 4. Push back up to your branch. 5. Keep working and pushing until it's ready. 6. Open a pull request. 7. Participate in the discussion about your changes, and work through any issues that need to be addressed before it can be merged.
  31. OTHER REALLY USEFUL GIT COMMANDS I don't use these every

    day, but they're just so nice to have when you need them: git log ‐‐grep="search terms" Searches commit messages. Accepts regular expressions. git stash Saves the working directory changes onto a stack, so you can switch branches without having to commit. git stash pop applies the topmost changes and removes them from the stack. git bisect Perform a binary search for the commit that introduced a bug.