Git 是一種分布式版本控制系統,它可以不受網路連接的限制,加上其它眾多優點,目前已經成為程式開發人員做專案版本管理時的首選,非開發人員也可以用 Git 來做自己的檔案版本管理工具,
一、Git 基礎
1.1 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哈希演算法,這能確保代碼內容的完整性,確保在遇到磁盤故障和網路問題時降低對版本庫的破壞,
1.2 版本控制
版本控制(Revision control)是一種在開發的程序中用于管理我們對檔案、目錄或工程等內容的修改歷史,方便查看更改歷史記錄,備份以便恢復以前的版本的軟體工程技術,一句話就是用于管理多人協同開發專案的技術,
- 優點
- 實作跨區域多人協同開發;
- 追蹤和記載一個或者多個檔案的歷史記錄;
- 組織和保護你的源代碼和檔案;
- 統計作業量;
- 并行開發、提高開發效率;
- 跟蹤記錄整個軟體的開發程序;
- 減輕開發人員的負擔,節省時間,同時降低人為錯誤,
1.3 Git 作業區、暫存區和版本庫
-
作業區:就是你在電腦里能看到的目錄,
-
版本庫:作業區有一個隱藏目錄
.git,這個不算作業區,而是Git的版本庫, -
暫存區:本地版本庫里存了很多東西,其中最重要的就是稱為
stage(或者叫index)的暫存區,
下面這個圖展示了作業區、版本庫中的暫存區和版本庫之間的關系:

1.4 分支
分支是為了將修改記錄的整個流程分開存盤,讓分開的分支不受其它分支的影響,所以在同一個資料庫里可以同時進行多個不同的修改,
- 主分支(Master)
是 Git 為我們自動創建的第一個分支,也叫主分支,其它分支開發完成后都要合并到 master
- 分支合并(Merge)
將某分支上的更改聯接到此主干或同為主干的另一個分支,
- 合并沖突(Conflict)
多人對同一檔案的作業副本進行更改,并將這些更改提交到倉庫,
1.5 標簽
標簽是用于標記特定的點或提交的歷史,通常會用來標記發布版本的名稱或版本號(如:publish/0.0.1),雖然標簽看起來有點像分支,但打上標簽的提交是固定的,不能隨意的改動,
1.6 頭(HEAD)
頭是一個象征性的參考,最常用以指向當前選擇的分支,
二、四個區域
2.1 Workspace:作業區
- 程式員進行開發改動的地方,是你當前看到的,也是最新的;
- 平常我們開發就是拷貝遠程倉庫中的一個分支,基于該分支進行開發,在開發程序中就是對作業區的操作,
2.2 Index / Stage:暫存區
.git目錄下的index檔案, 暫存區會記錄git add添加檔案的相關資訊(檔案名、大小、timestamp...),不保存檔案物體, 通過id指向每個檔案物體,可以使用git status查看暫存區的狀態,暫存區標記了你當前作業區中,哪些內容是被Git管理的;- 當你完成某個需求或功能后需要提交到遠程倉庫,那么第一步就是通過
git add先提交到暫存區,被Git管理,
2.3 Repository:本地倉庫
- 保存了物件被提交 過的各個版本,比起作業區和暫存區的內容,它要更舊一些;
git commit后同步index的目錄樹到本地倉庫,方便從下一步通過git push同步本地倉庫與遠程倉庫的同步,
2.4 Remote:遠程倉庫
遠程倉庫的內容可能被分布在多個地點的處于協作關系的本地倉庫修改,因此它可能與本地倉庫同步,也可能不同步,但是它的內容是最舊的,
2.5 四個區域的關系
- 任何物件都是在作業區中誕生和被修改;
- 任何修改都是從進入 index 區才開始被版本控制;
- 只有把修改提交到本地倉庫,該修改才能在倉庫中留下痕跡;
- 與協作者分享本地的修改,可以把它們 push 到遠程倉庫來共享,
三、Git 檔案操作
版本控制就是對檔案的版本控制:首先要知道檔案當前在什么狀態,然后才能對檔案進行修改、提交等操作,不然可能會提交了現在還不想提交的檔案,
3.1 檔案的四種狀態
Untracked: 未跟蹤, 此檔案在檔案夾中, 但并沒有加入到Git庫, 不參與版本控制.通過git add狀態變為Staged;Unmodify: 檔案已經入庫, 未修改, 即版本庫中的檔案快照內容與檔案夾中完全一致. 這種型別的檔案有兩種去處, 如果它被修改, 而變為Modified.如果使用git rm移出版本庫, 則成為Untracked檔案;Modified: 檔案已修改, 僅僅是修改, 并沒有進行其他的操作. 這個檔案也有兩個去處,通過git add可進入暫存staged狀態, 使用git checkout則丟棄修改過, 回傳到unmodify狀態, 這個git checkout即從庫中取出檔案, 覆寫當前修改;Staged: 暫存狀態.執行git commit則將修改同步到庫中, 這時庫中的檔案和本地檔案又變為一致, 檔案為Unmodify狀態. 執行git reset HEAD filename取消暫存, 檔案狀態為Modified,
3.2 查看檔案狀態
git status # 添加指定檔案到暫存區;
git add (dir) # 添加當前目錄的所有檔案到暫存區,
3.3 移除檔案與目錄(撤銷 add)
git rm --cached # 直接從暫存區洗掉檔案,作業區不做出改變
git checkout . # 用贊尋去全部或指定檔案替換作業區的檔案,這個操作很危險,會清楚作業區中未添加到暫存區的改動,
git clean # 一般會加上引數 -df,-d 表示包含目錄,-f 表示強制清除;
3.4 查看檔案修改后的差異
git status # 只能查看對哪些檔案做了改動,如果要看改動了什么,可以用;
git diff (files) # 查看檔案修改后的差異
此外,還有以下兩個常用命令:
git diff --cached # 比較暫存區的檔案與之前已經提交過的檔案
git diff HEAD~n # 比較 repo 與作業空間中的檔案差異
3.5 簽出
- 使用情景
該檔案已經存在倉庫中,作業區已經對其進行修改過了,如果想撤銷修改,可以使用 checkout,
檢出命令git checkout 是 git 最常用的命令之一,同時也是一個很危險的命令,因為折騰命令會重寫作業區,
3.6 提交
通過
add只是將檔案或者目錄添加到index即暫存區,使用commit可以實作將暫存區的檔案提交到本地倉庫,
git commit -m [message] # 提交暫存區到倉庫區
git commit [file1] [file2] ... -m [message] # 提交暫存區的指定檔案到倉庫區
git commit -a # 提交作業區自上次 commit 之后的變化,直接到倉庫區,跳過了 add,對新檔案無效
git commit -v # 提交時顯示所有 diff 資訊
3.7 撤銷更新
- 撤銷暫存區更新
git reset HEAD [filename] # 將暫存區指定檔案移出到作業區
- 撤銷本地倉庫更新
放棄作業區和暫存區的改動,同時 HEAD 指標指向前一個 commit 物件:
git log #查看提交日志,
git reset --hard HELD~1 #撤銷了上一次的提交,這里的上一次提交日志就不存在了,
cat [filename] #查看檔案內內容
git revert #把指定的提交修改回滾,并同時生成一個新的提交
3.8 日志與歷史
git log #查看所有提交日志;
git log [filename] #查看某檔案提交日志;
history #查看在 bash 下輸入過的指令;
git reflog #查看倉庫中所有分支的所有更新記錄,包括已經撤銷的更新,
四、Git 配置
4.1 分類介紹
Git組態檔有三個級別,分別是系統級別、全域級別以及倉庫級別,下面的表格展示了各個級別的配置的具體資訊:
| 配置級別 | 檔案位置 | 配置命令 | 優先級別 |
|---|---|---|---|
| 系統 | Git 安裝目錄\etc\gitconfig | git config --system | 低 |
| 全域 | 用戶檔案夾.gitconfig | git config --global | 中 |
| 倉庫 | 倉庫檔案夾.git\config | git config --local | 高 |
4.2 Git 常用配置命令
- 對全域的
Git用戶名和郵箱進行配置
git config --global user.name "xxxx" :設定所有倉庫提交的用戶名
git config --global user.email "[email protected]":設定所有倉庫提交的郵箱
- 查看所有配置或某一項配置:
git config --global --list;
git config --global --get user.name;
git config --global --get user.email;
系統和當前專案的命令同上,僅需將
global改為system/local即可,
五、本地倉庫
創建本地倉庫的方法有兩種:一種是創建全新的倉庫,另一種是克隆遠程倉庫,
5.1 創建全新倉庫
- 使用當前目錄作為
Git倉庫
只需使它初始化:git init ;執行后可以看到,僅僅在專案目錄多出了一個.git 目錄;
- 使用指定目錄作為
Git倉庫
使用如下命令,可以把創建目錄與倉庫一起完成:
git init [project-name] # 新建一個目錄,將其初始化為 Git 代碼庫
5.2 克隆遠程倉庫
- 將遠程服務器上的倉庫完全鏡像一份至本地,而不是取某一個特定版本,所以用
clone而不是checkout,語法格式為:
git clone (url)
例如:我們要從克隆的遠程倉庫托管在 Github 上,首先,我們先前往 Github 上拷貝地址如:
https://github.com/vanDusty/Java-Note,然后執行:
git clone https://github.com/vanDusty/Java-Note```
克隆遠程倉庫到當前目錄,
### 5.3 Git 倉庫目錄結構
- 初始化倉庫使用 `git init` 命令,初始目錄(`.git`)結構:
```xml
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
9 directories, 13 files
- 這個初始化后的倉庫,當創建完分支
dev-branch,并push后的目錄結構:
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ ├── heads
│ │ ├── dev-branch
│ │ └── master
│ └── remotes
│ └── origin
│ └── master
├── objects
│ ├── 2d
│ │ └── d2c71b69c837a7459f4bd9c9f7db6520731d06
│ ├── 5c
│ │ └── 7b8eda18a75e13d27c31e65a54b0abd7948510
│ ├── 77
│ │ └── cad3aecf7c2754231095598119979d62a1e1da
│ ├── info
│ └── pack
└── refs
├── heads
│ ├── dev-branch
│ └── master
├── remotes
│ └── origin
│ └── master
└── tags
19 directories, 25 files
5.4 目錄結構說明
branches目錄
一種不常用的存盤速記方式,用于指定 git fetch ,git pull 和 git push 的 URL ,目前已基本不用,
COMMIT_EDITMSG檔案
commit 編輯資訊,僅記錄最近一次提交的 commit 編輯資訊,
config檔案
存盤當前倉庫的配置資訊
description檔案
用于在 GitWeb 中展示專案的描述資訊,
HEAD檔案
存盤 HEAD 指標,指向當前分支,即:記錄當前活動分支,
hooks目錄
目錄下存盤了許多鉤子檔案(一些腳本),這些檔案是各種 Git 命令使用的自定義腳本,可以在 Git 特定階段自動執行,
index檔案
暫存區(stage),二進制檔案,
info目錄
存盤庫的其他資訊將記錄在此目錄中,
logs目錄
保存所有更新的參考記錄,
objects目錄
簡單理解就是:objects 目錄是 Git 的資料庫,存盤所有資料內容,
refs目錄
(1)heads 目錄
目錄有以各個本地分支名命名的檔案,保存對應分支最新提交的 ID,是通過 SHA1 演算法計算的一個字串,
(2)remotes 目錄
目錄有以各個遠程分支名命名的檔案,保存對應分支最新提交的 ID,和 heads 目錄一個原理,
(3)tags 目錄
存盤在開發程序中打的標簽,里面的檔案以標簽名命令,檔案內容為對應的 ID ,
六、遠程倉庫
Git 是分布式版本控制系統,同一個
Git倉庫,可以分布到不同的機器上,即發布到不同的遠程倉庫上,
6.1 常見的托管平臺
- GitHub
對,就是那個“全世界最大同性交友網站”,https://github.com
絕大多數好的開源專案都來自 GitHub,但是 GitHub 只能新建公開的 Git 倉庫,私有倉庫要收費,有時候訪問比較卡,如果你做的是一個開源專案,可以首選 GitHub,
- Gitlab
提到 GitHub 就會自然的想到 Gitlab,Gitlab 支持無限的公有專案和私有專案,https://about.gitlab.com
- Bitbucket
Bitbucket免費支持 5 個開發成員的團隊創建無限私有代碼托管庫,https://bitbucket.org
- Gitee 碼云
前面說的都是國外的,下面來說幾個國內的,碼云,個人開發者可免費創建 1000 個專案(不限公有、私有),提供最多 5G 的免費代碼存盤空間,http://git.oschina.net,
- Coding.net
談到 Coding.net,首先必須提的是速度快,同樣一個賬號最多可以創建 1000 個專案(5 個私有),也支持任務的創建等,https://coding.net
6.2 遠程倉庫操作
申請到了 Git 遠程倉庫的帳號并創建了一個空的遠程倉庫現在我們就可以結合本地的倉庫與遠程倉庫一起協同作業了,多人協同開發,這也是我們作業時的情形,這里我們全部使用命令完成(實際開發中很多開發工具例如:IDEA 等,無需命令操作),
- 克隆專案
遠程操作的第一步,通常是從遠程主機克隆一個版本庫,這時就要用到 git clone 命令,例如:
git clone https://github.com/vanDusty/Java-Note
該命令會在本地主機生成一個目錄,與遠程主機的版本庫同名,如果要指定不同的目錄名,可以將目錄名作為 git clone 命令的第二個引數,
git clone <版本庫的網址> <本地目錄名>
git clone 支持多種協議
除了HTTP(s)以外,還支持SSH、Git、本地檔案協議等,通常來說,Git協議下載速度最快,SSH協議用于需要用戶認證的場合,各種協議優劣的詳細討論請參考官方檔案,
git remote
為了便于管理,Git 要求每個遠程主機都必須指定一個主機名,git remote 命令就用于管理主機名,
不帶選項的時候, git remote 命令列出所有遠程主機名,
git remote -v #參看遠程主機的網址,
結果表示,當前只有一臺遠程主機,叫做 origin,以及它的網址,
origin [email protected]:jquery/jquery.git (fetch)
origin [email protected]:jquery/jquery.git (push)
克隆版本庫的時候,所使用的遠程主機自動被 Git 命名為 origin ,如果想用其他的主機名,需要用 git clone 命令的 -o 選項指定:
git clone -o dusty https://github.com/vanDusty/Java-Note
上面命令表示,克隆的時候,指定遠程主機叫做 dusty
更多命令如下:
$ git remote show <主機名> #查看該主機的詳細資訊
$ git remote add <主機名> <網址> #添加遠程主機
$ git remote rm <主機名> #洗掉遠程主機
$ git remoterename<原主機名> <新主機名> #遠程主機的改名
git fetch
一旦遠程主機的版本庫有了更新,需要將這些更新取回本地,這時就要用到該命令,
git fetch #將某個遠程主機的更新,全部取回本地,
git fetch <遠程主機名> <分支名> #取回指定主機名的指定分支
所取回的更新,在本地主機上要用"遠程主機名/分支名"的形式讀取,比如 origin 主機的 master,就要用 origin/master 讀取,
git checkout -b newBrach origin/master #在 origin/master 的基礎上,創建一個新分支,
也可以使用 git merge 命令或者 git rebase 命令,在本地分支上合并遠程分支,
git merge origin/master #或者$ git rebase origin/master
git pull
git pull 命令的作用是,取回遠程主機某個分支的更新,再與本地的指定分支合并,它的完整格式稍稍有點復雜,
git pull <遠程主機名> <遠程分支名>:<本地分支名>
示例:取回 origin 主機的 master 分支,與本地的 develop 分支合并:
git pull origin master:develop
如果遠程分支( master)要與當前分支合并,則冒號后面的部分可以省略,可以簡寫為:
git pull origin master
上面命令表示,取回 origin/master 分支,再與當前分支合并,實質上,這等同于先做 git fetch ,再做 git merge ,
git fetch origin
git merge master/develop
git fetch和git pull的區別
git fetch:相當于是從遠程獲取最新版本到本地,不會自動合并,
git pull:相當于是從遠程獲取最新版本并merge到本地
七、Git 命令
偷個懶,發現一個很全的【Git常用命令參考手冊】
技術交流,歡迎掃一掃!
風塵博客
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/374003.html
標籤:其他
