Git 常用命令与技巧
基础配置
rebase
# 在 pull 时使用 rebasegit config --global pull.rebase true为什么使用 rebase?
默认情况下,git pull 等同于 git fetch + git merge,当本地和远程都有新提交时,会产生一个额外的合并提交(merge commit),导致提交历史出现分叉:
* Merge branch 'main' of origin|\| * 远程提交* | 本地提交|/设置 pull.rebase true 后,git pull 变为 git fetch + git rebase,会将本地提交”变基”到远程分支之上,保持线性历史:
* 本地提交(重新应用)* 远程提交优点:提交历史更清晰,避免无意义的合并提交,方便 code review 和问题追溯。
用户信息配置
# 设置用户名git config --global user.name "yourname"
# 设置邮箱git config --global user.email "your@email.com"
# 查看所有配置git config --list常用别名配置
简单别名
# 查看状态git config --global alias.st status
# 切换分支git config --global alias.co checkout
# 分支操作git config --global alias.br branch高级别名(Shell 函数)
利用 Shell 函数实现更强大的别名:
# 一键添加、提交并推送(默认消息 "update")git config --global alias.update '!f() { git add . && git commit -m "${*:-update}" && git push; }; f'
# 一键添加并提交(默认消息 "update")git config --global alias.save '!f() { git add . && git commit -m "${*:-update}"; }; f'
# 美化的提交日志(支持当前分支、所有分支、指定分支)git config --global alias.lg '!f() { branch="$(git rev-parse --abbrev-ref HEAD)" if [ "$1" = "-a" ]; then branch="--all" shift elif [ "$1" = "-b" ] && [ -n "$2" ]; then branch="$2" shift 2 fi base="git log --oneline --graph $branch" if [ $# -eq 0 ]; then $base -10 elif [ $# -eq 1 ] && case "$1" in ""|*[!0-9]*) false;; *) true;; esac; then $base -n "$1" else $base "$@" fi}; f'别名使用示例
| 命令 | 说明 |
|---|---|
git update | 添加所有文件、提交 “update” 并推送 |
git update fix bug | 添加所有文件、提交 “fix bug” 并推送 |
git save | 添加所有文件并提交 “update” |
git save add feature | 添加所有文件并提交 “add feature” |
git lg | 当前分支最近 10 条美化日志 |
git lg 20 | 当前分支最近 20 条 |
git lg -a | 所有分支最近 10 条 |
git lg -a 20 | 所有分支最近 20 条 |
git lg -b main | 只看 main 分支最近 10 条 |
git lg -b main 20 | 只看 main 分支最近 20 条 |
提示:别名中的
!表示执行 Shell 命令,${*:-default}是 Bash 语法,表示使用所有参数,若无参数则使用默认值。
远程仓库管理
# 查看远程仓库地址git remote -v
# 添加远程仓库git remote add origin <repository-url>
# 删除远程仓库关联git remote rm origin
# 修改远程仓库地址git remote set-url origin <new-url>
# 克隆仓库git clone <repository-url>提交规范 (Conventional Commits)
推荐使用规范化的提交信息格式:<type>(<scope>): <description>
| 类型 | 说明 |
|---|---|
feat | 新功能 |
fix | 修复 bug |
docs | 文档变更 |
style | 代码格式(不影响功能) |
refactor | 代码重构(既不是新功能也不是修复) |
perf | 性能优化 |
test | 测试相关 |
build | 构建系统或外部依赖变更 |
ci | CI 配置变更 |
chore | 其他不修改 src 或 test 的变更 |
revert | 回退提交 |
合并多个提交 (Squash)
使用交互式 rebase 将多个提交合并为一个:
# 合并最近 n 个提交git rebase -i HEAD~n例如合并最近 3 个提交:
git rebase -i HEAD~3执行后会打开编辑器,显示类似:
pick abc1234 第一个提交pick def5678 第二个提交pick ghi9012 第三个提交将需要合并的提交前的 pick 改为 squash(或简写 s):
pick abc1234 第一个提交squash def5678 第二个提交squash ghi9012 第三个提交保存后会弹出编辑器让你编辑合并后的提交信息。
注意:
HEAD~n中的n是你要操作的提交数量。第一个提交必须保持pick,其他提交改为squash会被合并到第一个提交中。
换行符问题 (CRLF/LF)
不同操作系统使用不同的换行符:
- Windows: CRLF (
\r\n) - macOS/Linux: LF (
\n)
解决方案一:配置 core.autocrlf
| 设置 | 提交时 | 检出时 | 推荐系统 |
|---|---|---|---|
true | CRLF 转 LF | LF 转 CRLF | Windows |
input | CRLF 转 LF | 不转换 | macOS/Linux |
false | 不转换 | 不转换 | - |
# Windows 用户git config --global core.autocrlf true
# macOS/Linux 用户git config --global core.autocrlf input解决方案二:使用 .gitattributes(推荐)
在项目根目录创建 .gitattributes 文件,统一团队换行符规则:
# 自动检测文本文件并统一使用 LF* text=auto eol=lf这种方式的优势是配置跟随仓库,确保所有开发者使用相同的规则。
克隆到非空目录
当目标目录已存在且非空时,git clone 会报错:
fatal: destination path already exists and is not an empty directory解决方案
通过 git init 初始化后手动关联远程仓库:
# 进入目标目录cd /your/target/directory
# 初始化 Git 仓库git init
# 添加远程仓库地址git remote add origin <your-repo-url>
# 拉取远程代码git pull
# 切换到 main 分支(-f 强制覆盖本地文件)git checkout main -f
# 设置本地分支跟踪远程分支git branch --set-upstream-to origin/main注意:使用
-f参数会强制覆盖本地文件,执行前请备份重要文件。
自定义命令:git mp
将当前分支合并到指定目标分支并推送,遇到冲突时自动回退,确保工作区不受影响。
安装
git config --global alias.mp '!f() { if [ -z "$1" ]; then echo "Usage: git mp <target-branch>" return 1 fi target="$1" current="$(git rev-parse --abbrev-ref HEAD)" if [ "$current" = "$target" ]; then echo "Already on $target" return 1 fi echo "Merging $current into $target..." git checkout "$target" && git pull || { git checkout "$current"; return 1; } if git merge "$current"; then git push git checkout "$current" echo "Done! Merged $current into $target and pushed." else echo "Merge conflict! Aborting..." git merge --abort git checkout "$current" echo "Back on $current, nothing changed." return 1 fi}; f'用法
| 命令 | 效果 |
|---|---|
git mp test | 合并当前分支到 test 并推送 |
git mp staging | 合并当前分支到 staging 并推送 |
git mp master | 合并当前分支到 master 并推送 |
执行流程
- 切换到目标分支并拉取最新代码
- 将原分支合并到目标分支
- 合并成功则推送,随后切回原分支
- 合并冲突则自动中止合并,切回原分支,不做任何变更
提示:该命令适合日常将功能分支合并到公共分支的场景,省去手动切换、合并、推送、切回的繁琐步骤。