Bootstrap

[Pro Git#1] ubuntu安git | .git分析 | 版本回退 | HEAD指针

目录

目标

初识Git

Ubuntu 环境下安装 Git

创建 Git 本地仓库

Git 配置与基本操作

一、Git 的配置

二、认识工作区、暂存区、版本库

三、添加文件到仓库

四、查看提交历史

五、.git 目录结构

Git 暂存区、HEAD、对象库及文件

一、Git 内部结构概览

二、查看和理解 Git 对象

三、工作区、暂存区、版本库的操作流程

版本回退与撤销修改

一、Git 的版本回退功能

git reset

指定回退版本的方式

Git 版本回退速度及原理

二、撤销工作区中的修改

情况一:对于工作区的代码,还没有 add

情况二:已经 add,但没有 commit

三、回退已提交的更改

情况三:已经 add 并且也 commit 了

四、删除文件

删除文件的两种场景

总结


目标
  • 技术目标
    • 掌握Git的企业级应用,深入理解Git操作流程与原理,明确工作区、暂存区、版本库的概念。
    • 熟练进行Git版本管理,包括回退、撤销、修改等操作,并理解其背后的机制。
    • 精通Git分支管理,从创建、切换、合并到删除的完整生命周期,适应各种场景下的分支管理需求,学习常见的分支管理策略。
    • 结合版本管理和分支管理,掌握远程仓库与本地仓库的使用,实现基于分支级别的个人开发。
    • 理解分布式版本控制系统的工作方式,熟练掌握远程仓库与本地仓库之间的交互操作,熟悉多人协作开发模式。
  • 协作目标
    • 学习企业中常见的分支策略(如master/release/develop/feature/hotfix),了解不同公司和环境下的合适分支模型。通过案例分析,引入工程师、测试人员和技术经理等角色,展示项目开发全过程,深刻理解开发的整体流程及Git在其中的作用。
初识Git
  • 提出问题
    在日常工作或学习中,我们常常遇到需要保存多个版本文件的情况,例如文档编写时为了防止丢失或误改而产生的多个副本(如“报告-v1”、“报告-v2”等)。随着版本数量增加,不仅文件数量增多,而且难以记住每个版本具体修改了什么内容。同样地,项目代码也存在同样的问题。
  • 解决方案:版本控制器
    版本控制器是一种能够记录文件历史及其发展过程的系统,使我们可以方便地管理文件的不同版本,并支持多人协同作业。Git是当前最主流的版本控制工具,适用于管理各种格式的文件,特别是对于开发者来说,它对源代码文件的管理尤为重要。
  • 注意事项
    尽管Git可以处理所有格式的文件,但所有的版本控制系统主要跟踪的是文本文件的变化。对于文本文件,Git能详细记录每次修改的具体内容;而对于图片、视频等二进制文件,Git只能记录文件大小的变化,无法追踪具体内容的更改。

Ubuntu 环境下安装 Git

在Ubuntu 20.04环境下,安装Git非常简便。首先,可以通过命令行检查系统是否已经安装了Git:

git

如果系统中没有安装Git,会收到如下提示信息:

Command 'git' not found, but can be installed with:
sudo apt install git

根据提示,可以通过以下命令来安装Git:

sudo apt-get install git -y

安装完成后,可以使用以下命令查看已安装的Git版本:

这将显示当前安装的Git版本号。

补充:


创建 Git 本地仓库

要对文件进行版本控制,必须先创建一个Git仓库。创建本地Git仓库的命令是git init。此命令需要在你希望作为仓库根目录的文件夹内执行。例如:

执行上述命令后,你会注意到当前目录下出现了一个名为.git的隐藏目录:

.git目录是Git用来跟踪和管理仓库的地方。它包含了所有必要的元数据和配置文件。注意不要手动修改这个目录中的文件,以免破坏Git仓库的结构

对于有兴趣深入了解的 uu,可以在不影响项目的情况下探索.git目录的内容,以增进对Git工作原理的理解。


Git 配置与基本操作

一、Git 的配置

当安装完 Git 后,首要任务是设置你的用户名称和 E-mail 地址。这是非常重要的,因为每次 Git 提交都会使用这些信息。

  • 全局配置(适用于所有仓库):
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
  • 本地配置(仅适用于当前仓库):如果希望在不同仓库中使用不同的用户名或邮箱,可以在特定仓库内执行以下命令,而不带 --global 选项:
git config user.name "Your Name"
git config user.email "[email protected]"
  • 查看配置:使用以下命令可以列出所有的 Git 配置项:
git config -l

  • 删除配置:若要删除某个配置项,可以使用 --unset 选项:
git config [--global] --unset user.name
git config [--global] --unset user.email
二、认识工作区、暂存区、版本库
  • 工作区:这是你在电脑上编写代码或文件的目录。
  • 暂存区(Stage/Index):一般存放于 .git/index 文件中,用于存储即将提交到版本库中的更改。
  • 版本库(Repository):位于工作区的隐藏 .git 目录下,用来管理所有文件的修改和历史记录。

当你创建一个新的 Git 版本库时,Git 会自动创建一个名为 master 的分支及指向该分支的 HEAD 指针。对工作区的文件进行修改后,需先通过 git add 命令将更改添加到暂存区,再通过 git commit 将暂存区的内容提交至版本库。

三、添加文件到仓库

要将新文件或修改后的文件添加到 Git 管理中,需要经历两个步骤:addcommit

  • 添加文件到暂存区
    • 添加单个或多个文件:
git add [file1] [file2] ...
    • 添加指定目录及其子目录:
git add [dir]
    • 添加当前目录下的所有改动:
git add .
  • 提交暂存区内容到本地仓库
    • 提交暂存区的所有内容(默认):
git commit -m "message"
    • 提交暂存区的指定文件:
git commit [file1] [file2] ... -m "message"

注意,git commit 后面的 -m 参数用于提供描述性提交信息,这部分内容非常重要,因为它记录了你所做的更改细节。

四、查看提交历史

你可以使用 git log 查看项目的提交历史。为了简化输出,还可以加上 --pretty=oneline 参数以获得更简洁的格式。

git log --pretty=oneline

这将显示每个提交的简短摘要,包括 提交 ID(SHA1 格式的哈希值),它是一个由 Git 自动生成的唯一标识符,用以区分不同的提交。

五、.git 目录结构

.git 是 Git 用来跟踪和管理仓库的地方,包含了所有必要的元数据和配置文件。不要手动修改这个目录中的文件,以免破坏 Git 仓库的结构。

sum:


Git 暂存区、HEAD、对象库及文件

一、Git 内部结构概览
  1. 暂存区(Index)
    • index 文件位于 .git 目录下,是暂存区的物理存储位置。
    • 使用 git add 命令后,修改或新增的内容会被添加到这里。暂存区的作用是在提交前收集所有要纳入版本控制的更改。
  1. HEAD 指针
    • 默认情况下,HEAD 是指向当前分支的一个指针,通常是指向 master 分支。
    • 可以通过查看 .git/HEAD 文件来确认 HEAD 当前所指向的分支。
  1. master 分支
    • master 分支是一个特殊的默认分支,代表项目的主线发展。
    • 查看 master 分支最新的提交 ID(commit id),可以通过查看 .git/refs/heads/master 文件内容:

  1. 对象库(Objects)
    • .git/objects 目录存放了所有被 Git 管理的对象,包括提交(commits)、树(trees)、标签(tags)和 blob(文件内容)。
    • 对象名由 SHA-1 哈希值表示,前两位作为子目录名,剩余部分作为文件名。例如,对于提交 ID 23807c536969cd886c4fb624b997ca575756eed6,其路径为 .git/objects/23/807c536969cd886c4fb624b997ca575756eed6
二、查看和理解 Git 对象
  • 使用 git cat-file -p <object-id> 命令可以解码并查看对象的内容。
  • 提交对象包含元数据(如作者信息、时间戳)以及指向树对象的引用。例如:

三、工作区、暂存区、版本库的操作流程
  • 添加文件到仓库
    • 新建或修改文件后,使用 git add 将更改添加到暂存区。
    • 使用 git commit 提交暂存区的内容到本地仓库中。注意,只有在暂存区中的文件才会被提交。
  • 处理未添加到暂存区的文件
    • 如果有新的文件没有通过 git add 添加到暂存区,那么这些文件不会被 git commit 捕获。
    • 解决方法是再次执行 git add 后再进行 git commit
  • 修改文件
    • Git 跟踪的是修改而非文件本身。任何对文件内容的变更(如新增行、删除行、更改字符等)都被视为一次修改。
    • 修改文件后,可以使用 git status 查看哪些文件已被修改但尚未添加到暂存区。
    • 使用 git diff [file] 显示工作区与暂存区之间的差异,帮助理解具体做了哪些改动。
    • 使用 git diff HEAD -- [file] 查看工作区与最近一次提交之间的区别。

  • 提交修改后的文件
    • 修改文件后,先用 git add 将更改添加到暂存区,然后用 git commit 提交更改。
    • 提交完成后,git status 应显示 nothing to commit, working tree clean,表明没有待提交的更改。


版本回退与撤销修改

一、Git 的版本回退功能

Git 提供了强大的版本回退功能,允许开发者在发现当前工作存在重大问题时,能够快速地回到某个特定的历史版本重新开始。这不仅提高了开发效率,还保障了代码的质量和稳定性。

git reset

git reset 是用于回退版本的主要命令,它可以根据不同的参数选择性地回退工作区、暂存区或版本库的内容。其语法格式如下:

git reset [--soft | --mixed | --hard] [commit]
  • --soft:仅回退版本库 (commit 后的) 到指定版本,工作区和暂存区内容保持不变。
  • --mixed(默认):回退暂存区到指定版本 index,工作区文件保持不变。可以继续编辑这些文件。
  • --hard:将暂存区和工作区都回退到指定版本。注意:此操作会丢失工作区中未提交的更改,请谨慎使用。

指定回退版本的方式
  • 直接写 commit id精确指定要回退到的提交记录。
  • HEAD:表示当前版本。
  • HEAD^HEAD~1:表示上一个版本。
  • HEAD^^ HEAD~2:表示上上一个版本,以此类推。

为了演示版本回退的功能,我们先创建三个不同版本的 ReadMe 文件,并分别提交:

# 第一次修改提交
echo "hello bit" > ReadMe
echo "hello git" >> ReadMe
echo "hello world" >> ReadMe
echo "hello version1" >> ReadMe
git add ReadMe 
git commit -m "add version1"

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

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

查看历史提交记录:

现在假设我们在提交完 version3 后,发现编写错误,想回退到 version2并基于 version2 重新开始编写。此时我们需要使用 --hard 参数来确保工作区的内容也回退到 version2

验证回退成功~

如果之后又后悔想要回到 version3,可以通过 git reflog 查找之前的提交记录,找到 version3commit id 并执行回退:

Git 版本回退速度及原理

Git 的版本回退速度非常快,这得益于其内部机制。Git 在每个分支(例如 master)上维护一个指向当前提交的 HEAD 指针。具体来说:

  • refs/heads/master 文件:保存了当前 master 分支的最新 commit id
  • 回退版本时的操作:Git 实际上只是更新 refs/heads/master 中存储的 commit id,使其指向特定的历史版本。

这种设计使得 Git 可以迅速完成版本回退,而无需对整个项目进行重新构建或处理大量数据。

二、撤销工作区中的修改

当我们在工作区编写了一段时间后,如果觉得代码质量不高,想要恢复到最近一次 addcommit 的状态,可以使用以下几种方法:

情况一:对于工作区的代码,还没有 add
  1. 直接删除新增代码:如果你只修改了少量内容,可以直接编辑文件删除不需要的部分。
  2. 使用 git checkout -- [file] 命令:更推荐的方式是使用此命令来恢复文件到最近一次 addcommit 的状态。注意命令中的 -- 参数非常重要,不可省略。

示例:

# 向 ReadMe 中新增一行代码
vim ReadMe 
echo "This piece of code is like shit" >> ReadMe
:
# 查看状态
git status

# 恢复到最近一次 add 或 commit
git checkout -- ReadMe

# 验证恢复情况
cat ReadMe
git status

情况二:已经 add,但没有 commit

当你已经将更改添加到了暂存区,但尚未提交时,可以通过 git reset 命令撤消暂存区的内容,并选择是否保留工作区的更改。

示例:

# 向 ReadMe 中新增一行代码并添加到暂存区
echo "This piece of code is like shit" >> ReadMe
git add ReadMe

# 使用 git reset 回退暂存区的内容
git reset HEAD ReadMe

# 查看状态,发现暂存区干净,工作区有修改
git status

# 如果需要丢弃工作区的修改,可以继续使用 git checkout -- [file]
git checkout -- ReadMe

三、回退已提交的更改

如果你已经提交了更改,但希望回到之前的版本,可以根据是否推送至远程仓库采取不同的措施。

情况三:已经 add 并且也 commit
  1. 本地回退:如果更改还未推送到远程仓库,可以安全地使用 git reset --hard HEAD^ 回退到上一个版本。请注意,--hard 参数会同时影响工作区和暂存区,请谨慎使用。
  2. 远程回退:一旦推送至远程仓库,建议不要轻易回退,因为这可能会影响到其他开发者的工作。此时应该考虑创建新的提交来修正问题,而不是直接回退历史记录。

示例:

# 新增一行代码并提交
echo "This piece of code is like shit" >> ReadMe
git add ReadMe
git commit -m "test quash"

# 回退到上一个版本
git reset --hard HEAD^

# 验证回退结果
cat ReadMe
git status

sum:

  • get reset --mixed 回退 add & commit
  • get checkout --file 回退 work 区

四、删除文件

在 Git 中,删除文件也是一个修改操作。直接删除文件不会自动同步到版本库,因此需要额外的步骤来确保变更被正确记录。

删除文件的两种场景
  1. 确实要从版本库中删除该文件
    • 使用 git rm 命令将文件从暂存区和工作区中删除,并提交更改。
# 删除文件并提交
git rm file5
git commit -m "deleted file5"
  1. 误删文件
    • 如果不小心删除了文件,可以使用 git checkout -- [file] 来恢复文件。
# 恢复误删的文件
git checkout -- file5
总结
  • git checkout回退最近一次
  • git reset回退版本
  • git rm删除
;