Git与GitHub的核心定义及视频课程架构

Git和GitHub是AI编程时代不可或缺的两个工具,尽管在以往的开发中它们就至关重要。Git是一个软件,用来记录代码版本;当项目进展到特定阶段时,通过Git保存当时的代码状态。这样做的核心目的是在后续修改导致错误时,能够随时退回到之前存过的那个版本。相比之下,GitHub是一个网站平台,主要功能包括备份代码版本、支持多人协作开发以及公开分享源码。即使电脑硬件损坏,存储在GitHub上的数据也不会丢失。

本期视频旨在系统性地梳理这两个工具的核心功能,内容分为四个主要部分:Git的安装、存档和回滚机制、分支与合并策略以及GitHub的相关操作。视频涵盖了从基础安装到高级应用的全流程,确保学习者能够掌握Git和GitHub的完整工作流。为了方便学习,所有示例代码已上传至作者的GitHub仓库供下载。

Windows与macOS系统的Git安装指南

对于Windows用户,安装过程相对标准化。首先访问官方网站并点击“Install for Windows”,下载完成后运行安装包。安装方法跟普通软件类似,一路点击Next即可。在安装最后一步,建议取消勾选“View Release Notes”,因为发布记录对实际操作价值不大。安装完成后,通过开始菜单搜索并打开“Git Bash”,输入命令git --version。如果终端返回具体的版本号,则说明安装成功。若未显示版本信息或报错,则需要检查环境变量配置。

macOS用户的安装情况较为复杂。许多软件依赖Git,因此可能已预装或随其他工具一并安装。在终端输入git --version后,如果直接显示版本号,则无需额外操作。若提示需要安装Xcode命令行开发者工具,则需要点击Dock栏弹出的图标进行安装。这套开发工具箱包含编译器、调试器等必备组件。建议按照提示将这一整套全家桶安装完成,随后再次执行git --version确认版本号显示正常。至此,不同操作系统的Git环境均搭建完毕。

项目初始化与工作区、暂存区的概念解析

为了演示Git的工作流程,准备了一个名为“马克待办”的简单项目文件夹。该目录包含两个文件:index.html(约100多行代码的待办页面)和README.md(项目说明文档,目前内容为半成品)。虽然文件扩展名不同,但本质上都是普通文本文件。在开始版本管理前,项目尚未被Git追踪,这意味着任何修改都难以回退。因此,第一步是使用终端进入该目录(使用cd命令),然后执行第一个Git命令:git init。该命令的作用是将当前目录初始化为一个Git仓库,使其具备版本管理能力。

执行git init后,系统会在当前目录下创建一个名为.git的隐藏文件夹。这个文件夹存储了所有与Git相关的数据,包括版本记录。虽然仓库是“空”的(指没有保存任何提交历史),但.git内部已包含初始化所需的文件结构。为了直观理解Git的运作机制,需要引入三个核心区域的概念:工作区(Working Directory)、暂存区(Staging Area)和提交历史(Commit History)。工作区包含用户实际编辑的文件;暂存区用于临时存放准备提交的内容;提交历史则保存最终的版本快照。这种分层设计允许开发者一点一点地挑选出下一次要提交的内容,而不是盲目地将所有更改一次性打包。

版本提交的完整流程:从add到commit

将代码保存为版本的過程分为两步。首先,使用git add <filename>命令将文件内容复制到暂存区。在本例中,仅对index.html执行此操作,因为README.md尚未完成。暂存区的存在使得开发者可以精细控制哪些文件进入下一个版本。执行完git add index.html后,通过git status查看状态。此时终端会显示“Changes to be committed”区域列出了index.html,表明该文件已进入暂存区;而README.md仍位于“Untracked files”中,未被跟踪。

