The Sequel!
Follow-along at http://slides.com/rouben/gittin-it-2/live
or scan the QR code below!
Image credit: git-tower.com, used with permission.
Image credit: git-tower.com, used with permission.
There are plenty of VCSs out there, but git remains one of the most popular, because...
Image credit: git-tower.com, used with permission.
...without setting your hair on fire!
Image credit: git-tower.com, used with permission.
Step 1: Create the repository
OR...
Image credit: git-tower.com, used with permission.
Step 1: Clone the repository
Step 1: Create or clone a repository
git config --global user.name "John Doe"
git config --global user.email "john@doe.org"
git config --global color.ui auto
git init Create a new repository in current directory
Example:
$ mkdir myproject
$ cd myproject
$ git init
Initialized empty Git repository in /Users/tchakhma/tkf2015-git/myproject/.git/
git clone <address> Clone remote repository at <address> to current directory
Example:
$ git clone https://github.com/pcottle/learnGitBranching.git
Cloning into 'learnGitBranching'...
remote: Counting objects: 12885, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 12885 (delta 3), reused 0 (delta 0), pack-reused 12869
Receiving objects: 100% (12885/12885), 27.86 MiB | 808.00 KiB/s, done.
Resolving deltas: 100% (6820/6820), done.
Checking connectivity... done.
Image credit: git-tower.com, used with permission.
Step 2: Work work work
Image credit: git-tower.com, used with permission.
Step 3: Review changes
Step 3: Review changes
In case of NEW (untracked) files...
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
one.txt
three.txt
two.txt
nothing added to commit but untracked files present (use "git add" to track)
In case of modified existing (tracked) files...
$ 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: one.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/one.txt b/one.txt
index 5626abf..ec32321 100644
--- a/one.txt
+++ b/one.txt
@@ -1 +1,2 @@
-one
+this is the first line of one.txt
+this is the second line of one.txt
Image credit: git-tower.com, used with permission.
Step 4: Stage the next commit
Step 4: Stage the next commit
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
one.txt
three.txt
two.txt
nothing added to commit but untracked files present (use "git add" to track)
$ git add one.txt two.txt three.txt
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: one.txt
new file: three.txt
new file: two.txt
Image credit: git-tower.com, used with permission.
Step 5: Commit!
Step 5: Commit!
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: one.txt
new file: three.txt
new file: two.txt
$ git commit -m 'Added files one two and three'
[master (root-commit) 4afc746] Added files one two and three
3 files changed, 3 insertions(+)
create mode 100644 one.txt
create mode 100644 three.txt
create mode 100644 two.txt
$ git status
On branch master
nothing to commit, working directory clean
Step 6: Review commit history
Git commit logs provide the following:
Q: Why use commit hashes as IDs instead of numbers?
A: Sequential numbers lose meaning in multi-user, multi-context environment, particularly when working offline. Plus, you get data integrity as a bonus!
Good news: Usually first 4-8 characters of commit hash is enough.
Step 6: Review commit history
$ git log
commit 184811419ad75501005c047de532c7ca60661c9d
Author: Rouben Tchakhmakhtchian <rouben.tchakhmakhtchian@utoronto.ca>
Date: Thu May 7 01:45:23 2015 -0400
Made file one.txt more verbose
commit 4afc746022274a3b8eb33e3c5d9f8362aaf6f3f3
Author: Rouben Tchakhmakhtchian <rouben.tchakhmakhtchian@utoronto.ca>
Date: Thu May 7 00:34:09 2015 -0400
Added files one two and three
$ git log -p -1
commit 184811419ad75501005c047de532c7ca60661c9d
Author: Rouben Tchakhmakhtchian <rouben.tchakhmakhtchian@utoronto.ca>
Date: Thu May 7 01:45:23 2015 -0400
Made file one.txt more verbose
diff --git a/one.txt b/one.txt
index 5626abf..ec32321 100644
--- a/one.txt
+++ b/one.txt
@@ -1 +1,2 @@
-one
+this is the first line of one.txt
+this is the second line of one.txt
Bad commit message
(Single giant commit)
Added login screen, fixed bug #123, deleted obsolete CSS, refactored function getStuffDone()
Good commit messages
(Multiple smaller commits)
* Implemented login GUI * Implemented login logic * Fixed bug #123 * Deleted obsolete CSS * Refactored function getStuffDone()
Image credit: git-tower.com, used with permission.
Step 7: Branch, merge & share!
My aim is to try and cover as much of this as we can today...
Image credit: git-tower.com, used with permission.
Let's review...
Undoing!
Fixing the very last commit (message and/or content):
(Optional) git add forgotten_file.html
git commit --amend -m 'New commit message'
git revert <target commit hash>
git reset --hard <target commit hash>
git checkout <target commit hash>
Image credit: git-tower.com, used with permission.
At all times you're almost always working on a branch.
The default branch is called master; it's just a label.
Remember: branches are like contexts or topics; logical containers for sets of related commits.
git log output will match the current HEAD branch.
Cheat sheet
git branch newbranch
git checkout newbranch
Merging: integrating changes (sets of commits) from one branch into another, as they occurred in each branch.
The current HEAD branch is the recipient branch by default
Cheat sheet
git checkout master
git merge contact-form
Rebasing!
Rebasing: appending all commits since divergence point from source branch onto the tail of the recipient.
The current HEAD branch is the recipient branch by default.
This can be useful when ensuring that local modifications (e.g. application configuration) always appear as the latest commit.
Think of this as copy-pasting the source branch onto the tail of the recipient.
CAUTION! This operation rewrites commit history!
Cheat sheet
git checkout <recipient branch>
git rebase <source branch>
Image credit: git-tower.com, used with permission.
vs. merge...
Much like rebasing, except you are "cherry-picking" specific commits from the source branch(es) onto the tail of the recipient.
The current HEAD branch is the recipient branch by default.
This can be useful when you need to integrate very specific changes from one branch into another.
Think of this as copy-pasting specific commits onto the tip of the target branch from the source.
CAUTION! This operation rewrites commit history!
Cheat sheet
git checkout <recipient branch>
git rebase <source branch>
Working with remotes!
90% of all git work is done locally. Remote repositories come into play when locally stored work needs to be shared or published.
Image credit: git-tower.com, used with permission.
Working with remotes!
Git terminology refresher cheat sheet
New concepts!
Working with remotes: clone
git clone completely copies all data from a remote repository locally. It literally creates a "clone" of what's on the server.
Image credit: git-tower.com, used with permission.
Working with remotes: remote, checkout and status
git remote and git branch help manage remote repositories and remote branches respectively.
git checkout --tracking can be used to check out remote branches locally and set up a two way link (tracking) between them.
git status will compare the status of the current HEAD branch with its marching (tracking) remote counterpart. Remember: git stores a snapshot of the remote repository state locally, so don't forget to fetch the latest updates first. It will NOT update this snapshot automatically unless you explicitly tell it to.
Working with remotes: fetch
git fetch copies new data from the remote branch locally, but doesn't yet integrate (merge or rebase) it into your local branches.
Think of it as a "staging area" for changes imported from the remote, allowing you to review before you merge or rebase.
Image credit: git-tower.com, used with permission.
Working with remotes: pull
git pull copies all new data from the remote branch locally, AND integrates (merge or rebase) it into the local matching branch.
git pull = git fetch + git merge (yes, it's just a shortcut to two different commands run in succession)
Image credit: git-tower.com, used with permission.
Working with remotes: push
git push copies all new data from a local branch to the remote repository, AND integrates (merge!) it into the remote branch.
git push = the opposite of git pull
Image credit: git-tower.com, used with permission.
Working with remotes: command cheat sheet
$ git remote add origin https://example.com/project.git
$ git remote -v
origin https://example.com/project.git (fetch)
origin https://example.com/project.git (push)
$ git clone https://example.com/project.git
git checkout --track origin/branch-A
git branch -v -a
Image credit: git-tower.com, used with permission.
$ git status
# On branch dev
# Your branch and 'origin/dev' have diverged,
# and have 1 and 2 different commits each, respectively.
#
nothing to commit (working directory clean)
What's happening...
What git status will look like...
Illustration credits: git-tower.com; used with permission
Resources