从 0 到可推送:一次真实的 Git 本地 → Gitee 提交流程记录
一、写在前面:为什么要记录这次 Git 实践
之前对 Git 的理解,一直停留在「知道有这个东西,但不太敢用」。真正用的时候,经常会有几个问题:
.git是什么?git add到底在干嘛?- 为什么我本地已经有了,远程仓库却什么都没有?
- 分支看起来很复杂,是不是新手不该碰?
最近在做一个实际项目,需要代码可追溯、可交付、可回滚,不得不把 Git 从“知道”变成“真的会用”。
所以就趁这次 从新建仓库 → 提交 → 推送 → 分支 的完整过程,做一次记录。
使用的工具:git bash、gitee
二、本地已有代码,如何初始化 Git 仓库
2.1 当前目录状态说明
我的实际场景是:
- 本地已经有代码文件(
.py、.txt等) - 之前只是普通文件夹
- 现在希望:把整个项目纳入 Git 管理
2.2 执行 git init 的作用
在bash执行:
git init这条命令做的事情非常简单,但非常关键:
- 在当前目录下生成一个
.git文件夹 .git是 Git 的“数据库 + 管理中心”- 你的代码文件本身没有任何变化
此时,这个目录就变成了一个本地 Git 仓库。
三、为什么一定要写 .gitignore
3.1 我的项目里有哪些“不该上传”的东西
在实际项目中,并不是所有文件都适合提交到仓库,比如:
- 编译产物
- 临时文件
- 日志文件
- 编辑器配置目录(
.vscode、.idea)
这些文件有几个特点:
- 对别人没用
- 每个人机器不一样
- 变动频繁,会污染提交记录
3.2 .gitignore 的真实作用(一句话)
.gitignore 的作用不是:
“不让你用这些文件”
而是:
不让 Git 追踪、记录这些文件
比如一个常见的 .gitignore 示例:
# 日志
*.log
*.tmp
# 编辑器配置
.vscode/
.idea/
# 构建产物
.env/写好 .gitignore 后,再进行 git add,Git 会自动忽略这些内容。
四、第一次提交:git add / git commit 到底在干嘛
4.1 git status:我第一次看懂它在说什么
初始化完成后,先执行:
git status常见会看到类似输出:
Untracked files: paiqi.py test.py这里的 Untracked files 意味着:
这些文件存在于目录中,但 Git 还没有“记住”它们
4.2 git add . 做了什么
执行:
git add .这一步的真实含义是:
- 把当前目录下的文件
- 放进 Git 的「暂存区(staging area)」
- 并不是提交
可以把它理解成:
“告诉 Git:这些文件,等下我要一起提交”
4.3 git commit -m 的意义
执行提交:
git commit -m "初始化项目结构"这一步才是真正的“存档”:
- Git 会记录当前所有暂存区文件的状态
- 形成一个不可变的 commit
-m后面的内容是给未来的自己看的
一个好的 commit 信息,应该能回答:
这一次改了什么?为什么改?
五、为什么本地有了,远程仓库却还没有
这是我当时最困惑的一点。
5.1 本地仓库 vs 远程仓库的区别
需要明确一个概念:
git init + git commit:只发生在你自己的电脑上
- 远程仓库(Gitee / GitHub)
- 完全不知道你本地做了什么
所以:
本地 commit ≠ 已上传
5.2 git push 发生了什么
当你执行:
git pushGit 才会做这件事:
把本地仓库里的 commit(历史 + 文件变化)
同步到远程仓库
这一步完成后,刷新 Gitee 页面,才能看到代码。
第 6 章:Git 分支(branch)的真实作用与实际开发流程
6.1 为什么要使用 Git 分支?
如果所有代码修改都直接提交到 master(或 main)分支,实际开发中会遇到两个核心问题:
1️⃣ 不安全
- 代码只改了一半
- 实验性修改
- 临时测试逻辑
这些都会直接污染主分支。
2️⃣ 不可控
一旦代码被改乱,很难快速回到一个:
- 干净的
- 稳定的
- 可交付的状态
6.2 分支的核心作用(一句话理解)
分支 = 在不影响主线代码的情况下,安全地进行开发、试验和修改
可以把分支简单理解为:
- master 分支
👉 对外可交付、稳定版本 - 开发分支(branch)
👉 我正在改、正在试、还没准备好给别人看的版本
6.3 结合真实场景理解分支的意义
以我自己的实际操作为例。
场景描述
仓库中已经存在一个稳定可用的文件:
XXX.py
该文件已经在 master 分支中提交,并且是可交付版本。
但今天我打算:
- 删除 2 个冗余函数
- 重构部分逻辑
- 不确定是否会影响整体排程结果
👉 如果直接在 master 上改,是有风险的
6.4 正确做法:基于 master 新建分支
git checkout -b refactor-clean-functions这一步做了两件事:
- 新建一个分支
- 并自动切换到该分支
此时需要注意:
- 文件名仍然是 XXX
.py - 但所有修改只存在于该分支
即使我把代码改崩了:
master依然是干净、稳定的- 可以随时切回
6.5 一个完整、推荐的实际开发流程
Step 1:确认当前分支
git branch示例输出:
* master说明当前在 master 分支。
Step 2:新建开发分支
git checkout -b refactor-clean-functionsStep 3:在分支中修改代码
例如:
- 删除
paiqi1226.py中的 2 个无用函数 - 简化时间计算逻辑
- 文件名不变
此时 Git 只是检测到:
当前文件内容与上一次提交不一致
Step 4:查看修改状态
git status可能看到:
modified: XXX.py
说明:
- 文件已被修改
- 但还未提交
Step 5:添加并提交修改
git add XXXX.py git commit -m "refactor: 删除冗余函数,简化逻辑"⚠️ 一个非常重要的点:
Git 并不是保存整个文件副本,而是记录“改了什么”
它会自动记录:
- 删除了哪些行
- 新增了哪些行
- 修改了哪些行
Step 6:推送分支到远程仓库
git push origin refactor-clean-functions这一步的意义是:
7.2 用一个极简例子理解 diff
假设你第一次提交的代码是:
def add(a, b): return a + b def sub(a, b): return a - b
后来你做了两件事:
现在文件变成了:
def add(a, b): return a + b + 1
当你执行:
git add paiqi1226.py git commit -m "refactor: 简化函数逻辑"
Git 实际记录的是类似这样的信息:
- def sub(a, b): - return a - b - return a + b + return a + b + 1
也就是说:
全部是自动完成的,不需要你额外做任何事。
7.3 文件再大,diff 会不会很慢?
结论一句话:
不会,正常规模的代码几乎感觉不到延迟
原因是:
哪怕是几千行、上万行的 Python 文件:
通常都是毫秒级到秒级
这也是 Git 能成为工业级工具的原因。
第 8 章:什么时候合并分支,什么时候保留分支?
这是一个非常实际、非常重要的问题。
8.1 什么情况下可以合并到 master?
当你的分支满足下面 3 个条件时,就可以合并:
典型场景:
此时可以:
8.2 什么情况下不合并,分支留着就好?
下面这些情况,完全可以不合并:
分支本身就是:
“可被丢弃的安全实验区”
你可以:
对 master 没有任何影响。
- 本地分支 → 远程分支
- 哪一行被删除了
- 哪一行被新增了
- 哪一行被修改了
- 删除
sub函数 - 修改
add函数逻辑 - ❌ 删除了哪些行
- ➕ 新增了哪些行
- ✏️ 哪些行被修改
- Git 使用的是行级比较算法
- 比较的是「上一次提交」vs「当前文件」
- 而不是全历史、全仓库扫描
git addgit commit- 功能已经完成
- 不会破坏已有逻辑
- 当前版本是“可以交付”的
- 修复完成一个 bug
- 重构完成且验证过
- 提交合并请求(MR / PR)
- 或本地合并后再 push 到 master
- 实验性分支
- 临时分析 / 调试
- 尝试但最终放弃的方案
- 不合并
- 不删除
- 甚至以后直接删掉
- 更新了可交付数据或算法逻辑
用于备份、提交合并请求、后续查看
第 7 章:Git 是如何自动记录 diff 的(原理 + 直觉示例)
很多新手都会有一个疑问:
我只执行了git add和git commit,
Git 是怎么知道我删了哪几行、改了哪几行的?
7.1 Git 记录的不是“文件”,而是“变化(diff)”
这是一个非常关键的认知:
Git 不是保存一整个文件的副本
而是保存:相对于上一次提交,发生了什么变化
也就是说,Git 内部关注的是: