Git 项目从零上传到 GitHub

Git 项目从零上传到 GitHub

本文记录在 Windows PowerShell 中,将本地项目从零初始化并上传到全新 GitHub 仓库的完整流程。

本文的目标是上传项目源码,不是发布 Hexo 网站。两者的区别是:

  • 上传源码到 GitHub:保存 _config.ymlsource/themes/package.json 等项目文件。
  • 发布 Hexo 网站:将 Hexo 生成的网站部署到 GitHub Pages,属于另一条部署流程。

一、理解完整链路

1
2
3
4
5
6
7
项目文件
↓ git add
暂存区
↓ git commit
本地 Git 仓库
↓ git push
GitHub 远程仓库

几个容易混淆的概念:

  • git init:让一个普通文件夹成为本地 Git 仓库。
  • git add:选择准备提交的文件,并放入暂存区。
  • git commit:把暂存区内容保存为一次本地版本记录。
  • git remote:管理本地仓库对应的远程仓库地址。
  • git push:把本地提交上传到 GitHub。
  • origin:远程仓库的常用别名,不是固定关键字。
  • main:当前使用的主分支名称。

二、本次练习采用的安全方案

当前原项目 d:\code\blog 已经有 Git 历史和远程仓库。为了完整练习 git init,同时不破坏原项目,建议使用下面的方案:

  1. 复制项目到一个新的练习目录。
  2. 复制时排除 .gitnode_modulespublic 等目录。
  3. 只在练习目录中执行初始化、提交和推送。
  4. 在 GitHub 创建一个全新的空仓库。

不建议直接删除原项目中的 .git.git 保存了分支、提交历史和远程地址,删除后无法通过普通 Git 命令恢复。

2.1 使用文件资源管理器复制

  1. 新建目录,例如 d:\code\blog-github-practice
  2. 打开原项目 d:\code\blog
  3. 复制项目内容到练习目录。
  4. 不复制以下目录:
    • .git
    • node_modules
    • public
    • .deploy_git 或其他 .deploy* 目录

也可以在 PowerShell 中使用 robocopy

1
robocopy "d:\code\blog" "d:\code\blog-github-practice" /E /XD .git node_modules public .deploy_git

robocopy 返回码 07 通常都不表示复制失败,不能只根据非零返回码判断失败。

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
2
git config --global user.name "你的名字或 GitHub 用户名"
git config --global user.email "你的 GitHub 邮箱"

检查配置:

1
git config --global --list

这里的邮箱用于标记提交作者。若希望 GitHub 正确关联提交,应使用 GitHub 账户邮箱,或 GitHub 提供的 noreply 邮箱。

3.3 准备 GitHub 账户

确保已经:

  1. 注册并登录 GitHub
  2. 验证邮箱。
  3. 可以在 GitHub 右上角看到自己的头像和用户名。

本流程通过 GitHub 网页创建仓库,不要求安装 GitHub CLI gh

四、提交前检查项目

4.1 检查 .gitignore

.gitignore 用来排除依赖、构建产物、日志和本地隐私文件。当前 Hexo 项目至少应包含:

1
2
3
4
5
6
7
8
9
10
11
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
_multiconfig.yml
.env
.env.*
!.env.example

说明:

  • node_modules/ 可以通过 npm installnpm ci 重新安装,不应上传。
  • public/ 是 Hexo 构建产物,不应作为源码提交。
  • .env 往往包含密钥或令牌,不应上传。
  • .env.example 可以保留变量名示例,但不能填写真实密钥。

4.2 检查敏感信息

提交前重点检查:

  • GitHub Personal Access Token
  • 云服务 Access Key
  • 数据库密码
  • 私钥文件,如 *.pem*.key
  • .env 中的真实配置
  • _config.yml 和主题配置中的部署令牌、管理密码

原则:密钥一旦进入 Git 提交,即使后来删除文件,也可能仍存在于历史记录中。

4.3 可选:验证项目能够构建

这是 Hexo 项目,可以在提交前执行:

1
2
npm ci
npm run build

构建成功后,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
2
git diff --cached --stat
git diff --cached

如果发现某个文件不应该提交,可先取消暂存:

1
git restore --staged "文件路径"

然后把它加入 .gitignore

5.3 创建第一次提交

1
git commit -m "初始化博客项目"

查看提交记录:

1
git log --oneline --decorate -5

预期至少有一条提交记录。

