Git 使用详解
目录
- Git基础概念
- 基本配置
- 仓库操作
- 文件状态管理
- 分支管理
- 远程仓库操作
- 高级功能
- 在你的CLI工具中集成Git功能
1. Git基础概念
1.1 什么是Git?
Git是一个分布式版本控制系统,用于跟踪文件变化、协作开发和管理项目历史。
# Git的三个重要概念
工作区 (Working Directory) # 你当前编辑的文件
暂存区 (Staging Area/Index) # 准备提交的文件
版本库 (Repository) # 已提交的历史记录
1.2 Git工作流程
工作区 ──git add──► 暂存区 ──git commit──► 版本库 ──git push──► 远程仓库
▲ │ │ │
│ │ │ │
└──────git checkout──┘ git reset────┘ git pull──────┘
2. 基本配置
2.1 初始配置
# 设置用户信息
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 设置默认编辑器
git config --global core.editor "code" # VS Code
git config --global core.editor "vim" # Vim
# 设置默认分支名
git config --global init.defaultBranch main
# 查看配置
git config --list
git config user.name
git config user.email
# 设置命令别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
2.2 配置文件位置
# 全局配置 (推荐)
~/.gitconfig
# 系统配置
/etc/gitconfig
# 项目配置
.git/config
3. 仓库操作
3.1 创建仓库
# 初始化新仓库
git init
git init my-project
# 克隆现有仓库
git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-folder
# 克隆特定分支
git clone -b branch-name https://github.com/user/repo.git
# 浅克隆 (只克隆最近的提交)
git clone --depth 1 https://github.com/user/repo.git
3.2 仓库状态查看
# 查看仓库状态
git status
git status -s # 简短格式
# 查看文件差异
git diff # 工作区与暂存区的差异
git diff --staged # 暂存区与最后提交的差异
git diff HEAD # 工作区与最后提交的差异
git diff branch1 branch2 # 比较两个分支
# 查看提交历史
git log
git log --oneline # 简洁格式
git log --graph # 图形化显示
git log --stat # 显示文件变更统计
git log -p # 显示具体变更内容
git log --since="2 weeks ago" # 时间过滤
git log --author="John" # 按作者过滤
git log --grep="bug" # 按提交信息过滤
4. 文件状态管理
4.1 添加文件到暂存区
# 添加文件
git add file.txt # 添加特定文件
git add *.py # 添加所有Python文件
git add . # 添加所有文件
git add -A # 添加所有文件 (包括删除的)
git add -u # 只添加已跟踪的文件
# 交互式添加
git add -i # 交互模式
git add -p # 部分添加 (patch模式)
4.2 提交变更
# 提交到版本库
git commit -m "提交信息"
git commit -am "跳过暂存区直接提交" # 只对已跟踪文件有效
# 修改最后一次提交
git commit --amend -m "新的提交信息"
git commit --amend --no-edit # 只修改文件,不改提交信息
# 空提交 (用于触发CI/CD)
git commit --allow-empty -m "Empty commit"
4.3 撤销操作
# 撤销工作区的修改
git checkout -- file.txt
git restore file.txt # 新语法
# 撤销暂存区的文件
git reset HEAD file.txt
git restore --staged file.txt # 新语法
# 撤销提交
git reset --soft HEAD~1 # 保留工作区和暂存区
git reset --mixed HEAD~1 # 保留工作区,清空暂存区 (默认)
git reset --hard HEAD~1 # 清空工作区和暂存区 (危险!)
# 撤销特定提交 (创建新提交)
git revert commit-hash
5. 分支管理
5.1 分支基本操作
# 查看分支
git branch # 本地分支
git branch -r # 远程分支
git branch -a # 所有分支
# 创建分支
git branch feature-branch
git checkout -b feature-branch # 创建并切换
git switch -c feature-branch # 新语法
# 切换分支
git checkout main
git switch main # 新语法
# 删除分支
git branch -d feature-branch # 安全删除
git branch -D feature-branch # 强制删除
# 重命名分支
git branch -m old-name new-name
5.2 分支合并
# 合并分支
git checkout main
git merge feature-branch
# 快进合并 (Fast-forward)
git merge --ff-only feature-branch
# 强制创建合并提交
git merge --no-ff feature-branch
# 压缩合并 (将多个提交压缩为一个)
git merge --squash feature-branch
git commit -m "Feature: Add new functionality"
5.3 变基操作
# 变基
git rebase main # 将当前分支变基到main
git rebase main feature # 将feature分支变基到main
# 交互式变基
git rebase -i HEAD~3 # 修改最近3个提交
# 变基操作选项:
# pick - 使用提交
# reword - 使用提交,但修改提交信息
# edit - 使用提交,但停下来修改
# squash - 使用提交,但合并到前一个提交
# drop - 删除提交
6. 远程仓库操作
6.1 远程仓库管理
# 查看远程仓库
git remote -v
# 添加远程仓库
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git
# 修改远程仓库URL
git remote set-url origin https://github.com/user/new-repo.git
# 删除远程仓库
git remote remove origin
6.2 推送和拉取
# 推送到远程仓库
git push origin main
git push -u origin main # 设置上游分支
git push --all # 推送所有分支
git push --tags # 推送所有标签
# 从远程仓库拉取
git pull origin main # fetch + merge
git pull --rebase origin main # fetch + rebase
# 只获取不合并
git fetch origin
git fetch --all
6.3 标签管理
# 创建标签
git tag v1.0.0 # 轻量标签
git tag -a v1.0.0 -m "Version 1.0.0" # 带注释的标签
# 查看标签
git tag
git tag -l "v1.*" # 过滤标签
# 推送标签
git push origin v1.0.0
git push origin --tags
# 删除标签
git tag -d v1.0.0 # 删除本地标签
git push origin :refs/tags/v1.0.0 # 删除远程标签
7. 高级功能
7.1 暂存工作区
# 暂存当前工作
git stash
git stash save "Work in progress"
# 查看暂存列表
git stash list
# 恢复暂存
git stash pop # 恢复并删除最新的暂存
git stash apply # 恢复但保留暂存
git stash apply stash@{1} # 恢复特定暂存
# 删除暂存
git stash drop
git stash clear # 清空所有暂存
7.2 .gitignore文件
# .gitignore 示例
# 忽略文件类型
*.log
*.tmp
*.pyc
# 忽略目录
node_modules/
.vscode/
__pycache__/
# 忽略特定文件
config/secret.ini
.env
# 不忽略特定文件 (例外)
!important.log
# 只忽略根目录下的文件
/TODO
# 忽略任何目录下的文件
**/logs/
7.3 子模块管理
# 添加子模块
git submodule add https://github.com/user/repo.git path/to/submodule
# 克隆包含子模块的仓库
git clone --recurse-submodules https://github.com/user/repo.git
# 更新子模块
git submodule update --init --recursive
git submodule update --remote
# 查看子模块状态
git submodule status
8. 在你的CLI工具中集成Git功能
基于你的 demo.py 文件,让我们添加Git集成功能:
# 在现有代码基础上添加Git功能
import subprocess
import os
import json
from pathlib import Path
class GitIntegration:
"""Git集成功能"""
def __init__(self, repo_path="."):
self.repo_path = Path(repo_path)
self.is_git_repo = self._check_git_repo()
def _check_git_repo(self):
"""检查是否为Git仓库"""
return (self.repo_path / ".git").exists()
def _run_git_command(self, command):
"""执行Git命令"""
try:
result = subprocess.run(
["git"] + command,
cwd=self.repo_path,
capture_output=True,
text=True,
check=True
)
return {"success": True, "output": result.stdout.strip()}
except subprocess.CalledProcessError as e:
return {"success": False, "error": e.stderr.strip()}
except FileNotFoundError:
return {"success": False, "error": "Git命令未找到,请确保已安装Git"}
def init_repo(self):
"""初始化Git仓库"""
if self.is_git_repo:
return {"success": False, "error": "已经是Git仓库"}
result = self._run_git_command(["init"])
if result["success"]:
self.is_git_repo = True
print("✅ Git仓库初始化成功")
return result
def get_status(self):
"""获取Git状态"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["status", "--porcelain"])
def add_files(self, files=None):
"""添加文件到暂存区"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
if files is None:
files = ["."]
return self._run_git_command(["add"] + files)
def commit(self, message):
"""提交变更"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["commit", "-m", message])
def get_branches(self):
"""获取分支列表"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["branch"])
def create_branch(self, branch_name):
"""创建分支"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["checkout", "-b", branch_name])
def switch_branch(self, branch_name):
"""切换分支"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["checkout", branch_name])
def get_log(self, count=10):
"""获取提交历史"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command([
"log",
f"--max-count={count}",
"--oneline",
"--graph"
])
def push(self, remote="origin", branch="main"):
"""推送到远程仓库"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["push", remote, branch])
def pull(self, remote="origin", branch="main"):
"""从远程仓库拉取"""
if not self.is_git_repo:
return {"success": False, "error": "不是Git仓库"}
return self._run_git_command(["pull", remote, branch])
class EnhancedTaskManager(TaskManager):
"""增强的任务管理器,添加Git功能"""
def __init__(self, data_file=None):
super().__init__(data_file)
self.git = GitIntegration()
# 如果任务文件所在目录不是Git仓库,询问是否初始化
task_dir = Path(self.data_file).parent
if not (task_dir / ".git").exists():
self._maybe_init_git_repo(task_dir)
def _maybe_init_git_repo(self, directory):
"""询问是否初始化Git仓库"""
if input(f"📁 目录 {directory} 不是Git仓库,是否初始化? (y/N): ").lower() == 'y':
self.git.repo_path = directory
result = self.git.init_repo()
if result["success"]:
# 创建.gitignore文件
gitignore_path = directory / ".gitignore"
if not gitignore_path.exists():
with open(gitignore_path, 'w') as f:
f.write("# 任务管理工具\n*.tmp\n*.log\n.env\n")
print("📝 已创建.gitignore文件")
def git_status(self):
"""显示Git状态"""
result = self.git.get_status()
if result["success"]:
output = result["output"]
if not output:
print("✅ 工作区干净,没有需要提交的更改")
else:
print("📋 Git状态:")
for line in output.split('\n'):
if line.startswith('??'):
print(f" ❓ {line[3:]} (未跟踪)")
elif line.startswith(' M'):
print(f" 📝 {line[3:]} (已修改)")
elif line.startswith('M '):
print(f" ✅ {line[3:]} (已暂存)")
elif line.startswith('A '):
print(f" ➕ {line[3:]} (新文件)")
elif line.startswith('D '):
print(f" ➖ {line[3:]} (已删除)")
else:
print(f" 📄 {line}")
else:
print(f"❌ {result['error']}")
def git_commit_task_changes(self, message=None):
"""提交任务相关的更改"""
# 添加任务文件到暂存区
add_result = self.git.add_files([str(Path(self.data_file).name)])
if not add_result["success"]:
print(f"❌ 添加文件失败: {add_result['error']}")
return
# 如果没有提供提交信息,生成默认信息
if not message:
message = f"更新任务文件 - {self._get_timestamp()}"
# 提交更改
commit_result = self.git.commit(message)
if commit_result["success"]:
print(f"✅ 已提交更改: {message}")
else:
print(f"❌ 提交失败: {commit_result['error']}")
def git_log(self, count=10):
"""显示提交历史"""
result = self.git.get_log(count)
if result["success"]:
print(f"\n📚 最近{count}次提交:")
print("-" * 60)
print(result["output"])
else:
print(f"❌ {result['error']}")
def git_branches(self):
"""显示分支信息"""
result = self.git.get_branches()
if result["success"]:
print("\n🌳 分支列表:")
print("-" * 30)
for line in result["output"].split('\n'):
if line.startswith('*'):
print(f"👉 {line[2:]} (当前分支)")
else:
print(f" {line.strip()}")
else:
print(f"❌ {result['error']}")
# 重写add_task方法,自动提交
def add_task(self, title: str, description: str = "", priority: str = "medium", auto_commit=True):
"""添加任务并可选择自动提交"""
super().add_task(title, description, priority)
if auto_commit and self.git.is_git_repo:
self.git_commit_task_changes(f"添加任务: {title}")
# 重写complete_task方法,自动提交
def complete_task(self, task_id: int, auto_commit=True):
"""完成任务并可选择自动提交"""
# 获取任务标题用于提交信息
task_title = None
for task in self.tasks:
if task["id"] == task_id:
task_title = task["title"]
break
super().complete_task(task_id)
if auto_commit and self.git.is_git_repo and task_title:
self.git_commit_task_changes(f"完成任务: {task_title}")
def create_git_enhanced_parser():
"""创建支持Git的命令行解析器"""
parser = create_parser()
# 获取现有的subparsers
subparsers = None
for action in parser._subparsers._actions:
if isinstance(action, argparse._SubParsersAction):
subparsers = action
break
if subparsers:
# Git状态命令
git_status_parser = subparsers.add_parser(
"git-status",
help="显示Git状态",
description="显示当前Git仓库的状态"
)
# Git提交命令
git_commit_parser = subparsers.add_parser(
"git-commit",
help="提交任务更改",
description="手动提交任务文件的更改"
)
git_commit_parser.add_argument(
"-m", "--message",
help="提交信息",
default=None
)
# Git日志命令
git_log_parser = subparsers.add_parser(
"git-log",
help="显示提交历史",
description="显示Git提交历史"
)
git_log_parser.add_argument(
"-n", "--count",
type=int,
default=10,
help="显示的提交数量 (默认: 10)"
)
# Git分支命令
git_branch_parser = subparsers.add_parser(
"git-branch",
help="显示分支信息",
description="显示Git分支列表"
)
# 添加全局Git选项
parser.add_argument(
"--no-auto-commit",
action="store_true",
help="禁用自动Git提交"
)
return parser
def git_enhanced_main():
"""支持Git的主函数"""
parser = create_git_enhanced_parser()
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(1)
# 创建增强的任务管理器
task_manager = EnhancedTaskManager(args.data_file)
auto_commit = not getattr(args, 'no_auto_commit', False)
try:
if args.command == "git-status":
task_manager.git_status()
elif args.command == "git-commit":
task_manager.git_commit_task_changes(args.message)
elif args.command == "git-log":
task_manager.git_log(args.count)
elif args.command == "git-branch":
task_manager.git_branches()
elif args.command == "add":
task_manager.add_task(
args.title,
args.description,
args.priority,
auto_commit=auto_commit
)
elif args.command == "complete":
task_manager.complete_task(args.task_id, auto_commit=auto_commit)
elif args.command == "list":
task_manager.list_tasks(show_completed=args.all)
elif args.command == "delete":
task_manager.delete_task(args.task_id)
if auto_commit and task_manager.git.is_git_repo:
task_manager.git_commit_task_changes("删除任务")
elif args.command == "search":
task_manager.search_tasks(args.keyword)
elif args.command == "stats":
task_manager.stats()
else:
print(f"❌ 未知命令: {args.command}")
parser.print_help()
sys.exit(1)
except KeyboardInterrupt:
print("\n\n👋 再见!")
sys.exit(0)
except Exception as e:
print(f"❌ 发生错误: {e}")
sys.exit(1)
# 修改最后的执行部分
if __name__ == "__main__":
# 检查是否启用Git功能
if "--with-git" in sys.argv:
sys.argv.remove("--with-git")
git_enhanced_main()
else:
main()
9. 实用Git命令速查
9.1 日常工作流
# 典型的Git工作流
git status # 查看状态
git add . # 添加所有修改
git commit -m "Fix bug" # 提交修改
git push origin main # 推送到远程
# 拉取最新代码
git pull origin main # 拉取并合并
git fetch && git rebase origin/main # 拉取并变基
9.2 问题排查
# 查看文件修改历史
git log --follow -- file.txt
git blame file.txt # 查看每行的修改者
# 查找特定修改
git log --grep="bug" # 搜索提交信息
git log -S"function_name" # 搜索代码变更
# 比较版本
git diff HEAD~1 HEAD # 比较最近两次提交
git diff branch1..branch2 # 比较分支
9.3 紧急修复
# 快速修复
git stash # 暂存当前工作
git checkout -b hotfix # 创建修复分支
# 进行修复...
git add . && git commit -m "Hotfix"
git checkout main
git merge hotfix
git branch -d hotfix # 删除修复分支
git stash pop # 恢复之前的工作
10. 使用示例
# 使用你的Git增强CLI工具
python demo.py --with-git add "学习Git" -d "掌握Git的基本操作"
python demo.py --with-git git-status
python demo.py --with-git git-log -n 5
python demo.py --with-git git-branch
# 禁用自动提交
python demo.py --with-git --no-auto-commit add "临时任务"
# 手动提交
python demo.py --with-git git-commit -m "手动提交任务更改"
# 基本Git命令
git init # 初始化仓库
git add README.md # 添加文件
git commit -m "Initial commit" # 首次提交
git remote add origin https://github.com/user/repo.git
git push -u origin main # 推送到远程