Git 项目从零上传到 GitHub
本文记录在 Windows PowerShell 中,将本地项目从零初始化并上传到全新 GitHub 仓库的完整流程。
本文的目标是上传项目源码,不是发布 Hexo 网站。两者的区别是:
- 上传源码到 GitHub:保存
_config.yml、source/、themes/、package.json等项目文件。 - 发布 Hexo 网站:将 Hexo 生成的网站部署到 GitHub Pages,属于另一条部署流程。
一、理解完整链路
1 | 项目文件 |
几个容易混淆的概念:
git init:让一个普通文件夹成为本地 Git 仓库。git add:选择准备提交的文件,并放入暂存区。git commit:把暂存区内容保存为一次本地版本记录。git remote:管理本地仓库对应的远程仓库地址。git push:把本地提交上传到 GitHub。origin:远程仓库的常用别名,不是固定关键字。main:当前使用的主分支名称。
二、本次练习采用的安全方案
当前原项目 d:\code\blog 已经有 Git 历史和远程仓库。为了完整练习 git init,同时不破坏原项目,建议使用下面的方案:
- 复制项目到一个新的练习目录。
- 复制时排除
.git、node_modules、public等目录。 - 只在练习目录中执行初始化、提交和推送。
- 在 GitHub 创建一个全新的空仓库。
不建议直接删除原项目中的
.git。.git保存了分支、提交历史和远程地址,删除后无法通过普通 Git 命令恢复。
2.1 使用文件资源管理器复制
- 新建目录,例如
d:\code\blog-github-practice。 - 打开原项目
d:\code\blog。 - 复制项目内容到练习目录。
- 不复制以下目录:
.gitnode_modulespublic.deploy_git或其他.deploy*目录
也可以在 PowerShell 中使用 robocopy:
1 | robocopy "d:\code\blog" "d:\code\blog-github-practice" /E /XD .git node_modules public .deploy_git |
robocopy 返回码 0 到 7 通常都不表示复制失败,不能只根据非零返回码判断失败。
2.2 进入练习目录
1 | cd "d:\code\blog-github-practice" |
确认当前所在位置:
1 | Get-Location |
确认练习目录没有 Git 元数据:
1 | Test-Path .git |
预期结果:
1 | False |
如果结果为 True,说明复制了旧的 .git。先停止操作,确认自己确实位于练习副本,而不是原项目,再处理练习副本中的 .git。
三、准备 Git 和 GitHub
3.1 确认 Git 已安装
1 | git --version |
正常情况下会看到类似结果:
1 | git version 2.x.x.windows.x |
如果提示找不到 git,从 Git for Windows 下载并安装,然后重新打开 PowerShell。
3.2 配置提交身份
首次使用 Git 时设置用户名和邮箱:
1 | git config --global user.name "你的名字或 GitHub 用户名" |
检查配置:
1 | git config --global --list |
这里的邮箱用于标记提交作者。若希望 GitHub 正确关联提交,应使用 GitHub 账户邮箱,或 GitHub 提供的 noreply 邮箱。
3.3 准备 GitHub 账户
确保已经:
- 注册并登录 GitHub。
- 验证邮箱。
- 可以在 GitHub 右上角看到自己的头像和用户名。
本流程通过 GitHub 网页创建仓库,不要求安装 GitHub CLI gh。
四、提交前检查项目
4.1 检查 .gitignore
.gitignore 用来排除依赖、构建产物、日志和本地隐私文件。当前 Hexo 项目至少应包含:
1 | .DS_Store |
说明:
node_modules/可以通过npm install或npm ci重新安装,不应上传。public/是 Hexo 构建产物,不应作为源码提交。.env往往包含密钥或令牌,不应上传。.env.example可以保留变量名示例,但不能填写真实密钥。
4.2 检查敏感信息
提交前重点检查:
- GitHub Personal Access Token
- 云服务 Access Key
- 数据库密码
- 私钥文件,如
*.pem、*.key .env中的真实配置_config.yml和主题配置中的部署令牌、管理密码
原则:密钥一旦进入 Git 提交,即使后来删除文件,也可能仍存在于历史记录中。
4.3 可选:验证项目能够构建
这是 Hexo 项目,可以在提交前执行:
1 | npm ci |
构建成功后,public/ 应继续由 .gitignore 排除。
五、从零初始化本地 Git 仓库
以下命令必须在练习目录 d:\code\blog-github-practice 中执行。
5.1 初始化仓库
1 | git init |
将默认分支统一命名为 main:
1 | git branch -M main |
检查状态:
1 | git status |
此时文件通常显示为 Untracked files,表示 Git 已发现文件,但尚未纳入版本管理。
5.2 将文件加入暂存区
先确认将要处理的文件:
1 | git status --short |
将当前目录下未被忽略的文件加入暂存区:
1 | git add . |
再次检查:
1 | git status |
检查暂存区具体内容:
1 | git diff --cached --stat |
如果发现某个文件不应该提交,可先取消暂存:
1 | git restore --staged "文件路径" |
然后把它加入 .gitignore。
5.3 创建第一次提交
1 | git commit -m "初始化博客项目" |
查看提交记录:
1 | git log --oneline --decorate -5 |
预期至少有一条提交记录。
六、在 GitHub 创建全新空仓库
- 登录 GitHub。
- 点击右上角
+。 - 选择
New repository。 - 在
Owner中选择自己的账户。 - 输入仓库名,例如
blog-github-practice。 - 根据需要选择:
Public:所有人可见。Private:只有授权用户可见。
- 不要勾选以下选项:
Add a README fileAdd .gitignoreChoose a license
- 点击
Create repository。
这些初始化选项必须保持未勾选,因为本地已经有第一次提交。GitHub 仓库应保持完全空白,避免本地和远程出现两套无关历史。
创建完成后,复制 HTTPS 地址,格式类似:
1 | https://github.com/USERNAME/blog-github-practice.git |
把 USERNAME 和仓库名替换成自己的实际信息。
七、连接全新 GitHub 仓库
7.1 添加远程地址
1 | git remote add origin https://github.com/USERNAME/blog-github-practice.git |
检查远程地址:
1 | git remote -v |
预期能看到:
1 | origin https://github.com/USERNAME/blog-github-practice.git (fetch) |
发现地址错误时可以修改:
1 | git remote set-url origin https://github.com/USERNAME/正确仓库名.git |
7.2 第一次推送
1 | git push -u origin main |
参数说明:
origin:远程仓库别名。main:要推送的本地分支。-u:建立本地main与远程origin/main的跟踪关系。
建立跟踪关系后,以后通常只需要:
1 | git push |
7.3 完成 GitHub 身份验证
GitHub 不再支持使用账户密码进行 Git HTTPS 推送。Windows 上的 Git 通常通过 Git Credential Manager 打开浏览器完成授权:
- 执行第一次
git push。 - 在弹出的窗口中选择通过浏览器登录 GitHub。
- 登录并授权 Git Credential Manager。
- 返回 PowerShell,等待推送完成。
如果环境明确要求输入 Token,应使用 GitHub Personal Access Token,而不是 GitHub 登录密码。不要把 Token 写入项目文件或命令脚本。
八、验证上传结果
8.1 在本地验证
1 | git status |
理想状态类似:
1 | On branch main |
8.2 在 GitHub 验证
刷新新仓库页面,确认:
- 能看到项目源码。
- 能看到第一次提交信息。
- 仓库默认分支是
main。 - 没有
node_modules/、public/、.env或密钥文件。
九、以后每天的常用流程
开始修改前,先同步远程提交:
1 | git pull --ff-only |
修改完成后依次执行:
1 | git status |
推荐让一次提交只表达一个明确目的,例如:
1 | git commit -m "新增 Python 教程页面" |
避免长期使用含义不清的提交信息,例如 update、修改、test。
十、在新电脑下载项目
全新电脑不需要再次执行 git init,而是克隆已有仓库:
1 | git clone https://github.com/USERNAME/blog-github-practice.git |
区别:
git init:把现有普通目录变成本地 Git 仓库。git clone:下载一个已经存在的远程仓库,并自动配置origin。
十一、常见错误处理
11.1 remote origin already exists
原因:当前本地仓库已经存在名为 origin 的远程地址。
先查看现有地址:
1 | git remote -v |
如果只是地址写错:
1 | git remote set-url origin https://github.com/USERNAME/REPOSITORY.git |
如果在真正的全新练习目录中看到这个错误,通常说明旧 .git 也被复制过来了,应先停止并重新确认目录。
11.2 src refspec main does not match any
原因通常是还没有创建第一次提交,或者本地分支不叫 main。
检查:
1 | git status |
确认已经执行:
1 | git add . |
11.3 rejected 或 non-fast-forward
如果这是第一次推送,通常是创建 GitHub 仓库时勾选了 README、.gitignore 或 License,导致远程不为空。
初学练习时最清晰的处理方式是:
- 删除刚创建且没有重要内容的 GitHub 练习仓库。
- 重新创建同名空仓库。
- 不勾选任何初始化选项。
- 再次执行
git push -u origin main。
不要在不理解影响时使用强制推送 git push --force。
11.4 Authentication failed
依次确认:
- 浏览器登录的是正确 GitHub 账户。
- 当前账户对目标仓库有写入权限。
- 远程 URL 中的用户名和仓库名正确。
- 使用浏览器授权或 Personal Access Token,而不是账户密码。
11.5 不小心暂存了不该上传的文件
尚未提交时:
1 | git restore --staged "文件路径" |
把对应路径加入 .gitignore,再检查:
1 | git status --short |
如果密钥已经提交甚至推送,应立即到对应平台撤销并重新生成密钥。仅从文件中删除密钥并不能让旧密钥重新安全。
十二、保留本地历史、只更换 GitHub 仓库
如果以后不需要练习 git init,只想把现有本地提交完整上传到一个新 GitHub 仓库,则不必复制项目或删除 .git。
先把旧远程保留为 old-origin:
1 | git remote rename origin old-origin |
添加全新的空 GitHub 仓库:
1 | git remote add origin https://github.com/USERNAME/NEW-REPOSITORY.git |
这种方式会保留全部本地提交历史,但它不属于“从零初始化 Git 仓库”。执行前必须通过 git remote -v 确认旧、新仓库地址,避免推送到错误仓库。
十三、最终检查清单
- 操作目录是练习副本,不是原项目。
- 练习副本没有旧
.git。 - Git 用户名和邮箱配置正确。
-
.gitignore已排除依赖、构建产物和敏感文件。 - 已通过
git diff --cached检查第一次提交内容。 - 已创建第一次本地提交。
- GitHub 创建的是全新空仓库。
-
origin指向自己的新仓库。 - 已执行
git push -u origin main。 - GitHub 页面能看到源码和提交记录。
- GitHub 中不存在
.env、Token、私钥等敏感信息。
