《玩转Git三剑客》学习笔记Day3

113 阅读4分钟

修改commit的message

修改当前HEAD的commit message

git commit --amend 修改当前HEAD的commit,直接打这个指令会进入vim编辑器,如果不想的话可以执行git commit --amend -m "new message"来在终端直接输入new message来修改。注意,修改message实际是生成了一个新的commit,(因为commitID是根据commit对象的hash值生成的,messag改了必然不再匹配之前的commitID)

此时:

  1. 是会用生成的commit替换当前commit的位置,原commit也进入git的垃圾回收处理静候;
  2. 还是直接修改的原commit对象然后修改了文件名和移动到新位置

就不太重要了。

修改指定commit的message

需要用到rebase指令,后续会深入学习

  1. 首先使用 git rebase -i father_commitID 来rebase到要修改的commit的父级commit

会出现以下界面,最上面的是在本father_commit后进行的commit,然后下面是一些指令。其中r就是代表要修改commit message。

  1. 上图中的第一个圈起来的点,就是对应我们需要修改的信息,需要把pick换成r,修改完后wq保存退出。 保存退出后,会自动进入新的界面:

  1. 在这里,就可以修改commit的message了。修改完后,wq保存退出。
  2. 修改成功。

注意,此时从被修改message的commit开始,后续子commit链上的commit全部都生成新的commitID,影响面可能比较大,所以如果在生产环境,并且和别人共享共一个分支,尽量减少rebase命令。如果后续提交都在本地还没有push到远端,这样是可以的,如果已经push上去了且别人也在使用,那rebase并修改过往commit是会让伙伴非常苦恼的。

以上的流程中,在修改commit message后从log中可以看到过程生成了detached HEAD并由git自动更新到refs/heads/branch_name上了。

合并多个commit

  合并相邻的commit

  1. 同上节,先rebase,s/squash代表将该commit和前一个commit合并

  1. 关闭窗口并保存后,弹出如下窗口,此处列出commit1commit2commit3的commit message,可以将其合并。4、关闭窗口并保存后,弹出如下窗口,此处列出commit1、commit2和commit3的commit message,可以将其合并。

  1. 注意:commit message的第一行与第二行之间必须有一个空行,否则会报错。关闭窗口并保存后,弹出合并commit4、commit5、commit6的窗口,操作同上。

  7.2 合并间隔的commit

  1. 其实就是比合并相邻的commit多一步,就是在rebase后,手动移动各个commit的位置把想要合并的commit放在相邻的位置

  2. 用7.1的方法进行合并。

  3. 注意可能发生错误,然后按git的提示继续操作完成。合并完成后也是会生成新的commit。

    从上面操作可以看出,每个commit都是一个当前工程的快照,rebase就是要去重新整理各个commit之间的父子关系,操作比较灵活。

问题1: rebase操作中将某相邻两个commit顺序颠倒会发生什么?如果他们修改的内容包括同一行代码呢,是否会有conflict出现?

比较不同

  • 比较暂存区和HEAD的区别使用git diff --cached cached即表示暂存区。一般是要用git diff --cached commit-id来比较暂存区与指定commit的区别,如果commit-id缺省就是默认使用最新commit也就是HEAD。

  • 比较工作区和暂存区的区别使用git diff ,不加--cached表示比对的一方是工作区。

  • git diff也可以比对任意commit、object、file的区别,具体可以看help。

可以添加的指令有 --stat 来简化diff的结果,或者--output=来指定输出文件。

状态恢复

  • 暂存区恢复和HEAD一样(unstage):git reset HEAD将暂存区改动退回到工作区

  • 暂存区取消部分文件的修改: git reset HEAD <file>...将暂存区指定文件退回到工作区

  • 工作区恢复和暂存区一样(丢弃工作区修改):git checkout -- <file>..."--"代表后面要添加文件

  • 暂存区恢复用reset,工作区恢复用checkout

工作区和暂存区文件的保存是什么机制呢??

  • 消除最近的几次连续commit:git reset --hard father_commitid

  • 消除最近的不连续commit:使用rebase来操作

  • git rebase -i (father-commit-id)
    
  • 编辑文件,将要删除的commit之前的单词改为drop ,然后按照提示保存退出
    
  • 此已经删除了指定的commit,可以使用git log查看下
    
  • git push origin HEAD –force 然后推送到远程仓库
    

缓存操作 stash

git stash applygit stash pop

两个的区别是恢复后,stash栈里还会不会保留。pop会把stash里的drop掉。

stash会同时保存工作区和暂存区的内容吗?保存在哪里呢?数据类型是什么?