1. 先搞清楚这条工作流到底在解决什么问题
Git是当下最主流的分布式版本控制系统,Gitee则是最常用的代码托管平台之一。把这两者放在一起说,是因为对绝大多数开发者来说,日常开发循环就一条链路:从远端仓库拉取代码到本地,改完代码后提交,再推送到远端。这个循环看起来简单,但实际操作中翻车的人不在少数。
我见过太多人把Git当成一组孤立的命令来背:clone、add、commit、push、pull,每个单词都认识,组合起来就各种报错。有人clone下来的代码跟同事的不一致,有人push时被拒绝一脸茫然,有人解决冲突时把别人的代码覆盖掉了。这些问题本质上不是命令记错了,而是对整个工作流缺少全局认知。你只有理解了每一步在做什么、数据从哪里流向哪里,遇到异常时才有排查的思路。
这篇文章适合几类人:刚接触Git和Gitee的新手,需要把基础流程彻底跑通;已经在用但经常被合并、冲突、推送失败折磨的开发者;以及想在团队里梳理一套统一协作规范的推动者。我会按真实操作的顺序,把从拉取到推送这条链路上的每个关键节点全部拆开讲,包括命令背后的原理、参数选择的理由,以及那些文档里通常不会写的坑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备:Git安装与基础配置
2.1 各平台下的Git安装方式
不管你是Windows、macOS还是Linux,装Git本身都没什么难度,但不同平台有一些细节值得注意。
Windows下推荐直接去Git官网下载安装包,安装过程中有几个选项需要留个心眼:第一个是默认编辑器,不建议选Vim,新手在commit时误入Vim界面会完全不知道怎么退出,建议选Notepad++或VS Code,如果机器上没有这些编辑器,用默认的Vim也能过,但你至少要记住:wq是保存退出;第二个是PATH环境变量,选中间那个"Git from the command line and also from 3rd-party software"就行,这样在CMD和PowerShell里都能直接用git命令;第三个是行尾转换,默认的"Checkout Windows-style, commit Unix-style line endings"一般别改,这个后面讲跨平台协作时还会细说。
macOS上最简单的方式是brew install git,如果没装Homebrew,也可以下载安装包直接装。Linux发行版则用对应的包管理器,Debian/Ubuntu系是sudo apt install git,CentOS/RHEL系是sudo yum install git。装完统一验证一下,终端里执行git --version,能输出版本号就说明装好了。
2.2 首次配置:用户名和邮箱为什么必须设
装完Git第一件事不是急着clone仓库,而是先配置用户信息。执行这两条命令:
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
这里配置的用户名和邮箱会写入每一次commit的元数据里,Gitee上也会根据这个信息来关联提交者。很多人图省事随便填,结果就是仓库历史里留下的提交人信息乱七八糟,代码出问题想追溯都找不到人。
建议直接填Gitee账号绑定的昵称和邮箱,这样推送到Gitee后,提交记录能正确关联到你的账号,头像和个人主页都能对上。如果在不同项目里想用不同身份,可以把--global去掉,在某个仓库目录下单独配置,这个仓库的配置会覆盖全局配置。
2.3 SSH免密配置:一次配好,长期受益
访问Gitee上的仓库有HTTPS和SSH两种协议。HTTPS方式每次push都要输账号密码,虽然Gitee支持在密码框里填私人令牌来避免明文密码,但反复输入还是麻烦。SSH方式配好密钥后,拉取和推送都是免密的,体验顺畅得多。这也是大多数人在Gitee上推荐用SSH的原因。
生成密钥的步骤如下:
bash复制ssh-keygen -t ed25519 -C "你的邮箱"
执行后会有几个提示,第一个是问密钥文件保存位置,直接回车用默认路径~/.ssh/id_ed25519就行;第二个是设置口令,可以留空,这样用起来完全免密。生成完成后,把公钥内容复制出来,文件在~/.ssh/id_ed25519.pub,Windows下一般在C:\Users\你的用户名\.ssh\目录里。
打开Gitee网页端,进入"设置 -> SSH公钥",把公钥粘进去保存。然后测试连通性:
bash复制ssh -T git@gitee.com
如果配置成功,会返回一段欢迎信息,提示你已经通过认证。注意测试命令连的是git@gitee.com这个固定地址,不是你的用户名,别改。
3. 从Gitee拉取代码:clone与pull的正确打开方式
3.1 仓库地址选择:HTTPS还是SSH
打开一个Gitee仓库页面,会看到一个"克隆/下载"按钮,里面同时提供了HTTPS和SSH两种地址。选择原则很简单:SSH地址是git@gitee.com:用户名/仓库名.git这种格式,HTTPS地址是https://gitee.com/用户名/仓库名.git这种格式。如果你已经配置好了SSH密钥,就选SSH;如果只是临时拉取一个公开仓库看看代码,用HTTPS也可以,拉公开仓库不需要任何认证。
这里有个容易踩的坑:有些人在配置了SSH密钥后,复制地址时还是习惯性选了HTTPS,结果每次push都要输账号密码。我的建议是,既然要长期使用Gitee托管代码,就直接统一用SSH,一劳永逸。
3.2 首次拉取:git clone到底做了什么
第一次拿到一个项目,执行的是clone而不是pull。命令格式:
bash复制git clone git@gitee.com:用户名/仓库名.git
clone做的事是:在本地创建仓库目录、把远端所有分支的引用拉下来、默认检出主分支(通常是master或main)、把工作区文件填充完整。执行完你会得到一个完整的项目副本,里面包含了.git目录,这就是完整的版本历史库。所以clone不只是下载代码,它是把整个仓库的所有历史和分支元数据都复制到本地。
两个实际场景下常用的小技巧:
一是浅克隆。如果项目历史非常长,完整clone很慢,可以用--depth参数只拉取最近几条提交:
bash复制git clone --depth 1 git@gitee.com:用户名/仓库名.git
这适合只需要最新代码、不关心历史的情况,速度快很多。但要注意,浅克隆的仓库在后续push时可能会受到限制,因为本地缺少历史提交记录,远端无法判断能否快进合并。
二是修改默认分支名。Gitee上新建仓库时默认分支名可以选master或main,如果你本地clone下来的分支名和团队其他人不一致,后续推送会很别扭。clone之后进入项目目录,执行git branch -a就能看到所有分支。
3.3 日常更新:pull与fetch的选择
仓库已经在本地了,每天开工前需要同步远端其他人提交的新代码,这时候用的是pull。git pull实际上是两个操作的组合:先执行git fetch把远端最新提交拉取到本地某个隐藏引用里,再执行git merge把这些提交合并到当前分支。理解了这一点,你就知道为什么有时候pull会有两种结果:一种是直接快进,本地分支直接指向远端的最新提交;另一种是产生合并提交,因为本地和远端都有各自的修改。
如果你不想自动合并,只想看看远端有什么变化,可以先执行git fetch,再用git log对比差异,确认没问题再手动merge。这个习惯在团队协作时很有用,因为它把"获取数据"和"合并改动"分开了,给了你一个缓冲判断的机会。
实际工作中我推荐一个习惯:每天第一次开工先git pull一次,提交代码前再git pull一次。这个习惯能最大程度避免后面讲到的推送被拒问题。
4. 本地开发与提交:commit的正确姿势
4.1 工作区、暂存区、版本库三者关系
Git的本地仓库有三个区域:工作区(你看到的文件)、暂存区(index,记录你准备提交哪些修改)、版本库(commit后形成的提交历史)。理解这三个区域,是理解后面所有命令的基础。
你修改文件,改动只存在于工作区。执行git add,改动被记录进暂存区。执行git commit,暂存区的改动被打包成一个版本快照,存入版本库。日常纠结的"我改了文件但commit里没有"、"提交了但push不上去",几乎都能从这三个区域的关系找到答案。
有一个很实用的命令用来查看当前状态:
bash复制git status
它能告诉你工作区有哪些改动、哪些已被暂存、当前在哪个分支。我见过不少人忘记这个命令,改了一堆文件最后只提交了一部分,根源就是没养成先看status再操作的习惯。
4.2 add、commit的正确顺序与误区
基本提交流程是:
bash复制git add .
git commit -m "提交说明"
这里有个细节很多人没注意:git add .会把当前目录下所有改动都加入暂存区,包括你不想提交的临时文件,比如IDE配置文件、日志文件、本地环境配置。所以建议项目里一定要有.gitignore文件,把target/、node_modules/、.idea/、.vscode/、*.log这类文件排除掉。Gitee新建仓库时如果选择初始化了.gitignore模板,就不用自己写。
另一个建议是不要一把梭。如果一次改了多个不相关的功能点,最好分开提交。比如你同时改了前端页面和后台接口,可以分两次add和commit,每次只提交一组相关的文件。这样历史记录清晰,出了问题也好回退。具体操作是用git add 文件名精确添加,而不是一上来就git add .。
4.3 commit message怎么写才像样
提交信息看似随意,实际是团队协作中成本最低但收益最高的规范之一。好的提交信息应该让人不看代码也能知道这次改动做了什么。我常用的格式是类型(范围): 简述,比如:
text复制feat(登录模块): 增加手机号验证码登录接口
fix(订单列表): 修复分页数量计算错误
docs(README): 补充部署环境说明
类型常用的有feat(新功能)、fix(修复)、docs(文档)、style(格式调整)、refactor(重构)、test(测试)。这种约定对个人项目也有价值,几个月后翻历史记录,一眼就能定位到某次改动的目的。
4.4 分支管理:别在主干上乱来
团队协作中,直接在master或main上开发是大忌。正确做法是每次需求拉一个独立分支,开发完合并回去再删除。创建分支用:
bash复制git checkout -b feature/xxx
较新版本Git还支持git switch系列命令,语义更清晰:
bash复制git branch -b feature/xxx # 实际上没有这个,正确的是 git switch -c
git switch -c feature/xxx的等效写法更直观:-c是create的意思,创建并切换到新分支。不管用哪个,核心逻辑是:切分支前确保当前改动已经提交,否则未提交的改动会跟着你"跑到"新分支去。这是很多人切换到其他分支后,发现代码莫名其妙出现或消失的原因。
5. 推送到Gitee:push的完整过程与免密方案
5.1 推送前的黄金法则:先pull再push
push是把本地提交推送到远端仓库,但推送的前提是本地分支和远端分支之间没有冲突。如果远端在你有本地提交之后又新增了别人的提交,你的push会被拒绝,提示non-fast-forward之类的内容。
这时候正确做法是先git pull,把远端的新提交合并到本地,解决可能的冲突后再push。整个过程三步走:
bash复制git pull origin master
git add .
git commit -m "合并远端代码"
git push origin master
这里最怕的是有人被拒绝后直接git push -f强制推送。强制推送会用本地历史覆盖远端历史,如果远端有别人刚推的代码,就直接被覆盖丢失了。个人项目自己用可以这么干,团队协作中这是高风险操作,除非你非常确定要做,否则别碰。
5.2 push命令的参数与首次推送
首次推一个新分支到远端,命令是:
bash复制git push -u origin feature/xxx
这里的-u是--set-upstream的简写,作用是建立本地分支和远端分支的关联。加了-u之后,后续在这个分支上直接执行git push或git pull就不用再写origin feature/xxx了,Git知道要去跟远端哪个分支同步。
如果想把本地某个分支删除的改动同步到远端,用的是:
bash复制git push origin --delete feature/xxx
不过删除远端分支前一定确认这个分支已经合并完,没有未合入的代码,否则团队里其他人可能报错。这里还是那句话,状态不确定时就先git fetch --prune,让远端分支的最新状态同步到本地引用,再判断哪些分支是可以清理的。
5.3 推送免密:HTTPS协议下的持久化凭证
前面推荐了SSH方式,但如果你确实因为某些原因用了HTTPS地址(比如公司内网限制了SSH端口),推送时也不想一次次输账号密码,可以通过凭证管理器持久化。Git内置了credential helper,设置一下就能把凭证缓存到本地:
bash复制git config --global credential.helper store
这个命令会把首次输入的账号密码明文保存在用户目录的.git-credentials文件里。另一种更安全的选择是manager或osxkeychain,分别对应Windows和macOS的系统凭据管理器,加密保存,推荐优先使用。Gitee也支持在HTTPS方式下用私人令牌代替密码,在"设置 -> 私人令牌"里生成,复制到密码框处填写即可。
5.4 推送后的验证与确认
push成功后,建议执行git status确认工作区干净,执行git log --oneline -5查看最近的提交记录,再到Gitee网页端确认代码确实到了远端。这一套检查下来,整个"本地 -> 远端"的闭环才算完整。
有时候你会遇到push成功但Gitee网页端看不到的情况,大概率是分支名不一致。比如你推的是feature/xxx分支,但默认页面显示的是master分支,切一下分支标签就能看到。
6. 常见问题与排查技巧实录
6.1 clone报错"git did not exit cleanly"的真相
这是Gitee使用教程里被问得最多的问题之一。IDEA或其他客户端在clone时报这个错,实际原因是多样化的,最常见的有几种:仓库地址复制错误、SSH密钥没配好或公钥没添加到Gitee、网络连接问题、账号没有该仓库的访问权限。
排查顺序建议:先在终端里直接手动执行同样的clone命令,看完整报错信息。如果是SSH方式,先跑ssh -T git@gitee.com测试认证;如果是HTTPS方式,确认仓库是否公开、账号是否有权限。终端里的报错信息通常比IDE里提示的详细得多,能直接告诉你问题出在哪一环。报错信息里包含permission denied,基本就是权限问题;包含could not resolve host,则是网络或地址问题。
6.2 冲突解决:最考验心态的环节
多人并行开发时,冲突几乎不可避免。出现冲突时,Git会在冲突文件里插入类似<<<<<<< HEAD和>>>>>>> 分支名的标记,把两个版本的内容都显示出来,你需要手动判断保留哪部分。操作思路是:先打开冲突文件,逐段确认,删除标记符号,保留正确内容,然后git add标记为解决完成,最后commit。
冲突不是bug,它是版本控制机制在正常保护代码。关键是解决冲突时不要慌,不要在冲突文件里乱删别人代码。如果冲突范围很大,可以借助IDE的可视化合并工具,IntelliJ IDEA、VS Code都内置了合并界面,左右对比比纯文本改文件直观得多。我个人的经验是:先跟同事沟通一下各自的改动意图,再动手解决,比闷头改效率高,也避免误伤。
6.3 其他高频问题速查表
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
| push被拒绝 | 远端有新提交,本地落后 | 先pull合并,再push |
| 无法提交,提示身份未知 | user.name和user.email未配置 | 执行git config配置 |
| 文件总是被意外提交 | .gitignore未生效 | 确认规则正确,必要时git rm --cached |
| 切换分支后改动消失 | 未提交的改动被带到新分支 | 回原分支提交或stash暂存 |
| 提交信息写错了 | commit message不够准确 | git commit --amend修改最近一次 |
| 提交到了错误分支 | 切换分支前未检查状态 | 用git log找回提交,git cherry-pick移植 |
6.4 不敢提的几个"丢数据"场景
git reset和git checkout是误操作重灾区。git reset --hard HEAD会丢弃工作区和暂存区的所有未提交改动,执行前务必确认。如果误执行了,也不是完全没救——只要改动还在编辑器里,或者还有终端缓冲,尽量找回;更保险的做法是养成频繁commit的习惯,让版本历史里有多个可回退的锚点。
另一个让我印象深刻的场景是:有人把本地仓库整个删了,以为Gitee上有远端就没问题,结果发现本地很多未推送的提交和未提交的改动全没了。所以凡是牵扯到删除操作,先推送到远端或做备份,再动手。远端是保险,但不等于本地工作区的自动备份。
7. 最后分享几个我用下来的工作流习惯
文章写到这里,整条"从拉取到推送"的链路已经走完了,但我想额外聊几句在实际项目里沉淀下来的习惯,这些习惯帮我少踩了很多坑。
第一,开工前和收工前各执行一次git status。不用复杂理由,就是让你始终清楚自己手上有哪些改动、哪些还没提交。很多时候代码丢失不是因为Git不行,而是因为自己都忘了改过哪些文件。
第二,提交遵循"小而频繁"的原则。每次提交只包含一个逻辑完整的改动,宁可多提交几次也别攒一个大提交。一旦后续发现问题需要回退,小提交的定位成本低得多。配合清晰的分支命名,比如feature/订单模块、fix/登录超时,只看名字就知道分支在做什么。
第三,团队协作里把"先pull再push"当成铁律。我用Gitee管理团队项目时,要求所有人push前必须pull最新代码,哪怕觉得没冲突也要拉一下。这个习惯让推送被拒的概率降到了非常低,也让冲突永远发生在本地,而不是先在远端报错再手忙脚乱。
第四,善用Gitee网页端的代码审查和Issue功能。push不是终点,把改动通过Pull Request方式合入主干分支,让同事有机会审查你的代码,远比直接推到主分支安全。这条工作流不只是命令的串联,它也是团队协作质量的保障。
Git的学习曲线有一点陡,但一旦你真正理解了数据流向和每一步命令的作用,它就会变成非常顺手的工具。希望这篇从拉取到推送的实战拆解,能帮你把这条最核心的日常工作流跑通跑稳。
