前言

很多刚开始做深度学习、视觉大模型、多模态项目的同学,都会遇到一个问题:

我在 WSL Ubuntu 里写了很多代码,也有数据集、PDF、图片、模型权重、中间结果。现在我想把代码上传到 GitHub,但不想把数据集也上传上去,该怎么做?

这篇文章就是为了解决这个问题。

本文会从一个完全新手的角度出发,讲清楚:

  1. Git 是什么;
  2. GitHub 是什么;
  3. WSL Ubuntu 和 GitHub 之间是什么关系;
  4. 为什么项目需要 Git 管理;
  5. 为什么数据集不应该上传 GitHub;
  6. .gitignore 是干什么的;
  7. git addgit commitgit push 分别在做什么;
  8. 远程仓库已经有 README 时,为什么第一次 push 会失败;
  9. 遇到 nano 编辑器应该怎么保存退出;
  10. 如何形成一套日常更新代码的 Git 工作流。

本文会隐藏所有个人信息,所有路径、用户名、仓库名都使用示例占位符。


一、先建立概念:Git 到底是什么?

Git 是一个版本控制工具

通俗理解:

Git 就像代码项目的“时间机器”。

你每完成一个阶段,就可以让 Git 记录一次当前项目的状态。之后如果代码写坏了、文件改乱了、实验失败了,都可以通过 Git 回到之前的版本。

比如你今天写了一个训练脚本:

train.py

明天你修改它,加了很多新功能,结果代码跑不通了。

如果没有 Git,你可能只能手动复制备份:

train_old.py
train_new.py
train_final.py
train_final_final.py

这种方式非常混乱。

而使用 Git 后,你可以这样管理:

第一次提交:完成基础训练脚本
第二次提交:加入数据预处理
第三次提交:加入模型保存逻辑
第四次提交:修复显存溢出问题

每一次提交都是一个清晰的版本节点。

这就是 Git 的核心用途:

管理代码版本,记录修改历史,方便回退、协作和发布。


二、GitHub 又是什么?

Git 是本地工具,GitHub 是远程代码托管平台。

可以这样理解:

名称 作用
Git 管理你电脑本地的代码版本
GitHub 把你的 Git 仓库放到云端,方便备份、展示、协作

如果只使用 Git,你的代码历史只存在 WSL Ubuntu 本地。

如果电脑坏了、系统重装了、WSL 环境丢了,代码可能也没了。

把代码推送到 GitHub 后,就相当于多了一份云端备份。

GitHub 的主要用途包括:

  1. 备份代码;
  2. 展示项目;
  3. 和别人协作开发;
  4. 管理论文、实验、开源项目;
  5. 给导师、师兄、同学查看项目进度;
  6. 为以后实习、求职、科研项目积累作品。

三、WSL Ubuntu、Git 和 GitHub 的关系

很多 Windows 用户会用 WSL Ubuntu 跑深度学习项目。

这里有三层关系:

Windows
└── WSL Ubuntu
    └── 本地项目目录
        └── Git 仓库
            └── GitHub 远程仓库

解释一下:

1. Windows

这是你的电脑系统。

2. WSL Ubuntu

WSL 是 Windows Subsystem for Linux,也就是 Windows 里的 Linux 环境。

很多深度学习项目、视觉大模型项目更适合在 Linux 环境里运行,所以我们会用 WSL Ubuntu。如何安装使用WSL,各位看官可以移步如下链接
别再装虚拟机了!Windows 一键拥有 Linux 环境,并跑通你的第一个视觉大模型

3. 本地项目目录

比如:

~/projects/your_project

这个目录里放你的代码、配置文件、数据处理脚本、训练脚本等。

4. Git 仓库

当你在这个目录里执行:

git init

这个项目目录就变成了一个 Git 仓库。

Git 会开始记录这个项目的文件变化。

5. GitHub 远程仓库

你可以把本地 Git 仓库推送到 GitHub。

这样 GitHub 上也会有一份你的代码。


四、为什么不能直接把整个项目文件夹上传?

