$30 off During Our Annual Pro Sale. View Details »

Get Started with Git

Get Started with Git

In this tutorial, we'll start from zero and build your knowledge step-by-step about how to use Git effectively. We'll start with the basics of creating a repository and making commits, and move on to branching, merging, resolving conflicts, and generally moving commits around. Next, we'll cover the most popular options for hosting repositories online (GitHub, GitLab, and BitBucket), and how to interact with other peoples' Git repos on those websites.

Then we'll start getting into more advanced topics. You'll learn about rebase, and its awesome power to travel through time and re-write the history of your project. You'll also learn how to wield that power with restraint and recover from your mistakes, so that you can use it safely and confidently. Once you've learned how to rebase, you'll be able to split and combine commits, fix up poorly-written commit messages, remove passwords from your history before they were ever mistakenly committed, or even make it look like you wrote perfect code the first time.

You'll also learn how to be more productive with Git by integrating it into your everyday development tools, like your text editor and your shell. (Being able to constantly see what branch you're working on is a huge help!) You'll also learn how to streamline your workflow by using Git's event hooks to run arbitrary scripts for you, and how to take advantage of the integrations provided by your online host of choice.

Presented at PyCon 2016: https://us.pycon.org/2016/schedule/presentation/1620/

David Baumgold

May 28, 2016
Tweet

More Decks by David Baumgold

Other Decks in Technology

