分布式版本控制--Git的灵魂使用
版本控制简介
集中式版本控制
集中式版本控制系统有一个中央服务器,每个人在工作时都需要从中央服务器中获得最新版本,在修改后提交到中央服务器,其他人再获取最新代码进行更改。这种方式的缺点是,我们必须有一个中央服务器,由于网络等原因无法连接到服务器或者服务器宕机时,我们就无法进行数据获取和提交;而且由于是互联网操作,所以网络环境也会影响到提交、下载速度。常用的集中式版本系统有CVS和SVN等,如下所示。
分布式版本控制
分布式版本控制(DVCS)是一种不需要中心服务器的管理文件版本的方法,但是通常也有一台充当“中央服务器”的计算机,但这个服务器仅仅用来方便交换我们的修改,没有它时我们同样干活,只是交换修改时不太方便。分布式的设计理念有助于减少对中心仓库的依赖,从而有效减少中心仓库的负载,改善代码提交的灵活性。常用的分布式版本控制为Git,如下所示。
Git分布式设计思想所带来的另一个好处是支持离线工作。对于CVS、SVN这种严重依赖网络的C/S工具而言,没有了网络或者VPN,代码的检入与检出操作就无法正常进行了。而使用Git,则即便在没有WiFi的飞机或者火车上,我们照样可以频繁地提交代码,只不过是先提交到本地仓库,等网络通时,再上传到远程的镜像仓库。
Git分布式版本控制系统没有中央服务器,每个站点上都有一个完整的版本库,每个站点却只是我们自己用来开发的计算机而已。我们可以在本地进行修改、提交,在需要进行代码合并时,只要将自己的版本库推送给合作伙伴即可,这样对方就可以看到更改。同样,对方也可以将自己的版本库推送给我们,这样我们就可以看到对方的修改了。由于每个人的计算机里都是一个完整的版本库,所以若不小心丢失数据,则只需要从其他地方复制一份就可以了。
Git安装
Debian、Ubuntu系统下的安装如下:
$apt-get install git
CentOS 和 Fedora 系统下的安装如下:
$yum update
$yum install git
Git的常用命令
Git的主要区域如下
- 工作区:在计算机中能看到的目录,它持有实际文件。
- 缓存区:临时保存我们的改动。
- 版本库:工作区有一个隐藏目录.git,是Git的版本库。
- 远程仓库:托管在因特网或其他网络中的项目版本库,可供多人分布式开发。
Git配置项
显示当前的Git配置
$ git config --list
编辑Git配置文件
$ git config -e [--global]
设置用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
Git的设置文件为.gitconfig,它可以全局配置,也可以只为项目配置。
新建仓库
在当前目录新建一个Git仓库
$ git init
新建一个目录,将其初始化为Git仓库
$ git init [project-name]
克隆一个仓库
$ git clone [url]
增加、删除文件
添加指定文件到暂存区
$ git add [file1] [file2] ...
添加指定目录到暂存区,包括子目录
$ git add [dir]
添加当前目录的所以文件到缓存区
$ git add .
删除工作区文件,并且将这次删除放入缓存区
$ git rm [file1] [file2] ...
改名文件,并且将这个改名放入缓存区
$ git mv [file-original] [file-renamed]
提交文件
提交缓存区到仓库区
$ git commit -m [message]
提交缓存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]
提交工作区自上次commit之后的变化,直接提交到仓库区
$ git commit -a
提交时显示所有diff的信息
$ git commit -v
使用一次新的commit,替代上一次提交
如果代码没有任何新变化,则用来改写上一次comit的提交信息
$ git commit --amend -m [message]
Git分支
列出所有本地分支
$ git branch
列出所有远程分支
$ git branch -r
列出所有本地和远程分支
$ git branch -a
新建一个分支,但依然停留在当前分支
$ git branch [branch-name]
新建一个分支,并切换到该分支
$ git checkout -b [branch]
新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remoe-branch]
切换到指定分支,并更新工作区
$ git checkout [branch-name]
切换到上一个分支
$ git checkout -
建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
合并指定分支到当前分支
$ git merge [branch]
选择一个commit,合并在当前分支
$ git cherry-pick [commit]
删除分支
$ git branch -d [branch-name]
删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
Git的标签
列出所有tag
$ git tag
在当前commit上新建一个tag
$ git tag [ tag ]
在指定commit上新建一个tag
$ git tag [ tag ] [ commit ]
删除本地tag
$ git tag -d [ tag ]
删除远程tag
$ git push origin :refs/tags[tagName]
查看tag信息
$ git show [ tag ]
提交指定tag
$ git push [ remote ] [ tag ]
提交所有tag
$ git push [ remote ] --tags
新建一个分支,指向某个tag
$ git checkout -b [ branch ] [ tag ]
查看信息
显示有变更的文件
$ git status
显示当前分支的版本历史
$ git log
根据关键词搜索提交历史
$ git log -S [keyword]
显示指定文件是什么人在什么时间修改过
$ git blame [file]
显示暂存区和工作区的差异
$ git diff
显示暂存区和上一个commit的差异
$ git diff --cached [file]
显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
显示两次提交的元数据和内容变化
$ git diff [first-branch] ... [second-branch]
显示某次提交发生变化的文件
$ git show --name-only [commit]
远程同步
下载远程仓库的所有变动
$ git fetch [ remote ]
显示所有远程仓库
$ git remote -v
显示某个远程仓库的信息
$ git remote show [ remote ]
增加一个新的远程仓库并命名
$ git remote add [ shortname ] [ url ]
取回远程仓库的变化,并与本地分支合并
$ git pull [ remote ] [ branch ]
上传本地指定分支到远程仓库
$ git push [ remote ] [ branch]
强行推送当前分支到远程仓库,即使有冲突
$ git push [ remote ] --force
推送所有分支到远程仓库
$ git push [ remote ] -all
撤销
恢复暂存区的指定文件到工作区
$ git checkout [ file ]
恢复某个commit的指定文件到暂存区和工作区
$ git checkout [ commit ] [ file ]
恢复暂存区的所有文件到工作区
$ git checkout .
重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [ file ]
重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard
重置当前分支的HEAD为指定commit,同时重置暂存区,但工作区不变
$ git reset [ commit ]
重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [ commit ]
重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [ commit ]
新建一个commit,用来撤销指定commit
后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [ commit ]
暂时将未提交的变化移除,稍后再移入
$ git stash