Git 版本控制工具
学习目标
必备(项目开发中必定用到) * 能够克隆服务器上的分支并会切换分支
拓展 * 本地git操作 * 远程仓库合并 * 学会看提示信息去掌握git的方法
文档
中文权威文档:https://git-scm.com/book/zh/v2
安装Git
- git-scm https://git-scm.com/
需要了解几个问题
- 为什么需要版本控制工具?
- 了解版本控制工具的发展历程
- 了解本地版本控制系统、集中化版本控制系统和分布式版本控制系统的异同
为什么需要版本控制工具?
- 备份文件(U盘)
- 记录历史(历史书)
- 回到过去(时光机)
- 多端共享(百度云盘)
- 团队协作(复仇者联盟)
版本控制工具的发展历程
cvs(1985年) — svn(2000年) — git(2005)
Git诞生
在2002年以前,世界各地的志愿者把源代码文件发给Linus,然后由Linus本人通过手工方式合并代码!
因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。
有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。
到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。
安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。
Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。
Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。
集中式和分布式的区别
git-scm 官方说明
集中式:代码都保存在中央服务器,开发人员按需获取代码,修改完成后提交到中央服务器保存
- 优势:
- 方便权限和内容统一管理
- 可以按需检出代码,节省客户端硬盘空间
- 劣势:
- 连接不上服务器时,无法获取和提交更新
分布式:代码保存在每一个客户端中,开发人员在本地由完整的项目代码,修改完成后保存在本地仓库。在将来通过网络或其他方式,相互交换修改历史
- 优势:
- 分布式存储,不担心服务器故障导致的代码丢失
- 劣势:操作太灵活,有学习成本
Git的优势
- 分布式
- 强大的分支(支持非线性的开发模式)
- 灵活(甚至可以修改历史)
常用的操作
创建仓库
git init # 在当面目录下创建仓库
设置昵称和邮箱
git config --global user.name "Gavin" # 设置昵称 git config --global user.email "Gavin@email.com" # 设置邮箱
### 注意git的设置分为“当前仓库设置”和”全局设置”,上面加了–global是对全局生效的
- 创建或修改文件
这个就略了吧。。
将文件加入版本控制
git add xxx.md
提交此次修改
git commit -m "增加了一个文件,并且修改了内容"
查看修改历史
git log
创建新分支,进行实验性的操作
git checkout -b new_branch
合并分支
git checkout master # 切换到接收合并的分支 git merge new_branch # 接收new_branch 分支的合并
删除分支
git branch -d new_branch
切换版本
git reset --hard 1j284jf # 切换到指定了历史中
注意!以上命令都是你的本地仓库进行的!!!!
注意!以上命令掌握之后,日常使用GUI完成操作!
为什么?
如何和他人交换代码(其实就是交换History)
git托管平台
- github # 全球最大的同性交友网站
- gitlab # 开源的高度定制化的托管平台
- gogs# 国人使用go开发的开源精简平台
- bitbucket # 国外的免费私有库平台
- gitee # 国内的免费私有库平台
获取仓库地址
推送
push
思考,既然是分布式的,那么现在远程仓库和本地仓库的内容是一摸一样吗
对于已经push 的分支来说是的。但是对于没有push的分支,远程仓库是没有的
fork
- 派生一个远程仓库(注意远程仓库,是指托管平台中的仓库,本地仓库是指你电脑中的仓库)
Pull Request
- 远程仓库建的合并(请求目标仓库合并自己的仓库)
- 前提:有fork关系
- 本质将一个仓库的某分支合并到另一个的仓库的某分支
说明,获取代码是整个仓库,交换代码(更新)是以分支为单位的
所以,新功能一般在新分支开发,然后把整个分支合并到主分支上
Git工作流程
获取代码
- 如果没有克隆仓库,先克隆仓库
git clone git@gitee.com:DN_Ian/Vip1710.git
- 获取最新数据,使本地仓库与远程仓库一致
git fetch
# 注意pull命令fetch命令的区别,fetch/pull,抓取/拉取, **pull == fetch + merge **
- 如果没有克隆仓库,先克隆仓库
开发代码
切换到要开发的分支 (假设要对gavin分支进行开发)
git checkout origin/gavin
新建私有分支,进行开发
git checkout -b my_branch
开发代码
(略)
提交
git commit -a
(在私有分支my_branch
上)
上传代码
- 保存好正在开发的代码
获取最新数据,使本地仓库与远程仓库一致
git fetch origin
切换到要开发的分支 (假设要对gavin分支进行开发)
git checkout origin/gavin
// 切到一个临时分支,没有名字, 版本与远程gavin分支相同将开发完成的私有分支合并, 如果有冲突,使用gui处理冲突
git merge my_branch
上传修改后的gavin分支到远程仓库
git push origin my_branch:gavin #1,推送到属于自己的派生仓库,2.推送到目标分支
// 如果恰好此时远程仓库的gavin分支发生变化,会提示冲突。则重新操作- 保存好正在开发的代码
注意区别
本地和本地—— checkout/merge
本地和远程—— clone/pull/fetch/push
远程和远程—— fork/pull reuqets
- | 本地 | 远程 |
---|---|---|
本地 | checkout/merge | clone/fetch/push |
远程 | clone/fetch/push | fork/pull reuqets |