日本电影一区二区_日本va欧美va精品发布_日本黄h兄妹h动漫一区二区三区_日本欧美黄色

20 分鐘教你搞懂 Git!(git-)

Git 是最流行的版本管理工具,也是程序員必備的技能之一。本文就來教你 20 分鐘搞懂 Git!

20 分鐘教你搞懂 Git?。╣it-)

以下為譯文:

盡管每天你都會(huì)用到Git,但也有可能搞不懂它的工作原理。為什么Git可以管理版本?基本命令git add和git commit到底在干什么?

在這篇文章中,我將用一個(gè)例子來解釋Git的運(yùn)行過程,幫助你理解Git的工作原理。

20 分鐘教你搞懂 Git!(git-)

1.初始化

讓我們創(chuàng)建一個(gè)項(xiàng)目的目錄,然后進(jìn)入該目錄。

$ mkdir git-demo-project$ cd git-demo-project

如果想管理項(xiàng)目的版本,那么我們應(yīng)該做的第一件事情就是通過git init初始化。

$ git init

git init只做了一件事情,那就是在項(xiàng)目的根目錄下創(chuàng)建.git子目錄來保存版本信息。

$ ls .gitbranches/configdescriptionHEADhooks/info/objects/refs/

上述命令顯示了.git子目錄中的內(nèi)容。

2.保存對象

接下來讓我們創(chuàng)建一個(gè)新的空文件test.txt。

$ touch test.txt

然后把這個(gè)文件添加到Git代碼庫中,這一步將創(chuàng)建test.txt現(xiàn)有內(nèi)容的一個(gè)副本。

$ git hash-object -w test.txte69de29bb2d1d6434b8b29ae775ad8c2e48c5391

在上述代碼中,git hash-object命令將test.txt現(xiàn)有的內(nèi)容壓縮成二進(jìn)制文件,并保存到Git中。該壓縮文件叫做Git對象,保存在.git/objects目錄中。

我們可以通過這個(gè)命令根據(jù)對象的文件名獲取當(dāng)前內(nèi)容,并計(jì)算成SHA1 哈希(長度為40的字符串)。讓我們看看下列新生成的Git對象文件。

$ ls -R .git/objects.git/objects/e6:9de29bb2d1d6434b8b29ae775ad8c2e48c5391

如上述代碼所示,.git/objects目錄下又多出了一個(gè)子目錄,而且這個(gè)子目錄名是上述哈希值的前兩個(gè)字符。在這個(gè)子目錄下有一個(gè)文件,文件名是上述哈希值中其余的38個(gè)字符。

讓我們再來看看文件內(nèi)容。

$ cat .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391

上述代碼輸出的文件內(nèi)容是一些二進(jìn)制字符。你可能會(huì)問既然test.txt是空文件,又怎么會(huì)有這些內(nèi)容呢?這是因?yàn)樵摱M(jìn)制對象中還存儲(chǔ)了一些元數(shù)據(jù)。

如果你想看看該文件原始的文本內(nèi)容,那么應(yīng)該使用git cat-file。

$ git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

因?yàn)樵募榭?,所以上述命令什么都沒有顯示?,F(xiàn)在我們往test.txt文件中寫點(diǎn)東西。

$ echo ‘hello world’ > test.txt

這個(gè)文件的內(nèi)容已經(jīng)改變了,所以你需要再次把它保存為Git對象。

$ git hash-object -w test.txt3b18e512dba79e4c8300dd08aeb37f8e728b8dad

如上述代碼所示,test.txt的哈希值已經(jīng)隨著文件內(nèi)容的改變而發(fā)生了變化。同時(shí)還生成了新文件.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad?,F(xiàn)在你可以看到這個(gè)文件的內(nèi)容了。

$ git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dadhello world

3.更新索引

當(dāng)文件保存成二進(jìn)制對象以后,你需要告訴Git哪個(gè)文件發(fā)生了變化。Git會(huì)在一個(gè)名叫“索引”(或階段)的區(qū)域記錄所有發(fā)生了變化的文件。然后等到所有的變更都結(jié)束后,將索引中的這些文件一起寫入正式的版本歷史記錄中。

$ git update-index –add –cacheinfo 100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad test.txt

上述命令記錄了文件名test.txt、二進(jìn)制對象名(哈希值)以及索引中文件的訪問權(quán)限。

git ls-files命令可以顯示索引中當(dāng)前的內(nèi)容。

$ git ls-files –stage100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 test.txt

上述代碼顯示索引中只有一個(gè)test.txt文件,還顯示了該文件的二進(jìn)制對象名和訪問該文件的權(quán)限。如果你知道該二進(jìn)制對象名,就可以查看.git/objects子目錄中該文件的內(nèi)容。

git status命令可以輸出更多可讀的結(jié)果。

$ git statusChanges to submit: The new file: test.txt

上述代碼顯示索引中只有一個(gè)新文件test.txt,該文件正在等候?qū)懭氚姹镜臍v史記錄中。