深度学习项目经常包含这些内容:

your_project/
├── scripts/
├── src/
├── configs/
├── data/
├── datasets/
├── raw_data/
├── outputs/
├── checkpoints/
├── models/
├── logs/
├── train.py
├── requirements.txt
└── README.md

这里面并不是所有东西都应该上传。

一般推荐上传:

代码文件
配置文件
说明文档
依赖文件
小型示例文件

不推荐上传:

数据集
PDF 原始文件
图片数据
模型权重
训练日志
中间结果
API Key
虚拟环境
缓存文件

原因有几个。

1. 数据集通常很大

GitHub 普通仓库并不适合放大型数据集。

几百 MB、几个 GB 的数据集,会让仓库变得非常臃肿。

2. 模型权重通常很大

比如:

model.pth
model.pt
model.safetensors

这些文件可能几百 MB 甚至几十 GB。

它们不适合直接进入 Git 仓库。

3. 数据可能涉及隐私或版权

比如专利 PDF、图片、标注数据,可能不适合公开上传。

即使是私有仓库,也建议谨慎处理。

4. API Key 绝对不能上传

例如:

.env
config/private.yaml
api_key.txt

这些文件如果被上传,可能导致账号泄露、接口被盗刷。

所以专业项目管理中,一般有一个原则:

GitHub 仓库主要保存“能复现项目的代码和说明”,而不是保存所有数据和产物。


五、Git 的四个核心区域

新手最容易混淆 Git 命令,是因为不理解 Git 的几个区域。

可以先记住这四个概念:

工作区 → 暂存区 → 本地仓库 → 远程仓库

1. 工作区

工作区就是你正在编辑的项目目录。

比如:

~/projects/your_project

你在里面写代码、改文件、删文件,这些操作都发生在工作区。

2. 暂存区

暂存区可以理解为:

准备提交的文件清单。

当你执行:

git add .

就是把当前修改过的文件放进暂存区。

注意:

git add .

不是上传到 GitHub。

它只是告诉 Git:

这些文件我准备纳入下一次提交。

3. 本地仓库

当你执行:

git commit -m "提交说明"

Git 才会真正生成一个本地版本。

这个版本存在你的 WSL Ubuntu 本地电脑里。

注意:

git commit

也不是上传到 GitHub。

它只是保存到本地 Git 仓库。

4. 远程仓库

远程仓库就是 GitHub 上的仓库。

当你执行:

git push

才是把本地提交上传到 GitHub。

所以完整流程是:

修改代码
↓
git add .git commit -m "说明"git push

六、本次目标

假设我的项目根目录是:

~/projects/your_project

远程 GitHub 仓库地址是:

https://github.com/<your-github-username>/<your-repo-name>.git

注意:

<your-github-username>

表示你的 GitHub 用户名。

<your-repo-name>

表示你的 GitHub 仓库名。

我们的目标是:

  1. 在 WSL Ubuntu 中进入项目根目录;
  2. 初始化 Git 仓库;
  3. 配置 .gitignore
  4. 只提交代码,不提交数据;
  5. 连接已有 GitHub 私有仓库;
  6. 解决第一次推送时常见的冲突问题;
  7. 建立后续日常更新流程。

七、进入项目根目录

首先进入项目目录:

# 进入你的项目根目录
cd ~/projects/your_project

解释:

cd

表示切换目录。

~

表示当前 Linux 用户的 Home 目录。

~/projects/your_project

表示你的项目目录。

检查当前目录:

# 显示当前所在路径,防止在错误目录执行 Git 命令
pwd

解释:

pwd

表示 print working directory,也就是打印当前工作目录。

你应该看到类似:

/home/your_linux_username/projects/your_project

这里的:

your_linux_username

是你的 WSL Ubuntu 用户名。

为了隐藏个人信息,本文全部使用占位符。

再检查当前目录名:

# 只显示当前目录最后一级名字
basename "$PWD"

解释:

basename "$PWD"

会输出当前路径的最后一级目录名。

如果输出:

your_project

