Git由淺入深之操作與指令
獲取Git倉庫(Git repository)
使用Git的第一步是要獲取一個Git倉庫,我們使用Git的操作對象都是存放在Git倉庫里,獲取Git倉庫的方式有兩種:
- 導入一個項目或目錄到Git,初始化(init)生成Git倉庫;
- 從遠程伺服器克隆(clone)一個Git倉庫。
初始化倉庫(init)
若我們需要使用一個項目或目錄生成一個Git倉庫,只需要通過命令行進入該目錄,執行如下Git指令:
git init
此操作將在此目錄生成一個.git子目錄,該目錄包含整個倉庫結構,即倉庫的所有文件;同時會檢出(checkout)一個默認工作分支,通常名為master。
此時,我們只是初始化生成了一個Git倉庫,還未添加需要進行版本控制的對象–文件或目錄。
克隆倉庫(clone)
很多時候,我們需要從遠程伺服器獲取一個已存在的Git倉庫,我們只需要使用如下指令:
git clone https://github.com/codingplayboy/javascript_notes
git clone後面跟著的url就是已存在的Git倉庫地址,我們需要知道的是Git克隆是對伺服器上倉庫的一次近乎完整的數據拷貝,當前倉庫項目的所有文件及其各版本歷史都會被獲取。
執行如上指令後,會在當前目錄創建一個javascript_notes目錄並在javascript_notes中初始化一個.git子目錄,拉取倉庫的所有數據,然後根據倉庫(或項目)的最新版本檢出(check out)一個工作分支,通常該分支默認名稱為master。
倉庫別名
我們克隆一個Git倉庫時,其默認名還是倉庫名,但是也支持我們自定義本地別名:
git clone https://github.com/codingplayboy/javascript_notes js_notes
執行如上指令,會克隆一個倉庫,並導入到當前目錄下的js_notes目錄。
倉庫Url
Git倉庫Url支持的協議有很多,最常見的是https:// 和git@;還有使用SSH傳輸協議的,
形如git://或者user@server:path/xxx/repository.git。
版本控制對象
在上節,我們已經知道如何獲取一個Git倉庫,但是到目前為止也僅僅是存在一個倉庫,我們進行版本控制的對象(文件或目錄)並沒有添加進倉庫。
工作目錄及其內對象的狀態
相關指令:git status
當我們獲取一個倉庫,如克隆一個遠端倉庫後,在倉庫目錄執行上面指令,如圖所示:- 圖中第一行on branch master告訴我們當前我們處在名為master的分支;
- 第二行up-to-date with origin/master,說明目前分支與遠程倉庫的master分支保持同步最新版本;
- 第三行working directory clean,說明目前倉庫中沒有新加或修改過的對象(文件或目錄)。
關於控制對象的狀態(git status)
在當前工作目錄的文件或目錄,可能出於兩種狀態:
已標記(tracked)
所謂已標記文件或目錄,即那些在Git最新快照里存在的對象,可能是未修改(unmodified),已修改(modified)或暫存(staged)的文件或目錄。
未標記(untracked)
未標記對象,即除去已標記對象外,所有對象,比如在工作目錄下但是未包含在最新快照里並且不在暫存區(staging area)。
可以想像一下,當第一次克隆一個遠程倉庫後,倉庫下的所有文件都應該是處於已標記(tracked)但是未修改的狀態。
添加對象(git add)
添加版本控制對象的指令是git add,比如,我們可以使用如下指令添加一個README.txt文件,當然我們首先需要在倉庫目錄下,創建該文件(任意方式創建),查看狀態:
如上圖,顯示README.txt文件為Untracked file,並且提示:use git add to track; 然後使用git add指令後:git add README.txt
再次執行git status指令:
如上,出現:Changes to be committed,說明該文件已被標記(tracked)且被暫存,我們可以進行提交了。
當然該指令還可以對目錄使用:
git add test/
如上指令,將添加該test目錄及其內所有文件或子目錄。
最後,也許我們希望一次添加所有變更,而不是一個一個添加,如下指令,可以實現:git add .
我們還需要關注git add指令,不只是能添加版本控制對象,還有以下功能:
- 暫存變更(staged)
- 標記衝突已解決(resolved)
git add指令,更貼切的作用應該是添加新內容(文件/目錄/變更)到下一次提交,即將新內容加入最新快照,等待提交;
關於後兩點功能,後文有詳細介紹。
忽略對象(.gitignore)
有時候,我們並不希望對倉庫內所有對象(文件或目錄)進行管理,
某些開發依賴或本地調試使用文件和目錄,我們不需要在團隊間共享,這些文件應該被Git忽略,我們只需要創建一個.gitignore文件,在此文件中列出希望被忽略的文件或目錄,如:.gitignore文件語法主要如下:- 以行為單位,一行匹配一個條件
- 空行或以#開頭的行會被忽略
- 表達式支持glob格式
- 排除某表達式匹配項在該表達式前加!
暫存變更(git add)
在添加README.txt文件後,我們可以對其進行修改,如在該文件加入一行文字驚鴻三世的博客 - 路漫漫其修遠兮,吾將上下而求索。,然後執行git status指令,結果如下:
發現,除了之前新添加文件的記錄,又多了一條記錄:Changes not staged for commit,表明已標記對象發生變更但是未被暫存,其下面第一第二行是輔助信息,第三行告訴我們,README.txt已經修改(modified);
隨後我們可以使用git add指令暫存此次變更,此時,再執行git status指令,可以看到:
所有變更都已暫存,等待下一次提交。查看簡短狀態信息(git status -s)
上文已經指出,使用git status可以查看當前工作目錄完整的狀態,同時,git還支持使用參數指明查看簡短狀態信息:
git status -sor git status --short
如下,其信息比git status簡潔明了:
查看變更信息(git diff)
前文的git status可以查看當前工作目錄的狀態信息,包括當前分支,變更文件等,但都屬於文件層次的信息;
有時我們希望知道:- 哪些變更未被暫存;
- 哪些變更已暫存,等待提交
git status顯然是不能告訴我們,因為這是屬於git diff的使命,如,在README.txt文件中內容添加『/』:
git diff比較當前工作目錄和暫存區的內容,然後展示哪些文件內容發生變更並且尚未暫存;
同時,其支持額外參數--staged(或–cached),該參數指定時,將輸出上次提交內容與暫存區內容比較後的的變更,簡言之,git diff輸出未暫存的變更,git diff --staged輸出已暫存待提交的變更。
在使用git add .暫存變更後,使用git diff指令是沒用的,而使用git diff --staged指令,輸出如下:
提交變更(git commit)
所有的變更,最終都需要提交,才能在本地持久化報存,在將所有變更暫存(git add)後,我們就可以進行提交了,相關指令就是:
git commit
在輸入如上指令後,將進入Git commit信息編輯狀態:
我們可以編輯本次提交的備註信息,其中的默認備註信息都以#開頭,表明提交時會被忽略。
git commit指令告訴Git持久化記錄(提交)我們暫存區(staging area)中的快照,任何未被暫存的變更,不會被添加進暫存區的快照,仍然保留在當前工作目錄,我們可以隨後提交。
更詳細的提交信息(git commit -v)
除了使用默認的git commit指令,我們還可以添加-v參數,在提交信息中顯示變更內容,如下:
如上圖,和之前的比較,除了基本的提示,還有文件變更內容提示,可以避免某些誤提交。行內輸入提交信息(git commit -m)
當然,Git還支持我們使用-m參數,指明我們在使用git commit指令時直接填寫提交備註信息:
跳過暫存區(git commit -a)
我們知道對於發生變更的對象,我們需要先使用git add,暫存變更,再使用git commit提交變更;但是還有一種可以不使用git add指令的方式,可以提交變更,就是給git commit指令添加-a參數:
git commit -a
但是需要注意的是,該參數,只能直接提交工作目錄中已標記的對象(文件或目錄)的變更,對於未標記,如新添加的對象,是無效的。
查看提交歷史(Git log)
本節要介紹的是如何查看之前的提交歷史及信息,你應該知道的git log指令,
默認地,不帶參數時,執行git log指令,輸出的是當前倉庫按逆序排序(最近提交在最前)的提交記錄:如上圖,每個提交記錄包含其SHA-1校驗和,提交者用戶名,提交日期,提交備註信息。git log指令支持指定許多參數,以過濾輸出不同提交記錄,下文展開介紹。指定查看提交記錄數(git log -2)
Git支持我們指定數量參數,限定該次查看提交記錄數量,如git log -2,之後輸出最近的兩條提交記錄。
格式化輸出提交記錄(git log –pretty)
Git支持我們格式化輸出的提交記錄信息,使用–pretty參數,其值主要有以下幾個:
- oneline: 指定一行輸出一條提交記錄;
- short: 指定按原格式輸出簡要信息;
- full: 指定按原格式輸出信息;
- fuller: 指定按原格式輸出更多信息;
- format:」」: 允許指定自定義輸出格式,如:
git log --pretty=format:"%h - %an, %ar : %s"
查看簡要提交變更(git log –stat)
git log --stat輸出如下:
除了輸出基礎提交信息,後面還輸出了本次提交的簡要變更信息:變更了多少文件,及每個文件變更的行數,並在最後輸出總結數據。
查看詳細提交變更(git log -p)
相對於git log --stat輸出簡要提交變更信息,我們可以指定-p參數:git log -p,輸出提交變更的詳細內容,如:
更多參數說明
參數說明-p顯示詳細提交變更–stat顯示簡要提交變更–shortstat在–stat參數輸出基礎上只輸出修改,新增或刪除的行–name-only顯示提交時發生變更的文件名–name-status顯示提交時發生變更的文件名,並顯示變更類型(刪除,新增,或修改)–abbrev-commit只顯示提交記錄SHA-1校驗和的前幾個字元–relative-date顯示簡要提交日期(如, 「2 weeks ago」)–graph顯示分支提交歷史的ASCII圖–pretty支持預定義輸出格式,詳細說明見上文
過濾提交歷史輸出
Git支持我們在輸出歷史記錄時,添加多種過濾條件,最簡單的比如-<num>參數條件,指定輸出最近的若干條提交記錄,還有諸如提交時間,提交作者等條件。
–since/–after: git log --since=2.weeks
輸出兩周內的提交記錄,參數值還可以形如」2016-01-15″,」2 years 1 day 10 minutes ago」
–until/–before: git log --until=2016-01-15
–grep: git log --grep=README
可以指定關鍵字,只有提交信息中存在關鍵字才會輸出
–author: 過濾輸出指定提交作者的記錄
- –commiter: 輸出滿足指定commiter的提交記錄
- -S: git -log -Swebpack
- 輸出提交內容(代碼或文件或目錄)包含指定字元串的記錄
刪除對象(git rm)
很多時候,我們也會需要從Git倉庫中刪除某些對象,rm就是刪除文件或目錄的指令,但是需要特彆強調的是,該指令只是將某對象從當前工作目錄刪除,如:
使用rm後,當前狀態是」Changes not staged for commit:」此次變更未被暫存和提交。若你需要將某對象從已標記文件或暫存區刪除,則需要使用git rm指令,如下:使用git rm後,變更會被暫存。
強制刪除(git rm -f)
當我們發生某次變更,且將其添加到暫存區(index索引),我們只使用git rm指令是不行的:
我們必須加上-f參數,指明強制刪除。緩存變更(git rm –cached)
有時候,我們在某次變更添加了某文件(甚至可能已經添加到暫存區),但是暫時不需要提交,又不想直接刪除它,即只在工作目錄存在,而不將其放入暫存區,只需要添加--cached參數,如修改README.txt同時,新增了test.txt文件,並且暫存了變更,之後提交時我們不希望此次提交test.txt,但又不希望刪除它,則在提交前使用git rm --cached test.txt:
移動對象(git mv)
通常,我們也許需要移動或重命名某文件或目錄,Git有mv指令,還要一個更方便的指令git mv,如:
git mv a.txt b.txt
另一方面,重命名或移動某文件或目錄,這兩個操作對於Git來說是沒有太大區別的,比如上面的重命名文件操作等效於:
mv a.txt b.txtgit rm a.txtgit add b.txt
我們可以看到git mv指令是在mv指令操作的基礎上暫存此次操作的變更,而mv只是一個重命名或移動指令,不涉及版本控制流程。
到此,Git的基本使用,已經介紹完成,不過,本篇講解的基礎操作,都是在計算機本地進行的版本控制,並沒有同步到伺服器,那麼下一篇的主題就出來了:Git如何與遠程伺服器進行協同工作。
作者:驚鴻三世
鏈接:Git由淺入深之操作與指令版權歸作者所有,轉載請註明出處推薦閱讀:
※Git常用命令詳解
※一個人寫程序,版本控制用svn還是git?
※Git 工作流指南
※一個奇怪的git問題,求大家幫忙分析一下?
※如何控制git庫的膨脹?