Advanced Git - Olbat

Transcription

Advanced GitLuc SarzyniecXilopix, February 20151 / 86

AboutThis slides are using resources from the Pro Git book [isbn:1430218339]which is licensed under the Creative Commons v3.0 (by-nc-sa) license.The sources of the book can be found at https://github.com/progit/progit2 .The sources of this slides can be found dvanced-git .2 / 86

Summary1. Overview2. Basic usage3. Work with branches4. Rewrite history5. Code introspection6. Useful commands7. Internals3 / 86

OverviewOriginally developed to work on the GNU/Linux kernelFirst release in 2005 (1 year after subversion 1.0)Free software (GPLv2)Main goalsSpeedSimple designData integritySupport for distributed workflowsSupport for non-linear development4 / 86

Finding documentationRead the manualWell writtenA lot of examplesPro Git bookVery completeEasy to read/understandAvailable in different formatsOther books5 / 86

A distributed revision control system[Pro Git, chapter 5]6 / 86

A distributed revision control systemCentralized work ow7 / 86

A distributed revision control systemIntegration manager work ow8 / 86

A distributed revision control systemDictator and Lieutenants work ow9 / 86

Git basics[Pro Git, chapter 2]10 / 86

Start to work1. Create an empty (sandbox) repository git init --bare /tmp/sandbox.git2. Clone the repository git clone file:///tmp/sandbox.git3. Start to work in the master branch cd /tmp/sandbox git checkout -b master11 / 86

State of the repository[Pro Git, chapter 2.2]12 / 86

State of the repositoryState of the repository in long format git statusChanges to be committed:new file:staged filedeleted:fileChanges not staged for commit:modified:modified fileUntracked files:new fileState of the repository in short format git status -s # --shortD fileM modified fileA staged file? new file13 / 86

State of les14 / 86

HEAD, index and working dir.[Git blog, reset]15 / 86

Planing modi cations[Pro Git, chapter 2.2]16 / 86

Staging modi cationsStage only some parts of a file (interactive) git add -p FILE # --patchStage all indexed files that has changed git add -u # --updateStage both modified and untracked files git add -A # --allUnstage staged files git reset HEAD FILE1 FILE2 . FILEn17 / 86

Discard local modi cationsDiscard changes in files git checkout -- FILE1 FILE2 . FILEnUndo commit and keep modified/new files in index git reset --soft HEAD Undo commit and remove modified/new files from index git reset HEAD Undo commit and undo changes to indexed files git reset --hard HEAD [Pro Git, chapter 2.4]18 / 86

Save repository state w/o commitStash some modifications (saves the current diff) git status -sA fileM modified fileD removed file? untracked file git stash save git status -s? untracked fileList current stashed changes git stash listHEAD is now at ce499bc commitstash@{0}: WIP on test: ce499bc commitstash@{1}: WIP on master: 0029594 commit2[Pro Git, chapter 7.3]19 / 86

Save repository state w/o commitDisplay a specific stash git stash show stash@{0} # -p to show in diff formatfile 1 modified file 2 removed file 03 files changed, 2 insertions( ), 1 deletion(-)Apply stashed changes (apply diff) git stash apply # stash@{0} git status -sA fileM modified fileD removed file? untracked fileCreate a new branch and apply stashed changes in the top of itgit stash branch # stash@{0}20 / 86

Save modi cations21 / 86

Commit changesCommit and specify message on the CLI git commit -m 'message'Skip the staging area git commit -m "message" -a # git add -a && commitSelect what to commit (interactive) git commit -m "message" -p # git add -p && commitRewrite (amend) the last commit (staged files will be added in the commit) git commit --amend # --no-edit22 / 86

View modi cations23 / 86

View modi cationsView unstaged modifications git diffView staged modifications git diff --cachedView modifications between two branches git diff master.develop git diff origin/develop.developView changes of a specific file git diff -- filename git diff master.develop -- filename24 / 86

View modi cationsSummary of changes git diff --statShow bitwise diff git diff --color-wordsView changes of a specific commit git show HEAD Show the content of a file in a specified version git show HEAD :filename git show fa616be:filename25 / 86

Explore the history[Pro Git, chapter 2.3]26 / 86

Exploring the historyShow the history of another branch in short version git log --oneline branchnameShow the history with branch names git log --decorate # git config --global log.decorate trueShow graph version of the history git log --graph # --all to display every branchesSummary of history gouped by author git shortlog27 / 86

