成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺析git

jas0n / 2811人閱讀

摘要:還可以通過(guò)檢查對(duì)象內(nèi)容的的哈希值和對(duì)象名是否相同,來(lái)判斷對(duì)象內(nèi)容是否正確。對(duì)象對(duì)象和其它所有的對(duì)象一樣,都用其內(nèi)容的哈希值來(lái)命名的只有當(dāng)兩個(gè)對(duì)象的內(nèi)容完全相同包括其所指向所有子對(duì)象時(shí),它的名字才會(huì)一樣,反之亦然。

git是什么

簡(jiǎn)單來(lái)說(shuō),Git,它是一個(gè)快速的 分布式版本控制系統(tǒng) (Distributed Version Control System,簡(jiǎn)稱 DVCS)

同傳統(tǒng)的 集中式版本控制系統(tǒng) (Centralized Version Control Systems,簡(jiǎn)稱CVCS) 不同,Git的分布式特性使得開(kāi)發(fā)者間的協(xié)作變得更加靈活多樣。

這時(shí)候我們會(huì)想到:

什么又是版本控制呢?

什么是分布式什么是集中式?

我們帶著問(wèn)題往下走。

版本控制

版本控制是一種記錄一個(gè)或若干文件內(nèi)容變化,以便將來(lái)查閱特定版本修訂情況的系統(tǒng)。

比如:有一位程序員他可能需要保存一個(gè)代碼文件的所有的修訂版本,這樣就可以

將某個(gè)文件回溯到之前的狀態(tài)

甚至將整個(gè)項(xiàng)目都回退到過(guò)去某個(gè)時(shí)間點(diǎn)的狀態(tài)

比較文件的變化細(xì)節(jié),查出最后是誰(shuí)修改了哪個(gè)地方,從而找出導(dǎo)致怪異問(wèn)題出現(xiàn)的原因

這時(shí)候采用版本控制就是一個(gè)非常明智的選擇,使用版本控制系統(tǒng)通常還意味著,就算你亂來(lái)一氣把整個(gè)項(xiàng)目中的文件改的改刪的刪,你也照樣可以輕松恢復(fù)到原先的樣子。 但額外增加的工作量卻微乎其微。

版本控制的成長(zhǎng)

兒童:人們通過(guò)復(fù)制整個(gè)項(xiàng)目的方式來(lái)保存不同的版本,或許還會(huì)改名加上備份時(shí)間以示區(qū)別。好處就是簡(jiǎn)單,但是特別容易犯錯(cuò),一不小心會(huì)寫(xiě)錯(cuò)文件或者覆蓋意想外的文件。

少年:人們?yōu)榱松厦娴膯?wèn)題,很久以前就開(kāi)發(fā)了許多種本地版本控制系統(tǒng),大多是采用某種簡(jiǎn)單的數(shù)據(jù)庫(kù)來(lái)記錄文件的歷次更新差異,比如其中比較流行的 RCS 。

青年:人們又遇到一個(gè)問(wèn)題,如何讓在不同系統(tǒng)上的開(kāi)發(fā)者協(xié)同工作? 于是,集中化的版本控制系統(tǒng)( CVCS)應(yīng)運(yùn)而生。 這類系統(tǒng),諸如 CVS 、 Subversion ,都有一個(gè)單一的集中管理的服務(wù)器,保存所有文件的修訂版本,而協(xié)同工作的人們都通過(guò)客戶端連到這臺(tái)服務(wù)器,取出最新的文件或者提交更新?,F(xiàn)在,每個(gè)人都可以在一定程度上看到項(xiàng)目中的其他人正在做些什么。 而管理員也可以輕松掌控每個(gè)開(kāi)發(fā)者的權(quán)限,并且管理一個(gè) CVCS

事分兩面,有好有壞。 這么做最顯而易見(jiàn)的缺點(diǎn)是中央服務(wù)器的單方面故障。 如果關(guān)機(jī)一小時(shí),那么在這一小時(shí)內(nèi),誰(shuí)都無(wú)法提交更新,也就無(wú)法協(xié)同工作。 如果中心數(shù)據(jù)庫(kù)所在的磁盤(pán)發(fā)生損壞,又沒(méi)有做恰當(dāng)備份,毫無(wú)疑問(wèn)你將丟失所有數(shù)據(jù)——包括項(xiàng)目的整個(gè)變更歷史,只剩下人們?cè)诟髯詸C(jī)器上保留的多帶帶快照。