在提交之前,必须配置用户身份信息。Git每次commit都会记录作者信息,因此需执行`git config --global user.name

Git 提交流程与版本记录

Git 的核心操作遵循工作区、暂存区到提交历史的流转逻辑。以 index.html 和 README.md 为例,开发者需先执行 git add 将文件改动记录至暂存区,随后通过 git commit 基于暂存内容创建新的提交(commit)。这一过程确保了项目历史的完整记录。例如,在完善 README.md 后执行 git add,再通过 git status 确认文件从 "Untracked files"(未跟踪)变为 "Changes to be committed"(待提交),即表明文件已进入暂存区。执行 git commit 后,Git 会在提交历史中生成新节点。

"简单来说 就是先用 git add 命令 把工作区里面准备保存的内容 记录到暂存区 然后再用 git commit 命令 根据暂存区的内容 在提交历史里面创建一个 commit"

通过 git log 可查看完整的提交记录,确认当前存在两条 Commit:最新一条对应 README.md,前一条对应初始的 index.html。这种阶段性成果记录机制使得项目历史有据可查,为后续的回溯和回滚奠定基础。每次完成阶段性工作重复此流程,Git 便会逐步保存项目状态。

回滚场景一:工作区未暂存的修改

当代码修改仅存在于工作区(Working Directory/Tree)且尚未执行 git add 时,Git 状态显示为 "Changes not staged for commit"。此时若发现修改错误(如将页面改为深色主题),可通过 git restore 命令撤销工作区改动。

"使用 git restore 可以撤销工作区的改动"

执行 git status 时,Git 会提示 "discard changes working directory"(丢弃工作区更改),这正是回滚所需的操作。对于单个文件,直接指定文件名即可;若需同时回滚多个文件或当前目录下所有改动(尤其在 AI 批量生成代码场景下),可使用 git restore .,其中 . 代表当前目录。执行后再次检查状态为 "nothing to commit, working tree clean",页面恢复至浅色主题,证明工作区改动已彻底清除。注意区分 "working directory" 与 "working tree",二者均指代工作区。

回滚场景二:已暂存但未提交的修改

若执行了 git add,改动进入暂存区(Staged),状态变为 "Changes to be committed"。此时直接回滚工作区无效,因为 Git 记录中已包含该改动。正确的步骤是分两步走:首先从暂存区移除,再清除工作区。

"运行 git restore --staged 的命令 就可以把这部分改动 从暂存区里面去掉"

第一步执行 git restore --staged .(或指定文件),将改动从暂存区撤出,此时状态变回 "Changes not staged for commit"。需注意的是,文件内容本身未变(仍为深色主题),仅 Git 的追踪状态改变。第二步执行 git restore .,清除工作区的修改。此时再次检查,暂存区和工作区均无改动,页面恢复原状。此流程强调了Git 数据记录与文件实际内容的分离性:先解除暂存关联,再丢弃物理修改。

回滚场景三:已提交的 Commit

当改动已通过 git commit 提交至历史,形成新的 Commit(如第三个 Commit),回滚需针对提交历史操作。直接思路是删除该 Commit 并确保暂存区和工作区无残留改动。首先确认 HEAD 指向最新的提交(通过 git log 可见第三个 Commit)。随后执行特定命令移除该 Commit。

"HEAD 代表的就是 提交历史里面最新的 commit"

虽然文中未完整展示删除命令的最终执行结果,但明确了 HEAD 的概念及其指向性。在已提交的情况下,回滚涉及对历史记录的干预,需确保后续操作能清理暂存区和工作区的关联状态。这一场景区别于前两种仅涉及文件状态的操作,直接作用于版本历史树。

Git回滚机制:理解HEAD与Reset命令

在Git中,HEAD指针始终指向当前最新的提交(commit)。随着新提交的产生,HEAD会随之移动,而之前的提交则可以通过HEAD~1、HEAD~2等相对引用进行标识。当我们需要撤销最近的提交时,可以使用git reset HEAD~1命令将HEAD指向前一个状态。然而,仅移动指针并不足以完全恢复环境,因为Git包含工作区、暂存区和提交历史三个区域。--hard选项的作用是让这三个区域全部回滚到指定commit的状态。这意味着,无论是已提交的历史、暂存区的改动还是工作区未提交的修改,都会被彻底清除。执行该命令后,之前的提交将从历史中消失,且本地文件内容也会恢复到对应版本。由于这种操作具有不可逆的破坏性,执行前务必通过git status确认工作区安全。

三种Reset模式:Mixed与Soft的应用场景

除了彻底的--hard,Git还提供了更精细的控制选项。默认模式是--mixed,它仅回滚暂存区和提交历史,而将改动保留在工作区中。这意味着你可以撤销一次错误的commit,但代码修改仍在本地,方便你修正后重新提交。--soft模式则更为温和,它只回滚提交历史,同时保留工作区和暂存区的内容。这两种模式适用于在commit后发现小错误需要调整的情况:你可以撤销提交,修改代码或暂存内容后再次commit。相比之下,如果你确定不需要某些改动并希望其彻底消失,则应使用--hard。理解这三种模式的区别,关键在于明确回滚操作影响的区域范围不同。在实际开发中,合理使用--mixed或--soft可以避免数据丢失的风险。

安全回滚策略:Revert命令的优势

除了通过移动指针来“删除”提交,Git还提供了另一种更安全的回滚方式:git revert HEAD。该命令不会删除原有的commit,而是创建一个新的提交,其内容与原提交完全相反。例如,如果原提交增加了深色主题代码,新提交则会删除这些代码以恢复浅色背景。这种方式保留了完整的提交历史,便于追溯和审计。执行git revert时,Git会进入Vim编辑器界面展示默认的提交信息,其中包含“Revert”字样及被回滚commit的ID。用户可直接保存退出(:wq),Git将自动生成抵消性提交。这种方法的优点在于历史完整,即使未来需要恢复之前的状态,也能从历史记录中找到原始commit。虽然操作看似繁琐(需生成新提交),但它避免了直接修改历史带来的潜在风险,特别适合团队协作场景。

版本控制细节:.gitignore与分支概念

并非所有文件都需要被Git跟踪。对于个人笔记(如notes.txt)或系统生成的临时文件(如macOS的.DS_Store),可以通过创建.gitignore配置文件来忽略它们。将这些文件名写入该文件后,Git将不再监控其变化,也不会将其列入未跟踪列表。值得注意的是,.gitignore本身应被提交到仓库中,以便团队成员共享忽略规则。分支(Branch)本质上是一个指向commit的标签,如默认的master或main分支。每次提交时,该指针会自动移动到最新commit上。理解这一机制有助于掌握后续复杂的分支操作与合并策略,确保代码管理的灵活性与安全性。

为何需要分支隔离:保护 Master 主线的稳定性

在软件开发中,Master(或 Main)分支通常被视为项目的稳定主线。如果直接在 Master 上逐步提交未完成的功能代码,会导致主分支长期处于“半可用”甚至报错的状态。例如,在开发截止时间功能时,若分三个 Commit 提交:前端界面、保存逻辑和过期提醒。在第一个 Commit(仅含前端)完成后,用户若点击未实现的保存逻辑按钮,产品就会报错。这种不稳定的状态违背了主分支应“相对稳定可正常使用”的原则。

“master 或者是 main 分支...大家一般会希望这个分支上面的代码是相对稳定可以正常使用的,而不是长期放着一堆只做了一半还不能够正常工作。”

因此,更常见的做法是基于稳定的 Master 创建新分支。这样,在开发过程中,Master 保持原状不受影响;所有新功能相关的 Commit 仅存在于新分支中。只有当功能开发完成并测试通过后,才将新分支合并回 Master。本质上,合并过程是将 Master 的标签向前移动到新分支相同的位置。

分支操作实战:创建、切换与验证逻辑

Git 中创建新分支的命令为 git branch <branch_name>。教程中使用 feature/due-date 作为分支名,其中 feature/ 前缀用于标识新功能开发,斜杠无特殊含义但有助于团队规范。执行创建命令后终端无返回属正常现象,需通过 git branch(不加参数)列出所有分支来确认。星号 (*) 标记当前所在分支,创建新分支后默认仍停留在 Master。

切换至新分支可使用 git switch <branch_name>。实际开发中,常使用 git switch -c feature/due-date 一步完成创建并切换,其中 -c 代表 create。虽然老版本教程常用 git checkout -b,但 Git 官方推荐更清晰的 switch 命令。需注意的是,创建分支瞬间代码并无变化,因为新分支指向与 Master 相同的最新 Commit。只有在新分支上提交新的 Commit 后,两者才会产生差异。

功能开发与隔离验证:Commit 的历史记录分析

在 feature/due-date 分支上,开发者完成了三个阶段的提交:添加截止时间界面、保存逻辑及过期提醒。通过 git log --oneline 命令,可以简洁地查看提交历史。该选项仅显示 Commit ID 前几位和说明,便于快速浏览。此时观察日志发现:feature/due-date 指向最新的“增加过期提醒” Commit,而 Master 仍停留在之前的状态。

“feature/due-date 比 master 多出了三个 commit...换句话说,这三个 commit 只属于 feature/due-date,在 master 上面是看不到的。”

切回 Master 分支验证时,页面中日期选择框消失,功能未受影响。这证明了在新分支开发期间,Master 始终独立且稳定。当新功能验证无误后,执行 git merge 将新分支合并入 Master。合并成功后,Master 和 feature/due-date 指向同一个 Commit,代码完全一致。最后可使用 git branch -d feature/due-date 删除已合并的分支,保持仓库整洁。

冲突场景解析:多分支并行开发的常见陷阱

在实际开发中,多个功能分支同时基于 Master 创建并修改同一文件时极易引发冲突。教程构建了“排序”和“全部完成”两个功能分支。两者均基于 Master,且都试图在 index.html 中“添加”按钮下方的同一位置插入新代码。排序分支插入了排序逻辑,全部完成分支插入了全选按钮。Git 无法自动判断该保留哪一方或如何排列,导致 Automatic merge failed。

“Git 到这就懵了...它面前是同一个位置,两份不同的内容...那到底该放哪一个呢?还是说两个都放?”

执行 git status 会显示 Unmerged paths,提示文件两边都被修改。打开冲突文件(如 index.html),可见 Git 插入的标记符号: - <<<<<<< HEAD:当前分支(Master,已合并排序)的代码。 - =======:分隔符。 - >>>>>>> feature/complete-all:待合并分支(全部完成)的代码。

解决冲突需手动编辑文件,删除标记符号并保留双方所需内容(即两个按钮都留下)。修改完成后,执行 git add 和 git commit 即可完成合并。若不想处理冲突,可执行 git merge --abort 放弃此次合并。

Git 分支操作命令速查表

操作场景 推荐命令 (Git Switch) 备选/旧版命令 (Checkout) 说明
创建并切换分支 git switch -c <branch_name> git checkout -b <branch_name> -c 代表 create,一步到位
仅创建分支 git branch <branch_name> N/A 不切换上下文,需后续 switch
查看当前分支 git branch (无参数) N/A 星号(*)标记当前所在分支
切换至指定分支 git switch <branch_name> git checkout <branch_name> 仅改变工作区指向
删除已合并分支 git branch -d <branch_name> N/A -d 代表 delete,安全删除
查看简洁日志 git log --oneline N/A 单行显示 ID 前缀和提交信息
放弃合并 N/A (需先 abort) git merge --abort 在冲突解决前撤销合并操作
查看未合并文件 git status (冲突时) N/A 显示 Unmerged paths,提示 fix conflicts

解决合并冲突与理解 Fast-Forward

在 Git 分支合并过程中,若两个分支修改了同一行代码,Git 无法自动决定保留哪一方内容,从而产生冲突。处理此类冲突需手动编辑文件以解决标记行(如 HEAD、中间分隔线及分支名),保存退出后,必须执行 git add 将改动加入暂存区,随后通过 git commit 完成提交。> “要先解决冲突,然后再执行 git commit 命令”。只有当工作区干净(nothing to commit, working tree clean)时,才代表合并操作彻底完成。

两次合并行为的差异源于Fast-Forward(快进)机制。第一次合并非 Fast-Forward 模式,因为排序分支直接基于当前 master 节点后续提交,master 只需指针前移即可覆盖,无需创建新 commit。第二次合并时,由于 master 已前进至排序分支末端,而全部完成分支基于更早的节点创建,两者存在分歧。此时 Git 无法简单快进,否则将丢失排序分支的提交记录。

Rebase:重构分支地基以预防冲突

为避免在开发周期较长时(如几周)才面临大量合并冲突,推荐采用 Rebase 策略。该操作旨在将功能分支的“地基”(即起始 commit)重新定位到 master 的最新位置之后,使功能分支看起来像是基于最新代码开发的。> “rebase就是给分支重新换一个地基”。

实际操作中,需先回退项目状态至合并前。执行 git rebase master 后,Git 会将功能分支上的每个 commit 逐个应用到新的地基上。若过程中出现冲突(如两个按钮插入位置重叠),需手动解决并执行 git rebase --continue 而非普通的 commit。这一过程会弹出版本说明编辑器,确认后即可继续迁移剩余提交。

通过 Rebase 解决冲突后再次合并 master,由于分支已接在最新节点之后,Git 会执行 Fast-Forward 合并。此时 master 指针直接前移至功能分支末端,无需生成新的合并 commit,从而保持提交历史线性整洁。这种“随时同步 master”的做法能提前暴露兼容性问题,避免最后时刻的大规模返工。

Stash:临时存储未完成的开发进度

当开发者在功能分支上编写代码但未完成(如仅写了函数框架),却需紧急切换至 master 修复 Bug 时,直接 git checkout 会导致本地未提交改动被覆盖。Git 报错提示提供两条路径:> “commit your changes”或“stash them”。

对于半成品代码,提交会污染历史;因此应使用 Stash 功能。该命令将工作区和暂存区中所有未提交的改动(即 WIP, Work In Progress)打包隐藏。执行 git stash 后,文件恢复至上一次提交状态,此时可安全切换分支。Stash 不仅处理工作区改动,也包含暂存区(Index)内容。

“已经把工作区和暂存区里面还没有提交的改动保存起来了”。

待 master 分支修复完成后,切回原功能分支即可通过 git stash pop(或 apply)取回之前的开发进度,继续未完成的工作。这一机制确保了在紧急任务切换时,本地未提交的中间状态不会丢失或被意外覆盖。

利用 Stash 临时保存未完成的代码

在开发过程中,当需要切换分支处理紧急任务时,Git Stash 命令可以将当前未提交的改动暂时收起,使工作区恢复干净状态。执行 git stash 后,通过 git status 确认工作区和暂存区无未提交改动,且编辑器中之前写了一半的代码消失,文件回到上一次提交的模样。此时工作区已清空,可以安全地切换分支或执行其他操作。

“git stash 命令已经执行成功了……所有还没有提交的改动都被收起来了。”

当紧急任务处理完毕,需要回到之前的开发进度时,执行 git stash pop 命令即可将之前保存的改动取回工作区。该操作会将代码恢复到暂存前的状态,通过 git diff 可以验证之前的半成品(如未完成的函数)已重新出现。这种方式非常适合临时打断开发去处理其他任务,随后快速恢复现场的场景。

配置SSH密钥以验证身份

在将本地代码推送到GitHub之前,必须首先建立安全的身份认证机制。用户需要在终端中使用 cat 命令查看公钥文件内容,并将其完整复制。SSH密钥配置的核心在于将本地生成的公钥上传至GitHub服务器,以便后续操作无需重复输入密码。具体步骤包括:登录GitHub账户,点击右上角头像进入Settings,在左侧菜单找到SSH and GPG keys选项,点击New SSH key并将公钥粘贴至文本框中保存。

完成添加后,需在终端执行连接测试命令。首次连接时系统会提示确认主机身份,输入yes回车即可建立信任关系并结束询问。出现成功连接提示即表明SSH Key配置生效,此后GitHub便能利用该公钥验证用户身份。这一过程确保了本地机器与远程仓库之间的通信安全,是后续所有Git操作的基础前提。

创建GitHub仓库并初始化推送配置

身份验证完成后,下一步是在云端建立代码托管空间。用户需进入GitHub页面的Repositories选项卡,点击右上角New按钮创建新仓库。仓库名称建议使用英文(如MarkTodo),中文描述可填入Description字段,同时根据隐私需求选择Public或Private可见性。为保持本地代码纯净,创建时不勾选Add README、.gitignore或License等初始化选项。

仓库创建成功后,GitHub页面会提供三条命令行提示。第一条命令用于将远程仓库地址关联为 origin,这是Git的命名习惯,便于后续引用而非每次输入长串URL。第二条命令涉及分支重命名(master改main),本例中因本地使用master故跳过。第三条命令负责首次推送,但需注意分支名称匹配问题。执行 git push -u origin master 可将本地master分支推送到远程origin仓库,其中 -u 参数建立了本地与远程的绑定关系。此后日常推送仅需执行简短的 git push 命令,极大简化了操作流程。

日常开发流程与数据恢复验证

完成首次推送后,本地代码的历史记录及文件结构已完整同步至GitHub。日常开发遵循“修改-暂存-提交-推送”的标准闭环。核心命令序列为 git add、git commit 和 git push,确保本地变更及时同步至云端备份。执行提交后,可通过 git status 检查状态;若提示“Your branch is ahead of origin/master by N commit”,说明本地有新提交尚未上传,此时执行 git push 即可同步。

为验证备份有效性,可模拟本地数据丢失场景。删除本地项目文件夹后,通过 git clone 命令从GitHub拉取代码。克隆时需指定SSH地址及本地目标文件夹名称,例如 git clone <url> MarkTodo。恢复后的项目不仅包含所有源文件(如index.html),还完整保留了Git提交历史。GitHub的备份机制确保了即使本地设备损坏,项目数据仍可通过远程仓库完整找回,体现了版本控制在数据安全方面的核心价值。

结论

Git通过工作区、暂存区和提交历史的三层架构,实现了代码版本的精细化管理与安全回滚。其核心优势在于分支隔离机制能有效保护主线的稳定性,避免半成品代码污染生产环境;配合Rebase与Stash策略,开发者可在保持历史整洁的同时灵活应对紧急任务切换。GitHub作为云端平台,提供了可靠的代码备份与协作基础。

然而,并行开发中的合并冲突仍需人工介入解决。尽管Rebase能预防部分冲突并维持线性历史,但操作复杂度较高;而git revert虽保留完整审计轨迹,却增加了提交数量。总体而言,掌握这些工具能显著提升开发效率与数据安全性,但需严格遵循规范以规避人为失误。