说明你确实在项目根目录。

这一步非常重要。

因为如果你在数据集目录里执行 git init,Git 仓库根目录就会变成数据集目录,后面结构会全部错乱。


八、安装并检查 Git

先检查 Git 是否已经安装:

# 查看 Git 版本,如果能输出版本号,说明已经安装
git --version

解释:

git

是 Git 命令本体。

--version

表示查看版本号。

如果输出类似:

git version 2.xx.x

说明 Git 已经安装。

如果提示找不到 Git,可以安装:

# 更新 Ubuntu 软件源索引
sudo apt update

解释:

sudo

表示使用管理员权限执行命令。

apt

是 Ubuntu 的软件包管理工具。

update

表示更新软件源索引,不是升级系统。

继续安装 Git:

# 安装 Git,-y 表示自动确认安装
sudo apt install git -y

解释:

install git

表示安装 Git 软件包。

-y

表示自动回答 yes,避免中途手动确认。

安装完成后再次检查:

# 再次确认 Git 是否安装成功
git --version

九、配置 Git 用户名和邮箱

Git 每次提交代码时,都会记录是谁提交的。

所以第一次使用 Git 需要配置用户名和邮箱。

# 配置 Git 提交时显示的用户名
git config --global user.name "<your-name>"

解释:

git config

表示修改 Git 配置。

--global

表示全局配置,对当前 Linux 用户下所有 Git 仓库生效。

user.name

表示提交记录中的用户名。

"<your-name>"

替换成你希望显示的名字。

继续配置邮箱:

# 配置 Git 提交时使用的邮箱
git config --global user.email "<your-email@example.com>"

解释:

user.email

表示提交记录中的邮箱。

如果你不想暴露真实邮箱,可以在 GitHub 设置里使用 GitHub 提供的 noreply 邮箱。

查看配置:

# 查看当前全局 Git 配置
git config --global --list

解释:

--list

表示列出当前配置项。

你会看到类似:

user.name=<your-name>
user.email=<your-email@example.com>

十、初始化 Git 仓库

确保你在项目根目录:

# 再次进入项目根目录,防止路径不对
cd ~/projects/your_project

初始化 Git:

# 把当前目录初始化为 Git 仓库
git init

解释:

git init

会在当前目录下创建一个隐藏目录:

.git/

这个 .git/ 目录非常重要。

它里面保存了 Git 的版本历史、分支信息、远程仓库信息等。

一般不要手动修改或删除 .git/

设置分支名为 main

# 把当前分支重命名为 main
git branch -M main

解释:

git branch

表示管理分支。

-M

表示强制重命名当前分支。

main

表示新的分支名。

现在 GitHub 默认主分支通常是 main,所以这里统一成 main


十一、创建 .gitignore

.gitignore 是专业项目中非常重要的文件。

它的作用是:

告诉 Git 哪些文件不需要追踪,也不应该上传到远程仓库。

在机器学习项目里,.gitignore 尤其重要,因为我们经常有:

数据集
模型权重
训练日志
缓存文件
实验输出
API Key
虚拟环境

这些东西通常不应该进入 Git 仓库。

在项目根目录执行:

# 创建或覆盖 .gitignore 文件
cat > .gitignore <<'EOF'
# =========================
# Python cache
# =========================

# Python 运行时自动生成的缓存目录,不需要上传
__pycache__/

# Python 编译缓存文件,不需要上传
*.py[cod]
*.pyo
*.pyd

# Python 打包产物,不需要上传
*.egg-info/
build/
dist/


# =========================
# Virtual environments
# =========================

# Python 虚拟环境目录,不需要上传
.venv/
venv/
env/
ENV/

# conda 环境相关文件或目录,一般不上传
conda-env/
*.conda/


# =========================
# IDE / editor config
# =========================

# Jupyter Notebook 缓存
.ipynb_checkpoints/

# VS Code 配置目录,通常不上传
.vscode/

# PyCharm / IntelliJ 配置目录,通常不上传
.idea/


# =========================
# Logs / experiment outputs
# =========================

# 日志文件
*.log

# 常见运行输出目录
logs/
runs/
outputs/
output/
results/

# 常见机器学习实验记录目录
wandb/
mlruns/
lightning_logs/
tensorboard/


# =========================
# Model checkpoints / weights
# =========================

# 模型检查点目录
checkpoints/
checkpoint/
ckpt/

# 模型目录
models/
model_weights/

# 常见模型权重文件格式
*.ckpt
*.pt
*.pth
*.safetensors
*.bin


# =========================
# Secrets / API keys
# =========================

# 环境变量文件,可能包含 API Key,绝对不要上传
.env
.env.*

# 密钥文件,不上传
*.key
*.pem

# 私密配置目录
secrets/
config/private.*


# =========================
# Dataset directories
# =========================

# 常见数据集目录,不上传
data/
dataset/
datasets/
raw_data/
processed_data/
downloads/

# 如果你的项目中有子项目目录,不要直接忽略整个子项目
# 正确做法是只忽略子项目中的数据目录
sub_project/data/
sub_project/dataset/
sub_project/datasets/
sub_project/raw_data/
sub_project/processed_data/
sub_project/downloads/


# =========================
# Large data file formats
# =========================

# 压缩包通常是数据或模型,不上传
*.zip
*.tar
*.tar.gz
*.tgz
*.rar
*.7z

# 常见数据文件格式
*.jsonl
*.parquet
*.arrow
*.npy
*.npz
*.pkl
*.pickle
*.h5
*.hdf5

# PDF 和图片数据不上传
*.pdf
*.png
*.jpg
*.jpeg
*.webp
*.tif
*.tiff
EOF

解释:

cat > .gitignore <<'EOF'
...
EOF

这是一种在终端里快速写入文件的方式。

其中:

cat

可以把文本输出到文件。

>

表示覆盖写入文件。

.gitignore

是要写入的文件名。

<<'EOF'

表示从下一行开始,直到遇到 EOF 为止,中间所有内容都写进文件。

注意:

sub_project/

这种规则会忽略整个子项目目录。

如果你的子项目目录里既有代码又有数据,不要这样写。

应该只忽略:

sub_project/data/
sub_project/datasets/
sub_project/raw_data/

这样子项目里的代码仍然可以上传。


十二、.gitignore 不会删除本地文件

很多新手会误以为:

我写了 .gitignore,本地数据集应该消失。

这是错误理解。

.gitignore 不会删除任何本地文件。

它只影响 Git 是否追踪这些文件。

例如执行:

# 查找当前项目中大于 1MB 的文件
find . -type f -size +1M -not -path './.git/*'

解释:

find .

表示从当前目录开始查找。

-type f

表示只查找文件。

-size +1M

表示只查找大于 1MB 的文件。

-not -path './.git/*'

表示排除 .git 目录。

这个命令可能仍然会找到很多 PDF、图片、数据文件。

这很正常。

因为 find 查看的是:

本地磁盘上是否存在这些文件

.gitignore 控制的是:

Git 是否追踪这些文件

真正要判断文件会不会上传,应该看 Git 状态,而不是只看 find


十三、检查某个文件是否被忽略

假设你想检查 PDF 是否被 .gitignore 忽略。

先找一个 PDF:

# 查找当前项目中的 PDF 文件,只显示前几条
find . -type f -name "*.pdf" -not -path './.git/*' | head

解释:

-name "*.pdf"

表示只查找 .pdf 结尾的文件。

| head

表示只显示前几条结果,避免刷屏。

假设输出:

./data/example.pdf

然后检查它是否被 Git 忽略:

# 检查这个文件是否命中了 .gitignore 规则
git check-ignore -v ./data/example.pdf

解释:

git check-ignore

用于检查文件是否被 Git 忽略。

-v

表示显示具体命中了哪条规则。

如果输出类似:

.gitignore:120:*.pdf    ./data/example.pdf

说明这个 PDF 已经被忽略,不会被正常提交。


十四、查看 Git 当前状态

