很久之前就想系统的学习一下版本控制系统了,这两天抽空看了一下《Progit》和《GotGithub》这两本书,学习了Git这个版本控制系统以及只支持Git作为唯一版本库格式的项目托管平台Github,这两者在项目开发中都是很好的工具,下面总结一下使用方法,以方便以后使用时查阅。
原理
下面的两张图片很好的解释了Git和Github的原理:
分布式版本控制系统
Github的协同模式
添加SSH认证
1. 生成SSH密钥
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
The key fingerprint is:
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local
2. 添加公钥到Github
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== schacon@agadorlaptop.local
3. SSH认证
$ ssh -T git@github.com
Hi gotgithub! You've successfully authenticated, but GitHub does not provide shell access.
出现上面的提示则认证成功,以后就可以使用ssh协议(自动认证,不用输入口令)克隆远程仓库了。
配置用户信息
1. 配置全局信息
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
2. 配置本地仓库局部信息
首先进入当前仓库工作区
$ git config user.name "John Doe"
$ git config user.email johndoe@example.com
3. 查看当前配置信息
$ git config --list
user.name=Scott Chacon
user.email=schacon@gmail.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...
$ git config user.name
Scott Chacon
本地仓库常用命令
1. 初始化
本地初始化:
$ git init
$ git commit -m 'initial project version
$ git remote add origin git@github.com:gotgithub/helloworld.git
$ git push -u origin master
或者从远程仓库克隆:
$ git clone git://github.com/schacon/grit.git
$ git clone git://github.com/schacon/grit.git mygrit
2. 检查当前文件状态
$ git status
# On branch master
nothing to commit (working directory clean)
3. 添加文件到缓存区
$ vim README
$ git status
# On branch master
# Untracked files:
#
(use "git add <file>..." to include in what will be committed)
#
# README
nothing added to commit but untracked files present (use "git add" to track)
$
$ git add README
$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
4. 忽略某些文件
$ cat .gitignore
*.[oa]
*~
修改.gitignore文件即可。
5. 查看更新具体内容
查看工作目录中当前文件和缓存区域快照之间的差异:
$ git diff
diff --git a/benchmarks.rb b/benchmarks.rb
index 3cb747f..da65585 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -36,6 +36,10 @@ def main
@commit.parents[0].parents[0].parents[0]
end
+
run_code(x, 'commits 1') do
+
git.commits.size
+
end
+
run_code(x, 'commits 2') do
log = git.commits('master', 15)
log.size
查看缓存区文件和上次提交时的快照之间的差异:
$ git diff --cached
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README2
@@ -0,0 +1,5 @@
+grit
+ by Tom Preston-Werner, Chris Wanstrath
+ http://github.com/mojombo/grit
+
+Grit is a Ruby library for extracting information from a Git repository
6. 提交更新到本地仓库
从缓存区提交:
$ git commit -m "Story 182: Fix benchmarks for speed"
[master]: created 463dc4f: "Fix benchmarks for speed"
2 files changed, 3 insertion
从工作区提交:
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
1 files changed, 5 insertions(+), 0 deletions(-)
7. 移除文件
$ rm grit.gemspec
$ git status
# On branch master
#
# Changed but not updated:
#
(use "git add/rm <file>..." to update what will be committed)
#
#
deleted: grit.gemspec
#
$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
# On branch master
#
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
#
deleted: grit.gemspec
#
直接从缓存区移除文件:
$ git rm --cached readme.txt
8. 移动文件
$ git mv src/main.cpp ./main.cpp
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 3 commits.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: src/main.cpp -> main.cpp
#
9. 查看提交历史
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:
Mon Mar 17 21:52:11 2008 -0700
changed the verison number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:
Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:
Sat Mar 15 10:31:28 2008 -0700
first commit
如果使用Github托管项目的话到Github上去看比较清楚。
10. 覆盖上一次提交
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
新增的文件并入到上次提交的内容一起提交,覆盖上次提交。
11. 取消缓存区中的文件到工作区
$ git reset HEAD benchmarks.rb
benchmarks.rb: locally modified
$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
#
modified: README.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
#
#
modified: benchmarks.rb
12. 新建以及切换分支
$ git branch testing #新建分支
$ git checkout testing #切换分支
$ git checkout -b testing #新建并切换分支
13. 合并分支
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast forward
README |
1 -
1 files changed, 0 insertions(+), 1 deletions(-)
14. 删除分支
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
#强制删除未合并的分支
$ git branch -D mybranch1
Deleted branch mybranch1 (was f46a284).
15. 分支管理
$ git branch iss53
* master
testing
#查看哪些分支已被并入当前分支
$ git branch --merged
iss53
* master
#查看尚未合并的分支
$ git branch --no-merged testing
与远程仓库交互
1. 克隆仓库到本地
$ git clone git://github.com/schacon/ticgit.git
Initialized empty Git repository in /private/tmp/ticgit/.git/
remote: Counting objects: 595, done.
remote: Compressing objects: 100% (269/269), done.
remote: Total 595 (delta 255), reused 589 (delta 253)
Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done.
Resolving deltas: 100% (255/255), done.
2. 查看当前远程库
$ git remote
origin
$ git remote -v
origin git://github.com/schacon/ticgit.git
$ git remote -v
bakkdoor git://github.com/bakkdoor/grit.git
cho45 git://github.com/cho45/grit.git
defunkt git://github.com/defunkt/grit.git
koke git://github.com/koke/grit.git
origin git@github.com:mojombo/grit.git
3. 添加远程仓库
$ git remote
origin
$ git remote add pb git://github.com/paulboone/ticgit.git
$ git remote -v
origin git://github.com/schacon/ticgit.git
pb git://github.com/paulboone/ticgit.git
4. 从远程仓库抓取数据
$ git fetch [remote-name]
5. 推送数据到远程仓库
$ git push [remote-name] [branch-name]
$ git push origin master
$ git push [远程名] [本地分支]:[远程分支]
$ git push [远程名] :[远程分支] #删除远程分支
6. 查看远程仓库信息
$ git remote show [remote-name]
$ git remote show origin
* remote origin
URL: git://github.com/schacon/ticgit.git
Remote branch merged with 'git pull' while on branch master
master
Tracked remote branches
master
ticgit
7. 远程仓库的删除和重命名
$ git remote rename pb paul
$ git remote
origin
paul
$ git remote rm paul
$ git remote
origin
8. 在远程仓库中创建分支
将mybranch1分支推送到远程仓库中,在远程仓库中新建分支,并添加追踪
$ git push -u origin mybranch1
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:gotgithub/helloworld.git
* [new branch] mybranch1 -> mybranch1
Branch mybranch1 set up to track remote branch mybranch1 from origin.
Tag管理
1. tag的创建
$ git tag <tagname> [<commit>]
$ git tag -m "Tag on initial commit" mytag1 HEAD^
$ git tag -m "Tag on new commit" mytag2
2. 查看tag
$ git tag -l -n1
mytag1 Tag on initial commit
mytag2 Tag on new commit
3. 将本地tag推送到远程仓库中
$ git push origin refs/tags/*
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 548 bytes, done.
Total 5 (delta 0), reused 0 (delta 0)
To git@github.com:gotgithub/helloworld.git
* [new tag] mytag1 -> mytag1
* [new tag] mytag2 -> mytag2
4. 删除本地tag
$ git tag -d mytag3
Deleted tag 'mytag3' (was c71231c)
5. 删除远程仓库中的tag
$ git push origin :mytag3
To git@github.com:gotgithub/helloworld.git
[deleted] mytag3