国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

版本管理工具Git 的主要特點

2022-07-11 01:13石慶冬
電子技術(shù)與軟件工程 2022年7期
關(guān)鍵詞:命令分支倉庫

石慶冬

(英特爾(中國)有限公司 北京市 100013)

為了代替BitKeeper,Linux 之父Linus Torvalds 在2005年4 月開發(fā)出了Git,用于Linux 內(nèi)核2.6.12 版本的管理。同年12 月,Git 1.0 正式發(fā)布。當(dāng)初,Git 只是作為替代品,用來管理內(nèi)核代碼。目前,Git 已經(jīng)成為開源軟件項目版本管理工具的首選。Git 通常被認(rèn)為是Global Information Tracker 的縮寫,Git 官網(wǎng)的解釋是傻瓜式內(nèi)容跟蹤器(the stupid content tracker)。在Linux 內(nèi)核目錄里運行如下命令,可以看見Git 用于內(nèi)核版本管理的第一次提交:

1 免費并開源

Git 是免費的,在MacOS,Windows 和Linux/Unix 等主流操作系統(tǒng)下,可以任意下載和安裝Git。安裝包和安裝方法詳見:

https://git-scm.com/downloads

Git 的源代碼是公開的,如果愿意,可以參與到Git 的開發(fā)與維護(hù)當(dāng)中。用如下任意一條克隆命令可得到Git 的代碼庫:

Git 的源代碼,就是用Git 做版本控制的。也可以從源代碼安裝Git,就是先對源代碼進(jìn)行編譯然后再安裝,這需要相應(yīng)的編譯環(huán)境,通常是在Linux 下進(jìn)行。

2 易學(xué)

把Git 學(xué)精比較難,但入門很容易,掌握十條左右的Git 基本命令就可以開展工作了。了解Git 的三個區(qū)和相應(yīng)的三個文件狀態(tài),可以更容易學(xué)習(xí)基本命令。用git clone 命令把代碼倉庫取到本地后,即可進(jìn)入倉庫目錄開始修改文件。被修改過的文件處于工作區(qū),狀態(tài)是已修改(modified);通過git add 命令將修改好的文件放入暫存區(qū),文件的狀態(tài)變?yōu)橐褧捍妫╯taged);再使用git commit 命令將文件放入交付區(qū)(本地倉庫),文件的狀態(tài)變?yōu)橐烟峤唬╟ommitted),如圖1。

圖1:Git 的三個區(qū)

命令git restore --staged 可以將暫存區(qū)的文件移回工作區(qū),命令git reset --soft HEAD^1 可以將已交付的文件移回暫存區(qū)。注意,git restore 命令是在2.23 版本引入的,在這之前,相應(yīng)的命令是git checkout。

在多數(shù)情況下,能接觸到的狀態(tài)是以上三種。文件的狀態(tài)還可以是未跟蹤(untracked),新增(new file),被刪除(deleted)和被改名(renamed)等。

打個比方,車間是工作區(qū),成品倉庫是交付區(qū),倉庫門口是暫存區(qū)。暫放在門口的產(chǎn)品經(jīng)過檢查、清點和記錄后方可入庫。在這個過程中如果發(fā)現(xiàn)產(chǎn)品問題,可以退回。

很多時候不需要使用Git 的命令行,通過簡單易用的圖形界面(GUI)工具就能夠完成多數(shù)任務(wù)。例如,Windows下的SourceTree,Linux 下的gitk 和gitg 等。在各種主流操作系統(tǒng)下常用的Git 圖形界面工具在官網(wǎng)有介紹:

https://git-scm.com/downloads/guis/

