Decorative image frame

8.再遇工作区和版本库

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

”大神我看你用使用git reset时使用了--hard参数,是不是还有其他参数啊。“小白虚心问道
”小伙很细心啊,不错,还有其余的2个参数,我挨个给你讲吧。刚才用过–hard,咱们从他讲起。咱们先创建个文件,加两条commit,方便讲解“老鸟说到

1
2
3
4
5
6
7
$ echo "1"> test.txt
$ git add test.txt
$ git commit -m "1"
$ echo "2"> test.txt
$ git add test.txt
$ git commit -m "2"

“咱们创建了2条commit记录了,第一条记录test.txt里的内容是1,第二条记录test.txt里的内容是2。先看一下记录” 老鸟说

1
2
3
4
5
6
7
8
9
10
11
12
$ git log
commit a609df431578e5061b5d0261bfa38cb0fa01efb1 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:42:11 2020 +0800

2

commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

“接下来,咱们撤销一下看看效果”老鸟继续教导小白

1
2
3
4
5
6
7
8
9
$ git reset --hard HEAD^
HEAD is now at b5a6d3a 1
git log
commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

”现在历史被撤回了,咱们看git的状态“ 老鸟说

1
2
3
$ git status
On branch master
nothing to commit, working tree clean

”你看工作区和暂存区都是空的对吧“老鸟说
”恩恩,文件内容应该变成1了“小白说

1
2
$ cat test.txt
1

“回答正确,咱们先把历史还原,然后再来试试另一个参数”老鸟说。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git reset --hard a609df431578e5061b5d0261bfa38cb0fa01efb1
HEAD is now at a609df4 2
$ git log
commit a609df431578e5061b5d0261bfa38cb0fa01efb1 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:42:11 2020 +0800

2

commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

“接下来试试--mixed,看看会是什么效果”老鸟说

1
2
3
4
5
6
7
8
9
$ git reset --mixed HEAD^
Unstaged changes after reset:
M test.txt
$ git log
commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

“历史回退了”小白说
“恩,咱们看看文件状态有什么变化”老鸟说

1
2
3
4
5
6
7
8
9
10
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

“这是什么意思啊,这个提示不是文件发生修改的时候才有的吗”,小白疑惑
“看一下文件内容你就明白了”老鸟说到

1
2
$ cat test.txt 
2

”知道什么愿意你了吗“老鸟说
”哦,我明白了,历史回退了,按说文件的内容应该是1,但是现在内容是2,所以git以为文件发生了修改“小白说道。
”恭喜你答对了,--mixed参数会清空stage缓存区,但是不会直接修改文件的内容,如果需要将文件内容撤回,可以在执行git checkout <file>“老鸟解释道

1
2
3
$ git checkout test.txt
$ cat test.txt
1

”你看内容变了吧,接下来你猜一下--soft参数会是什么效果“老鸟说
”既然--hard文件工作区和缓存去都清空了,--mixed把缓存区清空了,那--soft是不是会保留缓存区啊“小白说道
”不错嘛,这都分析到了,没错,--soft参数只是撤销了记录,缓存区和工作区都不做修改,咱们来看下效果“。老鸟说,”先恢复一下记录方便看效果“

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git reset --hard a609df431578e5061b5d0261bfa38cb0fa01efb1
HEAD is now at a609df4 2
$ git log
commit a609df431578e5061b5d0261bfa38cb0fa01efb1 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:42:11 2020 +0800

2

commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

”历史回来了,咱们开始看下--soft的作用“老鸟敲下命令

1
2
3
4
5
6
7
8
$ git reset --soft HEAD^
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: test.txt

”你看,是不是和你想的一样啊,要想清理缓存区可以按提示执行git reset HEAD <file>,剩下的就不用我说了吧“老鸟说道
”恩恩,明白,文件线下的内容应该还是2吧,我清理完缓存区,然后git checkout <file>文件内容就会变回commit对应的内容,对吧“小白问道

”没错,那你知道为什么会有这三种不同的参数吗“老鸟问
”不明白,--hard很方便啊,其他两种还要做其他操作才能回复文件内容,多麻烦。“小白回答

