从零开始的Git生活 | 刚实习同学的噩梦 And 参与开源不可缺的一环

一、Git初识

Git 是一个开源的分布式版本控制系统 ,用于敏捷高效地处理任何或小或大的项目。是 Linus Torvalds 为了帮助管理 Linux 内核 开发而开发的一个开放源码的版本控制软件 。Git 与常用的版本控制工具 CVS , Subversion 等不同,它采用了分布式版本库 的方式,不必服务器端软件支持

二、Git是如何诞生的

1.版本控制工具

我们知道Git本质上是一个版本控制工具,那么在搞清楚Git的诞生原因前,我们先了解下什么是版本控制工具吧。

(1)版本控制工具的本质作用

一言以蔽之,版本控制工具是用于管理文件变更历史的软件系统,核心功能如下。

追踪变化:记录谁在何时修改了什么内容

时光倒流:回退到历史任意版本

团队协作:多人并行开发合并代码

分支管理:同时开发多个功能版本

备份恢复:防止代码丢失

(2)版本控制演进史

第一代:本地版本控制

代表工具:RCS、SCCS

工作原理:在本地机器 上保存文件的不同版本,差异存储,版本号自动递增

工作方式:锁定文件→修改→解锁

缺陷:1.锁机制 导致无法对某个特定文件进行协同开发;2.无共享版本机制,其他开发者需要手动拷贝新版本到本机


第二代:集中式版本控制

代表工具:CVS、Subversion/SVN

工作原理:中央服务器 存放完整仓库,客户端只有工作副本

工作流程:连接服务器→检出代码→修改→提交到服务器

缺陷:1.所有版本与分支只存储在服务器 上;2.无法离线 工作,网络重度依赖,大数据量操作缓慢


2.分布式版本控制工具应运而生

经过上面关于版本控制演进史的讲述,大家已经对版本控制工具有了基本的了解。第二代集中式版本控制存在着单一存储和处处网络依赖两大问题,由此我们迎来了它的又一次迭代。

第三代:分布式版本控制

代表工具:Git

工具原理:每个开发者拥有完整的版本库 ,包含所有历史、所有分支、所有提交信息。提交通过快照 + 内容寻址 存储,分支是41字节的指针。

工作流程:本地修改→暂存→提交生成快照链,按需push/pull与远程同步

集中式与分布式的区别:

先前我们谈到了像SVN这种集中式版本控制工具的完整代码仓库只存在与中央服务器,每个开发者工作区只拷贝了最新版本的代码,当需要别的版本的代码时都需要从中央服务器拷贝,这就导致了中央服务器一旦被攻击或者宕机,其他开发者工作区就面临停工的麻烦。而像Git这种分布式版本控制工具,每个开发者的本地都存储着完整的版本库。

|-----------|----------|----------------|----------------|
| 维度 | 本地版本控制 | 集中式版本控制 | 分布式版本控制 |
| 代表工具 | RCS、SCCS | CVS、Subversion | Git、Mercurial |
| 核心架构 | 单机单文件锁定 | 客户端-服务器模式 | 点对点(P2P)分布式 |
| 版本库存储 | 本机单个文件差异 | 中央服务器完整仓库 | 每个开发者拥有完整仓库 |
| 工作模式 | 锁定→修改→解锁 | 连接→检出→修改→提交 | 本地开发→暂存→提交→推送 |
| 分支机制 | 无分支概念 | 复制目录(昂贵) | 指针引用(极廉价) |
| 离线能力 | 本地可用 | 完全依赖网络 | 完全离线操作 |
| 协作规模 | 1人(无法并行) | 数十人(串行锁定) | 无限(10,000+开发者) |
| 性能瓶颈 | 无网络延迟 | 严重(所有操作走网络) | 极快(本地操作0.1秒) |
| 数据安全 | 本机损坏即丢失 | 服务器故障全丢失 | 天然多节点备份 |
| 主要缺陷 | 无法多人协作 | 单点故障、网络依赖 | 学习曲线陡峭 |
| 适用场景 | 个人文档管理 | 企业内网小型团队 | 现代全球化开源/商业开发 |

