git cherry-pick和git stash命令详解

git cherry-pick命令

  • 定义

    • 用于将指定的提交(commit)从一个分支"挑选"并应用到当前分支
    • 它复制某个提交的更改(diff),生成一个新的提交,保留原提交的更改内容,但拥有新的提交ID(SHA值)
  • 命令

    shell 复制代码
    git cherry-pick <commit-id>
  • 核心功能

    • 提取单个或多个提交的更改,应用到目标分支
    • 不影响分支的整体历史,仅复制指定提交
      • 适合修复bug、移植特性或整理提交
  • 适用场景

    • 需要从一个分支移植一个特定更改到另一个分支时非常有用
  • 示例

    shell 复制代码
    # 假设有以下分支
    # main分支有提交A、B、C。
    # feature分支从B分叉,包含提交D、E、F。
    A---B---C  (main)
         \
          D---E---F  (feature)
    
    # 现在将feature分支的提交E(例如一个Bug修复)应用到main,但不想要D或F。
    # 首先切换到main分支
    git switch main # git checkout main
    # 然后执行cherry-pick,选择提交E(假设E的SHA值为e123456)
    # 如果无冲突,Git会在main分支创建一个新提交E',包含E的更改
    git cherry-pick e123456
    
    # 提交后的结果
    A---B---C---E'  (main)
       \
        D---E---F  (feature)
        
        
    # 如果有冲突,提示错误信息,如下
    error: could not apply e123456... [commit message]
    
    # 手动解决冲突,解决完成后
    git add <file>
    
    # 继续cherry-pick
    git cherry-pick --continue
    
    # 或者放弃cherry-pick
    git cherry-pick --abort
  • 批量cherry-pick

    shell 复制代码
    # 挑选多个提交(如E和F)
    git cherry-pick e123456 f789012
    
    # 或指定范围(从D到F,不包括D)
    git cherry-pick D..F
  • 优点

    • 精准选择
      • 只引入特定提交,避免不需要的更改,灵活性高
      • 适合移植bug修复或特定功能
    • 独立操作
      • 不影响源分支或整体历史,仅在当前分支生成新提交
    • 便于协作
      • 可快速将关健修复从开发分支应用到生产分支
    • 简单直观
      • 相比mergerebase,操作单一,易于理解和执行
  • 缺点

    • 手动挑选成本高
      • 需要知道具体提交的SHA值或范围,手动操作繁琐
      • 不适合大量提交的整合
    • 冲突处理复杂
      • 如果cherry-pick的提交依赖其他未挑选的提交,可能导致冲突或功能不完整
      • 冲突需手动解决,多次cherry-pick可能重复处理类似冲突
    • 历史重复
      • cherry-pick生成新提交,可能导致代码重复(若后续合并源分支)
      • 例如:E'和E可能在在未来合并时造成冲突
    • 丢失上下文
      • 只复制提交内容,丢失原提交的完整分支上下文,调试或追溯可能困难
  • 适用场景

    • 修复bug
      • 将开发分支的bug修复快速应用到生产分支
    • 移植特性
      • 将特性分支的某些功能引入其他分支(如实验性功能)
    • 清理历史
      • 挑选关键提交,整理分支历史,结合rebase适用
    • 临时整合
      • 在合并整个分支前,测试特定提交的效果
  • mergerebase对比

    • vs merge
      • merge整合整个分支,保留历史(快进线性或非快进线性)
      • cherry-pick只选特定提交,适合精细控制
    • vs rebase
      • rebase重放整个分支历史,生成线性历史
      • cherry-pick只重放指定提交,操作更局部

git stash命令

  • 定义
    • 用于临时保存工作目录和索引(暂存区)的更改,并将工作目录恢复到最近一次提交的状态(干净状态)
    • 它将未提交的更改(包括已跟踪文件的修改和暂存的更改)存储到一个栈(stash stack)中,供后续恢复或应用
  • 命令
    • git stash
  • 核心功能
    • 保存未提交的更改(工作目录和暂存区)
    • 清理工作目录,恢复到最近的提交状态
    • 允许稍后恢复或应用保存的更改到当前或其他分支
  • 目的
    • 避免提交临时更改:在切换分支、拉取代码或执行其他操作时,临时保存未完成的工作
    • 保持工作目录干净:确保工作目录无未提交更改,便于git操作(如合并、变基)
    • 灵活管理更改:支持多次stash,随时恢复或丢弃

