Git
版本控制系统
版本控制
- 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统
- 版本控制系统(VCS)可以将某个文件回溯到之前的任意版本,可以比较文件的变化细节
源码管理
- 开发一个应用,无论使用任意一种语言,都是在编程。所编写的程序代码称为源代码
- 当多人合作开发项目时,就需要一种方式来避免共享代码修改时的合并冲突,恢复之前的版本
- SCM(Source Code Management)工具通过在仓库中保存代码来帮助进行版本控制与多人协作
VCS的发展
-
本地版本控制系统
-
大多是采用某种简单的数据库来记录文件的历次更新差异
-
RCS
- 最流行的一种 ,工作原理是在硬盘上保存补丁集(补丁是指文件修订前后的变化),通过应用所有的补丁,可以重新计算出各个版本的文件内容
- 做补丁: diff oldfile newfile > patchfile
- 更新: patch 原文件 补丁文件
-
-
集中化的版本控制系统CVCS
Centralized Version Control Systems-
有一个集中管理的服务器,保存所有文件的修订版本,协同工作者都通过客户端连到这台服务器,取出最新的文件或者提交更新
-
优点
- 可以在一定程度上看到项目中的其他人正在做些什么
- 管理员可以轻松掌控每个开发者的权限,管理更轻松
-
缺点
- 中央服务器的单点故障,如果宕机则所有人无法提交更新,如果磁盘损坏又未做备份则所有数据丢失
-
常用
- CVS、Subversion、SVN等
-
-
分布式版本控制系统DVCS
Distributed Version Control System-
客户端把代码仓库完整地镜像下来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复
-
可以指定和若干不同的远端代码仓库进行交互。籍此就可以在同一个项目中, 分别和不同工作小组的人相互协作
-
可以根据需要设定不同的协作流程,比如层次模型式的工作流
-
常用
- Git、Mercurial、Bazaar、Darcs等
-
Git简介
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等
Git与SVN区别
-
GIT是分布式的,SVN不是
- GIT和其它非分布式的版本控制系统最核心的区别
-
GIT按元数据存储内容,SVN按文件
- 所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn .cvs等的文件夹里
-
GIT分支和SVN的分支不同
- 分支在SVN中,就只是版本库中的另外的一个目录
-
GIT没有一个全局的版本号
- 跟SVN相比GIT缺少的最大的一个特征
-
GIT的内容完整性要优于SVN
- GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏
Git的诞生
- 2005年Bitkeeper收回授权,Linux没有SCM(Software Configuration Management)可满足分布式系统的需求
- Linux之父Linus Torvalds决定开发一个新的版本控制系统。周末他消失了,新的一周,Git 问世了
Git版本库简介
-
工作区
- 一个目录中的文件以及子目录都属于工作区范畴
-
版本库(Repository)
- 工作区有一个隐藏目录.git,这个不属于工作区,这是版本库
- 可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来
- 每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史、还原
- 版本库中包含stage(暂存区,也叫index),还有分支及指向分支的指针HEAD等
-
暂存区(stage或index)
- 一般存放在.git/index中,所以我们把暂存区有时也叫作索引(index)
-
Git提交文件到版本库步骤
- git add把文件添加到暂存区
- git commit提交更改,把暂存区的所有内容提交到当前分支上
安装配置
安装
- yum -y install git
git config
-
配置变量,这些变量可以存储在三个不同的位置,作用范围越小优先级越高
-
/etc/gitconfig
- 使用参数–system,针对所有系统用户
-
~/.gitconfig
- 使用参数–global,针对当前系统用户
-
.git/config
- 针对指定的库,无论当前在用的库是什么
配置
- 设置用户名及邮箱。每一个Git的提交都会使用这些信息,并且它会写入到每一次提交中,不可更改
- git config --global user.name “tom”
- git config --global user.email “tom@163.com”
帮助
-
git --help
- 获取git命令信息
-
git config --help
- 获取具体命令帮助信息
简单使用
创建工作区
- mkdir /project
创建版本库
- cd /project;git init
版本提交
-
echo “git study” > README.md
- 创建文件,注意文件必须要在工作区中
-
git status
- 查看工作区状态
-
git add ./
- 将工作区文件添加到暂存区
-
git commit -m “first file”
- 将文件提交到版本库,-m接描述信息(必选,不接系统会进入交互式vi强制填写)
查看版本
-
git log
- 查看版本详细信息,最近的版本在最上方
-
git log --oneline
- 一个版本占一行显示,简略信息
-
git log --pretty=oneline
- 完整版本号
-
git log --graph --pretty=oneline
- 左边绘制分支图形
-
git reflog
- 查看版本库操作记录,包含所有版本记录
版本比较
-
未添加到暂存区
-
git diff README.md
- 将工作区和最近一次版本进行比较
-
-
已添加到暂存区
-
git diff --cached README.md
- 将暂存区和最近一次版本进行比较
-
撤销修改
-
git checkout – filename
- 在工作区进行了修改,但未添加到暂存区,撤销后将回到修改前的状态
- 进行修改后已添加到暂存区又进行了修改,撤销后将回到暂存区的状态
-
git reset HEAD README.md
- 将已添加到暂存区的文件从暂存区撤除
版本回退
-
git reset --hard HEAD^
- 回退到上一个版本 ,上两个版本^^, …
-
git reset --hard HEAD~2
- HEAD~2 <=> HEAD^^
-
git reset --hard c30efe0
- 接版本号回退到指定版本
删除文件
- rm -rf README.md
git rm README.md
git commit -m “delete README”
标签管理
-
git tag
- 查看所有的标签
-
git tag v1.0
- 给最近的版本打标
-
git tag -a v0.9 -m “merged bug fix” 5076eb
- 给之前的某个版本打标
-
git checkout v0.9
- 回退到打标的某个版本
-
git show v0.9
- 查看标签信息
-
git tag -d v1.0
- 删除标签
分支管理
应用场景
- 为自己创建私人分支,避免和其他人产生干扰
- 做一个具有风险性的试验性更新
- 整合与其他人的工作,创建一个临时分支
- 将一部分代码分离出来,使其独立工作
创建分支
-
git branch test
- test为分支的名字,自定义
切换分支
-
git checkout test
- 切换到test分支
-
git checkout -b dev
- 创建并切换到dev分支
查看分支
-
git branch
- 带*的表示当前操作分支
删除分支
-
git branch -d test
- 不能直接删除当前所在分支,先切换出去
比较分支
- git diff master ^test
合并分支
-
git merge test
- 将test分支合并到当前分支(一般合并到master)
解决冲突
- 若两个分支对相同文件的相同内容做了不同修改,在合并时会出现冲突,需要手工解决冲突再提交
合并管理
- 通常合并分支Git会用Fast forward模式,这种模式下,删除分支后会丢掉分支信息
- 分支合并时可加上–no-ff选项强制禁用Fast forward模式
多分支实例
某公司版本管理实例
master
- 主分支,不做具体的软件的修订的更新,而是将其他分支测试完成的软件记录为一个主分支上的软件版本
- 类似于一个产品发布平台,当其他测试分支的软件稳定后即发布到master分支上
- 该分支由管理员负责维护,其它人只有拉取权限。来自于release分支的合并,供发版使用
- 生命周期:伴随着整个项目的生命周期,项目结束时结束
develop
- 开发的主要分支,无论是要做新feature(新特性开发)还是做bug fix(bug修订),都是从这个分支分出来做的
- 主要负责记录开发状态下相对稳定的版本,即完成某个feature或者修复了某个bug后的开发稳定版本
- 由开发人员在各自的feature分支开发完成后,合并至该分支
- 分支命名:dev-版本号
- 生命周期:一个阶段功能开发开始到本阶段结束
feature branches
- 由多个分别负责不同feature开发的分支组成的一个分支系列,新特性开发主要就在这个分支系列下进行开发
- 把项目分成很多个功能点,将各个功能点分派给不同的人员,每个人开发的功能点就会形成一个feature分支
- 当功能点开发测试完成后,就合并到develop分支中去
release branches
- 这也是有多个分支组成的一个分支系列,这个分支系统从develop分支分出来的,也就是预发布分支
- 在此分支下通常进行环境测试,如果在测试过程中出现缺陷,那么就在release分支下进行修复
- 修复完成测试通过后就分别合并到master分支和develop分支,随后master分支做正常发布
hotfix branches
- 紧急线上修复,当线上产品出现bug并且特别紧急的时候,就可以从master拉出分支到这里进行修复,修复完成后分别并入到master和develop分支
远程仓库
搭建本地git服务器
1.1.1.11
-
安装git
- yum -y install git
-
创建git用户
-
useradd -s /usr/bin/git-shell git
- 指定shell为git-shell,git用户可以正常通过ssh使用git,但无法登录shell
-
-
创建仓库
-
mkdir -p /git/pub.git
- 服务器上的Git仓库通常都以.git结尾
-
git init --bare /git/pub.git/
- 创建裸库(没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区)
-
chown -R git:git /git/
-
-
收集使用者公钥
- 考虑到安全问题,同时为了方便使用,在使用git远程仓库时一般使用密钥连接
- cd /home/git/
- mkdir .ssh;chown -R git.git .ssh/;chmod 700 .ssh/
- touch .ssh/authorized_keys;chmod 600 .ssh/authorized_keys
- 将使用者公钥内容手动拷贝到.ssh/authorized_keys
客户端使用远程仓库
1.1.1.12
-
创建密钥对
- ssh-keygen
-
将公钥拷贝到服务器
- cat ~/.ssh/id_rsa.pub
-
安装git并设置
- yum -y install git
- git config --global user.name “jim”
- git config --global user.email “jim@163.com”
-
克隆远程仓库
-
mkdir /git
-
git clone git@192.168.10.12:/git/pub.git /git
- 将服务器上的仓库克隆到本地的/git目录
-
-
查看关联的远程库
-
克隆成功后会自动将本地和远程仓库关联起来,远程仓库默认名称为origin
-
git remote -v
-
需要进入到工作区查看
-
origin git@1.1.1.11:/git/pub.git (fetch)
- 可拉取的仓库,仓库名origin
-
origin git@1.1.1.11:/git/pub.git (push)
- 可推送的仓库
-
-
如果想使用本地已有的git仓库,则先要将本地仓库和远程仓库关联起来
git remote add origin git@1.1.1.11:/git/pub.git
-
-
向远程仓库推送
-
在本地修改完成后先本地提交,然后推送到远程仓库
-
git push origin master
- 将master分支推送到origin,master -> master
-
推送后,在服务器中看不到数据,其他人新克隆的仓库则包含推送的数据
-
GitHub/Gitee
介绍
-
Gitee和GitHub都是在线的基于Git的代码托管服务,操作上基本都类似
-
GitHub是2008年由Ruby on Rails编写而成,访问可能网络受限。Gitee为国内开发
-
网址
-
Gitee
- https://gitee.com
-
GitHub
- https://github.com/
-
添加公钥
-
本机创建SSH-KEY
-
ssh-keygen
-
cat ~/.ssh/id_rsa.pub
- 复制密钥
-
-
登陆GitHub
- 个人中心(右上)->Settings->SSH and GPG keys->New SSH key->填写标题和公钥->Add SSH key
创建仓库(repositories)
- +(右上)->New repository->填写仓库名称->选择仓库类型->Create repository
关联远程仓库
-
本地已有git仓库
- git remote add origin git@github.com:hbgld/qfedu.git
- 关联后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的
- git remote -v #查看远程库
-
本地没有git仓库
- 直接将远程仓库克隆
- mkdir /git
- git clone git@github.com:hbgld/qfedu.git /git
修改后的版本先在本地提交
- git add .;git commit -m “xxx”
将本地库的版本推送到远程库
- git push origin master
远程查看
GitLab
简介
- GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目安装
- 它拥有与GitHub类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库
服务管理命令
-
gitlab-ctl start
- 启动所有 gitlab 组件
-
gitlab-ctl stop
- 停止所有 gitlab 组件
-
gitlab-ctl restart
- 重启所有 gitlab 组件
-
gitlab-ctl status
- 查看服务状态
-
gitlab-ctl tail
- 查看日志
-
gitlab-ctl reconfigure
- 初始化服务
安装配置
1.1.1.21
-
介绍
-
gitlab软件
- gitlab-ce 社区版
- gitlab-ee 企业版
-
获取
-
官网
- https://gitlab.cn/install/#
-
国内镜像源
- https://mirrors.tuna.tsinghua.edu.cn
-
-
-
服务器内存
- 4G+
-
软件安装
- wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-13.9.3-ce.0.el7.x86_64.rpm
- yum install -y gitlab-ce-13.9.3-ce.0.el7.x86_64.rpm
-
修改配置文件
external_url ‘http://1.1.1.21’ # 服务器的IP或域名
gitlab_rails[‘gitlab_email_from’] = ‘17733179623@163.com’ # 邮箱
gitlab_rails[‘smtp_enable’] = true
gitlab_rails[‘smtp_address’] = “smtp.163.com” # SMTP服务器
gitlab_rails[‘smtp_port’] = 25 # SMTP服务器的端口
gitlab_rails[‘smtp_user_name’] = “17733179623@163.com” # 邮箱
gitlab_rails[‘smtp_password’] = “邮箱授权码” # 邮箱授权码
gitlab_rails[‘smtp_domain’] = “163.com” # SMTP服务器的域
gitlab_rails[‘smtp_authentication’] = “login”
gitlab_rails[‘smtp_enable_starttls_auto’] = true
- 配置邮箱注意事项
- sina、163邮箱smtp端口为25, 其他邮箱的端口需要查询
- 需要在邮箱设置中开启smtp服务
- 若不配置邮箱则无法发送邮件至用户
-
初始化并启动服务
-
gitlab-ctl reconfigure
-
注
- 第一次初始化后会产生当前gitlab的配置文件 /var/opt/gitlab/gitlab-rails/etc/gitlab.yml
- 在后期维护的过程中尽量配置该文件,gitlab-ctl restart即可生效新的配置
- 如果没有必要不建议做第二次初始化
-
邮件测试
- gitlab-rails console
- irb(main):001:0> Notify.test_email(‘17733179623@163.com’, ‘Message Subject’, ‘Message Body’).deliver_now
-
-
登录
-
浏览器访问1.1.1.21,先设置root密码,再用root帐户登录
-
注
- gitlab-14以后会生成初始密码保存在/etc/gitlab/initial_root_password,将在首次初始化后24h自动删除
-
-
设置
-
关闭用户注册功能
- Admin Area(左上扳手图标)->Settings(左下)->Sign-up restrictions:Expabd->Sign-up enabled取消勾选->Save changes(下拉)
-
创建用户
- Admin Area->New user(中上)->填写名字邮箱->Access level选择身份->Create user->Edit->设置初始密码->Save changes
-
设置语言
- 个人(右上)->Preferences->Language(下拉)->选择语言->Save changes(重新登录生效)
-
使用
-
大部分公司的处理流程
- PM在gitlab创建任务,分配给开发人员
- 开发人员领取任务后,在本地使用git clone拉取代码库
- 开发人员创建开发分支(git checkout -b dev),并进行开发
- 开发人员完成之后,提交到本地仓库(git commit)
- 开发人员在gitlab界面上申请分支合并请求(Merge request)
- PM在gitlab上查看代码修改情况,确认无误后,将开发人员的分支合并到主分支(master)
- 开发人员在gitlab上Mark done确认开发完成,并关闭issue。这一步在提交合并请求时可以通过描述中填写"close #1"等字样,可以直接关闭issue
-
组和项目
- Gitlab上有 项目(project) 跟 组(group) 的概念
- 一个组里有一到多个成员(用户), 他们可能是各种不同的角色, 各角色权限不同
- 一个组里可以有多个项目(代码库)。先创建组,再在组中创建项目
-
PM操作
-
创建群组
-
群组->您的群组->新建群组->群组名称->可见级别->创建群组
-
可见级别
-
Private
- 私有,只有所有者、组内成员或已分配的用户有查看权限(同GitHub收费版的私有仓库)
-
Internal
- 内部,拥有GitLab账号的成员可以查看,无账号用户无法访问(适合于服务器放在公网但不想公开代码的情景,GitHub没有这个功能)
-
Public
- 公共,任何人都可以访问(同GitHub免费版的公共仓库)
-
-
-
添加组成员
-
进入组->成员->GitLab成员或电子邮件地址->选择角色权限->访问过期时间->邀请
-
角色
-
Guest
- 访客
-
Reporter
- 报告人
-
Maintainer
- 维护者
-
Developer
- 开发者(开发人员)
-
Owner
- 所有者(PM)
-
-
-
创建项目
- 进入群组->新建项目->创建空白项目->项目名称->可见级别->新建项目
- 项目->您的项目->新建项目->创建空白项目->项目名称->项目URL选择群组->可见级别->新建项目
-
创建README文件
- 进入项目->添加自述文件->编辑内容->提交->编辑描述信息->提交
-
处理合并请求
-
进入项目->合并请求->进入请求单->审批(查看变更)->合并
- 开发者提交请求后处理
-
-
-
开发人员操作
-
上传公钥
-
主机
-
ssh-keygen
-
cat ~/.ssh/id_rsa.pub
- 复制密钥
-
-
登录Gitlab
- 个人->Preferences->SSH密钥->粘贴密钥->添加密钥
-
-
将项目库克隆下来并创建新的分支进行开发
- yum -y install git
- git config --global user.name “lily”
- git config --global user.email “lily@xxx.com”
- git clone Gitlab项目中复制SSH克隆链接
- 进入项目库
- git checkout -b dev
- 进行开发
-
将代码提交到本地
- git add .
- git commit -m “xxxx”
-
将开发好的代码提交到Gitlab
- git push origin dev
- 开发人员不能直接提交到master分支
-
创建合并请求
- Gitlab进入项目->合并请求->新建合并请求->选择项目和分支->Compare branches and continue->填写请求内容->Submit合并请求
-
-
删除项目
- Gitlab进入项目->设置->高级->删除项目->输入确认内容->是的,删除项目
备份恢复
gitlab_rails[‘manage_backup_path’] = true
gitlab_rails[‘backup_path’] = “/backup/gitlab”
gitlab_rails[‘backup_keep_time’] = 604800 #若计划任务备份需设置保留时间s
- gitlab-ctl restart
- 备份
- gitlab-rake gitlab:backup:create
- 可以添加到crontab中定时执行
- gitlab.rb和gitlab-secrets.json不会备份,需要自己手动备份
-
恢复
gitlab_rails[‘backup_path’] = “/backup/gitlab”
- gitlab-ctl restart
- 停止数据库服务
- gitlab-ctl stop unicorn
- gitlab-ctl stop sidekiq
- 恢复
- gitlab-rake gitlab:backup:restore BACKUP=1530773117_2019_03_05
- 包名不接后缀
- 单个文件可不接包名
- gitlab-ctl restart
-
注意
- 通过备份文件恢复gitlab必须保证两台主机的gitlab版本一致,否则会提示版本不匹配
重置root密码
- [root@git ~]# gitlab-rails console
irb(main):001:0> user = User.where(id:1).first #定位到root用户
=> #<User id:1 @root>
irb(main):002:0> user.password = 12345678 #设置新密码
=> 12345678
irb(main):003:0> user.password_confirmation = 12345678 #重复新密码
=> 12345678
irb(main):004:0> user.save #保存修改
=> true
irb(main):005:0> exit