”你现在只是一个文件,如果你的一个历史记录有很多文件怎么办,如果你只需要撤回其中一个文件呢,用--hard不是自杀吗。使用--mixed--soft可以保证文件内容不撤销,这样你就可以用git checkout针对你需要撤销的文件进行撤回。多方便 “老鸟说道
”哦,明白了,谢谢大神“小白激动的说

”走了,有问题随时问我“,老鸟再次潇洒离去,留下了激动的小白

小结

  • --hard 撤销commit记录,清空tage暂存区,清空工作区内容,文件内容彻底还原
  • --mixed 撤销commit记录,清空tage暂存区,保留工作区内容,执行git checkout <file>可撤销修改,让文件内容还原
  • --soft 撤销commit记录,保留stage暂存区,保留工作区内容,如果要撤回需要先执行git reset HEAD <file>撤销暂存区,然后执行git checkout <file> 撤销修改

7.时光倒流

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

小白正在开心的写代码,刚刚完成了产品小伙伴的一个需求。还是小有成就感的,正准备起来活动活动喝杯水。谁知产品小伙伴有风风火火的跑过来。
“小白,小白,客户还是感觉以前的交互方式用着顺手。让把功能改回去”。产品小伙伴喊道。
听到这个消息,小白满脸的黑线。废了半天劲做出来的功能再改回去。这太坑了吧。
但是没办法,谁叫客户就是上帝呢,改吧。
开始撤销,ctrl z。。。
what,没法撤销了?编辑器撤销的步骤有限,这可如何是好啊,难道要手动改代码?这也太悲剧了吧。
“对了找大神问一下,看git有没有办法回退”小白灵光一闪想起来老鸟。

老鸟一听到小白喊他“大神”,瞬间心情舒畅跑过来知道小白。

“你是要回退以前的版本吗?”老鸟问道。
“恩恩”小白点头
“回退其实很简单,看我操作,要记住啊”说完,做到小白的坐位上开始了他的神操作。

“首先用git log看一下你的提交记录”,老鸟说道

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git log

Author: shooke <xingjiehu@163.com>
Date: Sat Mar 14 16:45:03 2020 +0800

<E7><8A><B6><E6><80><81><E4><BF><AE><E6><94><B9><E5><92><8C><E5><AF><B9><E6><AF><94><E6><97><B6><E9><97><B4>

commit 3e14b6822063c7add663cd79756e77818e821819
Author: shooke <xingjiehu@163.com>
Date: Sat Mar 14 00:30:27 2020 +0800

<E5><AE><A1><E6><A0><B8><E7><8A><B6><E6><80><81><E4><BF><AE><E6><94><B9>

“咦,你这里git log居然乱码啊”,老鸟说道
“这是咋回事啊”,小白疑惑
“好办,编码问题解决一下就可以了”。老鸟输入了如下三条命令

1
2
3
4
5
6
git config --global i18n.commitencoding utf-8

git config --global i18n.logoutputencoding utf-8

export LESSCHARSET=utf-8

再次执行git log果然好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
git log
commit 6531ff6013dd490f60bcd646ca01df61a1ecc8b1 (HEAD -> dev, origin/master, origin/dev, origin/HEAD, master)
Author: shooke <xingjiehu@163.com>
Date: Sat Mar 14 16:45:03 2020 +0800

状态修改和对比时间

commit 3e14b6822063c7add663cd79756e77818e821819
Author: shooke <xingjiehu@163.com>
Date: Sat Mar 14 00:30:27 2020 +0800

审核状态修改

...

“log记录有时候很多,你可以不停的按jk来实现向下或向上查看内容,不行看了,就输入:q退出。就跟vim编辑器使用方式一样”老鸟说。

“想要退回到那里,用git reset会退到对应的commit id就可以了。比如会退到审核状态修改。老鸟边说变执行命令

1
git reset --hard 3e14b6822063c

打开编辑器,小白发现,代码真的回到以前了。

“大神,commit id怎么输入了一部分啊,不需要全部输入吗”,小白激动说道

“不需要,只要git能够确定唯一的commit就行了,一般也就输入前几位”,老鸟说。

“每次都要看commit id好麻烦啊,有没有简单的方法?”小白谦虚问道

“当然有啊,可以用HEAD加上^或者~n回退啊”。老鸟说

1
git reset --hard HEAD^

“这样就会回退一条commit,如果退两条,就再加一个^,退几条就加几个^”老鸟说
”那退20条,岂不是20个^,多麻烦啊“,小白说
”孺子可教啊,这要用~n了,可以这样写“,老鸟说