Specifying revisionsThe previous commit: HEAD , HEAD , HEAD 1The previous commit of the develop branch: develop 1 or develop 1Two commit before fa616be: fa616be 2 or fa616be Three commit before this commit: HEAD 3 or HEAD Commit treeGH\ /D\IRevisionsJ\ /F/ \E \ / \ / BC\/\ /AABCDEFGHIJ A A 2A B 2B 3A D 2F F 2 A 0A 1A 2A 1 1A 2A 3A 1 1 1B 2B 3 B 3 2 A 1 A 2 A 3A 2 A 2 2A 3 A 3 2[git rev-parse manual, section SPECIFYING REVISIONS]28 / 86

Work in team[Pro Git, chapter 2.5 and chapter 5.2]29 / 86

Download and upload changesPush the current branch to the remote branch with the same name git push origin HEADPush several new branches to the remote git push origin branchname name:othername HEAD:name HEADDelete a branch on the remote git push origin :branchnameDelete local branches that track deleted remote branches git fetch origin -p # --pruneFetch changes from a remote branch in a specific local branch git fetch origin master:latest master[Pro Git, chapter 3.5]30 / 86

Working with remotesLocal view find .git/refs -type rigin/remotebranchClassic stateC1C2C3uri:///project.git/refs/heads/master /origin/master master -----------------------*(local,read-write)31 / 86

Fetch and PullFetch (git fetch origin master)C1C2C3uri:///project.git/refs/heads/master ----*----*----*(remote,read-write) updateC1C2vrefs/remotes/origin/master --------------*----* *(local,read-only)C3C1refs/heads/master -----------------------*(local,read-write)Pull (git pull origin master or git fetch origin master ----*----*----*(remote,read-write) updateC1C2vrefs/remotes/origin/master --------------*----* *(local,read-only) mergeC1vrefs/heads/master -----------------------* * *(local,read-write)C2C332 / 86

Discard remote modi cationsRevert commits (applies the reverse diffs) git revert COMMIT1 COMMIT2 . COMMITn git push origin HEADOverride a remote branch with a local one git rebase -i . # rewrite history git push --force-with-lease origin HEAD # (to avoid with shared branches)33 / 86

Working with branches[Pro Git, chapter 3]34 / 86

Working in branches git branch testing35 / 86

Working in branches git checkout testing36 / 86

Working in branches git add . && git commit . # in testing37 / 86

Working in branches git checkout master38 / 86

Working in branches git add . && git commit . # in master39 / 86

Working with branchesShow history of HEAD's values (find deleted/reseted branch) git reflogCreate and checkout a new branch based on an existing one git checkout -b feature origin/masterCheckout a new empty branch git checkout --orphan newbranch git rm -r --cached .Clean: remove every local branch that has been mergedgit branch --merged master grep -v ' \*' xargs -n 1 git branch -d40 / 86

Integrate changes between branches[Pro Git, chapter 5.3]41 / 86

Integrate changes between branchesSimple divergent history42 / 86

Integrate changes between branchesMerging git checkout master git merge experiment[Pro Git, chapter 3.2]43 / 86

Integrate changes between branchesSimple divergent history44 / 86

Integrate changes between branchesRebasing git checkout experiment git rebase master[Pro Git, chapter 3.6]45 / 86

Integrate changes between branchesRebasing git checkout master git merge --ff experiment46 / 86

Integrate changes between branchesComplex divergent history47 / 86

Integrate changes between branchesRebase a branch onto another git rebase --onto master server client48 / 86

Integrate changes between branchesRebase a branch onto another git checkout master git merge --ff client49 / 86

Integrate changes between branchesAnother simple divergent history50 / 86

Integrate changes between branchesCherry-Picking (applies the diff of a commit on another branch) git checkout master git cherry-pick e43a6[Pro Git, chapter 5.3]51 / 86

Integrate changes between branchesCherry-Picking and keep track of the original commit git checkout master git cherry-pick -x db3e256ed4a23c92077aa2f136edab95970e8597 git show HEADcommit 841a4e2375b5dc586c283fd4fb6f1f0a9ee443d3 (HEAD, master)Author: Luc Sarzyniec luc.sarzyniec@xilopix.com Date:Tue Feb 24 08:27:00 2015 0100commit4(cherry picked from commit db3e256ed4a23c92077aa2f136edab95970e8597)52 / 86

