type
status
date
slug
summary
category
tags
password
Created time
Sep 1, 2024 03:24 PM
Last edited time
Sep 3, 2024 02:20 PM
UUID
icon
🗒️发表的笔记
URL CK
ErrorCheck
ErrorCheck
Description
这里记录我打通各种刚开始入门使用git的各种应用的笔记和概念理解,以帮助我以后更好的使用git进行其他方式的应用,提高效率避免踩同样的坑,Git的使用对于概念和过程原理的理解非常重要,这也将巩固我对它的使用基础。
Git的复杂性让很多人望而却步
首先不得不承认git是一项伟大的发明,但是由于其丰富的各种代码管理功能,各种通信方式的适配性,以及其衍生的各种远程代码管理平台和插件工具,使其想要达到应用的地步入门门槛还是比较高,git的一些入门基础和简介剖析可以阅读我的文章Git深层剖析和git文章分类总览页面。
初始化仓库时之仓库种类理解的重要性
- 裸仓库:没有工作区(即没有实际文件和文件夹),只包含 Git 用来存储所有版本控制数据的
.git
目录。裸仓库适用于远程服务器共享和协作,作为团队合作的中央代码存储库,其他开发者可以将其作为远程仓库来推送和拉取代码。
- 标准(非裸)仓库:包含
.git
目录以及实际的工作目录。开发人员通常在本地使用标准仓库。
远程服务器端大部分都使用裸仓库的原因
- 协作:裸仓库适合用作中央存储库,允许多个开发者推送和拉取代码,而不需要担心工作目录冲突。
- 简洁:由于没有工作目录,只保存版本历史和提交对象,因此适合用于版本控制服务器。
- 一致性:裸仓库的格式和标准仓库一致,但不会有实际的代码文件,适合在服务器上管理代码。
push到的远程仓库的是不一定必须为裸仓库
推送到的远程仓库不一定必须是裸仓库,但在实际应用中,裸仓库是远程仓库的最佳实践和推荐设置。下面是一些关于裸仓库和非裸仓库的使用情况的详细信息,以及为什么裸仓库更适合作为远程仓库的原因。
1. 裸仓库(Bare Repository)
定义:裸仓库是没有工作目录的 Git 仓库。在一个以
.git
结尾的目录中,如果没有子目录 .git
,这实际上是一个裸仓库。裸仓库的结构和传统的非裸仓库(带有工作目录的仓库)是不同的,这也是为什么在裸仓库的根目录中不会看到一个单独的 .git
文件夹的原因。它只包含 .git
目录的内容,所有的 Git 对象(如提交、树、分支等)直接保存在裸仓库的根目录下。裸仓库的特点:
- 没有工作目录:裸仓库中只有
.git
目录中的内容,它包含了所有的版本历史、对象、引用等,但没有检出的文件。这意味着裸仓库没有一个可以直接看到或编辑文件的工作目录。
- 专用于共享和协作:裸仓库通常用作远程仓库(如 GitHub、GitLab 上的仓库),用来存放版本控制信息,开发者从远程裸仓库克隆下来后,会在自己的本地环境中有一个包含工作目录的普通仓库。
- 不能直接修改:不能在裸仓库中直接修改文件,因为它没有工作目录,不能直接用来编辑文件。需要把裸仓库克隆到本地(创建一个非裸仓库)才能查看和编辑项目文件。
典型用法:
- 远程共享:裸仓库通常用于远程服务器上,以便多个开发者可以推送和拉取更改。这是 Git 仓库托管服务(如 GitHub、GitLab、Bitbucket)使用的标准方式。
- 避免冲突:由于裸仓库没有工作目录,它不会有未提交的本地更改,从而避免了合并冲突和一致性问题。
- 集中管理:裸仓库常被用作集中的存储和管理代码的地方,开发者可以将本地更改推送到裸仓库中,其他人可以从中拉取最新的代码。
例子:创建裸仓库的命令如下:
裸仓库的目录结构
- 直接是 Git 目录:裸仓库本身就是
.git
目录的内容,而不是一个包含.git
子目录的普通仓库。通常情况下,一个裸仓库的目录名以.git
结尾,比如myrepo.git
。所有 Git 的元数据文件直接放在这个根目录下,而不是像在普通的工作目录仓库中那样放在.git
子目录中。
- 内容文件:在裸仓库中,会看到的典型文件和目录包括:
HEAD
:指向当前活动的分支。refs/
:包含分支和标签的引用。objects/
:包含所有的 Git 对象(如提交、树、blob 等)。config
:仓库配置文件。hooks/
:钩子脚本。info/
:一些额外的信息,如排除文件。
如何查看裸仓库中的内容
虽然不能直接在文件系统中看到裸仓库中的文件,但可以通过以下方式查看其内容:
- 克隆裸仓库:可以将裸仓库克隆到本地,然后在本地查看文件内容:
- 使用 Git 命令查看:在裸仓库中,可以使用 Git 命令来查看提交记录、文件树等。例如:
这些命令可以帮助查看裸仓库中的历史提交和文件树,而无需将仓库克隆到本地。
为什么有些裸仓库看起来“有数据”
当看到一个裸仓库中有数据,这些数据其实是 Git 的元数据和对象存储,而不是实际的工作目录文件。这些元数据和对象包括了项目的版本历史记录、提交对象、树对象和文件的压缩版本等。这些是 Git 用来跟踪版本控制信息的核心部分。
我们也可以利用钩子函数将最新的推送文件部署到自定义的工作目录,可以选择为xxxx.git仓库同目录下,这样看起来就跟标准仓库下的.git文件结构类似了。
2. 非裸仓库(Non-Bare Repository)
定义:非裸仓库有一个工作目录,开发者可以在其中编辑文件和执行提交操作。通常情况下,非裸仓库同时包含工作目录和
.git
子目录。典型用法:
- 本地开发:开发者通常在本地机器上使用非裸仓库来进行日常开发工作。在这个环境中,开发者可以修改文件、提交更改并推送到远程仓库。
- 部署环境:在某些情况下,非裸仓库用于服务器上的特定目录,以便直接部署应用程序。这种情况下,可以通过拉取操作来获取最新的代码。
3. 为什么远程仓库通常使用裸仓库?
- 避免工作目录冲突:非裸仓库具有工作目录,如果多个用户推送到同一个非裸仓库,可能会引发冲突,尤其是工作目录和 Git 数据库的状态不同步时。裸仓库没有工作目录,从而避免了这些问题。
- 权限控制:裸仓库只用于版本控制,所有文件的更改都必须通过 Git 操作进行,因此可以更好地控制代码的更改过程。
- 简化管理:裸仓库不涉及工作目录的同步和更新问题,因此它更适合作为远程共享仓库的解决方案,尤其是在多人协作和自动化部署场景下。
4. 非裸仓库也可以作为远程仓库的情况
虽然裸仓库是最佳实践,但在某些特定场景下,非裸仓库也可以用作远程仓库:
- 单人项目:如果是唯一的开发者,且希望在远程服务器上直接修改文件(如进行配置更新),非裸仓库可以满足需求。
- 简单部署:在一些小型项目中,使用非裸仓库可以直接通过
git pull
来获取最新的更改,而不必设置额外的钩子或自动化脚本。
- 特定开发环境:例如测试环境或开发服务器,非裸仓库可以用来直接编辑和测试代码,但这不推荐用于生产环境。
5. 如何在非裸仓库中配置 push
操作
如果决定使用非裸仓库作为远程仓库,以下是一些注意事项:
- 避免多用户并发推送:如果多个开发者向同一非裸仓库推送,很容易导致工作目录冲突和数据不一致问题。
- 使用 Git 钩子:在接收推送后,可以使用 Git 钩子(如
post-receive
钩子)来执行一些操作,确保工作目录同步更新。
- 谨慎使用:对于小型或个人项目可以使用非裸仓库,但对于多人协作项目,还是建议使用裸仓库。
与仓库进行通讯的多种方式
不管是GIthub、GitLab和Gitee这种大型网络平台远程仓库还是自己部署在云服务器或者本地服务器的代码仓库,其通讯方式和原理都是类似的。在版本控制系统(如 Git)中,有几种常见的方式来推送代码到远程仓库,每种方式有不同的用途和安全考量。下面是对 SSH 密钥、GitHub 的 Token、以及不同代码推送方式的区别和关系的解释:
SSH 通讯方式与登录验证→SSH keys
- 用途:SSH 密钥用于通过 SSH 协议安全地连接到远程服务器(如 GitHub、GitLab、Bitbucket)。它是一种基于公钥加密的认证方式。
- 工作原理:
- 在本地生成一对密钥(公钥和私钥)。
- 将公钥上传到远程服务器。
- 当尝试通过 SSH 连接到远程服务器时,服务器使用公钥验证本地的私钥,从而进行身份验证。
- 优点:
- 更加安全,因为密钥对的安全性比密码高。
- 一旦配置好,可以免去每次操作时输入用户名和密码的麻烦。
- 配置:
- 生成密钥对并将公钥添加到远程服务器的用户配置中。
- 当使用 SSH 协议连接到远程 Git 仓库时,Git URL 会是以
git@
开头的形式,例如git@github.com:user/repo.git
,在 Git 配置中使用 SSH URL(如git@github.com:user/repo.git
)来推送代码。 - 在进行操作时(如
git push
或git pull
),Git 会使用 SSH 协议来建立连接并进行数据传输。
SSH 推送方式
Github端交互全部都是以git用户,即
git@github.com:user/repo.git
但是自有远程服务器端是以自己的用户通信,例如root,即root@github.com:user/repo.git
,git是一个账户名,要想在自己本地远程服务器使用类似Github的用户名就必须要注册git账户,并配置好权限。- 使用:通过 SSH 协议将代码推送到远程仓库。
- 示例 URL:
git@github.com:user/repo.git
- 优点:
- 安全性高,利用公钥加密技术。
- 一旦配置完成,不需要每次推送时输入凭证。
https 通讯方式与登录验证→Access Token
- 用途:GitHub 的 Personal Access Token(PAT)用于通过 HTTPS 协议进行身份验证。它是用来代替传统密码的,用于访问 GitHub API 和 Git 操作。
- 工作原理:
- 在 GitHub 上生成一个 Token,并将其用于 HTTP/HTTPS 协议的身份验证。
- 当推送代码或进行其他 GitHub API 操作时,使用 Token 代替密码进行身份验证。
- 优点:
- 增加了安全性,可以为不同的应用或脚本生成不同的 Token,并对其权限进行控制。
- 支持多因素认证(2FA)时,Token 是一种有效的替代方案。
- 配置:
- 生成 Token 后,在 Git 配置中使用 HTTPS URL(如
https://github.com/user/repo.git
)。 - 当 Git 提示输入密码时,输入 Token 代替密码。
HTTPS 推送方式
- 使用:通过 HTTPS 协议将代码推送到远程仓库。
- 示例 URL:
https://github.com/user/repo.git
- 优点:
- 更容易穿越防火墙,因为 HTTPS 是一种常见的协议。
- 在没有配置 SSH 密钥的情况下也可以使用。
git用户名与ssh用户名关系
- 独立存在: Git 用户名和 SSH 用户名是独立的。Git 用户名用于代码提交历史记录,而 SSH 用户名用于远程服务器身份验证。
- 协同工作: 当使用 SSH 连接 Git 远程仓库(例如 GitHub、GitLab、自建的 Git 服务器)时,SSH 用户名(例如
git
)是用于建立连接和认证的,而 Git 用户名(例如Alice
)是用来记录谁在提交代码。
- 默认 SSH 用户名: 在大多数托管 Git 服务(如 GitHub、GitLab)中,通常 SSH 用户名固定为
git
,实际的用户识别依赖于所用的 SSH 密钥。SSH 用户名与 Git 提交者信息无关,只是用于建立 SSH 连接。
1. Git 用户名
- 用途: Git 用户名用于标识代码提交者。当提交代码时,Git 使用的用户名和电子邮件地址来记录谁进行了这次提交。这个用户名和邮箱信息通常在每次提交时会嵌入到提交历史中,用于审计和识别。
- 配置: Git 用户名和邮箱是通过以下命令配置的(这些信息只存储在本地 Git 仓库中,并不会自动用来验证身份或连接到远程服务器):
- 示例: 假设配置了以下信息:
当使用 Git 提交代码时,提交记录会显示 “Alice alice@example.com” 作为提交者。
2. SSH 用户名
- 用途: SSH 用户名用于远程登录到服务器。它是用于通过 SSH 协议建立安全连接的用户账户。在使用 Git 与远程仓库进行通信时(例如
git clone
,git pull
,git push
),SSH 可以用于认证和建立安全的传输通道。
- 配置: SSH 用户名通常是在 SSH 命令中指定的,或者在 SSH 配置文件中定义的。例如:
- 通过命令行指定:
ssh username@hostname
- 在 Git 使用 SSH URL 时:
git@hostname:path/to/repo.git
中的git
是 SSH 用户名。
也可以在
~/.ssh/config
文件中配置特定主机的 SSH 用户名:示例场景
假设使用 SSH 连接 GitHub 并推送代码:
- 配置了 Git 用户名和邮箱:
- 有一个 SSH 密钥对,并且公钥已添加到 GitHub 账户中。
- 克隆仓库使用了 SSH URL:
在这个场景中:
- SSH 用户名:用于认证的是
git
,GitHub 使用的 SSH 密钥来确认的身份。
- Git 用户名:用于标识的代码提交者信息,是
Alice
,这个名字会出现在提交记录中。