天天看點

Git【入門】這一篇就夠了

歡迎關注公衆号,白嫖原創PDF,也可以催更,微信搜:JavaPub,回複:【666】
Git 在生産工作中是使用頻率很高的工具,但我發現很多文章隻是對它做了簡單的送出指令說明,真正遇到 版本沖突或檔案丢失 等問題又定位不到原因,浪費大量時間。本篇文章較長,但都是在實際項目中用到的點。

<code>閱讀本文大概需要6分鐘</code>

前言

1.版本控制

1.1.什麼是版本控制

1.2.為什麼版本控制

1.3.本地版本控制

1.2.集中化的版本控制

1.2.分布式版本控制

2.認識 Git

2.1.Git 簡史

2.2.Git 與其他版本控制系統差別

2.3.Git 三種檔案狀态

3.Git 安裝

3.1.Linux 安裝

3.2.Windows 安裝

4.Git 快速入門

4.1.擷取倉庫

4.2.完整一次的送出流程

4.3.送出說明

4.4.推送到遠端倉庫

4.5.送出曆史

4.6.撤銷操作

4.7.分支

版本控制是一種記錄一個或若幹檔案内容變化,以便将來查閱特定版本修訂情況的系統。除了項目,你可以對任何類型的檔案進行版本控制。

采用版本控制系統(VCS)是個明智的選擇。 有了它就可以将某個檔案回溯到之前的狀态,甚至将整個項目都回退到過去某個時間點的狀态,可以比較檔案的變化細節,查出最後是誰修改了哪個地方,進而找出導緻怪異問題出現的原因,又是誰在何時報告了某個功能缺陷等等。 使用版本控制系統就算你對項目删除、修改錯誤,這也沒有關系,你也照樣可以很容易地就恢複到原先的樣子。但額外增加的工作量卻微乎其微。

許多人習慣用複制整個項目目錄的方式來儲存不同的版本,或許還會改名加上備份時間以示差別。 這麼做唯一的好處就是簡單,但是特别容易犯錯。 有時候會混淆所在的工作目錄,一不小心會寫錯檔案或者覆寫意想外的檔案。而且不利于團隊協作。 為了解決這個問題,人們很久以前就開發了許多種本地版本控制系統,大多都是采用某種簡單的資料庫來記錄檔案的曆次更新差異。圖檔來源 Git 官網。

Git【入門】這一篇就夠了

其中最流行的一種叫做 RCS,現今許多計算機系統上都還看得到它的蹤影。 甚至在流行的 Mac OS X 系統上安裝了開發者工具包之後,也可以使用 <code>rcs</code> 指令。 它的工作原理是在硬碟上儲存更新檔集(更新檔是指檔案修訂前後的變化);通過應用所有的更新檔,可以重新計算出各個版本的檔案内容。

接下來人們又遇到一個問題,如何讓在不同系統上的開發者協同工作? 于是,集中化的版本控制系統(Centralized Version Control Systems,簡稱 <code>CVCS</code>)應運而生。 諸如 <code>CVS</code>、Subversion(<code>SVN</code>) 以及 <code>Perforce</code> 等。 集中化的版本控制系統是單一的集中管理的伺服器,儲存所有檔案的修訂版本,而協同工作的人們都通過用戶端連到這台伺服器,取出最新的檔案或者送出更新。多年以來,這已成為版本控制系統的标準做法。如圖(來源 Git 官網):

Git【入門】這一篇就夠了

相對本地版本管理,集中化的版本控制每個人都可以在一定程度上看到項目中的其他人正在做些什麼。 而管理者也可以輕松掌控每個開發者的權限,并且管理一個 CVCS 要遠比在各個用戶端上維護本地資料庫來得輕松容易。

它也有如下诟病:

單點故障 如果當機,誰都無法送出更新,也就無法協同工作。 如果中心資料庫所在的磁盤發生損壞,又沒有做恰當備份,毫無疑問将丢失所有資料——包括項目的整個變更曆史,隻剩下人們在各自機器上保留的單獨快照。

需要聯網 為什麼需要聯網?<code>集中化的版本控制系統</code> 倉庫集中在一台伺服器,也就受到伺服器網絡環境的影響。

于是分布式版本控制系統(Distributed Version Control System,簡稱 <code>DVCS</code>)面世了。 <code>Git</code> 就是典型的分布式版本控制。還有 <code>Mercurial</code>、<code>Bazaar</code> 以及 <code>Darcs</code> 等。

