崩潰!實習(xí)生把小組的代碼倉庫搞得一團糟。。。
大家好,我是二哥呀!
對于剛參加工作的新手來說,Git 操作確實容易給代碼的版本庫帶來一些不必要的混亂,畢竟大學(xué)的時候,學(xué)習(xí)的重點在編程語言上,在計算機基礎(chǔ)上。可一旦參加了工作,就必須得在代碼版本庫上狠下一番功夫了,畢竟要多人運動啊,不,多人協(xié)作啊。
恰好二哥最近在連載 Git 方面的一系列文章,這篇就來手把手地教大家重溫一下 Git 的基本使用。嗯,我聞到了收藏夾吃灰的味道~
一、創(chuàng)建倉庫
倉庫,也就是 repository,可以簡單理解為一個目錄,這個目錄里面的所有文件都將被 Git 管理起來,每個文件的一舉一動,都將被 Git 記錄下來,以便在任何時刻進行追蹤和回滾。
新建一個文件夾,比如說 testgit,然后使用 git init 命令就可以把這個文件夾初始化為 Git 倉庫了。

初始化Git 倉庫成功后,可以看到多了一個 .git 的目錄,沒事不要亂動,免得破壞了 Git 倉庫的結(jié)構(gòu)。
接下來,我們來新增一個文件 readme.txt,內(nèi)容為“老鐵,記得給二哥三連啊”,并將其提交到 Git 倉庫。
第一步,使用 git add 命令將新增文件添加到暫存區(qū)。
第二步,使用 git commit 命令告訴 Git,把文件提交到倉庫。

可以使用 git status 來查看是否還有文件未提交。
也可以在文件中新增一行內(nèi)容“傳統(tǒng)美德不能丟,記得點贊哦~”,再使用 git status 來查看結(jié)果。

如果想查看文件到底哪里做了修改,可以使用 git diff 命令:

確認修改的內(nèi)容后,可以使用 git add 和 git commit 再次提交。
二、版本回滾
再次對文件進行修改,追加一行內(nèi)容為:“xxx,我愛你?”,并且提交到 Git 倉庫。
現(xiàn)在我已經(jīng)對 readme.txt 文件做了三次修改了。可以通過 git log 命令來查看歷史記錄:

也可以通過 gitk 這個命令來啟動圖形化界面來查看版本歷史。

如果想回滾的話,比如說回滾到上一個版本,可以執(zhí)行以下兩種命令:
1)git reset --hard HEAD^,上上個版本就是 git reset --hard HEAD^^,以此類推。
2)git reset --hard HEAD~100,如果回滾到前 100 個版本,用這個命令比上一個命令更方便。

那假如回滾錯了,想恢復(fù),不記得版本號了,可以先執(zhí)行 git reflog 命令查看版本號:

然后再通過 git reset --hard 命令來恢復(fù):

三、工作區(qū)和暫存區(qū)的區(qū)別
工作區(qū)和暫存區(qū)的概念其實在前面的章節(jié)里強調(diào)過了,但考慮到有些小伙伴在 git add 和 git commit 命令之間仍然有一些疑惑,我們這里就再強調(diào)一次——學(xué)習(xí)知識就是這樣,只有不厭其煩地重復(fù),才能真正地理解和掌握。
1)工作區(qū),比如說前面提到的 testgit 目錄就屬于工作區(qū),我們操作的 readme.txt 文件就放在這個里面。
2)暫存區(qū),隱藏目錄 .git 不屬于工作區(qū),它(Git 倉庫)里面存了很多東西,其中最重要的就是暫存區(qū)。
Git 在提交文件的時候分兩步,第一步 git add 命令是把文件添加到暫存區(qū),第二步 git commit 才會把暫存區(qū)的所有內(nèi)容提交到 Git 倉庫中。
“為什么要先 add 才能 commit 呢?”
最直接的原因就是Linus 搞了這個“暫存區(qū)”的概念。那為什么要搞這個概念呢?沒有暫存區(qū)不行嗎?
嗯,要回答這個問題,我們就需要追本溯源了。
在 Git 之前, SVN 是代碼版本管理系統(tǒng)的集大成者。SVN 比之前的 CVS 更優(yōu)秀的一點是,每次的提交可以由多個文件組成,并且這次提交是原子性的,要么全部成功,要么全部失敗。
原子性帶來的好處是顯而易見的,這使得我們可以把項目整體還原到某個時間點,就這一點,SVN 就完虐 CVS 這些代碼版本管理系統(tǒng)了。

