git原理剖析,站在git的設計者角度去思考git的操作

上一篇講解了IDEA中的git操作看這一篇就夠了

這篇側重原理講解:

git是開發者必需掌握的技能之一,在日常的使用過程中,經常有一些小白由於對git的原理沒有喫透,經常會出現一些坑隊友的操作。

對於初識git的開發者,簡單的認爲git就是提交代碼到倉庫。

在看完這一篇博客後、重新認識git。掌握git的核心原理

如果我寫的好,希望給個小星星,加個關注。

git的誕生緣由 

比如:

  1. 程序的某一行代碼被多人修改(在自己的電腦上修改)進行合併代碼?----多人寫代碼合併代碼難題
  2. 程序員A由於電腦宕機,寫的代碼丟失了。-------代碼丟失問題
  3. 程序員A想對之前寫的程序進行優化,然後直接修改代碼,結果程序跑不起來了。如果重新修改回去也比較麻煩,而且也記不起來修改了那些,以及修改前的代碼--------代碼無法回滾
  4. 等....

就前面3個問題任意一個一個問題,如果在自己頭上,都會抓耳撓腮,異常煩惱。

git原理剖析

在將一個項目進行版本控制後,git會在項目中創建一個.git的隱藏文件夾,下面和我一樣顯示隱藏文件夾

會看到一個.git文件夾,裏面存放的就git相關的數據

完成上面操作後,我將帶着大家一起去挖掘git,去思考創造git的作者是怎麼思考問題的

下面請和我一起去思考下面這些問題 

拋出第一個問題

當我們修改了代碼後,git如何去檢測到代碼進行了修改?

如果讓你來設計一個程序來檢測一個文件代碼有沒有修改,你改如何去設計?

請發揮自己的想象,暫停閱讀然後去思考一下這個問題。

大膽發揮想象,錯了沒有關係,注重思考問題的過程,一個好的解決方案往往是經過反覆推敲誕生的。

比如:

      文件狀態(時間,文件大小等)、文件中的代碼等

 

  1. 時間:可能我兩個時間的代碼是一樣的,這樣等於代碼沒有進行修改
  2. 文件大小:這個也不能解決問題,因爲可能我文件的大小是一樣的,但是裏面的字符我實際上是修改過的。這樣根本檢測不到文件代碼是否被修改過。

文件代碼:這個好理解,如果我檢測到代碼發生變化自然就是變化了,哪如何檢測代碼發生改變了呢

聯想到一些加密算法,比如md5、比如SHA-1、比如SHA-256等Hash算法。

這些加密算法可以將一串字符串算出另一個字符串,如果修改前的字符串和修改後進行算法後得到的字符串兩個進行比較,如果不同,自然代碼是進行了修改了。

顯然md5不合適,因爲md5可能得到同一個字符串。

SHA-1:git實際真正採用的算法就是SHA-1,哪也就是說我可以通過hash算法中的SHA-1將文件進行一次運算,會得到一個hash值,當我修改了代碼,我將修改後的文件進行sha-1運算會得到一個新的hash值,然後比較兩個hash值是否是一樣的

如果是一樣的則說明文件中的代碼沒有進行修改

如果hash不一樣,則說明文件的代碼進行了修改

到此第一個問題解決了,就是通過hash算法對文件(文件中的所有字符)進行運算,得到一個唯一的一個hash,如果修改後的代碼運算的hash值是一樣則代碼沒有進行改變,不一樣則說明源文件代碼進行了修改。------說明一下就算是加了一個空格也算是修改了源代碼文件,空格也是一個字符。

既然已經能通過sha-1算法來檢測出代碼是否被修改了

拋出第二個問題

假設有兩個程序員,程序員A和程序員B同時修改代碼提交代碼,如何讓兩個程序員修改的代碼都能得到管理?始終保證倉庫中的代碼是正確的?

案例:

程序員A和程序員B同時從倉庫下拉代碼,他們得到了通一份代碼。

經過一段時間後,兩人都代代碼進行了修改,兩人修改完代碼後都需要將代碼提交到倉庫中。提交總有先後的問題。

假設程序員A先提交了,那麼程序員B能否正確提交?

程序員提交肯定會遭到拒絕,因爲程序員A先將代碼提交上了遠程倉庫,那麼遠程倉庫的代碼已經被修改了,也就是說遠程倉庫中的hash值也變了,程序員B提交的時候,用舊的遠程倉庫hash值比較現在新的hash值。顯而易見肯定不同,自然會遭受到拒絕提交。

那麼程序員B改如何提交呢?

程序員B需要更新一下本地代碼,將服務器的代碼合併到本地,然後將合併後的代碼推送到倉庫中。合併過程就會將新的hash值更新過來。這樣程序員B再次提交的時候就是用新的hash值和同樣的新的hash值比較,匹配則允許你提交。

提交後遠程倉庫的hash值會變成新的hash值,對於程序員A來說如果他需要提交同樣需要合併遠程倉庫的代碼,更新本地的遠程hash值,然後再提交上去。

hash值文件的記錄示例:

在項目的隱藏.git文件夾中有logs文件夾,裏面存放的就是每一次提交是產生的hash值

本地的heads有個master文件如下,用文本編輯器打開查看,如下:

每一次提交就會像這樣比較一下hash值,如果相同才允許提交,CAS算法原理先比較修改前和之前的值比較是否一樣,一樣則允許你修改成新的值。

你會發現每一次提交對這樣右邊的上一行的hash和當前行的前面的一個hash值比較。

程序員A和程序員B同時下拉代碼後得到通一個hash值A1

然後程序員A修改代碼產生一個新的hash值A2

程序員A提交代碼時:它會比較hash值A1 和遠程倉庫中的A1

發現相同提交成功,於是遠程倉庫的hash值變成了A2

 

由於程序員B不知道程序員A提交了代碼,遠程倉庫的hash值變成了A2

程序員修改完代碼後,得到了一個新的hash值A3,而此時他也是拿A1和A2比較

顯然不同自然就會衝突,拒絕提交。

因此需要合併代碼將遠程代碼合併到本地,也就是或程序B將本地的A1更新爲了A2,然後拿A2和A2比較,將A3更新上去

git中的工作區、暫存區、倉庫

工作區:實時修改的代碼文件

倉庫:提交的代碼

暫存區:介於工作區和倉庫之間。相當於漢諾塔中的第三方工具,目的是爲了抽取工作區需要進行版本控制的文件

例如一個項目結構如下:其中框出來的是不需要進行版本控制的文件

工作區中的.idea、target、xxxx.iml文件,如果之間用工作區很難將這些文件去除,加個暫存區就可以將這些去除,然後提交暫存區的文件到倉庫。

 

soft、mixed、hard、keep之間的區別

在使用回滾操作的時候有上面4個選項

如果你還沒有搞懂,我將四個概念總結出來

soft: 

只是修改指針的位置,不修改暫存區的文件,工作區文件不變 。作用是改變提交的軌跡

mixed

改變指針指向、回滾到選擇的倉庫記錄、同時暫存區也會恢復到選擇的記錄。工作區文件不變。

hard

回滾操作會將指針、暫存區、工作區都恢復到選中的倉庫記錄狀態

keep

文件將恢復到所選提交的狀態,但本地更改將保持不變。

(Files will be reverted to the state of the selected commit,but local changes will be kept intact)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章