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

Git Agility

Git Agility

An advanced ~3 hour git workshop that premiered in Turku Agile Day 2012

Jyrki Pulliainen

May 16, 2012
Tweet

More Decks by Jyrki Pulliainen

Other Decks in Technology

Transcript

  1. $ tree . ├── module │ ├── __init__.py │ └──

    main.py ├── README └── setup.py 1 directory, 4 files
  2. $ git symbolic-ref HEAD refs/heads/master $ git rev-parse refs/heads/master 533276ca932fd605644eddd2a08d5c556736c278

    $ git cat-file -p 533276ca tree 8f7bc7153c59949e10822512a9ceb07d470bd9ff parent a5c2044e43c5415330d26db1dd74e0b897b7179b author Jyrki Pulliainen <[email protected]> 1336331027 +0200 committer Jyrki Pulliainen <[email protected]> 1336331027 +0200 Remove reference to common.py
  3. COMMIT size tree 34ff parent 0d54 author jyrki committer jyrki

    some nice commit msg TREE size blob 14ff README blob fd21 setup.py tree dd98 module TREE size blob 9eab __init__.py blob cafe main.py BLOB size #!/usr/bin/python setup(...) BLOB size def main(...) BLOB size # Copyright supercorp b3cf 34ff fd21 dd98 9eab cafe
  4. $ git status # On branch master # Changes to

    be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: README # What's the difference between index and HEAD
  5. $ tree . ├── module │ ├── __init__.py │ └──

    main.py ├── README └── setup.py 1 directory, 4 files
  6. $ git status # On branch master # Changes not

    staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: README # no changes added to commit (use "git add" and/or "git commit -a") What's the difference between index and working directory
  7. File v. 1 HEAD INDEX WORKING DIRECTORY git add File

    v. 2 File v. 2 File v. 1 File v. 1 git reset
  8. HEAD INDEX WORKING DIRECTORY File v. 1 File v. 2

    File v. 2 File v. 1 git checkout File v. 1 File v. 1
  9. hard mixed [the default] soft Move the HEAD back, reset

    the index but leave working directory Move the HEAD back and reset the working directory Move the HEAD back
  10. Tutorial Edit a file in working directory and add it

    to index. Reset index, re-add and do hard reset. Edit the file again and commit this time. Do a soft reset and commit Try git checkout HEAD^ -- file
  11. Porcelain git add git commit git pull git fetch git

    merge git status .... Plumbing git apply git commit-tree git pack-objects git update-ref git write-tree git merge-index ...
  12. • <shaid>, eg. 'deadb33f' • <revname>, eg. 'v1.0' • <ref>,

    eg. 'master', 'origin/master' • <refname>@{<date>}, eg. master@{1 year ago} • <refname>@{<n>}, eg. master@{4} • <rev>^, eg. HEAD^ • <rev>~[n], eg. HEAD~5
  13. $ git show :/fix # Show latest commit containing "fix"

    $ git show :/^Merge # Show latest merge commit
  14. $ git show v1.0^{commit} # Show commit object related to

    tag v1.0 $ git show HEAD^{tree} # Show a tree that contains the full history Funny stuff, don't try at hom e
  15. Tutorial Find the last commit that talks about snakes Find

    the second parent of commit referenced by branch terrario
  16. $ git status # On branch master # Changes to

    be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: snakepit/__init__.py # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # snakepit/reptile.py
  17. $ git diff diff --git i/README w/README index bae3a1d..779cc2a 100644

    --- i/README +++ w/README @@ -3,4 +3,4 @@ Please read this. However, ignore this line, as this talks about something you don't really gain anything by reading it. -And you know, mice are the coolest animals in the world. +And you know, honey badgers are the coolest animals in the world. Do removals, modifications and untracked files. Compare output of status and short status. Add something in the index, see how diff --cached works
  18. $ git diff --word-diff diff --git i/README w/README index bae3a1d..779cc2a

    100644 --- i/README +++ w/README @@ -3,4 +3,4 @@ Please read this. However, ignore this line, as this talks about something you don't really gain anything by reading it. And you know, [-mice-]{+honey badgers+} are the coolest animals in the world.
  19. $ git log --graph --oneline --decorate * 57d3792 (HEAD, master)

    Merge branch 'reptiles' |\ | * fc78165 (reptiles) Declare reptiles! * | 46592b0 Change mice to honey badgers * | 19d7900 Expand README |/ * 514a1ad Add snakepit module * 9ab964b Initial commit
  20. $ git status -sb ## master M snakepit/reptile.py $ git

    diff --staged # some boilerplate removed +++ i/snakepit/reptile.py @@ -2,3 +2,7 @@ def is_reptile(reptile): if reptile is 'worm': return False return True + + +def snakes(): + return ['viper', 'python', 'boa']
  21. Tutorial Do removals, modifications and untracked files. Compare output of

    status and short status. Add something in the index, see how diff -- staged works
  22. Tutorial Add text to README. Use add -p to add

    it in to the index. Try patch reset to revert it, but use edit command for it, and try reverting it. Reset working dir with git checkout -p
  23. A B C D E my-branch master True m erge

    master F HEAD MERGE_HEAD HEAD
  24. $ git branch foo [ref] # Create a new branch

    foo at ref $ git checkout -b foo [ref] # Create a new branch foo at ref and switch to it $ git branch -d foo # Delete branch foo
  25. $ git checkout conflict # Create branch conflict at origin/conflict

    and set up # tracking $ git checkout -b conflict origin/conflict # Same as above $ git checkout -t conflict # Same as above $ git checkout -b conflict # Just create a local branch called conflict
  26. $ git push origin master # Push branch master to

    origin and create it, if it does # not exist $ git push origin master:new-master # Push master to remote branch new-master $ git push origin :master # Delete remote branch master $ git push origin +master # Force push master to origin overwriting the remote # information about master branch
  27. $ git push -u origin master # Push branch master

    to origin and create it, if it does # not exist. Set up tracking for the branch.
  28. $ git config --global push.default [value] # From man page:

    # nothing - do not push anything. # matching - push all matching branches. All branches # having the same name in both ends are considered to # be matching. This is the default. # upstream - push the current branch to its upstream # branch. # tracking - deprecated synonym for upstream. # current - push the current branch to a branch of the # same name.
  29. $ git diff diff --cc INSTRUCTIONS index 63c473b,8cf737a..0000000 --- i/INSTRUCTIONS

    +++ w/INSTRUCTIONS @@@ -1,1 -1,1 +1,5 @@@ ++<<<<<<< HEAD +There are important ones ++======= + There is none! ++>>>>>>> conflict
  30. $ git show :1:INSTRUCTIONS # the common ancestor $ git

    show :2:INSTRUCTIONS # the HEAD version (our) $ git show :3:INSTRUCTIONS # the MERGE_HEAD version (theirs)
  31. $ git checkout --ours INSTRUCTIONS # Check out our (HEAD)

    version of file $ git checkout --theirs INSTRUCTIONS # Their version of the file (MERGE_HEAD) $ git checkout -m INSTRUCTIONS # Check out the merge conflict version
  32. $ git diff diff --cc INSTRUCTIONS index 63c473b,8cf737a..0000000 --- i/INSTRUCTIONS

    +++ w/INSTRUCTIONS @@@ -1,1 -1,1 +1,1 @@@ - There are important ones -There is none! ++There are important nones!
  33. $ git add [file] # This is done, mark it

    as merged $ git reset --hard # reset the whole merge conflict
  34. $ git checkout --conflict=diff3 [file] # Create a three way

    diff with the common # base of the file
  35. $ git checkout --conflict=diff3 INSTRUCTIONS $ git diff diff --cc

    INSTRUCTIONS index 63c473b,8cf737a..0000000 --- i/INSTRUCTIONS +++ w/INSTRUCTIONS @@@ -1,1 -1,1 +1,7 @@@ ++<<<<<<< ours +There are important ones ++||||||| base ++There are some ++======= + There is none! ++>>>>>>> theirs
  36. $ git config merge.tool "tool" # valid values "araxis", "bc3",

    "diffuse", "ecmerge", # "emerge", "gvimdiff", "kdiff3","meld", "opendiff", # "p4merge", "tkdiff", "tortoisemerge", "vimdiff" and # "xxdiff" $ git mergetool
  37. Tutorial Merge branch conflict to master. View diff with git

    diff Investigate with git log --merge Try checking out different versions of file and reset with git checkout -m Try git checkout --conflict=diff3 Solve the merge
  38. $ git config --global rerere.enabled 1 $ git config --global

    rerere.autoupdate 1 # Not really necessary, as we'll see soon
  39. $ git merge conflict $ git rerere status # Solve

    merge conflict $ git add [file] $ git rerere diff $ git commit
  40. $ git merge conflict Auto-merging snakepit/reptile.py CONFLICT (add/add): Merge conflict

    in snakepit/reptile. py Auto-merging INSTRUCTIONS CONFLICT (add/add): Merge conflict in INSTRUCTIONS Resolved 'INSTRUCTIONS' using previous resolution. Resolved 'snakepit/reptile.py' using previous resolution.
  41. Tutorial Merge branch conflict-other to master. Use rerere to record

    resolution. Resolve conflict and commit. Reset master to state before merge. Check out conflict-other and rebase it on master.
  42. pick ab8f5ff Add some instructions pick d8c062e Add newline pick

    8e10e9b There are some important instructions # Rebase e9a922e..8e10e9b onto e9a922e # # 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 # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
  43. Tutorial Switch honeybadger and "Add snake" master. Rename "Add snake"

    to "Add viper". Rebase conflict on top of master. If you have rerere, what happened?
  44. $ git reflog 250ed94 HEAD@{0}: checkout: moving from master to

    terrario 250cfb0 HEAD@{1}: checkout: moving from terrario to master 250ed94 HEAD@{2}: checkout: moving from master to terrario 250cfb0 HEAD@{3}: commit: Add line to README. ad11e8c HEAD@{4}: reset: moving to HEAD~ b387bb7 HEAD@{5}: commit: Add line to README ad11e8c HEAD@{6}: clone: from [email protected]: nailor/git-training.git
  45. $ git status -sb ## master M snakepit/reptile.py $ git

    stash save 'def for later' Saved working directory and index state On master: def for later HEAD is now at ad11e8c Honeybadger here. $ git stash list stash@{0}: On master: def for later $ git stash show stash@{0} snakepit/reptile.py | 4 ++++ 1 file changed, 4 insertions(+)
  46. $ git stash [save] $ git stash --keep-index $ git

    stash --patch # git stash -p $ git stash --include-untracked # git stash -u
  47. $ git stash apply $ git stash pop $ git

    stash drop $ git stash branch <branchname>
  48. Tutorial Start bisect and mark 9ab964b9 as good and master

    as bad. Find commit that introduces honey badgers.
  49. $ git config --global alias.lokg \ --graph --abbrev-commit --pretty=oneline --decorate

    $ git config --global alias.unmerged \ '!f() { git ls-files --unmerged | cut -f2 | sort -u ; }; $EDITOR `f`' $ git config --global alias.add_unmerged \ '!f() { git ls-files --unmerged | cut -f2 | sort -u ; }; git add `f`'
  50. $ git clean -f # Actually do something $ git

    clean -x # Remove files in gitignore $ git clean -d # Remove untracked directories $ git clean -X # Remove only files ignored by git