[git]常规/非常规操作记录

325 阅读3分钟

git stash pop 之前的文件改动消失

在某个分支上开发时,项目中出现了 bug,需要紧急修复,但是正在开发的内容只做到一半,还不想提交 commit,就可以用git stash将文件的修改暂时存起来,然后切换到 hotfix 分支修复 bug,修复完成后,再次切回到开发分支,从堆栈中恢复刚刚保存的内容继续开发。

但是这只适用于一次 stash,在需要多次 stash 的情况下最好使用git stash save 'stash msg ' 这样便于后续 stash 列表的查看和恢复。

之后可以使用git stash list 查看 stash 列表:

// stash 列表
stash@{0}: On master: 第一次stash
stash@{1}: On master: 第二次stash
...

当想恢复的时候就可以使用git stash pop 或者 git stash apply stash@{NUM} 来恢复,这两个命令的区别在于:

  • git stash pop 会把 stash 列表里面的信息删除
  • git stash apply stash@{NUM} 会继续保留
  • 推荐任何情况下都使用git stash apply stash@{NUM}来恢复

在确认 stash 列表不会再使用的时候可以删除 stash 列表

  • 清除一行:git stash drop stash@{NUM}
  • 清除所有:git stash clear

⚠️注意,如果执行git stash pop之后恢复的内容没有了,(比如你想输入 git status 查看状态,由于肌肉记忆输入了 git stash),还是有办法找回的:

  • 输入git fsck --lost-found 打印出所有的悬空的 commit:
    Checking object directories: 100% (256/256), done.
    dangling commit 24a77d43b6d760755b96ae7a19586d1c490e92e5
    dangling commit e7a8195d51f2e730eaad829c49e2fa3a88045091
    
  • 复制 commit 的 id 值, 输入git show commitId查看具体的改动
  • 之后再执行git stash apply commitID 去恢复工作区改动

总结一下:

  1. 尽量不要使用git stash,要切分支的时候git add . && git commit -m 'commit msg'
  2. 如果一定要 stash,不要直接 git stash /git stash pop
  3. 要使用git stash save 'stash msg'/ git stash appply stash@{NUM}
  4. 最后的防线是git fsck --lost-found 核对相应的 commitId 恢复改动

git 修改 commit log 日志

在开发中如果 commit 提交记录有验证导致无法提交,可以通过修改git commit --amend的方式修改,下面记录一下修改过程

首先执行git log查看改动日志,

  • 如果想修改一条:可以执行git commit --amend 直接修提交日志,然后:wq保存退出

  • 修改多条就比较麻烦,首先输入 git rebase -i HEAD~2 显示要修改的 2 条记录

      pick ba205c2 add new format add change msg xxx
      pick 428960b new add msg for amend commit log
    
      # Rebase 9e5267b..428960b onto 9e5267b (2 commands)
      #
      # Commands:
      # p, pick <commit> = use commit
      # r, reword <commit> = use commit, but edit the commit message
      # e, edit <commit> = use commit, but stop for amending
      # s, squash <commit> = use commit, but meld into previous commit
      # f, fixup <commit> = like "squash", but discard this commit's log message
      # x, exec <command> = run command (the rest of the line) using shell
      # b, break = stop here (continue rebase later with 'git rebase --continue')
      # d, drop <commit> = remove commit
      # l, label <label> = label current HEAD with a name
      # t, reset <label> = reset HEAD to a label
      # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
      # .       create a merge commit using the original merge commit's
      # .       message (or the oneline, if no original merge commit was
      # .       specified). Use -c <commit> to reword the commit message.
      #
      # These lines can be re-ordered; they are executed from top to bottom.
      #
      # If you remove a line here THAT COMMIT WILL BE LOST.
      #
      # However, if you remove everything, the rebase will be aborted.
      #
      # Note that empty commits are commented out
    
  • git 的注释里面写很清楚,把需要修改的记录前面的pick改为edit ,然后保存退出:

    edit ba205c2 add new format add change msg xxx
    edit 428960b new add msg for amend commit log
    
  • 退出之后 git 会提示::

      You can amend the commit now, with
    
        git commit --amend
    
      Once you are satisfied with your changes, run
    
        git rebase --continue
    
  • 输入git commit --amend修改 commit message ,保存退出

  • 再输入git rebase --continue,一条记录就修改成功

  • 重复git commit --amendgit rebase --continue操作直到全部修改完成,如果你再次输入git rebase --continue,git 会提示fatal: No rebase in progress?表示全部修改完成

参考:Git 工具 - 重写历史