导读
你是不是经历过这样的场景:改代码改到一半,老板突然说"先别动了,做个紧急修复"?或者更惨——改完发现代码全乱了,想回到昨天的版本却找不到路了?
这就是版本控制要解决的问题。Git 是目前最流行的版本控制工具,几乎所有开源项目(从 Linux 内核到 React)都在用它。学完本篇你不仅能管好自己的代码,还能参与团队协作、在分支上独立开发、甚至处理复杂的合并冲突。
本文以「日常开发」为主线,从克隆仓库开始,一步步走通:创建分支 → 提交更改 → merge 合并 → 必要时用 rebase 或 reset 回滚 → push 到远程。每个命令都附带解释,小白也能跟练。
参考基准:Runoob Git 教程(国内可直接访问)。如需更权威的官方文档,可参考 Git 中文文档 (git-scm.xyz) 或 GitHub Docs(国内用户可用 ghfast.top 代理加速)。
第一步:把代码 Clone 下来
打开终端(Windows 用 PowerShell 或 Git Bash),运行:
# 把远程仓库克隆到本地,<url> 替换为实际地址
git clone https://github.com/用户名/项目名.git
# 进入项目目录
cd 项目名
白话解释:clone 就是把服务器上的整个项目(包括所有历史提交记录)复制到你的电脑里。之后你所有的操作都在本地完成,不需要联网。
国内提示:如果
github.com连接慢或超时,可以用 ghfast.top 代理加速,把 URL 中的github.com替换为ghfast.top/github.com即可。
第二步:理解 Git 的三大区域
这是学习 Git 最重要的概念——理解了就不再死记硬背命令。
Git 的工作区分为三个区域:
| 区域 | 白话解释 | 对应操作 |
|---|---|---|
| 工作区 (Working Directory) | 你当前正在编辑的文件 | 写代码、改文件 |
| 暂存区 (Staging Area) | 一个"待发货清单",标记哪些改动准备提交 | git add |
| 仓库区 (Repository) | 已保存的版本,像拍照存档 | git commit |
用一个生活类比:你在厨房做菜(工作区),做好一道菜后先摆盘拍照放进相册(暂存区),周末统一把相册装订成册(仓库区)。
第三步:日常开发的分支工作流
3.1 为什么需要分支?
想象你在一本共享笔记本上写文章。如果你直接在原页面上涂改,其他同时看这本笔记的人就会看到混乱的过程。分支就是一张"透明复制纸"——你在上面随便改,不影响原版;改好了再贴回去。
Git 中最常见的分支:
main(或master):主分支,存放稳定可用的代码feature/xxx:功能分支,用于开发新功能bugfix/xxx:修复分支,用于修 bughotfix/xxx:热修复分支,紧急问题直接用
3.2 创建并使用分支
# 查看当前有哪些分支(* 号表示当前所在分支)
git branch
# 输出类似:
# feature/login
# * main ← 星号在 main,说明你现在在主分支
# 新建一个叫 feature/user-auth 的分支,并自动切换过去
git checkout -b feature/user-auth
# 或者用新版写法(Git 1.20+,推荐):
git switch -c feature/user-auth
# 现在你可以在这个分支上放心地改了——不会影响 main 分支
命令解析:
checkout -b:checkout是切换分支的命令,-b表示"同时新建"switch -c:Git 近年推出的新命令,语义更清晰——switch专用于切换,-c表示新建
3.3 在分支上提交更改
在 feature/user-auth 分支上做了几天的开发后:
# 查看当前状态:哪些文件被修改了
git status
# 输出示例:
# modified: src/auth.py
# modified: tests/test_auth.py
# new file: docs/oauth-flow.md
# 把修改的文件添加到"暂存区"(也就是放入待提交清单)
git add src/auth.py tests/test_auth.py
# 或者一次性把所有改动全部加入暂存区(推荐日常使用)
git add .
# 正式提交到本地仓库(提交前请仔细写好 message!)
git commit -m "feat: 完成用户登录验证功能
- 新增 OAuth2.0 认证流程
- 添加登录页面单元测试
- 修复密码加密时的边界情况"
💡 最佳实践:commit message 尽量写得让人一眼看懂做了什么。推荐使用 Conventional Commits 规范(虽然本文不深入展开,但养成好习惯对你以后看开源项目的日志非常有帮助)。
云间小贴士:写完 commit message 拿不准好不好?可以把代码 diff 发给 AI 助手帮你润色。如果想省事,可以直接用云端 OpenAI 兼容 API(比如云间 API 中转站,国内直连无需翻墙,90+ 模型按量计费,价格仅为官方价的零头)来生成规范的 commit message。
第四步:Merge vs Rebase——合并代码的两种姿势
当你觉得功能开发完成了,就要把它合回 main。Git 提供两种方式,各有优劣。
4.1 Merge(合并)——保守稳妥派
# 切回主分支
git checkout main
# 把 feature/user-auth 分支合并到 main
git merge feature/user-auth
# 如果有冲突,Git 会停下来让你手动解决(见第七节)
Merge 的特点:
- ✅ 安全:保留完整的分支历史,像一条真正的分叉线
- ✅ 直观:谁从谁合并来的,一目了然
- ❌ 历史记录会变"胖":每合并一次就多一个 merge commit,长长的时间线上会有很多"合并节点"
适合场景:团队协作、开源项目、需要保留完整审计轨迹的场景。
4.2 Rebase(变基)——简洁美观派
# 切换到你要"挪位置"的分支
git checkout feature/user-auth
# 把 feature/user-auth 的所有提交"搬"到 main 的最新提交之后
git rebase main
Rebase 的本质不是合并,而是**“把你的提交重新放到另一条线的末尾重写一遍”**。效果是你的分支看起来像是直接在 main 最新代码基础上开发的。
Rebase 的特点:
- ✅ 历史干净:提交记录是一条直线,没有多余的 merge commit
- ✅ 阅读友好:看
git log时思路清晰 - ❌ 有风险:如果 rebased 的分支已经在远程共享过,强行 rebase 推送会导致别人电脑出错
- ❌ 理解门槛高:出问题比 merge 难排查
📌 黄金法则:
| 场景 | 选择 |
|---|---|
| 个人私有分支(还没 push 过) | rebase,保持历史整洁 |
| 已经 push 到远程、别人可能在用的分支 | merge,绝不 rebase |
| 团队大项目,不确定 | merge,安全第一 |
4.3 一图胜千言
下面这张图展示了 main 分支和 feature 分支的关系:
图中绿色主线是 main,橙色支线是 feature/login,蓝色箭头表示 merge 回来。你可以看到 C/D/E 三次提交是在 feature 分支上完成的,最后 merge 到 main 变成了 F 节点。
第五步:回滚三招式——出错了怎么办?
代码写砸了、误删了关键文件、提交了不该 push 的内容……别慌,Git 给了你三种回滚方式。选对方法很关键,选错可能适得其反。
招式一:Reset —— 时光倒流
# 查看最近几次提交的 ID(取前几位就行)
git log --oneline -5
# 输出:
# a1b2c3d feat: 完成用户登录验证功能
# e4f5g6h fix: 修复密码加密 bug
# i7j8k9l docs: 更新 README
# 【软重置】只回退版本,但保留你的修改在工作区(方便继续改)
git reset --soft HEAD~1
# 【混合重置】回退版本 + 清除暂存区,但文件改动还在工作区
# ⭐ 最常用:相当于"撤销这次 commit",改动留给你调整
git reset --mixed HEAD~1
# (--mixed 是默认值,可以简写为 git reset HEAD~1)
# 【硬重置】⚠️ 一切归零:回退版本 + 丢弃所有未提交的改动
# 警告:HEAD~1 之后的所有修改都会丢失!务必确认好再执行
git reset --hard HEAD~1
白话记忆:
| –soft | –mixed(默认) | –hard |
|---|---|---|
| 回到上一个版本,改动原封不动留着 | 回到上一个版本,改动保留但你得重新 add | 完全回到上一个版本,什么都没留下 |
| 适合:还想微调后再提交 | 适合:commit 消息写错了想重写 | 适合:彻底不要这次改动了 |
⚠️ 注意:
reset是针对本地历史的操作。如果你的代码已经 push 到远程,reset 之后 push 会被拒绝(见下文)。此时应该用下文的 revert。
招式二:Revert —— 开倒车
# 撤销某次特定提交,生成一个新的"反向提交"来抵消它的效果
git revert <commit-id>
# 举例:假设 a1b2c3d 那次提交出了问题
git revert a1b2c3d
Revert 的核心特点:
- ✅ 安全:不改变任何已有历史,只是添加一个新提交来抵消之前的改动
- ✅ 适合远程共享的分支:同事可以随时 pull 到这次"撤销提交"
- ❌ 历史不会消失:被 revert 的那次提交仍然在日志里,只是效果被抵消了
Reset vs Revert 怎么选?
| Reset | Revert | |
|---|---|---|
| 改不改历史 | 改写(危险!) | 不改(安全) |
| 能用在远程分支吗 | 不能(除非 force push) | 完全可以 |
| 适合谁 | 只在你的本地私密分支用 | 任何人、任何分支 |
| 本质 | 让指针往回移 | 加一个新提交抵消旧提交 |
口诀:本地用 reset,远程用 revert。
招式三:Checkout / Restore —— 撤回单个文件的修改
有时候你只是想放弃某个文件的改动,而不是全局回滚:
# 【旧方法】放弃某个文件的所有未提交改动
git checkout -- src/auth.py
# 【新方法】Git 2.23+ 推荐的专用命令
git restore src/auth.py
# 如果想恢复之前某次提交中的某个文件版本
git restore --source=<commit-id> src/auth.py
总结三招的选择逻辑:
┌─────────────────────────────────┐
│ 我想撤回一些改动 │
└──────────────┬──────────────────┘
│
┌─────┴─────┐
▼ ▼
只改一个文件? 改了很多文件?
│ │
git restore 想保留改动吗?
│ ┌──┴──┐
│ 保留 不要了?
│ │ │
放弃文件 git reset git revert
改动 --soft/mixed (针对远程分支)
或
git reset --hard
(仅本地私有时)
└─────────────────────────────────┘
第六步:Push 到远程 & Pull 拉取更新
本地搞定了,该把成果分享给团队成员了。
6.1 Push(推送)
# 把当前分支推送到远程同名分支
git push origin main
# 首次推送时需要告诉 Git 上游关系(之后就不用写了)
git push -u origin main
# -u = --set-upstream,记住"当前分支跟踪 origin/main"
# 推送指定分支
git push origin feature/user-auth
# 强制推送 ⚠️(只有确定要覆盖远程历史时才用)
git push --force-with-lease origin main
# --force-with-lease 比 --force 安全:如果别人在你的提交之后也 push 了,
# 它会拒绝推送而不是直接覆盖别人的代码
6.2 Pull(拉取)
# 拉取远程最新代码并自动合并到当前分支
git pull origin main
# 等价于以下两步的组合:
# git fetch origin main (下载远程最新内容,但不合并)
# git merge origin/main (合并到当前分支)
# 如果你想先把本地改动暂存再拉取(避免冲突)
git stash # 把未提交的改动临时存放
git pull origin main # 拉取远程更新
git stash pop # 把暂存的改动放回来,可能需要解决冲突
6.3 Fetch 和 Pull 的区别
很多新手混淆这两个命令,这里澄清一下:
fetch | pull | |
|---|---|---|
| 做什么 | 只看远程有什么变化,下载到本地但不合并 | 下载并立即合并 |
| 安不安全 | 更安全(可以先看看再决定怎么合并) | 可能引入冲突 |
| 什么时候用 | 想先看远程更新了啥再小心合并 | 确认远程没啥大问题,直接拿来用 |
建议 workflow:先用 fetch 看看别人改了啥,再用 merge 或 rebase 合并,比直接 pull 更可控。
第七步:解决合并冲突——两个版本打架了
当两个人同时修改了同一个文件的同一行,Git 就不知道该听谁的——这就叫冲突 (Conflict)。
触发冲突的例子
场景:你和同事都在修改 config.py
你改了第 10 行:database_host = "localhost"
同事改了第 10 行:database_host = "192.168.1.100"
你们分别把自己的分支 push 上去后,尝试 merge 时会冲突
解决步骤
# 1. 执行 merge 或 pull 时 Git 提示冲突
$ git merge feature/user-auth
Auto-merging config.py
CONFLICT (content): Merge conflict in config.py
Automatic merge failed; fix conflicts and then commit the result.
# 2. 看哪些文件有冲突
git status
# 输出会标注:both modified: config.py
# 3. 打开冲突文件,找到冲突标记
# config.py 的内容会是这样的:
# === 前面是你和同事都没改的部分 ===
database_port = 5432
<<<<<<< HEAD
database_host = "localhost" ← 你(当前分支)的版本
=======
database_host = "192.168.1.100" ← 对方( incoming 分支)的版本
>>>>>>> feature/user-auth ← 对方的提交标识
# === 后面又是没改的部分 ===
# 4. 手动编辑,决定保留哪个(或写一个折中方案)
# 比如改成:
database_host = "db.example.com" # 用统一的数据库地址
# 5. 标记冲突已解决
git add config.py
# 6. 完成合并提交
git commit -m "Merge feature/user-auth: 解决 config.py 冲突"
高级工具:用图形化比较工具
如果你不喜欢手改,可以让 Git 用可视化工具帮你对比:
# macOS
git mergetool --tool=opendiff
# Windows(安装了 VS Code 的话)
git mergetool --tool=code --no-index
# Linux(安装了 meld 的话)
git mergetool --tool=meld
# 完成后工具会问你:解决了?点了 Yes 就算你处理完了
预防冲突的小技巧
- 频繁 pull/fetch:每天开工先拉一下远程最新代码
- 小步提交:每次改的东西越少,冲突的概率越低、范围越小
- 沟通:如果知道同事也在改同一个模块,先协调好分工
第八步:几个超实用的 Git 小技巧
学会这些,你的 Git 水平直接超过 80% 的用户。
8.1 Git Log 美化——一眼看清谁干了什么
# 以单行格式显示历史,附带作者和时间
git log --oneline --all --graph --decorate
# 输出类似:
# * f2a8b3c (HEAD -> main, origin/main) feat: 完成用户登录
# |\
# | * d4e5f6a (feature/login) feat: 新增登录页 UI
# |/
# * b1c2d3e fix: 修复密码加密 bug
# * a0b1c2d docs: 更新 README
# 加上日期,信息更全
git log --oneline --all --graph --date=short --format="%h %ad %s"
8.2 Stash(暂存)——快速切换战场
# 把当前的未提交改动"塞进口袋"
git stash save "WIP: 用户认证模块还差测试"
# 做点别的(比如修个紧急 bug)
git checkout main
# ... 修 bug ...
git commit -m "fix: 紧急修复登录超时问题"
# 做完回来,把之前塞进口的东西拿出来
git stash pop
# 想看口袋里还有多少个 stash
git stash list
# 输出:stash@{0}: WIP: 用户认证模块还差测试
# stash@{1}: WIP: 首页改版
# 清理掉已经不需要的 stash
git stash drop stash@{0}
# 或者一键清空所有 stash
git stash clear
8.3 Tag(标签)——标记重要版本
# 轻量标签(只是一个名字指向某个提交)
git tag v1.0.0
# 带注释的标签(更正式,推荐发布时用)
git tag -a v1.0.0 -m "Release v1.0.0 - 首个稳定版本"
# 把标签推送到远程(Git 默认不传标签)
git push origin v1.0.0
# 或者推送所有标签
git push origin --tags
# 检查某个标签指向哪里
git show v1.0.0
8.4 .gitignore——告诉 Git 忽略哪些文件
# 在项目根目录创建 .gitignore 文件
touch .gitignore
# 常见忽略规则(写入 .gitignore):
# Python
__pycache__/
*.py[cod]
*.egg-info/
.venv/
# 系统文件
.DS_Store
Thumbs.db
# IDE
.vscode/
.idea/
# 敏感信息
.env
secrets.json
8.5 Aliases(别名)——少敲键盘
# 给常用命令设缩写(只需设置一次)
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --oneline --all --graph --decorate"
# 之后只需要输入:
git st # 代替 git status
git co main # 代替 git checkout main
git lg # 漂亮的日志视图
如果你觉得一个个配太麻烦,一键脚本会自动帮你写好推荐的
.gitconfig配置——详见文末的脚本部分。对于国内用户,脚本还会检测网络环境并推荐合适的镜像源。
全文速查表
| 你想做什么 | 命令 |
|---|---|
| 克隆远程仓库 | git clone <url> |
| 查看状态 | git status |
| 暂存文件 | git add <file> 或 git add . |
| 提交改动 | git commit -m "描述" |
| 新建并切换分支 | git switch -c <branch> |
| 切换分支 | git switch <branch> |
| 列出所有分支 | git branch |
| 合并分支 | git merge <branch> |
| 变基到另一条线 | git rebase <branch> |
| 撤销上次 commit(保留改动) | git reset --mixed HEAD~1 |
| 撤销上次 commit(丢弃改动) | git reset --hard HEAD~1 |
| 安全撤销远程提交 | git revert <commit-id> |
| 放弃某个文件改动 | git restore <file> |
| 推送到远程 | git push origin <branch> |
| 拉取远程更新 | git pull origin <branch> |
| 暂存未完成的改动 | git stash save "说明" |
| 打版本号标签 | git tag -a v1.0.0 -m "说明" |
下一步
到这里你已经掌握了 Git 的日常完整工作流。如果要更进一步,推荐了解:
- Git Flow:一套标准化的分支命名和流转约定(develop/release/hotfix 等)
- Cherry-pick:只取别人分支上的某几次提交,不做整条分支合并
- Bisect:用二分法快速定位是哪次提交引入了 bug(类似折半查找)
当然,工具装好只是第一步——让 AI 帮你写 commit message、查命令报错、review 代码,才能真正提高效率。推荐使用云端 OpenAI 兼容 API(如云间 API 中转站,香港节点国内直连免翻墙,支持 OpenAI 和 Anthropic 两大模型生态,90+ 模型按需调用,价格不到官方价的五折),随时随地给你的开发流程装上"智能助手"。
📜 转载许可:本文采用 CC BY-NC-SA 4.0 协议,欢迎非商业性转载,请注明出处并保持相同许可证。
脚本公开源码,欢迎复制给任何 AI 审查。 不方便下载的同学也可以直接从以下链接获取:
- Linux/macOS/WSL:
https://cleanresolver.com/scripts/install-git-guide.sh- Windows:
https://cleanresolver.com/scripts/install-git-guide.ps1
#!/usr/bin/env bash
# ============================================================
# Git 版本控制实战 一键脚本(macOS / Linux / WSL)
# 公开源码,欢迎审查 —— 不放心可先复制给 AI 判断
# 功能:检测 git → 推荐配置 .gitconfig → 创建示例仓库
# ============================================================
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
step() { echo -e "${CYAN}[STEP]${NC} $1"; }
detect_network() {
step "检测网络环境(国内 / 国外)..."
if curl -fsI --max-time 5 "https://claude.ai" >/dev/null 2>&1; then
info "可直连 claude.ai,判定为海外网络"
echo "overseas"
else
warn "无法直连 claude.ai,判定为国内网络环境(将推荐镜像源 + 加速配置)"
echo "domestic"
fi
}
check_git() {
step "检查 Git 是否安装..."
if command -v git >/dev/null 2>&1; then
local VERSION
VERSION=$(git --version 2>/dev/null)
info "Git 已安装:$VERSION"
return 0
fi
warn "Git 未安装,开始安装..."
local NET="$1"
# 根据操作系统选择安装方式
if command -v apt >/dev/null 2>&1; then
# Debian / Ubuntu
if [ "$NET" = "domestic" ]; then
info "国内环境,使用清华镜像源安装..."
if sudo apt update -o Dir::Etc::sourcelist="sources.list.d/debian-mirror.sources" \
-o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" 2>/dev/null; then
sudo apt install -y git
else
# CONNECT 断网回退:尝试阿里源
warn "清华源失败,回退阿里源..."
sudo apt install -y git 2>/dev/null || true
fi
else
sudo apt install -y git
fi
elif command -v yum >/dev/null 2>&1; then
# CentOS / RHEL / Fedora
sudo yum install -y git
elif command -v brew >/dev/null 2>&1; then
# macOS Homebrew
if [ "$NET" = "domestic" ]; then
info "国内环境,Homebrew 使用清华大学镜像..."
export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles
fi
brew install git
elif command -v apk >/dev/null 2>&1; then
# Alpine Linux
sudo apk add git
else
error "无法识别的包管理器。请手动安装 Git:"
echo " 官网:https://git-scm.com/downloads"
echo " 国内镜像:https://mirrors.aliyun.com/gitosis/git-for-windows/"
return 1
fi
if command -v git >/dev/null 2>&1; then
info "Git 安装成功!"
return 0
else
error "Git 安装失败。请确保你有管理员权限(sudo)。"
echo " 也可以手动下载安装:https://git-scm.com/downloads"
return 1
fi
}
configure_gitconfig() {
step "配置 ~/.gitconfig(提升日常体验)..."
cat > ~/.gitconfig <<'GITCONFIG'
[user]
name = YourName
email = [email protected]
[init]
defaultBranch = main
[core]
autocrlf = false
eol = lf
[color]
ui = auto
[alias]
st = status
br = branch
co = checkout
cm = commit
lg = log --oneline --all --graph --decorate
lga = log --oneline --all --graph --decorate --date=short
[push]
default = simple
GITCONFIG
info "~/.gitconfig 已生成(请编辑第 3-4 行,填入你的名字和邮箱)"
info "已设置别名:st=status, br=branch, co=checkout, cm=commit, lg=漂亮日志"
if [ "$(uname)" = "Darwin" ]; then
warn "macOS 注意:Git 默认会做 CRLF/LF 转换。上面的 autocrlf=false 已关闭。"
warn "如需用 Windows 风格换行,改为 autocrlf=true"
fi
}
create_demo_repo() {
step "创建示例仓库演示 git init / add / commit..."
local DEMO_DIR="$HOME/git-demo-project"
if [ -d "$DEMO_DIR" ]; then
warn "示例仓库已存在:$DEMO_DIR"
echo " 想重新创建请先删除:rm -rf $DEMO_DIR"
return 0
fi
mkdir -p "$DEMO_DIR" && cd "$DEMO_DIR" || exit 1
git init
git checkout -b main
# 创建几个示例文件
cat > README.md <<'README'
# Git Demo Project
这是一个用于练习 Git 的示例仓库。
跟着下面的步骤走一遍,你就能熟悉最常用的 Git 命令。
## 练习步骤
1. 创建新分支: \`git switch -c feature/hello\`
2. 修改文件并提交
3. 回到 main 并合并: \`git merge feature/hello\`
4. 试试回滚: \`git reset\` 或 \`git revert\`
README
cat > app.py <<'PYEOF'
"""简易示例:欢迎程序"""
def greet(name: str) -> str:
return f"Hello, {name}! Welcome to Git practice."
if __name__ == "__main__":
print(greet("World"))
PYEOF
mkdir -p tests
cat > tests/test_app.py <<'TESTEOF'
"""示例测试"""
from app import greet
def test_greet():
assert greet("Git") == "Hello, Git! Welcome to Git practice."
def test_greet_empty():
assert greet("") == "Hello, ! Welcome to Git practice."
if __name__ == "__main__":
test_greet()
test_greet_empty()
print("All tests passed!")
TESTEOF
# 忽略虚拟环境目录
echo ".venv/" > .gitignore
git add .
git commit -m "init: 创建示例项目结构"
info "示例仓库已创建:$DEMO_DIR"
echo ""
info "接下来请在 $DEMO_DIR 中练习以下步骤:"
echo " 1. 创建分支: git switch -c feature/hello"
echo " 2. 编辑文件,然后:"
echo " git add ."
echo " git commit -m 'feat: 练习提交'"
echo " 3. 合并回 main:"
echo " git switch main"
echo " git merge feature/hello"
echo " 4. 回滚实验:"
echo " git reset --soft HEAD~1 # 试试不同的 reset 模式"
}
main() {
echo "============================================"
echo " Git 版本控制实战 一键配置脚本"
echo " 适用于 macOS / Linux / WSL"
echo "============================================"
echo ""
echo " 公开源码,欢迎审查 —— 可复制给 AI 判断"
echo " 功能:检测 git / 推荐配置 / 创建练习仓库"
echo ""
local NET
NET=$(detect_network)
check_git "$NET" || {
error "Git 不可用,脚本终止。"
exit 1
}
configure_gitconfig
create_demo_repo
echo ""
echo "============================================"
info "全部完成!"
echo " Git 配置已就绪,示例仓库在 ~/git-demo-project/"
echo " 进去跟着练一遍基础命令就能上手了"
echo " 配置别名:git st | git br | git co | git lg"
echo ""
echo " 想让 AI 帮你写 commit message 或查报错?"
echo " 用云端 OpenAI 兼容 API(如 https://cloudzone-api.cyou/,"
echo " 国内直连免翻墙,90+ 模型,0.05x 起)"
echo "============================================"
}
main "$@"
# ============================================================
# Git 版本控制实战 一键脚本(Windows PowerShell)
# 公开源码,欢迎审查 -- 不放心可先复制给 AI 判断
# 功能:检测 git → 推荐配置 .gitconfig → 创建示例仓库
# ============================================================
$ErrorActionPreference = "Stop"
function Write-Info { Write-Host "[INFO] $args" -ForegroundColor Green }
function Write-Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow }
function Write-Err { Write-Host "[ERROR] $args" -ForegroundColor Red }
function Write-Step { Write-Host "[STEP] $args" -ForegroundColor Cyan }
function Detect-Network {
Write-Step "检测网络环境(国内 / 国外)..."
try {
$null = Invoke-WebRequest -Uri "https://claude.ai" -Method Head -TimeoutSec 5 -UseBasicParsing
Write-Info "可直连 claude.ai,判定为海外网络"
return "overseas"
} catch {
Write-Warn "无法直连 claude.ai,判定为国内网络环境(将推荐镜像源 + 加速配置)"
return "domestic"
}
}
function Check-Git {
Write-Step "检查 Git 是否安装..."
$gitCmd = Get-Command git -ErrorAction SilentlyContinue
if ($gitCmd) {
$versionOutput = & git --version 2>&1
Write-Info "Git 已安装:$versionOutput"
return $true
}
Write-Warn "Git 未安装,请先安装:"
Write-Host ""
Write-Host " 方式一(推荐,Chocolatey):"
Write-Host " 以管理员身份打开 PowerShell,运行:"
Write-Host ' choco install git -y'
Write-Host ""
Write-Host " 方式二(winget):"
Write-Host " winget install Git.Git"
Write-Host ""
Write-Host " 方式三(手动下载):"
Write-Host " 官网:https://git-scm.com/download/win"
Write-Host " 国内镜像:https://mirrors.aliyun.com/gitosis/git-for-windows/"
Write-Host ""
Write-Host " 安装完成后请重启 PowerShell 再运行本脚本。"
return $false
}
function Configure-GitConfig {
Write-Step "生成 ~/.gitconfig 推荐配置..."
$gitConfigContent = @"
[user]
name = YourName
email = [email protected]
[init]
defaultBranch = main
[core]
autocrlf = input
eol = crlf
[color]
ui = auto
[alias]
st = status
br = branch
co = checkout
cm = commit
lg = log --oneline --all --graph --decorate
[push]
default = simple
"@
$gitConfigPath = Join-Path $env:USERPROFILE ".gitconfig"
if (Test-Path $gitConfigPath) {
Write-Warn "~/.gitconfig 已存在,将备份后写入推荐配置"
Copy-Item $gitConfigPath "$gitConfigPath.bak.$((Get-Date).ToString('yyyyMMdd-HHmmss'))" -Force
}
$gitConfigContent | Out-File -FilePath $gitConfigPath -Encoding UTF8
Write-Info "~/.gitconfig 已生成(请编辑第 3-4 行,填入你的名字和邮箱)"
Write-Info "已设置别名:st=status, br=branch, co=checkout, cm=commit, lg=漂亮日志"
Write-Host ""
Write-Host " Windows 注意:autocrlf=input 会在提交时把 CRLF 转为 LF,"
Write-Host " 检出时保留 CRLF(适合 Windows 编辑器)。"
Write-Host " 如需始终用 LF,把上面模板中的 autocrlf 改为 false"
}
function Create-DemoRepo {
Write-Step "创建示例仓库演示 git init / add / commit..."
$demoDir = Join-Path $env:USERPROFILE "git-demo-project"
if (Test-Path $demoDir) {
Write-Warn "示例仓库已存在:$demoDir"
Write-Host " 想重新创建请先删除:Remove-Item -Recurse -Force $demoDir"
return
}
New-Item -ItemType Directory -Path $demoDir -Force | Out-Null
Set-Location $demoDir
git init
git checkout -b main 2>$null -or git branch -m main
# README.md
@"
# Git Demo Project
这是一个用于练习 Git 的示例仓库。
跟着下面的步骤走一遍,你就能熟悉最常用的 Git 命令。
## 练习步骤
1. 创建新分支: \`git switch -c feature/hello\`
2. 修改文件并提交
3. 回到 main 并合并: \`git merge feature/hello\`
4. 试试回滚: \`git reset\` 或 \`git revert\`
"@ | Out-File -FilePath "README.md" -Encoding UTF8
# app.py
@"
'''简易示例:欢迎程序'''
def greet(name: str) -> str:
return f"Hello, {name}! Welcome to Git practice."
if __name__ == "__main__":
print(greet("World"))
"@ | Out-File -FilePath "app.py" -Encoding UTF8
# tests/test_app.py
New-Item -ItemType Directory -Path "tests" -Force | Out-Null
@"
'''示例测试'''
from app import greet
def test_greet():
assert greet("Git") == "Hello, Git! Welcome to Git practice."
def test_greet_empty():
assert greet("") == "Hello, ! Welcome to Git practice."
if __name__ == "__main__":
test_greet()
test_greet_empty()
print("All tests passed!")
"@ | Out-File -FilePath "tests/test_app.py" -Encoding UTF8
# .gitignore
".venv/" | Out-File -FilePath ".gitignore" -Encoding UTF8
git add .
git commit -m "init: 创建示例项目结构"
Write-Info "示例仓库已创建:$demoDir"
Write-Host ""
Write-Info "接下来请在 $demoDir 中练习:"
Write-Host " 1. 创建分支: git switch -c feature/hello"
Write-Host " 2. 编辑文件,然后:"
Write-Host " git add ."
Write-Host " git commit -m 'feat: 练习提交'"
Write-Host " 3. 合并回 main:"
Write-Host " git switch main"
Write-Host " git merge feature/hello"
Write-Host " 4. 回滚实验:"
Write-Host " git reset --soft HEAD~1 # 试试不同的 reset 模式"
}
# ---- 主入口 ----
Write-Host "============================================"
Write-Host " Git 版本控制实战 一键配置脚本"
Write-Host " 适用于 Windows (PowerShell)"
Write-Host "============================================"
Write-Host ""
Write-Host " 公开源码,欢迎审查 -- 可复制给 AI 判断"
Write-Host " 功能:检测 git / 推荐配置 / 创建练习仓库"
Write-Host ""
$net = Detect-Network
if (-not (Check-Git)) {
Write-Err "Git 未安装,请安装后重跑本脚本。"
Write-Host ""
Write-Host " 快速安装(需要管理员权限):"
Write-Host " choco install git -y (Chocolatey)"
Write-Host " winget install Git.Git (winget)"
exit 1
}
Configure-GitConfig
Create-DemoRepo
Write-Host ""
Write-Host "============================================"
Write-Info "全部完成!"
Write-Host " Git 配置已就绪,示例仓库在 ~/git-demo-project/"
Write-Host " 进去跟着练一遍基础命令就能上手了"
Write-Host " 配置别名:git st | git br | git co | git lg"
Write-Host ""
Write-Host " 想让 AI 帮你写 commit message 或查报错?"
Write-Host " 用云端 OpenAI 兼容 API(如 https://cloudzone-api.cyou/,"
Write-Host " 国内直连免翻墙,90+ 模型,0.05x 起)"
Write-Host "============================================"
请完成验证后查看评论区