Git 作為逼格最高的代碼版本管理系統(tǒng),自然要借鑒 SVN 這個優(yōu)良特性的。但不同于 SVN 的是,Git 一開始搞的都是命令行,沒有圖形化界面,如果想要像 SVN 那樣一次性選擇多個文件或者不選某些文件(見上圖),還真特喵的是個麻煩事。
對于像 Linus 這種天才級選手來說,圖形化界面無疑是 low 逼,可命令行在這種情況下又實在是麻煩~
嗯,怎么辦呢?
神之所以為神,就是他能在遇到問題的時候想到完美的解決方案——搞個暫存區(qū)不就完事了?
暫存區(qū)可以隨意地將各種文件的修改放進去,只需要通過 git add 這種簡單的命令就可以精心地挑選要提交哪些文件了,然后再一次性(原子性)的 git commit 到版本庫,所有的問題都迎刃而解嘛。
我們在 testgit 目錄下再新增一個文件 readyou.txt,內(nèi)容為“二哥,我要和你約飯~~~”;并且在 readme.txt 文件中再追加一行內(nèi)容“點贊、在看、留言、轉(zhuǎn)發(fā)一條龍服務(wù)~”。
我們先用 git status 命令查看一下狀態(tài),再用 git add 將文件添加到暫存區(qū),最后再用 git commit 一次性提交到 Git 倉庫。

四、撤銷修改
現(xiàn)在,我在 readyou.txt 文件中追加了一行內(nèi)容:“二哥,我想和你約會~~~”。在我想要提交的時候,突然發(fā)現(xiàn)追加的內(nèi)容有誤,我得恢復(fù)到以前的版本,該怎么辦呢?
1)我知道要修改的內(nèi)容,直接修改,然后 add 和 commit 覆蓋。
2)我忘記要修改哪些內(nèi)容了,通過 git reset -- hard HEAD 恢復(fù)到上一個版本。
還有其他辦法嗎?
答案當然是有了,其實在我們執(zhí)行 git status 命令查看 Git 狀態(tài)的時候,結(jié)果就提示我們可以使用 git restore 命令來撤銷這次操作的。

那其實在 git version 2.23.0 版本之前,是可以通過 git checkout 命令來完成撤銷操作的。

checkout 可以創(chuàng)建分支、導(dǎo)出分支、切換分支、從暫存區(qū)刪除文件等等,一個命令有太多功能就容易讓人產(chǎn)生混淆。2.23.0 版本改變了這種混亂局面,git switch 和 git restore 兩個新的命令應(yīng)運而生。
switch 專注于分支的切換,restore 專注于撤銷修改。

五、遠程倉庫
Git 是一款分布式版本控制系統(tǒng),所以同一個 Git 倉庫,可以分布到不同的機器上。一開始,只有一臺機器和一個原始版本庫,往后去,別的機器就可以從這臺機器上拷貝原始版本,就像黑客帝國里的那個特工史密斯一樣,沒有任何區(qū)別。
這也是 Git 比集中式版本控制系統(tǒng) SVN 特別的地方之一。
我們可以自己搭建一臺每天 24 小時可以運轉(zhuǎn)的 Git 服務(wù)器,然后其他人就從這臺“服務(wù)器”中拷貝就行了。不過,因為 GitHub 的存在,自主搭建 Git 服務(wù)器這個步驟就可以省了。
從名字上就可以看得出來,GitHub 是用來提供 Git 倉庫托管服務(wù)的,我們只需要注冊一個 GitHub 賬號,就可以免費獲取一臺每天可以運轉(zhuǎn) 24 小時的 Git 遠程服務(wù)器。
那其實在 GitHub 上有對應(yīng)的中文幫助文檔,來介紹如何通過 SSH 協(xié)議將本機和 GitHub 鏈接起來,從而不必在每次訪問時提供用戶名和密碼。
https://docs.github.com/cn/authentication/connecting-to-github-with-ssh/about-ssh
第一步,通過 ls -al ~/.ssh 命令檢查 SSH 密鑰是否存在

