很久之前就想系统的学习一下版本控制系统了,这两天抽空看了一下《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