在命令行模式下,可以執(zhí)行到Git 所有的命令及其所有的功能。而圖形界面工具,從功能上說,是命令行的子集,圖形工具不可能把命令行的功能全部實現(xiàn),真是那樣的話,圖形工具將被做得非常復(fù)雜并且令人眼花繚亂,失去了圖形界面讓人感覺易學(xué)易用的初衷。學(xué)會了命令行,再學(xué)習(xí)相應(yīng)的GUI 中的功能時,基本上不會有困難,反之就不一定了。對于初學(xué)者,命令行和圖形界面工具可以一起相輔相成地學(xué)習(xí)。

3 分布式

版本管理工具分為集中式(Centralized)和分布式(Distributed)兩種。比較常見的集中式工具有CVS,Subversion 和Perforce。在集中式的版本管理模式下,有一臺機(jī)器作為中央服務(wù)器,存放版本庫的全部內(nèi)容(分支、標(biāo)簽、修改歷史和版本庫的相關(guān)配置等),服務(wù)器的管理員可以輕松掌控每個賬戶的權(quán)限。開發(fā)人員工作在處于客戶端的機(jī)器上,開發(fā)者拿到的代碼,是按照某種配置規(guī)則得到自己權(quán)限范圍內(nèi)的某套版本代碼的快照。如果開發(fā)人員想查看某個文件在另一個分支的內(nèi)容,或者需要把修改好的文件提交,必須與服務(wù)器保持聯(lián)網(wǎng)。如果網(wǎng)絡(luò)或者服務(wù)器出現(xiàn)故障,開發(fā)人員無法提交更新,無法與他人協(xié)同工作。如果服務(wù)器的磁盤發(fā)生損壞并且沒有事先備份,很可能某些數(shù)據(jù)將永遠(yuǎn)丟失,即使把每位開發(fā)人員的快照都拿到、也很難恢復(fù)原本的數(shù)據(jù)庫。而分布式則不然。

在分布式模式下,開發(fā)人員一旦拿到代碼,不是僅提取到最新版本的、或者某種配置規(guī)則下的文件快照,而是將整個版本庫復(fù)制到本地,版本庫中所有的分支、標(biāo)簽、版本庫從創(chuàng)建到當(dāng)前所有的修改歷史(每次提交的信息)一應(yīng)俱全。本地機(jī)器有了版本庫后,開發(fā)者可以離線工作,本地機(jī)器既是客戶機(jī)也是服務(wù)器。一起協(xié)同工作的任何一臺機(jī)器發(fā)生故障,都不用擔(dān)心數(shù)據(jù)會丟失,因為這時可以從其他機(jī)器得到完整數(shù)據(jù)庫。當(dāng)然,無論是分布式還是集中式,平時都要做好數(shù)據(jù)庫的備份工作。

如果網(wǎng)絡(luò)中斷,使用Git 的開發(fā)者仍然可以繼續(xù)交互。git bundle 命令可以對一段時間的工作成果進(jìn)行打包,打包成一個文件,然后用U 盤拷貝給其他人。git bundle 命令也可以針對某個分支或者整個倉庫進(jìn)行打包。拿到包的開發(fā)者,用git fetch 命令即可得到需要的內(nèi)容。還可以使用命令git format-patch 生成補(bǔ)丁文本文件,再將補(bǔ)丁提供給需要的人。開發(fā)者拿到補(bǔ)丁后,用git am 命令可以將補(bǔ)丁打在自己的分支上??傊?,在分布式模式下,即便是網(wǎng)絡(luò)中斷了,團(tuán)隊的協(xié)作開發(fā)也不被完全終止。

4 并行開發(fā)十分方便

一個Git 倉庫在建立之初默認(rèn)只有主分支master,通過git branch 命令建立多個分支可以實現(xiàn)并行軟件開發(fā)。如圖2,工程師在工作告一段落后,可將本地新增的內(nèi)容推送到遠(yuǎn)程的公共倉庫,也可以隨時把遠(yuǎn)程倉庫的新增內(nèi)容同步到本地,使用git switch 命令進(jìn)行分支的切換,就可以看見其他分支的變化。使用git merge 和git rebase 命令可以實現(xiàn)分支之間的合并和代碼的同步。

