git: 提交前查看修改 git diff,HEAD^, HEAD~i

推荐安装 p4merge 作为 git 的 diff 工具:

# Starts git difftool for all modified files
git difftool

# Compare only specific file
git difftool location\filename

# diff 当前版本的文件和某个commit的某个文件
git difftool 3693493981a35c07f2bee7cae71f8e8bd95be625 -- filename

# git difftool [start commit]..[end commit] filename
git log filename  # 查看某个文件的提交记录
git difftool 6cde26245763dd43f9505c7578a1f7be44b7fad1..8d5336398  -- filename

常用 example:

git diff:是查看 workspace 与 index 的差别的。
git diff --cached:是查看 index 与 local repositorty 的差别的。
git diff HEAD:是查看 workspace 和 local repository 的差别的。(HEAD 指向的是 local repository 中最新提交的版本)

注:git diff 后跟两个参数,如果只写一个参数,表示默认跟 workspace中的代码作比较。git diff 显示的结果为 第二个参数所指的代码在第一个参数所指代码基础上的修改。如,git diff HEAD 表示 workspace 在 最新commit的基础上所做的修改。
如图
这里写图片描述

在git提交环节,存在三大部分:workspace, index, repository 尊重作者,原文链接

这三大部分中:

workspace:就是你所工作在的目录,每当你在代码中进行了修改,working tree的状态就改变了。
index:是索引文件,它是连接working tree和commit的桥梁,每当·我们使用git-add命令来登记后,index file的内容就改变了,此时index file就和working tree同步了。
repository:是最后的阶段,只有commit了,我们的代码才真正进入了git仓库。我们使用 git commit -m "xxx" 就是将 index 里的内容提交到本地仓库中(push 之后就到了远程仓库了)。

要跟历史版本中的代码作比较:

git diff HEAD^ 比较 workspace 与最新commit的前一次commit的差异(注意与git diff HEAD的差别)
git diff HEAD~2 比较 workspace 与上2次提交的差异,相当于 git diff HEAD~2 HEAD~0注意两个HEAD的位置,diff显示的结果表示 后一个(HEAD~0) 相对于 前一个的修改(HEAD~2)

当然也可以通过 a/b 来区分对应的文件,如下:

--- a/build/test.cmake   (a表示 git diff后的第一个文件,---表示删除)
+++ b/build/test.cmake   (b表示 git diff后的第二个文件,+++表示增加)

例如,git diff HEAD~2 HEAD^ 比较上次commit(即最新的commit的前一次)与上上次commit之间的差异,HEAD^=HEAD^1=HEAD~1;其中 a 表示 HEAD~2b表示 HEAD^

注意^~之间的区别,当存在多个分支时,^可以用来选择分支,HEAD~i永远只选择第i级父节点的第一个分支,HEAD~i^2选择第i级父节点的第二个分支,以此类推;HEAD^=HEAD^1=HEAD~1;如果没有分支,只有一条主线,则HEAD^^^=HEAD^1^1^1=HEAD~3,如果该级几点有第二个分支,则表示为:HEAD^^^2 = HEAD~2^2.
图文可见链接

为了更加清晰的阐释这个关系,来给出一个实例:

[yaya@yaya-desktop]$ cat main.c
#include<stdio.h>
int main(int argc,char *argv[])
{
	printf(“hello.\n”);
	printf(“he was a student.\n”);
	return 0;
}

然后git init, git add . , git commit;
之后你将源代码修改为:

[yaya@yaya-desktop]$ cat main.c
#include<stdio.h>
int main(int argc,char *argv[])
{
	printf(“hello.\n”);
	printf(“he was a student.\n”);
	printf(“he was born in finland.\n”);
	return 0;
}

此时你git add .,但不用执行git commit命令。然后你再将源代码改为:

[yaya@yaya-desktop]$ cat main.c
#include<stdio.h>
int main(int argc,char *argv[])
{
	printf(“hello.\n”);
	printf(“he was a student.\n”);
	printf(“he was born in finland.\n”);
	printf(“he is very clever!\n”);
	return 0;
}

这个时候,你执行如下三个命令,仔细查看,我相信你会发现它们三个的区别的!

$ git diff
$ git diff –cached
$ git diff HEAD

讲到这里,基本上对git diff命令有了比较深入的了解了,现在你再使用git status看看输出结果,样子大概是这样:

[yaya@yaya-desktop]$ git status
# On branch master
# Changes to be committed:
#   (use “git reset HEAD <file>…” to unstage)
#
#    modified:   main.c
#
# Changed but not updated:
#   (use “git add <file>…” to update what will be committed)
#
#    modified:   main.c

很明显可以知道:

Changes to be committed表示已经存在于index file里,但尚未提交。
Changed but not updated表示在working tree已经做修改,但还没有使用git add登记到index file里。

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值