1. 程式人生 > >快速瞭解 Git Git倉庫

快速瞭解 Git Git倉庫

轉自:https://my.oschina.net/wangnian/blog/2218757

一、Git介紹

(1)Git是一個開源(Linus Torvalds 為了幫助管理 Linux 核心開發而開發)的分散式版本控制系統,用於敏捷高效地處理任何或小或大的專案,與常用的版本控制工具 CVS, SVN等不同,它採用了分散式版本庫的方式,不必伺服器端軟體支援。

(2)Git 的工作區、暫存區和版本庫:

  • 工作區:就是你在電腦裡能看到的目錄。
  • 暫存區:英文叫stage, 或index。一般存放在 ".git目錄下" 下的index檔案(.git/index)中,所以我們把暫存區有時也叫作索引(index)。
  • 版本庫:工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。

二、安裝

Git 目前支援 Linux/Unix、Solaris、Mac和 Windows 平臺上執行。

(1)Windows 上安裝 Git

在 Windows 平臺上安裝 Git 很容易,有個叫做 msysGit 的專案提供了安裝包,可以到 GitHub 的頁面上下載 exe 安裝檔案並執行(安裝包下載地址:https://gitforwindows.org/

安裝成功後,就可以使用命令列的 git 工具(已經自帶了 ssh 客戶端,右擊->"Git Bash")進行Git操作,另外還有一個圖形介面的 Git 專案管理工具

(2)其他安裝 參見菜鳥教程: http://www.runoob.com/git/git-install-setup.html

三、使用

(1)基本使用

1. git init 可以在任何時候/目錄中建立新的 Git 倉庫,完全是本地化的:

git init //在目錄中建立新的 Git 倉庫,預設情況下 Git 就會為你建立"master"分支

建立完後會在專案中生成“ .git ”這個子目錄。 這就是你的 Git 倉庫了,所有有關你的此專案的快照資料都存放在這裡,eg:

2.git clone 拷貝一個 Git 倉庫到本地進行檢視修改:

 git clone [url] //預設,Git 會用此 URL 最後一個“/”之後的名稱作為本地專案名稱,你也可以在該命令後加上你想要的名稱: git clone [url] <project name>

eg.:

首先,去coding(較流行的一個Git伺服器)隨便找個專案,複製Git倉庫地址:

然後,到本地計算機右擊選擇“git clone”:

3.git add 將檔案新增到快取

新專案可以使用  “git add .  ” 命令遞迴地添加當前工作目錄中的所有檔案。

4.git status 檢視在你上次提交之後是否有修改

git status -s //檢視狀態, -s表示short,如果不加會詳細輸出內容
/** git status -s 狀態碼解析*****************
  A: 你本地新增的檔案(伺服器上沒有).   
  C: 檔案的一個新拷貝.   
  D: 你本地刪除的檔案(伺服器上還在).  
  M: 檔案的內容或者mode被修改了.    
  R: 檔名被修改了。   
  T: 檔案的型別被修改了。   
  U: 檔案沒有被合併(你需要完成合並才能進行提交)。  
  X: 未知狀態(很可能是遇到git的bug了,你可以向git提交bug report)  
  ?:未被git進行管理,可以使用git add file1把file1新增進git能被git所進行管理
  這些狀態也會組合出現,eg:
 "AM" :意思是,這個檔案在我們將它新增到快取之後又有改動,改動後我們再執行 git add 命令將其新增到快取中
 "UU" :
**/

5.git diff 檢視執行 git status 的結果的詳細資訊

git diff 比較工作目錄中當前檔案和暫存區域快照之間的差異,也就是修改之後還沒有暫存起來的變化內容。git status 顯示你上次提交更新後的更改或者寫入快取的改動, 而 git diff 則一行一行地顯示這些改動具體是啥:

  • 尚未快取的改動:git diff
  • 檢視已快取的改動: git diff --cached
  • 檢視已快取的與未快取的所有改動:git diff HEAD
  • 顯示摘要而非整個 diff:git diff --stat

6.git commit

 git add 將想要快照的內容寫入快取區, git commit 則將快取區內容新增到倉庫中。

git commit 
git commit -m "<message>" //使用 -m 選項以在命令列中提供提交註釋
git commit -a //把unstaged的檔案變成staged(不包括新建(untracked)的檔案)然後commit,一般還是推薦先git add再git commit
git commit -am "<message>"//或 git commit –a –m "<message>",相當於git add . + git commit –m "<message>"合併使用
git commit --amend //增補提交,會使用與當前提交節點相同的父節點進行一次新的提交,舊的提交將會被取消.

Git 為你的每一個提交都記錄你的名字與電子郵箱地址,所以第一步需要配置使用者名稱和郵箱地址

7.git reset HEAD  取消之前 git add 已快取的內容,但不包含在下一提交快照中的快取。

HEAD關鍵字指的是當前分支最末梢最新的一個提交,也就是版本庫中該分支上的最新版本.

git reset HEAD //把add進去的檔案從staged狀態取出來,可以單獨針對某一個檔案操作: git reset HEAD <filename>
git reset --mixed HEAD//--mixed是預設引數,是將git的HEAD變了(也就是提交記錄變了),但檔案目錄並沒有改變, 取消了commit和add的內容.
git reset --soft HEAD// 實際上,是git reset –mixed id 後,又做了一次git add.即取消了commit的內容.
git reset --hard HEAD//是將git的HEAD變了,檔案也變了.
     按改動範圍排序如下:
     soft (commit) < mixed (commit + add) < hard (commit + add + local working)

8.git revert HEAD: 撤銷最近的一個提交:

  git revert會建立一個反向的新提交,可以通過引數-n來告訴Git先不要提交.

9.git rm 從已跟蹤檔案清單中移除某個檔案:

如果只是簡單地從工作目錄中手工刪除檔案,執行 git status 時就會在 Changes not staged for commit 的提示。要從 Git 中移除某個檔案,就必須要從已跟蹤檔案清單中移除,然後提交:

git rm <file>
git rm -f <file> //如果刪除之前修改過並且已經放到暫存區域的話,則必須要用強制刪除選項 -f
git rm --cached <file>//僅從跟蹤清單中刪除,把檔案從暫存區域移除但仍保留在當前工作目錄中使用
git rm –r * //遞迴刪除,即如果後面跟的是一個目錄做為引數,則會遞迴刪除整個目錄中的所有子目錄和檔案

10.git mv 命令用於移動或重新命名一個檔案、目錄、軟連線:

git mv <file> <new file>

11.git clean是從工作目錄中移除沒有track的檔案:

git clean -d// -d表示同時移除目錄
git clean -f// -f表示force,因為在git的配置檔案中, clean.requireForce=true,如果不加-f,clean將會拒絕執行.

12.git stash把當前的改動壓入一個棧:

git stash將會把當前目錄和index中的所有改動(但不包括未track的檔案)壓入一個棧,然後留給你一個clean的工作狀態,即處於上一次最新提交處

git stash list//顯示這個棧的list.
git stash apply//取出stash中的上一個專案([email protected]{0}),並且應用於當前的工作目錄.也可以指定別的專案,如:git stash apply [email protected]{1}
git stash pop//在應用stash中專案的同時想要刪除它
git stash drop// 刪除上一個,也可指定引數刪除指定的一個專案
git stash clear// 刪除所有專案

13.git reflog 對reflog進行管理

reflog是git用來記錄引用變化的一種機制,比如記錄分支的變化或者是HEAD引用的變化,git會將變化記錄到HEAD對應的reflog檔案中,其路徑為 .git/logs/HEAD, 分支的reflog檔案都放在 .git/logs/refs 目錄下的子目錄中

git reflog//不指定引用的時候,預設列出HEAD的reflog。[email protected]{0}代表HEAD當前的值,[email protected]{3}代表HEAD在3次變化之前的值.

 (2)Git 分支管理

幾乎所有版本控制系統都支援分支。使用分支可以從開發主線上分離開來,在不影響主線的同時繼續工作。

1.建立分支:

git branch (branchname) //沒有引數時,git branch 會列出你在本地的分支。

2.切換分支:

當你切換分支的時候,Git 會用該分支的最後提交的快照替換你的工作目錄的內容, 所以多個分支不需要多個目錄。

git checkout (branchname) //該分支存在則切換到分之下否則建立新分支並立即切換到該分支下

3.合併分支:

Git 合併,不僅僅是簡單的檔案新增、移除的操作, 也會合並修改。你可以多次合併到統一分支, 也可以選擇在合併之後直接刪除被併入的分支。

git merge (branchname)  //將此分支合併到主分支去
git checkout -b (branchname) //建立並切換到新的分支,相當於git branch newbranch + git checkout newbranch 合併使用
git checkout <filename>//此命令會使用HEAD中的最新內容替換掉你的工作目錄中的檔案,已新增到暫存區的改動以及新檔案都不會受到影響。會刪除該檔案中所有沒有暫存和提交的改動,這個操作是不可逆的

合併出現衝突需要手動去修改它,然後:

git add // 解決了衝突要告訴 Git 檔案衝突已經解決
git merge --abort//或者你也可以取消merge

4.刪除分支:

git branch -d (branchname)

5.檢視分支的最後一次提交:

git branch -v

(3)Git log檢視提交日誌

Git 最為出色的是它的合併跟蹤(merge tracing)能力。使用 git log 命令檢視提交歷史:

git log
git log --oneline //檢視歷史記錄的簡潔的版本
git log --reverse --oneline //逆向顯示所有日誌
git log --oneline --number //顯示number條,每條log只顯示一行
git log --oneline --graph //圖形化顯示分支合併歷史
git log branchname// 顯示特定分支的log
git log --oneline branch1 ^branch2//檢視在分支1不在分支2中的log,^表示排除這個分支
git log --decorate//會顯示出tag資訊
git log --grep //根據commit資訊過濾log: git log --grep=keywords 預設情況下, git log --grep --author是OR的關係,即滿足一條即被返回,如果你想讓它們是AND的關係,可以加上--all-match的option
git log -S: filter by introduced diff ,如: git log -SmethodName (注意S和後面的詞之間沒有等號分隔).
git log -p//每一個提交都是一個快照(snapshot),Git會把每次提交的diff計算出來,作為一個patch顯示給你看,另一種方法是git show [SHA].
git log --stat//同樣是用來看改動的相對資訊的,--stat比-p的輸出更簡單一些.
//--no-merges可以將merge的commits排除在外.

用 --graph 選項,開啟了拓撲圖選項,可以更清楚明瞭地檢視歷史中什麼時候出現了分支、合併,eg.:

$ git log --oneline --graph
*   88afe0e Merge branch 'change_site'
|\  
| * d7e7346 changed the site
* | 14b4dca 新增加一行
|/  
* 556f0a0 removed test2.txt
* 2e082b7 add test2.txt
* 048598f add test.txt
* 85fc7e7 test comment from runoob.com

如果只想查詢指定使用者的提交日誌可以使用命令:git log --author ,eg.:

$ git log --author=Linus --oneline -5 //找 Git 原始碼中 Linus 提交的部分
81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
3bb7256 make "index-pack" a built-in
377d027 make "git pack-redundant" a built-in
b532581 make "git unpack-file" a built-in
112dd51 make "mktag" a built-in

如果你要指定日期,可以執行幾個選項:--since 和 --before, --until 和 --after,eg.:

$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges //看 Git 專案中三週前且在四月十八日之後的所有提交,我可以執行這個, --no-merges 選項以隱藏合併提交
5469e2d Git 1.7.1-rc2
d43427d Documentation/remote-helpers: Fix typos and improve language
272a36b Fixup: Second argument may be any arbitrary string
b6c8d2d Documentation/remote-helpers: Add invocation section
5ce4f4e Documentation/urls: Rewrite to accomodate transport::address
00b84e9 Documentation/remote-helpers: Rewrite description
03aa87e Documentation: Describe other situations where -z affects git diff
77bc694 rebase-interactive: silence warning when no commits rewritten
636db2c t3301: add tests to use --format="%N"

(4)Git 標籤

1.如果你希望永遠記住重要的階段那個特別的提交快照,你可以使用 git tag 給它打上標籤,eg.:

git tag -a v1.0 //給最新一次提交打上(HEAD)"v1.0"的標籤,-a 選項意為"建立一個帶註解的標籤",不用 -a 選項也可以執行的,但它不會記錄這標籤是啥時候打的,誰打的,也不會讓你添加個標籤的註解。推薦建立帶註解的標籤

2.檢視標籤:

$ git tag//檢視所有標籤
v0.9
v1.0

3.如果我們忘了給某個提交打標籤,又將它釋出了,我們可以給它追加標籤,eg.:

$ git tag -a v0.9 85fc7e7 //給釋出提交的 85fc7e7 追加標籤
$ git log --oneline --decorate --graph
*   88afe0e (HEAD, tag: v1.0, master) Merge branch 'change_site'
|\  
| * d7e7346 (change_site) changed the site
* | 14b4dca 新增加一行
|/  
* 556f0a0 removed test2.txt
* 2e082b7 add test2.txt
* 048598f add test.txt
* 85fc7e7 (tag: v0.9) test comment from runoob.com

4.指定標籤資訊:

git tag -a <tagname> -m "<message>"

5.PGP簽名標籤:

git tag -s <tagname> -m "<message>"

6.刪除標籤:

git tag -d <tagname>

7.檢視某個標籤版本所修改的內容:

git show <tagname>

四、Git倉庫

Git 並不像 SVN 那樣有個中心伺服器。 Git 命令都是在本地執行,如果你想通過 Git 分享你的程式碼或者與其他開發人員合作。 你就需要將資料放到一臺其他開發人員能夠連線的伺服器上。

(1)新增遠端庫

要新增一個新的遠端倉庫,可以指定一個簡單的名字,以便將來引用,命令格式如下:

git remote add [shortname] [url]

目前流行的Git倉庫有很多,使用最多的有:GitHub、Coding(兼具SVN、Git)。具體的使用如同普通的軟體一樣很簡單,可以直接上手

(2)使用Git倉庫

1.檢視當前的遠端庫

因為不需要每次都用完整的url,所以Git為每一個remote repo的url都建立一個別名,然後用git remote來管理這個list,如果你clone一個project,Git會自動將原來的url新增進來,別名就叫做:origin

git remote// 列出remote aliases.
git remote -v//檢視每一個別名對應的實際url.
git remote add [alias] [url]// 新增一個新的remote repo.
git remote rm [alias]// 刪除一個存在的remote alias.
git remote rename [old-alias] [new-alias]//重新命名
git remote set-url [alias] [url]//更新url, 可以加上—push和-fetch引數,為同一個別名set不同的存取地址.

2.提取遠端倉庫

git fetch //取所有你本地沒有的資料,取下來的分支(remote branches)和本地分支一樣(可以看diff、log、merge),但是Git不允許你checkout到它們
git fetch [alias]//取某一個遠端repo
git fetch --all//取到全部repo

3.推送到遠端倉庫

① 從遠端倉庫下載新分支與資料

 如果有多個人向同一個remote repo push程式碼, Git會首先在你試圖push的分支上執行git log,檢查它的歷史中是否能看到server上的branch現在的tip,如果本地歷史中不能看到server的tip,說明本地的程式碼不是最新的,Git會拒絕你的push,讓你先fetch,merge,之後再push,這樣就保證了所有人的改動都會被考慮進來

git push [alias] [branch] // 把當前分支merge到alias上的[branch]分支,如果分支已經存在,將會更新,如果不存在,將會新增這個分支.
git push (remote-name) (branch-name) //(local-branch)預設就意味著刪除remote-branch

② git merge 從遠端倉庫提取資料並嘗試合併到當前分支

git merge [alias]/[branch] 

git rebase不會產生合併的提交,它會將本地的所有提交臨時儲存為補丁(patch)放在”.git/rebase”目錄中,然後將當前分支更新到最新的分支尖端、最後把儲存的補丁應用到分支上。

//rebase的過程中,也許會出現衝突,Git會停止rebase並讓你解決衝突,在解決完衝突之後,用git add去更新這些內容,然後無需執行commit,只需要: 
git rebase --continue//就會繼續打餘下的補丁
git rebase --abort//終止rebase,當前分支將會回到rebase之前的狀態

4.刪除遠端倉庫

git remote rm [別名]

5.git pull 預設引數== fetch + merge FETCH_HEAD

git pull//== git pull --merge,先執行git fetch,然後執行git merge把取來的分支的head merge到當前分支產生一個新的commit   
git pull --rebase//先執行git fetch,然後執行git rebase

(3)自己搭建Git 倉庫

你也可以搭建屬於自己的Git伺服器,參見:http://www.runoob.com/git/git-server.html

1、安裝Git

$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git

建立一個git使用者組和使用者,用來執行git服務:

$ groupadd git
$ useradd git -g git

2、建立證書登入

收集所有需要登入的使用者的公鑰,公鑰位於id_rsa.pub檔案中,把我們的公鑰匯入到/home/git/.ssh/authorized_keys檔案裡,一行一個。如果沒有該檔案建立它:

$ cd /home/git/
$ mkdir .ssh
$ chmod 755 .ssh
$ touch .ssh/authorized_keys
$ chmod 644 .ssh/authorized_keys

3、初始化Git倉庫

選定一個目錄作為Git倉庫:

$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo

$ git init --bare runoob.git
Initialized empty Git repository in /home/gitrepo/runoob.git/

以上命令Git建立一個空倉庫,伺服器上的Git倉庫通常都以.git結尾。然後,把倉庫所屬使用者改為git:

$ chown -R git:git runoob.git

4、克隆倉庫

$ git clone [email protected]:/home/gitrepo/runoob.git
Cloning into 'runoob'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

五、目前主流的程式碼編譯器都已集成了版本控制系統

以webstorm為例,安裝了git後就可以使用:

分別是:拉取、提交

branch(分支)管理

右擊專案名,就能看到git選項

ps:webstorm自身的local history可以看到編譯日誌(專案執行後存放在webstorm生成的“.idea資料夾”)。右擊專案名,就能看到local history選項

開啟後可以看到每次修改的記錄,你還可以revert還原始碼,如下: