集中式版本控制系统:
版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。
首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
$ git add readme.txt
$ git commit -m "这里写的是说明内容"
$ git init 初始化一个Git仓库
添加文件到git仓库分两步:
1、git add 可反复添加文件
2、使用命令git commit,完成
$ git status 查看仓库当前的状态
$ git diff file 查看file的改变情况
$ git log 显示从最近到最远的提交日志
在git中,用HEAD表示当前版本,也就是最新的提交,上一个版本为HEAD^,往上10个版本是HEAD~10
$ git reset --hard HEAD^ 退回上一个版本
$ git reset --hard 23234 (这里请填写版本号,可以不用写全,git会自动去找)
$ git relog可以查看命令历史
工作区和暂存区:
Working Directory:就是电脑能够看到的目录,like learngit
Repository:工作区有一个隐藏的目录.git,这个不算一个working directory,是git的版本库
Git的版本库里存了很多东西,其中最重要的是称为stage的暂定区,还有git为我们创建的第一个分支master,
以及指向master的一个指针叫HEAD;
$ git add file 将文件添加进去,实际上是添加到暂存区
$ git commit -m"" 提交更改,实际上就是把暂存区的所有内容提交到当前分支
git commit 就是往master分支上提交更改
git跟踪并管理的是修改,而不是文件
git commit 只会将add到暂存区的修改commit上去
svn针对的则是整个文件的修改。
$ git checkout -- file
文件在work directory的修改全部撤销
$ git reset HEAD file
把暂存区的修改回退到工作区,使用HEAD表示最新的版本
$ rm file在文件管理器中把文件删除
$ git rm file 在版本库中删除该文件,git rm
$ git checkout -- test.txt
其实是用版本库里的版本替换工作区的版本,无论是修改还是删除,都可以一键还原。
远程仓库:
私钥公钥:用户主目录中找到.ssh目录,里面有id_rsa和id_rsa_pub两个文件
,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa_pub是公钥,可以放心地告诉任何人。
github允许添加多个Key,若干台电脑都可以同时提交,在github上免费托管的git仓库,任何人都可以看到,所以切记不要把敏感信息放上去
$ git remote add origin git@github.com:hmy361/learngit.git
本地仓库关联的远程仓库就是learngit.git,我的github下的账户
$ git push -u origin master
把本地库的内容推送到远程,用git push命令,实际上是把分支master推送到远程
由于远程库是空的,我们第一次推送master分支时,加上-u参数,git不但会把本地的master分支内容推送到远程,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
关联后本地做了提交,就可以通过命令:
$ git push origin master 把本地master分支的最新修改推送到github,至此已经拥有真正的分布式版本库
关联一个版本库,使用命令:git remote add origin git@server-name:path/repo-name.git
关联后,使用命令git push -u origin master第一次推送master分支的所有内容
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改!
克隆远程库
$ git clone git@github.com:hmy361/testclone.git
克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
git支持多种协议,包括https,但是通过ssh支持的原声git的速度最快
分支master
理应为工作小组中的每一个成员创建一个分支,在一天工作结束后,不能保证代码整体是可用的情况下,可将代码提供到自己的分支中,待代码完成后,一次性将本地分支提交到远程库。
这样子即确保了小组其他成员的开发不受影响,同时也确保了代码不会丢失
创建和合并分支
在版本回退中,每次提交,Git都把它们串成一个时间线,这条时间线就是一个分支,git中默认创建的分支,叫做主分支,即master分支,HEAD 严格来说不是指向提交,而是指向分支,master才是指向提交的,HEAD指向的就是当前分支。
一条时间线的时候:HEAD–>master–>当前分支,以及当前分支的提交点
每次提交master分支都会向前移动一步。
当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。
从现在开始,对工作区的修改和提交就是针对dev分支了,不如新提交一次后,de指针往前移动一步,而master指针不变
当dev上的工作完成时,就可以把dev合并到master上。
将master指针指向dev的当前提交,就完成合并了
$ git checkout -b dev
-b参数表示创建并切换,相当于以下两条命令:
$ git branc dev 创建分支
$ git checkout dev 切换到dev分支。
$ git branch 查看当前分支
$ git checkout master 切换回master分支
将dev的分支工作成果合并到master分支上。
$ git merge dev this is fast-forward,快进的方式合并
$ git branch -d dev删除dev分支
git建议使用分支完成某个任务。合并后再删掉分支这和直接在master分支上工作的效果是一样的
但是过程更加安全
分支常用指令:
$git branch 查看当前分支
$git branch name 创建分支。
$git checkout name切换分支
$git checkout -b name创建并切换分支
$git merge name 合并某分支到当前分支
$git branch -d name删除分支
冲突手动解决,可以借用同步工具解决冲突,解决冲突后,再提交,合并完成
$git log –graph
分支管理策略
通常,合并分支时,如果可能,Git会用”Fast forward”模式,但这种模式下,删除分支分支后,分支消息,会丢掉分支消息,如果要强制禁用”Fast forward”模式,Git就会再merge时生成一个新的commit,–no-ff方式的merge。
实际开发中,按照几个基本原则进行分支管理:
1、master分支应该是非常稳定的,也就是仅仅用来发布新版本,平时不能再上面干活
2、干活都在dev分支上,也就是说dev分支时不稳定的,在发布1.0版本的时候再把dev上合并到master上,在master分支发布1.0版本
3、和团队成员都在dev分支上干活,每个人都有自己的分支,时不时在dev上面合并就可以了!
–no-ff参数就可以用普通模式合并,合并后会有历史分支,就能看到曾经的合并,而fast-forward就看不到曾经的合并分支
Bug分支:应用场景:bug出现需要修复,当前分支工作尚未完成。需要新建分支修复bug,同时保存当前进度。
git提供一个stash功能,可以把当前工作现场”储藏”起来,等以后恢复线程后继续工作
$git stash 把当前工作隐藏起来,以后可以再恢复。
此时用status 查看work directory就是干净的,因此可以放心的创建分支来修复bug。
$git stash list 查看stash区间的目录
$git stash apply 恢复,但是此恢复,stash内容并不会删除,
$git stash drop 删除
$git stash pop 恢复并删除原来的
Feature分支,开发一个新的feature,最好新建一个分支,如果要丢弃一个没有被合并过的分支,可以通过
$git branch -D name强行删除
多人协作:
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且远程仓库的默认名称是origin。
要查看远程库的信息,用
$git remote:
$git remote -v显示更详细的信息
$git push origin name将某分支推送到远程
在有冲突的情况下,把最新的提交从origin/dev抓下来,然后再本地合并,解决冲突,再推送
工作模式通常是:
git push origin branch-name推送自己的修改
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并
如果合并有冲突,则解决冲突,并在本地提交
没有冲突或者解决掉冲突后,在用git push origin branch-name推送就能成功。
如果git pull提示“no tracking infomation”,则说明本地分支和远程分支未建立连接,用命令
git branch –set-upstream
branch-name origin/branch-name;
git tag name -m”说明的内容”;//打标签
git show tag -m“说明的内容”;//查询tag相关信息
git tag查看所有的tag标签
tag相关操作:
git push origin tagname 可以推送改一个本地标签
git push orgin –tags推送全部位推送过的本地标签
git tag -d tagname删除一个本地标签
git push origin :refs/tags/tagname可以删除一个远程标签