用戶端并不隻提取最新版本的檔案快照,而是把代碼倉庫完整地鏡像下來。 這麼一來,任何一處協同工作用的伺服器發生故障,事後都可以用任何一個鏡像出來的本地倉庫恢複。 因為每一次的克隆操作,實際上都是一次對代碼倉庫的完整備份。圖檔來源 Git 官網。

Git【入門】這一篇就夠了

分布式版本控制系統的優勢不單是不必聯網這麼簡單,後面我們還會看到 Git 極其強大的分支管理等功能。

2002 年,<code>Linux</code> 核心開源項目整個項目組啟用一個專有的分布式版本控制系統 BitKeeper 來管理和維護代碼。到了 2005 年,開發 BitKeeper 的商業公司同 Linux 核心開源社群的合作關系結束,他們收回了 Linux 核心社群免費使用 BitKeeper 的權力。 這就迫使 Linux 開源社群(特别是 Linux 的締造者 Linus Torvalds)基于使用 BitKeeper 時的經驗教訓,開發出自己的版本系統。

集中式的缺點:集中式版本控制系統最大的毛病就是必須聯網才能工作,如果在區域網路内還好,帶寬夠大,速度夠快。

分布式版本控制系統根本沒有“中央伺服器”,每個人的電腦上都是一個完整的版本庫,這樣,你工作的時候,就不需要聯網了,因為版本庫就在你自己的電腦上。既然每個人電腦上都有一個完整的版本庫。

比方說你在自己電腦上改了檔案A,你的同僚也在他的電腦上改了檔案A,這時,你們倆之間隻需把各自的修改推送給對方,就可以互相看到對方的修改了。

和集中式版本控制系統相比,分布式版本控制系統的安全性要高很多,因為每個人電腦裡都有完整的版本庫。

某一個人的電腦壞掉了不要緊,随便從其他人那裡複制一個就可以了。而集中式版本控制系統的中央伺服器要是出了問題,所有人都沒法幹活了。

在實際使用分布式版本控制系統的時候,其實很少在兩人之間的電腦上推送版本庫的修改,因為可能你們倆不在一個區域網路内,兩台電腦互相通路不了,也可能今天你的同僚病了,他的電腦壓根沒有開機。是以,分布式版本控制系統通常也有一台充當“中央伺服器”的電腦,但這個伺服器的作用僅僅是用來友善“交換”大家的修改,沒有它大家也一樣幹活,隻是交換修改不友善而已。

Git的存儲方式是 <code>快照技術</code> ,而其他版本控制系統的存儲基本上都是 <code>增量存儲</code>。以下圖檔來自網絡。

Git【入門】這一篇就夠了

Git在每次 <code>git add</code> 即将内容添加到 <code>緩存區</code> 時會進行一次快照,<code>快照</code> 就像給當時的整個目錄及檔案照了一張相,在任何時候通過快照就能将目錄及檔案恢複到發起快照點的狀态。Git 是這樣生成快照的,對于沒有變化的檔案,會生成一個引用指向原檔案的位置以節省空間提高效率,對于變化了的檔案則将整個檔案存儲。git每個版本存儲的是一個快照。

Git【入門】這一篇就夠了

所謂 <code>增量存儲</code> ,指的是除了第一個版本存儲的是每個檔案的完整内容,之後的版本存儲的是每個檔案相對于上一個版本對應檔案的變化的内容。

Git 在未進行 <code>commit</code> 操作之前,存在三種狀态:<code>Untracked files</code>,<code>Changes not staged for commit</code> 及 <code>Changes to be committed</code> ,每種狀态之間可以随意進行互相轉換。了解這三種狀态各自所對應的不同情況,能夠幫助你友善有效的使用 Git 來管理項目。

在 Git 中,檔案狀态是個非常重要的概念。

為了更清楚的說明 <code>檔案狀态</code> 的概念,使用網絡上三張圖檔。

初始化一個項目,也就是将項目所在目錄納入Git的管理之下。假設項目目錄為hello_world,初始化之後,在目錄下建立README.txt檔案,接着,使用“git status”檢視檔案狀态,如圖

Git【入門】這一篇就夠了

