ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux命令行Git推送代码到GitHub:认证配置与实战排错

Linux命令行Git推送代码到GitHub:认证配置与实战排错

1. 先把这件事想明白:Linux 里推代码到底推的是什么

很多人第一次在 Linux 终端里敲下推送命令的时候,心里其实是虚的:命令行黑漆漆一片,没有图形界面里那种"上传成功"的绿色提示,只有一个光标在那儿闪。我当年也是这样,对着终端反复敲git status看了七八遍,就怕哪天一个手抖把本地改了一半的代码给覆盖没了。后来带过几个刚入行的同学,发现大家在 Linux 上做这件事卡住的地方高度重合:不是不会写那几行命令,而是脑子里没有一张"本地仓库、远程仓库、工作区、暂存区"之间的空间关系图,所以每一步都像在盲操作。

这篇内容就围绕Linux 系统下用 Git 把代码上传到 GitHub 仓库这条主线展开。它解决的核心问题很具体:你有一台只有命令行的 Linux 机器(可能是云主机、可能是实验室的服务器、也可能是一台退役笔记本装的发行版),你想把上面写的代码同步到 GitHub 上做备份、做协作、做版本管理。适合三类人看:刚接触 Linux 和 Git 的入门者、平时只在图形化工具里点按钮、想搞懂底层命令的中级使用者,以及需要在不带界面的服务器上完成代码提交的从业者。整篇会按"仓库怎么设计—关键细节怎么处理—完整实操怎么走—出问题怎么查"的顺序推进。

先铺一个底层认知,不然后面全是死记硬背。Git 的模型是分布式的:你本地有一个完整的仓库,里面存着全部历史;GitHub 上那个叫远程仓库,它也是完整的。所谓"上传",本质是把本地新增的提交对象(commit 对象及其指向的目录树、文件内容)打包传过去,然后让远程仓库某个分支的指针移动到新的位置。这解释了后面很多现象:为什么第一次推送慢、为什么推送不是"复制文件夹"、为什么有时候推上去只传了几 KB。理解成"同步提交历史"而不是"上传文件",你在遇到冲突和拒绝时就不会慌,因为你知道它拒绝的是历史线对不上,不是文件坏了。

我也得说清楚一点:这篇里涉及的系统配置、路径、命令,都是基于常见发行版(主流的 Debian 系和 Red Hat 系)的通用实践,不同发行版的小工具名字会有点差异,我会把差异点标出来。至于版本号、具体包名,请以你机器上的包管理器实际输出为准,不要照抄我写的数字。

2. 整体设计:从一台裸机到能推代码,要打通哪几层

2.1 分层拆解:这件事其实是四层,不是一条命令

我习惯把"Linux 上推代码到 GitHub"拆成四层,一层不通,后面全堵。

  • 第一层:系统层。Git 程序本身装没装、版本够不够、有没有基础的编译和网络工具。这一层最容易被忽略,很多"命令找不到"的报错,根子在这里。
  • 第二层:身份层。Git 每次提交都要记录"谁提交的",需要配置用户名和邮箱。这一层配错了不会立刻报错,但你的提交记录会变成一堆奇怪的署名,事后改起来很麻烦。
  • 第三层:认证层。GitHub 不接受账号密码做命令行推送,必须用凭证(个人访问令牌或者密钥对)。这一层是新手卡死率最高的地方。
  • 第四层:仓库层。本地初始化为仓库、关联远程地址、分支对应、推送。这一层反而是最简单的,最顺的路径就三四条命令。

分层的好处是排错有方向。终端说command not found,去看第一层;说Permission denied或者Authentication failed,去看第三层;说rejected或者non-fast-forward,去看第四层。不要一上来就怀疑网络,绝大多数情况跟网络没关系。

2.2 为什么用命令行而不是图形工具

有人会问,既然有图形化客户端,为什么非要在 Linux 终端里折腾?我的理由有三条,都是踩出来的。

第一,服务器上没有图形界面。你连上去的就是一个 shell,图形工具根本起不来,这是硬约束。第二,命令行是唯一在所有环境都一致的接口。你在本地机器上学熟的这套命令,换到容器里、换到 CI 流水线里、换到别人的机器上,一字不改照样能用;图形工具换个版本菜单就变了。第三,排错时命令行给出的信息更完整。图形工具往往把底层报错吞掉,只给你一句"操作失败",而终端会把完整的拒绝原因打出来,那几行英文就是你排查的钥匙。