圖2:本地倉庫與遠(yuǎn)程倉庫

使用git cherry-pick 命令可以直接從其他分支上拿到某次提交的內(nèi)容應(yīng)用到當(dāng)前分支,正如字面意思,該命令用于篩選自己所需的內(nèi)容。

在并行開發(fā)過程中幾乎都會遇到代碼沖突的問題,而且不可能完全避免。當(dāng)同一個文件有兩個或以上的人修改,或者本地代碼長時間保持孤立時,就容易產(chǎn)生沖突。如果同一個項目組的每個人都經(jīng)常和遠(yuǎn)程倉庫同步,修改同一個模塊的人經(jīng)常在一起走讀和相互審核代碼,則可以大大降低沖突出現(xiàn)的概率。

GitFlow 工作流定義了一個圍繞項目開發(fā)的嚴(yán)格分支模型,它為不同的分支分配了明確的角色,并定義分支之間何時以及如何進(jìn)行交互,分支命名也有規(guī)范。master 分支只存放穩(wěn)定版本的代碼,用作軟件的正式對外發(fā)布,不能直接向master 分支推送,它的內(nèi)容只能來自其他分支的合并。develop 分支為主開發(fā)分支,基于master 分支克隆。release 分支用于軟件對內(nèi)發(fā)布并提交測試。feature 分支基于develop 分支克隆,主要用于新需求和新功能的開發(fā)??梢杂卸鄠€feature 分支,因為可能有多個新功能同時開發(fā)。hotfix 分支用于修復(fù)具體的問題,它的名字一般包含缺陷跟蹤號,修復(fù)完成并驗證后合并到其他種類的分支上。一個項目組遵從統(tǒng)一的分支管理流程,可以提高開發(fā)效率并更容易解決或者減少代碼的沖突。

5 未完成的工作可以暫存

當(dāng)文件修改到一半還沒有提交到版本庫時,如果遇到一個緊急的任務(wù),這時可使用git stash 或者git stash push 命令把未完成的工作現(xiàn)場保存起來(壓棧)。等緊急任務(wù)完成后,再使用git stash pop 命令恢復(fù)剛才的工作現(xiàn)場(出棧)。

暫存的任務(wù)可以有多個,用git stash list 命令查看它們,編號從0 開始。git stash pop 命令默認(rèn)恢復(fù)最后一個入棧的任務(wù),也可將任務(wù)編號作為參數(shù)來恢復(fù)指定的任務(wù)。用git stash drop 命令丟棄不再需要的任務(wù)。

git stash 命令不是必須使用的。當(dāng)遇到緊急任務(wù)時,完全可以建立一個新的目錄,在新目錄里重新克隆一份代碼,建立一個新分支,在新目錄里的新分支上完成緊急任務(wù)即可。如果希望緊急任務(wù)和老任務(wù)處在同一個工作目錄里,以方便參考或合并,就應(yīng)該使用git stash 命令。

6 強(qiáng)大的查詢功能

在軟件的開發(fā)過程中,不變的是,代碼一直在變,需求隨時會變,尤其是多人協(xié)同開發(fā)的大型軟件項目。大開發(fā)團(tuán)隊的工程師常常來自不同的部門,不同的城市,甚至不同的國家。某工程師休假歸來甚至一覺醒來,有可能發(fā)現(xiàn)了大量新代碼,這時,查詢一下代碼的歷史對理解新內(nèi)容很有幫助。

git log 命令的功能十分強(qiáng)大,可以查看一個文件從創(chuàng)建到當(dāng)前所有的修改記錄,包括每一次的修改時間、修改人、提交人、修改內(nèi)容等。git log 可以按照作者查詢,可以查詢指定時間段的修改內(nèi)容,也能針對某個目錄或者整個倉庫查詢。例如,在Linux 內(nèi)核代碼中查詢作者為Eric 的最近5 次提交信息:

命令git grep 用于在代碼中搜索字符串,可以是具體的字符串,也可以是正則表達(dá)式。例如,在Linux 內(nèi)核代碼中列出包含字符串tty_add_file 的文件:

假設(shè)發(fā)現(xiàn)某軟件版本有一個問題,僅從歷史信息不容易確定是哪一次提交引起的,這時可使用命令git bisect,該命令使用二分法,可以幫助迅速地定位引起問題的是哪一次提交。

命令git blame 是針對文件的,它可以列出文件每一行的最后一次提交信息,包括SHA1 值,作者名,提交時間,行號,該行的具體內(nèi)容等。就是說,通過git blame 命令,每一行代碼的是誰寫的,什么時候?qū)懙?,一目了然?/p>

git diff命令可用來比較不同分支或不同標(biāo)簽的內(nèi)容差異,也可以比較工作區(qū)和暫存區(qū)、暫存區(qū)和本地倉庫的不同,還可以比較某兩次提交的區(qū)別。利用git diff命令也可以生成補(bǔ)丁文件。

7 有多個支持Git的托管平臺

為防止意外發(fā)生,代碼倉庫一定不能只放在本地機(jī)器上。第三方托管平臺是一個很好的選擇,比較有名的平臺有g(shù)ithub,gitlab,gitee(碼云),coding 和bitbucket 等,網(wǎng)址分別為:https://github.com/;https://about.gitlab.com/;https://gitee.com/;https://coding.net/和https://bitbucket.org/。

使用托管平臺可以快速地建立并開展項目,節(jié)省了服務(wù)器的搭建與維護(hù)工作。托管平臺不是僅僅提供了存放代碼的空間,還可以用來在線編輯文件、查看文件修改歷史、軟件缺陷跟蹤、代碼審核、代碼合并、版本比較和權(quán)限管理等。免費的、收費的、開放給個人的和開放給公司的等各種類型的服務(wù),托管平臺都具備,選擇適合自己的就好。

托管平臺通常以網(wǎng)頁的形式使用,也可以安裝其客戶端。例如,在https://desktop.github.com/ 可以下載github在Windows 上的客戶端。Github 還有手機(jī)客戶端,地址為https://github.com/mobile,安裝后,在手機(jī)和平板電腦上也可以查看代碼。

8 Repo擴(kuò)展了Git

Linux 內(nèi)核代碼的Git 倉庫地址為:

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux

內(nèi)核的代碼量很大,但一個Git 倉庫已經(jīng)足夠管理它?,F(xiàn)在幾乎人手一部安卓智能手機(jī),安卓的代碼量非常巨大,它是一個多方合作的項目,有很多模塊,不同的模塊由不同的組織或公司維護(hù)。最新的安卓版本包含的Git 倉庫超過了1000 個。是否要運行多次git clone 命令才能取到全部的安卓代碼?當(dāng)然不是。安卓的Manifest 是一種xml 格式的文本文件,它包含了相應(yīng)版本所需的各個倉庫的配置信息(實際上Manifest 還包含其他信息,并非簡單地把所需倉庫的地址堆放在一起)。如下命令可取得安卓12.0.0_r27 版本的Manifest 文件,內(nèi)含1051 個Git 倉庫的信息:

repo init -u https://android.googlesource.com/platform/manifest -b android-12.0.0_r27

再運行repo sync 命令,等待一段時間,即得到該版本的全部代碼。Repo 是一個用Python 腳本寫的工具,它可以管理多個Git 倉庫。這里的一條repo sync 命令,相當(dāng)于1051 條git clone 命令??梢哉f,基于Manifest 文件,repo命令擴(kuò)展了git 命令。

9 權(quán)限控制能力弱

使用Git 取代碼時,整個倉庫都被取到。如果希望倉庫的某個分支或某個目錄不對特定用戶開放,缺省配置是做不到的,Git 自身遵循開源的原則,基本上沒有權(quán)限控制能力。Git具備鉤子(Hook)機(jī)制,Hook可以做一些權(quán)限控制的事情,但這不是Hook 的主要作用。使用git submodule 命令設(shè)置子模塊,可以控制子模塊的權(quán)限。總之,Git 的權(quán)限控制能力不強(qiáng)。