执行:

# 查看当前 Git 仓库状态
git status

解释:

git status

是 Git 中最常用的命令之一。

它会告诉你:

  1. 当前在哪个分支;
  2. 哪些文件被修改了;
  3. 哪些文件还没有被 Git 追踪;
  4. 哪些文件已经加入暂存区;
  5. 当前是否可以提交。

新手一定要养成习惯:

每做一步 Git 操作,都先看一眼 git status

简洁版状态:

# 用简短格式查看 Git 状态
git status --short

解释:

--short

表示用简洁格式输出。

比如:

?? train.py
 M README.md
A  .gitignore

大概意思是:

?? 表示 Git 还没有追踪这个文件
M  表示文件被修改
A  表示文件已经加入暂存区,准备提交

十五、检查是否有数据文件准备被提交

为了防止误上传数据集,可以执行:

# 检查当前 Git 状态中是否出现数据、图片、PDF、模型权重
git status --short | grep -Ei 'data|dataset|\.pdf$|\.png$|\.jpg$|\.jpeg$|\.webp$|\.pt$|\.pth$|\.safetensors$|\.env'

解释:

git status --short

输出当前 Git 状态。

|

管道符,把前一个命令的输出交给后一个命令。

grep

用于搜索文本。

-E

表示使用扩展正则表达式。

-i

表示忽略大小写。

后面的表达式表示筛选可疑文件:

data
dataset
.pdf
.png
.jpg
.pt
.pth
.safetensors
.env

如果这个命令没有任何输出,说明当前 Git 状态里没有明显的数据文件。

也可以加一句提示:

# 如果没有匹配到可疑文件,就输出安全提示
git status --short | grep -Ei 'data|dataset|\.pdf$|\.png$|\.jpg$|\.jpeg$|\.webp$|\.pt$|\.pth$|\.safetensors$|\.env' || echo "当前没有明显的数据/图片/模型权重准备提交"

十六、如果之前误执行过 git add .

新手很容易先执行:

git add .

然后才想起来没有写 .gitignore

这种情况下,一些数据文件可能已经进入暂存区。

这时可以执行:

# 从 Git 暂存区和追踪记录中移除所有文件,但不删除本地文件
git rm -r --cached .

解释:

git rm

表示从 Git 中移除文件。

-r

表示递归处理所有子目录。

--cached

非常重要,表示只从 Git 的追踪记录中移除,不删除本地真实文件。

.

表示当前目录下所有文件。

这条命令不会删除你的代码和数据,它只是让 Git 重新“忘记”当前已经追踪的文件。

然后重新添加:

# 重新添加没有被 .gitignore 忽略的文件
git add .

解释:

git add .

表示把当前目录下所有未被忽略的文件加入暂存区。

因为 .gitignore 已经写好了,所以数据集、PDF、模型权重不会被正常加入暂存区。

再次检查:

# 再次查看状态,确认没有数据文件准备提交
git status

十七、提交代码到本地仓库

当确认没有数据集、PDF、图片、模型权重后,可以提交:

# 创建一次本地提交
git commit -m "Initial commit"

解释:

git commit

表示创建一次 Git 提交。

-m

表示直接在命令里写提交说明。

"Initial commit"

表示提交信息,意思是“初始化提交”。

注意:

git commit

只是提交到本地 Git 仓库。

它还没有上传到 GitHub。


十八、连接远程 GitHub 仓库

假设你的 GitHub 仓库地址是:

https://github.com/<your-github-username>/<your-repo-name>.git

先查看当前是否已经有远程仓库:

# 查看当前项目绑定的远程仓库
git remote -v

解释:

git remote

表示管理远程仓库。

-v

表示显示详细信息。

如果没有任何输出,说明还没有绑定远程仓库。

添加远程仓库:

# 添加名为 origin 的远程仓库
git remote add origin https://github.com/<your-github-username>/<your-repo-name>.git

解释:

git remote add

表示添加一个远程仓库地址。

origin

是远程仓库的默认别名,行业里通常都叫 origin

