Git內部培訓課件

Git內部培訓課件

Git簡介

什麼是版本控制

版本控制系統(Version Control System,簡稱VCS)是一種記錄一個或若干文件內容變化,以便將來查閱特定版本修訂情況的系統。

按類型可以分爲:

  • 本地版本控制系統

    例如RCS(至少我是從來沒有用過) 本地版本控制系統解決了版本的管理問題,再也不用時不時的把工程目錄,通過手工拷貝的方式來存檔了。但本地版本控制系統的缺點是,無法解決多人協作的問題。
  • 集中化的版本控制系統

    例如CVS,SVN等(公司中SVN應該用的比較多) 有一個集中管理的服務器,所有開發人員通過客戶端連到這臺服務器,取出最新的 文件 或者提交更新。管理員可以掌控每個開發者的權限。 集中化的VCS不但解決了版本控制問題,還可以多人協作。但缺點也是有的,就是太依賴於遠程服務器,CVS服務器宕機後,會影響所有人的工作。版本記錄只保存在一臺服務器上,會有數據丟失風險。
  • 分佈式版本控制系統

    例如Git 客戶端並不只提取最新版本的文件,而是把 代碼倉庫 完整地鏡像下來。每一次的提取操作,實際上都是一次對 代碼倉庫 的完整備份。 所以並沒有"中心服務器"的概念,所謂的"Git服務器",也同每個人的電腦一樣,只是爲了多人協作時,方便大家交換數據而已。

什麼是Git

Git是目前世界上最先進的分佈式版本控制系統(沒有之一) 好不好用,看看它的開發者是誰就知道了:Linux之父 Linus Torvalds

小歷史: Linux內核社區原本使用的是名爲BitKeeper的商業化版本控制工具,2005年,因爲社區內有人試圖破解BitKeeper的協議,BitMover公司收回了免費使用BitKeeper的權力。 Linus原本可以出面道個歉,繼續使用BitKeeper,然而並沒有。。。Linus大神僅用了兩週時間,自已用C寫了一個分佈式版本控制系統,於是Git誕生了!

爲什麼要使用Git

爲什麼要使用Git,或者說Git相比SVN有什麼優勢呢?

  • 分佈式

  • 分支管理

  • GitHub

安裝Git

  • 大多數Linux發行版已經預裝了Git,系統默認自帶,如果不帶。。可以源碼make安裝或使用yum/apt等直接安裝,過程不贅述了。
  • macOS下,安裝Xcode後,它的CLI工具裏應該會包含Git了。或者使用brew手工安裝一下。
  • Windows下,可以直接下載安裝 msysGit 。 或者如果你的機器上已經有Cygwin,也可以直接用在它下面安裝Git。
  • 圖形工具推薦使用 SourceTree,查看分支非常直觀 。IntelliJ IDEA等IDE也會自帶一些圖形化的工具,在合併代碼時很高效。

學習路徑

  • 首先,忘掉SVN/CVS,不要把Git的各種操作與它們做類比,切記。
  • 剛開始不要依賴圖形客戶端。首先應該將精力用在理解原理上 -> 然後掌握一些基本CLI命令,動手操作實踐 -> 最後在實際工作中使用GUI工具以提高效率。
  • 重度Windows用戶使用Git時,與平時熟悉GUI的環境會有些違和感,畢竟Git是Linux下的產物,Git遵循Linux的哲學,Simple,簡單直接,但Simple並不等於Easy。需要轉換一下思維。

瞭解Git的工作原理

記錄文件整體快照

Git和其他版本控制系統的主要差別在於,Git只關心文件數據的 整體 是否發生變化,而大多數其他系統則只關心 文件內容 的具體差異。

SVN在每個版本中,以單一文件爲單位,記錄各個文件的差異:

Git在每個版本中,以當時的全部文件爲單位,記錄一個快照:

大多數操作都在本地執行

Git的絕大多數操作都只需要訪問本地文件和資源,不用連網。因爲你的本機上,就已經是完整的代碼庫了。這樣一來,在無法連接公司內網的環境中,也可以愉快的寫代碼了。 例如,如果想看當前版本的文件和一個月前的版本之間有何差異,Git會取出一個月前的快照和當前文件作一次差異運算,而不用每次都請求遠程服務器。

時刻保持數據完整性

在保存到Git之前,所有數據都要進行內容的校驗和(checksum)計算,並將此結果作爲數據的唯一標識和索引。 這項特性作爲Git的設計哲學,建在整體架構的最底層。所以如果文件在傳輸時變得不完整,或者磁盤損壞導致文件數據缺失,Git都能立即察覺。 Git使用SHA-1算法計算數據的校驗和,通過對文件的內容或目錄的結構計算出一個SHA-1哈希值,作爲指紋字符串。該字串由40個十六進制字符組成,看起來就像是: 24b9da6552252987aa493b52f8696cd6d3b00373 Git的工作完全依賴於這類指紋字串,所以你會經常看到這樣的哈希值。實際上,所有保存在 Git數據庫中的東西都是用此哈希值來作索引的,而不是靠文件名。

多數操作僅添加數據

常用的Git操作大多僅僅是把數據添加到數據庫,很難讓Git執行任何不可逆操作。在Git中一旦提交快照之後就完全不用擔心丟失數據,特別是養成定期推送到其他倉庫的習慣的話。

文件的三種狀態

對於任何一個文件,在 Git 內都只有三種狀態:已提交(committed) 已修改(modified) 已暫存(staged) 已提交表示該文件已經被安全地保存在本地數據庫中了; 已修改表示修改了某個文件,但還沒有提交保存; 已暫存表示把已修改的文件放在下次提交時要保存的清單中。

由此我們看到 Git 管理項目時,文件流轉的三個工作區域:Git 的工作目錄,暫存區域,以及本地倉庫。

每個項目都有一個名爲.git的目錄,它是 Git用來保存元數據和對象數據庫的地方。該目錄非常重要,每次克隆鏡像倉庫的時候,實際拷貝的就是這個目錄裏面的數據。 從項目中取出某個版本的所有文件和目錄,用以開始後續工作的叫做工作目錄。這些文件實際上都是從Git目錄中的壓縮對象數據庫中提取出來的,接下來就可以在工作目錄中對這些文件進行編輯。 所謂的暫存區域只不過是個簡單的文件,一般都放在 Git 目錄中。有時候人們會把這個文件叫做索引文件,不過標準說法還是叫暫存區域。

基本的 Git 工作流程如下:

  1. 在工作目錄中修改某些文件。
  2. 對修改後的文件進行快照,然後保存到暫存區域。
  3. 提交更新,將保存在暫存區域的文件快照永久轉儲到 Git 目錄中。

所以,我們可以從文件所處的位置來判斷狀態:如果是Git目錄中保存着的特定版本文件,就屬於已提交狀態;如果作了修改並已放入暫存區域,就屬於已暫存狀態;如果自上次取出後,作了修改但還沒有放到暫存區域,就是已修改狀態。

創建版本庫

有兩種取得Git項目倉庫的方法。第一種是在現存的目錄下,通過導入所有文件來創建新的Git倉庫。 第二種是從已有的Git倉庫克隆出一個新的鏡像倉庫來。

在目錄中創建新倉庫

如果一個目錄還沒有使用Git進行管理,只需到此項目所在的目錄,執行git init,初始化後,在當前目錄下會出現一個名爲.git的目錄

$ mkdir learngit
$ cd learngit
$ git init

從已有的倉庫克隆

如果Git項目已經存在,可以使用git clone從遠程服務器上覆制一份出來,Git支持多種協議:

$ git clone mobgit@134.32.51.60:learngit.git  #使用SSH傳輸協議
$ git clone git://134.32.51.60/learngit.git  #使用Git傳輸協議
$ git clone https://134.32.51.60/learngit.git  #使用HTTPS傳輸協議

版本庫基本操作

檢查當前文件狀態

使用git status命令可以查看文件的狀態

$ git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)

出現如上的提示,說明現在的工作目錄相當乾淨,所有已跟蹤文件在上次提交後都未被更改過。

現在我們做一些改動,添加一個readme.txt進去,然後再看一下狀態

$ cat>readme.txt
hello git
^C

git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    readme.txt

nothing added to commit but untracked files present (use "git add" to track)

Untracked files顯示了這個新創建的readme.txt處於未跟跟蹤狀態

跟蹤新文件

使用git add命令開始跟蹤一個新文件

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   readme.txt

readme.txt已 被跟蹤 ,並處於 暫存狀態

將本次修改暫存

現在我們再對readme.txt進行修改,添加一行,再執行git status查看狀態

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   readme.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   readme.txt

可以看到readme.txt 不僅出現在了Changes to be committed,還出現在了Changes not staged for commit
由此可見,Git關心的是 Changes ,而不是文件本身。
再次執行git add,可以將 本次修改 提交到暫存區,Changes not staged for commit提示消失

提交更新

使用git commit命令將暫存區中的內容提交至版本庫,工作區又是乾淨的了

$ git commit -m "my first commit"
[master (root-commit) 6c8912a] my first commit
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

$ git status
On branch master
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)
nothing to commit, working tree clean

注意:一定要使用-m參數加入註釋,認真描述本次的提交具體做了些什麼,這對於以後我們查詢歷史記錄非常重要。

如果覺得使用暫存區過於繁瑣,可以在commit時直接使用-a參數,Git就會自動把所有已經跟蹤過的文件暫存起來一併提交,從而跳過git add步驟。

$ git commit -a -m "my first commit"

查看歷史

使用git log命令可以查看歷史記錄

$ git log
commit 43c5d337ffdd76f33ce5f5f90103d57e55474956
Author: BlueXIII <bluexiii@163.com>
Date:   Thu Dec 8 14:45:59 2016 +0800

    this is my second commit

commit 6c8912ad2a8e90a7ba32cc8578fd0069a205221b
Author: BlueXIII <bluexiii@163.com>
Date:   Thu Dec 8 14:38:09 2016 +0800

    my first commit

可以看到,每次更新都有一個SHA-1校驗和、作者的名字和電子郵件地址、提交時間、提交說明。

撤消操作

撤消操作在這裏這裏不做重點描述了,只列出幾個常用命令。
修改最後一次提交:
git commit --amend
取消已經暫存的文件:
git reset HEAD readme.txt
取消對文件的修改:
git checkout -- readme.txt

遠程倉庫

之前介紹了在本地倉庫的一些操作。但當與他人協作開發某個項目時,需要至少使用一個遠程倉庫,以便推送或拉取數據,分享各自的工作進展。

克隆遠程庫

之前已經在講新建倉庫時已經提到,如何克隆遠程庫,這裏再重複列一遍:

$ git clone mobgit@134.32.51.60:learngit.git  #使用SSH傳輸協議
$ git clone git://134.32.51.60/learngit.git  #使用Git傳輸協議
$ git clone https://134.32.51.60/learngit.git  #使用HTTPS傳輸協議

查看綁定的遠程庫

如果之前我們使用的git clone命令直接克隆了一個遠程倉庫到本機,Git就已經默認綁定了一個名爲origin的遠程庫。當然我們還可以手工綁定其它遠程庫,遠程倉庫可以有多個。
使用git remote -v命令列出我們綁定了哪些遠程庫:

$ git remote -v
origin  mobgit@134.32.51.60:learngit.git (fetch)
origin  mobgit@134.32.51.60:learngit.git (push)

接下來還可以使用git remote show origin來查看這個名爲origin的遠程庫的更詳細的信息,這裏先不細講

$ git remote show origin
* remote origin
  Fetch URL: mobgit@134.32.51.60:learngit.git
  Push  URL: mobgit@134.32.51.60:learngit.git
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    dev
    master
    serverfix
    serverfix2
  Remote branches:
    dev        tracked
    master     tracked
    serverfix  tracked
    serverfix2 tracked
  Local branches configured for 'git pull':
    dev        merges with remote dev
    master     merges with remote master
    serverfix  merges with remote serverfix
    serverfix2 merges with remote serverfix2
  Local refs configured for 'git push':
    dev        pushes to dev        (up to date)
    master     pushes to master     (up to date)
    serverfix  pushes to serverfix  (up to date)
    serverfix2 pushes to serverfix2 (up to date)

手工添加一個遠程倉庫

我們先讓管理員新建一個名爲learngit2的遠程倉庫,再使用remote add命令將它添加進來,取名爲repo2

$ git remote add repo2 mobgit@134.32.51.60:learngit2.git

$ git remote -v
origin  mobgit@134.32.51.60:learngit.git (fetch)
origin  mobgit@134.32.51.60:learngit.git (push)
repo2   mobgit@134.32.51.60:learngit2.git (fetch)
repo2   mobgit@134.32.51.60:learngit2.git (push)

現在我們有origin和repo2兩個遠程倉庫了

從遠程倉庫抓取數據

使用git fetch [remote-name]從遠程倉庫抓取數據,注意fetch命令只是將遠端的數據拉到本地倉庫,並不自動合併到當前工作分支(關於分支稍後講解)
例如要抓取名爲origin遠程倉庫:

$ git fetch origin

推送數據到遠程倉庫

使用git push [remote-name] [branch-name]將本機的工作成果推送到遠程倉庫
例如要將本地的master分支推送到origin遠程倉庫上:

$ git push origin master

分支

也許到之前爲止,大家會覺得Git和Svn除了實現原理不同以及實現了分佈式之外,在日常使用上並沒有什麼太大的區別(甚至更繁瑣)。但接下來的分支,纔是Git的精髓部分。

爲什麼要使用分支

舉個簡單的例子:假設你準備開發一個新功能,但是需要兩週才能完成,第一週你寫了50%的代碼,如果立刻提交,由於代碼還沒寫完,不完整的代碼庫會導致別人不能幹活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。
於是你創建了一個屬於你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工作。
相比於Svn等工具,Git創建、切換分支的開銷是非常小的,Git鼓勵 頻繁使用分支

分支的原理

要理解分支,需要繼續深入一下Git的工作原理

Git如何儲存數據

在Git中提交時,會保存一個提交對象(commit object),該對象包含一個指向暫存內容快照的指針,並同時包含本次提交的作者等相關附屬信息,包含零個或多個指向該提交對象的父對象指針(首次提交是沒有直接祖先的,普通提交有一個祖先,由兩個或多個分支合併產生的提交則有多個祖先)。

假設在工作目錄中有三個文件已經 修改 過,準備將它們暫存後提交。
git add暫存操作時,會對 每一個文件 計算校驗和,然後把當前版本的文件快照使用 blog對象 保存到Git倉庫中(爲提高性能,若文件沒有變化,Git不會再次保存)。將它們的SHA-1校驗和加入到暫存區域等待提交。
git commit提交操作,時,Git首先會計算 每一個子目錄 的校驗和,然後將這些校驗和保存爲 tree對象 。 然後Git會創建一個 commit對象 ,它包含指向這個樹對象的指針及註釋、提交人、郵箱等信息。
現在,Git倉庫中有五個對象:三個blob 對象(保存着文件快照);一個樹對象(記錄着目錄結構和blob對象索引)以及一個提交對象(包含着指向前述樹對象的指針和所有提交信息)。

單個提交對象在倉庫中的數據結構:


多個提交對象之間的鏈接關係:

分支是什麼

Git 中的分支,其實本質上僅僅是個指向commit對象的可變指針。Git會使用master作爲分支的默認名字。在若干次提交後,你其實已經有了一個指向最後一次commit對象的master分支。它在每次提交的時候都會自動向前移動。

創建名爲testing的新的分支,本質上就是創建一個指針,可以使用git branch命令:

$ git branch testing

當前工作在哪個分支

Git 是如何知道你當前在哪個分支上工作的呢?其實答案也很簡單,它還保存着一個名爲HEAD的特別指針。它是一個指向你正在工作中的本地分支的指針。


切換分支時發生了什麼

切換分支,本質上就是移動HEAD指針。
要切換到其他分支,可以執行git checkout命令。我們現在轉換到剛纔新建的testing分支:

$ git checkout testing

分支切換的實際操作

爲了更好的理解分支,我們接下來模擬實際工作中的場景,進行一系列的切換操作。
現在我們已經處於testing分支了,目前testing分支和master分支都是指向同一個commit,所以我們的工作區的內容現在還沒有什麼變化。
現在,我們要在testing分支上做一些文件修改,然後commit:

echo "testing branch">>readme.txt
git commit -a -m "modify on testing branch"

提交後,產生了一個新的commit對象,並且HEAD隨着當前testing分支一起向前移動。而master分支則是停在原地不動。

我們可以試着使用git checkout命令切回master分支,看看發生了什麼:

$ git checkout master

這條命令做了兩件事:
  1. 它把HEAD指針移回到 master 分支。
  2. 把工作目錄中的文件換成了master分支所指向的快照內容。

我們試着在master上再做一些改動並commit:

echo "testing master">>readme.txt
git commit -a -m "modify on master branch"

現在分支變成了上圖所示,我們可以在master與testing間隨時切換,並修改工作區的文件內容。必要時再將這兩個分支合併。

分支新建與合併的實際操作

接下來,再以一個比較長的真實的工作場景進行舉例

我們首先在master分支上進行工作,並提交了幾次更新,測試無誤後編譯發佈至生產系統。


之後我們決定要修補問題追蹤系統上的53號問題,這時可以使用git checkout -b命令快速創建一個分支並切換過去:

$ git checkout -b iss53

這相當於執行了下面這兩條命令:

$ git branch iss53
$ git checkout iss53

我們在iss53分支上寫了一些代碼,並commit

$ vi index.html
$ git commit -a -m 'fixed the broken email address'

iss53上的工作還沒完成,突然接到通知,生產系統有一個緊急BUG需要立刻修復。所以我們首先切回master分支,然後在master的基礎上,又新建出一個hotfix分支來修復BUG。

$ git checkout master    #回到master分支
$ git checkout -b hotfix    #新建一個hotfix分支,並切過去
$ vim index.html    #修改一些東西,修復BUG
$ git commit -a -m 'fixed the broken email address'    #提交hotfix

在hotfix分支上搞定BUG之後,我們切回master分支,使用git merge把剛纔的hotfix合並進來

$ git checkout master  #切換回master分支
$ git merge hotfix    #將hotfix分支的修改,合併到當前master分支來(注意merge的方向,是從其它分支,合到當前分支)。
Updating f42c576..3a0874c
Fast-forward
 README | 1 -
 1 file changed, 1 deletion(-)

備註:本次合併時出現了“Fast forward”的提示。由於當前 master 分支所在的提交對象是要併入的 hotfix 分支的直接上游,Git 只需把 master 分支指針直接右移。換句話說,如果順着一個分支走下去可以到達另一個分支的話,那麼 Git在合併兩者時,只會簡單地把指針右移,因爲這種單線的歷史分支不存在任何需要解決的分歧,所以這種合併過程可以稱爲快進(Fast forward)。

這時hotfix分支已經沒用了,可以刪掉了

$ git branch -d hotfix    #只是刪除了一個指針

現在回到之前未完成的53號問題上,繼續寫一些代碼

$ git checkout iss53
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'

在問題53相關的工作完成之後,可以合併回master分支。實際操作同前面合併hotfix分支差不多,只需回到master分支,運行git merge命令指定要合並進來的分支。

$ git checkout master
$ git merge iss53
Auto-merging README
Merge made by the 'recursive' strategy.
 README | 1 +
 1 file changed, 1 insertion(+)


請注意,這次合併操作的底層實現,並不同於之前 hotfix 的併入方式。因爲這次你的開發歷史是從更早的地方開始分叉的。由於當前 master 分支所指向的提交對象(C4)並不是 iss53 分支的直接祖先,Git 不得不進行一些額外處理。就此例而言,Git 會用兩個分支的末端(C4 和 C5)以及它們的共同祖先(C2)進行一次簡單的三方合併計算。

這次,Git 沒有簡單地把分支指針右移,而是對三方合併後的結果重新做一個新的快照,並自動創建一個指向它的提交對象(C6)。這個提交對象比較特殊,它有兩個祖先(C4 和 C5)。

有時候合併操作並不會如此順利。如果在不同的分支中都修改了同一個文件的同一部分,需要手工來處理衝突。

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Git作了合併,但沒有提交,它會停下來等你解決衝突。

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

任何包含未解決衝突的文件都會以未合併(unmerged)的狀態列出。Git 會在有衝突的文件里加入標準的衝突解決標記。

$ vi index.html
<<<<<<< HEAD
<div id="footer">contact : [email protected]</div>
=======
<div id="footer">
  please contact us at [email protected]
</div>
>>>>>>> iss53

可以看到 ======= 隔開的上半部分是 HEAD,即master,下半部分是在iss53分支中的內容。
手工合併代碼後,把 <<<<<<<,======= 和 >>>>>>> 這些行也一併刪除。這時可以用git commit來提交了。

分支策略

實際開發中,對於分支的管理,已經有很多最佳實踐,大多數情況下,我們只需要遵守一些基本原則:

  • 首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面工作。
  • 平時的開發工作都放在dev分支上,也就是說,dev分支是不穩定的。到某個時候,比如測試通過,需要1.2版本發佈時,再把dev分支合併到master上,在master分支編譯發佈1.2版本。
  • 針對新需求、修復等具體的任務,每次都在dev分支上開一個新的任務分支出來,工作完成後,再向dev分支上合併就可以了。名稱沒有特別的規範,可以是人名,例如:zhangsan,也可以是任務名、需求編號等,例如:iss03、feature04、hotfix。


遠程分支

之前討論過遠程倉庫,接着又學習了分支,當二者結合到一起時,又會產生一些有趣的東西。

遠程分支的概念

遠程分支(remote branch),即遠程倉庫中的分支。同步到本地後,與本地分支不同的是,它們 無法移動 ;且只有在Git進行網絡交互時纔會更新。遠程分支就像是書籤,提醒着你上次連接遠程倉庫時上面各分支的位置。我們用 (遠程倉庫名)/(分支名) 這樣的形式表示遠程分支(例如origin/master)。

如果我們在本地master分支做了些改動,與此同時,其他人向遠程倉庫推送了他們的更新,那麼服務器上的master分支就會向前推進,而於此同時,我們在本地的提交歷史正朝向不同方向發展。(不過只要你不和服務器通訊,你的 origin/master 指針仍然保持原位不會移動。)

可以運行git fetch origin來同步遠程服務器上的數據到本地。該命令首先找到origin是哪個服務器,然後從上面獲取你尚未擁有的數據,更新你本地的數據庫,然後把origin/master的指針移到它最新的位置上。

可以使用git remote命令查看遠程倉庫的詳情

$ git remote -v    #列出遠程服務器清單
origin  mobgit@134.32.51.60:learngit.git (fetch)
origin  mobgit@134.32.51.60:learngit.git (push)

$ git remote show origin   #查詢某一個遠程服務器的詳情
* remote origin
  Fetch URL: mobgit@134.32.51.60:learngit.git
  Push  URL: mobgit@134.32.51.60:learngit.git
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    dev
    master
  Remote branches:
    dev    tracked
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

跟蹤遠程分支

從遠程分支checkout出來的本地分支,稱爲跟蹤分支 (tracking branch)。跟蹤分支是一種和某個遠程分支有直接聯繫的本地分支。
在跟蹤分支裏輸入 git push,Git 會自行推斷應該向哪個服務器的哪個分支推送數據。同樣,在這些分支裏運行 git pull 會獲取所有遠程索引,並把它們的數據都合併到本地分支中來。

在克隆倉庫時,Git 通常會自動創建一個名爲 master 的分支來跟蹤 origin/master。這正是 git push 和 git pull 一開始就能正常工作的原因。

$ git checkout -b serverfix origin/serverfix
或簡化爲:
$ git checkout --track origin/serverfix

這會新建並切換到serverfix本地分支,其內容同遠程分支origin/serverfix一致。

推送本地分支

要想和其他人分享某個本地分支,你需要把它推送到一個你擁有寫權限的遠程倉庫。
例如本地有一個serverfix分支需要和他人一起開發,可以運行 git push (遠程倉庫名) (分支名):

$ git push origin serverfix
Counting objects: 20, done.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 1.74 KiB, done.
Total 15 (delta 5), reused 0 (delta 0)
To [email protected]:schacon/simplegit.git
 * [new branch]      serverfix -> serverfix

或者加入--set-upstream設置跟蹤後,以後直接使用git push就可以推送了:

git push --set-upstream origin serverfix

GitHub

[GitHub](https://github.com)是一個面向開源及私有軟件項目的託管平臺,因爲只支持Git作爲唯一的版本庫格式進行託管,故名GitHub。


GitHub本身沒有什麼好學的,隨便看就知道怎麼用了 知乎:怎樣使用GitHub
重點是,GitHub上有非常多優秀的個人項目值得我們學習,我們也可以將自已的代碼發佈上去。可以看成是程序員的博客吧,只貼代碼,不廢話。
在GitHub上發佈開源項目是免費的,但是私有項目收費。

GitLab

GitLab是一個用Ruby on Rails寫的開源的版本管理系統,實現一個自託管的Git項目倉庫,可通過Web界面進行訪問公開的或者私人項目。它擁有與Github類似的功能,能夠瀏覽源代碼,管理缺陷和註釋。
可以管理團隊對倉庫的訪問,它非常易於瀏覽提交過的版本並提供一個文件歷史庫。團隊成員可以利用內置的簡單聊天程序(Wall)進行交流。它還提供一個代碼片段收集功能可以輕鬆實現代碼複用,便於日後有需要的時候進行查找。
GitLab是目前搭建內部Git服務器的首選,當然如果要求不高的話,我們也可以直接使用SSH協議來快速搭建Git服務端。

常用Git命令清單


更多內容請直接參考 阮一峯的網絡日誌

推薦文檔

不要指忘2小時的培訓能帶來多大的收益,最簡單高效的方式,還是要多看優秀的文檔。
本文大量參(chao)考(xi)了以下兩部文檔:
廖雪峯的在線教程 適合快速上手
Pro Git中文版 中文第一版



作者:bluexiii
鏈接:https://www.jianshu.com/p/9ce1c37a2751
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發佈了6 篇原創文章 · 獲贊 31 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章