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

Understanding git

Understanding git

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

F135ce7f204af6fac8075b469685c91d?s=128

Matthieu Moquet

October 09, 2014
Tweet

Transcript

  1. None
  2. Today’s topics

  3. 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
  4. Requirement Before using Git, make sure you correctly configured your

    user: git config --global user.name "Matthieu Moquet"
 git config --global user.email matthieu@moquet.net write in your global ~/.gitconfig Your real name
  5. 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.
  6. src/ Foobar.php Baz.php README.md src/ Foobar.php Baz.php README.md Workspace

  7. src/ Foobar.php Baz.php README.md abcdef234 Initial commit Workspace

  8. src/ Foobar.php Baz.php README.md New.php src/ Foobar.php Baz.php README.md New.php

    abcdef234 Initial commit Workspace
  9. src/ Foobar.php Baz.php README.md New.php deadbeef42 A new file abcdef234

    Initial commit Workspace
  10. 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
  11. 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
  12. 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!
  13. How to commit?

  14. How to commit? Workspace Staging area Commit git add file.txt

  15. How to commit? Workspace Staging area Commit git add file.txt

    git commit
  16. How to commit? Workspace Staging area Commit git add file.txt

    git commit
  17. ➜ 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
  18. ➜ git commit -A -m "Your commit message" Shortcut git

    add ALL FILES inline commit message
  19. 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
  20. ➜ 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
  21. Best practice commit 9342a5bf855042b29a2ebd3413ce8e6cfb65557f Author: Matthieu Moquet <matthieu@moquet.net> 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.
  22. Best practice commit c1230da7409d22fe78263da777da237e9fc702d4 Author: Matthieu Moquet <matthieu@moquet.net> 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
  23. How to display the diff between commits?

  24. 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?
  25. 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?
  26. Remember when I said a commit is immutable?

  27. What if I made a mistake and want to rollback

    the committed code?
  28. Case #1 I made a typo on my previous commit,

    let’s fix it quickly
  29. 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
  30. Case #2 I want to remove the previous commit

  31. 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
  32. Case #3 I need to revert one or several commits

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

    revert abc123 Create a new commit, which is the opposite of the given one
  34. demo

  35. git log

  36. 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
  37. commit 9342a5bf855042b29a2ebd3413ce8e6cfb65557f Author: Matthieu Moquet <matthieu@moquet.net> 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 <matthieu@moquet.net> Date: Tue Jul 30 12:34:56 2014 +0200 ! Update README.md ! commit c1230da7409d22fe78263da777da237e9fc702d4 Author: Matthieu Moquet <matthieu@moquet.net> 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
  38. [alias] lg = log --graph --abbrev-commit --date=relative \ --pretty=tformat:'%Cred%h%Creset -...

    %s %Cgreen(%an %cr)%Creset' git log Shortcut
  39. * 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
  40. git checkout HEAD

  41. git checkout master fear8342abc Update foobar abcdef234 Initial commit deadb33f42

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

    deadb33f42 A new file Workspace copy files
  43. src/ Foobar.php Baz.php README.md New.php fear8342abc Update foobar abcdef234 Initial

    commit deadb33f42 A new file Workspace HEAD
  44. src/ Foobar.php Baz.php README.md New.php fear8342abc Update foobar abcdef234 Initial

    commit deadb33f42 A new file Workspace HEAD
  45. Workspace src/ Foobar.php Baz.php README.md fear8342abc Update foobar abcdef234 Initial

    commit deadb33f42 A new file HEAD
  46. git checkout abcd1234 -- file.txt Copy the file.txt from abcd1234

    to local workspace
  47. git checkout HEAD -- file.txt Cancel the changes of file.txt

    git checkout file.txt
  48. Branches

  49. 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
  50. 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
  51. Branches When committing, the reference pointed by the HEAD is

    moved to the new commit master HEAD abcdef234 Initial commit deadb33f42 A new file
  52. 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
  53. 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
  54. 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
  55. Shortcut Create a new branch and checkout it immediately. ➜

    git branch foobar ; git checkout foobar ➜ git checkout -b foobar
  56. demo

  57. 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.
  58. foobar HEAD master ➜ git merge foobar Divergence —> create

    new commit
  59. foobar HEAD master ➜ git merge foobar Divergence —> create

    new commit
  60. foobar HEAD master ➜ git merge foobar No divergence —>

    Fast Forward
  61. foobar HEAD master ➜ git merge foobar No divergence —>

    Fast Forward
  62. foobar HEAD master ➜ git merge foobar --no-ff Force no

    Fast Forward
  63. foobar HEAD master ➜ git merge foobar --no-ff Force no

    Fast Forward
  64. History manipulation

  65. Merge Hell

  66. More readable

  67. Better (no fast-forward)

  68. HEAD master Understanding cherry-pick foobar Cherry-pick make a copy of

    a given commit
  69. HEAD master Understanding cherry-pick ➜ git cherry-pick foobar~ foobar

  70. HEAD master foobar Understanding cherry-pick ➜ git cherry-pick foobar

  71. HEAD master foobar Understanding cherry-pick ➜ git branch -D foobar

  72. HEAD master Understanding cherry-pick

  73. Let’s automatize with Rebase

  74. HEAD master Let’s automatize with Rebase ➜ git rebase master

    foobar
  75. HEAD master Let’s automatize with Rebase foobar ➜ git rebase

    master
  76. master Let’s automatize with Rebase foobar HEAD ➜ git rebase

    master
  77. master Let’s automatize with Rebase foobar HEAD ➜ git rebase

    master
  78. HEAD master Let’s automatize with Rebase foobar ➜ git merge

    --no-ff foobar master
  79. HEAD master Let’s automatize with Rebase foobar ➜ git merge

    --no-ff foobar master
  80. Interactive Rebase

  81. HEAD master Interactive Rebase ➜ git rebase -i master foobar

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

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

  84. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  85. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  86. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  87. HEAD master Interactive Rebase ➜ git rebase -i master foobar

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

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

  90. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  91. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  92. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  93. master Interactive Rebase ➜ git rebase -i master foobar HEAD

  94. 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
  95. demo

  96. Working with a remote server

  97. origin/master origin/foobar Working with a remote server git clone git@server.com

    master foobar
  98. Working with a remote server origin/master master origin/foobar master foobar

  99. 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
  100. Updating your local copy of remote branches origin/master master origin/foobar

    master foobar git fetch fetch will only update the origin/* branches
  101. Updating your local branch fast-forward master master origin/master

  102. master master origin/master git fetch Updating your local branch fast-forward

  103. master master origin/master git fetch Updating your local branch fast-forward

  104. master master origin/master git merge origin/master master Updating your local

    branch fast-forward
  105. master master origin/master Updating your local branch fast-forward

  106. Shortcut: git pull git pull origin master == git fetch

    origin ; git merge origin/master
  107. Protip Never use git pull, except for master branch* *because

    you’re not supposed to have divergence with master
  108. master origin/master Updating your local branch with divergence master

  109. origin/master Updating your local branch with divergence master master someone

    have added commits into master
  110. master origin/master Updating your local branch with divergence master me

    too git fetch
  111. origin/master Updating your local branch with divergence master master git

    merge origin/master master
  112. origin/master Updating your local branch with divergence master master Way

    to Merge-Hell (even with a single branch)
  113. origin/master Updating your local branch with divergence master master git

    rebase origin/master
  114. origin/master Updating your local branch with divergence master master

  115. origin/master Updating your local branch with divergence master master git

    push origin master
  116. origin/master Updating your local branch with divergence master master

  117. Never use git pull. Instead do git fetch + git

    rebase or git pull --rebase
  118. Basic Git Workflow

  119. Master Initially we only have one master branch Basic Git

    Workflow
  120. Master Branch We create a new branch to start a

    new feature Basic Git Workflow
  121. Master Branch Once the feature done, we merge it into

    master Basic Git Workflow
  122. Master Then we can safely delete the branch Basic Git

    Workflow
  123. master master origin/master Basic Git Workflow ➜ git chekcout -b

    dev ➜ git commit; git commit
  124. master master dev origin/master Basic Git Workflow ➜ git push

    origin dev
  125. master master dev origin/master Basic Git Workflow dev origin/dev Meanwhile,

    master have been updated…
  126. master master dev origin/master Basic Git Workflow dev origin/dev ➜

    git fetch
  127. master master origin/master Basic Git Workflow dev origin/dev dev ➜

    git rebase origin/master
  128. master master origin/master Basic Git Workflow dev origin/dev dev

  129. master master origin/master Basic Git Workflow dev origin/dev dev git

    push origin dev Server will reject the push because of the divergence
  130. 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
  131. master master origin/master Basic Git Workflow origin/dev dev git push

    -f origin dev dev
  132. master master origin/master Basic Git Workflow origin/dev dev dev ➜

    git merge --no-ff dev master
  133. master master origin/master Basic Git Workflow origin/dev dev Merged with

    Stash (non fast-forward)
  134. master master origin/master Basic Git Workflow origin/dev dev Prune option

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

    master ! ➜ git merge origin/master or ➜ git pull
  136. master origin/master Basic Git Workflow dev master ➜ git branch

    -d dev
  137. master origin/master Basic Git Workflow master

  138. TL;DR

  139. ➜ 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
  140. Bonus

  141. 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
  142. 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
  143. Push git push origin foobar:foobar Push into the branch with

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

    add patch only works on tracked file git add -p
  145. 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
  146. Rebase conflict HEAD master foobar conflicts (1) git rebase origin/master

    origin/master
  147. Rebase conflict HEAD master foobar conflicts (2) origin/master

  148. Rebase conflict HEAD master foobar conflicts (3) origin/master

  149. 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
  150. Rebase conflict HEAD master foobar origin/master pick 1df2b98 My green

    commit squash 3b7aff0 My yellow commit squash 2edf2b8 My purple commit
  151. Rebase conflict HEAD master origin/master

  152. Rebase conflict master origin/master HEAD

  153. Rebase conflict master origin/master HEAD

  154. Rebase conflict master origin/master HEAD

  155. Rebase conflict master origin/master HEAD

  156. Rebase conflict master origin/master HEAD foobar

  157. Rebase conflict master origin/master HEAD foobar git rebase origin/master Then

    you can rebase on master
  158. Rebase conflict master origin/master HEAD foobar git rebase origin/master Resolve

    conflicts once
  159. 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
  160. 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
  161. Branch naming feat-description-1234 feat-description-BBCTHREE-1234 fix-description-1234 Internal convention to name a

    branch
  162. 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}
  163. (last) demo

  164. http://git-scm.com/ https://try.github.io/ http://pcottle.github.io/learnGitBranching/ http://www.git-attitude.fr/2014/05/04/bien-utiliser-git-merge-et-rebase/ http://www.git-attitude.fr/2014/09/15/30-options-git-qui-gagnent-a-etre-connues/ Links