三、Git安装

下载地址:Click Here

四、Git的三个分区

1.工作区

是项目目录中用户直接编辑文件的部分,包含当前正在修改但尚未提交到版本库的文件,反映本地文件系统的实际状态。

注:整个Git_Study文件夹除了.git隐藏文件夹,剩下的都是工作区

2.暂存区

暂存区是Git工作流程中的一个中间区域 ,用于临时存放即将提交的更改。工作区的修改添加到暂存区,形成待提交的快照 。暂存区的存在允许用户选择性提交部分修改,而非全部文件变动。

注:.git文件夹里面的index文件就是暂存区,只有git add命令后index文件才会出现。

3.版本库

版本库是Git存储项目历史记录的核心部分,包含所有提交的快照、分支、标签等元数据。通过命令,暂存区的内容会永久保存到版本库中,生成一个新的提交记录。版本库通常分为本地仓库 (位于项目.git目录)和远程仓库(如GitHub、GitLab等)。

注:整个.git文件夹就是版本库

五、Git相关命令

1.配置Git参数

原因:

1.每次提交代码时,Git会记录提交者的姓名和邮箱,这些信息会永久保存在版本历史中。

2.开源项目或企业开发通常要求提交者提供真实或可验证的身份信息,以确保代码贡献的透明性。未配置可能导致提交被拒绝或无法通过自动化检查(如CI/CD流程)。

3.全局配置(--global)会将用户名和邮箱应用于当前用户的所有仓库,无需在每个本地仓库单独设置,提升效率。

(1)设置全局用户名

java 复制代码
git config --global user.name <用户名> // 设置全局用户名
git config --global user.name // 查看全局用户名

(2)设置全局邮箱

java 复制代码
git config --global user.email <邮箱> // 设置全局邮箱
git config --global user.email // 查看全局邮箱

2.创建仓库

注意 :一般来说git clone 在协同开发的时候更为常用,它一次性完成了仓库初始化、远程关联和代码拉取。而git init通常需要额外步骤来关联远程仓库和提交代码。

(1)手动创建一个本地仓库

适用情形:

  • 从零开始一个新项目,尚未与任何远程仓库关联。
  • 将现有代码转换为 Git 仓库管理。
  • 需要在本地实验或测试某些功能,而不影响远程仓库
java 复制代码
git init // 在当前目录创建一个新的Git仓库,生成隐藏的.git文件夹用于存储版本控制数据。

注意:.git文件是隐藏的,需要在文件资源管理器中配置隐藏文件可见

(2)克隆远程仓库到本地

适用情形:

  • 需要获取远程仓库的完整副本(如 GitHub、GitLab 上的项目)。
  • 参与团队协作,直接基于现有代码库工作。
  • 快速获取开源项目或第三方代码库。
java 复制代码
git clone <远程仓库的url> // 克隆远程仓库到本地。

以Github上的开源项目代码随想录为例,复制远程仓库URL后进行git clone url,克隆成功后当前文件夹里面就有了开源项目leetcode-master。

3.基础版本控制

(1)查看文件状态

Git中文件大致有四种状态,第一种为未跟踪,后三种为已跟踪,这四种状态之间的转换构成了Git版本控制的核心:

  1. 未跟踪 (Untracked):文件在文件夹中,但没有加入到git库,不参与版本控制。
  2. 未修改Unmodified):文件已经入库,未修改,即版本库中的文件快照内容与文件夹中完全一致。
  3. 已修改Modified):文件已修改,但尚未放入暂存区。
  4. 已暂存 (Staged):对已修改的文件做了标记,包含在下次提交列表中
java 复制代码
git status // 查看工作区和暂存区的文件状态

(2)将工作区文件添加到暂存区

未跟踪 -> 已暂存

