Git內部培訓課件

Git內部培訓課件

Git簡介

什么是版本控制

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

按類型可以分為:

  • 本地版本控制系統(tǒng)


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

  • 集中化的版本控制系統(tǒng)


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

  • 分布式版本控制系統(tǒng)


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

什么是Git

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

小歷史: Linux內核社區(qū)原本使用的是名為BitKeeper的商業(yè)化版本控制工具,2005年,因為社區(qū)內有人試圖破解BitKeeper的協(xié)議,BitMover公司收回了免費使用BitKeeper的權力。
Linus原本可以出面道個歉,繼續(xù)使用BitKeeper,然而并沒有。。。Linus大神僅用了兩周時間,自已用C寫了一個分布式版本控制系統(tǒng),于是Git誕生了!

為什么要使用Git

為什么要使用Git,或者說Git相比SVN有什么優(yōu)勢呢?

  • 分布式

  • 分支管理

  • GitHub

安裝Git

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

學習路徑

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

了解Git的工作原理

記錄文件整體快照

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

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

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

大多數操作都在本地執(zhí)行

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

時刻保持數據完整性

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

多數操作僅添加數據

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

文件的三種狀態(tài)

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

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

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

基本的 Git 工作流程如下:

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

所以,我們可以從文件所處的位置來判斷狀態(tài):如果是Git目錄中保存著的特定版本文件,就屬于已提交狀態(tài);如果作了修改并已放入暫存區(qū)域,就屬于已暫存狀態(tài);如果自上次取出后,作了修改但還沒有放到暫存區(qū)域,就是已修改狀態(tài)。

創(chuàng)建版本庫

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

在目錄中創(chuàng)建新倉庫

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

$ mkdir learngit
$ cd learngit
$ git init

從已有的倉庫克隆

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

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

版本庫基本操作

檢查當前文件狀態(tài)

使用git status命令可以查看文件的狀態(tài)

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

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

現在我們做一些改動,添加一個readme.txt進去,然后再看一下狀態(tài)

$ 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顯示了這個新創(chuàng)建的readme.txt處于未跟跟蹤狀態(tài)

跟蹤新文件

使用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已 被跟蹤 ,并處于 暫存狀態(tài)

將本次修改暫存

現在我們再對readme.txt進行修改,添加一行,再執(zhí)行git status查看狀態(tài)

$ 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 ,而不是文件本身。
再次執(zhí)行git add,可以將 本次修改 提交到暫存區(qū),Changes not staged for commit提示消失

提交更新

使用git commit命令將暫存區(qū)中的內容提交至版本庫,工作區(qū)又是干凈的了

$ 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參數加入注釋,認真描述本次的提交具體做了些什么,這對于以后我們查詢歷史記錄非常重要。

如果覺得使用暫存區(qū)過于繁瑣,可以在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

遠程倉庫

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

克隆遠程庫

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

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

查看綁定的遠程庫

如果之前我們使用的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除了實現原理不同以及實現了分布式之外,在日常使用上并沒有什么太大的區(qū)別(甚至更繁瑣)。但接下來的分支,才是Git的精髓部分。

為什么要使用分支

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

分支的原理

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

Git如何儲存數據

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

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

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


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

分支是什么

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

創(chuàng)建名為testing的新的分支,本質上就是創(chuàng)建一個指針,可以使用git branch命令:

$ git branch testing

當前工作在哪個分支

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


切換分支時發(fā)生了什么

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

$ git checkout testing

分支切換的實際操作

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

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


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

我們可以試著使用git checkout命令切回master分支,看看發(fā)生了什么:

$ 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間隨時切換,并修改工作區(qū)的文件內容。必要時再將這兩個分支合并。

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

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

我們首先在master分支上進行工作,并提交了幾次更新,測試無誤后編譯發(fā)布至生產系統(tǒng)。


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

$ git checkout -b iss53

這相當于執(zhí)行了下面這兩條命令:

$ git branch iss53
$ git checkout iss53

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

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

iss53上的工作還沒完成,突然接到通知,生產系統(tǒng)有一個緊急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號問題上,繼續(xù)寫一些代碼

$ 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 的并入方式。因為這次你的開發(fā)歷史是從更早的地方開始分叉的。由于當前 master 分支所指向的提交對象(C4)并不是 iss53 分支的直接祖先,Git 不得不進行一些額外處理。就此例而言,Git 會用兩個分支的末端(C4 和 C5)以及它們的共同祖先(C2)進行一次簡單的三方合并計算。


這次,Git 沒有簡單地把分支指針右移,而是對三方合并后的結果重新做一個新的快照,并自動創(chuàng)建一個指向它的提交對象(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)的狀態(tài)列出。Git 會在有沖突的文件里加入標準的沖突解決標記。

$ vi index.html
<<<<<<< HEAD
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
  please contact us at support@github.com
</div>
>>>>>>> iss53

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

分支策略

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

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


遠程分支

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

遠程分支的概念

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

如果我們在本地master分支做了些改動,與此同時,其他人向遠程倉庫推送了他們的更新,那么服務器上的master分支就會向前推進,而于此同時,我們在本地的提交歷史正朝向不同方向發(fā)展。(不過只要你不和服務器通訊,你的 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 通常會自動創(chuàng)建一個名為 master 的分支來跟蹤 origin/master。這正是 git push 和 git pull 一開始就能正常工作的原因。

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

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

推送本地分支

要想和其他人分享某個本地分支,你需要把它推送到一個你擁有寫權限的遠程倉庫。
例如本地有一個serverfix分支需要和他人一起開發(fā),可以運行 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 git@github.com: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上有非常多優(yōu)秀的個人項目值得我們學習,我們也可以將自已的代碼發(fā)布上去。可以看成是程序員的博客吧,只貼代碼,不廢話。
在GitHub上發(fā)布開源項目是免費的,但是私有項目收費。

GitLab

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

常用Git命令清單


更多內容請直接參考 阮一峰的網絡日志

推薦文檔

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

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

推薦閱讀更多精彩內容

  • Git是目前最流行的版本管理系統(tǒng),也是最先進的分布式版本控制系統(tǒng)(distributed version cont...
    pro648閱讀 5,746評論 1 17
  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,691評論 9 163
  • 今天媽媽回老家,我一個人在家?guī)蓚€兒子,以前哥哥也是我自己一個人帶大的,沒覺得怎么辛苦,可是如今一個人帶弟弟,確感...
    守望撒哈拉閱讀 190評論 0 0
  • 目標:種出理想的伴侶 感恩冥想: 1、感恩今天的我又瘦了兩斤,101斤了,雖然很開心,但是身體還是不好。 2、感恩...
    小兔兔姐姐愛吃胡蘿卜閱讀 125評論 0 0