1
git reset --hard HEAD~20

“明白了,谢谢大神”小白说道。
”你刚才要回退到那条commit啊“老鸟问道
”啊,我只需要退一条就行了,咱们刚才退了这么多,怎么办啊“小白说

”这怕啥,你只要知道历史中的commit id,就不用担心,及时你回退了50条,要回到第二条也没问题“老鸟边说变敲下哦了命令

1
git reset --hard 3e14b6822063c7add663cd79756e77818e821819

”你看这不是回到你第二条命令时的状态了吗,只要你记得回退前的commit id,随时可以穿梭到任何commit“老鸟说道。

小白豁然开朗,原来历史是可以任意切换的,并不是回退了就抹除了。

小结

  1. 解决乱码
    git config --global i18n.commitencoding utf-8 该命令表示提交命令的时候使用utf-8编码集提交

git config --global i18n.logoutputencoding utf-8 该命令表示日志输出时使用utf-8编码集显示

export LESSCHARSET=utf-8 设置LESS字符集为utf-8,为了让配置一直有效,可以把这个设置添加到~/.bashrc,然后执行source ~/.bashrc

  1. 查看历史
    git log可以查看历史。但是如果用git reset回退了,是看不到被退回的历史的,如果要保证历史,可以使用git revert,后面会讲这个命令
    git log --stat 显示commit历史,以及每次commit发生变更的文件
    git log -S [keyword] 搜索提交历史,根据关键词
    git log [tag] HEAD --pretty=format:%s 显示某个commit之后的所有变动,每个commit占据一行
    git log [tag] HEAD --grep feature 显示某个commit之后的所有变动,其”提交说明”必须符合搜索条件
    git log --follow [file]git whatchanged [file] 显示某个文件的版本历史,包括文件改名
    git log -p [file] 显示指定文件相关的每一次diff
    git log -5 --pretty --oneline 显示过去5次提交

  2. 历史切换
    git reset HEAD^可以向前撤销一次,多个^可以撤销多条历史,或者使用git reset HEAD~5这样可以一次撤销5条历史
    git reset可以任意切换到某个历史,使用git reset --hard commitid即可,commit id不一定要全的,可以只写前几位

6.撤销操作

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

”大神!你是再叫我吗“,老鸟回过头问小白。
“是啊大神,虽然git diff很牛,可以让我知道改过什么,但我一点点的改回去好麻烦啊,有没有别的办法?”

大神,老鸟暗喜。这个大神的称号还是很少用的。老鸟摆出一副高深莫测的表情。
“办法当然有,既然你问了,就告诉你吧”

老鸟回到小白的工位入座。拿过键盘,开始实战时光回退大法,输入 git checkout package.json。施展至于本着经验精神不忘问一句,“你确定这些修改不要了?”
“恩恩,前面的思路有问题,我想到了一个更好的办法,所以还原吧。”小白虚心的说道。
只见老鸟手起指落,敲击在回车上。

再次查看文件,package.json文件真的恢复了。小白满眼崇拜的目光看向老鸟。
看到小白的表情,老鸟还是非常受用的。

“既然你这么好学,老夫就再教你一招,包你从此不会写错代码。”老鸟说道
“恩恩,大神请将”小白谦虚道。

“这个git呢要活学活用,你已经知道git分为工作区,暂存区和仓库了吧?”老鸟说道
“恩恩”小白道

“git diff的功能你也了解了吧”,老鸟继续说
“恩恩”小白点头道

“其实工作区,暂存区和仓库的概念是贯彻始终的,git checkout 也适用”,老鸟继续说
“大神的意思是说,如果我对package.json进行了 git add操作,checkout的时候就会回到add时候的代码,如果没有add过,就会回到上一次commit时候的代码?”。小白问道

“恩,不错悟性很好啊,记住一点,开发一个功能要常add,完成后在用commit收尾。这样在开发过程中出错,可以及时撤销,也可以减少不必要的commit历史”。老鸟提醒小白。
“恩恩,谢谢大神”,小白真诚的向老鸟道谢

一口一个大神,叫的老鸟飘飘然。老鸟也是非常的开心。临走不忘说一句“遇到问题尽管找我”

小结

