ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Git 核心操作全解:提交、日志、版本回退与文件撤销实战指南

Git 核心操作全解:提交、日志、版本回退与文件撤销实战指南 不废话直接进入正题。做开发这几年Git 是我每天摸得最多的工具没有之一。提交代码、翻日志、回退版本、撤销文件这四件事几乎覆盖了日常工作里 80% 以上的 Git 操作也是新手最容易出问题的地方。网上讲 Git 的文章一抓一大把但大多数要么是纯命令罗列要么是翻译官方文档遇到真实场景照样不知道用哪个。这篇文章我打算用一套完整的实操链路把“提交、查看日志、版本回退、文件撤销”讲透每个命令都配上场景、原理和我在实际项目中踩过的坑希望能让刚入门的同学少走弯路也让用了一两年 Git 但还停留在 add/commit/push 三件套的朋友把这块补完整。先说清楚这篇内容适合谁如果你刚装好 Git、正准备把代码推到远程仓库如果你在团队协作里因为提交信息写得乱被 review 的人吐槽过如果你经历过“代码写错了想回退却把别人的提交也搞没了”的惊悚瞬间那这篇文章就是给你写的。全文不会绕弯子每一条命令我都会说清楚它解决什么问题、为什么这么用以及哪些操作应该谨慎。1. 环境准备与基础配置很多人装完 Git 就直接 clone、add、commit等到 push 的时候却报错或者提交记录里显示的提交人是一串乱码这些问题的根源都在最基础的配置上没做好。我见过太多同事卡在这一步所以先把环境这块捋清楚。1.1 Git 安装后的第一件事确认版本与用户信息安装 Git 本身不复杂Windows 下用安装包一路 NextmacOS 下可以用 HomebrewLinux 上一般是 apt 或 yum。装完以后先确认版本我一般喜欢用新版本因为 Git 的功能迭代很快一些好用的命令比如git switch、git restore都是后来加的版本太老可能用不了。git --version接下来是配置用户信息这一步很多人会忽略但它直接决定了你的提交记录上显示谁的名字。注意这里配置的 user.name 和 user.email 不是登录远程仓库的账号而是本地提交时写入提交记录的信息一般建议用公司统一的工号或昵称、邮箱这样团队里能对得上号。git config --global user.name 你的昵称 git config --global user.email 你的邮箱配置完可以查看确认git config --global --list提示--global表示全局生效换台电脑或者帮别人处理问题时记得先检查全局配置。如果某个仓库想用单独的身份可以去掉--global在该仓库内重新设置仓库级配置会覆盖全局配置。这里额外说一个踩过的坑有一次我在一台新电脑上忘了配 user.emailcommit 倒是能提交但推到远程仓库后代码平台上的提交记录直接显示成了“Unknown”或者自动关联到一个奇怪的账号。更麻烦的是团队在 review 代码时找不到对应的人。所以别省这一步装完先配。1.2 关联远程仓库从 origin 说起本地代码要跟远程仓库建立关联常用的做法是 clone 或者在已有目录下添加远程地址。如果你是从零开始的项目先在代码平台建一个空仓库然后在本地初始化并关联git init git remote add origin gitgithub.com:用户名/仓库名.git如果你想确认关联信息随时可以查看git remote -v这一条真的很实用。我经常遇到一种情况同事把代码从一个仓库迁移到另一个仓库本地却还指着旧地址push 的时候一脸懵。git remote -v一眼就能看出你有没有指向正确的地址。对于用 clone 方式拉下来的仓库远程地址是自动配好的不需要手动添加。这里多说一句远程地址有 HTTPS 和 SSH 两种形式。HTTPS 每次 push 可能都要输入账号密码配置一下凭证管理器可以记住SSH 则需要生成公钥并配置到代码平台。我个人更推荐 SSH配置一次之后就不用频繁输入密码在公司内网环境也更稳定不过不同企业网络策略不同大家按实际情况选择即可。1.3 几个容易被忽略的配置项除了用户信息还有几个配置项在日常使用中非常重要但很多人不知道。第一个是core.autocrlf这玩意儿专门处理 Windows 和 Linux/macOS 之间的换行符差异。Windows 用的是 CRLF类 Unix 系统用的是 LF如果没有统一Git 会提示整个文件都被修改了代码 review 都看不下去。团队里一般建议统一设置为input或true具体要看协作平台和操作系统关键是大家统一。第二个是文件名大小写的问题。Windows 和 macOS 默认文件系统不区分大小写但 Linux 区分。你如果在本地把App.js改成了app.jsGit 可能根本不识别这个重命名推到 Linux 服务器上就出问题。遇到这种情况要执行git config core.ignorecase false顺便说一句如果你的仓库里已经出现了大小写导致的跟踪混乱可以先用git mv -f做一个临时的两步重命名来纠正。第三个是默认编辑器。commit 时如果忘记写-mGit 会弹出默认编辑器等你填提交信息很多人第一次遇到 vim 直接卡住不知道怎么退出。建议一开始就换成一个自己熟悉的编辑器git config --global core.editor code --wait避免在终端里被 vim 支配。这些都是细节但细节决定体验越早配置越顺手。2. 提交代码的正确姿势add、commit 与提交规范提交是 Git 使用频率最高的操作但恰恰是这个操作很多人做得太随意。要么一股脑git add .把无关文件都提交上去要么提交信息写得含糊不清过一个月回头看根本不知道当时提交了什么。这一节我详细拆解提交链路。2.1 暂存区的价值为什么不要无脑 add .Git 的提交模型分三层工作区、暂存区、本地仓库。工作区就是你看得见的文件暂存区是你通过git add放进去的内容相当于一个待提交的缓存区本地仓库才是真正生成提交记录的地方。很多新手不理解暂存区存在的意义觉得多此一举。其实暂存区的最大价值是让你能够“分批次提交”。比如你一次改了三个文件分别修复了 bug、加了一个小功能、调整了格式这三个改动混在一起并不好 review。正确做法是先把第一个相关的文件git add提交一次再把第二个文件加进去提交一次让每一次提交都只做一件事。我常用的流程是git status git diff # 看看所有改动 git add src/components/Button.js git commit -m fix: 修复按钮组件在移动端点击区域过小的问题每次提交前先git status和git diff确认改动内容再针对性地 add 文件这习惯值得养成。git diff默认比较的是工作区和暂存区的差异加--staged可以看暂存区和上次提交的差异git diff # 工作区 vs 暂存区 git diff --staged # 暂存区 vs 上次提交注意如果你用了git add .然后又改了一个文件这个文件的新改动并不会被自动提交它还在工作区里。所以经常出现“我明明改了但提交里没有”的情况排查一下就会发现是 add 之后再改的。这种场景下要么重新 add 一次要么用git add -p做交互式添加。2.2 提交信息怎么写feat、fix 这些前缀不是形式主义国内很多团队现在都推行 Conventional Commits 规范约定式提交提交信息的前缀表示提交类型。常见的几个feat新功能fix修复 bugdocs文档变更style代码格式调整不改变逻辑refactor重构不改变功能perf性能优化test测试相关chore构建或辅助工具变动网上有不少人纠结“架构调整应该写啥”按规范这属于refactor它不影响外部行为、不新增功能也不修 bug纯粹是调整内部结构。如果你想做得更规范还可以在类型后面加范围比如feat(cart): 新增购物车合并功能范围就是这次变更影响的模块。为什么说提交信息重要因为它承载了代码演进的上下文。三个月后你要回退某个改动翻日志的时候如果只看到“改代码”“update”你根本不知道哪条记录对应哪个功能。而一条规范的提交信息能让你快速定位到目标提交节省大量时间。我待过的一个项目组提交信息里写了对应的需求单号后续排查线上问题时能直接从提交记录跳到需求文档效率提升不是一点半点。提交信息的写法也有讲究。类型和时间可以留到git log里自动记录但描述必须准确、简洁。描述尽量用一句话说清楚“做了什么、为什么”少用笼统的词。比如“修复了订单模块在并发场景下重复提交的问题”就比“修复订单 bug”有用得多。顺便提一下提交信息也应该用英文还是中文团队约定优先没有约定的情况下我建议中文写清楚就行工具是给人用的沟通效率第一。2.3 提交后发现写错了--amend 的用法和边界有时候提交上去才发现漏了一个文件或者提交信息拼错了这时候不需要慌--amend可以把本次提交修补掉不产生新的提交记录git add 漏掉的文件 git commit --amend使用--amend后会把你当前的暂存区内容合并进上一次提交同时可以重新编辑提交信息。如果只想改提交信息不修改文件内容git commit --amend -m 新的提交信息这里有一个非常重要的边界--amend实际上是创建了一个全新的提交来替换旧提交所以它会改变提交的 hash。如果你已经把旧提交推到了远程仓库而且这个分支是团队公用的那就不要用--amend了否则下次 push 的时候会跟远程的历史对不上。简单总结就是还没 push 的本地提交可以放心 amend已经 push 并且多人共用的分支不要 amend。3. 查看日志不只是 git log 那么简单日志是 Git 使用最频繁的查询类操作也是很多人学得最浅的部分。多数人只会用git log默认输出看到一长串内容直接放弃然后靠代码平台网页看提交记录。其实掌握了git log的参数组合很多排查工作根本不需要离开终端效率完全不一样。这一节我把日志的常用参数和实际场景结合起来讲。3.1 高频参数组合让 log 输出更易读默认的git log会输出完整的 commit hash、提交人、日期和提交信息信息多了以后可读性很差。我实际使用中最频繁的组合是这几条git log --oneline git log --oneline --graph --decorate git log -5--oneline把每个提交压缩成一行只显示短 hash 和提交信息扫一眼就知道最近发生了什么。--graph会在左侧画出分支合并的图形配合--decorate显示分支和标签指向看仓库的分支脉络非常清楚。-n表示限制条数比如-5只看最近五条。如果想知道每次提交具体改动了哪些文件用git log --stat git log -p--stat显示文件变更统计-p显示完整的 diff 内容。我一般查“这个提交到底改了啥”的时候用-p查“改了哪些文件”用--stat。如果只想看某个文件的完整历史git log -p -- src/xxx.js这个命令在排查“某段代码是谁改的、为什么改”时特别好使。3.2 按条件筛选日志作者、时间、关键词、代码内容日志多了以后全量翻肯定不现实Git 提供了灵活的筛选参数。按作者筛选git log --authorzhangsan按时间范围筛选git log --since2024-01-01 --until2024-03-01--since和--until接受的时间格式非常灵活也可以写 “2 weeks ago” 这种相对时间。按提交信息关键词搜索git log --grepfix还有一个极其实用的参数-S它能按代码内容的变化来搜索提交。比如你想知道“那行handleLogin()是谁加的”执行git log -S handleLogin --oneline它会找出所有让代码中handleLogin字符串出现次数发生变化的提交。这个命令在代码考古的时候简直是神器比git blame还常用因为它能直接定位到“引入某段代码”的提交而 blame 只能定位到最后一次触碰该行的提交。3.3 从日志回溯历史blame 与 refloggit blame按行显示文件的每一行是哪个提交引入的、谁写的、什么时候写的。当你想知道某一行代码的来源或者要跟同事确认“这行是不是你改的”时这个命令最直接git blame src/components/Button.js它输出的格式一般是commit hash 作者 时间 (行号) 源码信息很全。如果嫌输出太长可以用git blame -L 10,20 src/components/Button.js只看第 10 到 20 行。但这里要特别提醒blame只能显示“最后一次修改这一行”的提交如果这一行被后来的格式化工具批量改过你就找不到真正的业务改动来源了。这时候配合代码平台网页版的 Blame 功能或者结合上面的git log -S交叉验证才是完整的排查思路。reflog是我最想安利给所有人的命令之一把它归到日志这一节非常合适因为它是 Git 的“操作日志”。你执行过的reset、checkout、commit --amend等操作都会记录在 reflog 里哪怕你误操作把提交给“丢”了也能通过 reflog 找回。它的本质是记录本地仓库所有分支指针的移动历史git reflog输出会显示每一次 HEAD 指向变化包括对应的 hash 和操作说明。我后面讲版本回退时会详细说怎么用它来救命这里先记住一句话reflog是 Git 世界里最强的后悔药。4. 版本回退reset、revert 与恢复丢失的提交版本回退是 Git 术中风险最高、也最需要理解原理的操作。很多人只记住一个git reset --hard然后回退完发现自己写了一下午的代码没了欲哭无泪。这节我会把 reset 的三种模式讲透再讲清什么时候应该用 revert以及误操作后怎么用 reflog 捞回丢失的提交。4.1 理解 reset 的三种模式soft、mixed、hardgit reset的本质是把当前分支的 HEAD 指针移动到指定的提交影响范围取决于你选的模式。先从最直观的表格看区别模式HEAD 指向暂存区工作区典型场景--soft改变不变不变撤销 commit保留所有改动在暂存区--mixed默认改变改变不变撤销 commit 和暂存保留改动在工作区--hard改变改变改变彻底回到某个状态本地改动全部丢弃用大白话解释就是--soft只是把“提交”这个动作撤掉你写好的内容还整整齐齐地排在你面前相当于执行了一次“反 commit”--mixed把“添加进暂存区”也撤了文件回到“已修改未暂存”的状态--hard最暴力工作区里的改动会被直接覆盖没有提前备份就哭吧。具体使用场景撤销最近一次提交但想保留改动改写后重新提交git reset --soft HEAD~1撤销最近一次提交并且把文件从暂存区退出来重新整理后分多次提交git reset --mixed HEAD~1彻底丢弃最近的提交和所有相关改动让代码回到某个确认没问题的版本git reset --hard commit-hashHEAD~1表示当前提交的父提交也就是上一个提交。注意别把波浪号和减号写反了这个手滑的代价很大。提示在团队协作分支上如果你已经把提交推到了远程不要在本地用reset后再直接push --force这会导致远程分支历史被重写其他人的本地仓库会出现对不上的情况。重写公共历史的操作需要极其谨慎能用 revert 就用 revert。4.2 更安全的回退方案git revertgit revert和reset的思路完全不同。reset是“把指针往回拨”假装某些提交不存在了revert是“创建一次相反的新提交”把上一次提交的改动反着做一遍但原来的提交历史原封不动地保留着。比如你刚推送了一个有问题的提交需要让代码回退到它之前的状态但又不希望破坏已经同步给别人的历史git revert commit-hash执行后 Git 会开启一个新提交内容就是把你指定的提交里的改动全部反向应用。这样做的好处很明显整个提交历史是线性连续的协作的其他人 pull 下来就能自然对齐不需要强推。什么时候选 reset什么时候选 revert我的判断标准很简单如果提交还没 push或者只在你自己本地用 reset如果已经 push 到公共分支或者不太确定别人的本地状态用 revert。很多团队规范里直接规定公共分支禁止 reset只允许 revert就是怕大家强推把同事的本地仓库搞乱。4.3 回退版本后如何提交本地回退与远程同步热词里有个很典型的问题“git 怎么回退版本并提交”。很多人卡在“回退”和“提交”这两个动作的关系上。其实流程不复杂分两种情况。情况一你还没推送过操作完全在本地git reset --hard 目标版本hash git push origin 当前分支如果远程分支有你后面产生的提交这种强推会覆盖远程历史。在个人分支或你自己负责的功能分支上没问题但要确认这个分支没有别人在用。情况二你已经推过了推荐用 revertgit revert 问题提交hash git push origin 当前分支这样远程会多出一条“反向提交”但历史没有被重写。还有一种混合场景比如你回了 3 个提交发现回过头了或者回退的方向不对也可以用git revert --no-commit连续回退多个提交然后一次性提交git revert --no-commit 旧提交hash^..新提交hash git commit -m revert: 回退某个功能旧提交hash^表示旧提交的父提交这样从父提交开始到新提交为止的范围都会被反转。如果没有--no-commit默认每个被回退的提交会生成一次新的提交提交信息会比较啰嗦。4.4 误操作后的救命稻草reflog 恢复丢失的提交前面提过 reflog 是 Git 的“操作日志”。这里用真实场景说明它怎么救命。有一次我在一个分支上写了一大堆代码提交了三四次然后想退回某个中间状态看看效果顺手用了git reset --hard 一个很旧的hash。退完以后发现代码直接回到了几天前的版本前面写的那些提交在git log里全都不见了。那一瞬间心里确实咯噔一下。好在以前踩过类似的坑我马上一顿操作git reflogreflog 里能看到刚才 reset 之前 HEAD 指向的 hash那些“丢失”的提交其实只是没有分支引用了对象还在仓库里。找到最靠近当前的操作记录里写着reset: moving to之前的那个 hash然后git branch 备份分支名 找回的hash这样就把丢失的提交重新挂到一个新分支上原分支继续回退后的状态两边互不干扰。之后我可以从备份分支里 cherry-pick 需要的提交或者干脆把当前分支硬指回去。这个经历让我养成两个习惯第一大的回退操作前先git branch 备份名或者打一个git tag第二每次误操作后先想 reflog不要急着重新写代码。reflog 通常默认保留 90 天只要不是物理删除了 .git 目录基本都能捞回来。5. 文件撤销把误改、误加、误删的现场抢救回来文件撤销和版本回退经常被混在一起谈但它们的关注点不一样。版本回退着眼于“整个分支指针移动”文件撤销着眼于“工作区、暂存区、仓库之间怎么把文件恢复成想要的状态”。实际开发中文件级的撤销更常用也更值得仔细掌握。5.1 先建立三区模型工作区、暂存区、本地仓库要理解文件撤销不能只看命令必须先建立“三区模型”。我习惯用一个比喻工作区是你的办公桌暂存区是托盘本地仓库是文件柜。你在办公桌上改文件改完觉得行把文件放进托盘git add托盘里攒够了就把托盘里的文件一起归档进文件柜git commit。待处理文件放哪个区域决定了你能用什么命令把它恢复或撤销。理解这个模型之后文件撤销其实就三类问题文件在工作区、文件在暂存区、文件已经进了仓库。每一类的处理方式不同需要逐一看。5.2 工作区误改checkout 和 restore如果你在工作区改了文件但发现改错了、想恢复到上次提交的状态最直接的做法git checkout -- src/xxx.js新版 Git 更推荐的写法是git restore src/xxx.js这两个命令效果一样都是把工作区文件恢复成暂存区或 HEAD 中的版本。注意这里的风险工作区里“未提交的改动”会被直接覆盖而 Git 不会给你任何二次确认。如果你改了两个小时想撤销其中一个文件最好先确认这个文件的改动真的不要了。我曾经见过一个同事刚改完配置手滑执行了git checkout -- .整个目录所有未提交的改动全部回到上次提交的状态一天的工作白干。所以这里必须强调不要在手忙脚乱的时候执行带.的恢复命令宁可多打几个字把文件名写全也不要图省事全路径一把梭。更稳妥的做法是在撤销之前先把你不确定是否要保留的改动备份一下比如复制一份到临时目录或者用git stash把改动暂存起来。git stash后面会单独讲它非常有用。5.3 误将文件加入暂存区撤销暂存如果你git add了不想提交的文件暂存区里有它但工作区的改动还存在撤销暂存有两条路。老命令git reset HEAD -- src/xxx.js新命令git restore --staged src/xxx.jsgit restore --staged的作用是把文件从暂存区“撤下来”但保留工作区里的修改。执行后git status会显示文件从“已暂存”变成“未暂存”改动还在你可以重新整理再 add。这里要跟git reset --hard区分开。git reset HEAD -- file只影响暂存区不会动工作区git reset --hard会把工作区也一起覆盖。新手最容易犯的错就是混淆这两个命令。5.4 撤销一次本地提交而不伤害改动如果你刚 commit 完发现提交信息写错了、或者漏了文件、或者改的内容有误想撤销这一次提交但保留改动最安全的方式git reset --soft HEAD~1这会撤销最近一次提交所有改动保留在暂存区。如果连暂存也一起撤销让文件回到工作区未暂存状态git reset HEAD~1这里再说一遍区别--soft是“提交坏了但东西都别动”--mixed是“提交和暂存都撤了文件留在工作区”。两种都不会丢失更改只不过存放的位置不同。如果你的目标是连改动一起丢弃不想要这段代码了才用git reset --hard HEAD~1。在实际项目中我建议大家把上一条命令划重点记住因为它能让你在犯错后有后悔的余地。5.5 撤销 pull、merge、rebase 的操作现场热词里有一条“git pull 操作怎么撤销不能影响未 commit 的文件”这个问题很有代表性。场景一般是你正在本地干着活有一批没 commit 的改动结果手滑执行了git pull远程的更新跟你本地的状态冲突了或者 pull 之后你不想合并了。这里要分情况处理。如果git pull拉下来没冲突但你就是不想合入这个远程提交也没 commit 过可以这样merge 流程下撤销已经发生的 mergegit merge --abort它会终止这次合并恢复到 pull 之前的状态。注意--abort只对合并冲突或者合并中间状态有效如果 pull 已经正常合入且没有冲突那它已经生成了 merge 提交--abort就不管用了这时要找到 pull 之前的提交指针可能得借助 reflog。如果远程是 rebase 模式拉下来的也就是你的配置里 pull.rebase 为 true或者你主动用了git pull --rebase那么中断 rebase 的命令是git rebase --abortrebase --abort会把分支恢复到 rebase 前的状态你本地的未提交改动不会被影响因为它们根本不参与 rebase。这一点恰恰回应了热词里的“不能影响未 commit 的文件”rebase 和 merge 操作只针对已提交的内容工作区未提交的文件不会被动到除非过程中发生了需要你手动处理的冲突合并。如果你 pull 已经正常完成了想要撤销这次 pull 并且不碰未提交的改动操作思路是回到 pull 之前的提交。先git reflog找到 pull 前 HEAD 的位置然后git reset --soft hash把指针挪回去未提交的改动自然还在。这种做法的本质不是“撤销 pull”而是“把分支指针移回旧位置”覆盖范围可能包括很多提交所以务必先确认 reflog 里的位置准确。5.6 临时收工神器stash 保存现场文件撤销这个话题里git stash必须占一席。它的作用是把工作区和暂存区的改动临时保存起来让工作区变得干净然后你可以在需要的时候再把改动恢复回来。典型的场景是你正在开发 A 功能改了五六个文件突然线上出了个紧急 bug 要切换分支去修但你现在又不能 commit因为 A 功能还没写完提交上去就乱套了。操作过程git stash # 保存当前所有未提交的改动 git switch 紧急分支 # 修复 bug、提交、切换回来 git switch 原分支 git stash pop # 恢复之前保存的改动git stash pop会把最近一次保存的改动恢复到工作区并从 stash 列表中移除。如果你只想恢复但不想移除用git stash apply。想查看都有哪些 stashgit stash liststash 不会自动提交到分支所以它不会污染提交历史也不怕影响别人的协作。还有一个实用小技巧如果你的 stash 很多建议用git stash push -m 描述信息给每个 stash 加个备注否则恢复的时候容易分不清哪个是哪个。这项工作虽然简单但对维护现场秩序很有价值。6. 常见问题排查与实操心得最后这部分我把实际操作中经常遇到的问题集中梳理一下。这些问题是热词搜索里高频出现的也是大家在群里问得最多的。很多问题看起来五花八门但排查思路是相通的掌握方法比死记命令更重要。6.1 “git 无法将‘git’项识别为 cmdlet”的解决思路这个问题在 Windows 上极其常见。报错信息类似“git : 无法将‘git’项识别为 cmdlet、函数、脚本文件或可运行程序的名称”。本质上就是系统在 PATH 环境变量里找不到 git 的可执行文件。排查思路如下第一步确认 Git 装没装。按Win键输入git看有没有 Git Bash 或者 Git GUI 程序。如果没装去官网下载安装包安装过程中注意勾选 “Add to PATH” 或默认选项。第二步如果装了但报错多半是当前终端PowerShell 或 CMD启动早于 Git 安装PATH 没有刷新。关掉终端重新开一个再试。第三步如果重开终端还不行手动检查环境变量。在系统设置里搜“环境变量”找到 Path 变量确认里面有没有 Git 的 bin 目录比如C:\Program Files\Git\bin。没有就手动添加然后重启终端。提示安装 Git for Windows 时有一个步骤是选择 PATH 环境配置分别对应“仅使用 Git Bash”“从命令行使用 Git”“从第三方工具使用 Git”。强烈建议选中间或第三个选项这样在 PowerShell、CMD 和 VS Code 里都能直接调用 git 命令避免后续各种终端里找不到命令的问题。6.2git push -u origin main一直提交不上去怎么排查push 失败的原因很多常见的有几类第一类认证问题。SSH 方式下如果本地公钥没加到代码平台会报 “Permission denied (publickey)”。排查方法是ssh -T gitgithub.com或者用git remote -v确认远程地址。HTTPS 方式下如果账号密码不对会提示登录失败。注意这里说的认证问题跟网络环境无关是自己的密钥或账号配置问题顺着报错信息逐条排查即可。第二类远程分支比你本地领先。比如你在本地基于旧代码做了提交而远程仓库已经有其他人新的提交push 会被拒绝提示 “non-fast-forward”。解决办法是先把远程更新合并或变基到本地git pull --rebase然后解决冲突再 push。第三类分支名不一致。有的仓库默认分支是master有的平台默认是main还有的是develop。你在本地 push 到main但远程根本没这个分支或者远程保护规则不允许直接推送到 main也会报错。先用git branch -a看远程有哪些分支确认为什么名字。第四类提交内容过大或仓库容量限制。有的代码平台对单文件大小有限制超过限制会直接拒绝 push。这种情况系统一般会明确提示处理办法是把大文件从 Git 跟踪中移除重新提交。排查的顺序建议是先看远程地址对不对再看认证通不通再看分支是否同名最后看提交内容是否合规。不要一上来就怀疑平台有问题多数时候问题出在本地配置。6.3 误提敏感信息或大文件怎么办这里先给新手一个前置建议.gitignore 一定要在项目一开始就配好把日志、临时文件、本地配置文件、依赖目录等排除掉。别等到提交了核心配置才发现“完了这不该传上去”。如果在提交历史里已经出现了不该提的文件比如本地密钥最理想的办法是立即告知团队管理员并在代码平台侧轮换或吊销该密钥。本地仓库层面可以用git rm --cached把文件从跟踪中移除然后提交这样以后不会继续推但历史记录里仍然存在这个文件。如果必须从历史中彻底移除最简单的方案是找一段没有敏感信息的时间点用filter-branch或者更省心的工具重写历史并把所有分支和标签都更新一遍。但这种操作的成本很高而且要强制推送才会对远程生效对团队影响极大。我的态度是在团队项目里尽量走正规流程而不是在本地操作历史重写因为一旦涉及他人协作重写历史会造成大量不必要的问题。6.4 冲突处理的两个实用原则先看状态再选策略代码冲突是协作开发避不开的坎。很多新手遇到冲突的第一反应是慌实际上冲突的本质只是“两个人改了同一处”Git 自己无法判断谁对就停下来让你做决定。处理前先看状态git statusGit 会明确告诉你哪些文件有冲突除了状态信息还提示了当前处于 merge 还是 rebase 过程。打开冲突文件后你会看到 HEAD、、这三个标记它们把冲突双方的内容分隔开。手动整理成正确的代码后把git add这个文件标记为已解决。merge 的收尾是git merge --continuerebase 的收尾是git rebase --continue。这里想多说一句处理冲突最重要的是知道到底哪个版本是你要保留的。我见过不少人为了图省事直接把自己的改动全删了留远程的版本结果把自己功能写没了。解决冲突前最好先跟同事沟通一下或者至少看一眼git log确认修改意图。没人规定必须在终端里解决一切你可以用 VS Code 或任意 IDE 的冲突界面手动选择“保留当前分支”“保留传入分支”或“两者都保留”这个操作比手打标记更直观。选策略方面我的个人实践经验是功能分支在合并主干前优先用 rebase 把主干的最新更新拉到本地保持提交历史的线性主干分支的分支合入则用 merge保留合入的节点方便追溯。这个策略不是唯一的但结合你们团队的 review 流程选择适合的即可。结尾几点真实体会最后说点个人经验。Git 用久了你会发现学的不是命令本身而是一套“后悔”的体系。工作区误改有 restore暂存区误加有 restore --staged提交写错有 amend回退删错了有 reflog。几乎每一个危险操作背后都有对应的补救手段所以不需要因为害怕弄坏代码而不敢尝试。真正需要小心的只有两件事一是公共分支上的历史重写二是带.的全量恢复命令。另外一个实用习惯是给常用命令配置 alias。比如我本地的git lg就配置了这样一串git config --global alias.lg log --oneline --graph --decorate --all效果是输入git lg就能看到一张简洁的全分支提交图。类似地还可以配git st替代git status配git cm替代git commit -m。配置一次长期受用团队里也可以统一维护一份大家都认可的命令别名减少沟通成本。如果你现在正被某个 Git 操作卡住不妨先想清楚自己处在哪个区、想回到哪个区再选对应的命令思路对了命令自然就对了。
返回列表