git簡明手冊

一、git概述

區別于svn,git是個分布式的代碼版本控制系統。
在進行所有的操作之前,都需要設置一下個人信息,以區分不同提交者的身份

$ git config -global user.name "your name"
$ git config -global user.email "yourname@example.com"

二、理解代碼的位置

圖1 git 工作空間示意圖

通常情況下,在分布式版本控制中,代碼存放在三個重要的位置:遠程倉庫(Remote)、本地倉庫(Repository)和當前工作空間(workkkspace)。

通常的一次代碼修改包含以下步驟:

  1. 通過fetch/clone將代碼從遠程倉庫(Remote)下載到本地(Repository)
  2. 通過checkout從本地倉庫中找出需要修改的代碼開始修改
  3. git維護的index數據結構維護代碼的變化狀態
  4. 通過add命令讓index知道修改的內容
  5. 通過commit命令將修改提交到本地倉庫
  6. 通過push命令將修改提交到遠程倉庫

2.1 git clone:從遠程倉庫下載代碼

clone :將遠程倉庫下載到本地,指定目錄名則使用指定的目錄名,不指定則和遠程倉庫保持一致

$ git clone <版本庫的網址> <本地目錄名>
$ git clone https://github.com/jquery/jquery.git  #下載JQuery源碼

2.2 git remote:管理遠程主機名

remote:通常情況下遠程主機使用URL表示,不利于開發者記憶,可以使用remote命令給遠程主機命名
下載代碼庫后,如果沒有指定遠程主機的名字,則默認為:origin

$ git remote  #列出這個倉庫相關的所有遠程主機名
origin

$ git clone -o jQuery https://github.com/jquery/jquery.git #使用-o選項指定這個代碼庫的遠程主機名
$ git remote
jQuery

$ git remote -v #查看遠程主機的地址
origin  git@github.com:jquery/jquery.git (fetch)
origin  git@github.com:jquery/jquery.git (push)

$ git  remote show <主機名> #查看遠程主機的詳細信息
$ git remote add <主機名> <網址> #添加遠程主機
$ git remote rm <主機名> #刪除遠程主機
$ git remote rename <原主機名><新主機名>

2.3 git fetch:同步本地代碼庫為最新狀態

fetch:已經有clone可以拉取遠程倉庫的代碼了,為什么還需要fetch命令?
原創解答:如果遠程倉庫只有你一個人使用的話,你使用clone和fetch都是等效的,但是版本控制就是為群體協作而生的,只有一種情況下,你需要使用fetch命令。如下描述:
當你和你的隊友都clone了遠程倉庫的代碼,你的隊友修改完了并且push到了遠程倉庫,這個時候你的本地Repository和remote處于不同步的狀態,你如果使用push提交代碼,會提示錯誤,這個時候你就需要使用fetch同步你本地的Repository和remote然后再提交。

$ git fetch <遠程主機名><分支名稱> #默認情況下,幫你取回的是master分支,如果你要取回其他分支,請指定。
注:比較clone命令,fetch命令不再提供<本地目錄名 >的選項,因為使用這個命令的時候一般本地目錄都已經存在,僅僅是做了Repository和Remote的同步操作
 $ git fetch origin master #取回origin主機的master分支

通常情況下,取回了遠程分支后,要讀取操作遠程分支就需要使用 <遠程主機名/分支名>的格式

$ git branch -r #查看遠程分支
origin/master

$ git branch -a #查看所有分支
* master
  remotes/origin/master

$ git checkout -b newBrach origin/master #在遠程分支的基礎上創建新分支

$ git merge origin/master #合并遠程分支

2.4 git push:同步本地Repository到Remote

push:本地分支所有的修改都已經提交到local Repository后,需要將更新同步到Remote Repository。
只有你進行了push操作后,你的隊友從遠程倉庫下載代碼才可以看到那你的更新。所以本地修改更新完一定不能忘記push操作

注:git push 基于分支進行操作,默認不推送tag,除非使用 --tags指定

$ git push <遠程主機名> <本地分支名>:<遠程分支名> #推送操作是用本地同步遠程,所以后面的參數一定是<本地分支名:遠程分支名>
注:如果省略遠程分支名 ,通常表示你的本地分支名和遠程分支名是一致的,如果不一致,比如你在本地修改了分支名,則在推送時一定要指定遠程分支名,否則將會在遠程創建新的分支

# git push origin master#表示將本地的master分支更新到遠程主機 

通常情況下,我們要刪除一個遠程的分支是這樣操作。
# git push origin --delete master
利用push的特性,我們使用一個空的分支去更新遠程的特定分支,也可以達到刪除的目的
# git push origin :master

如果我們本地的分支和遠程的分支使用的命名是完全一致的,我們可以這樣操作:
# git push  origin
如果本地只有一個分支,操作更加簡單
# git push 

如果你的這個倉庫關聯了多個遠程主機(使用git remote 可以查看),你還想不加任何參數使用git push怎么辦?
解決方法:指定默認的遠程主機
$ git push -u origin master #執行了這個操作后就不需要使用任何參數來使用git push了

最后一個問題:不使用任何參數的git push默認只推送當前分支,即simple模式,還有一種matching模式,會推送所有遠程分支對應的本地分支。你可以通過修改配置文件的方式來選擇自己需要的模式。
$ git config --global push.default.matching
或者
$ git config --global push.default.simple

那么在simple模式下能不能強制推送呢?也是可以的
$ git push --force origin #將本地所有的分支都推送到遠程主機,如果該分支在遠程主機不存在,就創建分支



