大家好,歡迎來到週一git專題。
git clone
在上一篇文章當中我們聊了怎麼在github當中建立一個屬於自己的專案(repository),簡稱repo。除了建立自己的repo之外,我們更多的情況是拷貝別人的repo,這樣才可以獲得別人整理好的程式碼資料什麼的,也更符合開源(白嫖)精神嘛。
這也不是什麼難題,相信很多人都知道,當我們想要獲取其他人的repo的時候,可以通過git clone命令進行拉取。比如你想要獲取我們這個教程的repo,可以通過下面這個命令。
git clone git@github.com:moutsea/git-tutorial.git
這個命令我們都知道,通過git clone再加上repo的地址就可以了。但是這裡的地址是哪裡來的呢?簡單介紹一下,這是在github當中找到的。我們點選Code那個綠色按鈕,在下方的彈框裡點選一下,就可以複製下來。一般情況下我們預設使用SSH協議,如果你看過我們上篇文章的話,你一定知道我在說什麼。當然你也可以用HTTPS。
還有一個問題是我們clone下來的這個repo它存在哪裡呢?答案也很簡單,就是我們在哪裡執行的命令它就存在哪裡。
另外再說一個小技巧,我們這樣clone下來之後會在我們本地新建一個資料夾,然後把這個repo當中的內容存在裡面。這個資料夾的名字預設是這個repo的名字,如果你不喜歡這個名字,也可以在命令當中進行設定,設定的方法也很簡單,就是在命令最後加上一個你想要起的名字。
比如這樣,你得到的資料夾就是TechFlow。
git clone git@github.com:moutsea/git-tutorial.git techflow
git 四大狀態
即使是git新手應該也都知道git三板斧,也就是常說的git add,git commit和git push。但是當我們使用這些命令的時候,有沒有想過我們為什麼要用這些命令呢?它們究竟代表了什麼含義,這麼做的意義是什麼,如果我們不這麼幹又會發生什麼?
如果我只是簡單地告訴你git add就是新增,git commit就是提交,那麼其實一點用也沒有,和沒說一樣。因為關於git底層的執行機制一點也沒提,我們也不知道為什麼要新增,要提交,提交了新增了意味著什麼。所以要解釋清楚git這三板斧的原理,需要我們做一些更細緻地解釋,至少需要把git內部的四個狀態講清楚。
在我們進行這一段之前,首先和大家明確一個概念,就是git系統和我們計算機當中的檔案系統其實是兩碼事。雖然git有很多神奇的操作,可以自由地回滾或者是建立檔案,但它們依然是兩套系統。git並不會自發地感知檔案系統當中檔案的變更,除非我們執行相關的命令。可以理解為它是被動響應的,畢竟git只是我們安裝的一個軟體,並不是作業系統的一部分。
這一點看似是廢話,但是是很重要的基礎,如果沒搞明白,後面會產生很多疑惑。
我們繼續來說git內部的狀態,這四個狀態分別是untrack,modified,committed和staged。之所以用英文,是為了大家以後閱讀其他文件不會產生歧義。因為大家翻譯的譯名可能有多個版本,這會導致歧義。下面來簡單介紹一下這幾個狀態分別意味著什麼。
untrack
首先是untrack,untrack我們直譯就可以了。track有軌道以及記錄的意思,所以untrack就是還沒記錄。那麼什麼樣的東西是還沒記錄的呢?比如可以想到新生兒,剛出生的新生兒名字都沒有,當然也沒有記錄在案,所以需要登記一下人口。那麼在登記之前,就可以認為這些新生兒是untrack的。
遷移到開發當中來,我們新建立的檔案其實就是系統裡的“新生兒”。在我們將它們記錄在案之前,它們的狀態就是untrack。所以當你在一個git專案當中新建了檔案的時候,如果你用git status命令去檢視git當中的狀態,就會看到系統會提示你有些檔案狀態是untrack。
這裡的展示是亂碼,是因為我用的中文。這一串亂碼就是“第三篇”的意思。我們可以注意到,在輸出的結果最後一行,系統提示我們可以用git add命令來track它。這個也是git很人性化的一點,很多時候它會提醒我們可以使用什麼命令做成什麼樣的事情。所以大家千萬不要忽視這些日誌,裡面的資訊是很重要的。
modified
下一個說的狀態是modified,modified顧名思義就是修改過的意思。針對的就是已經登記在案的檔案最近又發生了改動的情況,也就是說我們最近改過了某一個之前已經登記在案的檔案,那麼當我們檢視狀態的時候得到的就是modified,表示改動了,之前的記錄已經不是最新的了,我們需要更新。
同樣,我們可以通過git status命名來檢視modified的情況。
我們看最下方的紅字,它說的是“第三篇”這個檔案我們已經有了新的改動,可以使用git add命令來將它更新,或者是使用git restore命令來取消這個檔案的登記資訊,也就是讓他回到“新生兒”的狀態。
staged
接下來介紹的狀態是staged,它沒有很好的翻譯,可以大概理解成暫存。也就是說我們把所有的改動都記錄下來了,現在git系統當中記錄的已經是這個檔案最新的狀態了。
當我們建立了新的檔案,或者是有了新的改動,執行git add之後,得到的狀態就是staged。這個時候當我們執行git status,就會看到我們當下建立和更新了哪些檔案。注意在所有的改動都暫存的情況下,git status是不會出現紅色的提示的,只會有綠色的提示資訊。
當然這裡的文字之所以有顏色是因為我使用了zsh這個終端,如果不配置是沒有的,就只能看到白色的的文字。zsh這個終端只在Linux和MacOS當中有,windows沒有。而win的終端和系統一直被程式設計師們吐槽難用,建議有條件的同學可以研究一下Linux,裝個虛擬機器也好。
當我們終端沒有顏色高亮的時候,就只能通過上面的文字來判斷了,如果出現了Untracked files或者是Changes to be committed這些提示語的話,說明你還有改動沒有同步到git當中來,可以通過git add命令完成。
committed
最後講的一個狀態就是committed,這個committed表示的已提交。前面說了staged只是暫存,還沒有真正提交進git系統當中。只有通過命令git commit之後,才算是真正把暫存區的程式碼提交了。經過git commit命令之後,所有被提交的檔案的狀態就是committed。
這個時候如果我們執行git status再來檢視,會看到提示nothing to commit, working tree clean.
這就表示我們所有的改動都已經提交進本地的git倉庫當中了,以後及時我們不小心刪錯了程式碼,或者是做了一些修改。只要本地的git倉庫還在,這些程式碼就都還可以找得回來。一直到這裡為止,我們所有的操作都是離線的,都不需要網路參與。這也是我們前文說的git的一個優點之一。
git commit之後,我們就可以通過git push來把本地的改動同步到遠端了。當然這一步是肯定需要網路的,並且也可能會遇到很多問題,其中也有很多細節,我們之後再詳細展開。
我們用一張圖來總結一下上面提到四種狀態,以及git的整個工作流來加深一下印象。
總結
看完了上面關於git狀態的介紹之後,想必大家就可以明白,我們在使用git的時候,最常用的三板斧也就是git add,git commit以及git push的命令究竟是幹嘛的了。
git add可以把所有的改動,無論是修改的還是新建的都存入暫存區。git commit可以將暫存區的改動提交到本地git倉庫,最後git push可以把本地倉庫的改動同步到遠端。看起來好像平平無奇對吧,但我們仔細琢磨會發現一個很奇怪的點,那就是既然我們git add和git commit都是提交,只不過是提交的目的地不同,一個是暫存區一個是本地倉庫。那麼為什麼我們不能直接將它們合併呢?我們git add就是直接提交到本地倉庫不行嗎?
實際上SVN這個版本控制工具就是這麼做的,但是這有一個問題就是當我們提交的時候,它會讓我們選擇我們要提交的檔案。如果改動量小還好,如果改動量很大,我們要手動去一個一個輸入需要提交的檔案顯然是一個非常麻煩的事情。而有了暫存區之後,我們就可以在開發的時候,一邊開發一個邊把檔案提交到暫存區,最後直接一起commit到倉庫就可以了。就可以避免最後提交之前的麻煩了,因為反正提交這個操作一定是原子的,要麼全部成功,要麼全部失敗,是不允許部分成功這種情況發生的。
而且很多極客更加喜歡在終端環境當中操作程式碼,而不是在一個彈出來的介面裡點點點,這會讓他們覺得非常不極客(逼格太低)。有了暫存區之後就可以很方便地做到這一點。
到這裡,我們的文章就結束了,感謝您的閱讀。相信看完之後,對於git當中的狀態以及它們的作用應該有了一個基礎的瞭解,並且應該還學到了一個裝逼技能,就是問你的小夥伴,你知道為什麼git裡有一個暫存區而SVN裡沒有嗎?因為不極客。
衷心祝願大家每天都有所收穫。如果還喜歡今天的內容的話,請來一個三連支援吧~(點贊、在看、轉發)
本文使用 mdnice 排版
- END -