04|保存文件变动:提交代码的 2 步核心流程
04|保存文件变动:提交代码的 2 步核心流程
大家好,我是小林。
你在写一篇重要的文章,写了一段后觉得不错,想要保存这个进度。但传统的保存方式只能覆盖之前的版本,如果后面写得不好,想要回到这个"不错"的版本,却发现已经无法回去了。如果能为文件创建多个快照,每个快照都能随时回到,那该多好啊! 今天,我们就来学习Git最核心的功能:如何保存文件的变动,让你永远不用担心丢失好的版本!
4.1 暂存文件:git add
现在你已经学会了创建Git仓库和查看文件状态,接下来我们要学习Git的第一个核心操作:git add
。这个命令的作用是把文件的修改添加到暂存区,为提交做准备。
让我们先创建一个练习环境。在你的项目文件夹中,创建一个简单的文本文件:
echo "这是我的第一个文件" > hello.txt
现在运行git status
查看状态,你会看到hello.txt显示为"未被追踪的文件"。接下来,使用git add
命令:
git add hello.txt
再次运行git status
,你会发现hello.txt的状态变成了"Changes to be committed",文件名变成了绿色。这意味着文件已经被成功添加到暂存区,准备提交了。
git add 的多种用法
git add
命令有几种不同的用法,每种用法适用于不同的场景。让我们用一个图示来清晰展示这些用法:
flowchart TD
A[git add 命令用法] --> B[添加单个文件]
A --> C[添加多个文件]
A --> D[添加当前目录修改]
A --> E[添加所有修改]
B --> B1[git add filename<br/>git add hello.txt]
C --> C1[git add file1 file2<br/>git add index.html style.css]
D --> D1[git add .<br/>当前目录及子目录]
E --> E1[git add -A<br/>整个仓库]
这个图示展示了git add
的不同用法:
- 添加单个文件:
git add 文件名
,比如git add hello.txt
- 添加多个文件:
git add 文件1 文件2 文件3
,可以同时添加多个指定文件 - 添加所有修改:
git add .
,添加当前目录下所有修改的文件 - 添加所有修改(包括子目录):
git add -A
,添加整个仓库中所有修改的文件
让我们来练习一下。创建多个文件并修改它们:
echo "HTML内容" > index.html
echo "CSS样式" > style.css
echo "更多内容" >> hello.txt
现在运行git status
,你会看到有新的文件和修改的文件。你可以选择性地添加它们:
git add hello.txt # 只添加hello.txt的修改
git add index.html style.css # 添加两个新文件
暂存区的实际意义
你可能会问,为什么要有一个暂存区呢?为什么不能直接提交所有修改?让我用一个实际的例子来说明。
假设你在开发一个网页项目,同时修改了三个文件:
- index.html:添加了一个新的功能
- style.css:修复了一个样式问题
- readme.txt:添加了一些注释
现在你想要提交,但只想要提交index.html的新功能和style.css的样式修复,而不想提交readme.txt的注释(因为注释还没写完)。这时候暂存区就派上用场了:
git add index.html style.css # 只暂存想要提交的文件
git commit -m "添加新功能并修复样式" # 提交时只包含暂存的文件
readme.txt的修改会保留在工作区中,不会被提交,你可以继续编辑它。
让我们用一个图示来展示暂存区的选择性提交功能:
flowchart LR
A[工作区文件] --> B[index.html<br/>新功能]
A --> C[style.css<br/>修复样式]
A --> D[readme.txt<br/>注释未完成]
B --> E[暂存区]
C --> E
D -.->|暂不提交| F[保留在工作区]
E --> G[提交版本1<br/>包含HTML+CSS]
F --> H[后续版本<br/>可单独提交]
这个图示展示了暂存区如何实现选择性提交:你可以选择哪些文件要立即提交,哪些文件要留到后续提交,这样可以保持每个提交的主题明确和逻辑完整。
4.2 提交版本:git commit -m
文件添加到暂存区后,下一步就是提交了。git commit
命令会创建一个新的版本快照,永久保存暂存区中的文件状态。
基本提交语法
提交的基本语法是:
git commit -m "提交说明"
这里的-m
参数表示"message",也就是提交说明。提交说明非常重要,它告诉其他开发者(以及未来的你)这次提交做了什么。
一个好的提交说明应该:
- 简短明了,通常不超过50个字符
- 准确描述这次提交的主要内容
- 使用祈使句,比如"添加功能"而不是"添加了功能"
让我们来实际提交一下:
git commit -m "初始版本:添加项目基础文件"
提交后,Git会显示一些信息,包括提交的哈希值、作者信息、提交时间和提交说明。
查看提交历史
提交完成后,你可以使用git log
命令查看提交历史:
git log --oneline
你会看到类似这样的输出:
1a2b3c4 (HEAD -> main) 初始版本:添加项目基础文件
这里的1a2b3c4
是提交的哈希值,它是每个提交的唯一标识符。
忘记加 -m 会怎么样?
有时候你可能会忘记加-m
参数,直接输入git commit
。这时Git会打开一个文本编辑器(通常是Vim或Nano),让你在编辑器中输入提交说明。
如果你不熟悉这些编辑器,可能会不知道如何保存和退出。这里有几个常见的解决方案:
- Vim编辑器:按
i
进入编辑模式,输入说明后按ESC
,然后输入:wq
保存退出 - Nano编辑器:直接输入说明,按
Ctrl+X
,然后按Y
确认保存 - 取消提交:如果不想提交了,可以删除所有内容后保存退出,Git会取消这次提交
为了避免这种情况,建议养成总是使用git commit -m "说明"
的习惯。
4.3 常见错误
在使用git add
和git commit
的过程中,初学者经常会遇到一些错误。让我来为你介绍最常见的几个错误以及解决方法。先来看看常见错误及其解决方法:
flowchart TD
A[常见错误] --> B[忘记git add]
A --> C[提交说明错误]
A --> D[暂存错误文件]
B --> B1[git status提示nothing to commit]
B1 --> B2[解决:先git add再提交]
C --> C1[说明写错或不清晰]
C1 --> C2[解决:git commit --amend]
D --> D1[不小心暂存不想提交的文件]
D1 --> D2[解决:git reset HEAD 文件名]
这个图示展示了常见错误及其解决方案,帮助你在遇到问题时快速找到解决方法。
忘记添加文件就提交
这是一个很常见的错误:你修改了文件,但忘记使用git add
就直接提交了。这时Git会提示"nothing to commit",因为暂存区是空的。
git status
# On branch main
# Changes not staged for commit:
# modified: hello.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
解决方法很简单:先使用git add
添加文件,然后再提交。
提交说明写错了
提交后发现说明写错了怎么办?如果这个提交还没有推送到远程仓库,你可以使用git commit --amend
来修改提交说明:
git commit --amend -m "正确的提交说明"
这个命令会打开一个编辑器,让你修改最后一次提交的说明。修改后,新的提交会替换原来的提交,但提交的哈希值会改变。
注意:如果提交已经推送到远程仓库,使用--amend
可能会造成问题,因为会改变提交历史。在团队协作中要谨慎使用。
暂存了错误的文件
有时候你可能会不小心暂存了不想提交的文件。这时可以使用git reset
命令将文件从暂存区移除:
git reset HEAD 文件名
比如,你不想提交hello.txt的修改:
git reset HEAD hello.txt
这样hello.txt会从暂存区回到工作区,保持修改状态但不被提交。
4.4 查看修改内容:git diff
在提交之前,你可能想要查看一下具体的修改内容。git diff
命令就是用来查看文件差异的。让我们通过图示来理解git diff的不同用法:
flowchart TD
A[git diff 命令] --> B[git diff]
A --> C[git diff --cached]
A --> D[git diff HEAD]
B --> B1[工作区 vs 暂存区<br/>查看未暂存的修改]
C --> C1[暂存区 vs 版本库<br/>查看即将提交的内容]
D --> D1[工作区 vs 版本库<br/>查看所有修改]
这个图示清晰地展示了git diff
的不同用法和作用范围。
查看工作区与暂存区的差异
git diff
命令会显示工作区中未被暂存的修改:
git diff
输出会显示哪些行被添加了(以+开头),哪些行被删除了(以-开头)。
查看暂存区与版本库的差异
如果你想要查看暂存区中的修改(即将要提交的内容),可以使用:
git diff --cached
这个命令在提交前很有用,可以让你确认要提交的内容是否正确。
实际使用示例
让我们来实际操作一下。首先修改hello.txt文件:
echo "添加新的一行" >> hello.txt
现在运行git diff
,你会看到文件的具体修改。然后添加到暂存区:
git add hello.txt
再运行git diff --cached
,查看即将提交的修改。确认无误后,就可以提交了:
git commit -m "添加新行到hello.txt"
常见问答
Q1: git add . 和 git add -A 有什么区别?
这是很多初学者都会混淆的问题。让我来为你解释清楚。
git add .
只会添加当前目录及其子目录中的修改,而git add -A
会添加整个仓库中所有目录的修改。对于大多数项目来说,这两者的效果是一样的,因为通常我们都在项目根目录下操作。
但如果你在项目的子目录中运行命令,git add .
只会添加该子目录中的修改,而git add -A
仍然会添加整个项目的修改。为了避免混淆,建议总是在项目根目录下操作,或者直接使用git add -A
。
Q2: 什么时候应该提交代码?
这个问题问得很好!提交的频率和时机会影响版本历史的质量。
一般来说,当你完成一个逻辑完整的功能单元时应该提交。这个功能单元可以是一个完整的功能实现、一个bug修复、或者一个代码重构。
提交的粒度要适中:不要太小(比如每修改一行就提交),也不要太大(把所有修改都放在一个提交里)。一个好的提交应该有一个明确的主题,相关的修改应该放在一起。
在实际开发中,建议在每天结束工作前提交一次,确保当天的工作不会丢失。同时,切换到其他任务前也应该先提交当前的工作。
Q3: 提交说明应该怎么写才好?
提交说明的写法确实很重要,好的提交说明能让其他人(以及未来的你)快速理解每个提交的目的。
好的提交说明应该简短明了,通常不超过50个字符。使用祈使句,比如"添加用户登录功能"而不是"添加了用户登录功能"。准确描述这次提交的主要内容,不要写"修复bug"这样模糊的说明,而要写"修复用户登录时的验证错误"。
如果需要详细说明,可以在第一行简短描述后空一行,然后添加详细说明。但大多数情况下,一行简短的说明就足够了。
Q4: 可以修改已经提交的内容吗?
可以,但需要谨慎操作。如果提交还没有推送到远程仓库,你可以使用git commit --amend
来修改提交说明或添加漏掉的文件。
如果已经推送到远程仓库,修改提交历史会造成问题,因为其他开发者可能已经基于你的提交进行了工作。在这种情况下,最好的做法是创建一个新的提交来修正问题,而不是修改历史。
练习题
练习 1:完整的提交流程
创建一个新文件,修改它,然后完成完整的提交流程:
echo "练习内容" > practice.txt
echo "添加新内容" >> practice.txt
# 完成添加和提交操作
答案
完整的提交流程如下:# 创建文件
echo "练习内容" > practice.txt
# 第一次修改
echo "添加新内容" >> practice.txt
# 查看状态
git status
# 添加到暂存区
git add practice.txt
# 提交
git commit -m "添加练习文件和初始内容"
# 再次修改
echo "更多内容" >> practice.txt
# 查看修改内容
git diff
# 添加并提交
git add practice.txt
git commit -m "向练习文件添加更多内容"
这个过程展示了Git的基本工作流程:修改文件→添加到暂存区→提交到版本库。
练习 2:选择性提交
创建三个文件,但只提交其中两个:
echo "文件1" > file1.txt
echo "文件2" > file2.txt
echo "文件3" > file3.txt
# 只提交file1.txt和file2.txt
答案
选择性提交的方法如下:# 创建三个文件
echo "文件1" > file1.txt
echo "文件2" > file2.txt
echo "文件3" > file3.txt
# 查看状态,确认有三个未被追踪的文件
git status
# 只添加file1.txt和file2.txt
git add file1.txt file2.txt
# 再次查看状态,确认只有前两个文件被暂存
git status
# 提交
git commit -m "添加file1和file2"
# 确认file3.txt仍在工作区中未被追踪
git status
这个练习展示了暂存区的作用:你可以选择性地提交文件,而不是必须提交所有修改。
练习 3:查看和比较差异
修改一个文件,然后比较不同状态下的差异:
echo "原始内容" > test.txt
git add test.txt
git commit -m "添加测试文件"
echo "修改后的内容" > test.txt
# 查看工作区和暂存区的差异
答案
查看和比较差异的方法:# 创建并提交初始文件
echo "原始内容" > test.txt
git add test.txt
git commit -m "添加测试文件"
# 修改文件
echo "修改后的内容" > test.txt
# 查看工作区和暂存区的差异
git diff
# 添加修改到暂存区
git add test.txt
# 查看暂存区和版本库的差异
git diff --cached
# 提交修改
git commit -m "修改测试文件内容"
这个练习展示了git diff
和git diff --cached
的用法,它们是查看文件差异的重要工具。
常见坑
很多人习惯性地修改文件后直接提交,忘记先用git add
添加到暂存区。结果Git提示"nothing to commit",因为暂存区是空的。记住Git的工作流程:工作区→暂存区→版本库,每一步都不能少。
有些人在提交时写很模糊的说明,比如"修改"、"更新"、"fix"等。这样的说明在以后查看历史时完全没用。好的提交说明应该清楚地说明这次提交做了什么,比如"添加用户登录功能"或"修复首页图片显示问题"。
有时候不小心暂存了不想提交的文件,然后直接提交了。为了避免这个问题,提交前一定要用git status
检查暂存区的内容,确保只提交想要提交的文件。如果暂存了错误的文件,可以用git reset HEAD 文件名
取消暂存。
修改已经推送到远程仓库的提交历史。在团队协作中,这会造成严重的问题,因为其他开发者可能已经基于你的提交进行了工作。如果必须修改历史,确保与团队成员沟通。
在大型项目中频繁地使用git add .
或git add -A
,可能会不小心添加不想提交的文件。建议养成先查看git status
,然后选择性添加文件的习惯,这样可以更精确地控制提交内容。
章节总结
通过这一章的学习,你现在应该掌握了Git最核心的操作流程:git add
和git commit
。这两个命令构成了Git版本控制的基础,让你能够保存文件的不同版本,随时回到任何历史状态。
你现在理解了Git的工作流程:先在工作区中修改文件,然后用git add
将修改添加到暂存区,最后用git commit
将暂存区的内容永久保存到版本库中。暂存区的存在让你能够精确控制每次提交的内容,这对于管理复杂项目非常重要。
你还学会了如何查看文件差异、如何处理常见错误、如何写好的提交说明,以及在实际项目中如何合理地安排提交时机。这些技能会让你在日常使用Git时更加得心应手。
现在你已经具备了Git的基本操作能力,可以开始管理你的项目版本了。在下一章中,我们将学习如何查看历史记录,找到过去的版本。相信我,一旦你习惯了Git的工作流程,你就再也回不去传统的文件管理方式了!