git问题记录-如何切换历史提交分支,且保留本地修改

问题记录

我在本地编写了代码,突然想查看之前提交的代码,并且想保留当前所在分支所做的修改

通过git stash对本地的代码进行暂存

使用git checkout <commit-hash>切换到之前的提交记录。

查看完之后我想切换回来,恢复暂存的本地代码

使用git stash pop恢复我本地暂存区的代码,这时候出现了 git 冲突

我需要解决冲突,通过git status查看暂存区的内容

对于Unmerged pathsUntracked files的内容,都通过git add 将这些文件添加到暂存区

git add .完成之后,我以为已经完全恢复了切换分支之前本地的代码,于是将分支切换为主分支。

此时提示我需要commit

执行git commit 操作后

切回自己的master分支

此时发现,现在的代码是所切换的代码,切换指定提交之前的本地代码丢失了


问题原因

  1. 没有使用git checkout master切换原来的分支就进行git stash pop

    • 没有切换回主分支,直接用git stash pop,会将暂存的修改(stash应用到当前所在的历史提交detached HEAD),才会导致冲突

      • 如果你在 detached HEAD 状态下 stash pop 后直接切换分支:

        git stash pop       # 修改应用到历史提交
        git checkout master # 切换分支

        Git 会提示“本地修改会被覆盖”,你必须选择:

        • git commit → 提交会留在游离状态,容易被遗忘。

        • git stash → 再次暂存,但需手动恢复。

        • 丢弃修改 → 代码丢失

  2. git stash push未添加-u参数导致未追踪的文件未被添加到暂存区

    • git stash 默认不保存未跟踪文件。最初执行 git stash 时没有加 -u--include-untracked 参数

什么是未跟踪文件

  1. 从未执行过 git add

    • 新创建的文件默认是未跟踪的。

    • 例如:你新建了一个 test.py,但还没用 git add test.py

  2. .gitignore 忽略的文件

    • 如果文件匹配 .gitignore 中的规则,即使手动 git add 也会被忽略。

    • 例如:IDE 配置文件(如 .idea/)、编译生成的 *.class 文件等。

  3. 已从 Git 中删除,但仍在本地磁盘

    • 如果文件曾被跟踪,但后来被 git rm 删除,而本地文件仍保留,它会变成未跟踪状态。


如何恢复丢失的代码?

1. 检查是否还能找回 stash

运行以下命令查看是否还有 stash 记录:

git stash list

如果仍有记录(如 stash@{0}),可以尝试重新应用:

git stash apply 'stash@{0}'  # 不删除 stash
​
#或者
git stash pop stash@{0} # 弹出删除 stash

这时候暂存区的代码就会恢复到工作区中了

2.未追踪代码未被恢复

这些文件没有被 git stash apply 恢复,是因为:

主要原因

  1. git stash 默认不保存未跟踪文件

    • 你最初执行 git stash 时没有加 -u--include-untracked 参数

    • 导致 IDE 配置文件(.idea/)和新创建的 Java 文件未被暂存

如果文件还在本地(未被删除)
  • 这些文件可能仍然在你的工作目录中,只是 Git 没有跟踪它们。你可以手动检查这些路径是否存在:

    ls habbit/.idea/          # 查看 .idea 目录是否存在
    ls habbit/HELP.md         # 查看 HELP.md 是否存在
  • 如果存在,可以直接用 git add 开始跟踪:

    git add habbit/HELP.md
如果文件已被删除
  • 检查 IDE(如 IntelliJ/VSCode)的 本地历史记录(Local History),可能会找到备份。

  • 使用文件恢复工具(如 Recuva)扫描硬盘。


正确操作流程

1. 切换分支前

  • 推荐提交代码(而不是 stash):

    git add .
    git commit -m "临时保存当前修改"

    这样即使切换分支,代码也会在提交历史中。

    后续也能通过git checkout <commit-hash>切换回来

  • 如果必须用 stash

    git stash push -u -m "暂存所有修改"  # -u 包含未跟踪文件

2. 切换分支后

  • 恢复 stash 时正确处理冲突

    git stash pop  # 或 git stash apply

    如果冲突:

    • git status 查看冲突文件。

    • 手动决定保留哪些代码(不要直接 git add .)。

    • 确认无误后再提交。

3. 切换回原分支

  • 确保所有代码已提交或 stash

    git status  # 确认没有未提交的修改
    git checkout master

不添加暂存区直接git checkout 可以吗?

对比项git checkout <commit>(第一种)git stash + git checkout(第三种)
是否保留本地更改✅ 保留(工作目录和暂存区)❌ 不保留(先存到 stash,再恢复)
工作目录状态仍然有未提交的更改切换到历史提交时是干净的
适用场景临时查看历史版本,同时继续修改完全回到历史版本,稍后恢复更改
是否进入 detached HEAD✅ 是✅ 是
冲突风险可能直接冲突(如果历史版本和本地更改冲突)切换时无冲突,stash pop 时才可能冲突
### 如何在保留本地修改的前提下切换Git分支 当存在未提交的更改并希望切换到另一个分支时,有几种方法可以在不丢失这些更改的情况下完成操作。 #### 方法一:使用 `git stash` 功能 对于不想立即提交但又需要清理工作目录的情况,可以先将改动暂存起来再切回原来的分支。具体命令如下: ```bash $ git stash save "message" ``` 这会把当前的工作状态保存下来,并重置工作区以便安全地执行分支转换。之后可以通过下面这条指令返回原分支重新应用之前隐藏的变化: ```bash $ git checkout original_branch_name $ git stash pop ``` 上述过程中的 `"message"` 是可选参数,用于描述这次 stashing 的内容[^2]。 #### 方法二:创建临时提交并在后续移除它 另一种方式是在现有基础上做一次临时性的提交,接着正常变更目标分支;一旦回到初始位置,则取消该次提交记录: ```bash # 创建一个新的临时提交 $ git add . $ git commit -m "WIP (work in progress)" # 切换至所需的目标分支 $ git checkout target_branch_name # 完成任务后再次转回源分支 $ git checkout source_branch_name # 移除最后一次不必要的提交历史 $ git reset HEAD~1 --mixed ``` 此方案适用于那些已经准备好要加入版本控制系统里的变动,只是暂时不适合推送出去的情形[^4]。 通过这两种策略之一,能够在不影响正在进行工作的前提下自由穿梭于不同开发路径之间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值