〇、VCS
VCS
版本控制系统,最基本三个要素
版本控制
主动提交
中央仓库
CVCS
中央式版本控制系统
研发部 > VCS之Git > 1600a9978ea4bec3.jpeg
DVCS
分布式版本控制系统
研发部 > VCS之Git > 1600a9a4a20c2e6e.jpeg
分布式 VCS 的优点:
大多数的操作可以在本地进行,所以速度更快,而且由于无需联网,所以即使不在公司甚至没有在联网,你也可以提交代码、查看历史,从而极大地减小了开发者的网络条件和物理位置的限制(例如,你可以在飞机上提交代码、切换分支等等);
由于可以提交到本地,所以你可以分步提交代码,把代码提交做得更细,而不是一个提交包含很多代码,难以 review 也难以回溯。
分布式 VCS 的缺点:
由于每一个机器都有完整的本地仓库,所以初次获取项目(Git 术语:clone)的时候会比较耗时;
由于每个机器都有完整的本地仓库,所以本地占用的存储比中央式 VCS 要高。
一、Git背景
在1991年创建了开源的Linux之后,Linux不断壮大。
全世界的志愿者参与其中,来自于世界各地的源代码文件发给Linus,由Linus手动合并代码。
直到2002年,一个商业VCS软件BitKeeper授权给Linux社区免费使用。
2005年,创造Samba的Andrew写了一个简单程序,可以连接BitKeeper的存储库,BitKeeper著作权拥有者Larry认为Andrew对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的许可。Linux内核开发团队与BitMover公司进行磋商,但无法解决他们之间的歧见。
Linus并没有向BitKeeper的母公司道歉,而是花十天时间自己用C写了个分布式VCS,就是Git。在一个月之内,Linux的代码就由Git进行管理了。
2008年,GitHub上线,为开源项目提供免费Git存储,无数开源项目迁移至GitHub,包括jQuery,PHP,Ruby
一直到2020年7月27日,Git更新到目前最新的2.28.0版本。
二、Git和SVN
分布式和中央式
元数据存储和文件存储
分支逻辑,Git分支是指向提交,SVN是拷贝的目录
Git有唯一的SHA-1代码快照,SVN是有全局版本号的
内容完整性,Git使用SHA-1 哈希算法保证内容完整,SVN没有
三、Git基础
- 工作区和暂存区、版本库
工作区:就是你能看到的目录。
暂存区:stage或index。在.git/index中。
版本库:工作区有一个隐藏目录.git,是Git的版本库。 - HEAD和Master、Branch
引用:commit 的快捷方式
所谓「引用」(reference),其实就是一个个的字符串。这个字符串可以是一个 commit 的 SHA-1 码(例:c08de9a4d8771144cd23986f9f76c4ed729e69b0),也可以是一个 branch(例:ref: refs/heads/feature3)。
Git 中的 HEAD 和每一个 branch 以及其他的引用,都是以文本文件的形式存储在本地仓库 .git 目录中,而 Git 在工作的时候,就是通过这些文本文件的内容来判断这些所谓的「引用」是指向谁的。
- HEAD
当前commit的引用,就是当前工作目录所对应的 commit。它是唯一的
- Branch
也是一种引用,HEAD可以指向commit,也可以指向Branch
研发部 > VCS之Git > 15fd779f5d3e6b63.jpeg
如果在master创建一个commit,HEAD会带着master一起移动到最新的commit
研发部 > VCS之Git > 15fd779f983c81e7.gif
- Master
1.默认Branch。新创建的 repository(仓库)是没有任何 commit 的。但在它创建第一个 commi时,会把 master 指向它,并把HEAD 指向 maste
研发部 > VCS之Git > 15fd779f5c66ac9e.gif
2.当出现clone的时候,git会把HEAD移动到master
研发部 > VCS之Git > 15fd779f5c191a3f.gif
- Branch的理解
branch指向的是一个commit,是一个commit的引用。但是也可以理解为branch所指向的是一个连续的commit串。本质上master指向的是3这个commit的引用,可以理解为它的七点是1,终点是3
研发部 > VCS之Git > 15fd779fa5e6970d.jpeg
这么理解需要注意的是
1.所有的branch都是平等的
研发部 > VCS之Git > 15fd779fa58eff02.jpeg
branch1 是 1 2 5 6 的串,而不要理解为 2 5 6 或者 5 6 。所有 branch 之间是平等的,master 除了上两点之外,并不比其他 branch 高级。路径图怎么画,表达的意思一样
研发部 > VCS之Git > 15fd779ff346fbd7.gif
2.branch包含的是从初始commit到它的所有路径
研发部 > VCS之Git > 15fe3354a1d3cd26.gif
master 在合并了 branch1 之后,从初始 commit 到 master 有了两条路径。这时,master 的串就包含了 1 2 3 4 7 和 1 2 5 6 7 这两条路径。而且,这两条路径是平等的,1 2 3 4 7 这条路径并不会因为它是「原生路径」而拥有任何的特别之处
- Branch的创建、切换、删除
创建
git branch feature1
研发部 > VCS之Git > 15fe3354a1b892f7.jpeg
切换
git checkout feature1
研发部 > VCS之Git > 15fe3354a130b3cd.jpeg
分叉
git commit
研发部 > VCS之Git > 15fe3354a2a32692.gif
git checkout master
…
git commit
研发部 > VCS之Git > 15fe3354ab0861a7.gif
这个时候才出现真整的分叉
删除
git branch -d feature1
研发部 > VCS之Git > 16006b7e3d35fe54.gif
删除的只是branch这个引用
HEAD所在branch不能删除
未合并master的branch -d删除会失败,可使用-D完全删除
四、Git的常见命令
- 基础操作
git init
创建仓库,生成.git/ 版本库
git checkout
从暂存区检出
git checkout –
git status
检查工作区
git status
#简版
git status -s
git add
追踪文件到暂存区
git add
git commit
提交文件到版本库
git commit
git commit -m “commit message”
流程图
研发部 > VCS之Git > 70.png
- 远程操作
git clone
克隆仓库
git clone
git remote
远程
#列出远程主机
git remote
#列出远程主机,带网址
git remote -v
#查看主机详细信息
git remote show origin
#在本地删除已经在远程删除的分支
git remote prune
#克隆版本库的时候,所使用的远程主机自动被Git命名为origin。-o 指定主机名
git clone -o jQuery https://github.com/jquery/jquery.git
git fetch
拉取
#查看本地所有分支情况
git branch -vv
#从远程取回所有更新到本地
git fetch
#取回origin主机的master分支
git fetch
#再检出到新分支origin/master
git checkout -b <origin/branch>
git pull
拉取并合并
git pull
#等同于
git fetch && git merge
#自动stash和stash pop
git pull --autostash
#以rebase方式合并
git pull --rebase
git push
推送
#指定本地分支推送到远程上的分支,如果不存在将新建
git push :
#强制推
git push -f
#推一个空的分支到远程分支,相当于删除
git push :
#相当于
git push --delete
#推送一个未追踪远程的分支
git push --set-upstream
#默认推本地分支到追踪的远程分支上
git push
研发部 > VCS之Git > bg2014061202.jpg
- 分支操作
git branch
分支
#查看远程
git branch -r
#查看本地
git branch -a
#基于当前分支创建new branch
git branch
#查看分支情况
git branch -vv
#删除分支
git branch -D
git checkout
检出
#切换分支
git checkout
#基于branch创建new branch并检出到new branch
git checkout -b
git merge
合并
#以squash操作合并
git merge --squash
#禁止使用fast-forward快进方式合并
git merge --no-ff
git cherry-pick
#单独合并一个commit
git cherry-pick
#合并连续commit,不包括start
git cherry-pick …
#合并连续commit,包括start
git cherry-pick ^…
git rebase
变基,多人开发分支不建议使用,会改变历史
#TODO
#指定分支变基合并
git rebase
4. 回滚操作
git checkout
#从暂存区检出文件
git chekcout –
git reset
reset之后的commit会被抛弃
#回滚最近一次commit
git reset HEAD^
#回滚指定commit
git reset [commit id]
#不删除commit内容,撤销commit,并且撤销git add . 操作
git reset [commit id] --mixed
#不删除commit内容,撤销commit,不撤销git add .
git reset [commit id] --soft
#删除commit内容,撤销commit,撤销git add .
git reset [commit id] --hard
git revert
提交一个相反的commit
git revert
5. 其它
git diff
对比
#比较暂存区和工作区
git diff
#比较指定commit和工作区
git diff
#比较指定commit
git diff
#比较工作区指定部分与指定commit-id
git diff
git log
提交记录
#查看最近n次提交
git log -n
#以补丁形式查看
git log -p
git show
查看commit
git show <commit -d>
git stash
暂存
#暂存当前工作区变更
git stash
#查看暂存列表
git stash list
#弹出第n个暂存
git stash pop
#删除第n个暂存
git stash drop
#清空列表
git stash clear
git reflog
查看所有操作记录,包括删除,类似mysql的bin log
六、Git Flow
1.主要分支
Master branches
主发布分支,整合其他分支后发布,和生产代码一致
Develop branches
开发分支,主开发分支,始于Master,优先使用rebase合并Master(小熊兼顾测试)
Feature branches
需求开发分支,个人需求开发分支,始于Develop归于Develop,不直接合并Master
Hotfix branches
热修复分支,个人生产问题紧急修复分支,始于Master归于Master和Develop
Tag
主分支发布版本,此版本无需和产品版本一致,每次Master发布都需发布Tag,清理个人的Feature和Hotfix分支
除release分支之外可以参考下图
研发部 > VCS之Git > img_468b01c81ca50586e9a673f017bbe045.png
2.命名约定
分支 格式 栗子
master master master
develop develop develop
feature feature/xx-xx feature/check-files
hotfix hotfix/xx-xx hotfix/check-files
tag v大版本.小版本.问题修复版本 v1.4.12
3. commit约定
提交内容为LF换行符
提交内容不使用Tab缩进提交,使用空格换行
提交内容禁止提交有关服务密码等敏感信息
不建议使用git add ., 建议先使用git status,再使用git add path/xx.php或git add ‘*.php’
commit message使用简洁的文字描述commit的内容,不建议填写无意义内容
原则上不追踪vendor目录和缓存,导入导出文件等相关目录,但是追踪composer.lock文件
禁止追踪.user.ini文件
例如:
git status
git add path/*.php
#hotfix
git commit -m “fix xxx功能xxx的bug”
#feature
git commit -m “add xxx功能模块”
4. gitignore常见内容
MacOS
.DS_Store
Jetbrains
.idea
VScode
.vscode
ThinkPHP6
.env
runtime/*
public/uploads/*
public/.user.ini
Composer
/vendor
七、GitLab使用
-
添加ssh key
/profile/keys -
分支权限配置
/user/project-name/-/settings/repository -> Protected Branches
/project_members
- 创建Merge Request
/user/project-name/-/merge_requests/new
八、补充资料
git-scm:https://git-scm.com/book/zh/v2