六、在 GitHub 创建全新空仓库

  1. 登录 GitHub。
  2. 点击右上角 +
  3. 选择 New repository
  4. Owner 中选择自己的账户。
  5. 输入仓库名,例如 blog-github-practice
  6. 根据需要选择:
    • Public:所有人可见。
    • Private:只有授权用户可见。
  7. 不要勾选以下选项:
    • Add a README file
    • Add .gitignore
    • Choose a license
  8. 点击 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
2
origin  https://github.com/USERNAME/blog-github-practice.git (fetch)
origin https://github.com/USERNAME/blog-github-practice.git (push)

发现地址错误时可以修改:

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 打开浏览器完成授权:

  1. 执行第一次 git push
  2. 在弹出的窗口中选择通过浏览器登录 GitHub。
  3. 登录并授权 Git Credential Manager。
  4. 返回 PowerShell,等待推送完成。

如果环境明确要求输入 Token,应使用 GitHub Personal Access Token,而不是 GitHub 登录密码。不要把 Token 写入项目文件或命令脚本。

八、验证上传结果

8.1 在本地验证

1
2
3
git status
git branch -vv
git remote -v

理想状态类似:

1
2
3
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

8.2 在 GitHub 验证

刷新新仓库页面,确认:

  • 能看到项目源码。
  • 能看到第一次提交信息。
  • 仓库默认分支是 main
  • 没有 node_modules/public/.env 或密钥文件。

九、以后每天的常用流程

开始修改前,先同步远程提交:

1
git pull --ff-only

修改完成后依次执行:

1
2
3
4
5
6
git status
git diff
git add .
git diff --cached
git commit -m "准确描述本次修改"
git push

推荐让一次提交只表达一个明确目的,例如:

1
2
3
git commit -m "新增 Python 教程页面"
git commit -m "修复文档导航链接"
git commit -m "调整 Butterfly 主题配置"

避免长期使用含义不清的提交信息,例如 update修改test

十、在新电脑下载项目

全新电脑不需要再次执行 git init,而是克隆已有仓库:

1
2
3
4
git clone https://github.com/USERNAME/blog-github-practice.git
cd "blog-github-practice"
npm ci
npm run server

区别:

  • 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
2
3
git status
git branch --show-current
git log --oneline

确认已经执行:

1
2
3
git add .
git commit -m "初始化项目"
git branch -M main

11.3 rejectednon-fast-forward

如果这是第一次推送,通常是创建 GitHub 仓库时勾选了 README、.gitignore 或 License,导致远程不为空。

初学练习时最清晰的处理方式是:

  1. 删除刚创建且没有重要内容的 GitHub 练习仓库。
  2. 重新创建同名空仓库。
  3. 不勾选任何初始化选项。
  4. 再次执行 git push -u origin main

不要在不理解影响时使用强制推送 git push --force

11.4 Authentication failed

依次确认:

  1. 浏览器登录的是正确 GitHub 账户。
  2. 当前账户对目标仓库有写入权限。
  3. 远程 URL 中的用户名和仓库名正确。
  4. 使用浏览器授权或 Personal Access Token,而不是账户密码。

11.5 不小心暂存了不该上传的文件

尚未提交时:

1
git restore --staged "文件路径"

把对应路径加入 .gitignore,再检查:

1
2
git status --short
git diff --cached

如果密钥已经提交甚至推送,应立即到对应平台撤销并重新生成密钥。仅从文件中删除密钥并不能让旧密钥重新安全。

十二、保留本地历史、只更换 GitHub 仓库

如果以后不需要练习 git init,只想把现有本地提交完整上传到一个新 GitHub 仓库,则不必复制项目或删除 .git

先把旧远程保留为 old-origin

1
git remote rename origin old-origin

添加全新的空 GitHub 仓库:

1
2
git remote add origin https://github.com/USERNAME/NEW-REPOSITORY.git
git push -u origin main

这种方式会保留全部本地提交历史,但它不属于“从零初始化 Git 仓库”。执行前必须通过 git remote -v 确认旧、新仓库地址,避免推送到错误仓库。

十三、最终检查清单

  • 操作目录是练习副本,不是原项目。
  • 练习副本没有旧 .git
  • Git 用户名和邮箱配置正确。
  • .gitignore 已排除依赖、构建产物和敏感文件。
  • 已通过 git diff --cached 检查第一次提交内容。
  • 已创建第一次本地提交。
  • GitHub 创建的是全新空仓库。
  • origin 指向自己的新仓库。
  • 已执行 git push -u origin main
  • GitHub 页面能看到源码和提交记录。
  • GitHub 中不存在 .env、Token、私钥等敏感信息。