第四阶段提升
时 间:2023年8月29日
参加人:全班人员
内 容:
Git分布式版本控制系统与github
目录
[(一) 本地版本控制](#(一) 本地版本控制)
[三、 Git简介](#三、 Git简介)
[(四) 分支结构](#(四) 分支结构)
一、案例概述
在开发一个软件项目时,本地只有几十行代码或几百行代码时还可以维护,但当代码达到一定的数量后或两三个人共同开发一个项目时,就很容易会出现代码混乱、冲突、排错难等问题。
一旦开发完工以后发现整个项目运行不了,提交的代码也无法确认到责任人,导致维护项目时需要花费数倍的时间。为解决上述问题,版本控制系统应运而生。
版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管 理,是软件配置管理的核心思想之一。
二、版本控制系统
(一) 本地版本控制
本地版本控制系统许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。
这么做唯一的 好处就是简单,但是特别容易犯错。有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件,无法识别文件中的修改。

(二)集中化的版本控制系统
如何让处于不同系统上的开发者协同工作?于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。
这类系统,诸如 CVS、Subversion(SVN) 以及Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。

(三)分布式版本控制系统
在这类系统中,像Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像(克隆)下来。
这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

三、 Git简介

(一)概述
git是一个分布式版本控制软件,最初由****林纳斯·托瓦兹(Linus Torvalds)****创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。
Git 官方中文手册 https://git-scm.com/book/zh/v2
(二)Git发展史
自2002年开始,林纳斯·托瓦兹决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护代码。因为BitKeeper为专有软件,这个决定在社区中长期遭受质疑。在Linux社区中,特别是理查德·斯托曼与自由软件基金会的成员,主张应该使用开放源代码的软件来作为Linux核心的版本控制系统。林纳斯·托瓦兹曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如CVS的架构,受到林纳斯·托瓦兹的批评。
2005年,安德鲁·垂鸠写了一个简单程序,可以连接BitKeeper的存储库,BitKeeper著作权拥有者拉里·麦沃伊认为安德鲁·垂鸠对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的授权。Linux内核开发团队与BitMover公司进行蹉商,但无法解决他们之间的歧见。林纳斯·托瓦兹决定自行开发版本控制系统替代BitKeeper,以十天的时间,编写出第一个git版本。
Git 是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。
一个原始 Git 版本仓库,可以让其他主机克隆这个原始版本仓库,从而使得一个Git 版本仓库可以同时分布到不同的主机上,并且每台主机的版本库都是一样的,并没有主次之分,极大的保证了数据的安全性,并使得用户能够自主选择 Git 服务器推送文件了,其实部署一个 Git 服务器是一件非常简单的事情。
如上所述,作为一个分布式的版本控制系统,在 Git 中并不存在主库这样的概念。每一 份复制出的库都可以独立使用,任何两个库之间的不一致之处都可以进行合并。
GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub。GitHub 可以提供给用户空间创建 Git 仓储,保存用户的一些数据文档或者代码等。
GitHub 作为开源代码库以及版本控制系统,目前拥有 140 多万开发者用户。随着越多的应用程序转移到了云上,GitHub 已经成为了管理软件开发以及发现已有代码的首选方法。
GitHub 可以托管各种 Git 库,并提供一个 Web 界面,但与其它像 SourceForge 或 Google Code 这样的服务不同,GitHub 的独特卖点在于从另外一个项目进行分支的简易性。为一个项目贡献代码非常简单:首先点击项目站点的"fork"的按钮,然后将代码检出并将修改加入到刚才分出的代码库中,最后通过内建的"pull request"机制向项目负责人申请代码合并。
Gitlab 是一个基于 Git 的项目管理软件,用于仓库管理系统的开源项目。使用 Git 作为代码管理工具,并在此基础上搭建起来 Web 服务。
Git、Gitlab、Github 都是基于 Git 的,可以说是 Git 的衍生品。
(三)Git功能特性
****克隆数据库版本:****从服务器上克隆数据库(包括代码和版本信息)到本机上;
****提交代码:****在本机上自己创建的分支上提交代码;
****合并分支:****在本机上合并分支;
****拉取合并分支:****新建一个分支,把服务器上最新版的代码 Fetch 下来,然后跟自己的主分支合并;
****代码冲突解决:****一般开发者之间解决冲突的方法,开发者之间可以使用 pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁。
四、GIT安装部署
(一)案例环境
|-----------------|-----------|--------|
| IP地址 | 主机名 | 角色 |
| 192.168.100.131 | gitserver | Git服务器 |
| 192.168.100.132 | git | Git客户端 |
(二)安装git
1、初始环境
root@gitclient \~\]# systemctl stop firewalld \[root@gitclient \~\]# iptables -F \[root@gitclient \~\]# setenforce 0
Gitserver服务端:

Git客户端:

2、yum安装Git
# centos 自带git
root@gitclient \~\]# rpm -q git  ****# 安装方法**** \[root@gitclient \~\]# yum -y install git  ****3、 编译安装**** 编译安装可以安装较新版本的git ****Git下载地址:**** [https://github.com/git/git/releases](https://github.com/git/git/releases "https://github.com/git/git/releases")  ****# 安装依赖关系**** \[root@gitclient \~\]# yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel  ****# 编译安装---服务端和客户端**** [root@gitclient ~]# wget https://github.com/git/git/archive/v2.22.0.tar.gz [root@gitclient ~]# tar xf git-2.22.0.tar.gz -C /usr/src/ [root@gitclient ~]# cd /usr/src/git-2.22.0/ [root@git git-2.22.0]# make configure [root@git git-2.22.0]# ./configure --prefix=/usr/local/git && make && make install  > \[root@git git-2.22.0\]# ln -sf /usr/local/git/bin/git /usr/bin/ > > \[root@git git-2.22.0\]# git --version  ****4、初次运行 Git 前的配置**** ****命令集**** > git config --global user.name "huyang" #配置git使用用户 > > git config --global user.email "13363571949@163.com" #配置git使用邮箱 > > git config --global color.ui true #语法高亮 > > git config --list #查看全局配置  ****配置过程**** > \[root@gitclient \~\]# git config --global user.name "crushlinux" #配置git使用用户 > > \[root@gitclient \~\]# git config --global user.email "crushlinux@163.com" #配置git使用邮箱 > > \[root@gitclient \~\]# git config --global color.ui true #语法高亮 > > \[root@gitclient \~\]# git config --list #查看全局配置 ****生成的配置文件**** \[root@gitclient \~\]# cat .gitconfig  ****获取帮助**** 使用Git时需要获取帮助,有三种方法可以找到Git命令的使用手册: 例如,要想获得配置命令的手册,执行 \[root@gitclient \~\]# git help config  \[root@gitclient \~\]# git config --help  \[root@gitclient \~\]# man git config  ****5、初始化及获取 Git 仓库**** ****Git服务器操作**** > \[root@gitserver \~\]# mkdir git_data.git > > \[root@gitserver \~\]# cd git_data.git/ > > \[root@gitserver git_data.git\]# git --bare init  ****Git客户端操作**** > \[root@gitclient \~\]# ssh-keygen > > \[root@gitclient \~\]# ssh-copy-id [root@192.168.100.131](mailto:root@192.168.200.111)  > \[root@gitclient \~\]# git clone root@192.168.100.131:/root/git_data.git > > \[root@gitclient \~\]# cd git_data/ > > \[root@git git_data\]# git status  ## ****(三)Git命令常规操作**** ****1、常用命令说明**** |----------|----------------------------| | 命令 | 命令说明 | | add | 添加文件内容至暂存区(索引) | | bisect | 通过二分查找定位引入 bug 的变更 | | branch | 列出、创建或删除分支 | | checkout | 检出一个分支或路径到工作区 | | clone | 克隆一个版本库到一个新目录 | | commit | 记录变更到版本库(本地) | | diff | 显示提交之间、提交和工作区之间等的差异 | | fetch | 从另外一个版本库下载对象和引用 | | grep | 输出和模式匹配的行 | | init | 创建一个空的 | | Git | 版本库或重新初始化一个已存在的版本库 | | log | 显示提交日志 | | merge | 合并两个或更多开发历史 | | mv | 移动或重命名一个文件、目录或符号链接 | | pull | 获取并合并另外的版本库或一个本地分支 | | push | 更新远程引用和相关的对象 | | rebase | 本地提交转移至更新后的上游分支中 | | reset | 重置当前HEAD到指定状态 | | rm | 从工作区和索引中删除文件 | | show | 显示各种类型的对象 | | status | 显示工作区状态 | | tag | 创建、列出、删除或校验一个GPG签名的 tag 对象 | ****常用操作示意图****  ****文件的状态变化周期****  ****2、创建文件**** \[root@git git_data\]# touch README \[root@git git_data\]# git status  \[root@git git_data\]# git add ./\* \[root@git git_data\]# git status  \[root@git git_data\]# tree .git/  ****由工作区提交到本地仓库**** \[root@git git_data\]# git commit -m 'first commit'  ****查看git的状态**** \[root@git git_data\]# git status  \[root@git git_data\]# git branch --unset-upstream \[root@git git_data\]# git status  \[root@git git_data\]# tree .git/  ****提交到远程仓库**** \[root@git git_data\]# git push root@192.168.100.131:/root/git_data.git  ****3、 添加新文件**** > ****git add**** ****#添加到暂存区域**** > > ****git commit**** ****#提交git仓库 -m 后面接上注释信息,内容关于本次提交的说明,方便自己或他人查看**** ****修改或删除原有文件**** ****常规方法**** > git add > > git commit ****简便方法**** > git commit -a -m "注释信息" > > -a 表示直接提交 ****4、删除git内的文件**** ****命令说明:**** > 没有添加到暂存区的数据直接rm删除即可。 > > 已经添加到暂存区数据: > > ****git rm --cached database**** > > #将文件从git暂存区域的追踪列表移除(并不会删除当前工作目录内的数据文件) > > ****git rm -f database**** > > #将文件数据从git暂存区和工作目录一起删除 ****操作命令:**** ****# 创建新文件**** \[root@git git_data\]# touch 123 \[root@git git_data\]# git status  \[root@git git_data\]# git add 123 \[root@git git_data\]# git status  ****# 删除文件**** \[root@git git_data\]# rm -f 123 \[root@git git_data\]# ls  \[root@git git_data\]# git status  \[root@git git_data\]# git reset HEAD ./\* \[root@git git_data\]# git status  \[root@git git_data\]# git rm 123 \[root@git git_data\]# git status  ****5、重命名暂存区数据**** > 没有添加到暂存区的数据直接mv/rename改名即可。 > > 已经添加到暂存区数据: 操作命令 \[root@git git_data\]# git mv README NOTICE \[root@git git_data\]# git status \[root@git git_data\]# ls  ****6、查看历史记录**** > • git log #查看提交历史记录 > > • git log -2 #查看最近几条记录 > > • git log -p -1 #-p显示每次提交的内容差异,例如仅查看最近一次差异 > > • git log --stat -2 #--stat简要显示数据增改行数,这样能够看到提交中修改过的内容,对文件添加或移动的行数,并在最后列出所有增减行的概要信息 > > • git log --pretty=oneline #--pretty根据不同的格式展示提交的历史信息 > > • git log --pretty=fuller -2 #以更详细的模式输出提交的历史记录 > > • git log --pretty=fomat:"%h %cn" #查看当前所有提交记录的简短SHA-1哈希字串与提交着的姓名。 ****使用format参数来指定具体的输出格式**** |-----|-------------------| | 格式 | 说明 | | %s | 提交说明。 | | %cd | 提交日期。 | | %an | 作者的名字。 | | %cn | 提交者的姓名。 | | %ce | 提交者的电子邮件。 | | %H | 提交对象的完整SHA-1哈希字串。 | | %h | 提交对象的简短SHA-1哈希字串。 | | %T | 树对象的完整SHA-1哈希字串。 | | %t | 树对象的简短SHA-1哈希字串。 | | %P | 父对象的完整SHA-1哈希字串。 | | %p | 父对象的简短SHA-1哈希字串。 | | %ad | 作者的修订时间。 | ****操作命令**** \[root@git git_data\]# git log  ****7、还原历史数据**** Git服务程序中有一个叫做HEAD的版本指针,当用户申请还原数据时,其实就是将HEAD指针指向到某个特定的提交版本,但是因为Git是分布式版本控制系统,为了避免历史记录冲突,故使用了SHA-1计算出十六进制的哈希字串来区分每个提交版本,另外默认的HEAD版本指针会指向到最近的一次提交版本记录,而上一个提交版本会叫HEAD\^,上上一个版本则会叫做HEAD\^\^,当然一般会用HEAD\~5来表示往上数第五个提交版本。 > ****git reset --hard hash**** > > ****git reset --hard HEAD\^ #还原历史提交版本上一次**** > > ****git reset --hard 3de15d4 #找到历史还原点的SHA-1值后,就可以还原(值不写全,系统会自动匹配)**** ****操作命令**** \[root@git git_data\]# vim NOTICE \[root@git git_data\]# cat NOTICE \[root@git git_data\]# git commit -a -m 'test'  \[root@git git_data\]# git log  \[root@git git_data\]# git reset --hard 6a71d \[root@git git_data\]# ls \[root@git git_data\]# cat README  ****8、还原未来数据**** > 什么是未来数据?就是你还原到历史数据了,但是你后悔了,想撤销更改,但是git log已经找不到这个版本了。 > > git reflog #查看未来历史更新点 ****操作命令**** \[root@git git_data\]# git reflog  \[root@git git_data\]# git reset --hard 94d46 \[root@git git_data\]# cat NOTICE  ****9、标签使用**** 前面回滚使用的是一串字符串,又长又难记。 > ****git tag v1.0****#当前提交内容打一个标签(方便快速回滚),每次提交都可以打个tag。 > > ****git tag****#查看当前所有的标签 > > ****git show v1.0****#查看当前1.0版本的详细信息 > > ****git tag v1.2 -m "version 1.2 release is test"****#创建带有说明的标签,-a指定标签名字,-m指定说明文字 > > ****git tag -d v1.0****#我们为同一个提交版本设置了两次标签,删除之前的v1.0 ****操作命令**** \[root@git git_data\]# git reset --hard 6a71d \[root@git git_data\]# git tag \[root@git git_data\]# git tag v20230829 \[root@git git_data\]# git tag \[root@git git_data\]# git reset --hard v20230829  ****10、对比数据**** > ****git diff****可以对比当前文件与仓库已保存文件的区别,知道了对NOTICE作了什么修改 > > 后,再把它提交到仓库就放⼼多了。 \[root@git git_data\]# echo "hello,gitserver" \>\> README \[root@git git_data\]# git diff README  ## ****(四) 分支结构**** 在实际的项目开发中,尽量保证master分支稳定,仅用于发布新版本,平时不要随便直接修改master分支里面的数据文件。 那在哪干活呢?干活都在dev分支上。每个人从dev分支创建自己个人分支,开发完合并到dev分支,最后dev分支合并到master分支。所以团队的合作分支看起来会像下图那样。  > \[root@git git_data\]# git branch linux > > \[root@git git_data\]# git branch > > \[root@git git_data\]# git checkout linux > > \[root@git git_data\]# git branch  ****在linux分支进行修改**** > \[root@git git_data\]# cat README > > \[root@git git_data\]# echo "hello,github" \>\> README > > \[root@git git_data\]# git add . > > \[root@git git_data\]# git commit -m "github" > > \[root@git git_data\]# git status  ****回到master分支**** > \[root@git git_data\]# git checkout master > > \[root@git git_data\]# cat README > > \[root@git git_data\]# git log -1  ****合并代码**** > \[root@git git_data\]# git merge linux > > \[root@git git_data\]# git status > > \[root@git git_data\]# cat README  ****2、合并失败解决**** ****模拟冲突,在文件的同一行做不同修改**** ****在master 分支进行修改**** > \[root@git git_data\]# cat README > > \[root@git git_data\]# echo "hello.error" \>\> README > > \[root@git git_data\]# git commit -a -m "master error"  ****切换到linux分支**** \[root@git git_data\]# git checkout linux \[root@git git_data\]# cat README  \[root@git git_data\]# echo "hello,linux" \>\> README \[root@git git_data\]# git commit -a -m "linux"  ****回到master分区,进行合并,出现冲突**** \[root@git git_data\]# git checkout master \[root@git git_data\]# git merge linux  ****解决冲突**** \[root@git git_data\]# vim README  ****# 手工解决冲突**** \[root@git git_data\]# git commit -a -m "master merge"  ****3、删除分支**** 因为之前已经合并了linux分支,所以现在看到它在列表中。 在这个列表中分支名字前没有 \* 号的分支通常可以使用 git branch -d 删除掉;你已经将它们的工作整合到了另一个分支,所以并不会失去任何东西。 > ****查看所有包含未合并工作的分支,可以运行 git branch --no-merged:**** \[root@git git_data\]# git branch --no-merged \[root@git git_data\]# git branch -d linux \[root@git git_data\]# git branch  如果真的想要删除分支并丢掉那些工作,如同帮助信息里所指出的,可以使用 -D 选项强制删除它。 ## ****(五)windwos上Git的使用**** windows 上git软件网站 https://git-for-windows.github.io ****软件下载地址:**** [https://github.com/git-for-windows/git/releases/download/v2.22.0.windows.1/Git-2.22.0-64-bit.exe](https://github.com/git-for-windows/git/releases/download/v2.22.0.windows.1/Git-2.22.0-64-bit.exe "https://github.com/git-for-windows/git/releases/download/v2.22.0.windows.1/Git-2.22.0-64-bit.exe") ****创建新的仓库****  ****定义仓库的路径****  ****添加用户信息(在 git bash中)**** > Crushlinux@DESKTOP-5JDO87L MINGW64 \~ > > $ git config --global user.email "crushlinux@163.com" > > Crushlinux@DESKTOP-5JDO87L MINGW64 \~ > > $ git config --global user.name "crushlinux" ****在git Gui 中添加用户信息,添加一次就可****   ****在页面中将数据配置好即可使用****  # ****五、GitHub托管服务**** Github顾名思义是一个Git版本库的托管服务,是目前全球最大的软件仓库,拥有上百万的开发者用户,也是软件开发和寻找资源的最佳途径,Github不仅可以托管各种Git版本仓库,还拥有了更美观的Web界面,您的代码文件可以被任何人克隆,使得开发者为开源项贡献代码变得更加容易,当然也可以付费购买私有库,这样高性价比的私有库真的是帮助到了很多团队和企业。 ## ****(一)注册GitHub**** 浏览器访问github官网 : [https://github.com/](https://github.com/ "https://github.com/") ,点击Sign up 进行注册  ****填写个人信息,进行注册****  ****输入验证码****  ****输入信息****  ****选择如下:****  ****选择仓库类型,默认免费,点击底下Continue注册****  ****用户创建完成,可以创建新的项目****  ****添加密钥**** 在github上添加一个新的ssh密钥   ## ****(二)获取Linux主机上的密钥**** \[root@gitserver \~\]# ssh-keygen \[root@gitserver \~\]# cat .ssh/id_rsa.pub  ## ****(三)获得Windows主机密钥的方法**** > Crushlinux@DESKTOP-5JDO87L MINGW64 \~ > > ****$ ssh-keygen.exe**** > > Generating public/private rsa key pair. > > Enter file in which to save the key (/c/Users/Crushlinux/.ssh/id_rsa): > > Created directory '/c/Users/Crushlinux/.ssh'. > > Enter passphrase (empty for no passphrase): > > Enter same passphrase again: > > Your identification has been saved in /c/Users/Crushlinux/.ssh/id_rsa. > > Your public key has been saved in /c/Users/Crushlinux/.ssh/id_rsa.pub. > > The key fingerprint is: > > SHA256:IHhPxTKtHlNZx0kqvob90V5tN8IM0VQT4hZ7yWBkznc Crushlinux@DESKTOP-5JDO87L > > The key's randomart image is: > > +---\[RSA 3072\]----+ > > \| o.o.o+X.+.\| > > \| . o.= o@ \* o\| > > \| . o o=. .. B =E\| > > \| . ++o . o o .\| > > \| ..oS . \| > > \| .o . .+ . \| > > \| . + . .+..+\| > > \| . . o ...o\| > > \| . . \| > > +----\[SHA256\]-----+ > Crushlinux@DESKTOP-5JDO87L MINGW64 \~ > > ****$ cat .ssh/id_rsa.pub**** > > ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHSP3L5h8irgkZe3snixWIDa4Q7JBQk0PzAoBQZPB1kgHuK5iZ4hY/mEqr/vegbWHdI0G5tYHRNi1PTnFrDSnjaIaFAoiuZt36aOUPmHpgmMHEV6hE3jeuoanK2LrIepVNvscwu15O8t2/dKc0An+x83miS5PRAojXj3BSQ1EsJ+LWmnl3W/UM6waVujmB7TihLYzPt8x2Mgi8jqvA6pgLwK/wdK+3pldSbTM3D3j8XLt2AXAPnkPa9C7HeUv7Tm905lbalRWmuhC/K2jc+WBXjbwc4xgjlLYtP5JjhGoecZ72CKCVVp1DN7Yz9Nb98rEzEsqTsvfvjVCrssmYDxSP2NRDWB8mkZw5XrKgnFRLuvpql2MPDAthWNYlZXH0RJ9yVHiqAN3E5PRuJhtFbSLJYRMNMmjkmptVwbjUYvpm3W9ZbAeP6z1ueJ9RGc1dwtBnYNN/PZlD/lqvJll+5t2c+V8xkStEEobQFg7aQSc+BU9ZAsdCL79veOHUtfiDh+k= Crushlinux@DESKTOP-5JDO87L **密钥创建完成后进行添加**  **密钥添加成功**  ## ****(四)创建仓库**** ****准备工作已经完毕,右上角点击创建一个新的仓库****  ****创建仓库,输入个人信息****   ## ****(五)在个人主机上进行推送测试**** \[root@gitserver \~\]# git config --global user.email "crushlinux13363571949root@gitserver \~\]# git config --global user.name "huyang" \[root@gitserver \~\]# git config --list  > \[root@gitserver \~\]# mkdir hy > > \[root@gitserver \~\]# cd hy > > \[root@gitserver hy\]# echo "# test" \>\> README.md > > \[root@gitserver hy\]# git init > > \[root@gitserver hy\]# git add README.md > > \[root@gitserver hy\]# git commit -m "first  \[root@gitserver hy\]# git remote add origin git@github.com:huyang-Ada/test1.git \[root@gitserver hy\]# git push -u origin master  ****Web访问测试:****  ## ****(六)创建新文件,进行拉取测试****  ****编辑内容:****  ****点击确定****  ****创建好后点击下面的commit即可****  ****github添加成功,进行拉取测试**** ## ****(七)拉取文件测试**** ****查看目录内容**** \[root@gitserver hy\]# pwd \[root@gitserver crushlinux\]# ls  ****进行拉取**** \[root@gitserver hy\]# git pull \[root@gitserver hy\]# ls \[root@gitserver hy\]# cat abc.test 