前言
上一篇文章Gitea与Git配置主要写了Gitea和Git的配置,比如安装Git、配置用户名邮箱、生成SSH密钥、连接远程仓库等。
这篇文章就不继续折腾SSH了,主要讲Git本身怎么用。
很多人刚开始用Git时,基本只会三板斧:
git clonegit pullgit push能用,但是一出冲突就开始懵。或者明明只是改了一行配置,结果把一堆临时文件也提交上去了。
所以这篇主要写几个最基础但最容易被跳过的东西:add到底干啥,commit到底是不是上传,分支为什么存在,pull为什么会把代码拉炸。
先把Git当成存档工具
Git最核心的作用其实很朴素:记录项目每一次比较重要的变化。
比如你今天写完了登录功能,可以存一个档;明天改坏了,还能回来看昨天到底改了什么。它不是网盘同步,也不是“点一下就自动备份全部文件”的东西,Git更像是你主动给项目打一个个版本点。
这个“版本点”在Git里就叫commit。
Git为什么会有add
很多人刚开始学Git时都会疑惑:
为什么不能直接commit?为什么中间还要来一个add?
因为Git把修改分成了几步:
工作区 -> git add -> 暂存区 -> git commit -> 本地仓库工作区就是你正在编辑的项目目录。你打开VS Code改了文件,这些改动一开始都在工作区里。
git add本质上是在告诉Git:
这些改动我准备提交了。这一步会把改动放进暂存区。暂存区可以理解成“这次准备提交的清单”。
这样做的好处是,你可以只提交一部分文件,而不是把所有改动一股脑全塞进一个提交里。
比如你同时改了两个文件:
login.jsREADME.md但这次只想提交登录相关代码,就可以:
git add login.jsgit commit -m "修复登录失败问题"README.md的改动还留在工作区,不会被这次提交带上。
当然,如果你确定当前目录下所有改动都要提交,也可以直接:
git add .这个命令很方便,也很容易把不该提交的东西带进去,所以提交前最好看一眼状态。
日常最常用的一套流程
我自己觉得初学时先记这一套就行:
git statusgit diffgit add .git commit -m "提交说明"git pullgit pushgit status先看现在乱不乱,git diff看具体改了什么,确认没问题再add和commit。
注意,commit只是提交到本地仓库,不是上传到Gitea、Github这种远程仓库。真正上传是git push。
所以可以简单理解成:
commit = 本地存档push = 上传远程这点很重要,不然很容易以为自己commit了别人就能看见,结果代码还躺在自己电脑里。
status:不知道干啥时先看它
git status大概是Git里最应该多敲的命令。
git status它会告诉你当前在哪个分支,哪些文件改了,哪些文件已经add了,哪些文件还没被Git跟踪。
很多时候你不知道下一步该add还是该commit,先敲一下git status就清楚了。
比如看到文件在Changes not staged for commit下面,说明改了但还没加入暂存区。
看到文件在Changes to be committed下面,说明已经add了,下一步可以commit。
diff:提交前看一眼不亏
git diff用来看具体改了哪些内容。
git diff这个看的是工作区里还没有add的改动。
如果已经add了,想看准备提交的内容,用:
git diff --cached我个人建议提交前尽量看一眼,尤其是写代码时临时加过console.log、测试地址、乱七八糟的注释,很容易忘记删。
只看某个文件也可以:
git diff 文件名commit到底该怎么写
提交命令一般这样写:
git commit -m "修复登录失败问题"commit保存的是暂存区里的内容,也就是你前面git add进去的那些改动。
一个提交最好只做一件事。比如修bug就修bug,改文档就改文档,别把“修复登录问题”和“顺手调整首页样式”混成一个提交。
不是说混了项目就不能跑,而是以后回头查问题会很痛苦。
提交说明也别总写:
git commit -m "update"这种写法当时很爽,三天后自己看日志也不知道这个update到底更新了什么。
看历史用log
提交多了以后,可以用git log看历史:
git log默认输出比较长,平时我更常用这个:
git log --oneline输出大概是:
a1b2c3d 修复登录失败问题e4f5g6h 添加用户设置页面前面那串是提交ID,后面是提交说明。
如果想看分支关系,可以用:
git log --oneline --graph --all虽然刚开始看会有点眼花,但至少能看出来分支是怎么分出去又合回来的。
restore:改错了怎么撤回
如果一个文件改坏了,还没提交,想恢复到上一次提交时的样子:
git restore 文件名撤销当前目录下所有未暂存修改:
git restore .这个命令会直接丢掉你的未提交修改,别手滑。执行前最好先git diff看一下。
如果文件已经git add了,但还没commit,想把它从暂存区拿出来:
git restore --staged 文件名这只是取消暂存,文件内容还在。要不要继续撤销,再用git restore 文件名决定。
.gitignore:哪些东西别传上去
项目里总有些东西不应该交给Git管,比如依赖目录、编译产物、日志、环境变量文件。
常见的.gitignore大概长这样:
node_modulesdist.env*.log.env这种文件尤其要注意,里面经常放密钥、数据库密码之类的东西,不要随便提交。
如果文件已经被提交过,再写进.gitignore是没用的,因为Git已经认识它了。要先取消跟踪:
git rm --cached 文件名目录的话:
git rm -r --cached 目录名然后再提交一次。
分支不是高级功能
分支听起来像是团队协作才用的东西,其实一个人写项目也很有用。
比如主分支main现在是能正常运行的版本。你突然想大改登录逻辑,如果直接在main上改,改一半发现跑不起来了,就很尴尬。
这时可以开个新分支:
git switch -c feature-login意思是创建并切换到feature-login分支。
查看当前有哪些分支:
git branch切回主分支:
git switch main分支的意义就是:我可以在一条独立的线上折腾,折腾好了再合回主分支。
merge:把分支合回来
假设你在feature-login分支把功能写完了,想合并回main:
git switch maingit merge feature-login如果两个分支改的是不同地方,Git通常会自动合并。
如果两个分支改了同一个文件的同一段内容,Git就不知道该听谁的,于是就会冲突。
冲突不是Git坏了,只是它不敢帮你乱选。
用完的分支可以删掉:
git branch -d feature-login如果Git提示这个分支还没合并,但你确定不要了,可以强制删除:
git branch -D feature-loginrebase:让历史看起来更直
rebase也是合并代码的一种方式,不过它和merge的思路不太一样。
merge像是把两条线接到一起,会留下一个合并提交。
rebase更像是把你的提交挪到目标分支最新提交后面,让历史看起来像一条直线。
比如:
git switch feature-logingit rebase main意思是把feature-login上的提交,重新放到main最新提交后面。
这个东西好用,但也别乱用。已经推送到远程、别人也在基于它开发的分支,不建议随便rebase,因为它会改写提交历史。
自己本地的分支,或者还没推送出去的分支,用rebase一般没什么问题。
pull到底做了什么
很多人天天敲:
git pull但不知道它其实做了两件事:
git fetchgit mergefetch是把远程的新提交下载下来,merge是把远程分支合并到你当前分支。
所以pull为什么会冲突?因为它本质上做了合并。
如果远程有人改了同一段代码,你本地也改了同一段,Git当然不知道该保留谁的。
冲突文件里一般会出现这种东西:
<<<<<<< HEAD这是你本地的内容=======这是远程分支的内容>>>>>>> origin/main你要手动改成最终想要的内容,然后把这些标记删掉。
普通pull冲突处理完后:
git add 冲突文件git commit如果你用的是:
git pull --rebase冲突处理完后继续:
git add 冲突文件git rebase --continue不想继续这次rebase,可以取消:
git rebase --abort推送前先拉一下
比较稳妥的日常习惯是:
git statusgit add .git commit -m "提交说明"git pullgit push如果远程没人动,pull基本没事;如果远程有人提交了新内容,先在本地合并好,再推送,出问题也能早点发现。
当然,提交前最好别无脑git add .,尤其是项目根目录一堆生成文件的时候。
常用命令速查
查看当前状态:
git status查看具体改动:
git diff加入暂存区:
git add 文件名git add .提交到本地仓库:
git commit -m "提交说明"查看历史:
git log --oneline撤销未提交修改:
git restore 文件名取消暂存:
git restore --staged 文件名拉取远程更新:
git pull推送到远程:
git push创建并切换分支:
git switch -c 分支名切换分支:
git switch 分支名合并分支:
git merge 分支名总结
Git初学时最容易混的其实就两点:
工作区 -> git add -> 暂存区 -> git commit -> 本地仓库 -> git push -> 远程仓库以及:
git pull = git fetch + git merge把这两个理解了,add、commit、push、pull、冲突这些东西就没那么玄学了。
剩下的命令不用死背,忘了就查。Git这东西刚开始确实反直觉,但常用流程其实就那么几步。先把status、diff、add、commit、pull、push用顺,后面再慢慢补分支和rebase就行。