练习前准备
设置工作环境
1
2
3
4
5
6
7
8
9
10
|
# 创建练习目录
mkdir git-practice
cd git-practice
# 查看是否已配置用户信息
git config --global --list | grep user
# 如果未设置,配置用户信息
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
|
基础操作
练习 1:仓库初始化与基本提交
创建项目结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 1. 创建并进入练习目录
mkdir exercise1
cd exercise1
# 2. 初始化仓库
git init
# 3. 创建文件
echo "# 这是一个Git练习项目" > README.md
cat > main.py << EOF
#!/usr/bin/env python3
print("Hello Git")
EOF
echo "测试数据1
测试数据2
测试数据3" > data.txt
|
分次提交
1
2
3
4
5
6
7
8
9
10
11
|
# 4. 提交README.md
git add README.md
git commit -m "添加README文件"
# 5. 提交main.py
git add main.py
git commit -m "添加主程序文件"
# 查看状态
git status
# 预期:显示data.txt是未跟踪文件
|
6-7:查看状态和历史
1
2
3
4
5
6
7
8
9
|
# 6. 查看状态
git status
# 输出应显示:data.txt (untracked)
# 7. 查看提交历史
git log --oneline
# 预期输出类似:
# 2a3b4c5 添加主程序文件
# 1a2b3c4 添加README文件
|
8-10:修改和提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# 8. 修改main.py
cat >> main.py << EOF
def add_numbers(a, b):
return a + b
if __name__ == "__main__":
result = add_numbers(5, 3)
print(f"5 + 3 = {result}")
EOF
# 9. 查看差异
git diff
# 显示main.py的修改内容
# 10. 一次性提交所有修改
git add .
git commit -m "为main.py添加add_numbers函数并提交所有文件"
# 验证
git log --oneline --graph
# 应该有3次提交
|
练习 2:文件管理
1-2:创建文件结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 回到git-practice目录
cd ../
# 1. 创建并进入exercise2
mkdir exercise2
cd exercise2
git init
# 2. 创建文件结构
mkdir src logs temp
echo "print('App started')" > src/app.py
echo "def helper(): pass" > src/utils.py
echo "2024-01-01 INFO: App started" > logs/app.log
echo "2024-01-01 ERROR: Something wrong" > logs/error.log
echo "temporary data" > temp/cache.tmp
echo "[database]
host=localhost
port=5432" > config.ini
|
3-5:.gitignore 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# 3. 暂存所有文件
git add .
# 4. 从暂存区移除logs文件(但不删除)
git rm --cached logs/app.log logs/error.log
# 5. 创建.gitignore
cat > .gitignore << EOF
# 忽略所有日志文件
*.log
# 忽略temp目录
temp/
# 忽略临时文件
*.tmp
# 忽略系统文件
.DS_Store
Thumbs.db
EOF
# 验证哪些文件被跟踪
git status
# 预期:logs/下的文件显示为untracked,temp/下的文件完全不显示
|
6-7:重命名和提交
1
2
3
4
5
6
7
8
9
10
|
# 6. 重命名文件
git mv config.ini settings.ini
# 查看状态
git status
# 应该显示:renamed: config.ini -> settings.ini
# 7. 提交
git add .gitignore
git commit -m "初始化项目结构,配置.gitignore,重命名配置文件"
|
🔄 第二阶段:撤销与恢复
练习 3:各种撤销操作
1-2:创建提交历史
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
cd ../
mkdir exercise3
cd exercise3
git init
# 第一章
echo "# 第一章:启程" > story.txt
git add story.txt
git commit -m "添加第一章"
# 第二章
echo "" >> story.txt
echo "# 第二章:冒险开始" >> story.txt
git add story.txt
git commit -m "添加第二章"
# 第三章
echo "" >> story.txt
echo "# 第三章:深入探索" >> story.txt
git add story.txt
git commit -m "添加第三章"
# 查看历史
git log --oneline
# 应该有3次提交
|
操作 1:checkout 撤销工作区修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 修改文件但未暂存
echo "# 错误的内容" >> story.txt
# 查看状态
git status
# 显示story.txt有修改但未暂存
# 撤销工作区修改
git checkout -- story.txt
# 验证文件是否恢复
git status
# 应该显示working tree clean
cat story.txt
# 应该只有三章内容,没有"错误的内容"
|
操作 2:reset 撤销暂存区修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 修改并暂存
echo "# 第四章:新的篇章" >> story.txt
git add story.txt
# 查看状态
git status
# 显示story.txt有修改已暂存
# 从暂存区移除
git reset HEAD story.txt
# 查看状态
git status
# 显示story.txt有修改但未暂存
# 文件内容还在吗?
cat story.txt | tail -1
# 应该显示"# 第四章:新的篇章"
|
操作 3:revert 撤销提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 先提交刚才的修改
git add story.txt
git commit -m "添加第四章"
# 查看历史
git log --oneline
# 应该有4次提交
# 撤销倒数第二次提交(第三章)
git revert HEAD~1
# 会打开编辑器,保存退出
# 查看文件内容
cat story.txt
# 第三章应该被删除了
# 查看历史
git log --oneline
# 应该有5次提交(包括revert那次)
|
操作 4:hard reset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 创建新文件并提交
echo "测试内容" > test.txt
git add test.txt
git commit -m "添加测试文件"
# 查看文件是否存在
ls
# 应该有story.txt和test.txt
# 硬重置到上一个提交
git reset --hard HEAD~1
# 再次查看
ls
# test.txt应该消失了!
git log --oneline
# 只有到revert的提交
# 警告:这是不可逆的,test.txt完全丢失了
|
🌿 第三阶段:分支管理
练习 4:基础分支操作
1-2:初始化项目
1
2
3
4
5
6
7
8
9
10
11
12
13
|
cd ../
mkdir exercise4
cd exercise4
git init
# 创建基础框架
mkdir src tests docs
echo "项目名称:MyApp" > README.md
echo "version = '1.0.0'" > config.py
git add .
git commit -m "初始化项目结构"
|
3-5:开发登录功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# 创建登录功能分支
git checkout -b feature/login
# 开发登录功能
cat > src/auth.py << EOF
def login(username, password):
"""用户登录功能"""
if username == "admin" and password == "123456":
return True
return False
def logout():
"""用户登出"""
return "Logged out"
EOF
git add src/auth.py
git commit -m "添加基础登录功能"
# 继续开发
echo "LOGIN_ATTEMPTS_LIMIT = 5" >> src/auth.py
git add src/auth.py
git commit -m "添加登录尝试限制"
# 添加测试
echo "import auth" > tests/test_auth.py
git add tests/test_auth.py
git commit -m "添加登录功能测试"
|
4-5:开发支付功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# 切换回main分支
git checkout main
# 创建支付功能分支
git checkout -b feature/payment
# 开发支付功能
cat > src/payment.py << EOF
def process_payment(amount, card_number):
"""处理支付"""
if len(card_number) != 16:
return False
return True
def refund(transaction_id):
"""退款处理"""
return f"Refund for {transaction_id}"
EOF
git add src/payment.py
git commit -m "添加支付处理功能"
# 继续开发
echo "PAYMENT_GATEWAY = 'Stripe'" >> src/payment.py
git add src/payment.py
git commit -m "配置支付网关"
|
6-7:合并与冲突
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 合并登录功能到main
git checkout main
git merge feature/login -m "合并登录功能"
# 应该会显示"Fast-forward"
# 尝试合并支付功能(模拟冲突)
# 先修改main中的README
echo "项目包含登录和支付功能" >> README.md
git add README.md
git commit -m "更新README说明"
# 在支付分支也修改README
git checkout feature/payment
echo "支付功能使用Stripe网关" >> README.md
git add README.md
git commit -m "更新支付功能说明"
# 尝试合并到main(会产生冲突)
git checkout main
git merge feature/payment
# 预期:CONFLICT (content): Merge conflict in README.md
|
8:解决冲突
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 查看冲突文件
cat README.md
# 会显示类似:
# <<<<<<< HEAD
# 项目包含登录和支付功能
# =======
# 支付功能使用Stripe网关
# >>>>>>> feature/payment
# 手动解决冲突(编辑README.md)
# 改为:项目包含登录和支付功能,支付功能使用Stripe网关
# 删除冲突标记后
git add README.md
git status
# 应该显示:All conflicts fixed
git commit -m "解决合并冲突,整合支付功能"
|
练习 5:高级分支操作
场景 1:rebase 练习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
cd ../
mkdir exercise5
cd exercise5
git init
# 创建基础提交
echo "初始文件" > file1.txt
git add .
git commit -m "A: 初始提交"
echo "更多内容" >> file1.txt
git add .
git commit -m "B: main更新1"
echo "main的更新" >> file1.txt
git add .
git commit -m "C: main更新2"
# 创建feature分支并添加提交
git checkout -b feature HEAD~2 # 回到提交A
echo "功能开发1" > file2.txt
git add .
git commit -m "D: feature功能1"
echo "功能开发2" >> file2.txt
git add .
git commit -m "E: feature功能2"
# 查看当前结构
git log --oneline --graph --all
# 应该是分叉的结构
# 执行rebase
git rebase main
# 注意观察发生了什么
# 再次查看
git log --oneline --graph
# feature分支应该在main的末端
|
场景 2:cherry-pick 练习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# 继续在上面的项目中
# 创建一些有意义的提交
git checkout -b bug-fixes
echo "修复bug #1" > bugfix1.txt
git add .
git commit -m "修复bug #1: 空指针异常"
echo "修复bug #2" > bugfix2.txt
git add .
git commit -m "修复bug #2: 内存泄漏"
echo "修复bug #3" > bugfix3.txt
git add .
git commit -m "修复bug #3: 性能问题"
# 查看提交哈希
git log --oneline
# 复制第二个提交的哈希(bug #2)
# 切换到main分支,只应用bug #2的修复
git checkout main
git cherry-pick <刚才复制的哈希值>
# 注意:<刚才复制的哈希值>替换为实际的哈希值,如a1b2c3d
# 验证
git log --oneline
# main分支应该只有bug #2的修复
ls
# 应该只有bugfix2.txt
|
场景 3:stash 练习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# 继续使用上面的项目
git checkout feature
# 开始工作
echo "正在开发新功能..." > new_feature.txt
# 突然需要修复紧急bug
git status
# 显示有未提交的修改
# 保存当前工作
git stash save "保存新功能开发进度"
# 验证工作区是否干净
git status
# 应该是干净的
# 切换到main分支修复bug
git checkout main
echo "紧急修复" > hotfix.txt
git add .
git commit -m "紧急修复生产环境bug"
# 返回feature分支恢复工作
git checkout feature
# 查看stash列表
git stash list
# 显示:stash@{0}: On feature: 保存新功能开发进度
# 恢复stash
git stash pop
# 自动应用并删除stash
# 验证
git status
# 应该显示有未暂存的修改
ls
# 应该有new_feature.txt
|
🌐 第四阶段:远程操作
练习 6:GitHub/GitLab 操作
注意:这部分需要真实的 GitHub/GitLab 账户
1-3:创建和关联远程仓库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
cd ../
mkdir exercise6
cd exercise6
git init
# 本地开发
echo "# 远程仓库练习项目" > README.md
echo "print('Hello Remote')" > main.py
git add .
git commit -m "初始化项目"
# 关联远程仓库(假设已在GitHub创建了仓库)
# 替换URL为你的实际仓库URL
git remote add origin https://github.com/你的用户名/git-practice-remote.git
# 第一次推送
git push -u origin main
# 需要输入用户名和密码/Token
|
4-5:远程修改和拉取
1
2
3
4
5
6
7
8
9
10
|
# 模拟其他人在远程修改(或自己在网页修改)
# 先在网页上修改README.md,添加一行:"## 远程修改的内容"
# 本地拉取更改
git pull origin main
# 或 git fetch + git merge
# 查看文件
cat README.md
# 应该包含你网页上添加的内容
|
6:模拟团队协作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# 创建开发分支
git checkout -b develop
# 本地开发
echo "新功能开发" > feature.txt
git add .
git commit -m "开发新功能"
# 推送分支
git push -u origin develop
# 模拟另一个开发者(在另一个目录)
cd ../
mkdir another-developer
cd another-developer
git clone https://github.com/你的用户名/git-practice-remote.git
cd git-practice-remote
# 也在develop分支开发
git checkout develop
echo "另一个开发者的修改" >> feature.txt
git add .
git commit -m "开发者B的修改"
git push origin develop
# 这个应该成功
# 回到第一个开发者目录
cd ../../exercise6
# 尝试推送(会产生冲突)
echo "我的更多修改" >> feature.txt
git add .
git commit -m "开发者A的更多修改"
git push origin develop
# 预期:被拒绝,需要先拉取
# 拉取并解决冲突
git pull origin develop
# 会有冲突,手动解决
# 编辑feature.txt,删除冲突标记
git add feature.txt
git commit -m "解决合并冲突"
git push origin develop
|
🏷️ 第五阶段:标签与发布
练习 7:版本标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
cd ../
mkdir exercise7
cd exercise7
git init
# 创建一些提交作为版本基础
echo "初始代码" > app.js
git add .
git commit -m "v1.0.0基础版本"
# 打标签
git tag v1.0.0
# 开发新功能
echo "新功能A" >> app.js
git add .
git commit -m "添加功能A"
echo "新功能B" >> app.js
git add .
git commit -m "添加功能B"
git tag v1.1.0
# bug修复
echo "修复已知问题" >> app.js
git add .
git commit -m "修复bug #123"
git tag v1.1.1
# 查看所有标签
git tag -l
# 应该显示:v1.0.0 v1.1.0 v1.1.1
# 查看标签详细信息
git show v1.1.0
# 推送标签到远程(如果有远程仓库)
# git push origin v1.0.0
# git push origin --tags # 推送所有标签
# 删除标签(本地)
git tag -d v1.1.1
# 验证
git tag -l
# v1.1.1应该消失了
|
🎯 综合实战项目
最终练习:完整开发流程
由于篇幅限制,这里给出关键步骤框架:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
# 1. 项目初始化
mkdir todo-app
cd todo-app
git init
echo "# 待办事项应用" > README.md
mkdir src tests
git add .
git commit -m "项目初始化"
# 2. 创建.gitignore
cat > .gitignore << EOF
__pycache__/
*.pyc
.env
.DS_Store
EOF
# 3. 建立开发分支
git checkout -b develop
# 4. 功能分支开发流程
# 功能1:添加任务
git checkout -b feature/add-task
# 开发代码...
git add .
git commit -m "实现添加任务功能"
git checkout develop
git merge feature/add-task --no-ff -m "合并添加任务功能"
# 功能2:删除任务
git checkout -b feature/delete-task
# 开发代码...
git add .
git commit -m "实现删除任务功能"
# 使用rebase保持历史整洁
git rebase develop
git checkout develop
git merge feature/delete-task --no-ff -m "合并删除任务功能"
# 5. 版本发布
git checkout main
git merge develop --no-ff -m "发布v1.0.0"
git tag v1.0.0
# 6. Hotfix流程
git checkout main
git checkout -b hotfix/urgent-bug
# 修复bug...
git add .
git commit -m "修复紧急bug #456"
git checkout main
git merge hotfix/urgent-bug -m "合并紧急修复"
git tag v1.0.1
git checkout develop
git merge hotfix/urgent-bug -m "同步紧急修复到develop分支"
# 可视化查看
git log --oneline --graph --all
|
💡 关键概念验证练习
1. 理解三个区域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
mkdir test-areas
cd test-areas
git init
# 工作区修改
echo "line1" > file.txt
git status # untracked
# 暂存区
git add file.txt
git status # changes to be committed
# 仓库
git commit -m "commit 1"
git status # clean
# 再次修改
echo "line2" >> file.txt
git diff # 工作区 vs 暂存区
git diff --cached # 暂存区 vs 仓库
git diff HEAD # 工作区 vs 仓库
|
2. HEAD 和分支指针
1
2
3
4
5
6
7
8
9
10
|
# 查看HEAD指向
cat .git/HEAD
# 创建分支时发生了什么
git branch new-branch
cat .git/refs/heads/new-branch
# 切换分支时HEAD的变化
git checkout new-branch
cat .git/HEAD # 指向ref: refs/heads/new-branch
|
3. 对象存储
1
2
3
4
5
6
|
# 查看对象
git hash-object file.txt
# 计算出的哈希值,可以在.git/objects/中找到
# 查看对象内容
git cat-file -p <hash>
|
🎮 Git 闯关练习对应命令
根据你的笔记,这些是闯关练习中的关键命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# 基础关卡
git commit
git branch newImage
git checkout newImage && git commit
git checkout -b bugFix
git merge bugFix
git rebase main
# 相对引用
git checkout HEAD^
git checkout HEAD~3
git branch -f main HEAD~3
# 远程操作
git clone <url>
git fetch
git pull
git push
git push origin feature
# 高级操作
git cherry-pick C2 C4
git rebase -i HEAD~4
git tag v1 C1
git describe <commit>
|
📝 快速检查清单
在每个练习完成后,检查你是否掌握了:
- ✅ 能初始化仓库并提交更改
- ✅ 能查看状态、差异和历史
- ✅ 能创建、切换、合并分支
- ✅ 能解决合并冲突
- ✅ 能使用 stash 暂存工作
- ✅ 能使用 rebase 整理历史
- ✅ 能关联和操作远程仓库
- ✅ 能创建和管理标签
- ✅ 理解 reset、checkout、revert 的区别
- ✅ 能进行完整的 Git 工作流程
记住,真正的掌握来自于反复练习和在实际项目中应用。每个命令至少练习 3-5 次,直到你能不查笔记就能正确使用!