特別說明:要在個人隨筆後寫評論的小夥伴們請注意了,個人博客開啓了 MathJax 數學公式支持,MathJax 使用
$
標記數學公式的開始和結束。若是某條評論中出現了兩個$
,MathJax 會將兩個$
之間的內容按照數學公式進行排版,從而致使評論區格式混亂。若是你們的評論中用到了$
,可是又不是爲了使用數學公式,就請使用\$
轉義一下,謝謝。html
想從頭閱讀該系列嗎?下面是傳送門:git
我是經過閱讀《Pro Git》這本書學習 Git 的,我讀的時候仍是初版的英文版,如今已經出第二版了,並且英文版和中文版都有。英文第二版的地址是 https://git-scm.com/book/en/v2,中文第二版的地址是https://git-scm.com/book/zh/v2。想看初版的話把地址中的v2
改爲v1
就能夠了。若是哪天忽然連接打不開了,也彆着急,記住《Pro Git》這個招牌,使用搜索引擎很快就能找到它。github
Git 是一個版本控制系統,它能夠保存工做文件的全部修訂版本。有了它你就能夠將某個文件回溯到以前的狀態,甚至將整個項目都回退到過去某個時間點的狀態,你能夠比較文件的變化細節,查出最後是誰修改了哪一個地方,從而找出致使怪異問題出現的緣由,又是誰在什麼時候報告了某個功能缺陷等等。使用版本控制系統一般還意味着,就算你亂來一氣把整個項目中的文件改的改刪的刪,你也照樣能夠輕鬆恢復到原先的樣子。但額外增長的工做量卻微乎其微。數據庫
Git 的特色:編程
下面是我簡化了的 Git 使用小結,圖片都來源於《Pro Git》初版。安全
每個項目都應該有一個工做目錄(Working directory),咱們能夠本身建一個目錄,而後把這個目錄裏面的代碼用 Git 管理起來(使用git init
命令和git add
命令),也能夠經過git clone
命令從別的地方克隆一個項目過來自動生成一個工做目錄。在工做目錄中的文件就是當前編輯和修改的文件,若是是新創建的目錄或新克隆來的目錄,工做目錄中的文件就是該項目最新的狀態。Git 是在本地保存有全部的歷史記錄和分支記錄的,這些內容都在工做目錄的.git
目錄中,稱之爲本地倉庫(local repository)。當切換分支或查看之前的歷史版本時,工做目錄中的文件自動改變(這纔是重點,工做無需切換目錄,目錄中的文件會自動切換)。工做目錄中的文件有三種狀態:已修改(modified)、已暫存(staged)、已提交(committed)。修改後的文件能夠先加入暫存區域,一次工做結束後一塊兒提交。服務器
Git是分佈式的,沒有中心服務器的概念,但實際工做中仍然能夠把代碼倉庫放到一臺你們均可以訪問的服務器上,作實際的中心服務器使用(僅在小團隊時使用此工做流程,緣由後面詳述)。在本地機器上工做完後,使用git push
命令把倉庫推送到服務器上,換一個地方換一臺機器後,只須要git clone
一下,又能夠得到全部的代碼(包含全部的歷史記錄及分支)繼續工做。服務器故障也沒問題,由於每個工做的機器上都保存有完整的代碼倉庫,因此從不用擔憂代碼丟失。沒有網絡也沒有關係,在本地機器上照樣能夠提交(git commit
),由於整個倉庫就在本身的機器上,當有網絡時,git push
一下就能夠了。網絡
Git有遠程倉庫(remote repository)的概念,並且能夠管理不少個遠程倉庫,遠程倉庫能夠是服務器,也能夠是別人的我的計算機(但通常沒有人這麼用),每個遠程倉庫都有一個簡短的名字和一個地址,最開始用git clone
克隆代碼的那個遠程倉庫別名每每默認爲 origin,本身添加的遠程倉庫能夠隨意指定別名,固然全部的遠程倉庫均可以隨意修改別名。能夠從遠程倉庫獲取代碼(git fetch
命令或git pull
命令),也能夠把本身的代碼推送到遠程倉庫(git push
命令,須要寫權限)。eclipse
既然 Git 便可以隨便從遠程倉庫獲取代碼,又能夠把本身的代碼推送到遠程倉庫,那麼當多人協做時,豈不會亂套嗎?解決這個問題的,就是 Git 的必殺之技——建立分支及分支合併。編程語言
首先,隨着一次次的提交,在本地代碼庫中造成一個主分支,以下圖:
有時爲了開發新特性,隨時能夠開一個新分支,以下圖:
新分支和主分支之間能夠隨意切換,隨着分支的發展,形式以下圖:
主分支也能夠向前發展,以下:
最終,當新分支代碼很穩定之後,能夠將其合併到主分支,以下圖:
而可以防止多人協做時出現混亂的關鍵就在於,當從遠程倉庫 clone 代碼庫到本地或 fetch 代碼庫到本地時,遠程分支的標記並不等於本地分支的標記。從遠程 clone 一個代碼庫到本地後,其 master 分支有兩個標記,一個標記爲 origin/master 表示遠程庫中的 master 分支,一個標記爲 master,表示本地的 master 分支。以下圖:
能夠想象,因爲別人的工做,遠程倉庫中的 master 分支確定會向前繼續移動,可是在下次聯網以前,該 origin/master 標記不會移動。而本地的 master 標記繼續向前移動。
直到下次聯網,使用git fetch
命令將遠程倉庫的內容取回本地,origin/master 標記纔會改變位置,這時,看起來就像是兩個分支,以下圖:
最後,將 origin/master 分支合併到 master 分支中(使用git merge
命令),本地代碼庫又一次變成了一個單一的 master 分支,繼續向前開發,並能夠將它 push 到遠程倉庫,供別人使用。
Git衝突的處理徹底靠人工完成。(從邏輯上講,機器也不可能完美處理衝突。)好比一個小型團隊一塊兒工做,他們能夠設置一個服務器用於保存遠程 Git 倉庫,而後每一個人工做以前先從該遠程倉庫 fetch 代碼,接着工做,工做完成後,先在本地提交,最後 push 到遠程倉庫。可是當一我的 push 的時候,已經有人在他以前 push 了,若是他們工做在同一個分支,就會出現衝突。解決衝突的辦法就是先把別人 push 的內容再次 fetch 下來,合併分支,而後再 push。
經過前面對git原理的瞭解,能夠分析得出使用Git時有如下幾種工做流程:
Git 服務器的建設也至關簡單,由於 Git 支持以 SSH、HTTP 等協議傳輸數據,若是須要對服務器有寫權限,就開通 SSH 服務吧,設一個帳戶供全部人訪問 Git 倉庫便可。若是隻須要讀權限,使用任何一個 HTTP 服務器都可。關於 Git 服務器的建設,請自行參考官方文檔。若是是我的的、開源的項目,可使用 Github 網站提供的服務,直接存儲在互聯網上。(Github 私人倉庫是要收錢的。)
得益於 Eclipse 中的 EGit 插件,在 Eclipse 中使用 Git 很是簡單。任何一個項目,均可以使用快捷菜單中的 "Team" -> "Share Project" 將文件交給版本控制軟件管理,以下圖:
如今最流行的版本控制軟件固然是非 Git 莫屬了。Eclipse 會提示咱們建立一個 Git 倉庫(Repository)。Eclipse 中的項目(Project)是一個比較小的概念,它不能等同於 Git 中的工做目錄(Working Directory),Git 中也沒有項目的概念,可是在 Git 的工做目錄中管理多個文件夾是沒有什麼問題的,而 Eclipse 中的項目就是一個文件夾,因此,在 Git 的一個工做目錄中管理多個 Project 是沒有問題的。所以,只有 Eclipse 的工做區(Workspace)纔等同於 Git 中的工做目錄(Working Directory)。而 Git 的倉庫(Repository)通常是放在 Git 工做目錄中的一個.git
目錄,考慮到 Eclipse 的工做區(Workspace)中原本就已經包含了不少元數據,再在裏面建立一個.git
目錄,而且在裏面存放 Git 的數據容易引發混亂,所以最好是把 Git 的工做目錄和倉庫建立在 Eclipse 的 Workspace 以外。幸虧,Eclipse 支持這樣的功能。以下圖,點擊 "Create" 按鈕,建立一個 Git 倉庫,這裏輸入的路徑/home/youxia/git/samples
實際上是一個工做目錄:
從下圖能夠看出,工做目錄爲/home/youxia/git/samples
,Git 的倉庫爲/home/youxia/git/samples/.git
,本來在 Workspace 中的項目 JavaIODemo 被自動移到了/home/youxia/git/samples
目錄中:
可使用 Navigator 視圖查看項目中全部的文件,沒有被 Git 跟蹤的文件其圖標中顯示一個小問號。可使用 "Ignore" 菜單項讓 Git 忽略對某些文件的跟蹤,好比源代碼編譯後產生的類文件,以下圖:
使用 "Add to Index" 菜單項讓 Git 對那些須要進行版本控制的文件進行跟蹤,以下圖:
進行提交,以下圖:
提交時需輸入 Commit Message,並指定 Author 和 Committer,能夠查看這次提交涉及哪些文件。以下圖:
已提交的文件其圖標又會發生變化,以下圖:
再來看一下在一個倉庫中管理多個項目。再建立兩個項目,JaasDemo 和 SecurityDemo,點擊菜單項 "Share Project",在彈出的對話框中,再也不選擇建立倉庫,而是選擇現有的倉庫,以下圖:
操做完成後,這三個項目都被同一個 Git 倉庫所管理。再有更多的項目均可以添加到這個倉庫中。我在 Github 中註冊了一個帳號,youxia 這個用戶名已經被佔用了,因此我只能用 youxia-cn,cn 表明中國,其實這個帳號挺好記的。而後,我又建立了一個 samples 倉庫,用來存放我博客中寫的源代碼。之後你們須要參看個人源代碼的時候,只須要訪問 https://github.com/youxia-cn/samples 就能夠了。
最後,把我本地的倉庫推送(Push)到 Github 中,以下三圖:
從遠程倉庫中獲取數據的方法有多種。若是是第一次獲取遠程倉庫,可使用git clone
命令。在 Eclipse 中,須要使用 "File" -> "Import" 功能。下面換一臺電腦,這臺電腦安裝的是 Ubuntu 系統,啓動 Eclipse,點擊菜單 "File" -> "Import",獲取剛纔存放在 Github 中的項目,在彈出的對話框中輸入正確的 URL 後,一路 Next,以下動圖:
可使用 "Show in History" 和 "Show in Repositories View" 查看倉庫的詳細信息,以下兩圖:
從遠程倉庫獲取數據還可使用git pull
命令,其對應的 GUI 操做界面以下:
能夠看到,它會讓你選擇是將遠程倉庫中的分支 Merge 到本地的當前分支仍是將本地的當前分支 Rebase 到遠程倉庫中的分支。使用 Pull 功能時,分支的 Merge 和 Rebase 是自動進行的,因此若是沒有準備好的話,不要輕易使用。
安全的作法是使用git fetch
命令從遠程倉庫獲取數據。Fetch 過來的分支不會自動合併,你能夠切換到這些分支進行查看,而後手工進行合併。其操做界面以下:
前面介紹過,隨着 Git 一次次的提交,會造成一個主分支,除此以外,還能夠建立新的分支。經過git branch
命令建立新分支,經過git checkout
命令切換分支。在 Git 中,有一個HEAD
指針老是指向當前正在工做的分支,以下圖:
若是切換分支,HEAD
指針也會隨着移動,以下圖:
同時,還可使用git reset
命令改變HEAD
指針的指向,以達到撤銷操做的目的。隨意改變HEAD
指針的指向是危險的,特別是使用git reset
命令的--hard
選項的話,它會使咱們的部分工做丟失。在《Pro Git》的第二版中專門有一節「重置揭祕」對該命令及其涉及的原理進行了論述。在 GUI 中使用 Reset 也是很是簡單的,以下圖:
而分支的合併又有兩種方式,Merge 和 Rebase。Merge 比較簡單,以下圖:
在圖中有兩個分支 origin 和 mywork,origin 作了提交 C3 和 C4,mywork 作了提交 C5 和 C6。若是將這兩個分支合併的話,就會產生提交 C7,以下圖:
可是若是使用 Rebase 就不同了,若是把 mywork 分支 Rebase 到 origin 上,就至關於把 C5 和 C6 中針對 C2 所作的修改在 C4 上重演一次,產生了 C5' 和 C6' 兩次提交,而原有的 C5 和 C6 會被丟棄,以下圖:
因此,Reset 和 Rebase 都是比較危險的命令,有引發數據丟失的風險。可是在 Git 中,只要是曾經 Commit 過的數據,都是能夠找回來的,能夠參考《Pro Git》中「維護與數據恢復」這一節(初版位於第 9 章,第二版位於第 10 章)。另外,《Pro Git》提到,對於已經公開發布到遠程倉庫中的代碼,不要使用 Rebase,不然會引發版本庫的混亂。
GUI 界面的使用沒有什麼困難的,難的是理解 Git 中的概念,好比 Push、Pull、Clone、Fetch、Checkout、Reset、Merge、Rebase 什麼的。學習 Git 最好的辦法,固然是認真閱讀《Pro Git》這本寶典。除了使用 GUI,最好也能多敲一下命令行,這樣對 Git 會有更加深刻的瞭解。
我對此次寫的這個系列要求是很是高的:首先內容要有意義、夠充實,信息量要足夠豐富;其次是每個知識點要講透徹,不能模棱兩可含糊不清;最後是包含豐富的截圖,讓那些不想裝 Linux 系統的朋友們也能夠領略到 Linux 桌面的風采。若是個人努力獲得你們的承認,能夠掃下面的二維碼打賞一下:
該隨筆由京山遊俠在2018年11月15日發佈於博客園,引用請註明出處,轉載或出版請聯繫博主。QQ郵箱:1841079@qq.com