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

Understanding git

Understanding git

This is an internal training I made at Blablacar to better understand Git with visual graphics.

Matthieu Moquet

October 09, 2014
Tweet

More Decks by Matthieu Moquet

Other Decks in Programming

Transcript

  1. Today’s topics The basics of commit
 git add, commit, revert,

    reset How to move in a git tree
 git checkout, HEAD References
 git branch, tag, merge History manipulation
 git cherry-pick, git rebase (—interactive) Working with a remote server
 git clone, remote, push, pull, fetch, merge, rebase
  2. Requirement Before using Git, make sure you correctly configured your

    user: git config --global user.name "Matthieu Moquet"
 git config --global user.email [email protected] write in your global ~/.gitconfig Your real name
  3. What is Git? Git is a distributed version control system.

    It works by creating local snapshots of all your files, like a big copy/paste, but better optimized.
  4. src/ Foobar.php Baz.php README.md New.php src/ Foobar.php Baz.php README.md New.php

    abcdef234 Initial commit deadbeef42 A new file Workspace
  5. src/ Foobar.php Baz.php README.md New.php fear8342abc Update foobar abcdef234 Initial

    commit deadb33f42 A new file Workspace internally it only stores the deltas between commits
  6. fear8342abc Update foobar abcdef234 Initial commit deadb33f42 A new file

    a commit: • is a snapshot of the sources • is identified by its hash (sha1) • has one (or many) parents • is immutable git commit once a commit is done, you can NOT modify it!
  7. ➜ git init ➜ vim README.md ➜ git status ➜

    git add README.md ➜ git commit ➜ git status Initialized empty Git repository in /path/to/myproject/.git/ Untracked files: (use "git add <file>..." to include in what will be committed) ! README.md Changes to be committed: (use "git reset HEAD <file>..." to unstage) ! new file: README.md [master (root-commit) 4b60dee] My commit ➜ git status On branch master nothing to commit, working directory clean
  8. ➜ git commit -A -m "Your commit message" Shortcut git

    add ALL FILES inline commit message
  9. Best practice ➜ git add -p diff --git a/README.md b/README.md

    index 540550a..2f10d41 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -This is an old line +This is the new line Stage this hunk [y,n,q,a,d,/,e,?]? y diff --git a/src/Foobar.php b/src/Foobar.php index 540550a..2f10d41 100644 --- a/src/Foobar.php +++ b/src/Foobar.php @@ -1 +1 @@ -class Foobar -{ - const BAZ = 'world'; -} Stage this hunk [y,n,q,a,d,/,e,?]? git add patch
  10. ➜ git commit Capitalized, short (50 chars or less) summary

    ! More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. In some contexts, the first line is treated as the subject of an email and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together. ! Write your commit message in the imperative: "Fix bug" and not "Fixed bug" or "Fixes bug." ! - Bullet points are okay, too - Use a hanging indent Best practice Open in your editor http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
  11. Best practice commit 9342a5bf855042b29a2ebd3413ce8e6cfb65557f Author: Matthieu Moquet <[email protected]> Date: Thu

    Sep 18 13:37:00 2014 +0200 ! Allow scope to be defined in the request entity body ! As defined in the RFC 6749: http://tools.ietf.org/html/rfc6749#section-4.4.2 ! Note that this change is backward compatible as it will first look up the request query.
  12. Best practice commit c1230da7409d22fe78263da777da237e9fc702d4 Author: Matthieu Moquet <[email protected]> Date: Tue

    Jul 29 17:00:33 2014 +0200 ! Use UserChecker in OAuth2 listener ! In order to deny block users on every API call ! Fix https://jira.example.net/browse/FOO-123
  13. git show abcdef Display the commit message + the diff

    with the previous one git diff abcdef dfebca Display the diff between the two commits git diff abcd~ abcd How to display the diff between commits?
  14. git diff --staged Display the change put in the staging

    area git diff Display the file I changed but not committed/staged How to display the diff between commits?
  15. git commit --amend Replace previous commit with new one, using

    the staging area git commit Oops, I made a mistake (typo, forget file, wrong commit msg) git add the_file.txt Add the concerned file into the staging area
  16. git commit Meh, I shouldn’t have committed git reset HEAD~

    Cancel the commit, but keep the change locally, so you can create another one git reset --hard HEAD~ Cancel the commit, and remove all the change
  17. Case #3 I need to revert one or several commits

    already pushed into production
  18. git commit Later: oops this commit (abc123) breaks something git

    revert abc123 Create a new commit, which is the opposite of the given one
  19. git log master HEAD fear8342abc Update foobar abcdef234 Initial commit

    deadb33f42 A new file Helps you to visualize the git tree start from a given commit… …and follow the parents to go through the history
  20. commit 9342a5bf855042b29a2ebd3413ce8e6cfb65557f Author: Matthieu Moquet <[email protected]> Date: Thu Sep 18

    13:37:00 2014 +0200 ! Allow scope to be defined in the request entity body ! As defined in the RFC 6749: http://tools.ietf.org/html/rfc6749#section-4.4.2 ! Note that this change is backward compatible as it will first look up the request query. ! commit c851bca7bf85504fe82639342acb237e9fc87420 Author: Matthieu Moquet <[email protected]> Date: Tue Jul 30 12:34:56 2014 +0200 ! Update README.md ! commit c1230da7409d22fe78263da777da237e9fc702d4 Author: Matthieu Moquet <[email protected]> Date: Tue Jul 29 17:00:33 2014 +0200 ! Use UserChecker in OAuth2 listener ! In order to deny block users on every API call ! Fix https://jira.example.net/browse/FOO-123 git log
  21. * 1187cf9 - (HEAD, master) Merge branch ‘update-ui' (Matthieu Moquet

    2 hours ago) |\ | * 3b1ba4e - Compile assets via Gulp (Matthieu Moquet 2 hours ago) | * 90575d5 - Fix layout login dependency (Matthieu Moquet 2 hours ago) | * a151f92 - Update editor shortcuts (Matthieu Moquet 2 hours ago) |/ * 56fa6f3 - Merge branch 'project-page' (Matthieu Moquet 3 hours ago) |\ | * 2ee4b97 - Add inLocale parameter to project page (Matthieu Moquet 4 hours ago) | * 73b044f - Update navbar user menu UI (Matthieu Moquet 4 hours ago) | * 6faa5c3 - Rework project page (Matthieu Moquet 6 hours ago) |/ * 0309542 - Merge branch 'rework-model' (Matthieu Moquet 30 hours ago) |\ | * 0082ea5 - Fix duplicate key error on import processor (Matthieu Moquet 2 days ago) | * 8dab5be - Add options parameters for export api (Matthieu Moquet 2 days ago) | * 0649be9 - Warmup symfony cache in Travis build (Matthieu Moquet 2 days ago) | * 6c72e8e - Refactor app architecture (Matthieu Moquet 2 days ago) |/ * 77cb4c9 - Remove old scripts (Matthieu Moquet 4 days ago) * ... * * git lg
  22. git checkout master fear8342abc Update foobar abcdef234 Initial commit deadb33f42

    A new file Workspace ➜ git checkout abcdef234 HEAD
  23. Branches master HEAD fear8342abc Update foobar abcdef234 Initial commit deadb33f42

    A new file A branch is just a pointer to a commit foobar ➜ git branch foobar deadb33f42
  24. Branches Internally a branch is simply a reference in a

    file ➜ cat .git/refs/heads/foobar deadb33f42d89b21f72f8115e34ad23c507db8b6 ➜ cat .git/HEAD ref: refs/heads/foobar So does HEAD ➜ cat .git/HEAD deadb33f42d89b21f72f8115e34ad23c507db8b6 git checkout foobar git checkout deadb33f42
  25. Branches When committing, the reference pointed by the HEAD is

    moved to the new commit master HEAD abcdef234 Initial commit deadb33f42 A new file
  26. Branches When committing, the reference pointed by the HEAD is

    moved to the new commit master HEAD fear8342abc Update foobar abcdef234 Initial commit deadb33f42 A new file
  27. Branches If HEAD points to a commit (and not a

    branch), then no branch will be updated master abcdef234 Initial commit deadb33f42 A new file HEAD
  28. Branches master HEAD fear8342abc Update foobar abcdef234 Initial commit deadb33f42

    A new file If HEAD points to a commit (and not a branch), then no branch will be updated orphan commit, no branch is referencing it
  29. Shortcut Create a new branch and checkout it immediately. ➜

    git branch foobar ; git checkout foobar ➜ git checkout -b foobar
  30. Merges Branches are useful when you’re working on a new

    feature. Once the feature is done you want it to be merged into the master branch.
  31. HEAD master Interactive Rebase ➜ git rebase -i master foobar

    pick 1df2b98 My green commit pick 3b7aff0 My yellow commit pick 2edf2b8 My purple commit
  32. HEAD master Interactive Rebase ➜ git rebase -i master foobar

    pick 1df2b98 My green commit pick 3b7aff0 My yellow commit pick 2edf2b8 My purple commit
  33. HEAD master Interactive Rebase ➜ git rebase -i master foobar

    pick 1df2b98 My green commit pick 2edf2b8 My purple commit pick 3b7aff0 My yellow commit
  34. HEAD master Interactive Rebase ➜ git rebase -i master foobar

    pick 1df2b98 My green commit squash 2edf2b8 My purple commit pick 3b7aff0 My yellow commit
  35. Interactive Rebase # Commands: # p, pick = use commit

    # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell
  36. Updating your local copy of remote branches origin/master master origin/foobar

    master foobar git fetch When the branch is updated on the server, you have to synchronize you local copy
  37. Updating your local copy of remote branches origin/master master origin/foobar

    master foobar git fetch fetch will only update the origin/* branches
  38. Protip Never use git pull, except for master branch* *because

    you’re not supposed to have divergence with master
  39. Master Branch We create a new branch to start a

    new feature Basic Git Workflow
  40. master master origin/master Basic Git Workflow dev origin/dev dev git

    push origin dev Server will reject the push because of the divergence
  41. master master origin/master Basic Git Workflow dev origin/dev dev git

    push -f origin dev Say the server to forget its old commits Use with caution if several people work on that branch
  42. master master origin/master Basic Git Workflow origin/dev dev Prune option

    delete removed origin/* branches ➜ git fetch -p
  43. master master origin/master Basic Git Workflow dev ➜ git checkout

    master ! ➜ git merge origin/master or ➜ git pull
  44. ➜ git:(master) git pull # ensure your master is up

    to date Updating 7afe47a..fb562e8 Fast-forward ➜ git:(master) git checkout -b feat-something-1234 # start new branch ➜ git:(feat-something-1234) vim files ; git add -p ; git commit # commit code Switched to a new branch 'feat-something-1234' ➜ git:(feat-something-1234) git push -u origin feat-something-1234 To ssh://git@server/path/to/project.git + fb562e8...4b60dee feat-something-1234 -> feat-something-1234 [feat-something-1234 4b60dee] Some commit message ➜ git:(feat-something-1234) git rebase origin/master # update your branch First, rewinding head to replay your work on top of it... Applying: Some commit message ➜ git:(feat-something-1234) git fetch -p # later, before merging ➜ git:(feat-something-1234) git push -f # push force To ssh://git@server/path/to/project.git + fb562e8...4b60dee feat-something-1234 -> feat-something-1234 (force update) ➜ git:(feat-something-1234) stash pull-request master # open a PR ➜ git:(feat-something-1234) meps deploy # deploy on maquette
  45. Push git push origin foobar:foobar Long command git push origin

    :foobar Deleting a remote branch branch name on the remote local branch name into the remote branch push nothing
  46. Push git push -u origin foobar Track upstream branch (the

    first time you push it) git push Use the shortcut the next time [push] # git < v2.0 # 'nothing' : Do not push anything # 'matching' : Push all matching branches (default) # 'upstream' : Push the current branch to whatever it is tracking # 'current' : Push the current branch default = upstream
  47. Push git push origin foobar:foobar Push into the branch with

    the same branch by default git push [push] # git >= v2.0 default = simple
  48. Track untracked file git add -N . Useful because git

    add patch only works on tracked file git add -p
  49. Rebase conflict HEAD master foobar Problem: sometimes it happens you

    have to resolves several times the same conflict while rebasing Solution: squash all your commits before rebasing on master
  50. Rebase conflict HEAD master foobar git rebase -i $(git merge-base

    master foobar) origin/master First rebase on yourself There won’t be any conflict here
  51. Rebase conflict HEAD master foobar origin/master pick 1df2b98 My green

    commit squash 3b7aff0 My yellow commit squash 2edf2b8 My purple commit
  52. Rebase conflict $ (vim the file.txt with the conflict) $

    git add file.txt $ git rebase --continue To resolve a rebase conflict $ git rebase --abort If you fucked up
  53. Branch diff $ git diff origin/master...foobar Diff for a whole

    branch $ git diff --name-status origin/master... Only display changed files $ git lg origin/master..foobar Log of the branch
  54. Git Stash git stash save "WIP something" Want to save

    your change, but don’t want to commit? git stash pop git stash list Try not to have too many thing in your stash, otherwise you will forgot it git stash show -p stash@{0}