一、Git是什麼?
- Git是一個開源的分散式版本控制系統,用於敏捷高效地處理任何或小或大的專案。
- Git 是 Linus Torvalds 為了幫助管理 Linux 核心開發而開發的一個開放原始碼的版本控制軟體。
- Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分散式版本庫的方式,不必伺服器端軟體支援。
二、Git與SVN區別
GIT不僅僅是個版本控制系統,它也是個內容管理系統(CMS),工作管理系統等。
如果你是一個具有使用SVN背景的人,你需要做一定的思想轉換,來適應GIT提供的一些概念和特徵。
Git 與 SVN 區別點:
- GIT是分散式的,SVN不是:這是GIT和其它非分散式的版本控制系統,例如SVN,CVS等,最核心的區別。
- GIT把內容按後設資料方式儲存,而SVN是按檔案:所有的資源控制系統都是把檔案的元資訊隱藏在一個類似.svn,.cvs等的資料夾裡。
- GIT分支和SVN的分支不同:分支在SVN中一點不特別,就是版本庫中的另外的一個目錄。
- GIT沒有一個全域性的版本號,而SVN有:目前為止這是跟SVN相比GIT缺少的最大的一個特徵。
- GIT的內容完整性要優於SVN:GIT的內容儲存使用的是SHA-1雜湊演算法。這能確保程式碼內容的完整性,確保在遇到磁碟故障和網路問題時降低對版本庫的破壞。
三、Git快速入門
Git官網:git-scm.com
Git完整命令手冊:git-scm.com/docs
Git命令手冊(pdf版):github-git-cheat-sheet.pdf
Git簡明指南:git-guide
四、Git安裝
在使用Git前我們需要先安裝 Git。Git 目前支援 Linux/Unix、Solaris、Mac和 Windows 平臺上執行。
Git 各平臺安裝包下載地址為:git-scm.com/downloads
五、Git配置
Git 提供了一個叫做 git config 的工具,專門用來配置或讀取相應的工作環境變數。
5.1 配置檔案的儲存位置
這些環境變數,決定了 Git 在各個環節的具體工作方式和行為。這些變數可以存放在以下三個不同的地方:
- /etc/gitconfig 檔案:系統中對所有使用者都普遍適用的配置。若使用 git config 時用 –system 選項,讀寫的就是這個檔案。
- ~/.gitconfig 檔案:使用者目錄下的配置檔案只適用於該使用者。若使用 git config 時用 –global 選項,讀寫的就是這個檔案。
- 當前專案的 Git 目錄中的配置檔案(也就是工作目錄中的 .git/config 檔案):這裡的配置僅僅針對當前專案有效。每一個級別的配置都會覆蓋上層的相同配置,所以 .git/config 裡的配置會覆蓋 /etc/gitconfig 中的同名變數。
在 Windows 系統上,Git 會找尋使用者主目錄下的 .gitconfig 檔案。主目錄即 $HOME 變數指定的目錄,一般都是 C:Users$USER。此外,Git 還會嘗試找尋 /etc/gitconfig 檔案,只不過看當初 Git 裝在什麼目錄,就以此作為根目錄來定位。
5.2 檢視git的版本資訊
檢視git的版本資訊:
git --version
複製程式碼
5.3 配置使用者資訊
當Git安裝完成後首先要做的事情是配置個人的使用者名稱稱和電子郵件地址。這是非常重要的,因為每次Git提交都會使用該資訊。它被永遠的嵌入到了你的提交中:
git config --global user.name `user_name`
git config --global user.email `user_email`
複製程式碼
具體可參考 Git Configuration
5.4 配置文字編輯器
設定Git預設使用的文字編輯器, 一般可能會是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的話,可以重新設定:
git config --global core.editor emacs
複製程式碼
5.5 配置差異分析工具
還有一個比較常用的是,在解決合併衝突時使用哪種差異分析工具。比如要改用 vimdiff 的話:
git config --global merge.tool vimdiff
複製程式碼
5.6 檢視配置資訊
要檢查已有的配置資訊,可以使用 git config –list 命令:
git config --list
複製程式碼
有時候會看到重複的變數名,這是因為Git從不同的的配置檔案中(例如:/etc/gitconfig以及~/.gitconfig)讀取相同的變數名。在這種情況下,對每個唯一的變數名,Git使用最後的那個值。
也可以直接查閱某個環境變數的設定,使用如下命令 git config {key}:
git config user.name
複製程式碼
也可以直接檢視某個配置檔案的配置資訊:
git config --global -l
or
git config --system -l
複製程式碼
5.7 git 配置檔案
- 系統級檔案 $(prefix)/etc/gitconfig,本文即 /usr/etc/gitconfig 檔案。
git config –system 用來指定讀寫系統級檔案。初始不存在,若不存在則無影響。 - 使用者級檔案 ~/.gitconfig
git config –global 指定只操作使用者級檔案。初始不存在,若不存在則無影響。 - Repository 級檔案 .git/config
git config –local 對寫操作,則只寫入 Repository 級檔案(預設行為);對讀操作,則只從 Repository 級檔案讀。 - git config –file config-file 則指定 config-file。
5.8 清除認證資訊
git config --global --unset credential.helper
or
git config --system --unset credential.helper
複製程式碼
上面的命令可以解決 remote: HTTP Basic: Access denied
錯誤。
5.9 儲存認證資訊
git config --local credential.helper store
or
git config --system credential.helper store
複製程式碼
上面的命令可以解決每次提交都要輸入使用者名稱和密碼的問題。具體可參考 Git Credential Storage
六、Git常用命令
6.1 建立程式碼倉庫
6.1.1 git init
git init
的命令格式為:
git init [-q | --quiet] [--bare] [--template=<template_directory>]
[--separate-git-dir <git dir>]
[--shared[=<permissions>]] [directory]
複製程式碼
第一步:建立一個程式碼倉庫非常簡單,首先,選擇一個合適的地方,建立一個空目錄:
mkdir repository
cd repository
pwd
複製程式碼
mkdir
命令用於建立目錄,cd
命令用於進入目錄,pwd
命令用於顯示當前目錄。
第二步,通過git init
命令把這個目錄變成Git可以管理的倉庫或者通過git init <directory>
命令直接指定一個目錄作為Gi倉庫:
git init
git init <directory>
複製程式碼
Git瞬間就把倉庫建好了,而且告訴你是一個空的倉庫(empty Git repository),細心的讀者可以發現當前目錄下多了一個.git
的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裡面的檔案,不然改亂了,就把Git倉庫給破壞了。如果你沒有看到.git
目錄,那是因為這個目錄預設是隱藏的,用ls -ah命令就可以看見。
6.1.2 git clone
git clone
的命令格式為:
git clone [--template=<template_directory>]
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
[-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
[--dissociate] [--separate-git-dir <git dir>]
[--depth <depth>] [--[no-]single-branch]
[--recurse-submodules] [--[no-]shallow-submodules]
[--jobs <n>] [--] <repository> [<directory>]
複製程式碼
克隆到當前目錄,可以使用以下命令格式:
git clone <repository>
複製程式碼
如果我們需要克隆到指定的目錄,可以使用以下命令格式:
git clone <repository> <directory>
複製程式碼
引數說明:
repository
:Git 倉庫。directory
:本地目錄。
6.2 新增暫存區
git add
的命令格式為:
git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]
[--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]
[--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]
[--chmod=(+|-)x] [--] [<pathspec>…]
複製程式碼
git add
命令可以在提交之前多次執行。它只在執行git add
命令時新增指定檔案的內容; 如果希望隨後的更改包含在下一個提交中,那麼必須再次執行git add
將新的內容新增到索引。預設情況下,git add
命令不會新增忽略的檔案。
6.2.1 基本用法
git add [path]
複製程式碼
通常是通過git add [path]
的形式把[path]
新增到索引庫中,[path]
可以是檔案也可以是目錄。
git不僅能判斷出[path]
中,修改(不包括已刪除)的檔案,還能判斷出新添的檔案,並把它們的資訊新增到索引庫中。
6.2.2 常用命令
git add . # 將所有修改新增到暫存區
git add *Presenter # 將以Presenter結尾的檔案的所有修改新增到暫存區
git add Base* # 將所有以Base開頭的檔案的修改新增到暫存區(例如:BaseActivity.java,BaseFragment.java)
git add Model? # 將以Model開頭且後面只有一位的檔案的修改新增到暫存區(例如:Model1.java,ModelA.java)
git add model/*.java # 將model目錄及其子目錄下所有*.java檔案的修改新增到暫存區
複製程式碼
6.3 程式碼提交
git commit
的命令格式為:
git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
[--dry-run] [(-c | -C | --fixup | --squash) <commit>]
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
[-i | -o] [-S[<keyid>]] [--] [<file>…]
複製程式碼
git commit
命令將索引的當前內容與描述更改的使用者和日誌訊息一起儲存在新的提交中。
6.3.1 提交暫存區到本地倉庫區
git commit -m [message]
複製程式碼
6.3.2 將未新增到暫存區的檔案,同時提交到本地倉庫區
git commit –am <message>
git commit –a –m <message>
複製程式碼
6.3.3 提交暫存區的指定檔案到倉庫區
git commit <file1> <file2> ... -m <message>
複製程式碼
6.3.4 提交時顯示所有diff資訊
git commit -v
複製程式碼
6.3.5 修改最近一次提交
git commit --amend
複製程式碼
6.3.6 修改最近一次提交,並改寫上一次commit的提交資訊
git commit --amend -m <message>
複製程式碼
6.4 分支管理
git branch
的命令格式為:
git branch [--color[=<when>] | --no-color] [-r | -a]
[--list] [-v [--abbrev=<length> | --no-abbrev]]
[--column[=<options>] | --no-column] [--sort=<key>]
[(--merged | --no-merged) [<commit>]]
[--contains [<commit]] [--no-contains [<commit>]]
[--points-at <object>] [--format=<format>] [<pattern>…]
git branch [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
git branch (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
git branch --unset-upstream [<branchname>]
git branch (-m | -M) [<oldbranch>] <newbranch>
git branch (-d | -D) [-r] <branchname>…
git branch --edit-description [<branchname>]
複製程式碼
git branch
命令用於列出,建立或刪除分支。
6.4.1 列出所有本地分支
git branch
複製程式碼
6.4.2 列出所有遠端分支
git branch -r
複製程式碼
6.4.3 列出所有本地分支和遠端分支
git branch -a
複製程式碼
6.4.4 新建一個分支,但依然停留在當前分支
git branch <branch-name>
複製程式碼
6.4.5 新建一個分支,並切換到該分支
git checkout -b <branch-name>
複製程式碼
git checkout
命令加上 -b
參數列示建立並切換,相當於以下兩條命令:
git branch <branch-name>
git checkout <branch-name>
複製程式碼
6.4.6 新建一個分支,指向指定commit
git branch <branch> <commit>
複製程式碼
6.4.7 新建一個分支,與指定的遠端分支建立追蹤關係
git branch --track <branch> <remote-branch>
複製程式碼
6.4.8 切換到指定分支,並更新工作區
git checkout <branch-name>
複製程式碼
6.4.9 切換到上一個分支
git checkout -
複製程式碼
6.4.10 建立追蹤關係,在現有分支與指定的遠端分支之間
git branch --set-upstream <branch> <remote-branch>
複製程式碼
6.4.11 合併指定分支到當前分支
git merge <branch>
複製程式碼
6.4.12 選擇一個commit,合併進當前分支
git cherry-pick <commit>
複製程式碼
6.4.13 刪除本地分支
git branch -d <branch-name>
複製程式碼
6.4.14 刪除遠端分支
git push origin :<branch-name>
或
git push origin --delete <branch-name>
複製程式碼
6.5 標籤管理
git tag
的命令格式為:
git tag [-a | -s | -u <keyid>] [-f] [-m <msg> | -F <file>]
<tagname> [<commit> | <object>]
git tag -d <tagname>…
git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]
[--points-at <object>] [--column[=<options>] | --no-column]
[--create-reflog] [--sort=<key>] [--format=<format>]
[--[no-]merged [<commit>]] [<pattern>…]
git tag -v [--format=<format>] <tagname>…
複製程式碼
git tag
命令用於建立,列出,刪除或驗證使用GPG簽名的標籤物件。
6.5.1 列出所有標籤
git tag
複製程式碼
6.5.2 新建一個標籤在當前commit
git tag <tag-name>
複製程式碼
6.5.3 新建一個標籤在指定commit
git tag <tag-name> <commit>
複製程式碼
6.5.4 新建一個帶標籤資訊的標籤在當前commit
git tag -a <tag-name> -m [message]
複製程式碼
6.5.5 刪除本地標籤
git tag -d <tag-name>
複製程式碼
6.5.6 刪除遠端標籤
方法一:直接刪除遠端標籤:
git push origin --delete tag <tag-name>
複製程式碼
方法二:先刪除本地標籤,再刪除遠端標籤:
git tag -d <tag-name>
git push origin :refs/tags/<tag-name>
複製程式碼
6.5.7 檢視標籤資訊
git show <tag-name>
複製程式碼
6.5.8 推送某個標籤到遠端
git push origin <tag-name>
複製程式碼
6.5.9 一次性推送所有尚未推送到遠端的本地標籤
git push origin --tags
複製程式碼
6.6 檢視資訊
6.6.1 檢視Git版本號
git --version
複製程式碼
6.6.2 顯示有變更的檔案
git status
複製程式碼
6.6.3 顯示當前分支的提交歷史記錄
下表介紹了一些 git log 命令支援的一些常用的選項及其釋義:
選項 | 說明 |
---|---|
-p | 按補丁格式顯示每個更新之間的差異。 |
–word-diff | 按 word diff 格式顯示差異。 |
–stat | 顯示每次更新的檔案修改統計資訊。 |
–shortstat | 只顯示 –stat 中最後的行數修改新增移除統計。 |
–name-only | 僅在提交資訊後顯示已修改的檔案清單。 |
–name-status | 顯示新增、修改、刪除的檔案清單。 |
–abbrev-commit | 僅顯示 SHA-1 的前幾個字元,而非所有的 40 個字元。 |
–relative-date | 使用較短的相對時間顯示(比如,“2 weeks ago”)。 |
–graph | 顯示 ASCII 圖形表示的分支合併歷史。 |
–pretty | 使用其他格式顯示歷史提交資訊。可用的選項包括 oneline,short,full,fuller 和 format(後跟指定格式)。 |
–oneline | –pretty=oneline –abbrev-commit 的簡化用法。 |
預設不用任何引數的話,git log
會按提交時間列出所有的更新,最近的更新排在最上面。可以看到,每次更新都有一個 SHA-1 校驗和、作者的名字和電子郵件地址、提交時間,最後縮排一個段落顯示提交說明。
git log
複製程式碼
git log
有許多選項可以幫助你搜尋感興趣的提交,接下來我們介紹些最常用的。
我們常用 -p
選項展開顯示每次提交的內容差異,用 -<n>
則僅顯示最近的兩次更新:
git log -p -2
複製程式碼
該選項除了顯示基本資訊之外,還在附帶了每次 commit 的變化。當進行程式碼審查,或者快速瀏覽某個搭檔提交的 commit 的變化的時候,這個引數就非常有用了。
--stat
,僅顯示簡要的增改行數統計。
git log --stat
複製程式碼
--pretty
選項,可以指定使用完全不同於預設格式的方式展示提交歷史。比如用 oneline
將每個提交放在一行顯示,這在提交數很大時非常有用。另外還有 short
,full
和 fuller
可以用,展示的資訊或多或少有些不同,後面也可以指定提交歷史的次數(比如:-<n>
),具體展示效果請自己動手實踐一下。
git log --pretty=oneline
複製程式碼
format
選項,可以定製要顯示的記錄格式,這樣的輸出便於後期程式設計提取分析。
git log --pretty=format:"%h - %an, %ar : %s"
複製程式碼
下表列出了常用的格式佔位符寫法及其代表的意義:
選項 | 說明 |
---|---|
%H | 提交物件(commit)的完整雜湊字串 |
%h | 提交物件的簡短雜湊字串 |
%T | 樹物件(tree)的完整雜湊字串 |
%t | 樹物件的簡短雜湊字串 |
%P | 父物件(parent)的完整雜湊字串 |
%p | 父物件的簡短雜湊字串 |
%an | 作者(author)的名字 |
%ae | 作者的電子郵件地址 |
%ad | 作者修訂日期(–date= 制定的格式) |
%aD | 作者修訂日期(RFC2822格式) |
%ar | 作者修訂日期(相對格式,如:1 day ago) |
%at | 作者修訂日期(UNIX timestamp) |
%ai | 作者修訂日期(ISO 8601 格式) |
%cn | 提交者(committer)的名字 |
%ce | 提交者的電子郵件地址 |
%cd | 提交日期 (–date= 制定的格式) |
%cD | 提交日期(RFC2822格式) |
%cr | 提交日期(相對格式,如:1 day ago) |
%ct | 提交日期(UNIX timestamp) |
%ci | 提交日期(ISO 8601 格式) |
%s | 提交說明 |
除了定製輸出格式的選項之外,git log
還有許多非常實用的限制輸出長度的選項,也就是隻輸出部分提交資訊。用 –since 和 –until選項顯示按照時間作限制的提交,比如說具體的某一天(“2008-01-15”),或者是多久以前(“2 years 1 day 3 minutes ago”)。用 –author 選項顯示指定作者的提交,用 –grep 選項搜尋提交說明中的關鍵字。
下表還列出了其他常用的類似選項:
選項 | 說明 |
---|---|
-(n) | 僅顯示最近的 n 條提交 |
–since, –after | 僅顯示指定時間之後的提交 |
–until, –before | 僅顯示指定時間之前的提交 |
–author | 僅顯示指定作者相關的提交 |
–committer | 僅顯示指定提交者相關的提交 |
6.7 遠端同步
6.7.1 顯示所有遠端倉庫
git remote -v
複製程式碼
6.7.2 獲取某個遠端主機的全部更新
git fetch <remote>
複製程式碼
6.7.3 獲取某個遠端主機的某個分支的更新
git fetch <remote> <branch>
複製程式碼
比如,取回origin主機的master分支的更新:
git fetch origin master
複製程式碼
6.7.4 顯示某個遠端倉庫的資訊
git remote show <remote>
複製程式碼
6.7.5 獲取某個遠端主機的某個分支的更新與當前分支合併
git pull <remote> <remote-branch>
複製程式碼
比如,要取回origin主機的dev分支,與當前分支合併:
git pull origin dev
複製程式碼
上面命令表示,取回origin/dev分支,再與當前分支合併。實質上,這等同於先做git fetch,再執行git merge。
git fetch origin
git merge origin/dev
複製程式碼
6.7.6 獲取某個遠端主機的某個分支的更新與本地的某個分支合併
git pull <remote> <remote-branch>:<local-branch>
複製程式碼
比如,要取回origin主機的dev分支,與本地的master分支合併:
git pull origin dev:master
複製程式碼
6.7.7 將本地的當前分支自動與對應的遠端主機”追蹤分支”進行合併
git pull <remote>
複製程式碼
6.7.8 將當前分支推送到遠端主機的對應分支
git push
複製程式碼
6.7.9 將當前分支到遠端主機的對應分支
git push <remote>
複製程式碼
6.7.10 將本地指定分支到遠端主機的對應分支
git push <remote> <branch>
複製程式碼
6.7.11 強行推送當前分支到遠端主機的對應分支(忽略衝突)
git push <remote> --force
複製程式碼
6.7.12 推送所有分支到遠端倉庫
git push <remote> --all
複製程式碼
6.8 程式碼回滾
6.8.1 恢復暫存區的指定檔案到工作區
git checkout <file-name>
複製程式碼
6.8.2 恢復某個commit的指定檔案到暫存區和工作區
git checkout <commit> <file-name>
複製程式碼
6.8.3 恢復暫存區的所有檔案到工作區
git checkout .
複製程式碼
6.8.4 回滾新增操作
git reset
複製程式碼
6.8.5 回滾最近一次提交
git reset --soft HEAD^
複製程式碼
6.8.6 永久刪除最後幾個提交
git reset --hard HEAD~3
複製程式碼
七、 Command line instructions
7.1 Git global setup
git config --global user.name "user-name"
git config --global user.email "user-email"
複製程式碼
7.2 Create a new repository
git clone <remote-repository>
cd <directory>
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
複製程式碼
7.3 Existing folder
cd <existing-folder>
git init
git remote add origin <remote-repository>
git add .
git commit -m "Initial commit"
git push -u origin master
複製程式碼
7.4 Existing Git repository
cd <existing-repository>
git remote rename origin old-origin
git remote add origin <remote-repository>
git push -u origin --all
git push -u origin --tags
複製程式碼