我们来比较一下git的一些命令的区别
reset hard/soft
1
2$ git reset --hard
$ git reset --softfetch/pull
1
2git fetch
git pullreset/revert
基本概念图
注意,图中的Stage和Index是同一个东西。
下图中,最后一个diff
应该为diff --cached
注意,Git中的branch实际上可以看做是一些列commit的集合。commit是按照repo全局的,这可以最长程度实现复用。
实验
实验:有关reset
Step 1
本实验说明soft reset不会改变working directory。
首先我们在空目录执行
1
git init
我们创建a.txt,并且填写其内容为
1
我们执行
1
2
3git add .
git commit -m"a=1"
git log得到输出
1
2
3
4
5commit 6bd3de7a2b1637dcb686f72af415c5d48f4d5dc2 (HEAD -> master)
Author: Calvin Neo <calvinneo1995@gmail.com>
Date: Fri Oct 30 22:46:37 2020 +0800
a=1修改a.txt的内容为
2
执行
1
git reset --soft
查看a.txt的内容为
2
这说明a.txt没有被reset掉
Step 2
本实验说明soft reset不会改变index
- 此时,a.txt的内容仍然为2
执行
1
git diff --cached a.txt
可以看到,a.txt已经被提交到了index里面
1
2
3
4
5
6
7
8
9diff --git a/a.txt b/a.txt
index 56a6051..d8263ee 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1 @@
-1
\ No newline at end of file
+2
\ No newline at end of file执行
1
git reset --soft
检查a.txt的内容仍然为2
Step 3
本实验说明soft reset能改变Repo
此时a.txt的内容仍然为2,执行
1
git commit -m"a=2"
检查git log
可以看到,a=2
已经进入了Repo1
2
3
4
5
6
7
8
9
10
11commit c0a4d93cb05eb39e149ff50d9b7e54257a51234b (HEAD -> master)
Author: Calvin Neo <calvinneo1995@gmail.com>
Date: Fri Oct 30 23:03:53 2020 +0800
a=2
commit 6bd3de7a2b1637dcb686f72af415c5d48f4d5dc2
Author: Calvin Neo <calvinneo1995@gmail.com>
Date: Fri Oct 30 22:46:37 2020 +0800
a=1执行
HEAD~1
表示HEAD
向前一个版本。1
git reset --soft HEAD~1
检查git log
发现a=2
的提交被回退了1
2
3
4
5commit 6bd3de7a2b1637dcb686f72af415c5d48f4d5dc2 (HEAD -> master)
Author: Calvin Neo <calvinneo1995@gmail.com>
Date: Fri Oct 30 22:46:37 2020 +0800
a=1检查a.txt
发现内容还是2,没有变。说明即使回退了Repo,也不会改变工作区。执行
1
git checkout
检查a.txt
发现值内容还是2,这个和图2似乎有矛盾。其实应该要加一个-f
1
git checkout -f
实验:有关bisect
Linux内核易于维护的一个原因就是因为Linus要求每一个commit只做一件事,所以他能够通过git bisect
快速地二分出错误的提交。
执行下面语句,得到10个提交1
2
3
4
5git init
for i in {1..10}
do
echo "print '$i'" > p.py && git add . && git commit -m"p $i"
done
我们的目标是找到第一个打印出大于等于5的错误提交。
我们写一个predicate脚本1
2
3
4
5
6
7# test.sh
printed=$(python p.py)
if [ $printed -lt 5 ]; then
exit 0; # good
else
exit 1; # bad
fi
执行下面语句,自动查找到第一个故障提交1
2
3
4git bisect start
git status
git bisect bad HEAD
git bisect good HEAD~9
下面执行git bisect run
,可以得到以下输出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17$ git bisect run ./test.sh
running ./test.sh
Bisecting: 1 revision left to test after this (roughly 1 step)
[552b511a6d14f48a258338527fb6532a6852d1c2] p 3
running ./test.sh
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[53c92c7bd287ae1cc06a0ff1eeb57f6bb9525424] p 4
running ./test.sh
6254d17800fc63757fd6b478e80db23480aec6f7 is the first bad commit
commit 6254d17800fc63757fd6b478e80db23480aec6f7
Author: Calvin Neo <calvinneo1995@gmail.com>
Date: Mon Nov 9 22:56:36 2020 +0800
p 5
:100644 100644 06cfe93d366cdbd541402affbcbf2305c1d7409b a6b723841de0d34ba0a7d30e7ba3b16ff48ad8e4 M p.py
bisect run success