壯年:于是分布式版本控制系統(tǒng)面世了。 在這類系統(tǒng)中,像 Git 、 Mercurial 等,客戶端并不只提取最新版本的文件快照,而是把代碼倉(cāng)庫(kù)完整地鏡像下來(lái)。 這么一來(lái),任何一處協(xié)同工作用的服務(wù)器發(fā)生故障,事后都可以用任何一個(gè)鏡像出來(lái)的本地倉(cāng)庫(kù)恢復(fù)。 因?yàn)槊恳淮蔚目寺〔僮?,?shí)際上都是一次對(duì)代碼倉(cāng)庫(kù)的完整備份。

許多這類系統(tǒng)都可以指定和若干不同的遠(yuǎn)端代碼倉(cāng)庫(kù)進(jìn)行交互。籍此,你就可以在同一個(gè)項(xiàng)目中,分別和不同工作小組的人相互協(xié)作。 你可以根據(jù)需要設(shè)定不同的協(xié)作流程,比如層次模型式的工作流,而這在以前的集中式系統(tǒng)中是無(wú)法實(shí)現(xiàn)的。

git誕生史記

很多人都知道, Linus 在1991年創(chuàng)建了開(kāi)源的 Linux ,從此,Linux 系統(tǒng)不斷發(fā)展,已經(jīng)成為最大的服務(wù)器系統(tǒng)軟件了。

Linus 雖然創(chuàng)建了 Linux,但 Linux 的壯大是靠全世界熱心的志愿者參與的,這么多人在世界各地為 Linux 編寫(xiě)代碼,那 Linux 的代碼是如何管理的呢?

事實(shí)是,在2002年以前,世界各地的志愿者把源代碼文件通過(guò) diff 的方式發(fā)給 Linus,然后由 Linus 本人通過(guò)手工方式合并代碼!

你也許會(huì)想,為什么 Linus 不把 Linux 代碼放到版本控制系統(tǒng)里呢?不是有 CVS、SVN這些免費(fèi)的版本控制系統(tǒng)嗎?因?yàn)?Linus 堅(jiān)定地反對(duì) CVSSVN,這些集中式的版本控制系統(tǒng)不但速度慢,而且必須聯(lián)網(wǎng)才能使用。有一些商用的版本控制系統(tǒng),雖然比 CVS 、 SVN 好用,但那是付費(fèi)的,和 Linux 的開(kāi)源精神不符。

不過(guò),到了2002年,Linux 系統(tǒng)已經(jīng)發(fā)展了十年了,代碼庫(kù)之大讓 Linus 很難繼續(xù)通過(guò)手工方式管理了,社區(qū)的弟兄們也對(duì)這種方式表達(dá)了強(qiáng)烈不滿,于是 Linus 選擇了一個(gè)商業(yè)的版本控制系統(tǒng) BitKeeper,BitKeeper 的東家 BitMover 公司出于人道主義精神,授權(quán) Linux 社區(qū)免費(fèi)使用這個(gè)版本控制系統(tǒng)。

安定團(tuán)結(jié)的大好局面在2005年就被打破了,原因是 Linux 社區(qū)牛人聚集,不免沾染了一些梁山好漢的江湖習(xí)氣。開(kāi)發(fā) SambaAndrew 試圖破解 BitKeeper 的協(xié)議(這么干的其實(shí)也不只他一個(gè)),被 BitMover 公司發(fā)現(xiàn)了(監(jiān)控工作做得不錯(cuò)!),于是 BitMover 公司怒了,要收回 Linux 社區(qū)的免費(fèi)使用權(quán)。

Linus 可以向 BitMover 公司道個(gè)歉,保證以后嚴(yán)格管教弟兄們,嗯,這是不可能的。實(shí)際情況是這樣的:

Linus 花了兩周時(shí)間自己用 C 寫(xiě)了一個(gè)分布式版本控制系統(tǒng),這就是 Git!一個(gè)月之內(nèi),Linux 系統(tǒng)的源碼已經(jīng)由 Git 管理了!牛是怎么定義的呢?大家可以體會(huì)一下。

Git 迅速成為最流行的分布式版本控制系統(tǒng),尤其是2008年,GitHub 網(wǎng)站上線了,它為開(kāi)源項(xiàng)目免費(fèi)提供 Git 存儲(chǔ),無(wú)數(shù)開(kāi)源項(xiàng)目開(kāi)始遷移至 GitHub,包括 jQuery,PHP,Ruby等等。

歷史就是這么偶然,如果不是當(dāng)年 BitMover 公司威脅 Linux 社區(qū),可能現(xiàn)在我們就沒(méi)有免費(fèi)而超級(jí)好用的 Git 了。

git的優(yōu)點(diǎn)