代价当然也有:没有可视化 diff、不能点选文件、冲突解决要靠编辑器。所以我的实际做法是混合使用:日常提交走命令行,涉及复杂合并冲突的时候,把仓库同步到有图形界面的机器上用可视化工具处理,处理完再推。工具是为人服务的,不必搞成信仰之争。

2.3 分支策略:个人项目也别全堆在主分支上

标题里说的是"上传代码",但只要你开始推第二次、第三次,就不可避免要面对分支问题。我给的建议很朴素:哪怕是一个人写的小项目,也别所有改动都直接怼到主分支。

原因很实际。主分支代表"当前可用的状态",你在上面做半成品的实验,一旦推上去,远程就处于一个半坏不坏的状态。正确的做法是拉一个特性分支干活,做完了确认能跑,再合回主分支。这个过程在命令行里就是两条命令的事:git switch -c feature-xxx建分支干活,干完git switch main切回来再合。多花的这十秒,换来的是任何时候远程仓库都是可用的。

对于纯学习练手的仓库,可以放宽一点,但也建议养成"一个功能一个分支"的肌肉记忆。习惯这东西,等你哪天真要跟别人协作的时候再补,成本会高得多。

2.4 传输方式的选择:HTTPS 还是 SSH

这是个必须提前决策的点,因为它决定了第三层认证怎么配。两种方式的差别我用一张表说清楚。

对比项HTTPS 方式SSH 方式
认证凭证个人访问令牌(PAT)密钥对(私钥留本地,公钥传平台)
首次配置难度低,网页上生成令牌即可中,要生成密钥、传公钥、可能还要配 config
日常使用体验每次推送要么输令牌要么靠凭证缓存配好之后免交互,直接推
适合场景临时机器、容器、一次性环境长期使用的开发机、服务器
出问题时的排查令牌过期、权限范围不够密钥权限、agent 未加载、端口被封
凭证泄露风险令牌等同于密码,泄露需立刻吊销私钥泄露风险更大,但私钥不出机器

我的选择逻辑是:长期用的机器一律配 SSH,临时环境用 HTTPS。原因很简单,SSH 配一次管很久,日常推送零摩擦;而在一台只用来跑一次任务的容器里配密钥,纯属浪费时间,用 HTTPS 加一个短期令牌更省事。

有人担心 SSH 在某些网络环境下连不上,这确实存在。我的应对办法是给 SSH 配一个备用端口和连接保活参数,写进~/.ssh/config,这样即使默认端口不通也能走备用路径。这部分配置我在第 3 章会给出具体写法。至于具体哪些端口可用,取决于你所在网络的实际策略,我不做推荐,你自己测。

3. 关键细节:那些不写出来一定会踩的坑

3.1 身份配置:一次配错,历史全是错的

user.name和user.email是每次提交都会写进 commit 对象的元数据。这两个值配错了,后果不是"报错",而是"悄无声息地错":你的提交记录署名是个奇怪的东西,等到你想在平台上看到自己的贡献图时,发现一片空白。

配置分两级,这点很多人不清楚:

# 全局配置:对当前用户的所有仓库生效 git config --global user.name "你的显示名" git config --global user.email "你的邮箱" # 仓库级配置:只对当前仓库生效,优先级高于全局 git config user.name "另一个显示名" git config user.email "另一个邮箱"

什么场景需要仓库级覆盖?比如你在公司机器上用全局配的是个人邮箱,但公司仓库要求用工作邮箱,这时候在仓库里单独覆盖一下就行,不用来回改全局。

一个特别容易踩的点:邮箱要和平台上账号绑定的邮箱一致(或者至少是平台能识别的形式),否则平台无法把提交归属到你名下。有些平台还提供一个专用的匿名转发邮箱,用那个也能正确归属,同时不暴露真实邮箱,具体地址在账号设置里能找到。

注意:不要在配置里随手写一个不存在的邮箱,很多平台的提交归属是靠邮箱匹配的,写错了你的提交会变成"未归属"状态,事后要批量改写历史才能修,非常痛苦。

配置完立刻验证,别等提交了才发现:

git config --global --list

这条命令会把当前生效的所有全局配置打出来,你重点确认user.name和user.email两行。

3.2 认证:命令行推送为什么总被拒