4.git add命令

針對每個(gè)文件執(zhí)行上述兩個(gè)步驟非常繁瑣。所以Git提供了git add命令來簡化這些操作。

$ git add –all

上述命令相當(dāng)于針對當(dāng)前項(xiàng)目中所有發(fā)生了變化的文件執(zhí)行上述兩個(gè)步驟。

5.提交(Commit)

索引保存發(fā)生了變化的文件信息。等到修改完成,所有這些信息都會(huì)被寫入版本的歷史記錄中,這相當(dāng)于生成一個(gè)當(dāng)前項(xiàng)目的快照。

項(xiàng)目的歷史記錄由不同時(shí)間點(diǎn)的項(xiàng)目快照組成。Git可以將項(xiàng)目恢復(fù)成任何一個(gè)快照。在Git中“快照”有一個(gè)專門的術(shù)語,即“提交”(commit)。所以生成快照也可以稱之為完成提交。

下列所有“快照”的引用指的都是提交。

6.完成提交

首先,我們需要設(shè)置用戶名和郵件地址。在你保存快照的時(shí)候,Git需要記錄是誰執(zhí)行的提交。

$ git config user.name “username” $ git config user.email “Email address”

接下來,保存現(xiàn)有的目錄結(jié)構(gòu)。在本文的前面我們討論了保存對象只會(huì)保存一個(gè)文件,并不會(huì)記錄文件之間的目錄結(jié)構(gòu)。

git write-tree命令可以根據(jù)當(dāng)前目錄結(jié)構(gòu)生成一個(gè)Git對象。

$ git write-treec3b8bb102afeca86037d5b5dd89ceeb0090eae9d

在上述代碼中,目錄結(jié)構(gòu)保存成了二進(jìn)制對象,而對象的名字是哈希值。它也保存在.git/objects目錄中。

讓我們來看看該文件的內(nèi)容。

$ git cat-file -p c3b8bb102afeca86037d5b5dd89ceeb0090eae9d100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad test.txt

可以看到,當(dāng)前目錄中只有一個(gè)文件test.txt。

這個(gè)所謂的快照就是保存當(dāng)前的目錄結(jié)構(gòu),以及每個(gè)文件相對應(yīng)的二進(jìn)制對象。之前的操作已經(jīng)保存了文件結(jié)構(gòu),所以現(xiàn)在你需要把這個(gè)目錄結(jié)構(gòu)和一些元數(shù)據(jù)一起寫入版本的歷史記錄中。

git commit-tree可以將目錄樹對象寫入到版本的歷史記錄中。

$ echo “first commit” | git commit-tree c3b8bb102afeca86037d5b5dd89ceeb0090eae9dc9053865e9dff393fd2f7a92a18f9bd7f2caa7fa

在上述代碼中,在提交時(shí)你需要提供提交的描述,而且你可以通過echo “first commit”提供提交描述。git commit-tree命令會(huì)根據(jù)元數(shù)據(jù)以及目錄樹生成一個(gè)Git對象。現(xiàn)在,讓我們來看看該對象的內(nèi)容。

$ git cat-file -p c9053865e9dff393fd2f7a92a18f9bd7f2caa7fatree c3b8bb102afeca86037d5b5dd89ceeb0090eae9dauthor jam 1538889134 0800committer jam 1538889134 0800first commit

在上述代碼中,第一行輸出是對應(yīng)于該快照的目錄樹對象,而第二行和第三行是有關(guān)作者和提交者的信息,最后一行內(nèi)容是提交的描述。

通過git log命令我們還可以查看某個(gè)快照的信息。

$ git log –stat c9053865e9dff393fd2f7a92a18f9bd7f2caa7facommit c9053865e9dff393fd2f7a92a18f9bd7f2caa7faAuthor: jam Date: Sun Oct 7 13:12:14 2018 0800 first commit test.txt | 1 1 file changed, 1 insertion( )

7.git commit命令

Git提供了git commit來簡化上述提交操作。在保存到索引后,你只需要執(zhí)行g(shù)it commit命令,就可以同時(shí)提交目錄結(jié)構(gòu)和描述,并生成快照。

$ git commit -m “first commit”

另外,還有兩個(gè)命令也非常實(shí)用。

通過git checkout命令,我們可以切換到某個(gè)快照。

$ git checkout c9053865e9dff393fd2f7a92a18f9bd7f2caa7fa

通過git show命令,我們可以顯示某個(gè)快照的所有代碼變更。

$ git show c9053865e9dff393fd2f7a92a18f9bd7f2caa7fa

8.分支(branch)

然而,如果你使用git log命令來查看整個(gè)版本的歷史記錄時(shí),卻無法看到剛剛生成的快照。

$ git log

上述命令輸出為空。這是為什么?這個(gè)快照剛剛不是寫入到歷史記錄中了嗎?

