For viewing
Source code
Git Logo
This work is licensed under a Creative Commons Attribution 4.0 International License.
Only the central repo gets a full copy of the history
Everyone can work offline
Written by Linus Torvalds in 2005 to meet the needs of the Linux kernel developers.
Now maintained by Junio Hamano.
torial @ StackOverflow:
"anything greater than a 1 second delay broke people out of the zone"
Homebrew:
$ brew update $ brew install git
Debian-based:
$ sudo apt-get install git
Otherwise: http://git-scm.com/download/
The hardest part of Git is the jargon.
The staging area holds changes that are about to be committed.
from the Git book.
Create a new repo:
$ git init Initialized empty Git repository in /home/nathan/devel/git-demo/.git/
Make a file:
$ touch README.md $ ls -a . .. .git README.md
By default, this new file is untracked:
$ git ls-files $ git status On branch master Initial commit Untracked files: README.md
Files need to be added with git add before Git knows about them:
$ git add README.md
Then they show up in the staging area:
$ git status On branch master Initial commit Changes to be committed: new file: README.md
$ git ls-files README.md
$ git commit -m ‘initial commit’ [master (root-commit) 104ea88] initial commit 1 file changed, 0 insertions(+), 0 deletions(-)
Commits move files from the staging area into the log.
$ git checkout -b hotfix
filer$ cd .git/refs/heads heads$ ll total 12 drwxr-xr-x 1 nathan nathan 28 Jun 16 09:06 cleanup -rw-r--r-- 1 nathan nathan 41 May 30 14:56 cython -rw-r--r-- 1 nathan nathan 41 Jul 8 11:43 develop drwxr-xr-x 1 nathan nathan 40 Jun 3 09:27 feature drwxr-xr-x 1 nathan nathan 28 May 27 10:30 hotfix -rw-r--r-- 1 nathan nathan 41 Jul 7 10:21 master heads$ cat master 9326780e3cde95034a6a402ee39a47e66e9c2398
$ git clone /opt/git/project.git
$ git clone user@server:project.git
Clone this repo!
$ git clone git@github.com:nathantypanski/git-talk.git Cloning into 'git-talk'... remote: Counting objects: 312, done. remote: Compressing objects: 100% (205/205), done. remote: Total 312 (delta 136), reused 270 (delta 94) Receiving objects: 100% (312/312), 1.69 MiB | 0 bytes/s, done. Resolving deltas: 100% (136/136), done. Checking connectivity... done.
If you have an account: fork this repo, then clone your fork:
$ git remote add kjb https://github.com/kinneyjb/git-talk.git git-talk$ git fetch kjb remote: Counting objects: 9, done. remote: Compressing objects: 100% (1/1), done. remote: Total 4 (delta 3), reused 3 (delta 3) Unpacking objects: 100% (4/4), done. From https://github.com/kinneyjb/git-talk * [new branch] gh-pages -> kjb/gh-pages * [new branch] jkinney-what -> kjb/jkinney-what * [new branch] master -> kjb/master
$ mkdir demo $ cd demo demo$ git init Initialized empty Git repository in ~/demo/.git/ demo$ la . .. .git demo$ vim helloworld.py
import sys def main(): if len(sys.argv) == 1: print('Hello, world') else: print(str.format('hello {}', ' '.join(sys.argv[1:]))) if __name__ == '__main__': main()
demo$ python3 helloworld.py Hello, world demo$ python3 helloworld.py nathan hello nathan
demo$ git add helloworld.py demo$ git commit -m 'initial commit' [master (root-commit) 62b720a] initial commit 1 file changed, 10 insertions(+) create mode 100644 helloworld.py
To show branches:
demo$ git branch * master
$ vim helloworld.py $ git diff
diff --git a/helloworld.py b/helloworld.py index 328978e..b2c550a 100644 --- a/helloworld.py +++ b/helloworld.py @@ -1,10 +1,16 @@ import sys +from datetime import date def main(): + today = datetime.today() if len(sys.argv) == 1: print('Hello, world') else: print(str.format('hello {}', ' '.join(sys.argv[1:]))) + print(str.format('Today is {}-{}-{}', + today.year, + today.month, + today.day())) if __name__ == '__main__': main()
demo$ git commit helloworld.py -m 'add date to helloworld' [date 58fba34] add date to helloworld 1 file changed, 6 insertions(+)
demo$ python3 helloworld.py Nathan Traceback (most recent call last): File "helloworld.py", line 16, in <module> main() File "helloworld.py", line 5, in main today = datetime.today() NameError: name 'datetime' is not defined
Darn! Should've tested before I committed that ...
Luckily, Git lets us amend our work before we send it anywhere.
$ vim helloworld.py $ git diff
diff --git a/helloworld.py b/helloworld.py index b2c550a..fd28150 100644 --- a/helloworld.py +++ b/helloworld.py @@ -2,7 +2,7 @@ import sys from datetime import date def main(): - today = datetime.today() + today = date.today() if len(sys.argv) == 1: print('Hello, world') else: @@ -10,7 +10,7 @@ def main(): print(str.format('Today is {}-{}-{}', today.year, today.month, - today.day())) + today.day)) if __name__ == '__main__': main()
demo$ python3 helloworld.py Nathan hello Nathan Today is 2014-7-14 demo$ git commit --amend helloworld.py
Great! It works. Let's amend that commit ...
add date to helloworld # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # Explicit paths specified without -i or -o; assuming --only paths... # On branch date # Changes to be committed: # modified: helloworld.py #
demo$ git commit --amend helloworld.py [date a497198] add date to helloworld 1 file changed, 6 insertions(+)
demo$ git log a497198 Nathan Typanski add date to helloworld 62b720a Nathan Typanski initial commit
This is safe, since every user basically has their own local branch by default.
Fix bigger mistakes with git rebase.
Working on this repo, I forgot to add an image that was referenced in one of the markdown files.
That was 3 commits ago. I can't just --amend it.
git-talk$ git rebase -i origin/master
origin/master is a remote branch.
It means I'm allowed to change things up until the history known on origin's master branch.
git-talk$ git rebase -i origin/master
Reorder and fixup (combine) the commits:
[detached HEAD 4344a8d] add gitlab ci 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 img/gitlab-ci-preview.png Successfully rebased and updated refs/heads/master.
Now my history looks like this:
2014-07-14 13:48 Unknown o Unstaged changes 2014-07-14 13:32 Nathan Typanski o [master] more branching 2014-07-14 13:32 Nathan Typanski o expand tool descriptions 2014-07-14 13:31 Nathan Typanski o add gitlab ci 2014-07-14 13:31 Nathan Typanski o tweak formatting 2014-07-14 12:42 Nathan Typanski o add link to gitbook 2014-07-14 12:37 Nathan Typanski o [gh-pages] [origin/HEAD] [origin/gh-pages] [origin/master] remotes before merging 2014-07-14 12:36 Nathan Typanski o add slides on cloning/forking repo
$ git merge hotfix master
To merge changes from local branch hotfix into local branch master:
$ git merge hotfix master
Merge changes from remote origin branch master into local branch master
$ git pull origin master
Often, you'll want to inspect a merge before it happens.
Use git fetch:
git-talk$ git fetch kinneyjb remote: Counting objects: 4, done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 1 (delta 0) Unpacking objects: 100% (4/4), done. From https://github.com/kinneyjb/git-talk * [new branch] gh-pages -> kinneyjb/gh-pages * [new branch] master -> kinneyjb/master
If you have local changes, do git stash to save them away:
git-talk$ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. Changes not staged for commit: modified: slides/merging.md no changes added to commit (use "git add" and/or "git commit -a")
git-talk$ git stash Saved working directory and index state WIP on master: 633c37b merging: fill out sections HEAD is now at 633c37b merging: fill out sections
Sometimes I'll make a new branch for the merge:
git-talk$ git checkout -b kjb Switched to a new branch 'kjb'
Merge a fetched remote branch with remotename/branchname:
git-talk$ git merge kinneyjb/master Merge made by the 'recursive' strategy. slides/benchmarks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
$ git log --graph --pretty=format:'%h %an %s'
* 5e2788f Nathan Typanski Merge remote-tracking branch 'kinneyjb/master' into kjb |\ | * b332517 kinneyjb fixed typos closes #2 * | 633c37b Nathan Typanski merging: fill out sections * | 4d2ac1f Nathan Typanski fade transition for backgrounds - easier to follow * | 25a4087 Nathan Typanski expand branches/remotes/ci * | 3ed07e5 Nathan Typanski more branching * | 5e1b3ab Nathan Typanski expand tool descriptions * | 4344a8d Nathan Typanski add gitlab ci * | 6a339e0 Nathan Typanski tweak formatting * | 2ba91f4 Nathan Typanski add link to gitbook * | 3965c22 Nathan Typanski remotes before merging * | a1dcf95 Nathan Typanski add slides on cloning/forking repo * | 221c3fe Nathan Typanski wider quotes, non-italic * | 0a8bf2e Nathan Typanski fill out "tracking changes" * | 19259c9 Nathan Typanski stop hyphenating titles * | ecf9034 Nathan Typanski add ci section * | b404b21 Nathan Typanski join slides for remotes |/
Now, put the changes back in master:
git-talk$ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits)
Merging with --ff-only means "don't give me a merge commit; just put the new changes on top of HEAD:
git-talk$ git merge --ff-only kjb Updating 633c37b..5e2788f Fast-forward slides/benchmarks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reapply my old work:
git-talk$ git stash apply On branch master Your branch is ahead of 'origin/master' by 3 commits.
git-talk$ git show --pretty=medium 5e2788f commit 5e2788f44c6db845c5a7456a2cace6d22f9fe809 Merge: 633c37b b332517 Author: Nathan Typanski <ntypanski@gmail.com> Date: Sat Jul 19 13:37:43 2014 -0400 Merge remote-tracking branch 'kinneyjb/master' into kjb
git-talk$ git show -c b332517
b332517 kinneyjb fixed typos closes #2 diff --git a/slides/benchmarks.md b/slides/benchmarks.md index 27930fd..a626042 100644 --- a/slides/benchmarks.md +++ b/slides/benchmarks.md @@ -70,7 +70,7 @@ - **350 MiB** - **Git** - entire history - - **450**. + - **450 MiB** [keithp](http://keithp.com/blog/Repository_Formats_Matter/) @@ -81,7 +81,7 @@ - **SVN**: 61 MiB - **bzr**: 64 MiB - **Hg**: 53 MiB -- **Git**: 43 Mib +- **Git**: 43 MiB [why git is better](http://thkoch2001.github.io/whygitisbetter/#git-is-small)
$ git config --global rerere.enabled true
$ git log
$ git blame
$ git grep
$ git bisect
git-talk$ git log --graph --pretty=format:'%h %an %s'
* bfd7061 Nathan Typanski remotes: change slide to use generic titlebg * 5418ad7 Nathan Typanski concepts:shorten title * 6e0aed4 Nathan Typanski whitespace nitpick fixup * e169333 Nathan Typanski add readme * 837fc50 Nathan Typanski rm extra slide * 7b4245f Nathan Typanski Merge branch 'jkinney-what' of ... |\ | * 524abf7 kinneyjb Merge branch 'jkinney-what' of ... | |\ | | * 9975749 kinneyjb Split out the notes from what into ... | * | 9f933af kinneyjb Split out the notes from what into ... | |/ | * 40790cb kinneyjb Some notes for the what section, ... * | 32330ac Nathan Typanski add section for remotes |/ * 66f5fdd Nathan Typanski stop lying about fast-forward merges
For these reasons, the "summary" must be no more than 70-75 characters, and it must describe both what the patch changes, as well as why the patch might be necessary. It is challenging to be both succinct and descriptive, but that is what a well-written summary should do.
$ git blame slides/concepts.md
9f933af3 (kinneyjb 2014-07-10) - (Client/Server) 9f933af3 (kinneyjb 2014-07-10) 9f933af3 (kinneyjb 2014-07-10) --- 9f933af3 (kinneyjb 2014-07-10) 9f933af3 (kinneyjb 2014-07-10) ### Centralized VCS 75f6b977 (Nathan Typanski 2014-07-10) <img src="img/centralized-vcs.svg" /> 9f933af3 (kinneyjb 2014-07-10) 9f933af3 (kinneyjb 2014-07-10) --- 9f933af3 (kinneyjb 2014-07-10) 9f933af3 (kinneyjb 2014-07-10) ### Distributed Version Control 9f933af3 (kinneyjb 2014-07-10) 9f933af3 (kinneyjb 2014-07-10) - Team members send changes to each 9f933af3 (kinneyjb 2014-07-10) - Everyone can work offline
Use it with --cached to grep only files Git knows about:
git-flow$ git grep --cached --break --heading --line-number "Linux"
(the other arguments are just for pretty output)
slides/benchmarks.md 44:[Linux Kernel Wiki](https://git.wiki.kernel.org/index.php/GitBenchmarks) slides/what.md 17:- Written by Linus Torvalds in 2005 to meet the needs of the Linux kernel developers. slides/workflows.md 29:- Linux kernel.
"A successful Git branching model"