版本控制系统
版本控制
版本控制(Version Control)的作用是追踪文件的变化。为什么需要版本控制?简单说,就是当你出错了,可以很容易地回到没出错时的状态。
你可能已经在不知不觉中,布置了自己的版本控制系统。比如,创建了类似下面这样的文件名:
- 论文_0510.doc
- 论文_0514.doc
- 论文_0521.doc
- 论文_修改版.doc
- 论文_最终不修改版.doc
这就是软件中为什么有”Save As”命令的原因。它使得你可以在不破坏源文件的基础上,得到一个类似的新文件。文件的多版本保存是一个常见问题,通常的解决办法是这样的:
- 做一个文件备份(比如Document.old.txt)。
- 在文件名中加入版本号或日期(比如Document_V1.txt,DocumentMarch2007.txt)。
- 在多人编辑的环境下,共享一个文件目录,并且要求每个人编辑完以后,在文件上做出标识。
什么是版本控制系统(VCS)?
大型的、频繁修改的、多人编写的软件项目,需要一个版本控制系统(简称VCS,行话叫做”文件数据库”),追踪文件的变化,避免出现混乱。
一次典型的使用过程是这样的:
爱丽丝add一个文件(list.txt)进入repo。然后,她又把这个文件check out,做了一次编辑(在文件中加入milk这个单词)。接着,她将修改后的文件check in,并附有一条checking message(”加入了新的条目”)。第二天早上,鲍勃update了他本地的working set,看到了list.txt的最新修订版,其中包含了单词”milk”。如果他使用changelog或diff,都可以发现前一天爱丽丝加入”milk”这个词。
网上有许多VCS软件可供选择,并且都有详细的教程或手册,比如SVN、CVS、RCS、Git、Perforce等等。
版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被版本控制系统管理起来,每个文件的修改、删除,都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
Git
安装Git
直接从AppStore安装Xcode,Xcode集成了Git,不过默认没有安装,你需要运行命令xcode-select --install
安装“Command Line Tools”,点“Install”就可以完成安装了。
创建版本库
- 选择一个合适的地方,创建一个空目录:
$ mkdir learngit $ cd learngit
- 通过
git init
命令把这个目录变成Git可以管理的仓库:$ git init Initialized empty Git repository in /Users/Chaosky/Desktop/learngit/.git/
瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
把文件添加到版本库
- 编写一个README.md文件,内容如下:
Git is a version control system. Git is free software.
一定要放到learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。
- 用命令
git add
告诉Git,把文件添加到仓库:$ git add readme.txt
执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。
- 用命令
git commit
告诉Git,把文件提交到仓库:$ git commit -m "wrote a readme file" [master (root-commit) cb926e7] wrote a readme file 1 file changed, 2 insertions(+) create mode 100644 readme.txt
简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
git commit命令执行成功后会告诉你,1个文件被改动(我们新添加的readme.txt文件),插入了两行内容(readme.txt有两行内容)。
为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt $ git add file2.txt file3.txt $ git commit -m "add 3 files."
工作区和暂存区
-
工作区(Working Directory)
就是你在电脑里能看到的目录。
-
版本库(Repository)
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用
git add
把文件添加进去,实际上就是把文件修改添加到暂存区;第二步是用
git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
?
版本库管理
-
git status
查看仓库当前的状态,要随时掌握工作区的状态,使用git status命令。
-
git diff
如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
-
git log
显示从最近到最远的提交日志。在Git中,用HEAD表示当前版本,也就是最新的提交,上一个版本就是HEAD^ ,上上一个版本就是HEAD^^ ,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
-
git reset –hard commit_id
在版本的历史之间进行切换,
commit_id
为提交版本的id。 -
git reflog
用来记录你的每一次命令
-
撤销修改
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令
git checkout -- README.md
。场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令
git reset HEAD README.md
,就回到了场景1,第二步按场景1操作。 -
git rm
用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
远程仓库
分布式版本控制系统通常也有一台充当“中央服务器”的电脑,而充当”中央服务器”角色的仓库就是远程仓库,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
如果有自己的私有仓库地址,则无需执行下面几个操作。
-
注册远程仓库账号
- [email protected]:开源中国Git托管平台
- Github:世界最大的Git项目托管平台
- Coding:国内新兴的Git托管平台
服务器左下角有上传远程服务器需要的代码
-
添加公钥到Git托管平台
-
生成公钥
SSH Keys:SSH key 可以让你在你的电脑和 Git托管平台之间建立安全的加密连接。
你可以按如下命令来生成sshkey:
$ ssh-keygen -t rsa -C "[email protected]"
其中
[email protected]
需要填写邮箱信息生成SSH key时,如果不清楚需要输入的信息,可以全部输入Enter键。
-
查看你的public key,并把他添加到Git托管平台
$ cat ~/.ssh/id_rsa.pub
具体添加的位置,查看具体的托管平台。一般来说,在个人资料中可以找到
SSH-KEYS
类似的字样就是添加公钥的地方。 -
测试是否添加成功
测试[email protected]输入命令:
$ ssh -T git@git.oschina.net Welcome to Git@OSC, yourname!
测试Github输入命令:
$ ssh -T git@github.com Hi chaoskyme! Youve successfully authenticated, but GitHub does not provide shell access.
生成SSH key只需要生成一次,不同的网站再将公钥拷贝到网站上即可。
-
-
在Git托管平台上创建项目
-
添加远程仓库
关联一个远程仓库命令:
$ git remote add origin git@server-name:path/repo-name.git
其中
origin
表示远程仓库的别名,默认为origin
[email protected]:path/repo-name.git
表示项目在Git托管平台上的ssh 地址。关联远程仓库只需要执行上面的命令一次即可。
关联后,第一次推送master分支的所有内容命令:
$ git push -u origin master
此后,每次本地提交后,只要有必要,推送最新修改就可以使用命令:
$ git push origin master
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
-
克隆远程仓库
$ git clone [email protected]name:path/repo-name.git <repo-name>
-
从远程分支获取最新版本到本地,有2个命令
- git fetch:相当于是从远程获取最新版本到本地,不会自动merge
$ git fetch origin master $ git log -p master..origin/master $ git merge origin/master
以上命令的含义:
首先从远程的origin的master主分支下载最新的版本到origin/master分支上;
然后比较本地的master分支和origin/master分支的差别;
最后进行合并。
- git pull:相当于是从远程获取最新版本并merge到本地
$ git pull origin master
上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些
因为在merge前,我们可以查看更新情况,然后再决定是否合并
分支管理
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
用git log --graph
命令可以看到分支合并图。
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
$ git push origin master
标签管理
git tag <name>
用于新建一个标签,默认为HEAD,也可以指定一个commit id;
git tag -a <tagname> -m "blablabla..."
可以指定标签信息;
git tag -s <tagname> -m "blablabla..."
可以用PGP签名标签;
git tag
可以查看所有标签
git push origin <tagname>
可以推送一个本地标签;
git push origin —tags
可以推送全部未推送过的本地标签;
git tag -d <tagname>
可以删除一个本地标签;
git push origin :refs/tags/<tagname>
可以删除一个远程标签。
Git常用命令速查表
参考文章
- http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
- 参考书籍:《Git权威指南》
- http://backlogtool.com/git-guide/cn/
关于 git管理我们的版本 总的来说 特点是:git非常灵活 易于管理 但是操作上要复杂一点
在学习git指令时可能比较复杂 可以去看上面廖旭峰的博客 它讲得很清楚
关于git 管理还有一款软件要推荐 SourceTree
用他可以很方便管理我们的版本 其中涉及到 克隆服务器上的项目 从URL克隆
克隆别的服务器上的项目 需要fork到自己的服务器 可以把服务器上的项目下载下来进行修改 然后通过 添加暂存 提交 以及推送 发送给自己的在线服务器 如果是发给别的服务器 需要用到一个pull request指令