java 复制代码
git add <文件名> // 添加特定文件
git add . // 添加所有变更文件

最开始创建了一个1.txt文件,git status查看它状态为未跟踪

使用git add命令把它添加到暂存区,并再次git status查看状态

(3)提交暂存区文件到本地仓库

已暂存 -> 未修改

java 复制代码
git commit -m "提交信息" // 提交暂存区的变更到本地仓库,附带提交信息

提交暂存区的1.txt到本地仓库,再次git status查看此时工作区暂存区状态clean。

未修改 -> 已修改

此时再对1.txt文件进行修改,然后git status查看状态此时就是已修改状态

已修改 -> 已暂存

再用add指令添入到暂存区就又回到了暂存状态,接下来就是commit又变成未修改。

4.分支管理

(1)列出所有本地分支

每个分支就代表一条独立功能工作线,保证功能开发时互不影响。起始init出来的本地仓库只有一条master主分支,远程克隆出来的开源项目的分支通常有很多条别人之前创建的分支。通常协同开发的时候都是开发一条分支,测试一条分支...只在各自的分支上修改代码,并不直接再master上编码,master一般只有在测试通过后上线项目的时候用。

java 复制代码
git branch // 列出所有本地分支
git branch -r // 查看远程分支
git branch -a // 查看所有的本地分支和远程分支

(2)创建新分支

向开源项目提PR的时候也是一样不能直接在master主分支上修改,需要创建自己的分支。

java 复制代码
git branch <新分支的名字> // 创建新分支

创建新分支a1,并查看所有分支

(3)删除分支

主分支也可以删除,但需要谨慎操作,操作前必须备份代码。

java 复制代码
git branch -d <待删除的分支名字> // 删除分支

删除分支a1,并查看所有分支

(4)切换分支

创建了分支后,必须切换到相应的分支上操作才行,不然还是停留在master分支上修改

java 复制代码
git checkout <要切换的目标分支名字> // 切换到指定分支

切换到a1分支,注意最右边蓝色部分从master变为a1

(5)合并分支

该操作全称为合并分支到当前分支,通常是合并到主分支。例如你是某个开源项目的创始人,有其他开发者在他自己的分支上对你的开源项目进行改良后提出PR请求合并,那必须要到你的master分支上执行git merge命令,才是把他的分支合并到你的分支上。

java 复制代码
git merge <指定被合并的分支> // 将指定分支合并到当前分支

我想把a1的分支合并到master分支上,就要先checkout到master分支,再进行merge a1,Already up to date就是主分支和a1分支已经是同步了的。

5.远程仓库操作

(1)添加远程仓库

在参与开源时,这里的远程仓库通常不是真正的开源项目所在的仓库,而是你fork到自己远程仓库的URL。这个远程服务器可以有多个,当然名字要设置不一样的。

java 复制代码
git remote add <远程服务器别名> <远程仓库URL> // 添加远程仓库

通常远程服务器名字都写origin,当然也可以自定义名字,后续也可以对已配置远程服务器进行rename修改名字。这里以代码随想录开源项目为例,将其添加为远程仓库,并查看自己的远程仓库名字。

(2)查看远程仓库地址

java 复制代码
git remote -v // 查看远程仓库地址

通常有两个一个fetch抓取一个push推送地址,都是一样的

(3)推送本地提交到远程仓库

刚刚建立的分支在这里又用上了,在推送本地commit到版本库的代码的时候,可以自行指定分支,一般来说都是推送到自己建立的分支上而不是master分支。远程仓库名字跟刚刚一样一般都是origin。代码写完之后只存在你的本地,push操作就是让远程仓库里面也有你的代码相当于也做了备份。记得推送前一定要commit。

java 复制代码
git push <远程仓库名字> <指定分支名字> // 推送到指定分支

(4)拉取远程变更并合并

