Git基础概念详解
一、引言
“ 掌握Git的基本概念是高效进行版本控制的第一步。本文将详细介绍如何创建本地和远程仓库,Git支持的不同协议(如HTTP、HTTPS、SSH),以及搭建一个Git中央服务器的步骤。通过这些基础知识,您将能够顺利开始使用Git进行代码管理,并确保您的版本控制过程更加安全和高效。接下来,让我们一步步探索Git的核心概念及其实际应用。”
二、基础概念概览
首先要理解仓库的概念。什么是仓库呢?就是可以用git
管理的一个目录,这个仓库里所有的文件的改动(增加 / 修改 / 删除)都由git
跟踪记录。也能通过git
查看所有的记录,当然也能够通过git
“还原”到某个记录点。
仓库可以把它想象成一个文件数据库,这个仓库分为两个仓库:一个是远端仓库,一个是我们的本地仓库。
如何创建一个仓库呢?
首先创建一个目录:
mkdir mysql_test
然后进入这个目录:
cd mysql_test
初始化一个空的仓库:
git init
上面三个步骤就可以创建一个空的仓库了,这个时候会在仓库目录下多了一个.git
目录,.git
目录里由很多关于git
管理的文件,这里面的东西不用我们管,没事也别去瞎折腾。
如果是创建远端仓库,在第三步初始化时一般都会使用--bare
参数来初始化成一个裸仓库。例如:
git init --bare
输出:
Initialized empty Git repository in /home/fly/mathlib/
这样就初始化成一个空的裸仓库了。那什么是裸仓库?裸仓库表示目里面不会出现任何代码,只有一些版本信息、分支管理信息、配置相关等内容。这些东西一般不需要特别的关注,我们后面提交代码时这个目录的内容也不会产生过多的变化(即不会产生具体的代码)。
$ ll total 32K drwxrwxr-x 2 fly fly 4.0K Jul 26 20: 10 branches -rw-rw-r-- 1 fly fly 66 Jul 26 20: 10 config -rw-rw-r-- 1 fly fly 73 Jul 26 20: 10 description -rw-rw-r-- 1 fly fly 23 Jul 26 20: 10 HEAD drwxrwxr-x 2 fly fly 4.0K Jul 26 20: 10 hooks drwxrwxr-x 2 fly fly 4.0K Jul 26 20: 10 info drwxrwxr-x 4 fly fly 4.0K Jul 26 20: 10 objects drwxrwxr-x 4 fly fly 4.0K Jul 26 20: 10 refs
如果服务器不小心泄露了,让别人拿到这个裸仓库内容,他也做不了什么,因为完全看不到我们的源代码,这样我们的代码是安全的。所以,裸仓库算是为了代码安全设计的。这就是为什么远端服务器使用的是裸仓库的重要原因。
注意,一旦创建了远端仓库之后,一般是本地仓库去与远端仓库进行交互。交互过程中Git会为远端仓库创建一个别名:origin
。这个别名其实是远端仓库的一些地址,我们只需要记住这个别名即可。
接下来演示如何创建一些本地仓库。
创建一个目录:
mkdir gitsrc
获取远端地址。
拉取远端代码。
git clone ....
有了仓库之后,就可以使用git add
和git commit
向仓库添加要跟踪的文件,和提交修改的内容了。
三、安全通信与协议
本地与远端交互的时候,需要遵循相同的协议。有四个协议可以用于交互:
HTTP:使用HTTP协议进行Git操作时,由于其开放性与广泛支持,使得Git可以直接通过网页浏览器或简单的HTTP客户端进行访问。HTTP的广泛可用性意味着可以使用各种在线工具或服务器来进行Git操作,但同时也意味着可能需要额外的服务器配置来处理身份验证、SSL安全以及可能的防火墙限制。
HTTPS:HTTPS是HTTP的加密版本,使用SSL/TLS协议来加密数据传输,确保了数据在从本地到远程仓库或从远程仓库到本地的传输过程中不被第三方截取或篡改。HTTPS提供了更高的安全性,是如今Web服务中数据传输的首选方式。在Git中使用HTTPS时,通常需要一个公钥和私钥对,公钥用于服务器验证,私钥则用于客户端身份验证和加密数据。
SSH(Secure Shell):SSH协议主要用于在两个计算机之间提供网络安全的通信。在Git中,SSH被用来安全地进行代码的远程传输,尤其适用于需要通过SSH密钥进行身份验证的情况,这种验证方式更加安全且无需输入用户名和密码。SSH协议通过端口22进行通信,提供了在用户认证、文件传输、远程命令执行等多个方面上的安全连接。
Git:这是Git本身提供的协议,主要用于在Git仓库间进行快照和差异的存储和传输。Git协议是专为版本控制而设计的,它使用一种称为“轻量级的传输协议”(LWTP),能够有效地进行快照存储、分支和合并等功能。相比于HTTP和HTTPS,Git协议在进行版本控制时更加高效和直接,能够更好地处理分支和合并等特性,而无需通过外部协议进行数据传输。
本地仓库和远端仓库交互的时候是基于TCP进行数据交互的,那么就需要一个上层协议来完成,比较常用的是SSH协议。使用SSH协议的原因是因为通用的服务器默认都安装有SSH服务器。
接下来了解一下如何使用SSH协议来让本地仓库和远端仓库进行交互。SSH协议是一个验证授权的网络协议,使用非对称的加密方式。SSH 生成密钥的时候会产生公钥和私钥,通常需要将公钥放到远端仓库服务器,然后在每次发送数据时以私钥的方式进行验证,这样一来远端仓库和本地仓库交互就比较的安全。
那么,怎么生成 SSH 公钥和私钥呢? 可以使用如下命令生成:
ssh-keygen –t rsa
这个命令后面一路按回车就行了。
那默认的公钥和私钥在哪个位置呢?
一般是在用户 家目录(Windows是C\用户\用户名\
,Linux是\home\用户名\
)下的.ssh
目录里,有一个公钥文件id_rsa.pub
和一个私钥文件id_rsa
。通常需要将公钥文件id_rsa.pub
里的内容复制拷贝到目标服务器中;这时候需要找到目标服务器\home\用户名\.ssh
目录的authorized_keys
文件(如果没有这个文件就自己新建一个),然后把公钥的内容拷贝到里面并保存就可以了。
这样一来,本地仓库就可以通过SSH免密登录远端仓库进行交互了。之后就可以通过 SSH协议 + 远端仓库的用户名 + 远端机器的IP地址 + 具体的仓库路径 拉取代码到本地了。
要想拉取远端代码到本地,就需要使用git clone
命令,这个命令需要指定具体的协议,示例如下:
git clone ssh://fly@192.168.31.91:/home/fly/srcs
这时,会生成对应的目录,并且在该目录下会有一个.git
的文件夹,这个.git
的文件夹就是本地仓库。
拉完远端仓库到本地之后,通常需要设置用户名和邮箱,因为提交代码到远端仓库的时候,git需要在服务器记录是谁在什么时候提交的哪个版本。
设置用户名和邮箱主要使用git config
命令,这个命令有全局的设置方式(通过--global
参数)和局部的设置方式。比如,本地的设置方式:
git config user.name "LionLong" git config user.email ntf_work@163.com
这个设置 git 一般是不会去验证的。注意,如果没有--global
参数,设置的是当前目录的用户名和邮箱地址,只在当前目录有效;一般保存在.git\config
文件下。
四、Git 服务器搭建与操作
虽然说git是一个分布式的版本管理工具,不像 SVN 那样离开了中央服务器的仓库就干不了活了,但是如果有个中央服务器存在,还是方便了多人之间的协作。
那如何创建git的中央服务器呢?
创建git账号和git用户组。
$ sudo adduser git #添加git用户 $ sudo passwd git #添加git的密码 $ sudo groupadd git #添加git用户组 $ sudo usermod -G git git #添加git用户到git用户组
创建git仓库。
$ cd /srv # srv目录下存放git的仓库 $ mkdir src-docs.git # 创建src-docs.git目录 $ cd src-docs.git $ git init --bare # bare选项指示该仓库为裸仓库 $ sudo chown -R git:git /srv/src-docs.git # 修改权限为git用户
禁止git用户登录shell,这样git通过sh服务登录会被拒绝。
chsh git
克隆远程仓库。比如在我的windows电脑上打开git bash shell,输入:
git clone git@192.106.79.26:/srv/src-docs.git
即clone命令为:
git clone git@<您的 CVM IP 地址>:git仓库路径
。在这个过程中需要输入用户名和密码,可以通过rsa认证的方式省略掉密码的输入。免密输入的配置。就是通过rsa认证,生成公钥和私钥,然后把客户端的公钥告诉git服务器,具体步骤如下:
在客户端机器上,比如我在windows机器上已经配置用户名和密码,见上一章的git配置说明。
然后打开
git bash shell
,生成rsa的秘钥对,ssh-keygen –t rsa
命令后一路按回车,此时会在C:/Users/fly/.ssh/
目录下生成id_rsa.pub
和id_rsa
文件,id_rsa.pub
是公钥文件,id_rsa
是私钥文件。在git服务器上的仓库路径执行
ssh-keygen –t rsa
和touch authorized_keys
,然后把客户端的id_rsa.pub
追加到这个文件里。这样后,我们就不需要每次都输入git密码了。
看起来很复杂,其实一点也不,简单概述就是:
创建远端仓库。
指定协议,通常是SSH协议。
设置免密。
配置用户名和密码。
五、Git 工作流程与原理
下面这张图就是 Git 的整个工作流程,也是 Git 抽象出来的几个概念。
Git 的四个区域:
workspace
:本地工作区,就是你平时存放项目代码的地方。比如你拉取代码git clone ssh://fly@192.168.31.91:/home/fly/srcs
,srcs
目录就是本地工作区了。开发者就在工作区里写代码。Index / Stage
:暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息。值得一提的是,SVN 是没有暂存区概念的。暂存区允许把多次修改统一放在暂存区中,然后再由暂存区统一提交到本地仓库,确保提交记录清晰。Repository
: 本地仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD
指向最新放入仓库的版本。Remote
: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换。
Git 的 工作流程 一般是这样的:
在工作区目录中添加、修改文件;产生数据变更。
将需要进行版本管理的文件
add
到暂存区域;将暂存区域的文件
commit
到git
仓库;本地的修改
push
到远程仓库,如果失败则执行第5步;git pull
将远程仓库的修改拉取到本地,如果有冲突需要修改冲突,回到第三步。
因此,git管理的文件至少有三种状态:已修改(modified)、已暂存(staged)、已提交(committed)。
开发者在工作区修改文件,然后把工作区修改的文件 暂存 到 暂存区,再使用git commit
命令将暂存区的内容提交到本地仓库,git commit
命令一般要加-m
参数告诉 Git 当前是提交的什么内容;最后通过git push origin master
命令推送到远端仓库。
可以使用git status
查看工作区的文件状态。文件主要有四种状态:
Untracked
:未追踪的文件,此文件在文件夹中,但并没有加入到git库,不参与版本控制。即Git还没有管理的文件。要想让文件变成被 Git 管理,需要将文件添加到暂存区,即使用git add
命令将状态变为Staged
。Unmodify
:文件已经入库且未修改, 即版本库中的文件快照内容与文件夹中完全一致,这种类型的文件有两种去处,如果它被修改, 而变为Modified
,如果使用git rm
移出版本库, 则成为Untracked
文件。Modified
:文件已修改,仅仅是修改,并没有进行其他的操作,这个文件也有两个去处,通过git add
可进入暂存staged
状态,使用git checkout
则丢弃修改,返回到unmodify
状态, 这个git checkout
即从库中取出文件,覆盖当前修改。Staged
:暂存状态,执行git commit
则将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify
状态。new file
:新建的文件,并且加入了 Git 暂存区管理。
六、Git 日志与操作
可以使用git log
命令查看提交日志,例如:
$ git log commit 4b16e0b15c412e977d95a122f4b16e0b15c412e9 (HEAD -> master, origin/master) Author: fly <fly@qq.com> Date: Tue Ju1 26 20:28:18 2022 +0800 feat:add func
可以注意到,有一个40位的hash
值4b16e0b15c412e977d95a122f4b16e0b15c412e9
(hash
值是通过sha1
函数来生成的),这个值就是当次提交生成的唯一标识ID,这个唯一标识ID也称为版本号。通常可以通过这个版本号查到是哪一次提交。
除了40位的hash
值,还有一个HEAD
也是需要注意的,HEAD
是当前检出记录的符号引用,可以理解为一个指针,也可以理解为一个引用。因为是协作开发,所以通常会有一个很长的提交记录(即提交序列或列表),HEAD
就是一个指向最近一次提交的指针。上述例子中HEAD
指向master
,同时和origin/master
是在相同位置。如果我们需要获取任何一个版本的信息,就可以以HEAD
作为基本依据,往前推几个版本。
回顾工作区、暂存区和仓库的概念:
七、总结
掌握Git的基本概念与实践操作,将助你在软件开发中实现高效协作与版本管理。从仓库创建到服务器搭建,从文件状态管理到版本控制,Git提供了一套完整的解决方案,助力你的项目从无到有,从简单到复杂,不断迭代前行。