Git使用

Git使用

  • [1. Git初识](#1. Git初识)
    • [1.1 为什么需要Git?](#1.1 为什么需要Git?)
    • [1.2 Git 是什么?](#1.2 Git 是什么?)
    • [1.3 Git 的注意事项](#1.3 Git 的注意事项)
    • [1.4 Git安装](#1.4 Git安装)
  • [2. Git基本操作](#2. Git基本操作)
    • [2.1 创建Git本地仓库](#2.1 创建Git本地仓库)
      • [`git init`:本地版本控制的 "起点"](#git init:本地版本控制的 “起点”)
      • [Gitee 仓库:远程协作的 "平台"](#Gitee 仓库:远程协作的 “平台”)
    • [2.2 配置Git](#2.2 配置Git)
    • [2.3 Git 工作区、暂存区、版本库](#2.3 Git 工作区、暂存区、版本库)
    • [2.4 添加文件与提交版本](#2.4 添加文件与提交版本)
    • [2.5 查看提交历史](#2.5 查看提交历史)
    • [2.6 Git 底层结构与文件操作](#2.6 Git 底层结构与文件操作)
    • [2.7 版本回退](#2.7 版本回退)

1. Git初识

1.1 为什么需要Git?

在日常工作和学习中,我们经常会遇到这样的场景:编写文档或代码时,为了防止内容丢失、修改失误,需要保留不同阶段的版本,于是会出现 "报告 - v1" ,"报告 - v2" ,"代码最终版" ,"代码究极进化版" 这类大量重复的文件副本。

随着版本数量增多,我们很难清晰记得每个版本具体修改了什么内容。这种问题在软件开发项目的代码管理中尤为突出。

为了解决这类版本管理的痛点,版本控制器应运而生,而 Git 就是目前最主流的版本控制器。

1.2 Git 是什么?

版本控制器是一套可以记录文件(或工程)历史变更、发展过程的系统。它能帮我们:

  • 追踪文件的每一次改动,明确版本演进的脉络;
  • 方便多人协同作业,在团队开发中高效管理代码版本;
  • 支持版本回退,当修改失误时能快速恢复到之前的正确版本。

Git 作为主流版本控制器,可以管理几乎所有格式的文件 ,包括文档(doc、txt 等)、表格(excel)、代码文件,甚至工程图纸(dwg、dgn 等)。对于开发人员而言,Git 最核心的价值是管理软件开发项目中的源代码文件,保障代码开发的高效性和可追溯性。

1.3 Git 的注意事项

需要明确的是,Git(以及所有版本控制系统)对文本文件二进制文件的追踪能力是有区别的:

  • 文本文件(如 TXT、网页代码、程序源代码等):Git 可以精确追踪每一次改动,比如能明确告诉你 "在第 5 行添加了单词'Linux',在第 8 行删除了单词'Windows'"。
  • 二进制文件 (如图片、视频、音频等):Git 可以管理这些文件的版本,但无法追踪具体的内容变化,只能记录文件大小、修改时间等基本信息(例如仅知道图片从 100KB 变为 120KB,却无法知晓图片内容具体改了哪里)。

通过以上内容,我们可以快速理解 Git 出现的背景、核心作用以及使用时的关键注意点,为后续学习 Git 的具体操作打下基础。

1.4 Git安装

复制代码
# ubuntu系统安装
sudo apt install git -y

2. Git基本操作

2.1 创建Git本地仓库

仓库是 Git 进行版本控制的文件目录,要对文件进行版本管理,必须先创建一个仓库。

git init

使用 git init 命令在指定文件目录下创建 Git 本地仓库,执行时需注意命令要在目标文件目录下执行

c 复制代码
zmm@zmm:~$ pwd
/home/zmm
zmm@zmm:~$ mkdir gitcode
zmm@zmm:~$ cd gitcode/
zmm@zmm:~/gitcode$ git init
提示:使用 'master' 作为初始分支的名称。这个默认分支名称可能会更改。要在新仓库中
提示:配置使用初始分支名,并消除这条警告,请执行:
提示:
提示:	git config --global init.defaultBranch <名称>
提示:
提示:除了 'master' 之外,通常选定的名字有 'main'、'trunk' 和 'development'。
提示:可以通过以下命令重命名刚创建的分支:
提示:
提示:	git branch -m <name>
已初始化空的 Git 仓库于 /home/zmm/gitcode/.git/

仓库的核心标识:.git 隐藏目录

执行 git init 后,当前目录会生成一个 .git 隐藏文件夹,它是 Git 跟踪管理仓库的核心目录,包含了仓库的版本信息、配置、历史记录等细节。

⚠️ 注意:不要手动修改 .git 目录内的文件 ,否则会破坏 Git 仓库的完整性。

git init 和 Gitee 上创建的仓库有本质区别,核心差异可以从定位、功能、使用场景三个维度来理解:

git init:本地版本控制的 "起点"

  • 定义git init 是 Git 命令,用于在本地计算机 创建一个 Git 仓库(生成 .git 隐藏目录),仅负责本地文件的版本管理(比如记录文件修改历史、版本回退等)。
  • 功能范围:仅支持本地操作,没有 "远程协作""代码托管" 等能力,相当于你在自己电脑上建了个 "版本管理文件夹"。
  • 典型场景 :个人开发时,想在本地记录代码 / 文档的修改历史,就用 git init 初始化本地仓库。

Gitee 仓库:远程协作的 "平台"

  • 定义 :Gitee 是基于 Git 的远程代码托管平台 ,你在 Gitee 上创建的仓库是托管在Gitee 服务器上的远程仓库。
  • 功能范围 :不仅支持版本控制,还提供多人协作 (如 Pull Request、代码评审)、DevOps 流程 (如 CI/CD)、权限管理(公开 / 私有仓库)等扩展功能,是团队协作和代码共享的工具。
  • 典型场景 :团队开发时,需要多人共享代码、审核修改、追踪问题,就会在 Gitee 上创建远程仓库,再结合本地 git init 的仓库进行协作。

2.2 配置Git

安装 Git 后,首先需要设置用户名称e-mail 地址,这是 Git 识别版本提交者身份的关键信息,也用于多人协作时的权限和记录管理。

复制代码
# 配置用户名
git config [--global] user.name "Your Name"

# 配置邮箱
git config [--global] user.email "email@example.com"
  • --global 选项
    • 若添加该选项,表示这台机器上所有 Git 仓库都会使用此配置
    • 若不添加 --global,则配置仅对当前仓库生效(执行命令时需在仓库目录内)。
  • 替换说明:将 Your Name 改为你的昵称,email@example.com 改为你的实际邮箱即可。

若想确认当前 Git 的配置信息,可执行:

复制代码
git config -l

如果需要删除已配置的用户名或邮箱,可执行:

复制代码
# 删除用户名配置
git config [--global] --unset user.name

# 删除邮箱配置
git config [--global] --unset user.email

(同样,--global 选项决定是删除全局配置还是仅当前仓库的配置,若之前是使用--global选项,则删除也需要带上--global)

2.3 Git 工作区、暂存区、版本库

1. 工作区

是你在电脑上写代码或存放文件的目录,就是你能直观看到的文件所在的文件夹。

2. 暂存区

英文名为 stageindex,一般存放在 .git 目录下的 index 文件(.git/index)中,也被称为索引(index)。它是工作区和版本库之间的 "中转站"。

3. 版本库

又名仓库,英文是 repository。工作区里的隐藏目录 .git 就是 Git 的版本库(它不算工作区)。版本库能跟踪管理所有文件的修改、删除等操作,让你可以随时追溯历史或还原版本。

4. 三者关系

  • 左侧是工作区 ,右侧是版本库 ,版本库中最关键的是暂存区(stage)
  • Git 初始化时会自动创建默认分支 master 和指向 master 的指针 HEAD(分支和 HEAD 后续详细讲)。
  • 当你在工作区修改或新增文件后,执行 git add 命令,暂存区的文件索引会被更新;执行 git commit 命令,master 分支会更新,相当于把暂存区的内容真正写入版本库。

简言之:新文件仅放在工作区时,不算加入版本库管理;必须通过 git add 放到暂存区,再通过 git commit 提交到版本库,才算完成版本跟踪。

2.4 添加文件与提交版本

场景一:添加单个文件到版本库

复制代码
# 1. 新建并编辑文件(以 vim 为例,也可通过其他方式创建)
vim ReadMe
# 2. 查看文件内容(可选)
cat ReadMe
# 3. 将文件添加到暂存区
git add ReadMe
# 4. 将暂存区内容提交到本地版本库(-m 后跟提交说明,必须填写)
git commit -m "commit my first file"

执行 git commit 后,会提示文件改动信息(比如新增了几行内容),表示提交成功。

场景二:批量添加多个文件到版本库

复制代码
# 1. 新建多个文件
touch file1 file2 file3
# 2. 分别将文件添加到暂存区(也可一次性 add 多个,如 git add file1 file2 file3)
git add file1
git add file2
git add file3
# 3. 一次性提交暂存区所有内容到版本库
git commit -m "add 3 files"

2.5 查看提交历史

git log执行后会显示从最近到最远的提交日志,包含提交者、时间、提交说明等信息:

git log --pretty=oneline当提交记录过多时,可通过该参数让输出更简洁,每行仅显示提交 ID 和提交说明:

其中可以看到的类似 23807c5...56eed6 的字符串是提交 ID(版本号),它是通过 SHA1 算法生成的十六进制大数字,而非简单的递增数字(每个人的提交 ID 都不同,以自己实际输出为准)。

2.6 Git 底层结构与文件操作

通过 tree .git/ 命令可以查看其目录结构,主要包含以下关键部分:

  • branches:早期 Git 分支管理的遗留目录,现在基本不用。
  • COMMIT_EDITMSG:存储最后一次提交的说明信息。
  • config:Git 的配置文件,包含用户信息、远程仓库等配置。
  • description:用于 GitWeb 等工具的仓库描述。
  • HEAD:指向当前所在分支的指针(如默认指向 master 分支)。
  • hooks:存放 Git 钩子脚本的目录,用于自动化触发操作(如提交前检查、推送后通知)。
  • index暂存区的核心文件git add 后的内容会更新到这里。
  • info:包含仓库的额外信息,如 exclude 文件(类似 .gitignore)。
  • logs:记录分支的历史操作日志。
  • objects:Git 的对象库,存储所有版本的文件内容、提交信息、目录结构等。
  • refs:存储分支和标签的引用,如 heads/master 指向当前 master 分支的最新提交 ID。

核心组件解析

  • index(暂存区)git add 命令会将文件添加到这里,是工作区和版本库之间的 "中转站"。

  • HEAD :是一个指针,默认指向 master 分支。执行 cat .git/HEAD 可查看其指向,示例输出 ref: refs/heads/master 表示当前在 master 分支。

    zmm@zmm:~/gitcode$ cat .git/HEAD
    ref: refs/heads/master

  • objects(对象库) :存储 Git 中的三种对象 ------blob(文件内容)、tree(目录结构)、commit(提交信息)。执行 git add 时,文件内容会被写入到 objects 目录下的新对象中。

    • 对象查找方式 :提交 ID(commit id)分为两部分,前 2 位是文件夹名,后 38 位是文件名。例如 23807c536969cd886c4fb624b997ca575756eed6 会存放在 objects/23/807c536969cd886c4fb624b997ca575756eed6
    • 查看对象内容 :使用 git cat-file -p <commit id/tree id/blob id> 命令,可查看提交、目录树、文件内容的详细信息。
  • 暂存区(清单):只记 "要提交什么文件、对应哪个货号",不存文件内容;
  • objects(货架):存文件的实际内容(blob)、目录结构(tree)、提交记录(commit),是所有数据的存储地;

假设你在工作区修改了 ReadMe 文件,执行 git add ReadMe

  • ① 先把 ReadMe当前内容 ,以 blob 类型对象的形式,写入 objects 目录(相当于把 "文章草稿" 的最终文本,存到 "数据档案室");
    • 比如文件内容会被压缩、计算 SHA1 哈希(就是后续的对象 ID),然后存到 objects/xx/xxxxxxxxxxxx(前两位是哈希前缀,后 38 位是完整哈希);
    • 此时 objects 里已经有了这个文件的当前版本数据,但这只是 "原始数据",还没和 "版本" 绑定。
  • ② 再更新 .git/index 文件(暂存区):把 ReadMe 的文件名、对应的 blob 对象 ID、文件权限等信息,记录到 index 里(相当于把 "文章草稿" 加入 "待发表清单");
    • 此时暂存区(index)知道 "要提交 ReadMe,且它的内容在 objects 目录的某个 blob 对象里",但这还不是一个完整的 "版本"。

👉 关键结论:git add 会往 objects 写文件内容(blob 对象),但 objects 不是 "暂存库"------ 暂存区是 index 文件(清单),objects 是存放清单对应 "原始数据" 的仓库。

执行 git commit -m "修改 ReadMe" 后,才会形成一个完整的版本:

  • ① 先创建一个 tree 类型对象,写入 objects 目录:
    • tree 对象记录了 "当前暂存区的目录结构"------ 比如 "当前目录下有 ReadMe 文件,对应哪个 blob 对象;有 docs 文件夹,对应哪个子 tree 对象"(相当于把 "待发表清单" 整理成 "文章目录");
    • 这个 tree 对象也会存在 objects 里,有自己的哈希 ID。
  • ② 再创建一个 commit 类型对象,写入 objects 目录:
    • commit 对象是 "版本的核心凭证",包含三部分关键信息:
      1. 指向刚才创建的 tree 对象(知道这个版本包含哪些文件 / 目录);
      2. 指向父提交对象(知道这个版本是基于哪个之前的版本修改的,形成版本链);
      3. 提交者信息、提交时间、提交说明(就是你 -m 后面写的内容);
    • 这个 commit 对象的哈希 ID,就是我们看到的 commit id(版本号)。
  • ③ 最后更新分支指针(比如 master 分支):
    • 把当前分支(如 refs/heads/master)的指针,指向这个新创建的 commit 对象(相当于把 "文章目录 + 核心凭证" 绑定到 "专栏",标记为最新版本)。

👉 关键结论:git commit 并没有把数据 "从 objects 搬到别的地方"------ 而是在 objects 里新增了 treecommit 对象,把之前 git add 存的 blob 对象(文件内容)"组织起来",形成一个可追溯的 "版本",最终记录到版本库中。

2.7 版本回退

版本回退是 Git 最核心的能力之一,当你发现最新代码出现严重问题时,它能帮你快速回到历史上的稳定版本。下面结合内容,从命令原理、操作场景、底层逻辑三个维度详细讲解。

git reset 是实现版本回退的命令,它通过不同的参数控制 "工作区、暂存区、版本库" 的回退范围,语法格式为:

复制代码
git reset [--soft | --mixed | --hard] [HEAD]

一般不要去使用--hard,mixed用的最多

HEAD 是 Git 中表示 "当前版本" 的指针,通过它可以灵活指定回退的目标版本:

  • HEAD:当前版本
  • HEAD^:上一个版本
  • HEAD^^:上上一个版本
  • HEAD~n:往上第 n 个版本(如 HEAD~3 表示往上 3 个版本)
  • 直接写 commit id:指定回退到某个具体版本(可通过 git loggit reflog 获取)
c 复制代码
zmm@zmm:~/gitcode$ cat ReadMe 
hello git
hello world
zmm@zmm:~/gitcode$ git log --pretty=oneline
e207f4e61cc36c7d1e1ad303ad090dc4d6974c17 (HEAD -> master) modify ReadMe
4299a6418c996357db5c26f00698028c21c63a4a add file4,5
b89c925366b6a7130255defd5c427317c365d47d add 3 file
269ced211fe34496dd3f820c99307755b27c4446 the first commit file
zmm@zmm:~/gitcode$ git reset --hard 269ced211fe34496dd3f820c99307755b27c4446
HEAD 现在位于 269ced2 the first commit file
zmm@zmm:~/gitcode$ ls
ReadMe
zmm@zmm:~/gitcode$ cat ReadMe 
hello git
zmm@zmm:~/gitcode$ git log --pretty=oneline
269ced211fe34496dd3f820c99307755b27c4446 (HEAD -> master) the first commit file
zmm@zmm:~/gitcode$ git reset --hard e207f4e61cc36c7d1e1ad303ad090dc4d6974c17
HEAD 现在位于 e207f4e modify ReadMe
zmm@zmm:~/gitcode$ ls
file1  file2  file3  file4  file5  ReadMe
zmm@zmm:~/gitcode$ git log --pretty=oneline
269ced211fe34496dd3f820c99307755b27c4446 (HEAD -> master) the first commit file
c 复制代码
# 第一次提交(version1)
echo "hello version1" >> ReadMe
git add ReadMe
git commit -m "add version1"

# 第二次提交(version2)
echo "hello version2" >> ReadMe
git add ReadMe
git commit -m "add version2"

# 第三次提交(version3)
echo "hello version3" >> ReadMe
git add ReadMe
git commit -m "add version3"

# 查看提交历史
git log --pretty=oneline
   
# 回退到 version2(用 --hard 参数)   
git reset --hard HEAD^  # 或直接用 version2 的 commit id,如 git reset --hard 14c12c3...
    
执行后:
工作区的 ReadMe 内容会回退到 version2;
git log 会显示当前版本是 version2,version3 的提交记录暂时 "消失"。    

如果回退后又想回到 version3,git log 已经看不到它的 commit id 了,这时候用 git reflog(记录所有操作历史):

复制代码
git reflog

输出中会显示所有操作的 commit id,找到 version3 对应的 commit id(如 d95c13f),再执行:

复制代码
git reset --hard d95c13f

就能回到 version3 版本。

底层逻辑:为什么版本回退这么快?

Git 版本回退的速度很快,因为它本质上是移动 HEAD 指针

  • 每个提交版本在 Git 中是 "链状存储" 的,refs/heads/master 文件里保存着当前分支的最新 commit id
  • 版本回退时,Git 只是把 HEAD 指针从 "新版本" 移动到 "旧版本" 的 commit id 上,并不删除历史版本数据;
  • 这也是为什么用 git reflog 能找回所有操作 ------ 历史版本的 commit id 一直存在,只是 HEAD 指针移动了。

核心本质:Git 的版本回退 / 复原 = 指针移动 ,所有已提交的版本数据(commit+tree+blob)都会保存在 objects 中,不会因为指针移动而删除;

复制代码
version3(commit id: C)← HEAD ← master 分支指针
       ↑
version2(commit id: B)
       ↑
version1(commit id: A)

执行 git reset --hard HEAD^ 回退到 version2
version3(commit id: C)【数据仍在 objects 中,只是没人指向它】
       ↑
version2(commit id: B)← HEAD ← master 分支指针
       ↑
version1(commit id: A)
相关推荐
大筒木老辈子6 小时前
Git笔记---远程仓库的创建与基本操作
笔记·git
9***Y487 小时前
终于解决了!Git拉取代码冲突的处理
git
南屿欣风9 小时前
Idea中Git切换分支,如何确保代码不丢失。
git
不一样的故事1269 小时前
将 Git 远程仓库的地址从 HTTP 修改为 SSH,
git·http·ssh
n***i959 小时前
终于搞定了!Git分支回滚的正确操作
git
A***279510 小时前
终于搞定了!Git拉取代码时权限被拒绝
git
秦jh_10 小时前
【git】多人协作
git
小坏讲微服务12 小时前
Docker Compose搭建Git仓库私服上传微服务
分布式·git·docker·微服务·容器·springcloud·springalibaba
七号练习生.c21 小时前
Git常用命令速查
大数据·git