Chp Git
Commit Type Must be one of the following:
feat: A new feature fix: A bug fix docs: Documentation only changes style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) refactor: A code change that neither fixes a bug nor adds a feature perf: A code change that improves performance test: Adding missing tests chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
記錄檔案快照,而不是差異的部份
Git有三種表達檔案的狀態: 已提交(committed)、已修改(modified)及已暫存(staged)。
- 已提交意謂著資料己安全地存在讀者的本地端資料庫。
- 己修改代表著讀者已修改檔案但尚未提交到資料庫。
- 已暫存意謂著讀者標記已修改檔案目前的版本到下一次提供的快照。
這帶領我們到Git專案的三個主要區域:Git目錄、工作目錄(working directory)以及暫存區域(staging area)。
基本Git工作流程大致如下:
- 讀者修改工作目錄內的檔案。
- 暫存檔案,將檔案的快照新增到暫存區域。add就是讓檔案暫存。
- 做提交的動作,這會讓存在暫存區域的檔案快照永久地儲存在Git目錄。
untracked 新增的檔案 Changes to be committed: 新增檔案add之後來這邊,已經有快照,在staged Changes not staged for commit: Changes to be committed修改之後到這邊,是unstaged
如果原本有一個檔案在這 Changes to be committed a.rb
修改之後會同時出現在兩個地方 Changes to be committed a.rb Changes not staged for commit a.rb 就是說如果commit是用Changes to be committed 這邊快照的版本, git add 就是更新Changes to be committed 的快照版本
好的Commit訊息: 1 去除whitespace errors。 2 首行標題 空一行 (剩下的細節解釋)
改完一定要Commit! git co file 就回不去了!
三種狀態
現在,注意。 若讀者希望接下來的學習過程順利些,這是關於Git的重要且需記住的事項。 Git有三種表達檔案的狀態:已提交(committed)、已修改(modified)及已暫存(staged)。 已提交意謂著資料己安全地存在讀者的本地端資料庫。 己修改代表著讀者已修改檔案但尚未提交到資料庫。 已暫存意謂著讀者標記已修改檔案目前的版本到下一次提供的快照。
這帶領我們到Git專案的三個主要區域:Git目錄、工作目錄(working directory)以及暫存區域(staging area)。
圖1-6. 工作目錄、暫存區域及git目錄。
Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這是Git最重要的部份,而且它是當讀者從其它電腦複製儲存庫時會複製過來的。
工作目錄是專案被取出的某一個版本。 這些檔案從Git目錄內被壓縮過的資料庫中拉出來並放在磁碟機供讀者使用或修改。
暫存區域是一個單純的檔案,一般來說放在Git目錄,儲存關於下一個提交的資訊。 有時稱為索引,但現在將它稱為暫存區域已開始成為標準。
基本Git工作流程大致如下:
- 讀者修改工作目錄內的檔案。
- 暫存檔案,將檔案的快照新增到暫存區域。
- 做提交的動作,這會讓存在暫存區域的檔案快照永久地儲存在Git目錄。
在Git目錄內特定版本的檔案被認定為已提交。 若檔案被修改且被增加到暫存區域,稱為被暫存。 若檔案被取出後有被修改,但未被暫存,稱為被修改。 在第二章讀者會學到更多關於這些狀態以及如何利用它們的優點或者整個略過暫存步驟。
假設讀者新增一些檔案到專案,如README。 若該檔案先前並不存在,執行 git status 命令後,讀者會看到未被追蹤的檔案,如下:
$ vim README
$ git status
On branch master
Untracked files:
(use "git add
README
nothing added to commit but untracked files present (use "git add" to track)
我們可以看到新增的README尚未被追蹤,因為它被列在輸出訊息的 Untracked files 下方。 除非我們明確指定要將該檔案加入提交的快照,Git不會主動將它加入。這樣可以避免加入一些二進位格式的檔案或其它使用者不想列入追蹤的檔案。 不過在這個例子中,我們的確是要將README 檔案加入追蹤:
追蹤新檔案
要追蹤新增的檔案,我們可以使用git add命令。例如:要追蹤README檔案,可執行:
$ git add README
如此一來,我們重新檢查狀態(status)時,可看到README檔案已被列入追蹤並且已被暫存:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
new file: README
因為它被放在Changes to be commited文字下方,讀者可得知它已被暫存起來。 若讀者此時提交更新,剛才執行git add加進來的檔案就會被記錄在歷史的快照。
檢視已暫存及尚未暫存的更動
在某些情況下,git status指令提供的資訊就太過簡要。 有的時候我們不只想知道那些檔案被更動,而是想更進一步知道被檔案的內容被做了那些修改,這時我們可以使用git diff命令。稍後我們會有更詳盡講解該命令。讀者使用它時通常會是為了瞭解兩個問題:目前已做的修改但尚未暫存的內容是哪些?以及將被提交的暫存資料有哪些?儘管git status指令可以大略回答這些問題,但git diff可顯示檔案裡的哪些列被加入或刪除,以修補檔(patch)方式表達。
假設讀者編輯並暫存(stage)README,接著修改benchmarks.rb檔案,卻未暫存。若讀者檢視目前的狀況,會看到類似下方文字:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
new file: README
Changes not staged for commit:
(use "git add
modified: benchmarks.rb
想瞭解尚未暫存的修改,執行git diff,不用帶任何參數:
$ git diff diff --git a/benchmarks.rb b/benchmarks.rb index 3cb747f..da65585 100644 --- a/benchmarks.rb +++ b/benchmarks.rb @@ -36,6 +36,10 @@ def main @commit.parents[0].parents[0].parents[0] end
- run_code(x, 'commits 1') do
- git.commits.size
- end + run_code(x, 'commits 2') do log = git.commits('master', 15) log.size
這命令會比對目前工作目錄(working directory)及暫存區域(stage area)的版本,然後顯示尚未被存入暫存區(stage area)的變更。
若讀者想比對暫存區域(stage)及最後一次提交(commit)的差異,可用git diff --cached指令(Git 1.6.1之後的版本,可用較易記的git diff --staged 指令):
$ git diff --cached diff --git a/README b/README new file mode 100644 index 0000000..03902a1 --- /dev/null +++ b/README2 @@ -0,0 +1,5 @@ +grit
- by Tom Preston-Werner, Chris Wanstrath
- http://github.com/mojombo/grit + +Grit is a Ruby library for extracting information from a Git repository
很重要的一點是git diff不會顯示最後一次commit後的所有變更;只會顯示尚未存入暫存區(即unstaged)的變更。這麼說可能會混淆,舉個例子來說,若讀者已暫存(stage)所有的變更,輸入git diff不會顯示任何資訊。
舉其它例子,若讀者暫存benchmarks.rb檔案後又編輯,可使用git diff看已暫存的版本與工作目錄內版本尚未暫存的變更:
$ git add benchmarks.rb
$ echo '# test line' >> benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
modified: benchmarks.rb
Changes not staged for commit:
(use "git add
modified: benchmarks.rb
現在讀者可使用git diff檢視哪些部份尚未被暫存:
$ git diff diff --git a/benchmarks.rb b/benchmarks.rb index e445e28..86b2f7c 100644 --- a/benchmarks.rb +++ b/benchmarks.rb @@ -127,3 +127,4 @@ end main()
pp Grit::GitRuby.cache_client.stats
+# test line
以及使用git diff --cached檢視目前已暫存的變更:
$ git diff --cached diff --git a/benchmarks.rb b/benchmarks.rb index 3cb747f..e445e28 100644 --- a/benchmarks.rb +++ b/benchmarks.rb @@ -36,6 +36,10 @@ def main @commit.parents[0].parents[0].parents[0] end
- run_code(x, 'commits 1') do
- git.commits.size
- end + run_code(x, 'commits 2') do log = git.commits('master', 15) log.size
跳過暫存區域
雖然優秀好用的暫存區域能很有技巧且精確的提交讀者想記錄的資訊,有時候暫存區域也比讀者實際需要的工作流程繁瑣。 若讀者想跳過暫存區域,Git提供了簡易的使用方式。 在git commit命令後方加上-a參數,Git自動將所有已被追蹤且被修改的檔案送到暫存區域並開始提交程序,讓讀者略過git add的步驟:
$ git status
On branch master
Changes not staged for commit:
(use "git add
modified: benchmarks.rb
no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m 'added new benchmarks' [master 83e38c7] added new benchmarks 1 files changed, 5 insertions(+)
留意本次的提交之前,讀者並不需要執行git add將benchmarks.rb檔案加入。
刪除檔案
要從Git刪除檔案,讀者需要將它從已被追蹤檔案中移除(更精確的來說,是從暫存區域移除),並且提交。 git rm命令除了完成此工作外,也會將該檔案從工作目錄移除。 因此讀者以後不會在未被追蹤檔案列表看到它。
若讀者僅僅是將檔案從工作目錄移除,那麼在git status的輸出,可看見該檔案將會被視為“已被變更且尚未被更新”(也就是尚未存到暫存區域):
$ rm grit.gemspec
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm
deleted: grit.gemspec
no changes added to commit (use "git add" and/or "git commit -a")
接著,若執行git rm,則會將暫存區域內的該檔案移除:
$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
deleted: grit.gemspec
下一次提交時,該檔案將會消失而且不再被追蹤。 若已更動過該檔案且將它記錄到暫存區域。 必須使用-f參數才能將它強制移除。 這是為了避免已被記錄的快照意外被移除且再也無法使用Git復原。
其它有用的技巧是保留工作目錄內的檔案,但從暫存區域移除。 換句話說,或許讀者想在磁碟機上的檔案且不希望Git繼續追蹤它。 這在讀者忘記將某些檔案記錄到.gitignore且不小心將它增加到暫存區域時特別有用。 比如說:巨大的記錄檔、或大量在編譯時期產生的.a檔案。 欲使用此功能,加上--cached參數:
$ git rm --cached readme.txt
開發合作時的Git開分支流程 1 先開分支再開發,注意終端機要在這個分支上面,然後如果跳回master就不要再改東西了 git branch new_branch_name git checkout new_branch_name 以上等於 git checkout -b new_branch_name
2 先commit再回master更新遠端資料 git checkout master git pull origin master
(如果這時候忘記跳回去master 就pull,結果發生conflict 就解玩衝突再commit一次)
3 到分支上對master做rebase git checkout new_branch_name git rebase master
PS 如果有衝突,解完之後 git add 檔案 然後git rebase - -continue
4 這時候跳到master, git merge 分支名稱 ( 如果分支位置就已經是在最新,那麼打rebase會說已經up to date )
4 回到master push上去,刪除分支 git checkout master git push git branch -d new_branch_name
在分支改到一半想要更新: 改到一半的檔案要先commit 或rebase 跳回去master git pull --rebase (本地 master跟遠端如果在不同主幹,會幫你rebase) 分支git rebase master,解完衝突 git rebase —continue,在分支上繼續改
復原: 已經更改還沒add或已add又改( Changes not staged for commit: ),要回復到上次commit狀態:git co - - file
復原已經add的檔案(Changes to be committed:)回上次commit狀態:
要先踢出add git reset HEAD
取消add(Changes to be committed:),變成untrack:git reset HEAD file 取消commit,把更動放回已add:git reset —soft HEAD^ 取消Merge git reset --hard ORIG_HEAD
clone專案下來後,本地端不會有分支, 譬如遠端有OOO分支,以下指令在本地端開OOO並track之 git checkout -b OOO origin/OOO
然後查看現在這隻分支對應到遠端哪支: git branch -vv
要在遠端開分支 先在本地端開完 git push origin/分之名
eb list 先確認在 Vidol-Staging Vidol-Module
- Vidol-Staging Vidol-work-production
eb deploy
更動最後一筆更新
最常見的復原發生在太早提交更新,也許忘了加入某些檔案、或者搞砸了提交的訊息。 若想要試著重新提交,可試著加上 --amend 選項:
$ git commit --amend
此命令取出暫存區資料並用來做本次的提交。 只要在最後一次提交後沒有做過任何修改(例如:在上一次提交後,馬上執行此命令),那麼整個快照看起來會與上次提交的一模一樣,唯一有更動的是提交時的訊息。
同一個文書編輯器被帶出來,並且已包含先前提交的更新內的訊息。 讀者可像往常一樣編輯這些訊息,差別在於它們會覆蓋上一次提交。
如下例,若提交了更新後發現忘了一併提交某些檔案,可執行最後一個命令:
$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend
這些命令的僅僅會提交一個更新,第二個被提交的更新會取代第一個。
取消已被暫存的檔案
接下來兩節展示如何應付暫存區及工作目錄的復原。 用來判斷這兩個區域狀態的命令也以相當好的方式提示如何復原。 比如說已經修改兩個檔案,並想要以兩個不同的更新提交它們,不過不小心執行 git add * 將它們同時都加入暫存區。 應該如何將其中一個移出暫存區?git status 命令已附上相關的提示:
$ git add .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
modified: README.txt
modified: benchmarks.rb
在 “Changes to be commited” 文字下方,註明著使用 “git reset HEAD
$ git reset HEAD benchmarks.rb
Unstaged changes after reset:
M benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
modified: README.txt
Changes not staged for commit:
(use "git add
modified: benchmarks.rb
這個命令看起來有點奇怪,不過它的確可行。 benchmarks.rb 檔案被移出暫存區了。
復原已被更動的檔案
若讀者發現其者並不需要保留 benchmarks.rb 檔案被更動部份,應該如何做才能很容易的復原為最後一次提交的狀態(或者最初複製儲存庫時、或放到工作目錄時的版本)? 很幸運的,git status 同樣也告訴讀者如何做。 在最近一次檢視狀態時,暫存區看起來應如下所示:
Changes not staged for commit:
(use "git add
modified: benchmarks.rb
在這訊息中已很明確的說明如何拋棄所做的修改(至少需升級為 Git 1.6.1或更新版本。 若讀者使用的是舊版,強烈建議升級,以取得更好用的功能。) 讓我們依據命令執行:
$ git checkout -- benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD
modified: README.txt
在上述文字可看到該變更已被復原。 讀者應該瞭解這是危險的命令,任何對該檔案做的修改將不復存在,就好像複製別的檔案將它覆蓋。 除非很清楚真的不需要該檔案,絕不要使用此檔案。 若需要將這些修改排除,我們在下一章節會介紹備份及分支。 一般來說會比此方法來的好。
先在本地端測沒問題, 再Deploy到staging看有沒有問題,(可以不用commit) 檢查加入的檔,再push到github.