真相是:git log命令只可以顯示當(dāng)前分支上的變化。盡管我們已經(jīng)提交了這個(gè)快照,但是還沒有記錄這個(gè)快照屬于哪個(gè)分支。

分支是快照的指針,分支的名字就是該指針的名字。雖然哈希值不可讀,但是分支允許用戶給快照起別名。另外,分支還會(huì)自動(dòng)更新,如果當(dāng)前分支是一個(gè)新的快照,那么這個(gè)指針會(huì)自動(dòng)指向它。例如,主分支(master branch)有一個(gè)名為master的指針指向主分支當(dāng)前的快照。

用戶可以為任何快照創(chuàng)建新指針。例如,如果你想創(chuàng)建一個(gè)新的fix-typo分支,那么只需創(chuàng)建一個(gè)名為fix-typo的指針,并指向一個(gè)快照。因此,在Git中創(chuàng)建一個(gè)新分支非常容易,而且開銷非常低。

Git有一個(gè)特殊的指針HEAD,它始終指向當(dāng)前分支中最新的那個(gè)快照。另外,Git還提供了快捷方式。例如,HEAD^指向HEAD之前的快照(父節(jié)點(diǎn)),而HEAD~6指向HEAD之前的第六個(gè)快照。

每個(gè)分支的指針都是一個(gè)文本文件,存儲(chǔ)在.git/refs/heads/目錄中。文件的內(nèi)容是它指向的快照的二進(jìn)制文件名(哈希值)。

9.更新分支

下面我們將演示如何更新分支。首先,修改test.txt。

$ echo “hello world again” > test.txt

然后保存二進(jìn)制對象。

$ git hash-object -w test.txtc90c5155ccd6661aed956510f5bd57828eec9ddb

接下來,將該對象寫入索引,并保存目錄結(jié)構(gòu)。

$ git update-index test.txt$ git write-tree1552fd52bc14497c11313aa91547255c95728f37

最后,提交目錄結(jié)構(gòu),并生成一個(gè)快照。

$ echo “second commit” | git commit-tree 1552fd52bc14497c11313aa91547255c95728f37 -p c9053865e9dff393fd2f7a92a18f9bd7f2caa7fa785f188674ef3c6ddc5b516307884e1d551f53ca

在上述代碼中,我們可以通過git commit-tree命令的參數(shù)-p來指定父節(jié)點(diǎn),即以哪個(gè)快照為基礎(chǔ)。

下面我們把快照的哈希值寫入到.git/refs/heads/master文件中,并讓master指針指向該快照。

$ echo 785f188674ef3c6ddc5b516307884e1d551f53ca > .git/refs/heads/master

現(xiàn)在,通過git log命令你可以看到兩個(gè)快照了。

$ git logcommit 785f188674ef3c6ddc5b516307884e1d551f53ca (HEAD -> master)Author: jam Date: Sun Oct 7 13:38:00 2018 0800 second commitcommit c9053865e9dff393fd2f7a92a18f9bd7f2caa7faAuthor: jam Date: Sun Oct 7 13:12:14 2018 0800 first commit

git log命令的運(yùn)行過程大致如下:

  • 找到HEAD指針對應(yīng)的分支。在上述示例中為master。
  • 找到master指針指向的快照。在上述示例中為785f188674ef3c6ddc5b516307884e1d551f53ca。
  • 找到父節(jié)點(diǎn)(即前一個(gè)快照)c9053865e9dff393fd2f7a92a18f9bd7f2caa7fa。
  • 等等,最后顯示當(dāng)前分支中所有的快照。

另外,上述我們曾提到分支指針是動(dòng)態(tài)的,下述三個(gè)命令會(huì)自動(dòng)覆蓋分支指針。

  • Git commit:當(dāng)前分支的指針將移動(dòng)到新創(chuàng)建的快照上。
  • Git pull:在當(dāng)前分支和遠(yuǎn)程分支合并后,指針會(huì)指向新創(chuàng)建的快照。
  • Git reset [commit_sha]:當(dāng)前分支的指針將被復(fù)位到某個(gè)指定的快照上。

原文:https://www.tutorialdocs.com/article/how-git-works.html

作者:Alex

譯者:彎月,責(zé)編:郭芮

相關(guān)新聞

聯(lián)系我們
聯(lián)系我們
公眾號
公眾號
在線咨詢
分享本頁
返回頂部
绵阳市| 烟台市| 闽清县| 岐山县| 东山县| 沙田区| 临清市| 曲靖市| 东山县| 昌平区| 环江| 利辛县| 英山县| 古丈县| 拉孜县| 盱眙县| 万荣县| 嘉义县| 固安县| 临武县| 新晃| 漳州市| 睢宁县| 顺昌县| 扎囊县| 南昌县| 绥芬河市| 祁门县| 南江县| 玉环县| 博客| 邓州市| 新余市| 于都县| 达孜县| 灌阳县| 静乐县| 遵义市| 久治县| 金寨县| 临江市|