By Joris Kraak / @joriskraak using Reveal.js
Available online at https://bauglir.github.io/me-myself-and-git
Track history
Collaboration
Proposal evaluation
Backup purposes
Every user has their own copy of the repository
Changes can be shared directly between repositories
The (optional) server copy is not really special
$ git init my-project && cd my-project
Initialized empty Git repository in /home/jkraak/Projects/my-project/.git/
$ git clone git@github.com:bauglir/me-myself-and-git.git
Cloning into 'me-myself-and-git'...
remote: Counting objects: 7127, done.
remote: Total 7127 (delta 0), reused 0 (delta 0), pack-reused 7127
Receiving objects: 100% (7127/7127), 5.38 MiB | 2.52 MiB/s, done.
Resolving deltas: 100% (3767/3767), done.
Checking connectivity... done.
$ echo 'foo' > foo.txt
$ echo 'bar' > bar.txt
$ git status
On branch master
Initial commit
Untracked files:
(use "git add < file>..." to include in what will be committed)
bar.txt
foo.txt
nothing added to commit but untracked files present (use "git add" to track)
git status
is your friend! It provides hints on what to do next
$ git add foo.txt
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached < file>..." to unstage)
new file: foo.txt
new file: bar.txt
$ git commit -m 'Add foo and bar literature'
[master (root-commit) 3f91579] Add foo and bar literature
2 files changed, 2 insertions(+)
create mode 100644 bar.txt
create mode 100644 foo.txt
$ echo 'baz' >> foo.txt
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: foo.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/foo.txt b/foo.txt
index 257cc56..0c071e1 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1 +1,2 @@
foo
+baz
$ git add -u && git commit -m 'Add baz reference'
[master e981856] Add baz reference
1 file changed, 1 insertion(+)
$ git log
commit e9818560edc7f0cf41317f15eec28167e507a3f7
Author: Joris Kraak < me@joriskraak.nl>
Date: Tue Feb 24 12:20:25 2015 +0100
Add baz reference
commit 3f91579623ef93cde0ebf5300b6da99bd70fa835
Author: Joris Kraak < me@joriskraak.nl>
Date: Tue Feb 24 12:08:31 2015 +0100
Add foo and bar literature
$ git rm *
rm 'bar.txt'
rm 'foo.txt'
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD < file>..." to unstage)
deleted: bar.txt
deleted: foo.txt
$ git reset HEAD foo.txt
Unstaged changes after reset:
D foo.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD < file>..." to unstage)
deleted: bar.txt
Changes not staged for commit:
(use "git add/rm < file>..." to update what will be committed)
(use "git checkout -- < file>..." to discard changes in working directory)
deleted: foo.txt
$ git checkout -- foo.txt
On branch master
Changes to be committed:
(use "git reset HEAD < file>..." to unstage)
deleted: bar.txt
$ ls
foo.txt
Branches make it easier to collaborate on a shared code base
What made Git easy for me is visualizing everything as a tree
$ git log --graph --oneline --decorate --all
or get a GUI capable of showing the history formatted as a tree
Git is very flexible with regards to picking a workflow
Popular choices are:
Keep a single master branch
Implement new features/bug fixes taking more than a single commit on a separate branch, then merge into master
Before merging, 'rebase' feature branch on master and fix any conflicts that may arise
Make the merge back into master explicit by forcing a merge commit
using git merge --no-ff
This results in a very clean history where the work on features stays clearly visible after a merge
http://mislav.uniqpath.com/2013/02/merge-vs-rebase/Let's force two branches to diverge
$ git checkout -b my-branch
Switched to a new branch 'my-branch'
$ cp foo.txt quuz.txt
$ git add quuz.txt && git commit -m 'Add quuz literature'
[my-branch cb4c59e] Add quuz literature
1 file changed, 2 insertions(+)
create mode 100644 quuz.txt
$ git checkout master
Switched to branch 'master'
$ cp foo.txt quux.txt
$ git add quux.txt && git commit -m 'Add quux literature'
[master afda51f] Add quux literature
1 file changed, 2 insertions(+)
create mode 100644 quux.txt
$ git checkout my-branch
Switched to branch 'my-branch'
'my-branch' does not yet contain the quux literature
$ ls
bar.txt foo.txt quuz.txt
Take 'my-branch' and attach it to the new top of the tree
$ git rebase master my-branch
First, rewinding head to replay your work on top of it...
Applying: Add quuz literature
$ ls
bar.txt foo.txt quux.txt quuz.txt
Finally merge 'my-branch' into 'master'
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff my-branch -m 'Merge branch my-branch'
Merge made by the 'recursive' strategy.
quuz.txt | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 quuz.txt
* f08e76f (HEAD, master) Merge branch my-branch
|\
| * 29233b8 (my-branch) Add quuz literature
|/
* afda51f Add quux literature
* e981856 Add baz reference
* 3f91579 Add foo and bar literature
Work can be shared using 'remotes'
The 'server' is typically referred to as 'origin'
When cloning a repository, the 'origin' is automatically set
First create a 'server' repository
$ git init --bare server
Then add the 'server' as a remote
$ git remote add origin server
Verify the remotes of the current repository
$ git remote -v
origin server (fetch)
origin server (push)
Publish our local work
$ git push origin master
* deadbeef (origin/foo) Remote only work
| * f08e76f (HEAD, master, origin/master) Merge branch my-branch
| |\
| | * 29233b8 (my-branch) Add quuz literature
| |/
|/
* afda51f Add quux literature
* e981856 Add baz reference
* 3f91579 Add foo and bar literature
git fetch remote_name branch_name
synchronizes local
branch history with remote
git pull remote_name branch_name
fetches and merges
or rebases a local branch with its remote equivalent
git push remote_name branch_name
publishes local
history to remote repository
BitBucket, GitHub, GitLab (CE)
Websites hosting Git repositories
Provide online functionality for branching and merging (Pull Requests)
Issue tracking capable of linking to code
Typically used as the 'server'
Git typically communicates over SSH
SSH requires public/private key pairs
These have to be in openSSH format
For generation use either the GitHub Client or PuTTYGen
The private key should be password protected and kept safe
The public key can be distributed where necessary
To cache the private key password, solutions such as Pageant can be used
git commit --amend
-p
to most operations allows more granular control (i.e. within files)git config --global alias.graph 'log --graph --oneline --decorate --all'
git stash
) allows temporary storage of in-progress work, useful when rebasinggit push -u remote_name branch_name
'tracks' remote branchesgit config --global url.https://.insteadOf git://
git config --global color.ui true
forces pretty colorsgit config --global pull.rebase true
forces a pull to always 'rebase' instead of 'merge'merge
, rebase
, etc. have a --abort
flag