SVN--集中式版本控制工具典型代表
Git-分布式版本控制工具典型代表
1、git概述
1.1 git结构
1.2 git和代码托管中心
代码托管中心的任务:维护远程库
1、局域网环境下:GitLab服务器
2、外网环境下:GitHub
码云
1.3 本地库和远程库
1、团队内部协作
2、跨团队协作
2 git命令行操作
2.1本地库初始化
D盘-->右击“Git Bash Here”
进入到工作区(workspace)中
cd workspaces/
进入到git专有目录(GitSpaceVideo)中
cd GitSpaceVideo/
在该目录下新建一个项目目录(WeChat作为开发的项目)
mkdir WeChat
进入WeChat目录
cd WeChat\
初试化Git本地库
git init
初试化的本地库还在.git目录下(.git为自动创建,为隐藏文件),显示隐藏文件
ls -la
.git目录下的文件(初始化本地库的效果)
ll .git/ 或 ls -l .git/
PS: .git目录中存放的是本地库相关的子目录和文件,不要删除,也不要胡乱修改
2.2设置签名
形式:
用户名:Tom
Email地址:goodmorning@nihao.com
作用:
区分不同开发人员的身份
PS: 这里设置的密码和登录远程库(代码托管中心)的账号、密码没有任何关系。
命令:
项目级别/仓库级别:仅在当前本地库范围内有效
git confg user.name Tom_pro
git config user.email goodMorning_pro@nihao.com
查看保存的项目级别的签名信息(保存在./.git/config文件中),cat .git/config
系统用户级别:在登录当前操作系统的用户范围内有效
git config --global user.name Tom_pro
git config --global user.email goodMorning_pro@nihao.com
查看保存的系统级别的签名信息(保存用户家目录中,位置~/.gitconfig文件中),cd ~
PS: 优先级:项目级别 > 系统用户级别 (就近原则)
两个级别都没有是不允许的
2.3添加提交以及查看状态操作
git命令都是以git开始的
查看状态: git status
创建txt文件(vim good.txt)后,再查看状态
执行添加操作: git add good.txt
再次查看状态
将文件从暂存区删除:git rm --cached good.txt
将文件从暂存区提交到本地库:git commit good.txt
VIM编辑器
按“i”键进入编辑模式
按esc键 输入:wq 写入退出编辑器
再次查看状态
提交完成后,再修改该文件(vim good.txt )
·
查看状态
提交时,不用打开vim编辑器来添加提交信息,命令:git commit -m "提交信息" good.txt
2.4 添加提交以及查看状态命令小结
状态查看: git status 查看工作区、暂存区的状态
添加操作:git add [filename] 将工作区的新建或修改添加到暂存区
提交操作:git commit -m "commit message" [filename] 将暂存区的内容提交到本地库
2.4 版本的前进与后退
1、查看版本的历史记录:
git log (显示的过于详细)
当版本特别多的时,每条日志只显示一行:git log --pretty=oneline(显示简洁)
或者: git log --oneline(哈希值只显示一部分)(只显示当前版本过去的版本)
在online基础上到某个历史版本,Head指针需要移动的次数: git reflog (显示所有历史版本)
HEAD@{需要移动的次数}
ps:多屏显示控制方式:
空格 :向下翻页
b : 向上翻页
q :退出
2、在历史记录的基础上,前进或后退到某个版本
本质上是HEAD指针的操作
1、基于索引值的操作【推荐】
git reset --hard [索引值]
2、使用^符号
只能往后退,且只显示当前所在版本的后面的版本,不显示前面的版本
git reset --hard HEAD^ (后退几个版本就加几个“^”符号)
3、使用~符号
只能往后退
git reset --hard HEAD~[后退几步的数字]
4、reset三个参数hard、soft以及mixed参数对比
--soft 参数 : 仅仅在本地库移动HEAD指针
--mixed 参数 :在本地库移动HEAD指针,并且重置暂存区
--hard 参数 : 在本地库移动HEAD指针,重置暂存区,重置工作区
3、提交到本地库的删除文件后找回
使用历史版本回退即可:git reset --hard [索引值]
创建一个文件:vim aaa.txt
添加到暂存区: git add aaa.txt
提交到本地库: git commit -m "new aaa.txt" aa.txt
查看暂存区状态: git status
删除文件: rm aaa.txt
查看工作区(文件已经被删除):ls -l 或 ll
查看状态:git status(即删除后的状态)
使用git add aaa.txt 添加到暂存区
git status 查看状态
删除的操作提交到了本地库
这种情形,想要恢复删除的文件,将版本回退到上一版本(即索引值为567f4e1),
使用索引值恢复文件:git reset --hard 567f4e1
4、添加到暂存区的删除文件后找回
将apple.txt添加到暂存区 git add apple.txt , 提交到本地库 git commit -m "new apple.txt" apple.txt
删除apple.txt文件
将删除的操作添加到了暂存区
但还没有提交到本地库
这种情形下恢复回复删除的文件,HEAD指针指向的版本即为想要恢复的版本(创建apple.txt时的版本)
使用HEAD指针恢复删除的文件,git reset --hard HEAD
5、删除文件找回方式小结
前提:删除前,文件存在的状态提交到了本地库
操作:git reset --hard [指针位置]
删除操作已经提交到本地库:指针位置指向文件存在时的历史记录,即使用索引值
删除操作并没有提交到本地库,而是添加到暂存库:指针位置使用HEAD
6、比较文件操作(diff命令)
存在两个文件
修改其中一个文件 vim apple.txt
比较文件修改前后的差异:git diff apple.txt
将修改后的文件添加到暂存区,再进行比较,没有任何区别
如果和本地库中的某个版本比较,git diff HEAD apple.txt 是有区别的
小结:
git diff [文件名]:将工作区的文件和暂存区进行比较
git diff [本地库中历史版本][文件名]:将工作区的文件和本地库历史记录比较
不带文件名,比较多个文件
7、git的分支
在版本控制过程中,使用多条线同时推进多个任务
提高开发效率,一个分支出现问题不会影响到其他分支
7-1、分支的操作
查看当前所有分支:git branch -v
创建分支:git branch [分支名]
切换分支:git checkout [分支名]
合并分支merge:
修改了一个分支后,最新修改的分支,在分支列表中,处于最前面
第一步:要将分支切换(checkout)到要合并到的分支上面:
git checkout [要合并到的分支]
第二步:合并分支:
git merge [修改过的分支名]
7-2 解决分支合并后产生的冲突
修改master分支上good.txt文件,并添加到缓存区,提交到本地库
切换分支到 hot_fix,修改该分支上同一文件(good.txt),并添加到暂存区,提交到本地库
此时,合并分支,出现错误(与SVN合并冲突的不同的是,git不会产生其他文件)
查看修改的文件
分支的表现
冲突解决
第一步:删除冲突的标记 , :wq 即可
第二步:使用 git add 命令将冲突标记为已解决: git add good.txt
所有的冲突已解决
第三步:使用git commit 命令再进行合并,此时命令中不能包含文件名
git commit -m "提交信息"
8、git的基本原理
8-1、哈希算法
不管输入数据的数据量有多大,输入同一个哈希算法,得到的加密结果长度固定;
哈希算法确定,输入数据确定,输出数据能够保证不变;
哈希算法确定,输入数据有变,输出数据一定有变化,而且通常变化很大;
哈希算法不可逆。
git底层采用的是SHA-1算法。哈希算法可以被用来验证文件的一致,git就是靠这种机制从根本上保证数据完整性的
8-2、git保存版本的机制
集中式版本控制工具(SVN)的文件管理机制:
以文件变更列表的方式存储文件,将保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异,是一种增量式
的版本控制。
Git的文件管理机制(快照流)
Git把数据看作是小型文件系统的一组快照。每次提交更新时Git都会对当前的全部文件制作一个快照并保存这个快照索引。如果文件没有被修改,G不再重新存储该文件,而是只保留一个链接指向之前存储的文件。
8-3、git创建合并分支的机制--指针
9、GitHub
9-1、账号注册
https://github.com 使用邮箱注册
9-2、初始化新的本地库
创建工作目录:mkdir huashan
进入该目录:cd huashan/
初始化目录:git init
设置用户签名:git config --global user.name Tom_pro
git config --global user.email goodMorning@nihao.com
新建一个文件:vim huashanjianfa.txt
添加到暂存区:git add huashanjianfa.txt
提交到本地库:git commit -m "testgithub" huashanjianfa.txt
9-3、远程库操作
登录github
创建新的仓库
验证邮箱地址
输入仓库名
远程库地址,复制地址:
在本地创建远程库地址别名(远程库地址过长)
git remote add 别名 远程库地址
查看该地址:git remote -v
1、推送操作(push):
git push 远程主机名 本地分支名:远程分支名
如果本地分支名与远程分支名相同,则可以省略冒号:
git push 远程主机名 本地分支名
远程库中有了刚刚推送的文件
2、克隆操作(clone)
开发人员想从产品经理的远程库获取文件
开发人员创建自己的工作目录,并进到该目录:
git clone [远程库地址]
本地工作目录就有了该远程库中的文件,并且自己的工作目录不用初试化,在进行克隆操作时,已经初试化好了(有了.git文件)
并且远程库的别名也被创建好了
小结:
克隆操作的三个效果:1、完整的将远程库下载到本地
2、创建origin远程地址别名
3、 初始化本地库
开发人员可以修改克隆的操作,并且添加至暂存区、提交到自己的本地库,但是此时开发人员不能将修改后的文件推动到远程库是不行的(该开发人员还不是项目经理团队的成员)
3、邀请加入团队成员操作
项目经理在github,Settings-->Collaborators-->输入想要邀请的开发人员的github账号-->点击add collaborator
复制邀请链接发给想要邀请的开发人员,
该开发人员通过该链接访问,接收邀请,成为团队成员
此时,开发人员再进行推送,推送至远程库成功。
4、远程库修改的拉取(pull = fetch + merge)
fetch和merge都是“读”操作,所以不需要进行登录操作,将fetch和merge分开,目的是,不急于将远程库修改的文件下载下来,而是看好修改后的文件是什么样子,再考虑之后是否合并。
fetch操作:
情景:开发人员修改了一个文件到了远程库,
项目经理抓取(fetch)远程库中这一文件:git fetch [远程库地址别名][远程分支名]
抓取完之后,本地文件没有变化(开发人员修改的地方没显示出来)
fetch只将远程库的内容下载到本地,但并没有更改本地工作区的文件
查看抓取的文件在哪里:
切换分支到 origin/分支 上 git checkout origin/master
查看该文件,就能看到开发人员修后的内容
merge操作
将远程库分支master上的文件合并到本地库分支master上
git merge [远程库地址别名/远程分支名]
pull操作
开发人员修改一个文件,添加至暂存区,提交到本地库,之后推送到远程库
执行pull操作,git pull [远程主机名] [远程分支名]:[本地分支名]
如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
9-4、协同开发时,冲突的解决
项目经理修改文件,提交到本地库,推送至远程库中。
此时,开发人员同样修改此文件,提交到本地库,推送至远程库时,出现错误。
情景:
开发人员必须先拿到在他修改之前被修改的文件(即,项目经理修改的文件),使用pull操作
此时文件正处于冲突状态
打开该冲突文件
解决冲突方法:1、将标志冲突记号删除,改成所需要的样子,:wq 保存退出
2、添加到暂存区,提交至本地库(commit 时不要添加文件名)
3、推送至远程库
小结:
1、如果不是基于github远程库的最新版本所做的修改,不能推送, 必须先拉取;
2、拉取下来,后如果进入冲突状态,则按照“分支冲突解决”操作解决即可。
9-5、跨团队协作
第一步: fork
本公司项目经理A将所属的远程库地址复制给其他公司开发人员C,
C登录github,访问A发给其的地址,点击“Fork”(是以C的身份点击Fork)
点击完成后,页面动画提示,正在Fork
第二步: C Clone到本地,push到远程库
C进入自己的工作空间,克隆到本地:git clone [远程库地址]
(该远程地址是自己已经fork完成后自己的远程库地址)
同样的,C执行克隆操作不需要进行初始化本地库
克隆完毕后,可以修改文件,之后提交到本地库
执行push操作,将修改后的文件,推送至远程库 push origin master
推送结束后,C就能在自己的远程库看推送的修改后的文件
第三步: pull request
C点击Pull requests-->New pull request-->Create pull request
C输入消息的标题和内容-->Create pull request
第三步:A登录github远程库-->pull request 能看到C发的消息
点击C发的消息,可以查看消息内容,并且与C进行对话
第四步:A审核
第五步:审核没问题,回到对话Conversation,进行合并Merge
添加合并信息
第五步:A将合并后的文件拉取本地:pull
git pull origin master