git: your best friend, ever

Post on 17-Jul-2015

82 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

GITYOUR BEST FRIEND, EVER

Chris Antes

chrisdoingweb.com

github.com/doingweb

WHAT IS GIT?

WHAT IS GIT?"Version Control""Revision Control""Source Control"

WHAT IS VERSION CONTROL?Snapshots of your work.

WHY DO YOU NEEDVERSION CONTROL?

"SAVE AS" ONLY WORKS FOR SO LONG.

YOUR CODE WILL BREAK.

YOU’RE TRYING TO COLLABORATE ON APROGRAMMING PROJECT THROUGH

DROPBOX.

WHAT ABOUT OTHERVERSION CONTROL

SYSTEMS?

TRY THEM TOO!

CVS

GIT IS NOW THE MOST POPULAR.

MUCH OF THE OPEN SOURCE COMMUNITYNOW LIVES ON GITHUB.

This slide deck is !on GitHub

ANATOMY OF A GITREPOSITORY

IT'S JUST A DIRECTORY!

LET'S CREATE A REPOSITORY!$ git initInitialized empty Git repository in .git/

The current directory becomes the working directory for the new Git repository.

THE WORKING DIRECTORY

COMMITTING

PUTTING IN WORK

THE LIFECYCLE OF A FILE

THE LIFECYCLE OF A FILEAdding a file:

$ git statusOn branch masternothing to commit, working directory clean$ atom new­file.txt$ git statusOn branch masterUntracked files: (use "git add ..." to include in what will be committed)

new­file.txt

nothing added to commit but untracked files present (use "git add" to track)$ git add new­file.txt$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)

THE LIFECYCLE OF A FILEModifying a file:

$ git statusOn branch masternothing to commit, working directory clean$ atom new­file.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: new­file.txt

no changes added to commit (use "git add" and/or "git commit ­a")$ git add new­file.txt$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)

THE LIFECYCLE OF A FILERemoving a file:

$ git statusOn branch masternothing to commit, working directory clean$ git rm new­file.txtrm 'new­file.txt'$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)

deleted: new­file.txt

$ git commit ­­message="Removed the file."[master 0d229e7] Removed the file. 1 file changed, 2 deletions(­) delete mode 100644 new­file.txt$ git statusOn branch master

AMENDING A COMMITRedo commits with git commit ‐‐amend:

$ git log ­­oneline ­­max­count 20d229e7 Removed the file.9bb1e7e Modified the file.$ git statusOn branch masterChanges to be committed: (use "git reset HEAD ..." to unstage)

new file: cat­names.txt

$ git commit ­­message="Needed soem cat names."[master 2e6c3b7] Needed soem cat names. 1 file changed, 1 insertion(+) create mode 100644 cat­names.txt$ git log ­­oneline ­­max­count 22e6c3b7 Needed soem cat names.0d229e7 Removed the file.$ git commit ­­amend ­­message="Needed some cat names."

Note that this changes history!

.gitignore# We want these files in our working directory, but not in our repository.

# Log files*.log

# Build output directorybuild/

# Third­party packagesnode_modules

Matching files not already in the repository are ignored:$ atom new­file­that­gets­ignored.log$ git statusOn branch masternothing to commit, working directory clean

WHERE DO COMMITS GO?

