git: your best friend, ever
TRANSCRIPT
![Page 1: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/1.jpg)
GITYOUR BEST FRIEND, EVER
Chris Antes
chrisdoingweb.com
github.com/doingweb
![Page 2: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/2.jpg)
WHAT IS GIT?
![Page 3: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/3.jpg)
WHAT IS GIT?"Version Control""Revision Control""Source Control"
![Page 4: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/4.jpg)
WHAT IS VERSION CONTROL?Snapshots of your work.
![Page 5: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/5.jpg)
WHY DO YOU NEEDVERSION CONTROL?
![Page 6: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/6.jpg)
"SAVE AS" ONLY WORKS FOR SO LONG.
![Page 7: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/7.jpg)
YOUR CODE WILL BREAK.
![Page 8: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/8.jpg)
YOU’RE TRYING TO COLLABORATE ON APROGRAMMING PROJECT THROUGH
DROPBOX.
![Page 9: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/9.jpg)
WHAT ABOUT OTHERVERSION CONTROL
SYSTEMS?
![Page 10: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/10.jpg)
TRY THEM TOO!
CVS
![Page 11: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/11.jpg)
GIT IS NOW THE MOST POPULAR.
![Page 12: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/12.jpg)
MUCH OF THE OPEN SOURCE COMMUNITYNOW LIVES ON GITHUB.
This slide deck is !on GitHub
![Page 13: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/13.jpg)
ANATOMY OF A GITREPOSITORY
![Page 14: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/14.jpg)
IT'S JUST A DIRECTORY!
![Page 15: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/15.jpg)
LET'S CREATE A REPOSITORY!$ git initInitialized empty Git repository in .git/
The current directory becomes the working directory for the new Git repository.
![Page 16: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/16.jpg)
THE WORKING DIRECTORY
![Page 17: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/17.jpg)
COMMITTING
![Page 18: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/18.jpg)
PUTTING IN WORK
![Page 19: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/19.jpg)
THE LIFECYCLE OF A FILE
![Page 20: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/20.jpg)
THE LIFECYCLE OF A FILEAdding a file:
$ git statusOn branch masternothing to commit, working directory clean$ atom newfile.txt$ git statusOn branch masterUntracked files: (use "git add ..." to include in what will be committed)
newfile.txt
nothing added to commit but untracked files present (use "git add" to track)$ git add newfile.txt$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)
![Page 21: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/21.jpg)
THE LIFECYCLE OF A FILEModifying a file:
$ git statusOn branch masternothing to commit, working directory clean$ atom newfile.txt$ git statusOn branch masterChanges not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout ..." to discard changes in working directory)
modified: newfile.txt
no changes added to commit (use "git add" and/or "git commit a")$ git add newfile.txt$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)
![Page 22: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/22.jpg)
THE LIFECYCLE OF A FILERemoving a file:
$ git statusOn branch masternothing to commit, working directory clean$ git rm newfile.txtrm 'newfile.txt'$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)
deleted: newfile.txt
$ git commit message="Removed the file."[master 0d229e7] Removed the file. 1 file changed, 2 deletions() delete mode 100644 newfile.txt$ git statusOn branch master
![Page 23: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/23.jpg)
AMENDING A COMMITRedo commits with git commit ‐‐amend:
$ git log oneline maxcount 20d229e7 Removed the file.9bb1e7e Modified the file.$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)
new file: catnames.txt
$ git commit message="Needed soem cat names."[master 2e6c3b7] Needed soem cat names. 1 file changed, 1 insertion(+) create mode 100644 catnames.txt$ git log oneline maxcount 22e6c3b7 Needed soem cat names.0d229e7 Removed the file.$ git commit amend message="Needed some cat names."
Note that this changes history!
![Page 24: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/24.jpg)
.gitignore# We want these files in our working directory, but not in our repository.
# Log files*.log
# Build output directorybuild/
# Thirdparty packagesnode_modules
Matching files not already in the repository are ignored:$ atom newfilethatgetsignored.log$ git statusOn branch masternothing to commit, working directory clean
![Page 25: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/25.jpg)
WHERE DO COMMITS GO?
You might recognize this structure from .eariler
![Page 26: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/26.jpg)
WHERE DO COMMITS GO?We can see the list of commits with git log:
$ git log oneline1eb2ce2 Slides on other VCSs. Refinements to previous slides.8516b87 Rewording Dropbox slide.1377305 Using drop shadow to set off images. Adding autoprefixer to build.b1b1dc8 Slides about why you need version control. Styles for headings against background images.2d05220 Bringing in the rest of the existing slides.ba54632 Updating Reveal.js to v3.0.0. Adding images. Using `slide` transition.4d51b9b Adding slides. Reducing indentation to 2 spaces. Copying in custom theme.fe0ddab Initial, from `yo reveal`.
![Page 27: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/27.jpg)
WHERE DO COMMITS GO?Commits live in the key-value store (.git/objects directory):
$ ls R .git/objects.git/objects:1e 5e ce info pack
.git/objects/1e:b98e70230c45fa1b61eab232ec1f66b29c8625
.git/objects/5e:08bc4c2da476233573fc7c4793412cede36bfa
.git/objects/ce:013625030ba8dba906f756967f9e9ca394464a
.git/objects/info:
.git/objects/pack:
![Page 28: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/28.jpg)
WHAT'S IN A COMMIT?
![Page 29: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/29.jpg)
WHAT'S IN A COMMIT?Let's go look at a raw commit!
git cat‐file gets objects from the key-value store:$ git catfile p 1eb2ce28cd1b6e89e9a9ed2f4681cb834a48fc87tree 48b8b000be35eb9d739aa63b5556226405745e86parent 8516b87e1307db03994c619693e2669a1d825608author Chris Antes 1426921898 0700committer Chris Antes 1426921898 0700
Slides on other VCSs. Refinements to previous slides.
![Page 30: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/30.jpg)
WHAT'S IN A COMMIT?Now let's get the commit's tree:
$ git catfile p 48b8b000be35eb9d739aa63b5556226405745e86100644 blob 69fad358018d530235f8e43c483d3ce960616a32 .bowerrc100644 blob d1d8a4176a416daffcfbfecdd3f35f24bd79fc7d .editorconfig100644 blob 3518e7f29dcc2b195d7077d989efa3f6bd6cfbef .gitignore100644 blob 855a9efe0a6aff5c442fbd1dc26a5af279d66b72 .jshintrc100644 blob 41ea8d4c4629041d42e6f090e41dcd3d5eace1eb .yorc.json100644 blob a62946614b7f1c3c43990b0cb39c2677060effc7 Gruntfile.coffee100644 blob 6f7daeaa8cf04b03638ddd6509a2508efee2b5cd bower.json040000 tree c38c7e40dc6b3671486d99d2cc3a15c4a36cd604 css040000 tree fc4a211f73968d6efb124f296f70acd9610eb19a images040000 tree 449df7430c1f8db1c0922d1fbc2ec99fb8ec3701 js100644 blob 0eeb399333af39939d3c83691747f7cf30a002ee package.json040000 tree b938f6a0fd291522d106549360c0a7facdaf1f30 slides040000 tree e4eaa88c5ddd86fd4a6a95bf2769d36565863dd8 templates
![Page 31: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/31.jpg)
WHAT'S IN A COMMIT?Let's see what a blob looks like:
$ git catfile p 0eeb399333af39939d3c83691747f7cf30a002ee "name": "gityourbestfriendever", "version": "0.0.0", "private": true, "devDependencies": "grunt": "^0.4.5", "gruntautoprefixer": "^2.2.0", "gruntcoffeelint": "0.0.13", "gruntcontribconnect": "^0.9.0", "gruntcontribcopy": "^0.7.0", "gruntcontribjshint": "^0.10.0", "gruntcontribsass": "^0.8.0", "gruntcontribwatch": "^0.6.1", "loadgrunttasks": "^1.0.0" , "engines": "node": ">=0.10.0",
![Page 32: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/32.jpg)
NOT TOO BAD, RIGHT?It's just linked lists and trees and stuff!
![Page 33: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/33.jpg)
LET'S GET BACK TO THE PRACTICAL BITS!
![Page 34: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/34.jpg)
BRANCHING
![Page 35: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/35.jpg)
WHY BRANCH?So we can work like this:
![Page 36: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/36.jpg)
WHAT IS A BRANCH?They're just pointers (also known as refs)! v1.0 and master are branches:
![Page 37: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/37.jpg)
WHAT'S HEAD?HEAD is just a pointer to the current branch.
$ git statusOn branch masternothing to commit, working directory clean$ cat .git/HEADref: refs/heads/master
![Page 38: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/38.jpg)
SWITCHING BRANCHESSwitch branches with git checkout:
$ git branch list* master testing$ git checkout testingSwitched to branch 'testing'
![Page 39: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/39.jpg)
CREATING BRANCHESCreate new branches with git branch:
$ git branch list* master$ git branch newfeature$ git branch list* master newfeature
Use git checkout ‐b to branch and switch in one command:$ git branch list* master$ git checkout b newfeatureSwitched to a new branch 'newfeature'$ git branch list master* newfeature
![Page 40: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/40.jpg)
DELETING BRANCHESDelete branches with git branch ‐‐delete:
$ git branch list* master newfeature$ git branch delete newfeatureDeleted branch newfeature (was f3bc86a).$ git branch list* master
![Page 41: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/41.jpg)
RENAMING BRANCHESBranches can be renamed with git branch ‐‐move:
$ git branch list master* newfeature$ git branch move newfeature feature/starringitems$ git branch list* feature/starringitems master
![Page 42: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/42.jpg)
CHANGING WHERE A BRANCH POINTSgit reset changes where the HEAD branch points. And maybe some other stuff:
![Page 43: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/43.jpg)
TIME TRAVEL WITH git resetResetting is useful when some commits should've been on a different branch:
$ git statusOn branch masternothing to commit, working directory clean$ git log oneline4f00f1a Adding a few more cat names.9abff09 Needed some cat names.0d229e7 Removed the file.9bb1e7e Modified the file.015ba6c Added new file.$ git branch feature/catnames$ git reset hard HEAD~2HEAD is now at 0d229e7 Removed the file.$ git checkout feature/catnamesSwitched to branch 'feature/catnames'$ git log oneline4f00f1a Adding a few more cat names.9abff09 Needed some cat names.0d229e7 Removed the file.
![Page 44: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/44.jpg)
MERGING BRANCHESLet's say we've just fixed a bug and we want to merge our fix into master:
![Page 45: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/45.jpg)
MERGING BRANCHESgit merge performs a :3-way merge
![Page 46: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/46.jpg)
MERGING BRANCHES$ git checkout masterSwitched to branch 'master'$ git merge iss53Merge made by the 'recursive' strategy.index.html | 1 +1 file changed, 1 insertion(+)
![Page 47: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/47.jpg)
FAST-FORWARD MERGES$ git checkout masterSwitched to branch 'master'$ git merge hotfixUpdating f42c576..3a0874cFastforward index.html | 2 ++ 1 file changed, 2 insertions(+)
![Page 48: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/48.jpg)
MERGE CONFLICTS HAPPENLet's say I did some similar work on two branches that I now want to merge:
$ git merge feature/catnamesAutomerging catnames.txtCONFLICT (add/add): Merge conflict in catnames.txtAutomatic merge failed; fix conflicts and then commit the result.$ git statusOn branch masterYou have unmerged paths. (fix conflicts and run "git commit")
Unmerged paths: (use "git add ..." to mark resolution)
both added: catnames.txt
no changes added to commit (use "git add" and/or "git commit a")
So scary!
![Page 49: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/49.jpg)
MERGE CONFLICTS: NOT REALLY SO SCARYHere's what the conflicted file looks like:
<<<<<<< HEADFluffySocrates=======HaloHaloChairman Meow>>>>>>> feature/catnamesSadieWhiskersSimba
The <<<<<<<, =======, and >>>>>>> lines denote where the conflict(s) are.The HEAD section is what our file (what we're merging into) has.The other section is what their file (what we're merging from) has.The rest of the file has been merged automatically.
![Page 50: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/50.jpg)
RESOLVING CONFLICTSOnce we've manually merged our conflicted files, we use git add to tell Git that
we've resolved the conflicts, then we resume the merge commit with gitcommit:
$ git add catnames.txt$ git commit[master b98a343] Merge branch 'feature/catnames'
![Page 51: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/51.jpg)
REBASINGReplay commits as if you had based them off of a different commit:
$ git checkout experiment$ git rebase masterFirst, rewinding head to replay your work on top of it...Applying: added staged command
![Page 52: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/52.jpg)
REMOTES
![Page 53: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/53.jpg)
GIT IS DISTRIBUTED
![Page 54: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/54.jpg)
CLONING A REMOTECloning is the first step to working with an existing repository:
![Page 55: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/55.jpg)
KEEPING REMOTES UP-TO-DATEDownload new commits with git fetch:
![Page 56: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/56.jpg)
SHARING YOUR COMMITSgit push sends your commits to the in the upstream repository:tracked branch
$ git pushCounting objects: 20, done.Delta compression using up to 4 threads.Compressing objects: 100% (11/11), done.Writing objects: 100% (11/11), 276.23 KiB | 0 bytes/s, done.Total 11 (delta 5), reused 0 (delta 0)To [email protected]:doingweb/gityourbestfriendever.git 85c7fae..af42118 master > master
![Page 57: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/57.jpg)
PUSHING A NEW BRANCHImagine we created a local branch and have now decided we want to track it, to
make future pushes easier:$ git checkout b newfeatureSwitched to a new branch 'newfeature'$ git pushfatal: The current branch newfeature has no upstream branch.To push the current branch and set the remote as upstream, use
git push setupstream origin newfeature
$ git push setupstream origin newfeatureTotal 0 (delta 0), reused 0 (delta 0)To [email protected]:doingweb/gityourbestfriendever.git* [new branch] newfeature > newfeatureBranch newfeature set up to track remote branch newfeature from origin.$ git pushEverything uptodate
![Page 58: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/58.jpg)
COLLABORATING
![Page 59: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/59.jpg)
PUBLIC PROJECTS ON GITHUBContributing to public projects on GitHub and similar services usually goes
something like:
1. Fork the upstream repository.2. Clone your fork into your local workspace.3. Create a branch for your changes.4. Work!5. Push back up to your fork.6. Keep working and pushing until it's ready.7. Squash your commits.8. Open a pull request.9. Participate in the discussion about your changes, and work through any
issues that need to be addressed before it can be merged.
![Page 60: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/60.jpg)
TEAM PROJECTS ON GITHUBIt's entirely up to the team how they work together, and there are a lot of
combinations that work. Here's just one example for a small team:
1. Clone the repository into your local workspace.2. Create a branch for your changes.3. Work!4. Push back up to your branch.5. Keep working and pushing until it's ready.6. Open a pull request.7. Participate in the discussion about your changes, and work through any
issues that need to be addressed before it can be merged.
![Page 61: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/61.jpg)
OTHER REALLY USEFUL GIT COMMANDSI don't use these every day, but they're just so nice to have when you need them:
git log ‐‐grep="search terms"Searches commit messages. Accepts regular expressions.
git stashSaves the working directory changes onto a stack, so you can switch brancheswithout having to commit. git stash pop applies the topmost changes and
removes them from the stack.
git bisectPerform a binary search for the commit that introduced a bug.
![Page 62: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/62.jpg)
AND THAT'S GIT!
![Page 63: Git: Your Best Friend, Ever](https://reader031.vdocuments.us/reader031/viewer/2022020123/55a85dbc1a28abc60b8b488e/html5/thumbnails/63.jpg)
FURTHER READING by
Pro GitGit: It’s Just Data! Julie Lerman