这是新手最常撞的墙。现象是:地址没问题、仓库存在、命令也对,但一推送就提示认证失败。原因在于,主流代码托管平台早就关闭了用账号密码直接做命令行认证的通道,必须改用令牌或密钥。

走 HTTPS 的话,需要在平台网页上生成一个个人访问令牌,并给它勾选合适的权限范围。这里有个细节:权限给多了不安全,给少了推不上去。最小可用的范围通常是"仓库内容读写"这一项,够你拉取和推送代码。生成后令牌只显示一次,务必当场复制保存到密码管理器里。

令牌的使用方式是把用户名填账号名、密码位置填令牌:

# 推送时会提示输入用户名和密码 git push origin main # Username: 你的账号名 # Password: 粘贴令牌(输入时不显示字符,这是正常的)

很多人在这里翻车是因为粘贴令牌时终端不回显,以为没输进去,反复敲回车,结果认证失败。记住:不回显是设计如此,粘完直接回车。

如果不想每次都输,可以启用凭证缓存:

# 缓存凭证一段时间(单位秒),这里是一小时 git config --global credential.helper 'cache --timeout=3600' # 或者用 store 明文存到磁盘(安全性差,仅限个人受控机器) git config --global credential.helper store

store会把凭证明文写在~/.git-credentials里,我只建议在完全个人控制、不共享的机器上用,共享服务器上绝对不要这么干。

走 SSH 的话,流程是本地生成密钥对、把公钥内容贴到平台的 SSH 密钥设置里、验证连通性。生成命令:

ssh-keygen -t ed25519 -C "你的邮箱或备注"

这里我强烈建议用ed25519而不是老的rsa,前者密钥短、速度快、安全性好。生成过程中会问保存路径(直接回车用默认)和口令(passphrase)。口令这一项我的建议是设一个,它不是登录密码,而是给私钥加的一层加密,即使私钥文件被拷走,没有口令也用不了。当然,如果你追求免交互(比如脚本里自动推送),可以不设,但要靠文件权限保护私钥。

生成后查看并复制公钥:

cat ~/.ssh/id_ed25519.pub

输出的整行内容(以算法名开头、以备注结尾)原样贴到平台即可,注意别漏了开头或结尾。

然后验证:

ssh -T git@github.com

第一次连接会提示确认主机指纹,输入yes。成功的标志是返回一句包含你账号名的欢迎语。注意它可能会显示"不提供 shell 访问"之类的提示,那是正常的,能连上就够了。

3.3 私钥权限:这个报错 90% 的人遇到过

SSH 密钥机制有个硬性要求:私钥文件必须只有你自己可读。如果你的私钥权限是 644(其他用户可读),SSH 客户端会直接拒绝使用它,报一句类似"权限过于开放"的错误。

# 修权限,目录 700,私钥 600,公钥 644 chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub

我第一次遇到这个报错的时候,盯着"权限"两个字看了半天,心想我明明是这台机器的所有者啊。后来才明白,SSH 不管你是谁,它只检查文件模式位。这个设计是对的——它在保护你。

注意:不要把整个家目录用chmod -R一把梭改权限,那会把很多系统预期的权限搞乱。只改~/.ssh下的这几个文件。

3.4 换行符:跨平台的隐形炸弹

这个问题极其隐蔽。Windows 上的换行是 CRLF(两个字符),Linux 上是 LF(一个字符)。当仓库里同时有不同平台上改过的文件时,Git 可能把整个文件标记为"全部修改",diff 里一片红,实际上你什么都没改。

在 Linux 单机环境下,最稳妥的做法是明确告诉 Git 怎么处理:

# 提交时把 CRLF 转成 LF,检出时不转换(适合纯 Linux 环境) git config --global core.autocrlf input # 或者干脆关闭自动转换,用 .gitattributes 精确控制 git config --global core.autocrlf false

我更推荐后者加一个.gitattributes文件,在仓库根目录写明各类型的处理规则,这样规则跟着仓库走,换哪台机器都一致,不依赖每个人的本地配置。这是我吃过亏之后改过来的习惯——依赖本地全局配置的方案,在多人协作时必然出问题,因为总有人没配。

4. 完整实操:从零到推送成功的每一步

4.1 第一步:确认系统里的 Git 能用

先别急着敲命令,确认工具在位:

git --version

有版本号输出就说明装了。如果提示找不到命令,按发行版装:

