1. 程式人生 > 其它 >Git 常用命令詳解

Git 常用命令詳解

Git 是一個很強大的分散式版本管理工具,它不但適用於管理大型開源軟體的原始碼(如:linux kernel),管理私人的文件和原始碼也有很多優勢(如:wsi-lgame-pro

Git 的更多介紹,請參考我的上一篇部落格:Git 版本管理工具

一、 Git 命令初識

在正式介紹Git命令之前,先介紹一下Git 的基本命令和操作,對Git命令有一個總體的認識

示例:從Git 版本庫的初始化,通常有兩種方式:

1)git clone:這是一種較為簡單的初始化方式,當你已經有一個遠端的Git版本庫,只需要在本地克隆一份

例如:git clone git://github.com/someone/some_project.git some_project

上面的命令就是將'git://github.com/someone/some_project.git'這個URL地址的遠端版本庫,完全克隆到本地some_project目錄下

2)git init 和 git remote:這種方式稍微複雜一些,當你本地建立了一個工作目錄,你可以進入這個目錄,使用'git init'命令進行初始化;Git以後就會對該目錄下的檔案進行版本控制,這時候如果你需要將它放到遠端伺服器上,可以在遠端伺服器上建立一個目錄,並把可訪問的URL記錄下來,此時你就可以利用'git remote add'命令來增加一個遠端伺服器端,

例如:git remote add origin git://github.com/someone/another_project.git

上面的命令就會增加URL地址為'git: //github.com/someone/another_project.git',名稱為origin的遠端伺服器,以後提交程式碼的時候只需要使用 origin別名即可

二、 Git 常用命令

1) 遠端倉庫相關命令

檢出倉庫: $ git clone git://github.com/jquery/jquery.git

檢視遠端倉庫:$ git remote -v

新增遠端倉庫:$ git remote add [name] [url]

刪除遠端倉庫:$ git remote rm [name]

修改遠端倉庫:$ git remote set-url --push [name] [newUrl]

拉取遠端倉庫:$ git pull [remoteName] [localBranchName]

推送遠端倉庫:$ git push [remoteName] [localBranchName]


*如果想把本地的某個分支test提交到遠端倉庫,並作為遠端倉庫的master分支,或者作為另外一個名叫test的分支,如下:

$git push origin test:master // 提交本地test分支作為遠端的master分支

$git push origin test:test // 提交本地test分支作為遠端的test分支

2)分支(branch)操作相關命令

檢視本地分支:$ git branch

檢視遠端分支:$ git branch -r

建立本地分支:$ git branch [name] ----注意新分支建立後不會自動切換為當前分支

切換分支:$ git checkout [name]

建立新分支並立即切換到新分支:$ git checkout -b [name]

刪除分支:$ git branch -d [name] ---- -d選項只能刪除已經參與了合併的分支,對於未有合併的分支是無法刪除的。如果想強制刪除一個分支,可以使用-D選項

合併分支:$ git merge [name] ----將名稱為[name]的分支與當前分支合併

建立遠端分支(本地分支push到遠端):$ git push origin [name]

刪除遠端分支:$ git push origin :heads/[name] 或 $ gitpush origin :[name]


*建立空的分支:(執行命令之前記得先提交你當前分支的修改,否則會被強制刪乾淨沒得後悔)

$git symbolic-ref HEAD refs/heads/[name]

$rm .git/index

$git clean -fdx

3)版本(tag)操作相關命令

檢視版本:$ git tag

建立版本:$ git tag [name]

刪除版本:$ git tag -d [name]

檢視遠端版本:$ git tag -r

建立遠端版本(本地版本push到遠端):$ git push origin [name]

刪除遠端版本:$ git push origin :refs/tags/[name]

合併遠端倉庫的tag到本地:$ git pull origin --tags

上傳本地tag到遠端倉庫:$ git push origin --tags

建立帶註釋的tag:$ git tag -a [name] -m 'yourMessage'

4) 子模組(submodule)相關操作命令

新增子模組:$ git submodule add [url] [path]

如:$git submodule add git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs

初始化子模組:$ git submodule init ----只在首次檢出倉庫時執行一次就行

更新子模組:$ git submodule update ----每次更新或切換分支後都需要執行一下

刪除子模組:(分4步走哦)

1) $ git rm --cached [path]

2) 編輯“.gitmodules”檔案,將子模組的相關配置節點刪除掉

3) 編輯“ .git/config”檔案,將子模組的相關配置節點刪除掉

4) 手動刪除子模組殘留的目錄

5)忽略一些檔案、資料夾不提交

在倉庫根目錄下建立名稱為“.gitignore”的檔案,寫入不需要的資料夾名或檔案,每個元素佔一行即可,如

target

bin

*.db

三、Git 命令詳解

現在我們有了本地和遠端的版本庫,讓我們來試著用用Git的基本命令:

git pull:從其他的版本庫(既可以是遠端的也可以是本地的)將程式碼更新到本地,例如:'git pull origin master'就是將origin這個版本庫的程式碼更新到本地的master主枝,該功能類似於SVN的update

git add:是將當前更改或者新增的檔案加入到Git的索引中,加入到Git的索引中就表示記入了版本歷史中,這也是提交之前所需要執行的一步,例如'git add app/model/user.rb'就會增加app/model/user.rb檔案到Git的索引中,該功能類似於SVN的add

git rm:從當前的工作空間中和索引中刪除檔案,例如'git rm app/model/user.rb',該功能類似於SVN的rm、del

git commit:提交當前工作空間的修改內容,類似於SVN的commit命令,例如'git commit -m story #3, add user model',提交的時候必須用-m來輸入一條提交資訊,該功能類似於SVN的commit

git push:將本地commit的程式碼更新到遠端版本庫中,例如'git push origin'就會將本地的程式碼更新到名為orgin的遠端版本庫中

git log:檢視歷史日誌,該功能類似於SVN的log

git revert:還原一個版本的修改,必須提供一個具體的Git版本號,例如'git revert bbaf6fb5060b4875b18ff9ff637ce118256d6f20',Git的版本號都是生成的一個雜湊值

上面的命令幾乎都是每個版本控制工具所公有的,下面就開始嘗試一下Git獨有的一些命令:

git branch:對分支的增、刪、查等操作,例如'git branch new_branch'會從當前的工作版本建立一個叫做new_branch的新分支,'git branch -D new_branch'就會強制刪除叫做new_branch的分支,'git branch'就會列出本地所有的分支

git checkout:Git的checkout有兩個作用,其一是在不同的branch之間進行切換,例如'git checkout new_branch'就會切換到new_branch的分支上去;另一個功能是還原始碼的作用,例如'git checkout app/model/user.rb'就會將user.rb檔案從上一個已提交的版本中更新回來,未提交的內容全部會回滾

git rebase:用下面兩幅圖解釋會比較清楚一些,rebase命令執行後,實際上是將分支點從C移到了G,這樣分支也就具有了從C到G的功能



git reset:將當前的工作目錄完全回滾到指定的版本號,假設如下圖,我們有A-G五次提交的版本,其中C的版本號是 bbaf6fb5060b4875b18ff9ff637ce118256d6f20,我們執行了'git resetbbaf6fb5060b4875b18ff9ff637ce118256d6f20'那麼結果就只剩下了A-C三個提交的版本

git stash:將當前未提交的工作存入Git工作棧中,時機成熟的時候再應用回來,這裡暫時提一下這個命令的用法,後面在技巧篇會重點講解

git config:利用這個命令可以新增、更改Git的各種設定,例如'git config branch.master.remote origin'就將master的遠端版本庫設定為別名叫做origin版本庫,後面在技巧篇會利用這個命令個性化設定你的Git,為你打造獨一無二的 Git

git tag:可以將某個具體的版本打上一個標籤,這樣你就不需要記憶複雜的版本號雜湊值了,例如你可以使用'git tag revert_version bbaf6fb5060b4875b18ff9ff637ce118256d6f20'來標記這個被你還原的版本,那麼以後你想檢視該版本時,就可以使用 revert_version標籤名,而不是雜湊值了