如果沒有 id_rsa.pub、id_ecdsa.pub、id_ed25519.pub 這 3 個文件,表示密鑰不存在。
第二步,生成新 SSH 密鑰
執(zhí)行以下命令,注意替換成你的郵箱:
ssh-keygen?-t?ed25519?-C?"[email protected]
然后一路回車:

記得復(fù)制一下密鑰,在 id_ed25519.pub 文件中:

第三步,添加 SSH 密鑰到 GitHub 帳戶
在個人賬戶的 settings 菜單下找到 SSH and GPG keys,將剛剛復(fù)制的密鑰添加到 key 這一欄中,點擊「add SSH key」提交。

Title 可不填寫,提交成功后會列出對應(yīng)的密鑰:

為什么 GitHub 需要 SSH 密鑰呢?
因為 GitHub 需要確認是“你本人”在往你自己的遠程倉庫上提交版本的,而不是別人冒充的。
第四步,在 GitHub 上創(chuàng)建個人倉庫
點擊新建倉庫,填寫倉庫名稱等信息:

第五步,把本地倉庫同步到 GitHub
復(fù)制遠程倉庫的地址:

在本地倉庫中執(zhí)行 git remote add 命令將 GitHub 倉庫添加到本地:

當我們第一次使用Git 的 push 命令連接 GitHub 時,會得到一個警告??:
The?authenticity?of?host?'github.com?(20.205.243.166)'?can't?be?established.
ECDSA?key?fingerprint?is?SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM.
Are?you?sure?you?want?to?continue?connecting?(yes/no/[fingerprint])??yes
這是因為需要你手動確認,輸入 yes 即可。
接下來,我們使用 git push 命令將當前本地分支推送到 GitHub。加上了 -u 參數(shù)后,Git 不但會把本地的 master 分支推送的遠程 master 分支上,還會把本地的 master 分支和遠程的master 分支關(guān)聯(lián)起來,在以后的推送或者拉取時就可以簡化命令(比如說 git push github master)。

此時,我們刷一下 GitHub,可以看到多了一個 master 分支,并且本地的兩個文件都推送成功了!

從現(xiàn)在開始,只要本地做了修改,就可以通過 git push 命令推送到 GitHub 遠程倉庫了。
還可以使用 git clone 命令將遠程倉庫拷貝到本地。比如說我現(xiàn)在有一個 3.4k star 的倉庫 JavaBooks,

然后我使用 git clone 命令將其拷貝到本地。

好了好了,關(guān)于 Git 的基本操作,我們就先講到這里,希望能給有需要的讀者一點點幫助和啟發(fā),我們下期見~
為了把 Git 這條線學(xué)好,建議大家把前面 4 個章節(jié)回顧一下:
可能是 Git 歷史上最偉大的一次代碼提交 終于有人把 Git 的數(shù)據(jù)模型講清楚了 昨晚看完 Linus 第一次提交的 Git 代碼后,我失眠了! 要熟練使用 Git,恐怕要記住這60個命令
由于公眾號的文章發(fā)布后不能修改,也沒辦法加個統(tǒng)一的目錄作為索引頁,所以二哥就把《Java 程序員進階之路》的系列文章開源到了 GitHub(點擊閱讀原文可以直接跳轉(zhuǎn)):
https://github.com/itwanger/toBeBetterJavaer
每天看著 star 數(shù)的上漲我心里真的非常的開心,希望越來越多的 Java 愛好者能因為這個開源項目而受益,而越來越多人的 star,也會激勵我創(chuàng)作出更優(yōu)質(zhì)的內(nèi)容~

沒有什么使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不系之舟。