git checkout --filename 可以撤销文件的变更。

  • 如果文件git add过,会撤回到add时的代码,即暂存区代码。
  • 如果没有git add过,会撤回到上次commit时的代码,也就是版本库中,最近的版本。

关于工作区和版本库的介绍,可以看上一篇《4.工作区和版本库》

如果一个功能比较复杂,可以完成一小部分执行一次add,或者是commit,这样在后续开发中发现改错了东西,可以及时撤回。

5.对比文件变化

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

了解了工作去和版本库的区别,小白开始自己开动脑筋举一反三。既然git status可以查看哪些文件发生的变化。那能不能知道具体的变化是什么呢。

毕竟作为一个程序猿,临时被唐僧召唤的事情经常发生。小白正在思考着,产品经理就喊上了。有个新需求需要确认排期。小白只好怪怪的跑过去。
确认完排期,回到座位上,继续开发今天的功能。add commit已经熟练的飞起。貌似git也很简单嘛。

中午到了,开饭。吃过午饭回到坐位的小白发现电脑关机了。据说是某个不知名的家伙不小心提到了插座。
好吧,重新开机就好了,打开自己熟悉的ide,一切如常。上午的功能还没有commit,看下改过哪些文件吧。git status发现改了十几个文件。
好多都已经记不清改的什么了,肿木办?先把自己记忆清除的几个add。然后commit。剩下几个实在想不起来改过什么了。ide也没法回退了,这该如何是好啊。

正在小白苦恼的时候,老鸟过来了。
看着发呆的小白,老鸟关系的问“小猴子,今天怎么发呆了?”。
小白如实回答“有几个文件忘记改过什么地方了,电脑关过机,ide也没法撤销操作了”。
老鸟熟练的敲下了git diff package.json,这时候所有的改动一目了然的展现在了小白面前。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ git diff package.json
diff --git a/package.json b/package.json
index 00570c9..f06efde 100755
--- a/package.json
+++ b/package.json
@@ -16,7 +16,6 @@
"@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"babel-eslint": "^10.0.3",
- "eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.6.10"
},
@@ -27,7 +26,7 @@
},
"extends": [
"plugin:vue/essential",
- "eslint:recommended"
+ "eslint:recommendeddd"
],
"rules": {
"no-console": "off"

还不待老鸟解释,小白已经明白减号-代表的是自己删除的行+是产生的新行。

这下好了,可以看出自己修改过的细节,就可以很清楚的解决问题了。

看着小白激动的目光,老鸟挥一挥衣袖,不带走一点代码。飘然而去。

望着老鸟离去的背影,小白激动的追上去,语出惊人“大神,留步!”

小结

git diff --filename 可以比较文件的变更情况。

  • 如果文件git add过,会显示工作区和暂存区的差别。
  • 如果没有git add过,会显示工作区和仓库历史版本的差异。

git diff --cached [file] 显示暂存区和上一个commit的差异

git diff HEAD 显示工作区与当前分支最新commit之间的差异

git diff --shortstat "@{0 day ago}" 显示今天你写了多少行代码

关于工作区和版本库的介绍,可以看上一篇《4.工作区和版本库》

4.啥事工作区、暂存区和版本库

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

回到家的小白,想着今天发生的事,为什么git status出来的提示信息不一样?为什么git status出来的提示信息不一样?为什么git status出来的提示信息不一样?
想着想着他就睡着了,梦里他遇到了linus大神,linus带他来到了一个神秘的机构。在这个房间里有2个人,还有一个大大的大屏幕。
每次大屏幕上显示git add,就会有一份文件到达一个人的手里,他会把信息进行整理。当大屏幕上显示git commit。第一个人就会把整理的内容放到第二个人的桌子上,然后回来继续工作。

小白疑惑的看向linus大神,大神和蔼的告诉他“小白,你不是一直奇怪,为什么git status出来的提示信息不一样?”,这就是你要的答案。

小白仔细打量着房间里的一切,第一个人的办公桌上有一个牌子,上面写着”stage”。
第二个人的办公桌上同样有一个牌子,上面写着”HEAD”。

小明若有所思,抬起头的时候,发现linus大神已经不见了。他冲出房门,发现街上根本没有大神的踪影,只有房子上高高挂起的牌匾写着”版本库”三个打字。

他大声的呼喊,这时耳边传来“叮铃铃叮铃铃”的响声。

小明从梦中醒来一看,哇,还有半小时就八点60了,飞快起身,背上背包冲向公司。

距离上班还有1秒钟的时候,小白打卡成功。

打开电脑,想起昨天遇到的情形,好像自己明白了什么,到网上一查,原来如此。

git是分为工作区和版本库的。代码发生更改后,执行git add代码会放到代码库的暂存区(stage),当执行git commit时代码会形成版本记录(HEAD),并且删除暂存取的记录。

当我们执行git status时,git会将工作区(当前的代码)与暂存区的记录进行比较,如果暂存区没有记录,则会跟做过记录的版本作比较。从而提示你哪个文件发生过修改。

明白了这些,小白开始反思昨天看到的提示。

1
2
3
4
5
6
7
8
9
10
11
$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)

我最帅.txt

nothing added to commit but untracked files present (use "git add" to track)

Untracked files列出的是新建的文件,还没有被add和commit过,所以提示你(use "git add <file>..." to include in what will be committed),这表示需要进行git add操作

1
2
3
4
5
6
7
8
9
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: readme.md

no changes added to commit (use "git add" and/or "git commit -a")

Changes not staged for commit列出被修改的文件,这时候文件还没有被add和commit。这时就是比较工作区和HEAD得出的结果。modified: readme.md意思是这个文件发生了更改。

了解了不同提示的原因,小白果断git add git commit开始开发新功能。

小结

git是分为工作区和版本库的。代码发生更改后,执行git add代码会放到代码库的暂存区(stage),当执行git commit时代码会形成版本记录(HEAD),并且删除暂存取的记录。工作区可以简单理解为项目目录,每次项目更改都会记录,这些变更记录就是版本库。

下面是各种状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
git status
On branch master

# 已经执行过`git add`但没有执行`git commit`
Changes to be committed:
# 可执行的命令,reset会移除暂存区记录,移除后需要重新进行add
(use "git reset HEAD <file>..." to unstage)

renamed: 我最帅.txt -> wo.txt

# 文件发生修改时提示
Changes not staged for commit:
# 可以执行的命令,文件修改是可以执行add加入到暂存区,也可以checkout进行撤销
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: readme.md

# 新增文件时提示
Untracked files:
# 可以执行的命令,新增文件只要add到
(use "git add <file>..." to include in what will be committed)

我很帅.txt

no changes added to commit (use "git add" and/or "git commit -a")

3.查看文件状态

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

第二天上班,小白开开心心的打开电脑,准备爽一把。忽然想起来,昨天好像有一个功能还没有做完,临走的时候没有执行addcommit

糟糕好像忘记修改过哪几个文件了。这可如何是好啊?

一盏灯泡从小白的脑袋里亮起,好像我开始使用git了,git应该知道我昨天哪些代码没有commit吧。
小白打开百度,果然,git是可以查看文件状态的。

1
2
3
4
5
6
7
8
9
10
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: readme.md

no changes added to commit (use "git add" and/or "git commit -a")

modified: readme.md,哦,原来是readme.md文件昨天修改过。马上git add readme.md git commit -m "readme"添加到仓库。

ok,继续快乐的工作。

开始开发新功能,创建一个新文件

1
touch 我最帅.txt

不一会功能开发完成。脑袋好乱,刚才出去又忘记改了什么文件。还是用git status吧。

1
2
3
4
5
6
7
8
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)

"\346\210\221\346\234\200\345\270\205.txt"

nothing added to commit but untracked files present (use "git add" to track)

"\346\210\221\346\234\200\345\270\205.txt"是什么鬼,我们打开万能的百度,是因为git对对0x80以上的字符进行quote,解决方法很简单

1
git config --global core.quotepath false

没有报错,应该没有问题吧,小白抱着试试看的态度敲下了git status命令

1
2
3
4
5
6
7
8
9
10
11
12
$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)

我最帅.txt

nothing added to commit but untracked files present (use "git add" to track)

果然正常了。小白那个开心啊。内心YY道:“我就说吗git这么强大,怎么可能弱鸡到中文都不能正常显示,我果然是天才,一下就找到了原因”

马上开始保存到仓库,咦,不对,好像两次git status出现的提示不一样,这是怎么回事啊。