Git 通常需要借助其他工具完善權(quán)限的控制。例如,Gitlab 把用戶分為不同的角色, 有Guest、Reporter、Developer、Maintainer 和Owner。簡單地說,Guest(訪客)權(quán)限最小,只能提交問題和發(fā)表評論;Reporter(問題報告人)可以克隆代碼;Developer(開發(fā)者)可以修改代碼;Maintainer(項目管理員)可以改寫或刪除標(biāo)簽、保護(hù)分支、添加項目成員、編輯項目等;Owner(系統(tǒng)管理員)權(quán)限最高,可以刪除項目,設(shè)置賬戶的角色等。

10 歷史可改寫

現(xiàn)實生活中已經(jīng)發(fā)生的事情不可能被改變,但Git 可“篡改歷史”。如果要舍棄最后一次提交,可以用 git reset --hard HEAD^1 命令。如果想修改最后一次提交信息,可以用帶選項--amend 的git commit 命令。帶選項-i 的git rebase 命令,可用來拆分、合并、去掉提交信息,或者調(diào)整提交順序。當(dāng)然,這些動作可能會引起問題,因為代碼的修改常常是有繼承性的。

git filter-branch 命令可以以腳本的方式修改大量的歷史條目。例如,你的電子郵箱變了,如果希望以前的歷史記錄當(dāng)中都顯示新郵箱,就可以使用這條命令重寫歷史。

當(dāng)本地倉庫某個分支的歷史被改寫后,用git push 命令基本上是無法上傳到遠(yuǎn)程倉庫的,因為本地分支與遠(yuǎn)程倉庫的相應(yīng)分支是有沖突的(歷史有差別),加上選項-f 可強(qiáng)行推送到遠(yuǎn)程倉庫、并完全覆蓋原有的遠(yuǎn)程分支。

文件的歷史可改寫,這很靈活,某些人認(rèn)為是優(yōu)點,他們的理由是:誰會關(guān)心空調(diào)說明書的第一版草稿的內(nèi)容?但是,一般地,選項-f 不推薦使用,畢竟沒有尊重歷史。業(yè)界的建議是,在自己充分滿意和充分驗證之前,不要推送你的工作成果。

如果發(fā)現(xiàn)是某次歷史提交引起了新問題,可以針對具體的問題做修改,或者用git revert 命令反向提交來沖抵引發(fā)問題的內(nèi)容(回滾),不應(yīng)首選“篡改歷史”。有的公司或組織,針對特定的分支是禁用強(qiáng)制推送的。

11 基于和支持Git的工具多種多樣

代碼審核是軟件開發(fā)過程中的重要一環(huán)。Gerrit 是一個免費、開源、建立在Git 之上、基于網(wǎng)頁界面的代碼審查工具。很多安卓代碼使用Gerrit 作為審核工具,工程師修改好的代碼不是直接推送到遠(yuǎn)程倉庫,而是先上傳到Gerrit 服務(wù)器,審查通過后才能進(jìn)入遠(yuǎn)程倉庫的集成分支。

Git 倉庫并非只能用來存儲代碼,也可以存放二進(jìn)制文件。二進(jìn)制文件往往比較大,每改變一次,對于倉庫來說會增加很大的體積,動輒就是幾個G,倉庫的總體積會增加很快。采用Git LFS(Large File Storage)機(jī)制,將大文件存放在專門的服務(wù)器,在倉庫中放置追蹤大文件的、只有幾行內(nèi)容的文件文件,相當(dāng)于保存了指向大文件的指針,大文件有變化時就改變指針信息,避免了倉庫的體積增長過快。僅當(dāng)需要用到大文件時,運行g(shù)it lfs pull命令,大文件就會被下載。LFS 機(jī)制的引入,極大地節(jié)省了空間和提高了倉庫拉取速度。