后面的 URL 是你的 GitHub 仓库地址。

添加后再次检查:

# 确认远程仓库地址是否添加成功
git remote -v

如果输出类似:

origin  https://github.com/<your-github-username>/<your-repo-name>.git (fetch)
origin  https://github.com/<your-github-username>/<your-repo-name>.git (push)

说明连接成功。


十九、如果 origin already exists

如果你添加远程仓库时看到:

error: remote origin already exists.

说明这个项目已经有一个叫 origin 的远程地址。

这时不要重复添加,应该修改地址:

# 修改 origin 的远程仓库地址
git remote set-url origin https://github.com/<your-github-username>/<your-repo-name>.git

解释:

git remote set-url

表示修改已有远程仓库的 URL。

origin

表示要修改的远程仓库别名。

执行后检查:

# 查看 origin 是否已经指向正确仓库
git remote -v

二十、第一次推送到 GitHub

执行:

# 把本地 main 分支推送到 GitHub 的 origin 远程仓库
git push -u origin main

解释:

git push

表示把本地提交上传到远程仓库。

-u

表示设置上游分支。

简单说,第一次用了 -u 之后,以后在这个分支上可以直接执行:

git push

不需要再写:

git push origin main
origin

表示远程仓库。

main

表示本地分支名。


二十一、如果第一次 push 被拒绝

你可能会看到:

! [rejected] main -> main (fetch first)
error: failed to push some refs

这不是账号问题,也不是权限问题。

它通常表示:

GitHub 远程仓库里已经有提交了,但是本地仓库没有这些提交。

最常见原因:

  1. 创建 GitHub 仓库时勾选了 README;
  2. 创建 GitHub 仓库时添加了 .gitignore
  3. 创建 GitHub 仓库时添加了 License;
  4. 远程仓库不是空仓库。

也就是说:

本地仓库有自己的历史
远程仓库也有自己的历史
两边历史不一致

Git 为了保护远程仓库,不允许你直接推送覆盖。


二十二、解决远程仓库已有内容的问题

执行:

# 拉取远程 main 分支,并允许合并无共同历史的两个仓库
git pull origin main --allow-unrelated-histories --no-rebase

解释:

git pull

表示从远程仓库拉取内容,并合并到本地。

origin

表示远程仓库别名。

main

表示远程分支名。

--allow-unrelated-histories

表示允许合并两个没有共同历史的仓库。

这个参数常用于:

本地先 git init 了一个仓库
GitHub 上也有一个初始化 README 提交
两边不是从同一个历史发展来的
--no-rebase

表示使用 merge 方式合并。

对于新手来说,merge 更直观。


二十三、如果出现 divergent branches

有时会出现:

fatal: Need to specify how to reconcile divergent branches.

意思是:

本地分支和远程分支已经分叉
Git 不知道你想用 merge 还是 rebase

所以我们明确告诉 Git 使用 merge:

# 明确指定使用 merge 方式拉取
git pull origin main --allow-unrelated-histories --no-rebase

这条命令就是为了解决这个问题。


二十四、进入 nano 编辑器怎么办?

执行 git pull 合并时,Git 可能会打开 nano 编辑器,让你确认合并提交信息。

你可能会看到:

GNU nano 7.2    .git/MERGE_MSG

Merge branch 'main' of https://github.com/<your-github-username>/<your-repo-name>

这是正常现象。

Git 的意思是:

请确认这次合并提交的说明。

不需要改内容。

直接按:

Ctrl + O
Enter
Ctrl + X

解释:

Ctrl + O

表示保存。

Enter

表示确认文件名。

Ctrl + X

表示退出 nano。

退出后会回到终端。


二十五、如果合并出现冲突

如果本地和远程都修改了同一个文件,可能会冲突。

先查看状态:

# 查看是否有冲突文件
git status

如果看到类似:

both added: README.md

说明本地和远程都添加了 README,Git 不知道保留哪个。

如果想保留本地版本:

# 冲突时保留本地版本
git checkout --ours README.md

解释:

--ours