时间在小白的思考中慢慢流失,抬头一看,哇,这不8点60了吗。赶紧回家…

小结

git status可以查看项目的变更情况
git config --global core.quotepath false 可以解决,git提示信息中文乱码问题

思考

为什么小白两次git status出现的提示不一样呢?这就要从git的管理机制,工作区和代码库说起了

预知后事如何,且看下回分解。

2.把项目交给git

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

小白接到上级指示,所有的项目代码都要用版本管理工具进行管理。本着对项目负责的态度,小白开始在网上搜索版本管理软件。
考察了svn和git后,最后决定使用git进行项目管理。

对于刚刚不如程序猿行列的小白来说,git好神秘啊,linus大神好神秘啊。

沐浴更衣,斋戒数天。开始使用git。

使用git的第一步当然是安装了。

1
2
$ sudo apt update
$ sudo apt install git

ok,搞定,这样就安装完了。

打开项目目录,输入神圣的git初始化命令

1
2
$ git init
Initialized empty Git repository in /home/shooke/learngit/.git/

完成了?这么简单?没有报错?小白小激动了一下,git初始化就这么简单?检查一下便知道。查看了一下,项目下果然多了个.git文件夹。

接下来我们把项目加入到git代码仓库

1
2
git add .
git commit -m "init"

这样,文件就被git记录下来了。就是这么easy。

不一会小白写好了一个新功能,然后git add . git commit -m "我有完成了一个牛X的功能"记录下自己的工作。好开心,原来git这么简单,每次做完功能先 add然后commit就好了。

就这样小白开始了他的git之旅…

小结

git init可以初始化项目
git add .可以将文件加入到暂存区,.是当前目录的意思,可以将目录下所有文件进行暂存,如果要针对某个文件可以加上文件名如git add readme.md
git commit -m "init"将文件加入到git代码仓库,并生成一条init的log记录

1.啥是git

事情要从linux说起,git的作者就是linux之父linus。在2002年以前,都是通过手工比较代码的方式来合并社区反馈的代码,进行合并。但随着linux项目越来月庞大。手工合并变得不现实了。当时市面上也有cvs或svn这样的版本控制软件。但linus反对使用这些集中式的版本控制系统,因为它们都必须联网才可以使用,而且速度比较慢。
有一些好用的速度快的系统,不过都是需要付费的,这与linux的开源精神不符。
2002年之前,由于没有合适的版本控制系统,linus都是通过手工diff去比较合并代码的。这时的工作太过繁重。
2002年的时候BitMover公司,将BitKeeper授权linux社区免费使用。人多的地方就有江湖,江湖中从来不乏高手,特别是linux社区。2005年,社区中有一些人将BitKeeper破解了。这可是人家BitMover公司吃饭的家伙啊,你破解了人家当然不愿意了。于是BitMover公司怒了,收回了免费使用权。
linus一看也不乐意啊。你不让我用那我就自己写一个呗。于是linus用了2周的时间,自己写了一个分布式的版本控制系统(牛人的世界就是这么牛X)。也就是git。很快(有多快呢,一个月左右)linux系统就全部由git管理了。
后来的事情大家都知道了。2008年github上线,让git走进了千家万户,是个知道开源的都知道github。知道github还不知道git(就相当于吃了猪肉,没见过猪跑一样),那是不可能的。

0.教程介绍

市面上已经有很多的git教程了,比如廖雪峰老师的git教程,还有阮一峰老师写的关于git的一些教程。我在刚开始接触git的时候,就是读的他们教程。他们写的都很好,git的所有功能都有所涵盖,但是很多人知道了命令,但在工作中还是不清楚该如何使用。

与网络上所有的教程都不同,本教程更注重使用场景,会根据不同的场景,选择最优的git命令,来解决问题。

教程中所有的命令都会有一段工作场景的介绍,我们可以跟随小白的视角,一起学习git是如何使用的。以及最后会做出总结,介绍命令的功能,以及一些使用技巧。

git中文文件名乱码解决方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)

Untitled-1
"git\347\256\200\344\273\213"

nothing added to commit but untracked files present (use "git add" to track)


其实"git\347\256\200\344\273\213"是个中文名的文件git简介,中文部分成了乱码,解决方法很简单

1
git config --global core.quotepath false

这样,不对0x80以上的字符进行quote,解决git status/commit时中文文件名乱码