在集中式系統(tǒng)中,每個(gè)開(kāi)發(fā)者就像是連接在集線器上的節(jié)點(diǎn),彼此的工作方式大體相像。 而在 Git 中,每個(gè)開(kāi)發(fā)者同時(shí)扮演著節(jié)點(diǎn)和集線器的角色——也就是說(shuō),每個(gè)開(kāi)發(fā)者既可以將自己的代碼貢獻(xiàn)到其他的倉(cāng)庫(kù)中,同時(shí)也能維護(hù)自己的公開(kāi)倉(cāng)庫(kù),讓其他人可以在其基礎(chǔ)上工作并貢獻(xiàn)代碼。 由此,Git 的分布式協(xié)作可以為你的項(xiàng)目和團(tuán)隊(duì)衍生出種種不同的工作流程。

速度快

簡(jiǎn)單的設(shè)計(jì),易用

對(duì)非線性開(kāi)發(fā)模式的強(qiáng)力支持(允許成千上萬(wàn)個(gè)并行開(kāi)發(fā)的分支)

完全分布式

有能力高效管理類似 Linux 內(nèi)核一樣的超大規(guī)模項(xiàng)目(速度和數(shù)據(jù)量)

git實(shí)現(xiàn)原理

從根本上來(lái)講 Git 是一個(gè)內(nèi)容尋址 (content-addressable) 文件系統(tǒng),并在此之上提供了一個(gè)版本控制系統(tǒng)的用戶界面,Git 的核心部分是一個(gè)簡(jiǎn)單的鍵值對(duì)數(shù)據(jù)庫(kù) (key-value data store) 。 你可以向該數(shù)據(jù)庫(kù)插入任意類型的內(nèi)容,它會(huì)返回一個(gè)鍵值,通過(guò)該鍵值可以在任意時(shí)刻再次檢索 (retrieve) 該內(nèi)容。

初始化的git目錄

當(dāng)在一個(gè)新目錄或已有目錄執(zhí)行 git init 時(shí),Git 會(huì)創(chuàng)建一個(gè) .git 目錄。 這個(gè)目錄包含了幾乎所有 Git 存儲(chǔ)和操作的對(duì)象。 如若想備份或復(fù)制一個(gè)版本庫(kù),只需把這個(gè)目錄拷貝至另一處即可。

$ ls -F1
HEAD
config*
description
hooks/
info/
objects/
refs/

這是一個(gè)全新的 git init 版本庫(kù),這將是你看到的默認(rèn)結(jié)構(gòu)。

description 文件僅供 GitWeb 程序使用,我們無(wú)需關(guān)心。

config 文件包含項(xiàng)目特有的配置選項(xiàng)。

info 目錄包含一個(gè)全局性排除(global exclude)文件,用以放置那些不希望被記錄在 .gitignore 文件中的忽略模式(ignored patterns)。

hooks 目錄包含客戶端或服務(wù)端的鉤子腳本 (hook scripts)。

objects 目錄存儲(chǔ)所有數(shù)據(jù)內(nèi)容。

refs 目錄存儲(chǔ)指向數(shù)據(jù)(分支)的提交對(duì)象的指針

HEAD 文件指示目前被檢出的分支

index 文件保存暫存區(qū)信息。

git對(duì)象模型

所有用來(lái)表示項(xiàng)目歷史信息的文件,是通過(guò)一個(gè)40個(gè)字符的 (40-digit) “對(duì)象名”來(lái)索引的,對(duì)象名看起來(lái)像這樣:

6ff87c4664981e4397625791c8ea3bbb5f2279a3

你會(huì)在Git里到處看到這種“40個(gè)字符”字符串。每一個(gè)“對(duì)象名”都是對(duì)“對(duì)象”內(nèi)容做 SHA1 哈希計(jì)算得來(lái)的,( SHA1 是一種密碼學(xué)的哈希算法)。這樣就意味著兩個(gè)不同內(nèi)容的對(duì)象不可能有相同的“對(duì)象名”。

這樣做會(huì)有幾個(gè)好處:

Git 只要比較對(duì)象名,就可以很快的判斷兩個(gè)對(duì)象是否相同。

因?yàn)樵诿總€(gè)倉(cāng)庫(kù) (repository) 的“對(duì)象名”的計(jì)算方法都完全一樣,如果同樣的內(nèi)容存在兩個(gè)不同的倉(cāng)庫(kù)中,就會(huì)存在相同的“對(duì)象名”下。

Git 還可以通過(guò)檢查對(duì)象內(nèi)容的 SHA1 的哈希值和“對(duì)象名”是否相同,來(lái)判斷對(duì)象內(nèi)容是否正確。

對(duì)象

每個(gè)對(duì)象 (object) 包括三個(gè)部分:類型,大小和內(nèi)容。大小就是指內(nèi)容的大小,內(nèi)容取決于對(duì)象的類型,有四種類型的對(duì)象:"blob" 、 "tree""commit""tag"

“blob” 用來(lái)存儲(chǔ)文件數(shù)據(jù),通常是一個(gè)文件。

“tree” 有點(diǎn)像一個(gè)目錄,它管理一些“tree”或是 “blob”(就像文件和子目錄)。

一個(gè)“commit”只指向一個(gè)"tree",它用來(lái)標(biāo)記項(xiàng)目某一個(gè)特定時(shí)間點(diǎn)的狀態(tài)。它包括一些關(guān)于時(shí)間點(diǎn)的元數(shù)據(jù),如時(shí)間戳、最近一次提交的作者、指向上次提交 (commits) 的指針等等。

一個(gè) “tag” 是來(lái)標(biāo)記某一個(gè)提交 (commit) 的方法。

幾乎所有的 Git 功能都是使用這四個(gè)簡(jiǎn)單的對(duì)象類型來(lái)完成的。它就像是在你本機(jī)的文件系統(tǒng)之上構(gòu)建一個(gè)小的文件系統(tǒng)。

Blob對(duì)象

一個(gè) blob 通常用來(lái)存儲(chǔ)文件的內(nèi)容。

Tree 對(duì)象

一個(gè) tree 對(duì)象可以指向一個(gè)包含文件內(nèi)容的 blob 對(duì)象, 也可以是其它包含某個(gè)子目錄內(nèi)容的其它 tree 對(duì)象,它一般用來(lái)表示內(nèi)容之間的目錄層次關(guān)系。 Tree 對(duì)象、blob 對(duì)象和其它所有的對(duì)象一樣,都用其內(nèi)容的 SHA1 哈希值來(lái)命名的;只有當(dāng)兩個(gè) tree 對(duì)象的內(nèi)容完全相同(包括其所指向所有子對(duì)象)時(shí),它的名字才會(huì)一樣,反之亦然。這樣就能讓Git 僅僅通過(guò)比較兩個(gè)相關(guān)的 tree 對(duì)象的名字是否相同,來(lái)快速的判斷其內(nèi)容是否不同。

Commit對(duì)象

commit 對(duì)象指向一個(gè) tree 對(duì)象,并且?guī)в邢嚓P(guān)的描述信息。

一個(gè)提交 commit 由以下的部分組成:

一個(gè) tree 對(duì)象:tree 對(duì)象的 `SHA1簽名, 代表著目錄在某一時(shí)間點(diǎn)的內(nèi)容。

父對(duì)象 (parent(s)): 提交 (commit) 的SHA1簽名代表著當(dāng)前提交前一步的項(xiàng)目歷史。合并的提交 (merge commits) 可能會(huì)有不只一個(gè)父對(duì)象。如果一個(gè)提交沒(méi)有父對(duì)象,那么我們就叫它“根提交" (root commit) ,它就代表著項(xiàng)目最初的一個(gè)版本 (revision)。 每個(gè)項(xiàng)目必須有至少有一個(gè)“根提交"(root commit)。

作者 (author) :做了此次修改的人的名字,還有修改日期。

提交者(committer):實(shí)際創(chuàng)建提交(commit)的人的名字, 同時(shí)也帶有提交日期。

注釋:用來(lái)描述此次提交。

注意:一個(gè)提交(commit)本身并沒(méi)有包括任何信息來(lái)說(shuō)明其做了哪些修改; 所有的修改(changes)都是通過(guò)與父提交(parents)的內(nèi)容比較而得出的。 值得一提的是, 盡管git可以檢測(cè)到文件內(nèi)容不變而路徑改變的情況, 但是它不會(huì)去顯式(explicitly)的記錄文件的更名操作(可以看一下 git diff )。

一般用 git commit 來(lái)創(chuàng)建一個(gè)提交 (commit), 這個(gè)提交 (commit) 的父對(duì)象一般是當(dāng)前分支 (current HEAD) ,同時(shí)把存儲(chǔ)在當(dāng)前索引 (index) 的內(nèi)容全部提交。

對(duì)象模型:

如果我們把它提交 (commit) 到一個(gè) Git 倉(cāng)庫(kù)中, 在 Git 中它們也許看起來(lái)就如下圖:

你可以看到:每個(gè)目錄都創(chuàng)建了 tree對(duì)象 (包括根目錄), 每個(gè)文件都創(chuàng)建了一個(gè)對(duì)應(yīng)的 blob對(duì)象。最后有一個(gè) commit 對(duì)象 來(lái)指向根 tree 對(duì)象 (root of trees) , 這樣我們就可以追蹤項(xiàng)目每一項(xiàng)提交內(nèi)容.

標(biāo)簽對(duì)象:

一個(gè)標(biāo)簽對(duì)象包括一個(gè)對(duì)象名(SHA1簽名), 對(duì)象類型, 標(biāo)簽名, 標(biāo)簽創(chuàng)建人的名字(tagger), 還有一條可能包含有簽名(signature)的消息.

回到我們的問(wèn)題 強(qiáng)大的git分支

有人把 Git 的分支模型稱為它的必殺技特性,也正因?yàn)檫@一特性,使得它 從眾多版本控制系統(tǒng)中脫穎而出。

Git 保存的不是文件的變化或者差異,而是一系列不同時(shí)刻的文件快照。

在進(jìn)行提交操作時(shí),Git 會(huì)保存一個(gè)提交對(duì)象(commit object)。知道了 Git 保存數(shù)據(jù)的方式,該提交對(duì)象會(huì)包含一個(gè)指向暫存內(nèi)容快照的指針。 但不僅僅是這樣,該提交對(duì)象還包含了作者的姓名和郵箱、提交時(shí)輸入的信息以及指向它的父對(duì)象的指針。首次提交產(chǎn)生的提交對(duì)象沒(méi)有父對(duì)象,普通提交操作產(chǎn)生的提交對(duì)象有一個(gè)父對(duì)象,而由多個(gè)分支合并產(chǎn)生的提交對(duì)象有多個(gè)父對(duì)象,

當(dāng)使用 git commit 新建一個(gè)提交對(duì)象前,Git 會(huì)先計(jì)算每一個(gè)子目錄的校驗(yàn)和(40 個(gè)字符長(zhǎng)度 SHA-1 字串),然后在 Git 倉(cāng)庫(kù)中將這些目錄保存為樹(shù)(tree)對(duì)象。之后 Git 創(chuàng)建的提交對(duì)象,除了包含相關(guān)提交信息以外,還包含著指向這個(gè)樹(shù)對(duì)象(項(xiàng)目根目錄)的指針,如此它就可以在將來(lái)需要的時(shí)候,重現(xiàn)此次快照的內(nèi)容了。

Git 中的分支,其實(shí)本質(zhì)上僅僅是個(gè)指向 commit 對(duì)象的可變指針。Git 會(huì)使用 master 作為分支的默認(rèn)名字。在若干次提交后,你其實(shí)已經(jīng)有了一個(gè)指向最后一次提交對(duì)象的 master 分支,它在每次提交的時(shí)候都會(huì)自動(dòng)向前移動(dòng)。

Git 是如何知道你當(dāng)前在哪個(gè)分支上工作的呢?其實(shí)答案也很簡(jiǎn)單,它保存著一個(gè)名為 HEAD 的特別指針。在 Git 中,它是一個(gè)指向你正在工作中的本地分支的指針,我們可以將 HEAD 想象為當(dāng)前分支的別名。

由于 Git 中的分支實(shí)際上僅是一個(gè)包含所指對(duì)象校驗(yàn)和的文件,所以創(chuàng)建和銷毀一個(gè)分支就變得非常廉價(jià)。說(shuō)白了,新建一個(gè)分支就是向一個(gè)文件寫(xiě)入 41 個(gè)字節(jié)(外加一個(gè)換行符)那么簡(jiǎn)單,當(dāng)然也就很快了。

大多數(shù)版本控制系統(tǒng)它們管理分支大多采取備份所有項(xiàng)目文件到特定目錄的方式,所以根據(jù)項(xiàng)目文件數(shù)量和大小不同,可能花費(fèi)的時(shí)間也會(huì)有相當(dāng)大的差別,快則幾秒,慢則數(shù)分鐘。

而 Git 的實(shí)現(xiàn)與項(xiàng)目復(fù)雜度無(wú)關(guān),它永遠(yuǎn)可以在幾毫秒的時(shí)間內(nèi)完成分支的創(chuàng)建和切換。同時(shí),因?yàn)槊看翁峤粫r(shí)都記錄了祖先信息(parent 對(duì)象),將來(lái)要合并分支時(shí),尋找恰當(dāng)?shù)暮喜⒒A(chǔ)(譯注:即共同祖先)的工作其實(shí)已經(jīng)自然而然地?cái)[在那里了,所以實(shí)現(xiàn)起來(lái)非常容易。Git 鼓勵(lì)開(kāi)發(fā)者頻繁使用分支,正是因?yàn)橛兄@些特性作保障。

分支的新建與合并

新建分支并進(jìn)入

$ git checkout -b iss53

根據(jù)需求寫(xiě)代碼并提交

$ git commit -a -m "new text"

接到線上問(wèn)題需要并且修改bug

$ git checkout master
$ git checkout -b hotfix
$ git commit -a -m "fixed bug"

合并修改完bug的代碼進(jìn)master(暫無(wú)沖突)

$ git checkout master
$ git merge hotfix

解決問(wèn)題后刪除hotfix分支并返回原來(lái)的iss53分支繼續(xù)工作

$ git branch -d hotfix
$ git checkout iss53
$ git commit -a -m "finished"

合并iss53分支進(jìn)主分支

$ git checkout master
$ git merge iss53

請(qǐng)注意,這次合并操作的底層實(shí)現(xiàn),并不同于之前 hotfix 的并入方式。因?yàn)檫@次你的開(kāi)發(fā)歷史是從更早的地方開(kāi)始分叉的。由于當(dāng)前 master 分支所指向的提交對(duì)象(C4)并不是 iss53 分支的直接祖先,Git 不得不進(jìn)行一些額外處理。就此例而言,Git 會(huì)用兩個(gè)分支的末端(C4 和 C5)以及它們的共同祖先(C2)進(jìn)行一次簡(jiǎn)單的三方合并計(jì)算。

這次,Git 沒(méi)有簡(jiǎn)單地把分支指針右移,而是對(duì)三方合并后的結(jié)果重新做一個(gè)新的快照,并自動(dòng)創(chuàng)建一個(gè)指向它的提交對(duì)象(C6)。這個(gè)提交對(duì)象比較特殊,它有兩個(gè)祖先(C4 和 C5)。

有時(shí)候合并操作并不會(huì)如此順利。如果在不同的分支中都修改了同一個(gè)文件的同一部分,Git 就無(wú)法干凈地把兩者合到一起。如果你在解決問(wèn)題 #53 的過(guò)程中修改了 hotfix 中修改的部分,將會(huì)出現(xiàn)問(wèn)題。

Git 作了合并,但沒(méi)有提交,它會(huì)停下來(lái)等你解決沖突。

任何包含未解決沖突的文件都會(huì)以未合并 unmerged 的狀態(tài)列出。Git 會(huì)在有沖突的文件里加入標(biāo)準(zhǔn)的沖突解決標(biāo)記,可以通過(guò)它們來(lái)手工定位并解決這些沖突。

rebase 變基

最容易的整合分支的方法是 merge 命令,它會(huì)把兩個(gè)分支最新的快照(C3 和 C4)以及二者最新的共同祖先(C2)進(jìn)行三方合并,合并的結(jié)果是產(chǎn)生一個(gè)新的提交對(duì)象(C5)。:

但是,如果你想讓 experiment分支歷史看起來(lái)像沒(méi)有經(jīng)過(guò)任何合并一樣,還有另外一個(gè)選擇:你可以把在 C3 里產(chǎn)生的變化補(bǔ)丁在 C4 的基礎(chǔ)上重新打一遍。在 Git 里,這種操作叫做變基 (rebase)。有了 rebase 命令,就可以把在一個(gè)分支里提交的改變移到另一個(gè)分支里重放一遍。

$ git checkout experiment
$ git rebase master

它的原理是回到兩個(gè)分支最近的共同祖先,根據(jù)當(dāng)前分支(也就是要進(jìn)行變基的分支 experiment )后續(xù)的歷次提交對(duì)象(這里只有一個(gè) C3),生成一系列文件補(bǔ)丁,然后以基底分支(也就是主干分支 master)最后一個(gè)提交對(duì)象(C4)為新的出發(fā)點(diǎn),逐個(gè)應(yīng)用之前準(zhǔn)備好的補(bǔ)丁文件,最后會(huì)生成一個(gè)新的合并提交對(duì)象(C3"),從而改寫(xiě) experiment 的提交歷史,使它成為 master 分支的直接下游

簡(jiǎn)單講他就是把你的 experiment 分支里的每個(gè)提交 commit 取消掉,并且把它們臨時(shí) 保存為補(bǔ)丁 patch (這些補(bǔ)丁放到".git/rebase"目錄中),然后把 experiment 分支更新 到最新的 origin 分支,最后把保存的這些補(bǔ)丁應(yīng)用到 experiment 分支上。

現(xiàn)在的 C3" 對(duì)應(yīng)的快照,其實(shí)和普通的三方合并,即上個(gè)例子中的 C5 對(duì)應(yīng)的快照內(nèi)容一模一樣了。雖然最后整合得到的結(jié)果沒(méi)有任何區(qū)別,但變基能產(chǎn)生一個(gè)更為整潔的提交歷史。如果視察一個(gè)變基過(guò)的分支的歷史記錄,看起來(lái)會(huì)更清楚:仿佛所有修改都是在一根線上先后進(jìn)行的,盡管實(shí)際上它們?cè)臼峭瑫r(shí)并行發(fā)生的。

rebase 的過(guò)程中,也許會(huì)出現(xiàn)沖突 conflict。在這種情況,Git 會(huì)停止 rebase 并會(huì)讓你去解決 沖突;在解決完沖突后,用 git-add 命令去更新這些內(nèi)容的索引 index, 然后,你無(wú)需執(zhí)行 git-commit ,只要執(zhí)行:

$ git rebase --continue
這樣git會(huì)繼續(xù)應(yīng)用 apply 余下的補(bǔ)丁。在任何時(shí)候,你可以用 --abort 參數(shù)來(lái)終止 rebase 的行動(dòng),并且 experiment 分支會(huì)回到 rebase 開(kāi)始前的狀態(tài)。

$ git rebase --abort

git merge 應(yīng)該只用于為了保留一個(gè)有用的,語(yǔ)義化的準(zhǔn)確的歷史信息,而希望將一個(gè)分支的整個(gè)變更集成到另外一個(gè) branch 時(shí)使用 rebase。這樣形成的清晰版本變更圖有著重要的價(jià)值。

所有其他的情況都是以不同的方式使用 rebase 的適合場(chǎng)景:經(jīng)典型方式,三點(diǎn)式,interactivecherry-picking

我們使用變基的目的:是想要得到一個(gè)能在遠(yuǎn)程分支上干凈應(yīng)用的補(bǔ)丁 — 比如某些項(xiàng)目你不是維護(hù)者,但想幫點(diǎn)忙的話,最好用變基:先在自己的一個(gè)分支里進(jìn)行開(kāi)發(fā),當(dāng)準(zhǔn)備向主項(xiàng)目提交補(bǔ)丁的時(shí)候,根據(jù)最新的 origin/master 進(jìn)行一次變基操作然后再提交,這樣維護(hù)者就不需要做任何整合工作(實(shí)際上是把解決分支補(bǔ)丁同最新主干代碼之間沖突的責(zé)任,化轉(zhuǎn)為由提交補(bǔ)丁的人來(lái)解決。),只需根據(jù)你提供的倉(cāng)庫(kù)地址作一次快進(jìn)合并,或者直接采納你提交的補(bǔ)丁。

需要注意,合并結(jié)果中最后一次提交所指向的快照,無(wú)論是通過(guò)變基,還是三方合并,都會(huì)得到相同的快照內(nèi)容,只不過(guò)提交歷史不同罷了。變基是按照每行的修改次序重演一遍修改,而合并是把最終結(jié)果合在一起。

有趣的變基

我在不同的topic之間來(lái)回切換,這樣會(huì)導(dǎo)致我的歷史中不同topic互相交叉,邏輯上組織混亂;

我們可能需要多個(gè)連續(xù)的commit來(lái)解決一個(gè)bug;

我可能會(huì)在commit中寫(xiě)了錯(cuò)別字,后來(lái)又做修改;

甚至我們?cè)谝淮翁峤粫r(shí)純粹就是因?yàn)閼卸璧脑颍铱赡馨珊芏嗟淖兏挤旁谝粋€(gè)commit中做了提交。

rebase可以合并commit

rebase可以用來(lái)修改commit信息

rebase可以用來(lái)拆分commit

git rebase -i HEAD~3

變基也可以放到其他分支進(jìn)行,并不一定非得根據(jù)分化之前的分支。

變基的風(fēng)險(xiǎn)

要用它得遵守一條準(zhǔn)則:

不要在公共分支上使用rebase。

“No one shall rebase a shared branch”?—?Everyone about rebase

如果你遵循這條金科玉律,就不會(huì)出差錯(cuò)。

在進(jìn)行變基的時(shí)候,實(shí)際上拋棄了一些現(xiàn)存的提交對(duì)象而創(chuàng)造了一些類似但不同的新的提交對(duì)象。如果你把原來(lái)分支中的提交對(duì)象發(fā)布出去,并且其他人更新下載后在其基礎(chǔ)上開(kāi)展工作,而稍后你又用 git rebase 拋棄這些提交對(duì)象,把新的重演后的提交對(duì)象發(fā)布出去的話,你的合作者就不得不重新合并他們的工作,這樣當(dāng)你再次從他們那里獲取內(nèi)容時(shí),提交歷史就會(huì)變得一團(tuán)糟。

注意rebase往往會(huì)重寫(xiě)歷史,所有已經(jīng)存在的commits雖然內(nèi)容沒(méi)有改變,但是commit本身的hash都會(huì)改變。

結(jié)論:只要你的分支上需要rebase的所有commits歷史還沒(méi)有被push過(guò)(比如上例中rebase時(shí)從分叉處開(kāi)始有兩個(gè)commit歷史會(huì)被重寫(xiě)),就可以安全地使用git rebase來(lái)操作。

上述結(jié)論可能還需要修正:對(duì)于不再有子分支的branch,并且因?yàn)閞ebase而會(huì)被重寫(xiě)的commits都還沒(méi)有push分享過(guò),可以比較安全地做rebase

思考下它的功能吧 git pull --rebase

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94909.html

相關(guān)文章

  • 淺析webpack源碼之Tapable粗解(五)

    摘要:打開(kāi)是個(gè)構(gòu)造函數(shù),定義了一些靜態(tài)屬性和方法我們先看在插件下地址上面寫(xiě)的解釋就跟沒(méi)寫(xiě)一樣在文件下我們看到輸出的一些對(duì)象方法每一個(gè)對(duì)應(yīng)一個(gè)模塊而在下引入的下面,我們先研究引入的對(duì)象的英文單詞解釋,除了最常用的點(diǎn)擊手勢(shì)之外,還有一個(gè)意思是水龍頭進(jìn) 打開(kāi)compile class Compiler extends Tapable { constructor(context) { ...

    Arno 評(píng)論0 收藏0
  • 淺析git

    摘要:淺析筆者在此整理了常見(jiàn)的命令,的重要性無(wú)需多言,與其再百度海中搜索命令,不妨嘗試收藏筆者的此篇作品。旨在快速高效地處理無(wú)論規(guī)模大小的任何軟件工程。其最大特色就是分支及合并操作非常快速簡(jiǎn)便。 淺析git 筆者在此整理了常見(jiàn)的git命令,git的重要性無(wú)需多言,與其再百度海中搜索git命令,不妨嘗試收藏筆者的此篇作品。希望對(duì)你的學(xué)習(xí)有所幫助。 版本控制系統(tǒng)之git Git: (一)簡(jiǎn)介:G...

    explorer_ddf 評(píng)論0 收藏0
  • 淺析git

    摘要:淺析筆者在此整理了常見(jiàn)的命令,的重要性無(wú)需多言,與其再百度海中搜索命令,不妨嘗試收藏筆者的此篇作品。旨在快速高效地處理無(wú)論規(guī)模大小的任何軟件工程。其最大特色就是分支及合并操作非??焖俸?jiǎn)便。 淺析git 筆者在此整理了常見(jiàn)的git命令,git的重要性無(wú)需多言,與其再百度海中搜索git命令,不妨嘗試收藏筆者的此篇作品。希望對(duì)你的學(xué)習(xí)有所幫助。 版本控制系統(tǒng)之git Git: (一)簡(jiǎn)介:G...

    Neilyo 評(píng)論0 收藏0
  • 淺析git

    摘要:淺析筆者在此整理了常見(jiàn)的命令,的重要性無(wú)需多言,與其再百度海中搜索命令,不妨嘗試收藏筆者的此篇作品。旨在快速高效地處理無(wú)論規(guī)模大小的任何軟件工程。其最大特色就是分支及合并操作非??焖俸?jiǎn)便。 淺析git 筆者在此整理了常見(jiàn)的git命令,git的重要性無(wú)需多言,與其再百度海中搜索git命令,不妨嘗試收藏筆者的此篇作品。希望對(duì)你的學(xué)習(xí)有所幫助。 版本控制系統(tǒng)之git Git: (一)簡(jiǎn)介:G...

    Big_fat_cat 評(píng)論0 收藏0
  • python setup.py 淺析

    摘要:淺析參數(shù)說(shuō)明對(duì)于所有列表里提到的純模塊做處理需要在腳本里有一個(gè)包名到目錄的映射。闡明包名到目錄的映射,見(jiàn)鍵代表了包的名字,空的包名則代表不在任何包中的頂層包。最終會(huì)在下生成可執(zhí)行文件,調(diào)用制定的函數(shù)實(shí)例分析 python setup.py 淺析 setuptools.setup() 參數(shù)說(shuō)明 packages 對(duì)于所有 packages 列表里提到的純 Python 模塊做處理 需要...

    sevi_stuo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<