功能与命令

  • 保存更改
    • 保存工作目录和暂存区的更改到stash栈
    • 默认保存已跟踪文件的修改(包括暂存和未暂存更改)
  • 恢复工作目录
    • 将工作目录和暂存区恢复到最近提交的状态
  • 恢复更改
    • 将工作目录和暂存区恢复到最近提交的状态
  • 恢复更改
    • 从stash栈中恢复保存的更改到当前分支
  • 管理stash
    • 查看、应用、删除或清理stash记录

常用命令

  • 保存更改

    shell 复制代码
    git stash
    
    # 默认保存更改,命名为stash@{n}(n为栈索引,从0开始)
    
    # 添加描述
    git stash push -m 'message'
    • 保存未跟踪文件,包含未跟踪文件(如新文件)

    shell 复制代码
    git stash -u
    • 保存所有文件,包含未跟踪和忽略文件。

      shell 复制代码
      git stash -a
    • 查看stash列表

      shell 复制代码
      git stash list
      
      # 显示所有stash记录,例如
      stash@{0}: WIP on feature: abc1234 Add feature X
      stash@{1}: On main: def5678 Temp changes
    • 应用stash

    shell 复制代码
    git stash apply
    # 应用最新stash(stash@{0}),保留stash记录
    git stash apply stash@{1}
    • 应用并删除stash

    shell 复制代码
    git stash pop
    # 应用最新stash并从栈中移除
    • 删除stash

    shell 复制代码
    git stash drop stash@{1}
    # 删除指定stash
    • 清理所有stash

    shell 复制代码
    git stash clear
  • 优点

    • 灵活性
      • 快速保存和恢复未提交更改,无需创建临时提交
      • 支持多次stash,管理多个工作状态
    • 保持干净
      • 清理工作目录,便于切换分支、拉取代码或执行其他git操作
    • 非破坏性
      • 更改安全存储在stash栈,不会丢失(除非手动清理)
    • 跨分支应用
      • 可将stash应用到其他分支,适合移植临时更改
    • 简单易用
      • 命令直观,适合快速上下文切换
  • 缺点

    • 管理复杂
      • 多个stash可能导致栈混乱,难以记住每个stash的内容
      • 默认命令,如stash@{0}不够直观,需手动添加描述
    • 冲突风险
      • 应用stash时,若当前分支状态不兼容,可能引发冲突,需手动解决
    • 未跟踪文件遗漏
      • 默认不保存未跟踪文件,需显式使用-u或-a,否则可能遗漏
    • 不适合长期存储
      • stash设计为临时保存,长期依赖可能导致管理混乱,不如提交或分支
    • 调试困难
      • stash记录仅保存更改差异,缺乏完整提交上下文,追溯可能不便
  • 应用场景

    • 临时切换分支
      • 在开发特性时,需紧急切换到main修复bug,stash保存未完成的工作
    • 拉取最新的代码
      • 执行git pull前,工作目录有未提交更改,stash清理目录以避免冲突
    • 测试临时更改
      • 测试某些修改后想恢复原始状态,stash保存实验性更改
    • 移植更改
      • 将未提交更改应用到其他分支,类似cherry-pick但针对未提交内容
    • 清理提交历史
      • 在提交前整理工作目录,stash临时更改,调整后再提交
相关推荐
sduwcgg22 分钟前
git经验
git
麻雀无能为力33 分钟前
git的使用
git
算法歌者3 小时前
Visual Studio 项目 .gitignore 文件指南
git·visual studio
Lw老王要学习4 小时前
Linux架构篇、第五章git2.49.0部署与使用
linux·运维·git·云计算·it
爱学习的张哥4 小时前
专栏项目框架介绍
git·fpga开发·udp·ddr·gt收发器
Aric_Jones6 小时前
lua入门语法,包含安装,注释,变量,循环等
java·开发语言·git·elasticsearch·junit·lua
Sapphire~13 小时前
odoo-049 Pycharm 中 git stash 后有pyc 文件,如何删除pyc文件
ide·git·pycharm
Willis_m17 小时前
Linux 服务器用 SSH 拉取多个 Git 工程
linux·服务器·git·ssh
1candobetter17 小时前
git如何将本地 dev 分支与远程 dev 分支同步
git