git操作笔记

Git 操作笔记

> 按学习曲线编排:从初始化配置 → 基础使用 → 进阶操作 → 回滚处理


目录

  1. 初始化与配置\](#1-初始化与配置)

  2. 基础操作 - 分支\](#3-基础操作---分支)

  3. 同步与推送\](#5-同步与推送)

  4. 回滚操作\](#7-回滚操作)

  5. 查询与调试\](#9-查询与调试)


1. 初始化与配置

初始化 Git 项目

```bash

cd /path/to/your/project # 进入项目目录

git init # 初始化 Git 仓库

```

创建初始提交

```bash

git add . # 将所有文件加入暂存区

git commit -m "Initial commit" # 添加初始提交

```

配置 pull 行为

```bash

git config --global pull.rebase true # 设置 pull 后默认执行 rebase

git config --unset --global pull.rebase # 取消设置

```

> 建议:代码在提交前最好执行一次 `git pull --rebase`


2. 基础操作 - 仓库与远程

添加远程仓库

```bash

git remote add origin https://github.com/yourname/your-repo.git

git remote -v # 查看远程仓库地址

```

添加多个远程仓库

```bash

方式一:添加为独立远程

git remote add gitlab https://gitlab.com/yourname/repo.git

git remote add gitee https://gitee.com/yourname/repo.git

推送时指定远程

git push origin main

git push gitlab main

git push gitee main

```

让一个远程名称对应多个推送地址

```bash

git remote add origin https://github.com/yourname/repo.git

为同一个 origin 添加额外的 push 地址

git remote set-url --add --push origin https://gitlab.com/yourname/repo.git

git remote set-url --add --push origin https://gitee.com/yourname/repo.git

移除默认 push URL(避免重复推送)

git remote set-url --delete origin --push https://github.com/yourname/repo.git

git remote -v # 查看所有远程仓库地址

```


3. 基础操作 - 分支

创建分支

```bash

git checkout -b feature/new-feature # 创建并切换到新分支

```

推送并创建远程分支

```bash

git push -u origin feature/new-feature # -u 关联本地与远程分支

```

绑定已存在的远程分支

```bash

git branch -u origin/<远程分支名> <本地分支名>

git branch --set-upstream-to=origin/<远程分支名> <本地分支名>

```

创建本地分支并关联远程

```bash

git checkout -b <本地分支名> origin/<远程分支名>

```

检查分支关联信息

```bash

git branch -vv # 显示每个本地分支对应的远程分支

```

删除远程分支

```bash

git push origin --delete <远程分支名>

```

> 删除后,其他协作者执行 `git fetch --prune` 可以同步删除本地的远程追踪引用


4. 基础操作 - 提交

基本提交

```bash

git add . # 添加所有更改到暂存区

git commit -m "提交信息" # 提交

```

修改最后一次提交

```bash

git commit -a --amend # 将更改追加到最近一次提交

会打开编辑器,可修改提交信息

```

合并多个提交

```bash

git rebase -i HEAD~3 # 针对最近 3 次提交做交互式变基

```

编辑器中按从旧到新排列提交:

```

pick abc1234 第一次提交

squash def5678 第二次提交

squash ghi9012 第三次提交

```

  • **pick**:保留该提交

  • **squash**:合并到前一个提交,保留提交信息

  • **fixup**:合并到前一个提交,丢弃提交信息

Cherry-pick 挑拣提交

> 挑选某个提交(或提交范围)到当前分支重新提交,**副作用:会增加一次提交**

>

> 注意:使用前需先切换到目标分支

使用步骤

```bash

1. 切换到目标分支(要接收挑拣提交的分支)

git checkout target-branch

2. 挑拣单个提交

git cherry-pick <commitId>

3. 推送到远程

git push origin target-branch

```

常用命令

| 命令 | 说明 |

|------|------|

| `git cherry-pick <commitId>` | 挑拣单个提交到当前分支 |

| `git cherry-pick <commit0>..<commitN>` | 挑拣 commit1 到 N(**不包含** commit0) |

| `git cherry-pick <commit0>^..<commitN>` | 挑拣 commit0 到 N(**包含** commit0) |

| `git cherry-pick <commitId> -n` | 挑拣但**不自动提交**(修改留在暂存区) |

| `git cherry-pick <commitId> -e` | 挑拣并**编辑提交信息** |

| `git cherry-pick <commitId> -x` | 挑拣时在提交信息末尾**添加原始 commit 的引用** |

| `git cherry-pick --continue` | 解决冲突后继续挑拣流程 |

| `git cherry-pick --abort` | 取消整个挑拣操作,恢复到挑拣前的状态 |

参数说明

  • **`<commitId>`**:要挑拣的提交哈希值(可用 `git log` 查看)

  • **`-n, --no-commit`**:挑拣后不自动提交,修改留在暂存区,方便手动调整

  • **`-e, --edit`**:挑拣后打开编辑器,可修改提交信息

  • **`-x`**:在提交信息末尾添加一行 `cherry picked from commit <hash>`,方便追溯

  • **`--continue`**:冲突解决后,继续执行挑拣

  • **`--abort`**:放弃挑拣,恢复原状

示例

**挑拣单个提交:**

```bash

git checkout main

git cherry-pick abc1234

```

**挑拣多个连续提交(不包含起点):**

```bash

git checkout main

git cherry-pick abc1234..def5678 # 挑拣 def5678 及其之后的所有提交

```

**挑拣多个连续提交(包含起点):**

```bash

git checkout main

git cherry-pick abc1234^..def5678 # 挑拣 abc1234 到 def5678 的所有提交

```

**挑拣但不立即提交(用于修改后再提交):**

```bash

git cherry-pick abc1234 -n

此时修改已在暂存区,可根据需要修改后再提交

git commit -m "自定义提交信息"

```

**挑拣并保留原始提交信息:**

```bash

git cherry-pick abc1234 -x

```

冲突处理

```bash

1. 挑拣时发生冲突,Git 会暂停

git cherry-pick abc1234

报错:CONFLICT (content): Merge conflict in <file>

2. 手动解决冲突后,标记为已解决

git add <file>

3. 继续挑拣流程

git cherry-pick --continue

或放弃本次挑拣

git cherry-pick --abort

```

注意事项

  • Cherry-pick **会增加新的提交**(新的 hash),不是移动提交

  • 如果挑拣的提交涉及文件已被目标分支修改,可能产生冲突

  • 建议在干净的工作区上执行挑拣操作


5. 同步与推送

同步远程仓库

```bash

git fetch origin # 同步 origin 的所有分支数据(不合并)

git pull # 同步并合并当前分支

相当于 git fetch + git merge

或 git fetch + git rebase

```

拉取特定分支

```bash

git fetch origin main # 只更新 origin/main

git pull origin dev:my-feature # 拉取并合并到本地指定分支

```

推送

```bash

git push <远程名称> <本地分支名>:<远程分支名>

git push origin main # 推送本地 main 到远程 main

git push origin main:feature-new # 推送本地 main 到远程 feature-new

```

git push 机制

**第一步比对 old commit id:**

| 变量 | 含义 |

|------|------|

| old-commit-hash | 客户端认为远程分支当前指向的提交(本地 origin/main 记录) |

| new-commit-hash | 客户端希望远程分支更新到的提交(本地 main 的哈希) |

**服务器比对逻辑:**

  1. **old 匹配** → 进入对象协商阶段,客户端上传缺失对象

  2. **old 不匹配** → 拒绝推送(有人比你先推送了,需先 fetch)

**能否推送成功:**

  • **fast-forward**(快进):本地提交包含远程提交作为祖先 → 推送成功

  • **non-fast-forward**(非快进):分支分叉 → 默认拒绝,需 `--force`

强制推送

```bash

git push --force origin <分支名> # 强制覆盖远程

git push --force-with-lease origin <分支名> # 安全强制推送(检查远程是否被更新)

```


6. 合并操作

> `git merge` 不加 `--no-ff` 默认使用 fast-forward 方式,可能不产生提交;加 `--no-ff` 总是产生新提交

检查两个分支是否存在冲突

**方法一:`git merge-tree`(推荐,Git 2.36+,不修改工作区)**

```bash

git merge-tree --write-tree branch-A branch-B

```

  • 退出码 0:无冲突,输出合并后的文件树

  • 退出码 1:有冲突,输出冲突信息

**方法二:`git merge --no-commit --no-ff`(会修改工作区)**

```bash

git checkout master

if git merge --no-commit --no-ff feature/login >/dev/null 2>&1; then

echo "无冲突"

git merge --abort

else

echo "有冲突"

git merge --abort

fi

```


7. 回滚操作

git add 后回退

```bash

git reset HEAD # 回退所有文件的暂存状态

git reset HEAD filename # 回退指定文件

```

> 文件修改不会丢失,`git status` 仍能看到修改

git commit 后回退

> 回退后如需重新提交,需重新 `git add`

| 模式 | 命令 | HEAD | 暂存区 | 工作区 |

|------|------|------|--------|--------|

| 硬回退 | `git reset --hard <hash>` | 回退 | 清空 | 清空(丢失修改) |

| 软回退 | `git reset --soft <hash>` | 回退 | 保留 | 保留 |

| 混合回退 | `git reset --mixed <hash>` | 回退 | 清空 | 保留(变未暂存) |

```bash

git reset --hard <commit-hash> # 硬回退(慎用,丢失所有修改)

git reset --soft <commit-hash> # 软回退(撤销提交,修改保留在暂存区)

git reset --mixed <commit-hash> # 混合回退(默认,修改变未暂存)

```

安全的撤销方式(推荐)

```bash

git revert <commit-hash> # 创建逆向提交,撤销指定提交

历史完整,不会丢失提交记录

```

修补最后一次提交

```bash

git add . && git commit --amend # 漏提交时补救,不产生新提交

```

git push 后回退

```bash

git revert <commit-hash> # 创建逆向提交

git push origin <branch> # 推送(git revert 新增提交,无需强制推送)

```

如果需要回退多个提交:

```bash

git revert HEAD~3..HEAD # 回退最近 3 个提交

```

其他情况需要强制推送:

```bash

git push --force-with-lease origin <branch>

```


8. 进阶操作

交互式变基

```bash

git rebase -i HEAD~3 # 打开编辑器,编辑最近 3 个提交

```

可用操作:

  • `pick`:保留提交

  • `squash`:合并提交,保留提交信息

  • `fixup`:合并提交,丢弃提交信息

  • `reword`:修改提交信息

  • `drop`:删除提交

> 如果已 push,需要 `git push --force-with-lease` 强制推送

获取分支最新 commit id

```bash

git rev-parse origin/feature-newapi-26900

```


9. 查询与调试

Git Log

```bash

git log --graph # 显示合并路径

git log -1 # 最新 1 条日志

git log -1 --oneline # 一行显示

git log -1 --format="%ai" # 显示最新提交时间

git log --since="2026-01-01" # 按日期筛选

```

查看历史记录(指针移动历史)

```bash

git reflog # 记录本地所有 HEAD 指针移动

git reflog -1 --format='%ai' # 最新一次操作的时间

```

遍历与对比提交

```bash

两点表示法:列出 B 中有而 A 中没有的提交

git rev-list A..B

三点表示法:列出 A 和 B 各自独有的提交(对称差集)

git rev-list A...B

统计差异提交数

git rev-list --count main..feature

快速判断 A 是否包含 B 的所有提交

if [ $(git rev-list --count B..A) -eq 0 ]; then echo "A 包含 B"; fi

```

对比两个分支差异

```bash

git diff --quiet "origin/SOURCE_BRANCH" "origin/TARGET_BRANCH"

```

退出码:

  • **0**:无差异

  • **1**:有差异

  • **128**:命令执行出错

查询分支是否存在

```bash

本地分支

git show-ref --verify --quiet "refs/heads/$SOURCE_BRANCH"

远程分支

git ls-remote --exit-code --heads origin "$TARGET_BRANCH"

```

> `--heads` 只查询分支,不查询标签

查找分支交叉点

```bash

git merge-base branch-A branch-B # 找出最近共同祖先

判断 A 是否是 B 的祖先(合入检查)

git merge-base --is-ancestor A B

如果 A 的内容全部已合入 B,返回 0

```

其他查询

```bash

git rev-list --since="1 week ago" --author="John" --all # 某人本周的提交

git rev-list --grep="hotfix" --all # 包含关键字的提交

git rev-list --merges main..HEAD # 指定范围的合并提交

git rev-list @{upstream}..HEAD # 领先上游分支的提交

```

stash 暂存修改

```bash

git stash # 暂存当前修改

git stash save "备注信息" # 暂存并添加备注

git stash list # 查看暂存列表

git stash pop # 恢复暂存并删除

git stash apply # 恢复暂存但保留记录

git stash drop # 删除某个暂存

git stash clear # 清空所有暂存

```

忽略文件

```bash

git update-index --assume-unchanged <file> # 临时忽略(本地有效)

git update-index --no-assume-unchanged <file> # 取消忽略

git ls-files -v | grep "^h " # 查看被忽略的文件

```

清理与重置

```bash

git clean -fd # 删除未跟踪的文件和目录

git clean -n # 预览将要删除的文件(不实际删除)

git gc --aggressive # 垃圾回收,优化仓库

```

标签操作

```bash

git tag v1.0.0 # 创建轻量标签

git tag -a v1.0.0 -m "版本说明" # 创建附注标签

git tag # 查看标签列表

git push origin v1.0.0 # 推送标签到远程

git push origin --tags # 推送所有标签

```

查看差异

```bash

git diff # 查看工作区与暂存区的差异

git diff --staged # 查看暂存区与上次提交的差异

git diff HEAD # 查看工作区与上次提交的差异

git diff commit1 commit2 # 对比两个提交

git diff branch1 branch2 # 对比两个分支

```

查看文件历史

```bash

git log -p <file> # 查看文件的提交历史

git blame <file> # 查看文件的每一行是谁修改的

git log --follow <file> # 跟踪文件的重命名

```

撤销操作

```bash

git checkout -- <file> # 丢弃工作区的修改(未暂存)

git restore <file> # 同上(新命令)

git restore --staged <file> # 取消暂存(保留工作区修改)

git reset HEAD <file> # 同上(旧命令)

```

其他常用命令

```bash

git status # 查看当前状态

git status -s # 简洁模式

git remote -v # 查看远程仓库地址

git remote show origin # 查看远程仓库详情

git remote prune origin # 清理已删除的远程分支引用

git fetch --all # 获取所有远程仓库的更新

git branch -a # 查看所有分支(包括远程)

git branch -d <分支名> # 删除本地分支

git tag -d <标签名> # 删除本地标签

git push origin --delete <分支名> # 删除远程分支

git push origin :<分支名> # 同上,另一种写法

```


10. Shell 脚本示例

批量合并脚本

```bash

#!/bin/bash

BASE_DIR="."

SOURCE_BRANCH="feature/your-feature-branch"

TARGET_BRANCH="master"

find "$BASE_DIR" -maxdepth 2 -type d -name ".git" | sed 's/\/.git//' | while read -r repo; do

echo "检查仓库: $repo"

cd "$repo" || continue

git fetch origin

if git diff --quiet "origin/SOURCE_BRANCH" "origin/TARGET_BRANCH"; then

echo "✅ 无差异,跳过"

else

echo "⚠️ 发现差异,开始合并"

git checkout "TARGET_BRANCH" 2\>/dev/null \|\| git checkout -b "TARGET_BRANCH" "origin/$TARGET_BRANCH"

git reset --hard "origin/$TARGET_BRANCH"

if git merge "origin/$SOURCE_BRANCH" --no-edit; then

echo "✅ 合并成功"

else

echo "❌ 合并冲突"

git merge --abort

fi

fi

done

```

检测合入后是否有新提交

```bash

#!/bin/bash

check_repo() {

local repo_path=$1

local repo_name=(basename "repo_path")

cd "repo_path" \|\| { echo "ERROR\|repo_name||仓库无法访问"; return; }

拉取最新代码

if [[ "$FETCH_BEFORE_CHECK" == "yes" ]]; then

export GIT_TERMINAL_PROMPT=0

git fetch origin --quiet 2>/dev/null

fetch_result=$?

unset GIT_TERMINAL_PROMPT

if [[ $fetch_result -ne 0 ]]; then

echo "SKIP|$repo_name||拉取失败(需要认证)"

return

fi

fi

检查远程分支是否存在

if ! git ls-remote --exit-code --heads origin "$SOURCE_BRANCH" >/dev/null 2>&1; then

echo "SKIP|repo_name\|\|源分支 SOURCE_BRANCH 不存在"

return

fi

if ! git ls-remote --exit-code --heads origin "$TARGET_BRANCH" >/dev/null 2>&1; then

echo "SKIP|repo_name\|\|目标分支 TARGET_BRANCH 不存在"

return

fi

找共同祖先

local merge_base

merge_base=(git merge-base "origin/SOURCE_BRANCH" "origin/$TARGET_BRANCH" 2>/dev/null)

if [[ -z "$merge_base" ]]; then

echo "NEVER_MERGED|repo_name\|SOURCE_BRANCH|无共同祖先从未合入"

return

fi

检查源分支是否是目标分支的祖先

if git merge-base --is-ancestor "origin/SOURCE_BRANCH" "origin/TARGET_BRANCH" 2>/dev/null; then

local merge_date

merge_date=(git log -1 --format="%ai" "merge_base" 2>/dev/null)

echo "OK|repo_name\|SOURCE_BRANCH|0|0|merge_date\|merge_base|无遗漏"

else

local merge_date

merge_date=(git log -1 --format="%ai" "merge_base" 2>/dev/null)

local missing_count

local missing_merges

missing_count=(git rev-list "merge_base..origin/$SOURCE_BRANCH" --count 2>/dev/null)

missing_merges=(git rev-list "merge_base..origin/$SOURCE_BRANCH" --merges --count 2>/dev/null)

echo "WARNING|repo_name\|SOURCE_BRANCH|missing_count\|missing_merges|merge_date\|merge_base|合入后存在新提交!"

fi

}

```


附录:origin 是什么

> `origin` 是 git 默认的远程仓库别名,你也可以换成其他名称(如 `gitlab`、`gitee` 等)

相关推荐
卡次卡次12 小时前
注意点:可能是上一篇文章的进阶版,明天再对比一下
大数据·数据库
2401_832298102 小时前
AI 智能体 “寒武纪”——OpenClaw 狂飙迭代,引领开源 Agent 商业化落地浪潮
大数据·人工智能
weikecms2 小时前
外卖红包CPS小程序快速搭建api
大数据·微客云
科技互联.2 小时前
2026年5月观察:四大头部工具如何重塑短视频矩阵的“生产规则”
大数据·人工智能·矩阵
陆水A2 小时前
运输时效预测模型:静态路由时效的计算与验证
大数据·人工智能·算法·spark·数据库开发·etl工程师
2601_957780843 小时前
GPT-5.5时代:从“指令集“到“任务契约“的Prompt工程范式迁移
大数据·人工智能·gpt·架构·prompt
189228048613 小时前
H27QBG8GDAIR-BCB闪存H27QCG8HEAIR-BCB
大数据·科技·缓存
财经资讯数据_灵砚智能3 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年5月11日
大数据·人工智能·python·信息可视化·自然语言处理
Promise微笑3 小时前
AI搜索时代的流量重构:Geo优化精细化运营标准与实战路径
大数据·人工智能·重构