Git之所以能夠提供方便的本地分支等特性,是與它的檔案儲存機制有關的。Git儲存版本控制資訊時使用它自己定義的一套檔案系統儲存機制,在程式碼根目錄下有一個.git資料夾,會有如下這樣的目錄結構:


有幾個比較重要的檔案和目錄需要解釋一下:HEAD檔案存放根節點的資訊,其實目錄結構就表示一個樹型結構,Git採用這種樹形結構來儲存版本資訊,那麼HEAD就表示根;refs目錄儲存了你在當前版本控制目錄下的各種不同引用(引用指的是你本地和遠端所用到的各個樹分支的資訊),它有heads、remotes、stash、tags四個子目錄,分別儲存對不同的根、遠端版本庫、Git棧和標籤的四種引用,你可以通過命令'git show-ref'更清晰地檢視引用資訊;logs目錄根據不同的引用儲存了日誌資訊。因此,Git只需要程式碼根目錄下的這一個.git目錄就可以記錄完整的版本控制資訊,而不是像SVN那樣根目錄和子目錄下都有.svn目錄。那麼下面就來看一下Git與SVN的區別吧

四、 Git 與SVN 比較

SVN(Subversion)是當前使用最多的版本控制工具。與它相比較,Git最大的優勢在於兩點:易於本地增加分支和分散式的特性。

下面兩幅圖可以形象的展示Git與SVN的不同之處:

------------

1)本地增加分支

圖中Git本地和伺服器端結構都很靈活,所有版本都儲存在一個目錄中,你只需要進行分支的切換即可達到在某個分支工作的效果

而SVN則完全不同,如果你需要在本地試驗一些自己的程式碼,只能本地維護多個不同的拷貝,每個拷貝對應一個SVN伺服器地址

舉一個實際的例子:

使用SVN作為版本控制工具,當正在試圖增強一個模組,工作做到一半,由於會改變原模組的行為導致程式碼伺服器上許多測試的失敗,所以並沒有提交程式碼。

這時候假如現在有一個很緊急的Bug需要處理, 必須在兩個小時內完成。我只好將本地的所有修改diff,並輸出成為一個patch檔案,然後回滾有關當前任務的所有程式碼,再開始修改Bug的任務,等到修改好後,在將patch應用回來。前前後後要完成多個繁瑣的步驟,這還不計中間程式碼發生衝突所要進行的工作量。

可是如果使用Git, 我們只需要開一個分支或者轉回到主分支上,就可以隨時開始Bug修改的任務,完成之後,只要切換到原來的分支就可以優雅的繼續以前的任務。只要你願意,每一個新的任務都可以開一個分支,完成後,再將它合併到主分支上,輕鬆而優雅。

2)分散式提交

Git可以本地提交程式碼,所以在上面的圖中,Git有利於將一個大任務分解,進行本地的多次提交

而SVN只能在本地進行大量的一次性更改,導致將來合併到主幹上造成巨大的風險

3)日誌檢視

Git 的程式碼日誌是在本地的,可以隨時檢視

SVN的日誌在伺服器上的,每次檢視日誌需要先從伺服器上下載下來

例如:程式碼伺服器在美國,當每次檢視幾年前所做的工作時,日誌下載可能需要十分鐘,這不能不說是一個痛苦。但是如果遷移到Git上,利用Git日誌在本地的特性,檢視某個具體任務的所有程式碼歷史,每次只需要幾秒鐘,大大方便了工作,提高了效率。

當然分散式並不是說用了Git就不需要一個程式碼中心伺服器,如果你工作在一個團隊裡,還是需要一個伺服器來儲存所有的程式碼的。

五、 總結

上面簡單介紹了Git 的基本概念、一些常用命令和原理,大家也可以嘗試動手,在Google Code 或 GitHub 上建立一個自己的開源專案

Git 建立與使用示例:

在Google Code 上,我建立了Git 專案:linux-kernel-source

在GitHub上,我引用的Git 專案:hiphop-php

在osChina上,我分享的專案:gcc-4.5.2