2.5 git pull :獲取遠程分支同本地分支合并

實際中只有一種情況用到這個命令,當你和你的隊友同時在本地操作同一個分支,他比你先提交,也就意味著此刻你的本地庫比遠程庫要舊,這個時候你如果要push就會被拒絕,可以使用pull把這個分支最新代碼拉下來。
從圖示中就很容易看出來,這個命令直接從遠程拿個分支到本地的工作空間和你正在進行操作的分支進行合并。

$ git pull <遠程主機名><遠程分支名>:<本地分支名> #注意比較這個命令和push的格式的區別
$ git pull origin next:master

$ git pull origin next #獲取遠程的next分支和當前工作空間中正在操作的分支合并
等價于:
$ git fetch origin
$ git merge origin/next
雖然也可以簡單的使用git pull,但是并不建議這么做,需要的自己查手冊吧

三、理解代碼的狀態

圖2 git代碼狀態示意圖

既然是版本控制,肯定要維護代碼不同版本的狀態,git是通過定義了四個不同的存儲區域來維護代碼狀態的。
如圖所示,自左向右存在4個不同區域,對應了代碼的四個不同的新舊程度。

  1. workspace:用戶直接面對的空間就是workspace,這個空間和你操作任何普通目錄時沒有區別的,也不具備跟蹤文件修改狀態的功能,用戶直接在這個空間修改代碼,所以這個空間的代碼狀態最新。
  2. index:普通目錄不具備跟蹤版本功能,index本質是個數據結構,維護指向不同的文件版本的索引,只有在該空間建立索引,才能跟蹤文件的狀態。
  3. local Repository:本地倉庫存儲一次更新的完整版本。
  4. remote Repository:遠程倉庫存儲所有的軟件版本。通常代碼狀態最舊。

代碼版本更新的過程為:workspace-> index -> local repository -> remote repository

3.1 workspace -> index :為指定文件建立版本跟蹤信息

workspace中的文件不具有任何版本信息,和普通目錄一樣,但是可以通過創建索引的形式在index中創建文件的版本信息。

文件修改后,我們通常想知道這次修改的具體內容,可以通過和歷史版本的對比得到。

$ git diff <文件名> #列出工作空間中的指定文件和index中維護的文件不同,如果不指定,則會列出工作空間內所有被跟蹤的文件同index中維護的版本的差異 
注意:不要在提交之后只用該命令,提交后workspace和index的狀態已經同步了,這個命令是沒有輸出的

修改完成后,我們需要將修改,同步到index

$ git add <文件名> #為指定文件創建版本信息

3.2 index -> local repository :提交穩定的版本到本地倉庫

通過將index中最新的版本提交的本地倉庫實現一次完整版本的跟蹤。
注:index跟蹤每一次修改,local Repository跟蹤每一個版本,僅僅是版本控制的粒度的大小不同

提交版本之前,可以通過和歷史版本的對比查看更新的內容

$ git diff -cached
注意:不要在提交后使用這個命令,提交后index和local Repository的版本已經同步了,這個操作沒有輸出。

提交修改,更新本地代碼庫。

$ git commit <文件名>

3.3 workspace -> local repository

注意:只有一種情況可以這么操作,就是該文件已經使用git add在index中建立版本記錄的時候可以實現這個狀態的轉移

$ git diff HEAD  #查看工作空間中的代碼和本地代碼庫的舊版本的相比更新的地方

直接從本地工作空間提交代碼到本地代碼庫

$ git commit -a <文件名>

四、理解分支

很多情況下,我們需要做一些類似與實驗性的特性的開發,這個時候直接在主分支上進行操作不是很合適,我們可以基于主分支創建一個新的分支進行開發,如果開發通過了測試就可以合并到主分支;如果這個實驗性分支不合適,就可以直接刪除。以此降低開發對主分支的影響。

圖3. 一張圖看懂分支.PNG

如上圖所示,一般項目都會維護至少兩條分支,master和dev,master可以理解為我們通常下載軟件時使用的release版本,主要用于穩定版本的發布,一般的開發工作不在master上操作。
開發流程:
正常的開發流程是這個樣的,每個開發者基于dev分支創建新的分支,開發完了以后將分支合并到dev分支,dev分支上的功能通常就是可以測試的了,dev分支打上完整的發布標簽后測試團隊就可以介入對這個版本進行測試,測試通過后就可以合并到master作為穩定版本進行發布。

多人協作

  1. 首先,可以試圖使用 git push origin branch-name 推送自己的修改
  2. 如果推送失敗,則因為遠程分支比你的本地代碼要新,需要先用git pull 試圖合并
  3. 如果合并有沖突,則解決沖突,并在本地提交
  4. 沒有沖突或者解決了沖突后,再用 git push origin branch-name 推送
    注:如果git pull 提示 “No tracking infomation”,則說明本地分支和遠程分支的鏈接關系沒有創建,用命令 git branch --set-upstream branch-name origin/branch-name

4.1 分支操作:git branch

4.2 分支間切換:git checkout

五、總結

回答好下面三個問題就可以基本掌握git了,下面的問題自己去了解吧。

問題一:版本在哪里?(commit 和 tag的區別)####

tag只是commit的一個特殊的狀態,可以認為是里程碑。

問題二:什么是版本控制(HEAD是什么)?####

HEAD是指向你當前操作版本的分支

問題三:如何實現任意版本的切換(log和reflog)?####

log記錄了你當前操作版本之前的每一次提交的日志,reflog其實是真正的日志,記錄每次操作,這個日志和文件系統的日志基本是一樣的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內容