尚且注意,这个 bash 命令行是类 unix 的所以 window 的路径中的斜杠要修改为反斜杠才能识别正确路径,进入 D 盘的命令为
cd /d/
查看提交的所有次数
git rev-list --count HEAD
Git 命令大全
全局配置
git config --global user.name "用户名" # 设置全局用户名
git config --global user.email "邮箱" # 设置全局邮箱
git config --global core.editor "编辑器命令" # 设置默认文本编辑器
git config --global init.defaultBranch main # 设置默认分支名
git config --list # 列出所有配置
git config user.name # 查看当前用户名
git config --global alias.<别名> '命令' # 设置命令别名
仓库操作
git init # 初始化本地仓库
git clone <仓库地址> # 克隆远程仓库到本地
git clone --depth 1 <仓库地址> # 浅克隆(只下载最近一次提交)
git remote add origin <仓库地址> # 关联远程仓库
git remote -v # 查看远程仓库信息
git remote show origin # 查看远程仓库详细信息
git remote set-url origin <新地址> # 修改远程仓库地址
git remote remove origin # 删除远程仓库关联
工作区与暂存区
git status # 查看工作区状态
git status -s # 简洁状态显示
git add <文件名> # 将指定文件添加到暂存区
git add . # 将所有修改添加到暂存区
git add -A # 添加所有修改(包括删除的文件)
git add -p <文件名> # 交互式添加文件部分修改
git rm <文件名> # 删除文件并添加到暂存区
git rm --cached <文件名> # 从暂存区移除文件(保留本地文件)
git mv <原文件名> <新文件名> # 重命名文件并添加到暂存区,也能重命令暂存区的文件
git restore <文件名> # 撤销工作区的修改(Git 2.23+)
git restore --staged <文件名> # 将文件从暂存区撤出(Git 2.23+),并撤销工作区的修改
git checkout -- <文件名> # 丢弃工作区的修改
git reset HEAD <文件名> # 将暂存区的修改撤销到工作区
提交操作
git commit -m "提交信息" # 提交暂存区到本地仓库
git commit -am "提交信息" # 直接提交已跟踪文件的修改(跳过 add)
git commit --amend # 修改最近一次提交(未推送到远程时使用),注意要先将要添加或者修改的文件放入暂存区,但是这个过程可能会很久
git commit --amend "修改最近一次的提交信息"
git commit --amend --no-edit # 修改最近一次提交,但不修改提交信息
git commit --allow-empty -m "提交信息" # 允许空提交
分支操作
git branch # 查看本地分支
git branch -r # 查看远程分支
git branch -a # 查看所有分支(本地 + 远程)
git branch -vv # 查看分支详细信息(包括跟踪关系)
git branch <分支名> # 创建新分支
git checkout <分支名> # 切换到指定分支
git switch <分支名> # 切换到指定分支(Git 2.23+)
git checkout -b <分支名> # 创建并切换到新分支
git switch -c <分支名> # 创建并切换到新分支(Git 2.23+)
git merge <分支名> # 将指定分支合并到当前分支
git merge --no-ff <分支名> # 合并分支时禁用快进(Fast-forward)模式
git branch -d <分支名> # 删除本地分支(需先合并)
git branch -D <分支名> # 强制删除本地分支(未合并也可删)
git push origin --delete <分支名> # 删除远程分支
git branch -m <新分支名> # 重命名当前分支
git branch -m <旧分支名> <新分支名> # 重命名指定分支
远程同步
git fetch # 从远程仓库下载最新数据,但不合并
git fetch --prune # 获取远程更新并清理已删除的远程分支
git fetch origin <分支名> # 获取远程指定分支的更新
git pull # 拉取远程仓库更新并合并到本地
git pull origin <分支名> # 拉取指定远程分支并合并
git pull --rebase # 拉取远程更新并使用变基方式合并
git push # 推送本地提交到远程仓库
git push origin <分支名> # 推送本地分支到远程
git push -u origin <分支名> # 推送并关联远程分支(首次推送新分支用)
git push -f # 强制推送(谨慎使用,会覆盖远程历史)
git push --force-with-lease # 强制推送,但不会覆盖他人的提交(比-f安全)
历史查看
git reflog # 查看所有操作记录(包括已删除的提交)
git log # 查看提交历史
git log --oneline # 简洁显示提交历史
git log --graph # 图形化显示分支合并历史
git log --all # 查看所有分支的提交历史
git log --author="用户名" # 查看指定作者的提交
git log --since="2024-01-01" --until="2024-01-31" # 查看指定时间段的提交
git log --grep="关键词" # 搜索提交信息中的关键词
git log -p # 显示每次提交的详细差异
git log --graph --oneline --all --decorate # 图形化展示所有分支,显示简洁提交信息和标签/分支指向
git log --pretty=format # "%h - %an, %ar # %s" # 自定义格式显示(哈希、作者、相对时间、提交信息)
git log --since=1.weeks --pretty=oneline # 显示最近1周的提交(支持1.day/1.month)
git log -p <文件名> # 查看指定文件的历史修改记录(包含具体变更内容)
git log --stat # 显示每个提交的文件修改统计(增删行数)
git log --name-only # 显示每个提交修改的文件名列表
git log --author="用户名" --grep="关键词" # 查找指定作者且提交信息含关键词的记录
git log -n 5 # 只显示最近5条提交
git log <分支1>..<分支2> # 查看分支2比分支1多的提交
git log --left-right <分支1>…<分支2> # 对比两个分支的差异(左为分支1独有的,右为分支2独有的)
git show <提交哈希> # 显示某次提交的详细信息
git blame <文件名> # 逐行显示文件的修改历史和作者
git shortlog # 按作者分组显示提交历史
git whatchanged # 查看文件变更历史
版本回退
git reset --hard <提交哈希> # 回退到指定版本(彻底丢弃之后的提交)
git reset --soft <提交哈希> # 回退到指定版本(保留修改在暂存区)
git reset --mixed <提交哈希> # 回退到指定版本(保留修改在工作区,默认行为)
git clean -nfd # 查看将被删除的未追踪文件和目录
git clean -fd # 删除未追踪的文件和目录
# 所以,git reset --hard 和 git clean -fd 是一对黄金搭档,它们共同协作,才能将你的本地工作区完完全全地重置到一个指定的历史提交状态
git revert <提交哈希> # 创建新提交来撤销指定提交的修改(安全,不改变历史)
git revert --no-commit <提交哈希> # 撤销但不自动提交,可以多次撤销然后一起提交
git revert -n <提交哈希> # 同上,撤销但不提交
变基操作
git rebase <分支名> # 将当前分支变基到指定分支
git rebase --interactive <提交哈希> # 交互式变基(可以修改、合并、删除提交)
git rebase --continue # 继续变基(解决冲突后)
git rebase --abort # 终止变基操作,回到变基前的状态
git rebase --skip # 跳过当前提交(在交互式变基中)
暂存工作区
git stash # 暂存当前工作区的修改
git stash save "备注信息" # 带备注暂存
git stash list # 查看所有暂存记录
git stash apply <stash@{n}> # 应用指定暂存(不删除暂存记录)
git stash pop # 应用最近的暂存并删除记录
git stash drop <stash@{n}> # 删除指定暂存记录
git stash clear # 清空所有暂存
git stash show -p <stash@{n}> # 显示指定暂存的详细修改内容
git stash branch <新分支名> <stash@{n}> # 从暂存创建新分支
标签操作
git tag # 查看所有标签
git tag <标签名> # 创建轻量标签
git tag -a <标签名> -m "标签说明" # 创建带注释的标签
git tag -a <标签名> <提交哈希> # 在指定提交上打标签
git show <标签名> # 查看标签信息
git push origin <标签名> # 推送标签到远程
git push origin --tags # 推送所有标签到远程
git tag -d <标签名> # 删除本地标签
git push origin --delete <标签名> # 删除远程标签
子模块
git submodule add <仓库地址> <路径> # 添加子模块
git submodule init # 初始化子模块
git submodule update # 更新子模块
git submodule update --init --recursive # 递归初始化并更新子模块
git submodule foreach '命令' # 在每个子模块中执行命令
高级操作
git bisect start # 开始二分查找
git bisect bad # 标记当前提交为有问题
git bisect good <提交哈希> # 标记某提交为正常
git bisect reset # 结束二分查找
git worktree add <路径> <分支名> # 添加工作树
git worktree list # 列出所有工作树
git cherry-pick <提交哈希> # 选择某个提交应用到当前分支
git filter-branch # 重写分支历史(谨慎使用)
git fsck # 检查仓库完整性
清洁 git 仓库
这里是清洁所有的记录,我们并不推荐
git reflog # 查看所有操作记录(包括已删除的提交)
git clean -fdx # 清理工作区所有未追踪/忽略的文件(彻底清空工作区冗余)
git reflog expire --expire=now --all # 删除找回旧提交的 “线索”
git gc --prune=now --aggressive # 删除 Git 仓库中存储的旧提交 / 缓存数据
git reflog # 查看所有操作记录(包括已删除的提交)
这里展示只保留我们要的记录,清空其他的记录数据,但是有点麻烦
# 清除特定的一条信息
git reflog delete HEAD@{0}
# 1. 强制过期所有旧 reflog
git reflog expire --expire=all --all
# 2. 清理所有不可达的对象
git reflog expire --expire-unreachable=now --all
# 3. 垃圾回收 + 彻底删除所有隐藏历史
git gc --prune=now --aggressive
# 4. 重置 HEAD 引用(彻底消除隐藏操作痕迹)
git update-ref HEAD $(git rev-parse HEAD)
忽略文件
# .gitignore 文件示例
*.log
node_modules/
.DS_Store
.env
dist/
build/
差异比较
git diff # 比较工作区和暂存区的差异
git diff --staged # 比较暂存区和最新提交的差异
git diff HEAD # 比较工作区和最新提交的差异
git diff <分支1> <分支2> # 比较两个分支的差异
git diff --name-only # 只显示有差异的文件名
git diff --cached # 同 --staged
我将在你提供的 Git 命令大全基础上,补充关于撤销本地和远程提交的相关命令:
撤销提交操作
撤销本地提交上一次提交
git reset --mixed <提交哈希> # 哈希值填写,倒数第二次提交,即上一次提交之前
然后重新提交即可
撤销远程提交
# 方法1: 使用revert(推荐,不改变历史,安全)
# 撤销远程最近一次提交,会创建一个新的撤销提交
git revert HEAD
git push origin <当前分支名>
# 撤销远程上上次提交
git revert HEAD~1
git push origin <当前分支名>
# 撤销远程指定提交
git revert <提交哈希>
git push origin <当前分支名>
# 方法2: 使用reset + 强制推送(危险,会改写历史,团队协作中慎用)
# 1. 先本地撤销到目标提交
git reset --hard <目标提交哈希>
# 2. 强制推送到远程(会覆盖远程历史)
git push -f origin <当前分支名>
# 更安全的强制推送方式(如果有其他人提交会失败)
git push --force-with-lease origin <当前分支名>
完整安全提交步骤:
我们需要利用分支安全的操作
在主分支暂存所有修改
先在master分支将当前所有修改(包括新增、修改、删除的文件)添加到暂存区,确保工作区的变更被暂存:(这一步的目的是:让后续新建的临时分支能完整继承这些暂存的修改,避免遗漏)git checkout master # 确保当前在主分支 git add -A # 暂存所有变更(-A 等价于 --all,包含删除的文件)新建临时分支并隔离状态
基于当前master分支的暂存状态,新建并切换到临时分支(此时临时分支会包含主分支的所有暂存修改):git checkout -b safe-temp-branch # 新建分支并切换,自动继承暂存区内容在临时分支提交并验证钩子
在临时分支执行提交,不跳过钩子(以此验证钩子是否正常,避免直接污染主分支):git commit -m "临时保存:验证钩子及当前状态" # 正常触发 pre-commit、commit-msg 等钩子若提交成功:说明钩子逻辑没问题,当前修改的格式、规范等符合要求。
若提交失败:钩子检测到问题(如代码格式错误、提交信息不规范等),此时直接在
safe-temp-branch分支修改问题(比如调整代码格式、修改提交信息模板),然后重新提交:# 修复问题后重新暂存并提交(仍在临时分支) git add -A git commit -m "修复钩子问题:调整格式/规范"反复验证直到提交成功,确保钩子不再报错。
切换回主分支并合并验证后的修改
确认临时分支的提交和钩子都正常后,切换回主分支,将临时分支的修改合并过来:git checkout master # 回到主分支(此时主分支仍保持合并前的纯净状态) git merge safe-temp-branch # 合并临时分支的所有验证通过的修改若合并时出现冲突(如主分支在你操作期间有其他人提交了修改):
手动解决冲突文件(文件中会用<<<<<<< ======= >>>>>>>标记冲突区域),解决后执行git add -A和git commit -m "合并 safe-temp-branch 并解决冲突"完成合并。
清理临时分支
合并完成且确认主分支状态正常后,删除临时分支(避免仓库分支冗余):git branch -d safe-temp-branch # 删除已合并的临时分支
(若提示分支未合并,可先确认是否真的已合并,确认后用 git branch -D safe-temp-branch 强制删除)
创建并切换到新分支,将这次分支保留,然后回到主分支
要将当前修改提交到新分支,可按以下步骤操作:
创建并切换到新分支
首先创建一个新分支(例如命名为study-original,可根据需求修改),并自动切换到该分支:git checkout -b study-original
(-b 选项表示创建并切换分支,study-original 是新分支的名称,可自定义)
暂存当前修改
将工作区的所有修改暂存(如果只需暂存特定文件,将.替换为文件名即可):git add .提交修改到新分支
用指定的提交信息提交暂存的修改(避免使用我们设定好的钩子函数):git commit --no-verify -m "学习原项目,无果"
完成后,当前修改就会被提交到新创建的 study-original 分支中了。
切换到 master 分支后,就可以继续主分支学习了
git checkout master
妙用
具体步骤(生成「操作日志.md」)
假设目标分支为 target-branch,目标文件为 path/to/file.txt,整合后的文件为「操作日志.md」,操作如下:
1. 获取该文件的所有提交哈希(按时间正序排列)
# 切换到目标分支(或直接在命令中指定分支,如:git log target-branch -- …)
git checkout target-branch
# 获取所有修改过该文件的提交哈希(按时间倒序),反转后为「最早→最新」
commits=$(git log --pretty=format:%H -- README.md | tac)
2. 遍历提交,提取内容并追加到「操作日志.md」
#!/usr/bin/env bash
set -euo pipefail
# 导出指定文件在当前分支(默认 HEAD)的历史快照(考虑重命名)到 README_Overall.md
# 用法:
# bash tools/export_file_history.sh # 默认 README_Section.md
# bash tools/export_file_history.sh src/main.ts # 指定文件
FILE=${1:-README.md}
OUT="README_Overall.md"
# 确定 HEAD 时刻的文件路径(处理重命名)
HEAD_PATH="$FILE"
# 检查 HEAD 中是否存在该文件(处理当前名称)
if ! git cat-file -e "HEAD:$FILE" 2>/dev/null; then
# 查找最近一次涉及该文件的路径(含重命名历史)
maybe=$(git log -n1 --follow --name-only --pretty="" -- "$FILE" || true)
if [ -n "${maybe:-}" ]; then
HEAD_PATH=$(printf "%s\n" "$maybe" | head -n1)
fi
fi
# 验证最终路径是否存在提交历史
if ! git log --pretty=format:%H -n1 -- "$HEAD_PATH" 2>/dev/null; then
echo "错误:文件 '$HEAD_PATH' 没有提交历史"
exit 1
fi
printf '# %s 历史快照汇总\n' "$HEAD_PATH" > "$OUT"
# 获取所有相关提交(按时间正序),使用 readarray 确保完整读取
readarray -t commits < <(git log --follow --reverse --pretty=format:%H -- "$HEAD_PATH")
# 循环处理每个提交
for commit in "${commits[@]}"; do
{
echo
printf '## 提交: %s\n' "$commit"
printf -- '- 作者: %s\n' "$(git log -1 --pretty=format:%an "$commit")"
printf -- '- 时间: %s\n' "$(git log -1 --date=iso-strict --pretty=format:%cd "$commit")"
echo '---'
# 获取该提交中文件的实际路径(处理重命名)
# 使用 git log 而非 git show 以提高路径解析可靠性
commit_path=$(git log -1 --name-only --pretty="" "$commit" -- "$HEAD_PATH" | head -n1 || true)
if [ -n "${commit_path:-}" ]; then
# 尝试获取该提交中的文件内容
if git cat-file -e "$commit:$commit_path" 2>/dev/null; then
git show "$commit:$commit_path"
else
echo "(该提交中文件内容不可用)"
fi
else
echo "(该提交中未找到文件记录)"
fi
echo
} >> "$OUT"
done
echo "已生成: $OUT"