Rewrite history[Pro Git, chapter 7.6]53 / 86

Rewrite historyRewrite (amend) the last commit # git add .; git rm . git commit --amend # --no-editRewrite several commits git rebasepick f7f3f6dpick 310154epick a5f4a0d-i HEAD 3commit 4commit 5commit 6# Rebase 710f0f8.a5f4a0d onto 710f0f8## 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 shell54 / 86

Rewrite historyRewrite commit messages only git rebase -i HEAD 3pick f7f3f6d commit 4reword 310154e commit 5pick a5f4a0d commit 6Re-order commits git rebasepick 310154epick f7f3f6dpick a5f4a0d-i HEAD 3commit 5 # commit 4 # - commit 6Delete commits git rebase -i HEAD 3pick f7f3f6d commit 4pick a5f4a0d commit 655 / 86

Rewrite historyEdit several commits56 / 86

Edit several commitsSelect which commit to edit git rebase -i HEAD 3edit f7f3f6d commit 4edit 310154e commit 5pick a5f4a0d commit 6# Save and quitStopped at f7f3f6d . commit 4You can amend the commit now, withgit commit --amendOnce you are satisfied with your changes, rungit rebase --continueRewrite the first commit# edit files git add . # git rm . git commit --amend57 / 86

Edit several commitsContinue with the second commit git rebase --continueStopped at 310154e . commit 5# edit files git add . # git rm . git commit --amend git rebase --continueSuccessfully rebased and updated refs/heads/master.Check that everything was done as expected git log --oneline -353bb260 commit 4 # SHA1 has changed since files were modifiedf8765fa new commit 5 # SHA1 has changed since files and message were modified4fc3652 commit 6 # SHA1 has changed since parents were modified58 / 86

Rewrite historyMix commits59 / 86

Mix commitsSelect the commits to be mixed (with the previous commit) git rebase -i HEAD 3pick f7f3f6d commit 4squash 310154e commit 5pick a5f4a0d commit 6Create a new commit message# This is a combination of 2 commits.# The first commit's message is:commit 4# This is the 2nd commit message:commit 5Check that everything was done as expected git log --oneline -2pick f7f3f6d commit 4 and 5pick a5f4a0d commit 660 / 86

Rewrite historyInsert new commits61 / 86

Insert new commitsSelect where to insert the commit (after witch existing commit) git rebaseedit f7f3f6dedit 310154epick a5f4a0d-i HEAD 3commit 4commit 5commit 6Add files and create new commits gitgitgitgitgitadd . && git commit -m "commit 4-1"rebase --continueadd . && git commit -m "commit 5-1"add . && git commit -m "commit 5-2"rebase --continueCheck that everything was done as expected git log --oneline -6f7f3f6d commit 40737964 commit 4-1310154e commit 5fa96cb9 commit 5-126cd81d commit 5-2cc4ad9a commit 662 / 86

Rewrite historySplit commits63 / 86

Split commitsSelect the commits to split git rebasepick f7f3f6dedit 310154epick a5f4a0d-i HEAD 3commit 4commit 5commit 6Reset the current commit git reset HEAD Create several new commits git add . git commit -m 'first' git add . git commit -m 'second' git add . git commit -m 'third'64 / 86

Split commitsContinue once it's done git rebase --continueSuccessfully rebased and updated refs/heads/master.Check that everything was done as expected git log --oneline -5f7f3f6d commit 466b1120 firstafcd336 second4fc3652 thirda5f4a0d commit 665 / 86

Automatically rewrite historyAutomatically rewrite all the historygit filter-branch --tree-filter 'rm -f passwords.txt' HEADChange your email addressgit filter-branch --commit-filter 'if [ " GIT AUTHOR EMAIL" "schacon@localhost" ];thenGIT AUTHOR NAME "Scott Chacon";GIT AUTHOR EMAIL "schacon@example.com";git commit-tree " @";elsegit commit-tree " @";fi' HEAD66 / 86

Debugging[Pro Git, chapter 7.10]67 / 86

Code introspectionRead the code annotated with commit/line git blame -L 1,10 zlib.cb0613ce0 (Jonathan Nieder 2010-11-06b0613ce0 (Jonathan Nieder 2010-11-06b0613ce0 (Jonathan Nieder 2010-11-06b0613ce0 (Jonathan Nieder 2010-11-06b0613ce0 (Jonathan Nieder 2010-11-06b0613ce0 (Jonathan Nieder 2010-11-061a507fc1 (Junio C Hamano 2011-06-10b0613ce0 (Jonathan Nieder 2010-11-061a507fc1 (Junio C Hamano 2011-06-10b0613ce0 (Jonathan Nieder 2010-11-061a507fc1 (Junio C Hamano 2011-06-10b0613ce0 (Jonathan Nieder 2010-11-061a507fc1 (Junio C Hamano 2011-06-101a507fc1 (Junio C Hamano 2011-06-101a507fc1 (Junio C Hamano 2011-06-101a507fc1 (Junio C Hamano 2011-06-101a507fc1 (Junio C Hamano 2011-06-101a507fc1 (Junio C Hamano 2011-06-101a507fc1 (Junio C Hamano 2011-06-10b0613ce0 (Jonathan Nieder 14)15)16)17)18)19)20)/** zlib wrappers to make sure we don't* at init time.*/#include "cache.h"static const char *zerr to string(int s{switch (status) {case Z MEM ERROR:return "out of memory";case Z VERSION ERROR:return "wrong version";case Z NEED DICT:return "needs dictionarcase Z DATA ERROR:return "data stream errcase Z STREAM ERROR:return "stream consistedefault:68 / 86

Code introspectionIn short format git blame -L 1,10 -s zlib.cb0613ce0 1) /*b0613ce0 2) * zlib wrappers to make sure we don't silently miss errorsb0613ce0 3) * at init time.b0613ce0 4) */b0613ce0 5) #include "cache.h"b0613ce0 6)1a507fc1 7) static const char *zerr to string(int status)b0613ce0 8) {1a507fc1 9)switch (status) {b0613ce0 10)case Z MEM ERROR:1a507fc1 11)return "out of memory";b0613ce0 12)case Z VERSION ERROR:1a507fc1 13)return "wrong version";1a507fc1 14)case Z NEED DICT:1a507fc1 15)return "needs dictionary";1a507fc1 16)case Z DATA ERROR:1a507fc1 17)return "data stream error";1a507fc1 18)case Z STREAM ERROR:1a507fc1 19)return "stream consistency error";b0613ce0 20)default:69 / 86

Code introspectionSee where sections of code originally came from git blame -s -C -L 1,20 zlib.cb0613ce0 zlib.c1) /*39c68542 wrapper.c 2) * zlib wrappers to make sure we don't silently miss errors39c68542 wrapper.c 3) * at init time.39c68542 wrapper.c 4) */b0613ce0 zlib.c5) #include "cache.h"b0613ce0 zlib.c6)1a507fc1 zlib.c7) static const char *zerr to string(int status)b0613ce0 zlib.c8) {1a507fc1 zlib.c9) switch (status) {b0613ce0 zlib.c10) case Z MEM ERROR:1a507fc1 zlib.c11)return "out of memory";b0613ce0 zlib.c12) case Z VERSION ERROR:1a507fc1 zlib.c13)return "wrong version";1a507fc1 zlib.c14) case Z NEED DICT:1a507fc1 zlib.c15)return "needs dictionary";1a507fc1 zlib.c16) case Z DATA ERROR:1a507fc1 zlib.c17)return "data stream error";1a507fc1 zlib.c18) case Z STREAM ERROR:1a507fc1 zlib.c19)return "stream consistency error";b0613ce0 zlib.c20) default:70 / 86

Track a bug using binary searchStart to search, specify the commit of the last working version git bisect start HEAD v2.2.0Bisecting: 150 revisions left to test after this (roughly 7 steps)At each step specify if the current snapshot is working or not# Do some tests git bisect goodBisecting: 75 revisions left to test after this (roughly 6 steps)# Do some tests git bisect badBisecting: 37 revisions left to test after this (roughly 5 steps)# .Find the version that introduced the bug (- read the diff to understand)# .bcbdeb1a1256f777e52192fa7da0f7dbad680162 is the first bad commit git show -p bcbdeb1a1256f777e52192fa7da0f7dbad68016271 / 86

Track a bug automating binary searchFind a command or create a script to reproduce the bugrake test # ?Start the binary search git bisect start HEAD v2.2.0Use the script to automatically run the binary search git bisect run rake testStop the binary search procedure git bisect reset[See http://lwn.net/Articles/317154/]72 / 86

Other useful commands[Pro Git, chapter 7]73 / 86

Other useful commandsGrep in a specific commitgit grep test :lib/disco/common/service.rb:test connect()def test connect()Find in which tag a commit was included git describe --tag e untracked files from the working directory git clean # -d to remove directories tooCreate an archive of the repository (a commit/tag can be specified) git archive -o soft-2.2.0.tar.gz v2.2.074 / 86

Other useful commandsResolve conflicts using an external (GUI?) tool git mergetool[Pro Git, chapter 3.2]Share changes saving commits in a bundle file (can be sent by mail, .)Create the bundle file git bundle create repo.bundle HEAD masterLoad the downloaded bundle file git clone repo.bundle repo git fetch ./commits.bundle master:other-master[Pro Git, chapter 7.12]75 / 86

Memo tgitadd -pcheckout -- FILEreset REV # --soft/--hardstashcommit --amenddiff REV -- FILEdiff --color-wordsshow REV:FILElog --decorate --graphfetch origin BRANCH:OTHER BRANCHrevert REVrebase -i REVcherry-pick -x REVblame FILEbisect REV END REV STARTgrep STR REVcleanarchive -o FILE.tar.gz REV76 / 86

Internals[Pro Git, chapter 10]77 / 86

Git: content-addressable lesystemObject database, index SHA1 hashObjects are stored in the filesystem under the .git/objects directorySeveral kind of objects: commit, tree, blob, .Objects linking each-other (commits, trees)Compression on demand or when files are too big78 / 86

Git objects: blobsCreate and store a new blob (file) object: echo "Awesome!" git hash-object --stdin -w6d4ed2c98c4fbe835280634af0cbddefffaf7ee6 touch file && git hash-object -w filee69de29bb2d1d6434b8b29ae775ad8c2e48c5391Find this object in the filesystem find 98c4fbe835280634af0cbddefffaf7ee6Get information about the object git cat-file -t 6d4ed2c98c4fbe835280634af0cbddefffaf7ee6blob git cat-file -p 6d4ed2c98c4fbe835280634af0cbddefffaf7ee6Awesome!79 / 86

Git objects representationContent of the file associated to the object cat 7ee6xKÊÉOR dp,O-ÎÏMUä,Sdeflate (zip,gzip,zlib,.) decompressed content cat 7ee6 \openssl zlib -d od -vtc -tx10000000blob9 \0Awesome!62 6c 6f 62 20 39 00 41 77 65 73 6f 6d 65 21 0a\nCalculation of the SHA1 hash associated of the object printf %b 'blob 9\0Awesome!\n' sha1sum6d4ed2c98c4fbe835280634af0cbddefffaf7ee6 *-80 / 86

Git objects: commits and treesContent of a commit object git cat-file -p (git rev-parse HEAD) # 00c4dfee3c28787870d2574a50c5de3725d5fcfbtree 4814e377c18f2da9cce56631f24e0d09181b0febparent e8a0d201e0b701d7c2de28cb33fa03ef59b22506author Luc Sarzyniec luc.sarzyniec@xilopix.com 1424853891 0100committer Luc Sarzyniec luc.sarzyniec@xilopix.com 1424853895 0100Commit messageContent of a tree object git cat-file -p (git rev-parse HEAD {tree}) # 4814e377c18f2da9cce56631f24e0d09181b0feb040000 tree e4af7700f8c091d18cc15f39c184490125fb0d17dir100644 blob 4 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391file3 git cat-file -p e4af7700f8c091d18cc15f39c184490125fb0d17100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391file281 / 86

A commit82 / 86

History83 / 86

Branches84 / 86

BranchesBranch pointer on a commit object cat d3088cbe69a8HEAD pointer on the current branch cat .git/HEADref: refs/heads/masterCreate a branch echo 7f4ba4b6e3ba7075ca6b379ba23fd3088cbe69a8 .git/refs/heads/testLocal and remote branches find .git/refs -type /master85 / 86

Thank you !86 / 86

git push origin branchname name:othername HEAD:name HEAD Delete a branch on the remote git push origin :branchname Delete local branches that track deleted remote branches git fetch origin -p # --prune Fetch changes from a remote branch in a specific local branch git fetch origin master:latest_master [Pro Git, chapter 3.5] 30 / 86