# Debian / Ubuntu 系 sudo apt update sudo apt install -y git # Red Hat / CentOS / Fedora 系 sudo dnf install -y git # 老版本用 yum # Arch 系 sudo pacman -S git

装完再看一眼版本。如果版本特别老(比如低于 2.23),某些现代命令(如git switch)不支持,那就用等价的旧命令(git checkout -b)。判断标准很简单:报"未知命令"就换旧写法。

顺便配好身份,这一步别跳过:

git config --global user.name "你的显示名" git config --global user.email "你的邮箱" git config --global init.defaultBranch main

最后一行是把默认分支名设成main。现在主流平台新建仓库默认都是main,本地如果还叫master,推送时分支名对不上,会多一步手工对应。提前设好省事。

4.2 第二步:在平台上先把仓库建出来

这一步在网页上完成。要点有几个:

不要勾选自动生成 README 或 .gitignore。为什么?如果你勾了,远程仓库就不是空的,它会有一个初始提交;而你本地是空仓库,两边历史毫无关系,第一次推送会直接被拒(报"历史不相关")。新手最容易在这里卡住。要么建一个完全空的仓库,要么在本地先拉取再往里加东西。

仓库建好后,页面会给出仓库地址,形如git@<host>:<账号>/<仓库名>.git(SSH)或https://<host>/<账号>/<仓库名>.git(HTTPS)。用哪种取决于你第 3 章选的认证方式,要对应上。混用是常见错误:配了 SSH 密钥却用 HTTPS 地址,然后疑惑为什么还要输密码。

4.3 第三步:本地初始化并关联远程

进入你的代码目录,初始化:

cd /path/to/your/project git init

这一步会在当前目录建一个.git隐藏目录,所有版本信息都在里面。不要手动去改这个目录里的任何东西,它是 Git 的工作区,不是给人编辑的。

关联远程地址:

git remote add origin git@<host>:<账号>/<仓库名>.git

origin是远程仓库的默认别名,你可以叫别的名字,但没必要,生态里所有人都用origin。关联完检查一下:

git remote -v

会打出两行(fetch 和 push),确认地址没打错。地址错了后面所有操作都会失败,而且报错信息未必直观,所以这一步值得多看一眼。如果写错了,用git remote set-url origin <新地址>改,不用删了重加。

4.4 第四步:暂存与提交,理解两段式设计

Git 的提交是两段式的:先add到暂存区,再commit到仓库。很多人觉得这一步多余,直接提交不就行了?这个设计其实很有价值,它让你能精确挑选这次提交包含哪些改动。你改了三个文件,但只有一个跟当前这个功能相关,另外两个是顺手改的实验性代码——有了暂存区,你就能只把相关的那一个提上去,保持提交的语义干净。

# 看当前状态,哪些改了、哪些已暂存 git status # 暂存单个文件 git add path/to/file # 暂存所有改动(包括新增文件,不包括删除) git add . # 暂存所有改动,包括删除和重命名 git add -A # 交互式挑选,按块(hunk)暂存,这是我最常用的 git add -p

git add -p值得单独说。它会把每个改动块逐个展示给你,让你选择暂存还是跳过(y/n),甚至拆分更细的块(s)。我用它来把一次大改动拆成几个语义清晰的提交,回头查历史的时候非常舒服。前期会觉得麻烦,用顺手之后回不去。

提交时写清楚信息:

git commit -m "修复配置解析在空值时的异常"

提交信息的写法,我的经验是:第一行说清"做了什么",不要写"修改了一些东西"这种废话。半年后你回来看历史,只有具体的信息能帮你定位。如果改动稍复杂,用多行:

git commit -m "重构配置加载逻辑" -m "把散落在各处的读取收敛到单一入口,便于后续加缓存"

两个-m会自动用空行分隔,第一行当标题,后面当正文。

4.5 第五步:推送,以及第一次推送的特殊写法

推送命令:

git push -u origin main

-u(等同于--set-upstream)的作用是把本地main和远程origin/main建立跟踪关系。建立之后,以后在这个分支上直接git push就行,不用再写后面那一串。第一次推送加-u,之后可以省,这是我建议的习惯。

推送过程中你会看到类似这样的输出:

Enumerating objects: 12, done. Counting objects: 100% (12/12), done. Writing objects: 100% (12/12), 2.31 KiB | 2.31 MiB/s, done. To <host>:<账号>/<仓库名>.git * [new branch] main -> main