Transcript

  1. GET STARTED

    WITH GIT
    David Baumgold
    @singingwolfboy

    View Slide

  2. PRE-WORK
    ➤ Install Git
    ➤ Install a text editor with shell commands (Atom is a good choice)
    ➤ Optional: Install zsh and oh-my-zsh
    ➤ Learn how to use the command line
    ➤ Make an account with GitHub.com
    ➤ Optional: Make an account on GitLab.com
    If you have not already done these things, you should go to
    https://github.com/singingwolfboy/git-tutorial-prework
    and do them!

    View Slide

  3. Elisabeth Robson & Eric Freeman
    A learner’s guide to Git
    Head First
    Git
    David Baumgold
    A Brain-Friendly Guide
    Learn how
    to travel
    through
    time
    Editing has never
    been so enlightening
    Compatible
    with all kinds
    of text, not
    just software
    Track down issues
    at their source
    Discover the
    freedom in
    branching,
    forking,
    & merging
    Change history without
    tying yourself in knots

    View Slide

  4. WHAT IS VERSION CONTROL?
    ➤ Ability to always go back to an old version
    ➤ Track metadata about changes: who, when, and why?
    ➤ Allow multiple editors to make changes simultaneously
    without stepping on each others’ toes
    Sadly, version control is not often taught in school.
    Therefore, I will assume that this is all new for you.
    If you’ve done version control before: great! Refresh your knowledge.

    View Slide

  5. Central
    Repository
    Partial
    copy
    Partial
    copy
    Partial
    copy
    Partial
    copy
    changes
    CENTRALIZED VCS
    ➤ One central repository
    ➤ Many partial copies, one for
    each editor
    ➤ Partial copies can download
    updates from central repo, and
    send changes to central repo
    (if changes don’t conflict)
    ➤ Partial copies never talk to each
    other directly
    ➤ Examples: CVS, Subversion,
    ClearCase, Perforce

    View Slide

  6. Repo
    Repo
    Repo
    Repo
    Repo
    Repo
    DECENTRALIZED VCS
    ➤ Every editor has a copy of the
    entire repository, including all
    history for the project
    ➤ Every repo has its own owner
    & permissions: forking is
    common
    ➤ Central repository is not
    necessary — however, some
    teams choose to designate one
    repo as the “main” one
    ➤ Examples: Git, Mercurial

    View Slide

  7. AGENDA
    ➤ Create your own Git repo, make commits to track changes
    ➤ Collaborate with others by pushing and pulling changes
    between repos, making pull requests, and merging them
    ➤ Learn about Git’s branching model and how to work on
    multiple changes simultaneously
    ➤ Move commits around between branches,

    move branches around within repos
    ➤ Travel through time and change history in your repo

    View Slide

  8. THE BASICS
    Create a repo, make some commits

    View Slide

  9. MAKE A REPO
    $ git init cookbook
    ➤ git init creates a new, empty repo
    ➤ Optional argument is the name of the directory to create;

    otherwise the repo will be created in the current directory
    ➤ Creates a .git directory that stores all the repo information

    View Slide

  10. EXPLORE THE REPO
    $ ls .git
    HEAD info/
    config objects/
    description refs/
    hooks/
    Mostly, you shouldn’t need to touch the contents of the

    .git directory, but there is one very useful file: .git/config

    View Slide

  11. GIT CONFIG
    $ git config []
    ➤ git config allows you to read and write values

    to Git’s config files
    ➤ By default, it uses .git/config

    Use the --global flag to use ~/.gitconfig
    ➤ You’ll need to set your name and email address:
    $ git config --global user.name "Joe Developer"

    $ git config --global user.email "[email protected]"

    View Slide

  12. MAKE A FILE
    ➤ Find a delicious recipe, copy the text, paste it into a file

    in your “cooking” Git repo. For example:
    S'mores Recipe
    Ingredients:
    1 large marshmallow
    1 graham cracker
    1 bar of chocolate
    Directions:
    1. Heat the marshmallow over an open flame

    until it begins to brown and melt.
    2. Break the graham cracker in half.

    Sandwich the chocolate between the cracker

    and the hot marshmallow. Allow the marshmallow

    to cool a moment before eating.
    smores.txt

    View Slide

  13. GIT STATUS
    $ git status
    ➤ git status tells you the status of the files in your repo:

    what is new, what has changed, what’s been deleted
    ➤ git status is always safe to run, and will never change

    or break anything in your repo
    ➤ My most frequently used Git command!

    View Slide

  14. GIT ADD
    $ git add smores.txt
    ➤ git add tells Git that you want a certain file added to the

    repository in an upcoming commit
    ➤ Marks the file to be included as it is at that point in time.

    Picks up on changes since the last commit, but won’t pick

    up on changes you make after running git add — you’ll

    need to re-add the file to include those changes!
    ➤ Adding a directory will add all files in that directory.

    Use git add . to add all files at once!

    View Slide

  15. GIT COMMIT
    $ git commit
    ➤ git commit creates a new commit based on the files

    you’ve marked using git add
    ➤ A commit message is required: Git will open your text

    editor so you can write one
    ➤ You can use the -m flag to provide a message on the

    command line, instead

    View Slide

  16. COMMITTING CHANGES
    To commit a change to the repo, do the following:
    ➤ Edit files and save changes
    ➤ git add
    ➤ git commit
    Special case: to delete a file from the repo, use
    $ git rm
    exactly like how you would use git add

    View Slide

  17. COMMANDS FOR MAKING COMMITS
    ➤ git init
    ➤ git status
    ➤ git add
    ➤ git rm
    ➤ git commit

    View Slide

  18. VIEWING THE COMMIT LOG
    $ git log
    ➤ git log displays a log of all the commits,

    from most recent to least recent
    ➤ Use the arrow keys to scroll, press “Q” to quit

    View Slide

  19. GIT SHOW
    $ git show
    ➤ git show displays detailed information about a particular commit
    ➤ The hash argument is optional, defaults to current commit
    ➤ Use the arrow keys to scroll, press “Q” to quit

    View Slide

  20. VIEWING A DIFF
    $ git diff
    ➤ git diff shows the changes you’ve made that haven’t yet

    been committed
    ➤ Useful for checking to be sure that you’ve made all the

    changes you intend, and none of the ones you didn’t
    ➤ Use the --staged argument to view changes that you’ve

    already added using git add
    ➤ Use the arrow keys to scroll, press “Q” to quit

    View Slide

  21. BROWSING HISTORY
    $ git checkout
    ➤ git checkout allows you to view your project

    as it was at a particular commit
    ➤ You will get a big scary “detached HEAD” warning:

    ignore it for now
    ➤ To get back to your most recent commit, use master

    instead of a hash, like this:
    $ git checkout master
    Do this before making any new commits!

    View Slide

  22. COMMANDS FOR VIEWING COMMITS
    ➤ git log
    ➤ git show
    ➤ git diff
    ➤ git checkout

    View Slide

  23. ALL THE GIT COMMANDS WE KNOW SO FAR
    git log
    git show
    git diff
    git checkout
    git init
    git config
    git status
    git add
    git rm
    git commit
    making commits viewing commits

    View Slide

  24. COLLABORATION
    Sharing commits across repos

    View Slide

  25. CREATE REPO ON GITHUB
    ➤ Visit GitHub.com, log in, and click on the plus sign at the top
    to make a new repository

    View Slide

  26. View Slide

  27. View Slide

  28. GIT REMOTES
    my
    repo
    https://github.com/
    singingwolfboy/cookbook.git
    https://yoursite.com/
    cookbook.git
    https://github.com/
    example/cookbook.git
    https://gitlab.com/
    singingwolfboy/
    cookbook.git

    View Slide

  29. GIT REMOTES
    my
    repo
    origin
    yoursite
    example
    gitlab

    View Slide

  30. GIT REMOTES
    $ git remote add
    ➤ git remote creates short nicknames for URLs that point to

    other Git repos that you want to share commits with
    ➤ Run git remote -v to list all the remotes that the repo knows about
    ➤ Remotes are saved in the .git/config file: you can edit it, if you want

    View Slide

  31. GIT PUSH
    $ git push
    ➤ git push sends commits from your repo to another repo
    ➤ Can specify a remote; if not, pushes to whatever remote is set as default
    $ git push -u origin master
    This is what GitHub tells you to run
    ➤ -u origin sets the “origin” remote as the default remote
    ➤ master is a branch, and it’s the same thing we use to get back to the

    most recent commit. We’ll learn about branches in a little bit.

    View Slide

  32. CREATING COMMITS ON GITHUB
    Step 1
    Step 2
    Step 3

    View Slide

  33. GIT PULL
    $ git pull
    ➤ git pull gets commits from another repo to your repo, and updates

    your files with those changes
    ➤ Can specify a remote; if not, pulls from whatever remote is set as default
    git fetch git merge
    +
    “fetch” is what downloads commits.
    “fetch” never changes the files on

    your computer, even if the commits

    say the files should change.
    “merge” is what updates files.
    We’ll learn more about “merge”

    on the next slide

    View Slide

  34. GIT FETCH
    $ git fetch
    ➤ git fetch downloads information from a remote, but

    does not change any files in your repo
    ➤ Run automatically as part of git pull
    ➤ The equivalent of saying: “Hey remote, tell me what’s new

    since we last saw each-other!”

    View Slide

  35. GIT MERGE
    $ git merge /master
    ➤ git merge combines the commits

    on a remote repo with the commits

    on your local repo
    ➤ Creates a new commit that has

    multiple parents: called a

    “merge commit”
    ➤ In the diagram, every commit has

    a black pointer to its parent. We’ll

    talk about those more later.
    local remote
    merge
    most
    recent
    commits
    oldest
    commits

    View Slide

  36. GIT CLONE
    $ git clone
    ➤ git clone makes a local copy of a repo

    that is available at the given URL
    ➤ The local copy is a full, complete repo,

    with all commits and history
    ➤ Local copy has a remote named origin,

    which is set to the original URL
    ➤ The local copy is yours: you can change it

    however you want!
    Taking an existing project and making your own changes

    is called “forking”, and it happens all the time with Git

    View Slide

  37. COMMANDS FOR COLLABORATION
    ➤ git clone
    ➤ git remote
    ➤ git push
    ➤ git pull
    ➤ git fetch
    ➤ git merge

    View Slide

  38. ALL THE GIT COMMANDS WE KNOW SO FAR
    git clone
    git remote
    git push
    git pull
    git fetch
    git merge
    git log
    git show
    git diff
    git checkout
    git init
    git config
    git status
    git add
    git rm
    git commit
    making commits viewing commits collaborating

    View Slide

  39. RUNNING INTO PROBLEMS
    ➤ Clone the repo at

    https://github.com/singingwolfboy/tutorial-cookbook
    ➤ Create a new file in the repo with a new recipe. Write out
    your favorite recipe, or find a random one on Google and
    copy-paste it in.
    ➤ Commit your new recipe, and try to push it up to the GitHub
    repo you that cloned from!
    (Spoiler alert: it won’t work. Why not? What is the error message?)

    View Slide

  40. PULL REQUESTS
    1. Fork the repo, so you have control over your fork
    2. Make commits in your fork to change it however you want
    3. Contact the owner of the upstream repo, show your changes,
    ask the owner to pull your changes into upstream repo
    GitHub has a special interface for managing these requests,

    which they call Pull Requests

    View Slide

  41. View Slide

  42. View Slide

  43. MAKING PULL REQUESTS
    ➤ Fork the repo at

    https://github.com/singingwolfboy/tutorial-cookbook
    ➤ Clone your forked repo to your computer
    ➤ In your forked repo, create a new file with a new recipe, and
    commit it
    ➤ Push your commit to your fork on GitHub
    ➤ Make a pull request from your fork to my repo (known as the
    “upstream” repo)

    View Slide

  44. MERGING PULL REQUESTS
    ➤ Can use the merge button on a GitHub pull request
    ➤ OR, do it manually with Git:
    ➤ Add requester’s fork as a remote
    ➤ git fetch
    ➤ git merge /master
    ➤ git push
    ➤ GitHub will automatically update the pull request!
    Remember, “git pull” is “git fetch” followed by “git merge”,

    so in this case, I’m being more explicit about what I merge with

    View Slide

  45. OTHER GIT HOSTING
    ➤ GitHub is not the only website you can use to host repos
    ➤ GitLab, BitBucket: free private repos
    ➤ GitLab is open source: can run it on your own server
    ➤ It’s all Git, so you can clone from GitHub and push to GitLab
    (or vice versa)

    View Slide

  46. BRANCHING & HISTORY
    Moving commits around within a repo

    View Slide

  47. RUNNING INTO PROBLEMS, PART 2
    ➤ Let’s say you want to propose two separate changes, unrelated
    to each other. One is adding a new recipe, one is modifying an
    existing recipe.
    ➤ Try making two separate pull requests.
    ➤ Spoiler alert: you can’t make more than one pull request
    between the same two repos, based on what we know so far.
    Fortunately, we’re not done learning yet!

    View Slide

  48. STRUCTURE OF A COMMIT
    Content
    +S’mores Recipe
    +
    +Ingredients:
    smores.txt
    Metadata
    Initial commit
    Commit Message
    David Baumgold

    Author
    Sat May 28 10:05:03 2016
    Date
    Commit
    +This repo contains
    +recipes from my
    +personal cookbook.
    README.txt

    View Slide

  49. STRUCTURE OF A COMMIT
    Content
    +Salad Recipe
    +
    +Ingredients:
    salad.txt
    Metadata
    Added a salad recipe
    Commit Message
    David Baumgold

    Author
    Sat May 28 10:08:42 2016
    Date
    Commit
    Content
    +S’mores Recipe
    +
    +Ingredients:
    smores.txt
    Metadata
    Initial commit
    Commit Message
    David Baumgold

    Author
    Sat May 28 10:05:03 2016
    Date
    Commit
    +This repo contains
    +recipes from my
    +personal cookbook.
    README.txt
    parent pointer

    View Slide

  50. MASTER BRANCH
    most
    recent
    commits
    oldest
    commits

    View Slide

  51. MASTER BRANCH
    master
    most
    recent
    commits
    oldest
    commits

    View Slide

  52. MASTER BRANCH
    master
    most
    recent
    commits
    oldest
    commits

    View Slide

  53. FIX-TYPOS BRANCH
    master
    fix-typos
    most
    recent
    commits
    oldest
    commits

    View Slide

  54. FIX-TYPOS BRANCH
    master
    fix-typos
    most
    recent
    commits
    oldest
    commits

    View Slide

  55. MERGING BRANCHES
    master
    fix-typos
    most
    recent
    commits
    oldest
    commits

    View Slide

  56. MANAGING BRANCHES
    $ git branch
    ➤ git branch shows which branches exist in the repo,

    and which one you’re currently attached to (if any)
    ➤ git branch creates a new branch pointing

    to the commit you’re currently sitting on
    ➤ git branch -d deletes an existing

    branch from your local repo (not but from remotes!)

    View Slide

  57. SHORTCUT
    $ git checkout -b
    ➤ Creates a new branch and immediately switches over to it
    ➤ This is what you want most of the time!

    View Slide

  58. UPSTREAM
    $ git branch --set-upstream
    ➤ Every branch has its own “upstream” setting:

    the remote that the branch normally pulls from and pushes to,

    and the branch in that remote that it uses for those operations
    ➤ Normally the branch in the remote has the same name as the

    local branch, but it doesn’t have to!

    View Slide

  59. UPSTREAM
    master
    fix-typos
    master
    fix-typos
    Local Repo Remote Repo

    View Slide

  60. EXERCISE: ADD MORE CHOCOLATE!
    ➤ On your clone of the tutorial-cookbook repo, make a new

    branch called add-chocolate
    ➤ Check git log to be sure that the commits are the same
    ➤ Modify a recipe to add chocolate to it (or add more chocolate!)
    ➤ Commit your modification, and make sure the commit is in

    the add-chocolate branch and not the master branch
    ➤ Push your branch to GitHub, and make a pull request

    from your add-chocolate branch to my master branch

    View Slide

  61. MOVING COMMITS
    $ git cherry-pick
    ➤ git cherry-pick creates a new commit that is a copy of

    an existing commit that you reference: same changes,

    same files, same author
    ➤ You can use a hash, branch name, or any other valid

    Git reference
    ➤ This does not delete the referenced commit!

    View Slide

  62. CHERRY-PICK
    master
    fix-typos
    c
    most
    recent
    commits
    oldest
    commits

    View Slide

  63. CHERRY-PICK
    master
    fix-typos
    c
    c′
    most
    recent
    commits
    oldest
    commits

    View Slide

  64. MOVING BRANCH POINTERS
    $ git reset
    ➤ git reset moves the branch pointer to make it point

    to whatever commit you want
    ➤ By default, does not modify the files in your working

    tree, but use --hard to modify them

    View Slide

  65. RELATIVE REFERENCES
    ➤ Use ~ after a reference to refer to its parent commit
    ➤ You can use multiple tildes (~~~~~) or define a number (~5)
    ➤ You can use HEAD to refer to the current commit
    ➤ To refer to the parent of the current commit: HEAD~
    To remove the most recent commit from the current branch:
    $ git reset --hard HEAD~

    View Slide

  66. RESET AFTER CHERRY-PICK
    master
    fix-typos
    c
    c′
    most
    recent
    commits
    oldest
    commits

    View Slide

  67. FLASHBACK: DETACHED HEAD
    ➤ Now we know enough to understand Git’s “detached HEAD”
    warning!
    ➤ “HEAD” means the current commit
    ➤ “detached” means not attached to a branch
    ➤ New commits will also not be attached to a branch!
    ➤ Hard to find those commits again
    ➤ Solution: git checkout -b to create a new
    branch for your commits!

    View Slide

  68. CONFLICTS
    ➤ What if you try to cherry-pick a change that has already
    happened on your branch? Or a change in a file that doesn’t
    exist on your branch?
    $ git cherry-pick e98d69f0a5942704076182139acb50856ca8bc7c
    error: could not apply e98d69f... Conflicting commit message
    hint: after resolving the conflicts, mark the corrected paths
    hint: with 'git add ' or 'git rm '
    hint: and commit the result with 'git commit'

    View Slide

  69. RESOLVING CONFLICTS
    ➤ Git will alter the file to show conflicting lines
    ➤ Edit the file to look the way you want, then use git add to
    indicate that the conflict is resolved
    not in conflict
    <<<<<<< HEAD
    first part of conflict
    =======
    second part of conflict
    >>>>>>> Conflicting commit message

    View Slide

  70. GIT REBASE
    $ git rebase
    ➤ git rebase does a series of cherry-picks to recreate a branch

    on a different commit base, and moves the branch pointer

    to point to the newly-created branch
    ➤ Just like with cherry-pick, the old commits are not deleted
    ➤ Rebase is the command for changing history

    View Slide

  71. GIT REBASE
    most
    recent
    commits
    oldest
    commits
    c
    b
    a
    master
    d
    e
    fix-typos
    f
    e′
    f′

    View Slide

  72. CHANGING HISTORY
    ➤ Changing history is confusing for others
    ➤ Never change history when other people might be using your
    branch, unless they know you’re doing so
    ➤ Never change history on master
    ➤ Best practice: only change history for commits that haven’t
    yet been pushed to any remote

    View Slide

  73. FORCE PUSH
    c
    b
    a
    master
    d
    fix-typos
    e′
    f′
    c
    b
    a
    master
    d
    e
    fix-typos
    f
    Local Repo Remote Repo

    View Slide

  74. INTERACTIVE REBASE
    ➤ Step through commits and perform operations on them:
    ➤ Squash multiple commits together
    ➤ Edit a commit to separate it into multiple smaller ones
    ➤ Insert, delete, and reorder commits in history
    ➤ With great power comes great responsibility
    $ git rebase -i

    View Slide

  75. GIT REFLOG
    $ git reflog
    ➤ git reflog shows every commit you’ve touched recently,

    regardless of where that commit is in Git’s history
    ➤ Useful for recovering commits that you’ve lost track of
    ➤ Example: commits you’ve deleted through interactive rebase
    pronounced “ref-log”, not “re-flog”

    View Slide

  76. COMMANDS FOR MOVING COMMITS AROUND
    ➤ git branch
    ➤ git reset
    ➤ git cherry-pick
    ➤ git rebase

    View Slide

  77. ALL THE GIT COMMANDS WE KNOW SO FAR
    git clone
    git remote
    git push
    git pull
    git fetch
    git merge
    git log
    git show
    git diff
    git checkout
    git init
    git config
    git status
    git add
    git rm
    git commit
    making commits viewing commits collaborating
    git branch
    git reset
    git cherry-pick
    git rebase
    moving commits

    View Slide

  78. MISCELLANEOUS TOOLS
    Everything you didn’t know you couldn’t live without

    View Slide

  79. GIT TAG
    ➤ git tag is like git branch, but branches move and tags
    don’t
    ➤ Useful for historical references: version 1.0 that shipped to
    customers, or was put on the production website
    ➤ Tags can be lightweight or annotated
    $ git tag

    View Slide

  80. GIT BLAME
    ➤ For every line, git blame will tell you who last changed the
    line
    ➤ Useful for when something broke and you need to know who
    can fix it
    ➤ To find out who was the second-to-last to change a line (or
    further back), check out the commit before when that line
    changed, and run git blame again
    $ git blame

    View Slide

  81. GIT BISECT
    ➤ git bisect will help you find which commit introduced a
    breakage or a bug
    ➤ Provide three things: a working commit, a broken commit,
    and a test to determine whether a commit is working or not
    ➤ bisect uses binary search to quickly find the commit where
    things went from working to broken
    $ git bisect

    View Slide

  82. GIT BISECT
    $ git bisect start
    $ git checkout broken-commit
    $ git bisect bad
    $ git checkout working-commit
    $ git bisect good

    View Slide

  83. GIT BISECT
    Broken Working
    ?

    View Slide

  84. GIT BISECT
    Broken Working
    Broken
    Test here next

    View Slide

  85. GIT BISECT
    Broken Working
    Working
    Test here next
    And keep going recursively….

    View Slide

  86. GIT BISECT
    ➤ Even faster with an automated test
    ➤ Return code 0 on success, return code 1 on failure
    $ git bisect run my_test.sh

    View Slide

  87. HOOK SCRIPTS
    ➤ Every Git repo has a “hooks” directory in the “.git” directory,

    with scripts that Git will run automatically
    ➤ Names include: pre-commit, pre-push, pre-rebase,
    prepare-commit-message, etc
    ➤ See also: pre-commit.com
    $ ls .git/hooks

    View Slide

  88. GIT ADD BY PATCH
    ➤ Situation: you’re trying to add a new feature, but you discover
    you need to fix a bug to do so
    ➤ Should be two separate commits, but code is tangled up
    ➤ Use git add -p to craft commits one patch at a time, instead
    of by whole files
    $ git add -p .

    View Slide

  89. CHECK OUT GITHUB PULL REQUESTS
    Edit your .git/config and add this to your GitHub remote:
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
    Now you can run:
    git checkout pr/123
    And you’ll check out pull request #123 locally! Easy!

    View Slide

  90. TEACH GIT ABOUT GITHUB
    git create — create a GitHub repo for your local repo
    Adds Git commands like:
    git pull-request — make a pull request
    git issue create — make a GitHub issue
    https://hub.github.com/

    View Slide