很多流行的持續(xù)集成和持續(xù)交付工具支持Git,或者說能夠很好地與Git 配合。例如,Jenkins,TeamCity 和Buildbot 等。

如果項目中有一個庫是用SVN(Subversion)管理的,如果你打算使用Git 又不想轉(zhuǎn)變SVN 版本庫,可以使用git svn 命令,該命令相當(dāng)于Git 與SVN 的一個雙向橋接。注意,安裝完Git 之后默認(rèn)是沒有g(shù)it svn 命令的,需要單獨安裝。例如,Ubuntu 系統(tǒng)中的安裝命令是sudo apt-get install gitsvn。

隨著Python 語言的普及,使用集成開發(fā)環(huán)境PyCharm的人越來越多,在PyCharm 中安裝Git 插件之后,通過PyCharm 就可以直接克隆Python 代碼到本地。同樣,也可以在Visual Studio 中使用Git,詳見https://code.visualstudio.com/Docs/editor/versioncontrol。

Git 的源代碼中有一個文件git-completion.bash,把它添加到.bashrc 之后,在Linux 的bash 環(huán)境下使用Git 時,命令可以自動補(bǔ)齊。

可以在Java 程序中使用Git,JGit 是Git 版本控制系統(tǒng)的輕量級的純Java 庫實現(xiàn),包括存儲庫訪問例程、網(wǎng)絡(luò)協(xié)議和核心版本控制算法。在Java 社區(qū)中JGit 被廣泛使用。

總之,在很多軟件工具的使用過程中會發(fā)現(xiàn)Git 的“身影”,Git 已經(jīng)無處不在。

12 命令有高層底層之分

Git 的常用命令大多為“高層命令”,Git 還為用戶提供了“底層命令”。普通用戶一般只需要知道高層命令,如果想更深入地了解Git,最好學(xué)習(xí)一下它的底層命令。

Git 是直接記錄快照,而非像SVN 那樣做文件的差異比較。Git 可以做到時刻保持?jǐn)?shù)據(jù)完整性。Git 實際上是一套內(nèi)容尋址文件系統(tǒng),采用的是哈希的方式進(jìn)行存儲和查找,也就是說,Git 只是通過簡單的存儲鍵值對(key-value)的方式來實現(xiàn)內(nèi)容尋址的,key 就是文件的哈希值,value 就是經(jīng)過壓縮后的文件內(nèi)容。下面舉例說明兩個底層命令的使用。

先產(chǎn)生一個文本文件,內(nèi)容為test,然后用git hashobject 查看其哈希值:

這時進(jìn)入目錄.git/objects/里面,可以發(fā)現(xiàn)一個子目錄,子目錄的名字就是剛才的哈希值的前兩位,子目錄里面有個文件,文件名就是該哈希值的后38 位:

帶選項-p 的git cat-file 命令可查看哈希值對應(yīng)的內(nèi)容,換為選項-t 時顯示相應(yīng)的類型,blob 一般就是指文件:

13 結(jié)語

Git 并非完美無瑕,它有優(yōu)點也有缺點。Git 的命令很多,命令的選項也非常多,一篇文章很難涵蓋它的所有特點。平均一個季度左右,Git 官網(wǎng)會有新版本發(fā)布,其功能日臻成熟和完善。從事軟件相關(guān)工作的人員,和程序設(shè)計相關(guān)專業(yè)的在校師生,了解和學(xué)習(xí)Git 都會受益匪淺。

猜你喜歡
命令分支倉庫
只聽主人的命令
填滿倉庫的方法
四行倉庫的悲壯往事
巧分支與枝
移防命令下達(dá)后
一類擬齊次多項式中心的極限環(huán)分支
這是人民的命令
消防設(shè)備
生成分支q-矩陣的零流出性
碩果累累