git pull <远程仓库名字> <指定分支>是一个组合命令,用于从远程仓库拉取指定分支的更新并合并到当前分支。其行为可以拆解为两个独立操作:git fetch和git merge。一般来说这个操作就是起到一个同步别人代码的作用,在协同开发的时候如果当别的开发人员修改了代码并推送到远程仓库的时候,需要你这边先pull进行合并更新,再进行自己这边的开发工作。

git fetch 的作用

git fetch <remote> <branch> 从远程仓库下载指定分支的最新提交记录和文件,但不会自动修改本地工作目录或当前分支。这些更新会存储在本地仓库的远程跟踪分支 (如 origin/<branch>)中,供后续操作使用。

git merge 的作用

git merge <remote>/<branch>远程跟踪分支 (如 origin/<branch>)的更新合并到当前本地分支。此操作会尝试自动整合更改,若存在冲突需手动解决。

注意:这里的推送代码冲突主要的产生原因就是多个开发者同时修改了同一位置的代码才会产生冲突。一般是在IDEA中发现被拒绝推送的警告,然后按照指示找到冲突位置,选择性拉取代码

java 复制代码
git pull <远程仓库名字> <指定分支> // 从远程仓库拉取指定分支的更新并合并到当前分支

6.撤销与日志

(1)查看提交历史

java 复制代码
git log // 查看提交的日志

(2)回退提交或取消暂存

java 复制代码
git reset <暂存区中的文件名> // 取消指定文件的暂存

先将2.txt文件add到暂存区

随后使用git reset命令取消暂存

git reset --hard <版本号>/<head~1>这个命令主要用于切换版本,有着撤销提交的强大效果,通常搭配git reflog或者git log查看版本号或者指针使用。版本号就是中间的一串长长的黄色码,如果用指针的话,head表示正在使用的版本,那么head ~ n就是表示回到前n个版本。

java 复制代码
git reset <版本号>/<head~1> // 切换版本/回退到前一个版本

先使用git log查看中间黄色的一串码,以及当前的提交记录,此时我想要回退到只提交了1.txt的版本号中就使用git reset <提交1.txt时候的版本号>即可

可见reset过后提交日志里面就只有1.txt了,原本提交的2.txt和3.txt现在都变成了未追踪的状态。但是要注意这两个文件并没有被删除,相当于它只是撤回了你的提交,但没有删除你的代码。

java 复制代码
git reset --hard <版本号>/<head~1> // 切换版本同时把该版本后的代码都删除掉

我如果加了参数--hard,那么大家可以看到我再次git log,它不仅撤回了提交,打开文件夹发现工作区里面的2.txt和3.txt文件也都被删除了。

7.标签管理

(1)创建轻量标签

通常每次开发到一个标志性阶段,也就是一个新的版本就打一个标签

java 复制代码
git tag <name> // 创建轻量标签

六、总结

对于大部分在校生而言git命令都是不熟悉的,很多刚实习的同学想必深有体会。这不是因为git命令有多难,而是因为大家缺乏协同开发的相关经验,对于有过实习经历经常写git命令的同学会发现常用的也就那几个,所以说大家不需要害怕,推荐参与开源项目,这个过程也可以让你不断熟悉git命令。

相关推荐
不老刘2 小时前
Git Cherry-Pick:微前端架构下的“精准医疗”与最佳实践
前端·git
南国微雪3 小时前
记一次神奇的光猫改桥接经历
生活
爬楼的猪3 小时前
Git Folder Dashboard
git
Uncertainty!!3 小时前
claude code中添加skills自动生成git commit信息
git·git commit·claude code
FserSuN5 小时前
Git Worktree 使用学习
git·学习
Z文的博客5 小时前
嵌入式LINUX QT 开发 .gitignore 文件编写指南
linux·git·qt·elasticsearch·嵌入式
前端双越老师5 小时前
3 个命令 7 个步骤,学会 git worktree 并行开发
git·ai编程·全栈
小黑要努力20 小时前
智能音箱遇到的问题(一)
linux·运维·git
RePeaT20 小时前
【git】指令场景实战:单分支与多分支协作流程
git