可以看到,Git友好的标示出README.txt為“Untracked files”,并且提示使用“git add ...”的指令将檔案包含到待送出清單中。按照提示,使用“git add README.txt”指令,然後,使用“git status”檢視檔案狀态,如圖:

Git【入門】這一篇就夠了

檔案README.txt狀态變成了“Changes to be committed”,也就是說README.txt在暫存區域生成了快照,等待被送出。正如Git所提示的那樣,通過“git rm --cached README.txt”指令,可以将檔案狀态還原為未暫存狀态,即回到“Untracked files”檔案狀态。現在,README.txt已經可以被送出到git目錄中了,但是暫時不送出。打開README.txt,向其中加些内容,儲存之後,用“git status”檢視,傳回如圖資訊:

Git【入門】這一篇就夠了

可以看到,除了之前的“Changes to be committed”狀态,現在又多了一條“Changes not staged for commit”狀态,表明檔案已經修改,但是還沒有放入暫存區域,也就是沒生成快照。如果現在進行commit操作,隻是将修改之前的檔案快照送出到了git目錄,一定記住:隻有暫存區域的檔案(即:檔案狀态為“Changes to be committed”)才會被送出。正如提示,通過“git add README.txt”指令将已修改檔案更新到暫存區域中,如果想撤銷修改,可以使用“git checkout -- README.txt”指令。

Centos/RedHat 安裝

$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
$ yum -y install git-core
$ git --version git version 1.7.1

Linux 的其他版本系統需要其他方式安裝。

直接在官網下載下傳。

Git【入門】這一篇就夠了

另一種是在 <code>Github</code> ,搜尋 <code>GitHub for Windows</code> 項目。

第一種:

建立一個存項目檔案夾,在 <code>git bash</code> 執行 <code>git init</code> ,項目檔案夾下出現 <code>.git</code> 的子目錄。

第二種

從遠端代碼倉庫拉去一個現有的:<code>git clone [url]</code> 也可以自定義本地倉庫名字 <code>git clone [url] dirName</code>

進入 Git 項目目錄

cd /myProject

送出所有修改到暫存區

git add .

送出暫存區修改内容到本地倉庫

git commit -m "送出描述"

推送到遠端倉庫

git push

現在就可以拉去 JavaPub 的遠端倉庫了。

忽略檔案配置:<code>.gitignore</code> 檔案

移除檔案:<code>git rm filename</code>(從暫存區移除,然後送出)

檢視檔案狀态:<code>git status</code>

推送到遠端倉庫:<code>git push origin master</code> 推送到遠端 <code>master</code> 分支

如果沒有遠端倉庫,現在想讓本地和遠端倉庫關聯,

如下指令添加:<code>git remote add origin &lt;server&gt;</code> ,比如我們要讓本地的一個倉庫和 Github 上建立的一個倉庫關聯可以這樣 <code>git remote add origin https://github.com/Rodert/test.git</code>

現在就可以将項目推送到遠端倉庫了。

有時我們需要查詢以前的送出曆史,使用指令 <code>git log</code>。

隻看某人送出記錄

git log --author=bob

有時你送出過代碼之後,發現一個地方改錯了,你下次送出時不想保留上一次的記錄;或者你上一次的 <code>commit</code> message的描述有誤,這時候你可以使用接下來的這個指令:<code>git commit --amend</code>。

git commit --amend

取消上一步操作,如 <code>git add</code> 、 <code>git commit</code> 之後。

git reset filename

分支是用來将特性開發絕緣開來的。在你建立倉庫的時候,<code>master</code> 是預設的。在其他分支上進行開發,完成後再将它們合并到主分支上。

不同的版本或系統子產品并行開發時,我們一般會單獨建立一個分支進行開發,最後再合并到主分支。

建立本地分支

git branch test

切換到 <code>test</code> 分支

git checkout test

也可以合并上面倆步,<code>git checkout -b feature_x</code>。

切換到 master 分支

git checkout master

合并分支 (可能有沖突)

git merge test

把建立的分支删掉

git branch -d test

另外,也可以把分支推送到遠端倉庫 <code>git push &lt;遠端主機名&gt; &lt;本地分支名&gt;:&lt;遠端分支名&gt;</code>

git push origin test:test
聲明:參考來源網際網路,有任何争議可以留言。站在前人的肩上,我們才能看的更遠。
本教程純手打,緻力于最實用教程,不需要什麼獎勵,隻希望多多轉發支援。