git-master by josiahsiegel/claude-plugin-marketplace
npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill git-master强制要求:在 Windows 上始终对文件路径使用反斜杠
在 Windows 上使用 Edit 或 Write 工具时,你必须在文件路径中使用反斜杠 (\),而不是正斜杠 (/)。
示例:
D:/repos/project/file.tsxD:\repos\project\file.tsx这适用于:
除非用户明确要求,否则切勿创建新的文档文件。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
从基础到高级的所有 Git 操作的综合指南,包括带有安全防护措施的危险操作。
安全第一 - 在任何破坏性操作之前:
# 始终先检查状态
git status
git log --oneline -10
# 对于危险操作,创建一个安全分支
git branch backup-$(date +%Y%m%d-%H%M%S)
# 记住:git reflog 是你的安全网(默认 90 天)
git reflog
用户偏好检查:
此技能为任何 Git 操作提供完整的 Git 专业知识,无论多么高级、小众或危险。它涵盖:
必须使用此技能的情况:
关键:在任何破坏性操作(reset --hard、force push、filter-repo 等)之前:
# 危险操作的安全模式示例
echo "⚠️ 警告:此操作具有破坏性,将:"
echo " - 永久删除未提交的更改"
echo " - 重写 Git 历史"
echo " - [针对此操作的具体风险]"
echo ""
echo "安全建议:首先创建备份分支..."
git branch backup-before-reset-$(date +%Y%m%d-%H%M%S)
echo ""
echo "如果需要恢复:git reset --hard backup-before-reset-XXXXXXXX"
echo ""
read -p "你确定要继续吗?(yes/NO): " confirm
if [[ "$confirm" != "yes" ]]; then
echo "操作已取消。"
exit 1
fi
在任何 Git 任务开始时始终询问: "你希望我:
在整个会话中尊重此选择。
Git 行为和跨平台及托管提供商的工作流有所不同:
Windows (Git Bash/PowerShell):
Linux/macOS:
托管平台:
# 初始化新仓库
git init
git init --initial-branch=main # 指定默认分支名称
# 克隆仓库
git clone <url>
git clone <url> <directory>
git clone --depth 1 <url> # 浅克隆(更快,历史记录更少)
git clone --branch <branch> <url> # 克隆特定分支
git clone --recurse-submodules <url> # 包含子模块
# 用户身份(提交必需)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 默认分支名称
git config --global init.defaultBranch main
# 行尾处理(Windows)
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # macOS/Linux
# 编辑器
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim"
# 差异工具
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
# 合并工具
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# 别名
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'
# 查看配置
git config --list
git config --global --list
git config --local --list
git config user.name # 获取特定值
# 检查状态
git status
git status -s # 简短格式
git status -sb # 简短格式带分支信息
# 添加文件
git add <file>
git add . # 添加当前目录中的所有更改
git add -A # 添加仓库中的所有更改
git add -p # 交互式暂存(补丁模式)
# 移除文件
git rm <file>
git rm --cached <file> # 从索引中移除,保留在工作目录中
git rm -r <directory>
# 移动/重命名文件
git mv <old> <new>
# 提交
git commit -m "message"
git commit -am "message" # 添加并提交已跟踪的文件
git commit --amend # 修改最后一次提交
git commit --amend --no-edit # 修改但不更改消息
git commit --allow-empty -m "message" # 空提交(对触发器有用)
# 查看历史
git log
git log --oneline
git log --graph --oneline --all --decorate
git log --stat # 显示文件统计信息
git log --patch # 显示差异
git log -p -2 # 显示最后 2 次提交及其差异
git log --since="2 weeks ago"
git log --until="2025-01-01"
git log --author="Name"
git log --grep="pattern"
git log -- <file> # 特定文件的历史
git log --follow <file> # 跟踪重命名
# 显示更改
git diff # 未暂存的更改
git diff --staged # 已暂存的更改
git diff HEAD # 自上次提交以来的所有更改
git diff <branch> # 与另一个分支比较
git diff <commit1> <commit2>
git diff <commit> # 自特定提交以来的更改
git diff <branch1>...<branch2> # 分支之间的更改
# 显示提交详情
git show <commit>
git show <commit>:<file> # 显示特定提交时的文件
# 列出分支
git branch # 本地分支
git branch -r # 远程分支
git branch -a # 所有分支
git branch -v # 带最后一次提交信息
git branch -vv # 带跟踪信息
# 创建分支
git branch <branch-name>
git branch <branch-name> <start-point> # 从特定提交/标签创建
# 切换分支
git switch <branch-name>
git checkout <branch-name> # 旧语法,仍然有效
# 创建并切换
git switch -c <branch-name>
git checkout -b <branch-name>
git switch -c <branch-name> <start-point>
# 删除分支
git branch -d <branch-name> # 安全删除(仅在已合并时)
git branch -D <branch-name> # 强制删除(即使未合并)
# 重命名分支
git branch -m <old-name> <new-name>
git branch -m <new-name> # 重命名当前分支
# 设置上游跟踪
git branch --set-upstream-to=origin/<branch>
git branch -u origin/<branch>
Git Flow:
main/master:生产就绪代码develop:功能集成分支feature/*:新功能release/*:发布准备hotfix/*:生产修复GitHub Flow:
main:始终可部署feature/*:短期功能分支主干开发:
main:单一分支GitLab Flow:
production、staging、mainmain# 快进合并(如果可能则为默认)
git merge <branch>
# 强制合并提交(即使可以快进)
git merge --no-ff <branch>
# 压缩合并(将所有提交合并为一个)
git merge --squash <branch>
# 然后手动提交:git commit -m "Merged feature X"
# 使用特定策略合并
git merge -s recursive <branch> # 默认策略
git merge -s ours <branch> # 始终使用"我们的"版本
git merge -s theirs <branch> # 始终使用"他们的"版本(需要 merge-theirs)
git merge -s octopus <branch1> <branch2> <branch3> # 合并多个分支
# 使用策略选项合并
git merge -X ours <branch> # 在冲突中优先使用"我们的"更改
git merge -X theirs <branch> # 在冲突中优先使用"他们的"更改
git merge -X ignore-all-space <branch>
git merge -X ignore-space-change <branch>
# 中止合并
git merge --abort
# 解决冲突后继续
git merge --continue
# 当合并冲突发生时
git status # 查看冲突文件
# 文件中的冲突标记:
# <<<<<<< HEAD
# 你的更改
# =======
# 他们的更改
# >>>>>>> branch-name
# 手动解决冲突,然后:
git add <resolved-file>
git commit # 完成合并
# 使用合并工具
git mergetool
# 完全接受一方
git checkout --ours <file> # 保留我们的版本
git checkout --theirs <file> # 保留他们的版本
git add <file>
# 查看冲突差异
git diff # 显示冲突
git diff --ours # 与我们的版本比较
git diff --theirs # 与他们的版本比较
git diff --base # 与基础版本比较
# 列出冲突
git diff --name-only --diff-filter=U
⚠️ 警告:变基会重写历史。切勿对已推送到共享分支的提交进行变基!
# 基础变基
git rebase <base-branch>
git rebase origin/main
# 交互式变基(功能强大)
git rebase -i <base-commit>
git rebase -i HEAD~5 # 最后 5 次提交
# 交互式变基命令:
# p, pick = 使用提交
# r, reword = 使用提交,但编辑消息
# e, edit = 使用提交,但停止以进行修改
# s, squash = 使用提交,但融入前一个提交
# f, fixup = 类似 squash,但丢弃提交消息
# x, exec = 使用 shell 运行命令(行的其余部分)
# b, break = 在此处停止(稍后使用 'git rebase --continue' 继续)
# d, drop = 移除提交
# l, label = 用名称标记当前 HEAD
# t, reset = 将 HEAD 重置到标签
# 变基到不同的基础
git rebase --onto <new-base> <old-base> <branch>
# 解决冲突后继续
git rebase --continue
# 跳过当前提交
git rebase --skip
# 中止变基
git rebase --abort
# 保留合并提交
git rebase --preserve-merges <base> # 已弃用
git rebase --rebase-merges <base> # 现代方法
# 自动压缩(与修复提交一起使用)
git commit --fixup <commit>
git rebase -i --autosquash <base>
# 将特定提交应用到当前分支
git cherry-pick <commit>
# 拣选多个提交
git cherry-pick <commit1> <commit2>
git cherry-pick <commit1>..<commit5>
# 拣选但不提交
git cherry-pick -n <commit>
git cherry-pick --no-commit <commit>
# 解决冲突后继续
git cherry-pick --continue
# 中止拣选
git cherry-pick --abort
# 列出远程仓库
git remote
git remote -v # 带 URL
# 添加远程仓库
git remote add <name> <url>
git remote add origin https://github.com/user/repo.git
# 更改远程 URL
git remote set-url <name> <new-url>
# 移除远程仓库
git remote remove <name>
git remote rm <name>
# 重命名远程仓库
git remote rename <old> <new>
# 显示远程信息
git remote show <name>
git remote show origin
# 清理过时的远程分支
git remote prune origin
git fetch --prune
# 从远程获取(不合并)
git fetch
git fetch origin
git fetch --all # 所有远程仓库
git fetch --prune # 移除过时的远程跟踪分支
# 拉取(获取 + 合并)
git pull
git pull origin <branch>
git pull --rebase # 获取 + 变基而不是合并
git pull --no-ff # 始终创建合并提交
git pull --ff-only # 仅在可以快进时
# 设置默认拉取行为
git config --global pull.rebase true # 始终变基
git config --global pull.ff only # 仅快进
# 推送到远程
git push
git push origin <branch>
git push origin <local-branch>:<remote-branch>
# 推送新分支并设置上游
git push -u origin <branch>
git push --set-upstream origin <branch>
# 推送所有分支
git push --all
# 推送标签
git push --tags
git push origin <tag-name>
# 删除远程分支
git push origin --delete <branch>
git push origin :<branch> # 旧语法
# 删除远程标签
git push origin --delete <tag>
git push origin :refs/tags/<tag>
# ⚠️ 危险:强制推送(覆盖远程历史)
# 始终先请求用户确认
git push --force
git push -f
# ⚠️ 更安全:带租约的强制推送(如果远程已更新则失败)
git push --force-with-lease
git push --force-with-lease=<ref>:<expected-value>
强制推送安全协议:
在任何强制推送之前,执行此安全检查:
echo "⚠️ 危险:强制推送将覆盖远程历史!"
echo ""
echo "远程分支状态:"
git fetch origin
git log --oneline origin/<branch> ^<branch> --decorate
if [ -z "$(git log --oneline origin/<branch> ^<branch>)" ]; then
echo "✓ 不会丢失提交(远程落后于本地)"
else
echo "❌ 警告:远程有将被丢失的提交:"
git log --oneline --decorate origin/<branch> ^<branch>
echo ""
echo "这些来自其他开发者的提交将被销毁!"
fi
echo ""
echo "考虑使用 --force-with-lease 而不是 --force"
echo ""
read -p "输入 'force push' 以确认: " confirm
if [[ "$confirm" != "force push" ]]; then
echo "已取消。"
exit 1
fi
# 储藏更改
git stash
git stash save "message"
git stash push -m "message"
# 储藏包括未跟踪的文件
git stash -u
git stash --include-untracked
# 储藏包括忽略的文件
git stash -a
git stash --all
# 列出储藏
git stash list
# 显示储藏内容
git stash show
git stash show -p # 带差异
git stash show stash@{2}
# 应用储藏(保留在储藏列表中)
git stash apply
git stash apply stash@{2}
# 弹出储藏(应用并移除)
git stash pop
git stash pop stash@{2}
# 丢弃储藏
git stash drop
git stash drop stash@{2}
# 清除所有储藏
git stash clear
# 从储藏创建分支
git stash branch <branch-name>
git stash branch <branch-name> stash@{1}
# Git 2.51+:导入/导出储藏(在机器之间共享储藏)
# 导出储藏到文件
git stash store --file=stash.patch stash@{0}
# 从文件导入储藏
git stash import --file=stash.patch
# 像分支/标签一样共享储藏
git stash export > my-stash.patch
git stash import < my-stash.patch
⚠️ 警告:重置可能永久删除更改!
# 软重置(保留更改已暂存)
git reset --soft <commit>
git reset --soft HEAD~1 # 撤销最后一次提交,保留更改已暂存
# 混合重置(默认 - 保留更改未暂存)
git reset <commit>
git reset HEAD~1 # 撤销最后一次提交,保留更改未暂存
# ⚠️ 硬重置(删除所有更改 - 危险!)
# 始终先创建备份分支!
git branch backup-$(date +%Y%m%d-%H%M%S)
git reset --hard <commit>
git reset --hard HEAD~1 # 撤销最后一次提交并删除所有更改
git reset --hard origin/<branch> # 重置到远程状态
# 取消暂存文件
git reset HEAD <file>
git reset -- <file>
# 将特定文件重置到提交
git checkout <commit> -- <file>
# 还原提交(创建撤销更改的新提交)
# 对于共享分支比重置更安全
git revert <commit>
# 还原但不创建提交
git revert -n <commit>
git revert --no-commit <commit>
# 还原合并提交
git revert -m 1 <merge-commit> # 保留第一个父提交
git revert -m 2 <merge-commit> # 保留第二个父提交
# 还原多个提交
git revert <commit1> <commit2>
git revert <commit1>..<commit5>
# 解决冲突后继续
git revert --continue
# 中止还原
git revert --abort
reflog 是你的安全网 - 它跟踪所有 HEAD 移动 90 天(默认)
# 查看引用日志
git reflog
git reflog show
git reflog show <branch>
# 更详细的引用日志
git log -g # 引用日志作为日志
git log -g --all
# 查找丢失的提交
git reflog --all
git fsck --lost-found
# 恢复已删除的分支
git reflog # 查找分支存在的提交
git branch <branch-name> <commit-hash>
# 从硬重置恢复
git reflog # 查找重置前的提交
git reset --hard <commit-hash>
# 恢复已删除的提交
git cherry-pick <commit-hash>
# 引用日志过期(更改保留时间)
git config gc.reflogExpire "90 days"
git config gc.reflogExpireUnreachable "30 days"
# 开始二分查找
git bisect start
# 标记当前提交为错误
git bisect bad
# 标记已知正确的提交
git bisect good <commit>
# 测试每个提交,然后标记为正确或错误
git bisect good # 当前提交正确
git bisect bad # 当前提交错误
# 使用测试脚本自动化
git bisect run <test-script>
# 二分查找显示第一个错误提交
# 完成二分查找
git bisect reset
# 如果无法测试则跳过提交
git bisect skip
⚠️ 警告:清理会永久删除未跟踪的文件!
# 显示将被删除的内容(试运行 - 始终先执行此操作!)
git clean -n
git clean --dry-run
# 删除未跟踪的文件
git clean -f
# 删除未跟踪的文件和目录
git clean -fd
# 删除未跟踪和忽略的文件
git clean -fdx
# 交互式清理
git clean -i
# 列出工作树
git worktree list
# 添加新工作树
git worktree add <path> <branch>
git worktree add ../project-feature feature-branch
# 为新分支添加工作树
git worktree add -b <new-branch> <path>
# 移除工作树
git worktree remove <path>
# 清理过时的工作树
git worktree prune
# 添加子模块
git submodule add <url> <path>
# 初始化子模块(克隆后)
git submodule init
git submodule update
# 克隆包含子模块
git clone --recurse-submodules <url>
# 更新子模块
git submodule update --remote
git submodule update --init --recursive
# 在所有子模块中执行命令
git submodule foreach <command>
git submodule foreach git pull origin main
# 移除子模块
git submodule deinit <path>
git rm <path>
rm -rf .git/modules/<path>
⚠️ 极其危险:重写整个仓库历史!
# 安装 git-filter-repo(非内置)
# pip install git-filter-repo
# 从所有历史中移除文件
git filter-repo --path <file> --invert-paths
# 从所有历史中移除目录
git filter-repo --path <directory> --invert-paths
# 更改作者信息
git filter-repo --name-callback 'return name.replace(b"Old Name", b"New Name")'
git filter-repo --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'
# 移除大文件
git filter-repo --strip-blobs-bigger-than 10M
# ⚠️ 过滤仓库后,需要强制推送
git push --force --all
git push --force --tags
过滤仓库安全协议:
echo "⚠️⚠️⚠️ 极端危险 ⚠️⚠️⚠️"
echo "此操作将:"
echo " - 重写整个仓库历史"
echo " - 更改所有提交哈希"
echo " - 破坏所有现有的克隆"
echo " - 要求所有团队成员重新克隆"
echo " - 强制推送后无法撤销"
echo ""
echo "强制要求:创建完整备份:"
git clone --mirror <repo-url> backup-$(date +%Y%m%d-%H%M%S)
echo ""
echo "在继续之前通知所有团队成员!"
echo ""
read -p "输入 'I UNDERSTAND THE RISKS' 以继续: " confirm
if [[ "$confirm" != "I UNDERSTAND THE RISKS" ]]; then
echo "已取消。"
exit 1
fi
⚠️ 危险:更改已推送的提交需要强制推送!
# 修改最后一次提交
git commit --amend
# 修改但不更改消息
git commit --amend --no-edit
# 更改最后一次提交的作者
git commit --amend --author="Name <email>"
# ⚠️ 如果已推送则需要强制推送
git push --force-with-lease
⚠️ 危险:对已推送的提交进行交互式变基!
# 交互式变基
git rebase -i HEAD~5
# 更改较早提交的作者
git rebase -i <commit>^
# 将提交标记为 "edit"
# 当停止时:
git commit --amend --author="Name <email>" --no-edit
git rebase --continue
# ⚠️ 需要强制推送
git push --force-with-lease
拉取请求:
# 安装 GitHub CLI
# https://cli.github.com/
# 创建 PR
gh pr create
gh pr create --title "Title" --body "Description"
gh pr create --base main --head feature-branch
# 列出 PR
gh pr list
# 查看 PR
gh pr view
gh pr view <number>
# 在本地检出 PR
gh pr checkout <number>
# 审查 PR
gh pr review
gh pr review --approve
gh pr review --request-changes
gh pr review --comment
# 合并 PR
gh pr merge
gh pr merge --squash
gh pr merge --rebase
gh pr merge --merge
# 关闭 PR
gh pr close <number>
GitHub Actions:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
拉取请求:
# 安装 Azure DevOps CLI
# https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
# 创建 PR
az repos pr create --title "Title" --description "Description"
az repos pr create --source-branch feature --target-branch main
# 列出 PR
az repos pr list
# 查看 PR
az repos pr show --id <id>
# 完成 PR
az repos pr update --id <id> --status completed
# 分支策略
az repos policy list
az repos policy create --config policy.json
Azure Pipelines:
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- script: npm test
displayName: 'Run tests'
拉取请求:
# 创建 PR(通过网页或 Bitbucket CLI)
bb pr create
# 审查 PR
bb pr list
bb pr view <id>
# 合并 PR
bb pr merge <id>
Bitbucket Pipelines:
# bitbucket-pipelines.yml
pipelines:
default:
- step:
script:
- npm test
合并请求:
# 安装 GitLab CLI (glab)
# https://gitlab.com/gitlab-org/cli
# 创建 MR
glab mr create
glab mr create --title "Title" --description "Description"
# 列出 MR
glab mr list
# 查看 MR
glab mr view <id>
# 合并 MR
glab mr merge <id>
# 关闭 MR
glab mr close <id>
GitLab CI:
# .gitlab-ci.yml
stages:
- test
test:
stage: test
script:
- npm test
# 垃圾回收
git gc
git gc --aggressive # 更彻底,更慢
# 清理不可达对象
git prune
# 验证仓库
git fsck
git fsck --full
# 优化仓库
git repack -a -d --depth=250 --window=250
# Git 2.51+:路径遍历重新打包(生成更小的包)
# 通过遍历路径实现更高效的增量压缩
git repack --path-walk -a -d
# 计数对象
git count-objects -v
# 仓库大小
du -sh .git
# 在历史中查找大文件
git rev-list --objects --all |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
sed -n 's/^blob //p' |
sort --numeric-sort --key=2 |
tail -n 10
# Git LFS(大文件存储)
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes
git add file.psd
git commit -m "Add large file"
# 列出 LFS 文件
git lfs ls-files
# 获取 LFS 文件
git lfs fetch
git lfs pull
# 浅克隆(更快,磁盘空间更少)
git clone --depth 1 <url>
# 取消浅克隆(转换为完整克隆)
git fetch --unshallow
# 获取更多历史
git fetch --depth=100
# 轻量标签
git tag <tag-name>
git tag v1.0.0
# 附注标签(推荐 - 包含元数据)
git tag -a <tag-name> -m "message"
git tag -a v1.0.0 -m "Release version 1.0.0"
# 标记特定提交
git tag -a <tag-name> <commit>
# 签名标签(GPG 签名)
git tag -s <tag-name> -m "message"
# 列出标签
git tag
git tag -l "v1.*" # 模式匹配
# 显示标签信息
git show <tag-name>
# 删除本地标签
git tag -d <tag-name>
# 删除远程标签
git push origin --delete <tag-name>
git push origin :refs/tags/<tag-name>
# 推送标签
git push origin <tag-name>
git push --tags # 所有标签
git push --follow-tags # 仅附注标签
# 钩子位置:.git/hooks/
# pre-commit:提交前运行
# 示例:.git/hooks/pre-commit
#!/bin/bash
npm run lint || exit 1
# prepare-commit-msg:编辑器打开前编辑提交消息
# commit-msg:验证提交消息
#!/bin/bash
msg=$(cat "$1")
if ! echo "$msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore):
MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).
Examples:
D:/repos/project/file.tsxD:\repos\project\file.tsxThis applies to:
NEVER create new documentation files unless explicitly requested by the user.
Comprehensive guide for ALL Git operations from basic to advanced, including dangerous operations with safety guardrails.
Safety First - Before ANY Destructive Operation:
# ALWAYS check status first
git status
git log --oneline -10
# For risky operations, create a safety branch
git branch backup-$(date +%Y%m%d-%H%M%S)
# Remember: git reflog is your safety net (90 days default)
git reflog
User Preference Check:
This skill provides COMPLETE Git expertise for ANY Git operation, no matter how advanced, niche, or risky. It covers:
MUST use this skill for:
CRITICAL: Before ANY destructive operation (reset --hard, force push, filter-repo, etc.):
# Example safety pattern for dangerous operations
echo "⚠️ WARNING: This operation is DESTRUCTIVE and will:"
echo " - Permanently delete uncommitted changes"
echo " - Rewrite Git history"
echo " - [specific risks for the operation]"
echo ""
echo "Safety recommendation: Creating backup branch first..."
git branch backup-before-reset-$(date +%Y%m%d-%H%M%S)
echo ""
echo "To recover if needed: git reset --hard backup-before-reset-XXXXXXXX"
echo ""
read -p "Are you SURE you want to proceed? (yes/NO): " confirm
if [[ "$confirm" != "yes" ]]; then
echo "Operation cancelled."
exit 1
fi
ALWAYS ASK at the start of ANY Git task: "Would you like me to:
Respect this choice throughout the session.
Git behavior and workflows differ across platforms and hosting providers:
Windows (Git Bash/PowerShell):
Linux/macOS:
Hosting Platforms:
# Initialize new repository
git init
git init --initial-branch=main # Specify default branch name
# Clone repository
git clone <url>
git clone <url> <directory>
git clone --depth 1 <url> # Shallow clone (faster, less history)
git clone --branch <branch> <url> # Clone specific branch
git clone --recurse-submodules <url> # Include submodules
# User identity (required for commits)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Default branch name
git config --global init.defaultBranch main
# Line ending handling (Windows)
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # macOS/Linux
# Editor
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim"
# Diff tool
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
# Merge tool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# Aliases
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'
# View configuration
git config --list
git config --global --list
git config --local --list
git config user.name # Get specific value
# Check status
git status
git status -s # Short format
git status -sb # Short with branch info
# Add files
git add <file>
git add . # Add all changes in current directory
git add -A # Add all changes in repository
git add -p # Interactive staging (patch mode)
# Remove files
git rm <file>
git rm --cached <file> # Remove from index, keep in working directory
git rm -r <directory>
# Move/rename files
git mv <old> <new>
# Commit
git commit -m "message"
git commit -am "message" # Add and commit tracked files
git commit --amend # Amend last commit
git commit --amend --no-edit # Amend without changing message
git commit --allow-empty -m "message" # Empty commit (useful for triggers)
# View history
git log
git log --oneline
git log --graph --oneline --all --decorate
git log --stat # Show file statistics
git log --patch # Show diffs
git log -p -2 # Show last 2 commits with diffs
git log --since="2 weeks ago"
git log --until="2025-01-01"
git log --author="Name"
git log --grep="pattern"
git log -- <file> # History of specific file
git log --follow <file> # Follow renames
# Show changes
git diff # Unstaged changes
git diff --staged # Staged changes
git diff HEAD # All changes since last commit
git diff <branch> # Compare with another branch
git diff <commit1> <commit2>
git diff <commit> # Changes since specific commit
git diff <branch1>...<branch2> # Changes between branches
# Show commit details
git show <commit>
git show <commit>:<file> # Show file at specific commit
# List branches
git branch # Local branches
git branch -r # Remote branches
git branch -a # All branches
git branch -v # With last commit info
git branch -vv # With tracking info
# Create branch
git branch <branch-name>
git branch <branch-name> <start-point> # From specific commit/tag
# Switch branch
git switch <branch-name>
git checkout <branch-name> # Old syntax, still works
# Create and switch
git switch -c <branch-name>
git checkout -b <branch-name>
git switch -c <branch-name> <start-point>
# Delete branch
git branch -d <branch-name> # Safe delete (only if merged)
git branch -D <branch-name> # Force delete (even if not merged)
# Rename branch
git branch -m <old-name> <new-name>
git branch -m <new-name> # Rename current branch
# Set upstream tracking
git branch --set-upstream-to=origin/<branch>
git branch -u origin/<branch>
Git Flow:
main/master: Production-ready codedevelop: Integration branch for featuresfeature/*: New featuresrelease/*: Release preparationhotfix/*: Production fixesGitHub Flow:
main: Always deployablefeature/*: Short-lived feature branchesTrunk-Based Development:
main: Single branchGitLab Flow:
production, staging, mainmain# Fast-forward merge (default if possible)
git merge <branch>
# Force merge commit (even if fast-forward possible)
git merge --no-ff <branch>
# Squash merge (combine all commits into one)
git merge --squash <branch>
# Then commit manually: git commit -m "Merged feature X"
# Merge with specific strategy
git merge -s recursive <branch> # Default strategy
git merge -s ours <branch> # Always use "our" version
git merge -s theirs <branch> # Always use "their" version (requires merge-theirs)
git merge -s octopus <branch1> <branch2> <branch3> # Merge multiple branches
# Merge with strategy options
git merge -X ours <branch> # Prefer "our" changes in conflicts
git merge -X theirs <branch> # Prefer "their" changes in conflicts
git merge -X ignore-all-space <branch>
git merge -X ignore-space-change <branch>
# Abort merge
git merge --abort
# Continue after resolving conflicts
git merge --continue
# When merge conflicts occur
git status # See conflicted files
# Conflict markers in files:
# <<<<<<< HEAD
# Your changes
# =======
# Their changes
# >>>>>>> branch-name
# Resolve conflicts manually, then:
git add <resolved-file>
git commit # Complete the merge
# Use mergetool
git mergetool
# Accept one side completely
git checkout --ours <file> # Keep our version
git checkout --theirs <file> # Keep their version
git add <file>
# View conflict diff
git diff # Show conflicts
git diff --ours # Compare with our version
git diff --theirs # Compare with their version
git diff --base # Compare with base version
# List conflicts
git diff --name-only --diff-filter=U
⚠️ WARNING: Rebase rewrites history. Never rebase commits that have been pushed to shared branches!
# Basic rebase
git rebase <base-branch>
git rebase origin/main
# Interactive rebase (POWERFUL)
git rebase -i <base-commit>
git rebase -i HEAD~5 # Last 5 commits
# Interactive rebase commands:
# p, pick = use commit
# r, reword = use commit, but edit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like squash, but discard commit message
# x, exec = run command (rest of line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop = remove commit
# l, label = label current HEAD with a name
# t, reset = reset HEAD to a label
# Rebase onto different base
git rebase --onto <new-base> <old-base> <branch>
# Continue after resolving conflicts
git rebase --continue
# Skip current commit
git rebase --skip
# Abort rebase
git rebase --abort
# Preserve merge commits
git rebase --preserve-merges <base> # Deprecated
git rebase --rebase-merges <base> # Modern approach
# Autosquash (with fixup commits)
git commit --fixup <commit>
git rebase -i --autosquash <base>
# Apply specific commit to current branch
git cherry-pick <commit>
# Cherry-pick multiple commits
git cherry-pick <commit1> <commit2>
git cherry-pick <commit1>..<commit5>
# Cherry-pick without committing
git cherry-pick -n <commit>
git cherry-pick --no-commit <commit>
# Continue after resolving conflicts
git cherry-pick --continue
# Abort cherry-pick
git cherry-pick --abort
# List remotes
git remote
git remote -v # With URLs
# Add remote
git remote add <name> <url>
git remote add origin https://github.com/user/repo.git
# Change remote URL
git remote set-url <name> <new-url>
# Remove remote
git remote remove <name>
git remote rm <name>
# Rename remote
git remote rename <old> <new>
# Show remote info
git remote show <name>
git remote show origin
# Prune stale remote branches
git remote prune origin
git fetch --prune
# Fetch from remote (doesn't merge)
git fetch
git fetch origin
git fetch --all # All remotes
git fetch --prune # Remove stale remote-tracking branches
# Pull (fetch + merge)
git pull
git pull origin <branch>
git pull --rebase # Fetch + rebase instead of merge
git pull --no-ff # Always create merge commit
git pull --ff-only # Only if fast-forward possible
# Set default pull behavior
git config --global pull.rebase true # Always rebase
git config --global pull.ff only # Only fast-forward
# Push to remote
git push
git push origin <branch>
git push origin <local-branch>:<remote-branch>
# Push new branch and set upstream
git push -u origin <branch>
git push --set-upstream origin <branch>
# Push all branches
git push --all
# Push tags
git push --tags
git push origin <tag-name>
# Delete remote branch
git push origin --delete <branch>
git push origin :<branch> # Old syntax
# Delete remote tag
git push origin --delete <tag>
git push origin :refs/tags/<tag>
# ⚠️ DANGEROUS: Force push (overwrites remote history)
# ALWAYS ASK USER FOR CONFIRMATION FIRST
git push --force
git push -f
# ⚠️ SAFER: Force push with lease (fails if remote updated)
git push --force-with-lease
git push --force-with-lease=<ref>:<expected-value>
Force Push Safety Protocol:
Before ANY force push, execute this safety check:
echo "⚠️ DANGER: Force push will overwrite remote history!"
echo ""
echo "Remote branch status:"
git fetch origin
git log --oneline origin/<branch> ^<branch> --decorate
if [ -z "$(git log --oneline origin/<branch> ^<branch>)" ]; then
echo "✓ No commits will be lost (remote is behind local)"
else
echo "❌ WARNING: Remote has commits that will be LOST:"
git log --oneline --decorate origin/<branch> ^<branch>
echo ""
echo "These commits from other developers will be destroyed!"
fi
echo ""
echo "Consider using --force-with-lease instead of --force"
echo ""
read -p "Type 'force push' to confirm: " confirm
if [[ "$confirm" != "force push" ]]; then
echo "Cancelled."
exit 1
fi
# Stash changes
git stash
git stash save "message"
git stash push -m "message"
# Stash including untracked files
git stash -u
git stash --include-untracked
# Stash including ignored files
git stash -a
git stash --all
# List stashes
git stash list
# Show stash contents
git stash show
git stash show -p # With diff
git stash show stash@{2}
# Apply stash (keep in stash list)
git stash apply
git stash apply stash@{2}
# Pop stash (apply and remove)
git stash pop
git stash pop stash@{2}
# Drop stash
git stash drop
git stash drop stash@{2}
# Clear all stashes
git stash clear
# Create branch from stash
git stash branch <branch-name>
git stash branch <branch-name> stash@{1}
# Git 2.51+ : Import/Export stashes (share stashes between machines)
# Export stash to a file
git stash store --file=stash.patch stash@{0}
# Import stash from a file
git stash import --file=stash.patch
# Share stashes like branches/tags
git stash export > my-stash.patch
git stash import < my-stash.patch
⚠️ WARNING: reset can permanently delete changes!
# Soft reset (keep changes staged)
git reset --soft <commit>
git reset --soft HEAD~1 # Undo last commit, keep changes staged
# Mixed reset (default - keep changes unstaged)
git reset <commit>
git reset HEAD~1 # Undo last commit, keep changes unstaged
# ⚠️ HARD reset (DELETE all changes - DANGEROUS!)
# ALWAYS create backup branch first!
git branch backup-$(date +%Y%m%d-%H%M%S)
git reset --hard <commit>
git reset --hard HEAD~1 # Undo last commit and DELETE all changes
git reset --hard origin/<branch> # Reset to remote state
# Unstage files
git reset HEAD <file>
git reset -- <file>
# Reset specific file to commit
git checkout <commit> -- <file>
# Revert commit (creates new commit that undoes changes)
# Safer than reset for shared branches
git revert <commit>
# Revert without creating commit
git revert -n <commit>
git revert --no-commit <commit>
# Revert merge commit
git revert -m 1 <merge-commit> # Keep first parent
git revert -m 2 <merge-commit> # Keep second parent
# Revert multiple commits
git revert <commit1> <commit2>
git revert <commit1>..<commit5>
# Continue after resolving conflicts
git revert --continue
# Abort revert
git revert --abort
reflog is your safety net - it tracks all HEAD movements for 90 days (default)
# View reflog
git reflog
git reflog show
git reflog show <branch>
# More detailed reflog
git log -g # Reflog as log
git log -g --all
# Find lost commits
git reflog --all
git fsck --lost-found
# Recover deleted branch
git reflog # Find commit where branch existed
git branch <branch-name> <commit-hash>
# Recover from hard reset
git reflog # Find commit before reset
git reset --hard <commit-hash>
# Recover deleted commits
git cherry-pick <commit-hash>
# Reflog expiration (change retention)
git config gc.reflogExpire "90 days"
git config gc.reflogExpireUnreachable "30 days"
# Start bisect
git bisect start
# Mark current commit as bad
git bisect bad
# Mark known good commit
git bisect good <commit>
# Test each commit, then mark as good or bad
git bisect good # Current commit is good
git bisect bad # Current commit is bad
# Automate with test script
git bisect run <test-script>
# Bisect shows the first bad commit
# Finish bisect
git bisect reset
# Skip commit if unable to test
git bisect skip
⚠️ WARNING: clean permanently deletes untracked files!
# Show what would be deleted (dry run - ALWAYS do this first!)
git clean -n
git clean --dry-run
# Delete untracked files
git clean -f
# Delete untracked files and directories
git clean -fd
# Delete untracked and ignored files
git clean -fdx
# Interactive clean
git clean -i
# List worktrees
git worktree list
# Add new worktree
git worktree add <path> <branch>
git worktree add ../project-feature feature-branch
# Add worktree for new branch
git worktree add -b <new-branch> <path>
# Remove worktree
git worktree remove <path>
# Prune stale worktrees
git worktree prune
# Add submodule
git submodule add <url> <path>
# Initialize submodules (after clone)
git submodule init
git submodule update
# Clone with submodules
git clone --recurse-submodules <url>
# Update submodules
git submodule update --remote
git submodule update --init --recursive
# Execute command in all submodules
git submodule foreach <command>
git submodule foreach git pull origin main
# Remove submodule
git submodule deinit <path>
git rm <path>
rm -rf .git/modules/<path>
⚠️ EXTREMELY DANGEROUS: Rewrites entire repository history!
# Install git-filter-repo (not built-in)
# pip install git-filter-repo
# Remove file from all history
git filter-repo --path <file> --invert-paths
# Remove directory from all history
git filter-repo --path <directory> --invert-paths
# Change author info
git filter-repo --name-callback 'return name.replace(b"Old Name", b"New Name")'
git filter-repo --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'
# Remove large files
git filter-repo --strip-blobs-bigger-than 10M
# ⚠️ After filter-repo, force push required
git push --force --all
git push --force --tags
Safety protocol for filter-repo:
echo "⚠️⚠️⚠️ EXTREME DANGER ⚠️⚠️⚠️"
echo "This operation will:"
echo " - Rewrite ENTIRE repository history"
echo " - Change ALL commit hashes"
echo " - Break all existing clones"
echo " - Require all team members to re-clone"
echo " - Cannot be undone after force push"
echo ""
echo "MANDATORY: Create full backup:"
git clone --mirror <repo-url> backup-$(date +%Y%m%d-%H%M%S)
echo ""
echo "Notify ALL team members before proceeding!"
echo ""
read -p "Type 'I UNDERSTAND THE RISKS' to continue: " confirm
if [[ "$confirm" != "I UNDERSTAND THE RISKS" ]]; then
echo "Cancelled."
exit 1
fi
⚠️ DANGER: Changing pushed commits requires force push!
# Amend last commit
git commit --amend
# Amend without changing message
git commit --amend --no-edit
# Change author of last commit
git commit --amend --author="Name <email>"
# ⚠️ Force push required if already pushed
git push --force-with-lease
⚠️ DANGER: Interactive rebase on pushed commits!
# Interactive rebase
git rebase -i HEAD~5
# Change author of older commits
git rebase -i <commit>^
# Mark commit as "edit"
# When stopped:
git commit --amend --author="Name <email>" --no-edit
git rebase --continue
# ⚠️ Force push required
git push --force-with-lease
Pull Requests:
# Install GitHub CLI
# https://cli.github.com/
# Create PR
gh pr create
gh pr create --title "Title" --body "Description"
gh pr create --base main --head feature-branch
# List PRs
gh pr list
# View PR
gh pr view
gh pr view <number>
# Check out PR locally
gh pr checkout <number>
# Review PR
gh pr review
gh pr review --approve
gh pr review --request-changes
gh pr review --comment
# Merge PR
gh pr merge
gh pr merge --squash
gh pr merge --rebase
gh pr merge --merge
# Close PR
gh pr close <number>
GitHub Actions:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
Pull Requests:
# Install Azure DevOps CLI
# https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
# Create PR
az repos pr create --title "Title" --description "Description"
az repos pr create --source-branch feature --target-branch main
# List PRs
az repos pr list
# View PR
az repos pr show --id <id>
# Complete PR
az repos pr update --id <id> --status completed
# Branch policies
az repos policy list
az repos policy create --config policy.json
Azure Pipelines:
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- script: npm test
displayName: 'Run tests'
Pull Requests:
# Create PR (via web or Bitbucket CLI)
bb pr create
# Review PR
bb pr list
bb pr view <id>
# Merge PR
bb pr merge <id>
Bitbucket Pipelines:
# bitbucket-pipelines.yml
pipelines:
default:
- step:
script:
- npm test
Merge Requests:
# Install GitLab CLI (glab)
# https://gitlab.com/gitlab-org/cli
# Create MR
glab mr create
glab mr create --title "Title" --description "Description"
# List MRs
glab mr list
# View MR
glab mr view <id>
# Merge MR
glab mr merge <id>
# Close MR
glab mr close <id>
GitLab CI:
# .gitlab-ci.yml
stages:
- test
test:
stage: test
script:
- npm test
# Garbage collection
git gc
git gc --aggressive # More thorough, slower
# Prune unreachable objects
git prune
# Verify repository
git fsck
git fsck --full
# Optimize repository
git repack -a -d --depth=250 --window=250
# Git 2.51+: Path-walk repacking (generates smaller packs)
# More efficient delta compression by walking paths
git repack --path-walk -a -d
# Count objects
git count-objects -v
# Repository size
du -sh .git
# Find large files in history
git rev-list --objects --all |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
sed -n 's/^blob //p' |
sort --numeric-sort --key=2 |
tail -n 10
# Git LFS (Large File Storage)
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes
git add file.psd
git commit -m "Add large file"
# List LFS files
git lfs ls-files
# Fetch LFS files
git lfs fetch
git lfs pull
# Shallow clone (faster, less disk space)
git clone --depth 1 <url>
# Unshallow (convert to full clone)
git fetch --unshallow
# Fetch more history
git fetch --depth=100
# Lightweight tag
git tag <tag-name>
git tag v1.0.0
# Annotated tag (recommended - includes metadata)
git tag -a <tag-name> -m "message"
git tag -a v1.0.0 -m "Release version 1.0.0"
# Tag specific commit
git tag -a <tag-name> <commit>
# Signed tag (GPG signature)
git tag -s <tag-name> -m "message"
# List tags
git tag
git tag -l "v1.*" # Pattern matching
# Show tag info
git show <tag-name>
# Delete local tag
git tag -d <tag-name>
# Delete remote tag
git push origin --delete <tag-name>
git push origin :refs/tags/<tag-name>
# Push tags
git push origin <tag-name>
git push --tags # All tags
git push --follow-tags # Only annotated tags
# Hooks location: .git/hooks/
# pre-commit: Run before commit
# Example: .git/hooks/pre-commit
#!/bin/bash
npm run lint || exit 1
# prepare-commit-msg: Edit commit message before editor opens
# commit-msg: Validate commit message
#!/bin/bash
msg=$(cat "$1")
if ! echo "$msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore):"; then
echo "Error: Commit message must start with type (feat|fix|docs|...):"
exit 1
fi
# post-commit: Run after commit
# pre-push: Run before push
# post-checkout: Run after checkout
# post-merge: Run after merge
# Make hook executable
chmod +x .git/hooks/pre-commit
# pre-receive: Run before refs are updated
# update: Run for each branch being updated
# post-receive: Run after refs are updated
# Example: Reject force pushes
#!/bin/bash
while read oldrev newrev refname; do
if [ "$oldrev" != "0000000000000000000000000000000000000000" ]; then
if ! git merge-base --is-ancestor "$oldrev" "$newrev"; then
echo "Error: Force push rejected"
exit 1
fi
fi
done
Detached HEAD:
# You're in detached HEAD state
git branch temp # Create branch at current commit
git switch main
git merge temp
git branch -d temp
Merge conflicts:
# During merge/rebase
git status # See conflicted files
# Edit files to resolve conflicts
git add <resolved-files>
git merge --continue # or git rebase --continue
# Abort and start over
git merge --abort
git rebase --abort
Accidentally deleted branch:
# Find branch in reflog
git reflog
# Create branch at commit
git branch <branch-name> <commit-hash>
Committed to wrong branch:
# Move commit to correct branch
git switch correct-branch
git cherry-pick <commit>
git switch wrong-branch
git reset --hard HEAD~1 # Remove from wrong branch
Pushed sensitive data:
# ⚠️ URGENT: Remove from history immediately
git filter-repo --path <sensitive-file> --invert-paths
git push --force --all
# Then: Rotate compromised credentials immediately!
Large commit by mistake:
# Before pushing
git reset --soft HEAD~1
git reset HEAD <large-file>
git commit -m "message"
# After pushing - use filter-repo or BFG
Recover after hard reset:
git reflog
git reset --hard <commit-before-reset>
Recover deleted file:
git log --all --full-history -- <file>
git checkout <commit>^ -- <file>
Recover deleted commits:
git reflog # Find commit hash
git cherry-pick <commit>
# or
git merge <commit>
# or
git reset --hard <commit>
Recover from corrupted repository:
# Verify corruption
git fsck --full
# Attempt repair
git gc --aggressive
# Last resort: clone from remote
Conventional Commits format:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Formatting (no code change)refactor: Code restructuringtest: Adding testschore: MaintenanceExample:
feat(auth): add OAuth2 authentication
Implement OAuth2 flow for Google and GitHub providers.
Includes token refresh and revocation.
Closes #123
feature/user-auth, fix/header-crashgit diff --staged).gitignore, environment variables)# Environment files
.env
.env.local
*.env
# Dependencies
node_modules/
vendor/
venv/
# Build outputs
dist/
build/
*.exe
*.dll
*.so
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS files
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Temporary files
tmp/
temp/
*.tmp
# Store credentials (cache for 1 hour)
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=3600'
# Store credentials (permanent - use with caution)
git config --global credential.helper store
# Windows: Use Credential Manager
git config --global credential.helper wincred
# macOS: Use Keychain
git config --global credential.helper osxkeychain
# Linux: Use libsecret
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
# Generate SSH key
ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # If ed25519 not supported
# Start ssh-agent
eval "$(ssh-agent -s)"
# Add key to ssh-agent
ssh-add ~/.ssh/id_ed25519
# Test connection
ssh -T git@github.com
ssh -T git@ssh.dev.azure.com
# Generate GPG key
gpg --full-generate-key
# List keys
gpg --list-secret-keys --keyid-format LONG
# Configure Git to sign commits
git config --global user.signingkey <key-id>
git config --global commit.gpgsign true
# Sign commits
git commit -S -m "message"
# Verify signatures
git log --show-signature
# Git-secrets (AWS tool)
git secrets --install
git secrets --register-aws
# Gitleaks
gitleaks detect
# Pre-commit hook
#!/bin/bash
if git diff --cached | grep -E "(password|secret|api_key)" ; then
echo "Potential secret detected!"
exit 1
fi
# Windows (CRLF in working directory, LF in repository)
git config --global core.autocrlf true
# macOS/Linux (LF everywhere)
git config --global core.autocrlf input
# No conversion (not recommended)
git config --global core.autocrlf false
# Use .gitattributes for consistency
# .gitattributes:
* text=auto
*.sh text eol=lf
*.bat text eol=crlf
# macOS/Windows: Case-insensitive filesystems
# Linux: Case-sensitive filesystem
# Enable case sensitivity in Git
git config --global core.ignorecase false
# Rename file (case-only change)
git mv --force myfile.txt MyFile.txt
# Git always uses forward slashes internally
# Works on all platforms:
git add src/components/Header.jsx
# Windows-specific tools may need backslashes in some contexts
CRITICAL: Git Bash is the primary Git environment on Windows!
Git Bash (MINGW/MSYS2) automatically converts Unix-style paths to Windows paths for native executables, which can cause issues with Git operations.
Path Conversion Behavior:
# Automatic conversions that occur:
/foo → C:/Program Files/Git/usr/foo
/foo:/bar → C:\msys64\foo;C:\msys64\bar
--dir=/foo → --dir=C:/msys64/foo
# What triggers conversion:
# ✓ Leading forward slash (/) in arguments
# ✓ Colon-separated path lists
# ✓ Arguments after - or , with path components
# What's exempt from conversion:
# ✓ Arguments containing = (variable assignments)
# ✓ Drive specifiers (C:)
# ✓ Arguments with ; (already Windows format)
# ✓ Arguments starting with // (Windows switches)
Controlling Path Conversion:
# Method 1: MSYS_NO_PATHCONV (Git for Windows only)
# Disable ALL path conversion for a command
MSYS_NO_PATHCONV=1 git command --option=/path
# Permanently disable (use with caution - can break scripts)
export MSYS_NO_PATHCONV=1
# Method 2: MSYS2_ARG_CONV_EXCL (MSYS2)
# Exclude specific argument patterns
export MSYS2_ARG_CONV_EXCL="*" # Exclude everything
export MSYS2_ARG_CONV_EXCL="--dir=;/test" # Specific prefixes
# Method 3: Manual conversion with cygpath
cygpath -u "C:\path" # → Unix format: /c/path
cygpath -w "/c/path" # → Windows format: C:\path
cygpath -m "/c/path" # → Mixed format: C:/path
# Method 4: Workarounds
# Use double slashes: //e //s instead of /e /s
# Use dash notation: -e -s instead of /e /s
# Quote paths with spaces: "/c/Program Files/file.txt"
Shell Detection in Git Workflows:
# Method 1: $MSYSTEM (Most Reliable for Git Bash)
case "$MSYSTEM" in
MINGW64) echo "Git Bash 64-bit" ;;
MINGW32) echo "Git Bash 32-bit" ;;
MSYS) echo "MSYS environment" ;;
esac
# Method 2: uname -s (Portable)
case "$(uname -s)" in
MINGW64_NT*) echo "Git Bash 64-bit" ;;
MINGW32_NT*) echo "Git Bash 32-bit" ;;
MSYS_NT*) echo "MSYS" ;;
CYGWIN*) echo "Cygwin" ;;
Darwin*) echo "macOS" ;;
Linux*) echo "Linux" ;;
esac
# Method 3: $OSTYPE (Bash-only, fast)
case "$OSTYPE" in
msys*) echo "Git Bash/MSYS" ;;
cygwin*) echo "Cygwin" ;;
darwin*) echo "macOS" ;;
linux-gnu*) echo "Linux" ;;
esac
Git Bash Path Issues & Solutions:
# Issue: Git commands with paths fail in Git Bash
# Example: git log --follow /path/to/file fails
# Solution 1: Use relative paths
git log --follow ./path/to/file
# Solution 2: Disable path conversion
MSYS_NO_PATHCONV=1 git log --follow /path/to/file
# Solution 3: Use Windows-style paths
git log --follow C:/path/to/file
# Issue: Spaces in paths (Program Files)
# Solution: Always quote paths
git add "/c/Program Files/project/file.txt"
# Issue: Drive letter duplication (D:\dev → D:\d\dev)
# Solution: Use cygpath for conversion
file=$(cygpath -u "D:\dev\file.txt")
git add "$file"
Git Bash Best Practices:
A Git workflow using this skill should:
Quick recovery commands:
# Undo last commit (keep changes)
git reset --soft HEAD~1
# Undo changes to file
git checkout -- <file>
# Recover deleted branch
git reflog
git branch <name> <commit>
# Undo force push (if recent)
git reflog
git reset --hard <commit-before-push>
git push --force-with-lease
# Recover from hard reset
git reflog
git reset --hard <commit-before-reset>
# Find lost commits
git fsck --lost-found
git reflog --all
# Recover deleted file
git log --all --full-history -- <file>
git checkout <commit>^ -- <file>
Always activate for:
Key indicators:
This skill provides COMPLETE Git expertise. Combined with the reference files and safety guardrails, you have the knowledge to handle ANY Git operation safely and effectively.
Weekly Installs
127
Repository
GitHub Stars
21
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
gemini-cli110
opencode110
codex103
cursor98
github-copilot97
amp91
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
120,000 周安装