目录
目标
- 技术目标
-
- 掌握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 管理中,需要经历两个步骤:add
和 commit
。
- 添加文件到暂存区:
-
- 添加单个或多个文件:
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 内部结构概览
- 暂存区(Index)
-
index
文件位于.git
目录下,是暂存区的物理存储位置。- 使用
git add
命令后,修改或新增的内容会被添加到这里。暂存区的作用是在提交前收集所有要纳入版本控制的更改。
- HEAD 指针
-
- 默认情况下,
HEAD
是指向当前分支的一个指针,通常是指向master
分支。 - 可以通过查看
.git/HEAD
文件来确认HEAD
当前所指向的分支。
- 默认情况下,
- master 分支
-
master
分支是一个特殊的默认分支,代表项目的主线发展。- 查看
master
分支最新的提交 ID(commit id),可以通过查看.git/refs/heads/master
文件内容:
- 对象库(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
查找之前的提交记录,找到 version3
的 commit id
并执行回退:
Git 版本回退速度及原理
Git 的版本回退速度非常快,这得益于其内部机制。Git 在每个分支(例如 master
)上维护一个指向当前提交的 HEAD
指针。具体来说:
refs/heads/master
文件:保存了当前master
分支的最新commit id
。- 回退版本时的操作:Git 实际上只是更新
refs/heads/master
中存储的commit id
,使其指向特定的历史版本。
这种设计使得 Git 可以迅速完成版本回退,而无需对整个项目进行重新构建或处理大量数据。
二、撤销工作区中的修改
当我们在工作区编写了一段时间后,如果觉得代码质量不高,想要恢复到最近一次 add
或 commit
的状态,可以使用以下几种方法:
情况一:对于工作区的代码,还没有 add
- 直接删除新增代码:如果你只修改了少量内容,可以直接编辑文件删除不需要的部分。
- 使用
git checkout -- [file]
命令:更推荐的方式是使用此命令来恢复文件到最近一次add
或commit
的状态。注意命令中的--
参数非常重要,不可省略。
示例:
# 向 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
了
- 本地回退:如果更改还未推送到远程仓库,可以安全地使用
git reset --hard HEAD^
回退到上一个版本。请注意,--hard
参数会同时影响工作区和暂存区,请谨慎使用。 - 远程回退:一旦推送至远程仓库,建议不要轻易回退,因为这可能会影响到其他开发者的工作。此时应该考虑创建新的提交来修正问题,而不是直接回退历史记录。
示例:
# 新增一行代码并提交
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 & commitget checkout --file
回退 work 区
四、删除文件
在 Git 中,删除文件也是一个修改操作。直接删除文件不会自动同步到版本库,因此需要额外的步骤来确保变更被正确记录。
删除文件的两种场景
- 确实要从版本库中删除该文件
-
- 使用
git rm
命令将文件从暂存区和工作区中删除,并提交更改。
- 使用
# 删除文件并提交
git rm file5
git commit -m "deleted file5"
- 误删文件
-
- 如果不小心删除了文件,可以使用
git checkout -- [file]
来恢复文件。
- 如果不小心删除了文件,可以使用
# 恢复误删的文件
git checkout -- file5
总结
git checkout
回退最近一次git reset
回退版本git rm
删除