Linux 桌面玩家指南:13. 使用 Git 及其和 Eclipse 的集成

原文: Linux 桌面玩家指南:13. 使用 Git 及其和 Eclipse 的集成

特別說明:要在個人隨筆後寫評論的小夥伴們請注意了,個人博客開啓了 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 的特色:編程

  1. Git是分佈式的版本控制系統,它沒有中心服務器的概念(雖然實際開發中能夠建一箇中心服務器),每一臺開發機器上都保存完整的歷史記錄;可是它有本地代碼倉庫和遠程代碼倉庫的概念(否則怎麼多人協做?),並且能夠追蹤多個遠程倉庫。
  2. Git 在沒有網的狀況下也能夠工做。Git在本地磁盤上保存有項目的完整歷史,Git 中的絕大多數操做都只須要訪問本地文件和資源,通常不須要來自網絡上其它計算機的信息。因此 Git 可以很是快地創建分支和合並分支,並具備強大的跟蹤分支和切換分支的能力。大部分操做看起來瞬間完成。有網的時候,再向遠程倉庫 push 一下就好了。
  3. Git 通常只添加數據。你執行的 Git 操做,幾乎只往 Git 數據庫中增長數據。 很難讓 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時有如下幾種工做流程:

  1. 一我的單幹,不須要考慮衝突,隨時能夠開分支、合併分支和切換分支,隨時能夠本地提交。若是爲了防止代碼丟失,能夠開一個服務器,每次工做完成就 push 到服務器上;
  2. 小型團隊合做,如前所述,開一個服務器保存代碼倉庫,而後全部的人把該服務器當成遠程倉庫,工做以前先 fetch,工做以後再 push。若是有衝突,則先 fetch,合併分支解決衝突後再 push。若是團隊人數太多,每一個人都向該服務器 push,那衝突該是有多少?有可能一個開發者第一次向服務器 push 的時候,有人在他以前已經 push 過了,他只好先 fetch,手工合併解決衝突,可等他再次 push 的時候,發現又有人再他以前已經 push 了,因而他只好再作一次解決衝突的流程,但是若是在他工做的時候,又有人 push 了呢?這也是以前講的該工做流程只適合小型開發團隊的緣由。
    以上流程通過適當修改也能夠供大型團隊使用,那就是將團隊分組,每一個組的成員共用一個服務器當遠程倉庫,組長合併了該組的工做成果後,再push到另外一個服務器當總的遠程倉庫,這樣就能夠大大減小衝突的數量,減小工做量。
  3. 開源項目的合做,在這種狀況下,每一個人都把本身的倉庫暴露在互聯網上。開源項目的組織者或負責人將全部人的倉庫設爲遠程倉庫,並把有意義的工做合併到主分支,而後發佈官方的 Git 倉庫。每一個開發者從官方倉庫 fetch 代碼後,完成本身的工做,而後再把它 push 到互聯網上本身的倉庫,等着項目負責人將本身的工做整合到官方倉庫中。若是項目負責人不幹了,改人了,只要還有人繼續開發,該項目就能夠繼續下去。碰到團隊比較大的狀況,也能夠進行分組。

Git 服務器的建設也至關簡單,由於 Git 支持以 SSH、HTTP 等協議傳輸數據,若是須要對服務器有寫權限,就開通 SSH 服務吧,設一個帳戶供全部人訪問 Git 倉庫便可。若是隻須要讀權限,使用任何一個 HTTP 服務器都可。關於 Git 服務器的建設,請自行參考官方文檔。若是是我的的、開源的項目,可使用 Github 網站提供的服務,直接存儲在互聯網上。(Github 私人倉庫是要收錢的。)

在 Eclipse 中使用 Git

得益於 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 中,以下三圖:


Clone、Pull 和 Fetch

從遠程倉庫中獲取數據的方法有多種。若是是第一次獲取遠程倉庫,可使用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 過來的分支不會自動合併,你能夠切換到這些分支進行查看,而後手工進行合併。其操做界面以下:

Checkout、Reset、Merge 和 Rebase

前面介紹過,隨着 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

相關文章
相關標籤/搜索