表示选择我们本地当前分支的版本。

如果想保留远程版本:

# 冲突时保留远程版本
git checkout --theirs README.md

解释:

--theirs

表示选择远程分支合并进来的版本。

处理完冲突后:

# 标记冲突文件已经处理完成
git add README.md

解释:

git add README.md

告诉 Git:这个冲突文件已经解决。

然后提交合并:

# 创建合并提交
git commit -m "Merge remote main"

解释:

git commit

完成本次冲突解决后的提交。


二十六、再次推送

合并完成后,再推送:

# 把合并后的本地 main 分支推送到 GitHub
git push -u origin main

如果成功,会看到类似:

Enumerating objects
Counting objects
Writing objects
To https://github.com/<your-github-username>/<your-repo-name>.git

这说明你的代码已经上传到 GitHub。


二十七、完整流程命令总结

下面是完整命令版本。

注意:把路径和仓库地址替换成你自己的。

# 1. 进入项目根目录
cd ~/projects/your_project

# 2. 确认当前路径,避免在错误目录初始化 Git
pwd

# 3. 初始化 Git 仓库
git init

# 4. 将当前分支命名为 main
git branch -M main

# 5. 创建 .gitignore,忽略数据集、模型权重、图片、PDF、日志、缓存等
cat > .gitignore <<'EOF'
__pycache__/
*.py[cod]
.venv/
venv/
env/
.ipynb_checkpoints/
.vscode/
.idea/

*.log
logs/
runs/
outputs/
results/
wandb/
mlruns/
lightning_logs/

checkpoints/
checkpoint/
ckpt/
models/
model_weights/
*.ckpt
*.pt
*.pth
*.safetensors
*.bin

.env
.env.*
*.key
*.pem

data/
dataset/
datasets/
raw_data/
processed_data/
downloads/

sub_project/data/
sub_project/dataset/
sub_project/datasets/
sub_project/raw_data/
sub_project/processed_data/
sub_project/downloads/

*.zip
*.tar
*.tar.gz
*.tgz
*.rar
*.7z

*.jsonl
*.parquet
*.arrow
*.npy
*.npz
*.pkl
*.pickle
*.h5
*.hdf5

*.pdf
*.png
*.jpg
*.jpeg
*.webp
*.tif
*.tiff
EOF

# 6. 如果之前误 add 过文件,清空 Git 暂存区和追踪记录,但不删除本地文件
git rm -r --cached .

# 7. 重新添加未被 .gitignore 忽略的文件
git add .

# 8. 检查是否有数据、图片、模型权重等可疑文件准备提交
git status --short | grep -Ei 'data|dataset|\.pdf$|\.png$|\.jpg$|\.jpeg$|\.webp$|\.pt$|\.pth$|\.safetensors$|\.env' || echo "当前没有明显的数据/图片/模型权重准备提交"

# 9. 查看完整 Git 状态
git status

# 10. 提交到本地 Git 仓库
git commit -m "Initial commit"

# 11. 绑定远程 GitHub 仓库
git remote add origin https://github.com/<your-github-username>/<your-repo-name>.git

# 12. 如果 origin 已经存在,使用下面这句修改远程地址
# git remote set-url origin https://github.com/<your-github-username>/<your-repo-name>.git

# 13. 查看远程仓库地址是否正确
git remote -v

# 14. 如果远程仓库已有 README 或其他初始化文件,先拉取合并
git pull origin main --allow-unrelated-histories --no-rebase

# 15. 如果进入 nano 编辑器:
# 按 Ctrl + O
# 按 Enter
# 按 Ctrl + X

# 16. 推送到 GitHub
git push -u origin main

二十八、日常开发应该怎么用 Git?

第一次配置完成后,以后每次更新代码,一般只需要四步。

1. 查看状态

# 查看当前哪些文件发生了变化
git status

2. 添加修改

# 添加所有未被 .gitignore 忽略的修改
git add .

3. 提交本地版本

# 创建一次本地提交
git commit -m "Update code"

提交信息建议写清楚一点,例如:

git commit -m "Add data preprocessing script"

或者:

git commit -m "Fix training config bug"

不要每次都写:

update

因为以后看历史记录会很难理解。

4. 推送到 GitHub

# 推送到远程 GitHub 仓库
git push

第一次执行过:

git push -u origin main

之后,就可以直接:

git push

二十九、常见错误总结

1. .gitignore 写了,为什么本地还是能找到 PDF?

因为 .gitignore 不会删除本地文件。

它只是不让 Git 追踪这些文件。

本地仍然可以有:

data/example.pdf

只要它没有被 Git 追踪,就不会上传。

检查方法:

# 检查某个文件是否被忽略
git check-ignore -v data/example.pdf

2. 怎么确认数据集没有被 Git 追踪?

执行:

# 查看当前已经被 Git 追踪的文件中是否有数据文件
git ls-files | grep -Ei 'data|dataset|\.pdf$|\.png$|\.jpg$|\.pt$|\.pth$|\.safetensors$'

解释:

git ls-files

表示列出 Git 当前已经追踪的文件。

如果这条命令没有输出可疑文件,说明 Git 仓库里没有这些数据文件。


3. 如果已经把数据集 add 进去了怎么办?

执行:

# 清空 Git 当前暂存和追踪记录,但保留本地文件
git rm -r --cached .

# 重新按 .gitignore 规则添加文件
git add .

然后再检查:

# 查看是否还有数据文件准备提交
git status

4. 如果已经把数据集 commit 了怎么办?

如果还没有 push,可以执行:

# 移除被 Git 跟踪的数据文件,但不删除本地文件
git rm -r --cached .

# 重新添加符合 .gitignore 的文件
git add .

# 再提交一次,说明移除了不该追踪的文件
git commit -m "Remove ignored files"

如果已经 push 到远程仓库,处理会更复杂,可能需要清理 Git 历史。

所以一定记住:

先写 .gitignore,再 git add .

5. 为什么 git push 会出现 rejected?

常见原因是远程仓库里已经有 README 或 License。

解决:

# 拉取远程内容并合并
git pull origin main --allow-unrelated-histories --no-rebase

# 再推送
git push -u origin main

6. nano 编辑器怎么退出?

如果进入 nano,直接按:

Ctrl + O
Enter
Ctrl + X

意思是:

保存
确认
退出

三十、从工程管理角度看,推荐的项目结构

对于机器学习或视觉大模型项目,推荐结构类似:

your_project/
├── README.md                 # 项目说明
├── requirements.txt          # Python 依赖
├── .gitignore                # Git 忽略规则
├── configs/                  # 配置文件
├── scripts/                  # 脚本
├── src/                      # 核心源码
├── notebooks/                # 实验 notebook
├── docs/                     # 文档
├── data/                     # 本地数据,不上传
├── outputs/                  # 输出结果,不上传
├── checkpoints/              # 模型权重,不上传
└── logs/                     # 日志,不上传

这里面一般应该上传:

README.md
requirements.txt
.gitignore
configs/
scripts/
src/
docs/

一般不上传:

data/
outputs/
checkpoints/
logs/
.env

这样做的好处是:

  1. 仓库干净;
  2. 别人能看懂代码;
  3. 不会误传大文件;
  4. 不会泄露密钥;
  5. 后续复现实验更方便;
  6. 项目更符合工程规范。

三十一、最终总结

对于新手来说,Git 不应该只理解成“上传 GitHub 的工具”。

更准确地说:

Git 是本地代码版本管理工具,GitHub 是远程代码托管平台。

常用流程是:

工作区修改代码
↓
git add 加入暂存区
↓
git commit 保存到本地仓库
↓
git push 上传到 GitHub

机器学习项目尤其要注意:

代码可以上传
数据集不要随便上传
模型权重不要随便上传
API Key 绝对不要上传

所以在第一次提交前,一定要先写好:

.gitignore

并且每次提交前都执行:

git status

只要养成这个习惯,就能避免大多数 Git 新手常见错误。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