1.1 關於版本控制 1.1.1 本地版本控制 本地版本控制系統 許多人習慣用複製整個項目目錄的方式來保存不同的版本,或許還會改名加上備份時間以示區別。這麼做唯一的 好處就是簡單,但是特別容易犯錯。有時候會混淆所在的工作目錄,一不小心會寫錯文件或者覆蓋意想外的文件。 1.1.2 集中化的版本控制系統 ...
1.1 關於版本控制
1.1.1 本地版本控制
本地版本控制系統 許多人習慣用複製整個項目目錄的方式來保存不同的版本,或許還會改名加上備份時間以示區別。這麼做唯一的 好處就是簡單,但是特別容易犯錯。有時候會混淆所在的工作目錄,一不小心會寫錯文件或者覆蓋意想外的文件。
1.1.2 集中化的版本控制系統
如何讓在不同系統上的開發者協同工作?於是,集中化的版本控制系統(Centralized Version Control Systems,簡稱 CVCS)應運而生。這類系統,諸如 CVS、Subversion 以及Perforce 等,都有一個單一的集中管理的伺服器,保存所有文件的修訂版本,而協同工作的人們都通過客戶端連到這台伺服器,取出最新的文件或者提交更新。多年以來,這已成為版本控制系統的標準做法。
1.1.3 分散式版本控制系統
在這類系統中,像Git、Mercurial、Bazaar 以及 Darcs 等,客戶端並不只提取最新版本的文件快照,而是把代碼倉庫完整地鏡像下來。這麼一來,任何一處協同工作用的伺服器發生故障,事後都可以用任何一個鏡像出來的本地倉庫恢復。因為每一次的克隆操作,實際上都是一次對代碼倉庫的完整備份。
1.2 Git簡介
官網:https://git-scm.com
git是一個分散式版本控制軟體,最初由林納斯·托瓦茲(Linus Torvalds)創作,於2005年以GPL發佈。最初目的是為更好地管理Linux內核開發而設計。
Git 官方中文手冊 https://git-scm.com/book/zh/v2
1.2.1 Git歷史
自2002年開始,林納斯·托瓦茲決定使用BitKeeper作為Linux內核主要的版本控制系統用以維護代碼。因為BitKeeper為專有軟體,這個決定在社區中長期遭受質疑。在Linux社區中,特別是理查德·斯托曼與自由軟體基金會的成員,主張應該使用開放源代碼的軟體來作為Linux核心的版本控制系統。林納斯·托瓦茲曾考慮過採用現成軟體作為版本控制系統(例如Monotone),但這些軟體都存在一些問題,特別是性能不佳。現成的方案,如CVS的架構,受到林納斯·托瓦茲的批評。
2005年,安德魯·垂鳩寫了一個簡單程式,可以連接BitKeeper的存儲庫,BitKeeper著作權擁有者拉里·麥沃伊認為安德魯·垂鳩對BitKeeper內部使用的協議進行逆向工程,決定收回無償使用BitKeeper的授權。Linux內核開發團隊與BitMover公司進行蹉商,但無法解決他們之間的歧見。林納斯·托瓦茲決定自行開發版本控制系統替代BitKeeper,以十天的時間,編寫出第一個git版本
1.3 安裝git
1.3.1 環境說明
[root@gitlab ~]# rpm -qa centos-release centos-release-7-4.1708.el7.centos.x86_64 [root@gitlab ~]# uname -a Linux gitlab 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@gitlab ~]# getenforce Disabled [root@gitlab ~]# systemctl status firewalld.service ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1)
# 本文使用的linux系統均為該系統
# 本文使用的windows系統為 Microsoft Windows [版本 10.0.15063]
1.3.2 Yum安裝Git
# centos 自帶git
[root@gitlab ~]# rpm -qa git git-1.8.3.1-11.el7.x86_64
# 安裝方法
yum install git -y
1.3.3 編譯安裝
編譯安裝可以安裝較新版本的git
Git下載地址: https://github.com/git/git/releases
# 安裝依賴關係 yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel # 編譯安裝 tar -zxf git-2.0.0.tar.gz cd git-2.0.0 make configure ./configure --prefix=/usr make make install
1.4 初次運行 Git 前的配置
1.4.1 配置git
命令集
git config --global user.name "clsn" #配置git使用用戶 git config --global user.email "[email protected]" #配置git使用郵箱 git config --global color.ui true #語法高亮 git config --list # 查看全局配置
配置過程
[root@gitlab ~]# git config --global user.name "clsn" #配置git使用用戶 [root@gitlab ~]# git config --global user.email "[email protected]" #配置git使用郵箱 [root@gitlab ~]# git config --global color.ui true #語法高亮 [root@gitlab ~]# git config --list # 查看全局配置 user.name=clsn user.email=[email protected] color.ui=true
生成的配置文件
[root@gitlab ~]# cat .gitconfig [user] name = clsn email = [email protected] [color] ui = true
1.4.2 獲取幫助
使用Git時需要獲取幫助,有三種方法可以找到Git命令的使用手冊:
git help <verb> git <verb> --help man git-<verb>
例如,要想獲得配置命令的手冊,執行
git help config
1.5 獲取 Git 倉庫(初始化倉庫)
# 創建目錄 mkdir git_data # 進入目錄 cd git_data/ # 初始化 git init # 查看工作區狀態 git status
操作過程
[root@gitlab ~]# mkdir git_data [root@gitlab ~]# cd git_data/ [root@gitlab git_data]# git init 初始化空的 Git 版本庫於 /root/git_data/.git/ [root@gitlab git_data]# git status # 位於分支 master # # 初始提交 # 無文件要提交(創建/拷貝文件並使用 "git add" 建立跟蹤)
1.6 Git命令常規操作
常用命令說明
命令 |
命令說明 |
add |
添加文件內容至索引 |
bisect |
通過二分查找定位引入 bug 的變更 |
branch |
列出、創建或刪除分支 |
checkout |
檢出一個分支或路徑到工作區 |
clone |
克隆一個版本庫到一個新目錄 |
commit |
記錄變更到版本庫 |
diff |
顯示提交之間、提交和工作區之間等的差異 |
fetch |
從另外一個版本庫下載對象和引用 |
grep |
輸出和模式匹配的行 |
init |
創建一個空的 |
Git |
版本庫或重新初始化一個已存在的版本庫 |
log |
顯示提交日誌 |
merge |
合併兩個或更多開發歷史 |
mv |
移動或重命名一個文件、目錄或符號鏈接 |
pull |
獲取併合並另外的版本庫或一個本地分支 |
push |
更新遠程引用和相關的對象 |
rebase |
本地提交轉移至更新後的上游分支中 |
reset |
重置當前HEAD到指定狀態 |
rm |
從工作區和索引中刪除文件 |
show |
顯示各種類型的對象 |
status |
顯示工作區狀態 |
tag |
創建、列出、刪除或校驗一個GPG簽名的 tag 對象 |
常用操作示意圖
文件的狀態變化周期
1.6.1 創建文件
[root@gitlab git_data]# touch README [root@gitlab git_data]# git status # 位於分支 master # # 初始提交 # # 未跟蹤的文件: # (使用 "git add <file>..." 以包含要提交的內容) # # README 提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
添加文件跟蹤
[root@gitlab git_data]# git add ./* [root@gitlab git_data]# git status # 位於分支 master # # 初始提交 # # 要提交的變更: # (使用 "git rm --cached <file>..." 撤出暫存區) # # 新文件: README #
文件會添加到.git的隱藏目錄
[root@gitlab git_data]# tree .git/ .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 ├── index ├── info │ └── exclude ├── objects │ ├── e6 │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ ├── info │ └── pack └── refs ├── heads └── tags
由工作區提交到本地倉庫
[root@gitlab git_data]# git commit -m 'first commit' [master(根提交) bb963eb] first commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README
查看git的狀態
[root@gitlab git_data]# git status # 位於分支 master 無文件要提交,乾凈的工作區
提交後的git目錄狀態
[root@gitlab git_data]# tree .git/ .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 │ └── master ├── objects │ ├── 54 │ │ └── 3b9bebdc6bd5c4b22136034a95dd097a57d3dd │ ├── bb │ │ └── 963eb32ad93a72d9ce93e4bb55105087f1227d │ ├── e6 │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ ├── info │ └── pack └── refs ├── heads │ └── master └── tags
1.6.2 添加新文件
git add * 添加到暫存區域
git commit 提交git倉庫 -m 後面接上註釋信息,內容關於本次提交的說明,方便自己或他人查看
修改或刪除原有文件
常規方法
git add *
git commit
簡便方法
git commit -a -m "註釋信息"
-a 表示直接提交
Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected.
1.6.3 刪除git內的文件
命令說明:
• 沒有添加到暫存區的數據直接rm刪除即可。
• 已經添加到暫存區數據:
git rm --cached database
#→將文件從git暫存區域的追蹤列表移除(並不會刪除當前工作目錄內的數據文件)
git rm -f database
#→將文件數據從git暫存區和工作目錄一起刪除
命令實踐:
# 創建新文件 [root@gitlab git_data]# touch 123 [root@gitlab git_data]# git status # 位於分支 master # 未跟蹤的文件: # (使用 "git add <file>..." 以包含要提交的內容) # # 123 提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
# 將文件添加到暫存區域
[root@gitlab git_data]# git add 123 [root@gitlab git_data]# git status # 位於分支 master # 要提交的變更: # (使用 "git reset HEAD <file>..." 撤出暫存區) # # 新文件: 123
# 刪除文件
[root@gitlab git_data]# rm 123 -f [root@gitlab git_data]# ls [root@gitlab git_data]# git status # 位於分支 master # 要提交的變更: # (使用 "git reset HEAD <file>..." 撤出暫存區) # # 新文件: 123 # # 尚未暫存以備提交的變更: # (使用 "git add/rm <file>..." 更新要提交的內容) # (使用 "git checkout -- <file>..." 丟棄工作區的改動) # # 刪除: 123 #
[root@gitlab git_data]# git reset HEAD ./* [root@gitlab git_data]# git status # 位於分支 master 無文件要提交,乾凈的工作區
1.6.4 重命名暫存區數據
• 沒有添加到暫存區的數據直接mv/rename改名即可。
• 已經添加到暫存區數據:
git mv README NOTICE
1.6.5 查看歷史記錄
• git log #→查看提交歷史記錄
• git log -2 #→查看最近幾條記錄
• git log -p -1 #→-p顯示每次提交的內容差異,例如僅查看最近一次差異
• git log --stat -2 #→--stat簡要顯示數據增改行數,這樣能夠看到提交中修改過的內容,對文件添加或移動的行數,併在最後列出所有增減行的概要信息
• git log --pretty=oneline #→--pretty根據不同的格式展示提交的歷史信息
• git log --pretty=fuller -2 #→以更詳細的模式輸出提交的歷史記錄
• git log --pretty=fomat:"%h %cn" #→查看當前所有提交記錄的簡短SHA-1哈希字串與提交著的姓名。
使用format參數來指定具體的輸出格式
格式 |
說明 |
%s |
提交說明。 |
%cd |
提交日期。 |
%an |
作者的名字。 |
%cn |
提交者的姓名。 |
%ce |
提交者的電子郵件。 |
%H |
提交對象的完整SHA-1哈希字串。 |
%h |
提交對象的簡短SHA-1哈希字串。 |
%T |
樹對象的完整SHA-1哈希字串。 |
%t |
樹對象的簡短SHA-1哈希字串。 |
%P |
父對象的完整SHA-1哈希字串。 |
%p |
父對象的簡短SHA-1哈希字串。 |
%ad |
作者的修訂時間。 |
命令實踐
[root@gitlab git_data]# git log commit a409fc46f792228a8119705e9cc97c2a013534ab Author: clsn <[email protected]> Date: Wed Nov 29 11:44:14 2017 +0800 test commit bb963eb32ad93a72d9ce93e4bb55105087f1227d Author: clsn <[email protected]> Date: Wed Nov 29 10:57:02 2017 +0800 first commit
1.6.6 還原歷史數據
Git服務程式中有一個叫做HEAD的版本指針,當用戶申請還原數據時,其實就是將HEAD指針指向到某個特定的提交版本,但是因為Git是分散式版本控制系統,為了避免歷史記錄衝突,故使用了SHA-1計算出十六進位的哈希字串來區分每個提交版本,另外預設的HEAD版本指針會指向到最近的一次提交版本記錄,而上一個提交版本會叫HEAD^,上上一個版本則會叫做HEAD^^,當然一般會用HEAD~5來表示往上數第五個提交版本。
git reset --hard hash
git reset --hard HEAD^ #→還原歷史提交版本上一次
git reset --hard 3de15d4 #→找到歷史還原點的SHA-1值後,就可以還原(值不寫全,系統
會自動匹配)
測試命令
[root@gitlab git_data]# git log commit a409fc46f792228a8119705e9cc97c2a013534ab Author: clsn <[email protected]> Date: Wed Nov 29 11:44:14 2017 +0800 test commit bb963eb32ad93a72d9ce93e4bb55105087f1227d Author: clsn <[email protected]> Date: Wed Nov 29 10:57:02 2017 +0800 first commit
還原數據
[root@gitlab git_data]# git reset --hard bb963 HEAD 現在位於 bb963eb first commit # 查看數據 [root@gitlab git_data]# ls README
1.6.7 還原未來數據
什麼是未來數據?就是你還原到歷史數據了,但是你後悔了,想撤銷更改,但是git log已經找不到這個版本了。
git reflog #→查看未來歷史更新點
測試命令
[root@gitlab git_data]# git reflog bb963eb HEAD@{0}: res