You might recognize this structure from .eariler

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`.

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:

WHAT'S IN A COMMIT?

WHAT'S IN A COMMIT?Let's go look at a raw commit!

git cat‐file gets objects from the key-value store:$ git cat­file ­p 1eb2ce28cd1b6e89e9a9ed2f4681cb834a48fc87tree 48b8b000be35eb9d739aa63b5556226405745e86parent 8516b87e1307db03994c619693e2669a1d825608author Chris Antes 1426921898 ­0700committer Chris Antes 1426921898 ­0700

Slides on other VCSs. Refinements to previous slides.

WHAT'S IN A COMMIT?Now let's get the commit's tree:

$ git cat­file ­p 48b8b000be35eb9d739aa63b5556226405745e86100644 blob 69fad358018d530235f8e43c483d3ce960616a32 .bowerrc100644 blob d1d8a4176a416daffcfbfecdd3f35f24bd79fc7d .editorconfig100644 blob 3518e7f29dcc2b195d7077d989efa3f6bd6cfbef .gitignore100644 blob 855a9efe0a6aff5c442fbd1dc26a5af279d66b72 .jshintrc100644 blob 41ea8d4c4629041d42e6f090e41dcd3d5eace1eb .yo­rc.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

WHAT'S IN A COMMIT?Let's see what a blob looks like:

$ git cat­file ­p 0eeb399333af39939d3c83691747f7cf30a002ee "name": "git­your­best­friend­ever", "version": "0.0.0", "private": true, "devDependencies": "grunt": "^0.4.5", "grunt­autoprefixer": "^2.2.0", "grunt­coffeelint": "0.0.13", "grunt­contrib­connect": "^0.9.0", "grunt­contrib­copy": "^0.7.0", "grunt­contrib­jshint": "^0.10.0", "grunt­contrib­sass": "^0.8.0", "grunt­contrib­watch": "^0.6.1", "load­grunt­tasks": "^1.0.0" , "engines": "node": ">=0.10.0",

NOT TOO BAD, RIGHT?It's just linked lists and trees and stuff!

LET'S GET BACK TO THE PRACTICAL BITS!

BRANCHING

WHY BRANCH?So we can work like this:

WHAT IS A BRANCH?They're just pointers (also known as refs)! v1.0 and master are branches:

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

SWITCHING BRANCHESSwitch branches with git checkout:

$ git branch ­­list* master testing$ git checkout testingSwitched to branch 'testing'

CREATING BRANCHESCreate new branches with git branch:

$ git branch ­­list* master$ git branch new­feature$ git branch ­­list* master new­feature

Use git checkout ‐b to branch and switch in one command:$ git branch ­­list* master$ git checkout ­b new­featureSwitched to a new branch 'new­feature'$ git branch ­­list master* new­feature

DELETING BRANCHESDelete branches with git branch ‐‐delete:

$ git branch ­­list* master new­feature$ git branch ­­delete new­featureDeleted branch new­feature (was f3bc86a).$ git branch ­­list* master

RENAMING BRANCHESBranches can be renamed with git branch ‐‐move:

$ git branch ­­list master* new­feature$ git branch ­­move new­feature feature/starring­items$ git branch ­­list* feature/starring­items master

CHANGING WHERE A BRANCH POINTSgit reset changes where the HEAD branch points. And maybe some other stuff:

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/cat­names$ git reset ­­hard HEAD~2HEAD is now at 0d229e7 Removed the file.$ git checkout feature/cat­namesSwitched to branch 'feature/cat­names'$ git log ­­oneline4f00f1a Adding a few more cat names.9abff09 Needed some cat names.0d229e7 Removed the file.

MERGING BRANCHESLet's say we've just fixed a bug and we want to merge our fix into master:

MERGING BRANCHESgit merge performs a :3-way merge

MERGING BRANCHES$ git checkout masterSwitched to branch 'master'$ git merge iss53Merge made by the 'recursive' strategy.index.html | 1 +1 file changed, 1 insertion(+)

FAST-FORWARD MERGES$ git checkout masterSwitched to branch 'master'$ git merge hotfixUpdating f42c576..3a0874cFast­forward index.html | 2 ++ 1 file changed, 2 insertions(+)

MERGE CONFLICTS HAPPENLet's say I did some similar work on two branches that I now want to merge:

$ git merge feature/cat­namesAuto­merging cat­names.txtCONFLICT (add/add): Merge conflict in cat­names.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: cat­names.txt

no changes added to commit (use "git add" and/or "git commit ­a")

So scary!

MERGE CONFLICTS: NOT REALLY SO SCARYHere's what the conflicted file looks like:

<<<<<<< HEADFluffySocrates=======Halo­HaloChairman Meow>>>>>>> feature/cat­namesSadieWhiskersSimba

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.

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 cat­names.txt$ git commit[master b98a343] Merge branch 'feature/cat­names'

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

REMOTES

GIT IS DISTRIBUTED

CLONING A REMOTECloning is the first step to working with an existing repository:

KEEPING REMOTES UP-TO-DATEDownload new commits with git fetch:

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 git@github.com:doingweb/git­your­best­friend­ever.git 85c7fae..af42118 master ­> master

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 new­featureSwitched to a new branch 'new­feature'$ git pushfatal: The current branch new­feature has no upstream branch.To push the current branch and set the remote as upstream, use

git push ­­set­upstream origin new­feature

$ git push ­­set­upstream origin new­featureTotal 0 (delta 0), reused 0 (delta 0)To git@github.com:doingweb/git­your­best­friend­ever.git* [new branch] new­feature ­> new­featureBranch new­feature set up to track remote branch new­feature from origin.$ git pushEverything up­to­date

COLLABORATING

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.

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.

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.

AND THAT'S GIT!

top related