很多新手第一次用 Git 的时候,最容易卡住的不是命令本身,而是"我明明按教程敲了,怎么就一直报错"这个环节。尤其是刚接触 GitHub 的朋友,经常在 push 那一步被网络、权限、仓库配置折腾到怀疑人生。这篇文章我打算按自己这些年带新人的经验,把"第一次把本地项目推到 GitHub"这条路上所有可能会踩的坑,从头到尾捋一遍。全程用最直白的方式讲,不绕弯子,你看完直接照着做就行。
先说清楚这篇文章能解决什么问题:从零开始装 Git、完成基础配置、在 GitHub 上建仓库、生成并配置 SSH 密钥、把本地项目完整推送到远程,以及在这一过程中最常见的报错怎么处理。项目级别从最简单的单文件 demo 到多人协作的完整工程都适用,只要你能把自己本地的文件夹变成"有 Git 管理的项目",后面所有流程都是一样的。
1. 内容整体设计与思路拆解
1.1 这套流程到底在做什么
先想明白一件事——Git 和 GitHub 是两样东西。Git 是一个运行在你电脑上的版本管理工具,负责记录你对文件的每一次改动;GitHub 是一个基于 Git 的远程代码托管平台,相当于帮你在云端建了一个备份仓库。两者通过 SSH 或 HTTPS 协议通信,把你本地的提交记录同步到远端。
所以整个"第一次上传"的流程,本质上就是在做三件事:
- 让电脑具备 Git 环境,并且告诉 Git"你是谁"。
- 在 GitHub 上开一个空仓库作为远端目标。
- 把本地文件夹初始化成 Git 仓库,和远程仓库建立连接,把内容推送上去。
这三件事本身都不难,难在每一件事都有几个容易出错的边缘情况。比如"Git 装了但环境变量没配好"、"SSH key 生成了一堆但根本没把公钥加进 GitHub"、"push 的时候远程仓库已经有 README 文件导致冲突"。我后面会一项项把这些情况拆开讲。
1.2 为什么推荐用 SSH 而不是 HTTPS 上传
GitHub 支持两种远程连接方式:HTTPS 和 SSH。很多教程默认用的是 HTTPS,因为配置起来最简单——push 的时候输入用户名和密码(现在是输入个人访问令牌)就可以了。
但我个人的建议是走 SSH。原因有几条:
- SSH 公钥配置一次之后,后续 push、pull、clone 都不需要反复输凭证,真正的一次配置终身使用。
git push的时候输入密码这种操作在自动化和脚本场景下特别烦人,而 SSH 密钥认证天然适合脚本调用。- 在网络安全方面,SSH 的密钥对机制比密码认证更可控,你可以随时在 GitHub 后台撤销某台电脑的访问权限。
唯一的代价是第一次配置 SSH 密钥需要多花几分钟。但这个过程只需要做一次,之后就完全不操心了。
1.3 目录结构与示例项目说明
为了让教程足够具体,我后面会用一个叫my-first-project的文件夹当示例。这是一个非常普通的项目目录,里面有index.html、css/style.css、js/main.js三个文件,模拟一个常见的前端静态页面结构。
如果你手上已经有现成项目,直接拿自己的项目替换即可,命令完全一样。如果只是想先练习一遍流程,手动创建这么个目录也行。
2. 环境准备:Git 安装与初始配置
2.1 Windows / macOS / Linux 三种系统下的安装办法
Windows 系统
去 Git 官网下载 Windows 版本的安装包,下载下来以后一路 Next 安装就行。这里我特别提醒几个安装选项,新手最容易在这几处踩坑:
- Adjusting your PATH environment:务必选 "Git from the command line and also from 3rd-party software"(默认选项),否则后面在 CMD 或 PowerShell 里用不了
git命令。 - Choosing the SSH executable:选 "Use bundled OpenSSH",这样 Git 自带的 SSH 工具就能直接生成密钥,省得再去配 Windows 的 OpenSSH。
- Line ending conversions:选 "Checkout Windows-style, commit Unix-style line endings"(默认第一项)。这个选项的意思是,从仓库 checkout 出来的文件用 Windows 换行符,提交到远程时自动转成 Unix 换行符。对于团队协作项目,这个默认配置能避免大量"整个文件都被标记为修改"的假冲突。
安装完成后,打开新的 CMD 或 PowerShell 窗口,输入:
git --version如果你能看到git version 2.x.x.windows.x之类的输出,说明安装成功。
macOS 系统
macOS 上最省事的方式是安装 Xcode Command Line Tools,它会附带 Git。在终端输入:
xcode-select --install弹窗出来后点确认,等它下载完即可。或者用 Homebrew 安装新版 Git:
brew install git个人感觉 Homebrew 的方式更可控,因为你拿到的永远是较新的版本,而 Xcode Command Line Tools 附带的版本有时候会偏旧。
Linux 系统
Debian/Ubuntu 系列用:
sudo apt update sudo apt install gitCentOS/RHEL/Fedora 系列用:
sudo yum install git或
sudo dnf install git2.2 首次使用必须做的两行配置
Git 安装好以后,第一件要做的事不是建仓库,而是告诉 Git 你是谁。这一步的作者信息会写入每一次 commit 记录里,相当于你在这套版本体系里的身份标识。
打开终端,运行:
git config --global user.name "你的名字" git config --global user.email "你的邮箱"名字和邮箱用什么都可以,但强烈建议用 GitHub 上注册的那个邮箱。重要原因:GitHub 会把提交记录里的邮箱和账号邮箱关联起来,用来在贡献图上标记"谁提交的"。如果你用了另一个邮箱,GitHub 的贡献图也可能统计不到你的提交。
用--global参数表示这是全局配置,对当前用户的所有仓库生效。查看当前配置可以运行:
git config --global --list输出里应该能看到user.name和user.email两行,确认无误就完成了基础配置。
这里补充一个很多人不知道的小技巧,--global只是针对当前系统的当前用户。不同的项目完全可以设置不同的用户名和邮箱——比如公司项目用公司邮箱,个人项目用个人邮箱。去掉--global,在具体仓库目录下单独配置即可。
2.3 安装完成后建议立刻验证的事项
装完 Git 后别急着建仓库,先花两分钟做一次体检。
验证 Git 是否能正常工作:
git help如果终端弹出 Git 的帮助文档,说明基础命令没问题。然后再验证一个容易被忽略的项——Git 自带的 SSH 工具是否可用:
ssh -T git@github.com这时候大概率会报Permission denied (publickey)错误。别慌,这是正常的,因为你还没配置 SSH 公钥。只要不是提示command not found或ssh: Could not resolve hostname github.com,说明 SSH 客户端是正常可用的。
3. 注册 GitHub 账号并创建第一个远程仓库
3.1 注册与登录
如果你还没有 GitHub 账号,先去官网注册。打开网站后,依次填写邮箱、密码和用户名这三个信息。这里有个实用建议:用户名决定了你后续所有代码仓库的公开地址前缀,最好选择一个简洁、正式、不会后悔的名字。因为仓库链接里会一直携带这个名字,后期改名会连带着 GitHub 给的重定向逻辑一起折腾。
注册后 GItHub 会要求验证邮箱。这个步骤很多人会跳过,但建议尽早完成,因为未验证邮箱的账号在某些操作上会受到限制。
3.2 手动创建一个空仓库
登录后,点击页面右上角的"+"号,选择 "New repository"。
进入创建页面后需要设置如下几项:
- Repository name:仓库名,建议和本地文件夹同名。不要用中文或空格,用连字符
-分隔单词。 - Description:项目描述,可填可不填,但填了会让仓库看起来更规范。
- Public / Private:公开仓库任何人在互联网上都能看到;私有仓库仅自己(或你邀请的协作者)可见。自己练手用推荐 Public,不担心敏感信息泄露的话。公司项目或包含敏感代码的则必须选 Private。
- Initialize this repository with:这里我强烈建议什么都不要勾选,包括 README、.gitignore、License。原因是你本地已经有项目文件了,如果在创建远程仓库时初始化了 README 或 .gitignore,本地和远程的历史就产生了分叉。第一次 push 的时候,Git 会把两边当成两个不相干的仓库历史,你不得不处理 merge 冲突或者用
git pull --rebase之类的命令去整合。对新手来说这是完全没有必要的一步。
创建完成后,页面会显示一个仓库地址,形式如下:
git@github.com:你的用户名/你的仓库名.git这就是后面要添加到本地仓库的远程地址。先复制下来,后面要用。
3.3 创建仓库后先别急着初始化文件
很多人创建完仓库后,看到 GitHub 上展示的示例命令会忍不住直接照着敲。比如页面会提示你:
echo "# 项目名" >> README.md git init git add README.md git commit -m "first commit" git remote add origin git@github.com:用户名/仓库名.git git push -u origin main这套命令本身没问题,但有个小陷阱:它默认你的本地目录是空的,或者你只是想提交 README 这一个文件。如果你已经是"本地有完整项目代码"的状态,最好跳过echo那一步,直接用git init初始化你的项目根目录,然后按自己项目需要去写.gitignore(如果不需要忽略文件,也可以省)。
4. SSH 密钥配置:让本地和 GitHub 互相信任
4.1 为什么要用 SSH 密钥
想象你有一把保险柜的钥匙和一把锁。SSH 密钥就像是这样的机制:你手上有一把私钥(钥匙),GitHub 的服务器上存了一把公钥(锁)。只有拿着私钥的本地电脑,才能打开对应公钥的"锁",也就是访问你的 GitHub 仓库。这种方式的优势在于,私钥永远只在你的电脑上,不会经过网络传输,安全性比输入密码高得多。
4.2 生成密钥对的具体命令
打开终端(Windows 用户建议直接打开 Git Bash),输入以下命令:
ssh-keygen -t ed25519 -C "你的GitHub注册邮箱"回车后会提示你输入文件保存位置:
Enter file in which to save the key (/c/Users/你的用户名/.ssh/id_ed25519):直接回车使用默认路径即可。
再提示你输入 passphrase(密码短语):
Enter passphrase (empty for no passphrase):这里可以直接回车留空,也可以输入一段密码。区别在于:留空的话,每次 push 不需要额外输入;设置了密码短语的话,每次使用私钥时都要求输入一次,安全性更高但会多一步操作。个人项目建议留空,公司电脑建议设置。
生成完成后,终端会显示一串随机图案(key fingerprint)。你在默认路径下会得到两个文件:
id_ed25519:私钥,绝对不要给任何人id_ed25519.pub:公钥,需要加到 GitHub 上
4.3 把公钥添加到 GitHub 后台
查看公钥内容,运行:
cat ~/.ssh/id_ed25519.pub然后复制输出的整行内容。到 GitHub 网站,点击右上角头像 → Settings → SSH and GPG keys → 点击 "New SSH key"。
在 Title 里填一个方便识别的名字,比如 "My-Laptop";在 Key 文本框里粘贴刚才复制的公钥内容。最后点击 "Add SSH key"。
4.4 测试 SSH 连接是否成功
配置完成后,在终端运行:
ssh -T git@github.com如果之前没连过 GitHub,会看到一条提示:
The authenticity of host 'github.com (IP地址)' can't be established. Are you sure you want to continue connecting (yes/no)?输入yes回车。如果看到下面这句,说明 SSH 已经配置成功:
Hi 你的用户名! You've successfully authenticated, but GitHub does not provide shell access.这句话意思是你已经通过认证,但 GitHub 不允许 shell 登录,这是完全正常的提示,不要误解为报错。
4.5 多台电脑或多账号时的注意事项
如果你有办公电脑和家用电脑,每台电脑上都要各自生成一个密钥对,并把各自的公钥都加到 GitHub 账号下。这是允许的,GitHub 在设计上就支持一个账号绑定多把公钥。
如果你在配置过程中遇到过"疑似有人用你的账号提交代码"的问题,可以去 GitHub 后台查看账号下绑定的所有 key,把不认识的删掉即可。
5. 核心环节实操:本地项目上传到 GitHub 完整流程
5.1 初始化本地 Git 仓库
进入你的项目根目录。比如项目在D:\projects\my-first-project,在终端里执行:
cd /d/projects/my-first-project接下来初始化 Git 仓库:
git init运行完看看目录里有没有多出一个.git文件夹(默认隐藏了,用ls -a才能看到)。这个.git文件夹是 Git 的"数据库",所有版本记录、分支信息、配置信息都存这里。所以删除.git文件夹就等于删除了整份版本历史。平时不需要手动改它。
运行git init后 Git 默认创建的分支名可能是master,也可能因版本而异。现在 GitHub 默认的主分支名是main,不过命名不同的问题后面统一处理就行。
5.2 编写并核实 .gitignore(可选但建议)
如果你的项目里有不需要纳入版本控制的文件——比如本地的环境配置、密钥文件、依赖包目录(node_modules)、编译产物(build/dist)——就应该在项目根目录创建一个.gitignore文件。
示例内容:
node_modules/ dist/ build/ .env *.log .DS_Store.gitignore是在 commit 之前生效的,这意味着你先写这个文件,再执行git add,Git 就会自动跳过规则里匹配的文件。
这里有个新手常踩的坑:如果先git add .了,再创建.gitignore,那之前已经被 add 的文件并不会自动被移除。需要先git rm -r --cached把它们从 Git 的暂存区删除,再重新 add 才会生效。所以最优顺序是先写好.gitignore,再git add。
5.3 检查文件状态:git status 的正确用法
每次提交前,养成看git status的习惯。先运行:
git status此时终端会显示当前仓库里有哪些未被跟踪的文件(untracked files),也就是 Git 还不认识的"新面孔"。例如:
Untracked files: (use "git add <file>..." to include in what will be committed) css/ index.html js/git status输出的信息量其实很大,它是 Git 的"体检报告",告诉你当前处于哪个分支、暂存区里有什么、工作区有没有未提交的改动。新手不用记参数,只要会看这段输出就能判断当前状态。
5.4 将文件加入暂存区,并完成第一次提交
执行:
git add .注意git add和git commit的区别。git add是把文件从工作区(你磁盘上的实际文件)挪到暂存区(索引区);git commit是把暂存区里的这些文件正式拍一张"快照"写入版本历史。
打个比方,git add相当于你在商店把商品放进购物车,git commit相当于去收银台结账。不结账,东西还不算买下来;不 commit,改动还不算真正记录进 Git 历史。
接着执行:
git commit -m "first commit: 初始化项目结构"-m后面是提交说明。提交说明应该清晰、简短,描述这次提交做了什么。比如:
"feat: 新增用户登录页面""fix: 修复首页在移动端错位的问题"
不要用这种说明:"update"或"111"。项目提交历史是给别人(包括未来的你自己)看的,好的提交信息能省很多沟通成本。
执行完 commit 后可以再次运行git status,如果显示 "nothing to commit, working tree clean",说明工作区已经干净,当前内容已经记录进了 Git 历史。
5.5 把主分支命名为 main
前面提到过,不同 Git 版本初始化的默认分支名可能不同。统一命名为main,和 GitHub 保持一致,省得以后 push 时遇到分支名不匹配的问题。
git branch -M main-M是强制重命名,即使main分支已经存在,也会强制覆盖。
5.6 添加远程仓库地址
现在把之前复制的 GitHub 仓库地址添加进来。在项目目录里运行:
git remote add origin git@github.com:你的用户名/你的仓库名.git这里的origin是远程仓库的别名。你可以随便起别的名字,但origin是社区约定俗成的默认名字,不建议改。添加后可以查看远程地址:
git remote -v输出应该显示两行,分别对应 fetch 和 push 的地址:
origin git@github.com:你的用户名/你的仓库名.git (fetch) origin git@github.com:你的用户名/你的仓库名.git (push)如果你发现之前已经配置过远程地址,或者配置错了,可以用以下命令修改:
git remote set-url origin git@github.com:你的用户名/你的仓库名.git5.7 推送到远程仓库:第一次 push
执行:
git push -u origin main解释一下这个命令:
push:把本地提交推送到远程。-u是--set-upstream的简写:表示把本地分支和远程分支关联起来。以后你在这个分支上直接执行git push或git pull,就不用再指定远程名和分支名了。origin:远程仓库别名。main:本地分支名。
如果一切顺利,终端会出现类似这样的输出:
Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Writing objects: 100% (3/3), 262 bytes | 262.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), reused 0 (delta 0) To github.com:你的用户名/你的仓库名.git * [new branch] main -> main branch 'main' set up to track 'origin/main'.这时去 GitHub 仓库页面刷新一下,就能看到你本地的文件已经全部出现在远程仓库里了。
5.8 推送后必须养成的验证习惯
推送成功不代表万事大吉。我通常会在 push 完成后到 GitHub 页面上确认这几个点:
- 文件列表是否完整,关键文件是否都在;
- 提交记录(Commits)那一栏是否显示了你刚才的提交;
- README 文件是否在页面下方正常渲染。
这些检查只需要一分钟,但能帮你在第一时间发现"有的文件没被提交"或者"提交信息不对"之类的问题,避免后面返工。
6. 使用 HTTPS 方式的备选方案
如果因为某些原因你不想配置 SSH,也可以全程用 HTTPS 方式上传。不过 GitHub 早已不支持在命令行里直接输入账号密码进行身份认证,你需要用Personal Access Token(个人访问令牌)代替密码。
创建 Token 的路径是:GitHub 头像 → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token。
创建时勾选repo范围即可,这是操作仓库内容的基础权限。生成以后 Token 只显示一次,务必复制保存好。
后续添加远程地址时用 HTTPS 链接:
git remote add origin https://github.com/你的用户名/你的仓库名.git第一次 push 时,Git 会弹出窗口让你输入用户名和密码。在密码一栏粘贴 Token 而不是账号密码。之后 Windows 上的 Git 凭据管理器会记住你的 Token,后续操作就不需要再输入了。
个人体会是 HTTPS 方式的首次配置确实更快,适合临时提交或者只偶尔用一下的场景。但如果你打算长期在命令行里操作 Git,还是 SSH 一劳永逸。
7. 常见问题与排查技巧实录
7.1 push 时报错 "repository not found"
这个报错在 SSH 方式下很常见,通常有三种原因:
- 远程地址拼错了,仓库名或者用户名大小写写错。GitHub 用户名和仓库名是区分大小写的。
- GitHub 账户没有这个仓库的访问权限。如果你用的是别人的仓库,或者本地配置的 SSH key 不属于仓库拥有者,就会报这个错。
- 在 GitHub 上创建的仓库还是空的,并且你用的地址和创建页面显示的地址不一致。
排查方式:先运行git remote -v看当前远程地址是否正确,再运行ssh -T git@github.com确认当前 SSH key 关联的是哪个账号。如果账号对不上,去检查是否在别的路径下存在另一个.ssh/id_ed25519被加载了。
7.2 push 时报错 "Permission denied (publickey)"
这表示 SSH 认证失败。可能是以下原因:
- 公钥没添加到 GitHub 后台:把
.pub文件内容重新复制一次,确认粘贴时没有多出空格或空行。 - 添加公钥后没有等生效:一般来说立即生效,但偶尔也有延迟。
- 终端没有加载 ssh-agent 里面的密钥:如果之前设置过 passphrase,ssh-agent 需要手动加载一次:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519如果还是不行,用ssh -vT git@github.com查看详细连接日志,看它最终用了哪个 key 文件去认证了。
7.3 push 时报错 "failed to push some refs"
这个问题太经典了。常见的完整报错是:
! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:用户名/仓库名.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally.出现这个提示,说明远程仓库里有本地没有的提交。最常见的原因是:你之前在 GitHub 网页上创建仓库时勾选了 README 初始化,或者后来在网页端直接修改过文件产生了新的提交。
处理方法:
git pull --rebase origin main--rebase的意思是把你本地的提交"放到"远程提交的上面,形成一条直线历史,比默认的合并(merge)看起来清晰得多。
执行完再 push:
git push -u origin main如果pull --rebase过程出现冲突,Git 会提示你哪个文件冲突了。用编辑器手动解决冲突后执行:
git add 冲突文件 git rebase --continue最后再 push。
7.4 Windows 下提示 "warning: LF will be replaced by CRLF"
这是 Windows 平台的换行符警告,不是错误。原因是 Windows 使用 CRLF(回车+换行)作为换行符,Linux/macOS 使用 LF(换行)。Git 在提交时默认会把 CRLF 转换成 LF 存入仓库,检出时根据系统配置转回。
如果团队全员都用 Windows,或者全员都用 macOS/Linux,这个问题基本不会引发实际冲突。最麻烦的是混合系统协作,可能导致 Git 觉得"整个文件都改了"。
处理方案在 git 配置层面有几个选择:
# 提交时转 LF,检出时转 CRLF,Windows 默认推荐 git config --global core.autocrlf true # 提交时转 LF,检出时不转,macOS/Linux 推荐 git config --global core.autocrlf input # 关闭自动转换 git config --global core.autocrlf false我个人实践后最推荐的做法是:给根目录添加一个.gitattributes文件,显式声明仓库使用 LF 作为标准换行符:
* text=auto eol=lf这样无论谁在哪个平台提交,仓库里的换行符都是统一的 LF,能最大程度避免混合平台的换行符灾难。
7.5 GitHub 页面打不开或下载速度很慢
在国内访问 GitHub 偶尔会遇到连不上或者速度奇慢的情况。原因不展开说了,直接给几个实操技巧,按推荐程度排序:
第一招:检查 hosts 文件是否被改乱。很多人早期为了特殊用途改过 hosts 文件,后来忘了清理。改坏的情况下,访问 GitHub 会超时或跳转到不正确的 IP。Windows hosts 路径是C:\Windows\System32\drivers\etc\hosts,macOS/Linux 是/etc/hosts。先检查里面有没有 github.com 相关条目,如果有而且导致访问异常,注释掉或删除相关行。
第二招:设置代理。如果你本地有可用的 HTTP 代理(可以是公司网管分配的、也可以是软件提供的),在 Git 中可以这样设置:
git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy http://127.0.0.1:7890不需要代理时取消:
git config --global --unset http.proxy git config --global --unset https.proxy第三招:切换远程地址试试。如果你用的是 SSH 方式连不上,换 HTTPS 地址试试,有时候是 SSH 的 22 端口被网络环境屏蔽导致的。也可以测试 GitHub 的 SSH over 443 端口:
ssh -T -p 443 git@ssh.github.com如果 443 端口能通,那就在 SSH 配置里加一段:
Host github.com Hostname ssh.github.com Port 443 User git配置方法是在~/.ssh/config文件(没有就新建一个)里加上上述内容。
第四招:使用 GitHub 镜像站或加速服务。这个方案主要是针对"下载 release 资源"和"访问 GitHub 页面"这些场景的,对纯git push/pull操作的作用不大,因为命令行走的是 git 协议。
第五招:如果公司网络有合规的加速方案就用公司方案。很多公司内部有 Git 代理或镜像服务,具体配置看公司 IT 文档。
7.6 所有操作都正确但 push 依然超时
这种情况多半是网络层面的问题。先做两个测试:
ping github.com如果 ping 不通,说明 DNS 解析或网络路由有问题。然后:
git ls-remote https://github.com/用户名/仓库名.git这条命令只探测远程仓库是否可达,不实际拉代码。如果 ping 得通但 ls-remote 超时,可能是某些端口被限制。如果两个都失败,考虑换网络(比如手机热点)排除本地网络问题。
7.7 分支名不统一:main 还是 master
老项目默认分支叫master,GitHub 在2020年以后新仓库默认是main。如果你之前初始化仓库时是master,push 的时候指定成main了,本地分支名就会和远程不一致,容易混淆。
修正方式:
git branch -M main这条命令可以随时把当前分支强制重命名为main。如果远程已经是main,本地改名后直接 push 即可。
7.8 commit message 写错了怎么办
很多人第一次提交时都会犯这个错:git commit -m "init",后来想改成"初始化项目"。
改最近一次提交的信息:
git commit --amend -m "初始化项目"这个命令会把最近一次提交替换成新提交,新的提交会生成新的 hash,且原来的提交记录被覆盖。所以如果这个提交已经 push 到远程,且是多人共享的分支,不要随便 amend,因为会把历史搞乱。
还没 push 的提交随便改,push 之后的提交宁可重新提交一个也别 amend。
7.9 不小心 add 了不该提交的文件
如果只是 add 了但还没 commit:
git rm --cached 文件名--cached表示只从暂存区移除,不删除本地文件。
如果已经 commit 了,但还没 push:
git reset --soft HEAD~1这个命令撤销最近一次提交,但保留所有改动的文件在暂存区。然后你可以修改.gitignore,重新 add 和 commit。
7.10 GitHub 邮箱隐私保护设置
用 GitHub 网页操作创建仓库、提交 issue 时,你的邮箱会暴露在公开页面。GitHub 提供了一个隐私选项:在 Settings → Emails 里勾选 "Keep my email addresses private",GitHub 会给你生成一个用户名@users.noreply.github.com的匿名邮箱。
勾选后,基于网页的提交(比如在网页端编辑文件)都会用匿名邮箱。但这个设置不影响你本地 Git 的user.email配置,如果你希望本地提交也隐藏邮箱,把user.email配成那个 noreply 邮箱即可。
8. 进阶建议:首次上传后的日常操作习惯
8.1 每次修改代码后的三连命令
项目上传完了不代表结束,日常开发里你会反复用这样一套操作:
git add . git commit -m "描述本次修改" git push这三条是 Git 最核心的"三连"。很多新人会疑惑,为什么要先 add 再 commit 再 push,不能一次搞定吗?原因在于:git add可以精确控制要纳入这次提交的文件;git commit生成一个带描述的提交节点;git push把本地所有提交同步到远程。把这三步拆开,你才能做到"只提交该提交的,不误提交不该提交的"。
在实际操作中,比如你改了index.html和README.md,但只想提交index.html,就可以只git add index.html,README 留到下次提交。
8.2 研究别人的项目:git clone 与 fork 的区别
上传自己的项目是第一步,接下来大概率你会去研究别人的开源项目。这时候会遇到两个概念:git clone和fork。
git clone:把远程仓库完整复制到本地。只要这个仓库是公开的,任何人都可以 clone。fork:在 GitHub 上把别人的仓库复制一份到你的账号下,之后你可以随意修改这个副本,然后通过 Pull Request 把改动提交回原仓库。
实操中,如果你只是想看看某个项目的代码,直接 clone 就行。如果你准备给开源项目贡献代码,先 fork 再 clone。
git clone git@github.com:用户名/仓库名.gitclone 下来后,默认只有一个远程仓库别名origin,并且本地会自动创建一个和远程主分支同名的分支。
8.3 分支对新手意味着什么
分支是我见过新手最容易绕晕但也最值得早点学会的概念。简单理解,分支就是"平行时空"。你在main分支上稳定跑着的代码,想要尝试一个新功能,又怕把主分支搞坏,这时可以开一个dev-feature分支,在这个分支上随便折腾。折腾好了,合并回main;折腾坏了,直接删除分支,对主分支零影响。
常用命令:
# 创建并切换到新分支 git checkout -b dev-feature # 切回 main 分支 git checkout main # 把 dev-feature 合并到当前分支 git merge dev-feature # 删除本地分支 git branch -d dev-feature新手刚开始不需要深入理解分支的内部机制,只要学会创建、切换、合并删除这几个操作,就足以应付绝大多数日常场景了。
我见过不少人的工作流是:一年到头所有的代码全在 main 分支上提交,编辑文章也是。一个人开发的时候这没问题,但只要是两人以上协作,就要尽早养成开分支的习惯。
8.4 用 .gitignore 从根源减少误提交
前面提到过.gitignore,这里我再多说一点实际经验。很多新人 commit 了一些不该提交的敏感文件(比如.env数据库密码、本地调试的config.local文件),然后 push 到公开仓库,再匆匆删掉重新 push——但这已经没用了,因为在 Git 历史里这些敏感信息是永久存在的,任何 clone 过你仓库的人都能通过历史版本翻出来。
所以最好的策略是预防:在项目最开始就创建.gitignore,把可能的敏感文件先排除在外。
GitHub 官方提供了针对各种语言和框架的 .gitignore 模板,在创建仓库时或者 GitHub 的 gitignore 仓库里都能找到。建议直接套用模板,再根据项目情况微调。
8.5 使用 --force 的禁忌
新手最容易在 push 的时候加-f或--force,因为 "fatal: prevent force pushing" 这类提示经常被当作必须克服的障碍。事实恰恰相反:force push 会强制覆盖远程分支的历史。一旦你强制推送了,远程仓库里原本的记录就被你的本地历史替换了,如果别人的提交在上面,它们的改动就全丢了。
什么时候可以用--force?比如你确定远程仓库的历史已经没有价值(比如刚上传的新仓库,想推一版干净的),或者你在自己的个人分支上操作。多人共用的主干分支,永远不要 force push。
必要的时候用--force-with-lease替代--force。它的意思是:只有在远程分支没有被别人修改过的情况下才强制推送,相当于加了一层保险。
9. 我的一些实际操作体会
第一次把项目推上 GitHub 这个流程,我现在闭着眼睛都能三步走完:配置 SSH、初始化仓库、push。但对于第一次接触的人来说,每个环节里的报错信息都像迷宫里的死胡同,怎么看都像是自己电脑出了问题,其实是流程里某个细微的地方没对齐。
我见过最多的情况就是三种:SSH key 公钥没粘全、初始化远程仓库时勾了 README、push 命令少写了-u。这三种各对应一类问题,但它们的报错都指向同一个结果:push 失败。如果你能提前知道这些坑在哪,整个过程会顺畅得多。
如果你在实操过程中遇到了这篇教程里没提到的问题,先别急着到处复制粘贴代码。我建议按这个顺序自检:先git status看本地状态,再git remote -v看远程地址,最后ssh -T git@github.com看认证状态。这三条命令的输出,能覆盖我自己平时遇到的大部分情况。
有一点要提醒大家,Git“失败不可怕,难的是不知道失败的原因”。用git status和各类报错信息,Git 其实一直在告诉你它当前的状态,只要你会读这些信息,你就能自己诊断八成的问题。
这套流程走完一遍之后,你就不再是 "Git 小白"了。你会对自己项目的每一次提交和每一次回滚都有掌控感,这种掌控感,是所有版本管理工具的最终价值所在。后续有精力的话,可以继续研究分支合并、回滚、子模块等内容,但那是另一个故事了。今天这篇,足够你先把第一个项目稳稳当当地送上网。