1. 基本操作
git init
$ mkdir git-tutorial # 新建目錄
$ cd git-tutorial # 進入目錄
$ git init # 初始化倉庫
- 執行初始化操作會生成一個
.git
目錄(該目錄儲存著管理當前目錄內容所需的倉庫資料); - 檔案的編輯等操作在工作樹中進行,然後記錄到倉庫中,以此管理檔案的歷史快照;
- 如果想將檔案恢復到原先的狀態,可以從倉庫中調取之前的快照,在工作樹中開啟。
git status
$ git status # 顯示 Git 倉庫的狀態
git add
$ git add README.md # 向暫存區新增檔案
- 如果這是用 Git 倉庫的工作樹建立了檔案,那麼該檔案並不會被記入 Git 倉庫的版本管理物件當中(Untracked files);
- 要讓檔案成為管理物件,需要加入到暫存區(Stage 或者 Index);
- 暫存區是提交之前的一個臨時區域。
git commit
$ git commit -m "First commit" # 儲存倉庫的歷史記錄
- 該命令將當前暫存區中的檔案實際儲存到倉庫的歷史記錄中;
- 通過這些記錄,我們可以在工作樹中復原檔案;
-
-m
引數後面的字串稱作提交資訊,是對這個提交的概述; - 如果要記述詳細資訊,請不加
-m
,直接執行git commit
命令。
git log
$ git log # 檢視提交日誌
$ git log --pretty=short # 只顯示提交資訊的第一行
$ git log README.md # 只顯示指定目錄、檔案的日誌(README.md)
$ git log -p # 顯示檔案的改動
$ git log -p README.md # 檢視README.md 檔案的提交日子以及提交前後的差別
git diff
$ git diff # 檢視工作樹和暫存區的差別
$ git diff HEAD # 檢視工作樹和最新提交的差別
PS:不妨養成這樣一個好習慣:在執行
git commit
命令之前先執行git diff HEAD
命令,檢視本次提交與上次提交之間有什麼差別,等確認完畢後再進行提交。這裡的HEAD
是指向當前分支中最新一次提交的指標。
2. 分支的操作
master -----> master
|---> feature-A
|---> fix-B
- 建立分支後,往往會存在多個最新程式碼狀態;
-
master
分支是 Git 預設建立的分支,基本上所有開發都是以這個分支為中心進行的; - 不同分支進行不同的作業,等該分支完成之後再與
master
分支合併。
/--- fix-B
master ---------------> master
--------/ feature-A
git branch
$ git branch # 顯示分支一覽表
* master # master 分支左側標有 `*`(星號),表示當前所在分支
git checkout -b
$ git checkout -b # 建立、切換分支
$ git checkout -b feature-A # 切換到 feature-A 分支並進行提交(下面兩條命令等同該條命令)
$ git branch feature-A # 建立 feature-A 分支
$ git checkout feature-A # 將當前分支切換為 feature-A 分支
$ git checkout master # 切換到 master 分支
$ git checkout - # 切換回上一分支
- Git 與 SVN 不同,建立分支時不需要連線中央倉庫,這讓建立分支變得相對輕鬆;
- 當今大部分工作流程都用到了
特性(Topic)分支
,即集中實現單一特性(主題),除此之外不進行任何作業的分支; - 日常開發中,往往會建立數個特性分支,同時在此之外再保留一個隨時可以釋出軟體的穩定分支;
- 穩定分支通常由
master
分支擔當; - 基於特定主題的作業在特性分支中進行,主題完成後再與
master
分支合併。只要保持這樣一個開放流程,就能保證master
分支可以隨時供人檢視。這樣一來,其他開發者也可以放心大膽地從master
分支建立新的特性分支; - 主幹分支是特性分支的原點,同時也是合併的終點。通常人們會用
master
分支作為主幹分支; - 有時我們需要讓這個主幹分支總是配置在正式環境中,有時又需要用標籤 Tag 等建立版本資訊,同時管理多個版本釋出。擁有多個版本釋出時,主幹分支也有多個。
git merge
下面演示如何將分支 feature-A
合併到 master
:
首先,切換到 master
分支:
$ git checkout master
Switch to branch `master`
然後合併 feature-A
分支:
為了在歷史記錄中明確下本次分支合併,我們需要建立合併提交。因此在合併時加上
--no-ff
引數。
$ git merge --no-ff feature-A
隨後編輯器會啟動,用於錄入合併提交的資訊。隨後,feature-A
分支的內容就合併到 master
分支中了。
git log –graph
$ git log --graph # 用圖表形式輸出提交日誌
該命令可以清楚看到特性分支的建立以及合併。
3. 更改提交的操作
git reset
/------> fix-B
master ---------------> master
------------/ feature-A
$ git reset --hard fd0cbf0d4a234f67sjdkfjklbj6786a # 回溯歷史版本
HEAD is now at fd0cbf0 Add index
- 要讓倉庫的 HEAD、暫存區、當前工作樹回溯到指定狀態,需要用到
git reset --hard
命令,只要提供目標時間點的雜湊值,就可以完全恢復至該時間點的狀態; - 使用
git reflog
命令可以檢視當前倉庫執行過的操作日誌,只要不進行 Git 的GC
(Garbage Collection,垃圾回收),就可以通過日誌隨意調取近期的歷史狀態,就像給時間機器指定一個時間點,在過去未來中自由穿梭一般; - 即便開發者錯誤執行了 Git 操作,基本也都可以利用
git reflog
命令恢復到原先的狀態,請務必牢記!(因為git reflog
命令列印出來的操作前面都有版本雜湊碼,可以拿來使用)
git commit –amend
$ git commit -amend # 修改提交資訊
git rebase -i
$ git rebase -i # 壓縮歷史
4. 推送至遠端倉庫
git remote add
$ git remove add origin git@github.com:github-book/git-tutorial.git # 新增遠端倉庫
git push
$ git push -u origin master # 推送至 master 分支
$ git checkout -b feature-D # 建立 feature-D 分支
$ git push -u origin feature-D # 推送至 feature-D 分支
- 引數
-u
可以在推送的同時,將origin
倉庫的master
分支設定為本地倉庫當前分支的upstream
(上游); - 新增了這個引數,將來執行
git pull
命令從遠端倉庫獲取內容時,本地倉庫的這個分支就可以直接從origin
的master
分支獲取內容,省去了另外新增引數的麻煩。
5. 從遠端倉庫獲取
git clone
$ git clone git@github.com:github-book/git-tutorial.git # 獲取遠端倉庫
$ git branch -a # 檢視當前分支的相關資訊
PS:引數
-a
可以同時顯示本地倉庫和遠端倉庫的分支資訊。
git pull
git pull origin feature-D # 獲取最新的遠端倉庫分支
6. 幫助深入理解 Git 的資料
- Pro Git 由就職於 GitHub 公司的 Scott Chacon 執筆,是一部零基礎的 Git 學習資料。
- LearnGitBranching 是學習 Git 基本操作的網站。注重樹形結構的學習方式非常適合初學者,點選右下角的地球標誌還可切換各種語言進行學習。
- tryGit 可以讓我們正在 Web 上一邊操作一邊學習 Git 的基本功能(只有英文版)。