几个字段值得看懂:Enumerating是清点要传的对象数,Writing是实际传输的字节数,最后一行是分支映射。如果对象数很少但字节数很大,说明你提交了一个大文件(比如误提交了编译产物或数据集),这时候要停下来处理,别硬推。

关于大文件:Git 对大文件不友好,一个几十兆的二进制文件进了历史,之后每次克隆都要拖着它。我的做法是在项目一开始就写好.gitignore,把编译输出、依赖目录、日志、本地配置、数据集统统排除。写到一半发现已经提交了大文件,处理起来要走历史重写,很麻烦。预防成本远低于治疗成本,这条我吃过两次亏。

.gitignore的写法示例(针对常见项目结构):

# 依赖目录 node_modules/ venv/ __pycache__/ # 编译产物 build/ dist/ *.o *.so # 日志与临时文件 *.log *.tmp .DS_Store # 本地配置(含敏感信息,绝不能提交) .env config.local.*

如果某个文件已经被跟踪了,加进.gitignore是不起作用的,要先取消跟踪:

git rm --cached path/to/file

注意是--cached,只从索引里移除,本地文件保留。不加这个参数会把本地文件一起删掉,这是很多人手抖的地方。

4.6 第六步:验证,别只看命令没报错就以为成了

推送完做三件事确认:

  1. 本地看远程跟踪状态:git status应该显示"你的分支与 origin/main 一致"。
  2. 看提交历史:git log --oneline -5,确认最近几条提交都在,署名正确。
  3. 去平台网页上刷新,肉眼确认文件在、提交信息对、署名归属到你。

第三步不能省。我遇到过一种情况:命令返回成功,但推到的是一个同名的旧仓库地址(远程地址配错),网页上看什么都没有。肉眼看一眼,比什么都可靠。

5. 常见问题与排查实录

5.1 报错速查表

下面这张表是我这些年攒下来的高频问题,按报错关键词排列,遇到问题先在这里找。

报错关键词典型原因处理办法
command not foundGit 未安装或不在 PATH用包管理器安装,确认git --version
Authentication failed用了账号密码而非令牌,或令牌过期/权限不足重新生成令牌并勾选仓库读写权限
Permission denied (publickey)公钥未上传、密钥未加载、私钥权限过宽检查公钥是否贴对、ssh -T验证、chmod 600
Host key verification failed主机指纹未确认或被变更首次连接输yes;变更时先确认再更新 known_hosts
rejected ... non-fast-forward远程有你本地没有的提交先git pull --rebase再推,别用强制推
refusing to merge unrelated histories本地和远程是两条独立历史建空仓库;或确认后加--allow-unrelated-histories
remote: Support for password authentication was removed平台已关闭密码认证改用令牌或 SSH
File exists/ 已跟踪文件忽略无效文件已在索引中git rm --cached后重新提交
error: insufficient permission for adding an object.git目录属主或权限不对修正目录属主,别用 sudo 混跑 git
推送卡住无响应网络到目标端口不通检查连通性,SSH 可配备用端口

5.2 三个我亲身踩过的坑

坑一:用 sudo 跑 git,把仓库权限搞乱。

有次在一台新机器上装完 Git,顺手用sudo git init,结果整个.git目录属主变成了 root。之后用普通用户提交,一路报权限错误。更麻烦的是有些操作部分成功部分失败,状态变得很乱。教训很明确:Git 命令永远用普通用户跑,不要加 sudo。需要系统级操作的时候单独用 sudo,别和 git 混在一起。已经搞乱了就用sudo chown -R 用户名:组名 /path/to/repo修回来。

坑二:强制推送覆盖了远程的改动。

早期我习惯遇到推送被拒就git push -f,觉得省事。有一次在另一台机器上改了点东西推上去了,本机不知道,一个强制推直接把那边的提交抹掉了。虽然纯个人项目损失不大,但这个习惯极其危险,在协作场景里是事故级的。后来我给自己定了死规矩:除非确认这个分支只有我一个人在用,并且明确知道要丢弃什么,否则绝不加-f。被拒了老老实实拉取合并。

坑三:把含密钥的配置文件提交上去了。

有次赶时间,把一份带数据库连接串的本地配置一起提交推了上去。虽然及时发现并删了文件,但历史里还留着,要彻底清除得重写历史。平台的密钥扫描会在几分钟内发告警邮件,那一刻真的后背发凉。从此我的项目模板里第一个文件永远是.gitignore,.env类和*.local.*一律排除。如果真发生了,处理顺序是:立刻吊销那个凭证(这是第一优先,改历史是第二步)、清理历史、强制推、通知可能的协作方重新克隆。

5.3 排查的基本方法论

遇到问题别乱试命令,按这个顺序走,能省大量时间。

第一步,看完整报错。终端里的报错往往有好几行,重点在最后两三行,但前面几行常有关键上下文。别只盯着第一行的error字样。

第二步,确认当前状态。git status和git remote -v这两条命令几乎能定位一半的问题:你在哪个分支、有哪些未提交改动、远程地址对不对。

第三步,分层定位。按第 2 章的四层模型判断问题出在哪:系统层(命令能不能跑)、身份层(配置对不对)、认证层(能不能连上远程)、仓库层(分支和历史对不对)。ssh -T能单独验证认证层,非常有用。

第四步,最小化复现。如果问题复杂,在一个空目录里重新走一遍最小流程,看是否还复现。这一步能排除掉大量"本地环境特殊状态"造成的干扰。

第五步,查历史操作。git reflog记录了你所有 HEAD 移动,误操作后想找回之前的提交,这里是救命稻草。git reset --hard搞丢了东西,先用 reflog 找到那个提交的哈希,再恢复。

提示:git reflog的记录默认保留一段时间,不是永久的。重要节点该打标签就打标签(git tag),别指望 reflog 兜底一切。

5.4 几个容易被忽略的实用技巧

用别名减少打字。把常用命令配成短别名,效率提升明显:

git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.last "log -1 HEAD --stat" git config --global alias.unstage "reset HEAD --"

配完git st就是git status。别配太多,配到肌肉记忆里常用的那几个就行,配多了换台机器反而不会用了。

提交前先看 diff。git diff看未暂存的改动,git diff --staged看已暂存的。养成提交前扫一眼的习惯,能拦住大量误提交,比如调试用的打印语句、临时改的端口号。

用git log的图形模式看分支结构:

git log --oneline --graph --all --decorate

这一条能把整个分支拓扑画出来,合并关系一目了然。排查"为什么我的提交不见了"这类问题时,先看这个图,比瞎猜快得多。

换行符和文件模式的噪音。如果git status显示一堆你没动过的文件被修改了,先怀疑换行符(第 3.4 节)或文件权限位变化。后者可以用git config core.fileMode false关掉对权限位的跟踪,在跨文件系统(比如挂载的共享目录)里工作时这个设置很有用。

推送前先拉一下。哪怕确定只有你一个人在改,git pull --rebase一下也就几秒钟,能避免大部分"被拒"的情况。--rebase和默认的 merge 的区别在于,前者把你的本地提交接到远程最新提交之后,历史是一条直线,看起来干净;后者会生成一个合并提交。个人项目我倾向 rebase,协作项目按团队约定来。

6. 一套可复用的日常流程

把上面所有东西收拢成一个每次开新项目都能照着走的流程,我自己是这么干的,写在这里供参考。

新项目初始化:平台上建空仓库(不勾任何自动生成项)→ 本地git init→ 配好身份 →git remote add origin→ 写.gitignore→git add→ 首次提交 →git push -u origin main。这套走完,项目就活了。

日常改动:git status看状态 →git diff扫一眼改动 →git add -p挑选 →git commit -m "具体描述"→git pull --rebase→git push。六七条命令,熟练之后一分钟内完成。

分支干活:git switch -c feature-xxx→ 改代码、提交若干次 →git switch main→git pull --rebase→git merge feature-xxx(或先在平台上发起合并请求)→ 推送 → 删掉特性分支。分支别留太多,做完就删,不然一段时间后你自己都分不清哪个是哪个。

定期维护:隔一段时间跑一次git remote prune origin清理远程已删除分支的本地引用,跑一次git gc整理对象库。这些不是必须的,但能让本地仓库保持健康。

最后分享一个我自己定的小规矩,它帮我避免了很多麻烦:每次推送前,问自己一句"这条提交信息,三个月后的我看得懂吗"。看不懂就重写提交信息。代码是写给未来的自己看的,提交历史也是。这个习惯看起来小题大做,但当你需要回溯某个 bug 是什么时候引入的时候,一份清晰的提交历史能省下你半天的时间。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进