Git學習之旅

前言:該文章內容僅爲git學習筆記,同時博主將git總結出git的思惟導圖有助記憶學習,若是須要有誤或但願增刪內容能夠下載XMind版的源文件linux

1、關於版本控制

1.1本地版本控制

本地版本控制系統 許多人習慣用複製整個項目目錄的方式來保存不一樣的版本,或許還會更名加上備份時間以示區別。這麼作惟一的好處就是簡單,可是特別容易犯錯。有時候會混淆所在的工做目錄,一不當心會寫錯文件或者覆蓋意想外的文件。
git

1.2集中化的版本控制系統

如何讓在不一樣系統上的開發者協同工做?因而,集中化的版本控制系統(Centralized Version Control Systems,簡稱 CVCS)應運而生。這類系統,諸如 CVS、Subversion 以及Perforce 等,都有一個單一的集中管理的服務器,保存全部文件的修訂版本,而協同工做的人們都經過客戶端連到這臺服務器,取出最新的文件或者提交更新。多年以來,這已成爲版本控制系統的標準作法。
程序員

1.3分佈式版本控制系統

在這類系統中,像Git、Mercurial、Bazaar 以及 Darcs 等,客戶端並不僅提取最新版本的文件快照,而是把代碼倉庫完整地鏡像下來。這麼一來,任何一處協同工做用的服務器發生故障,過後均可以用任何一個鏡像出來的本地倉庫恢復。由於每一次的克隆操做,實際上都是一次對代碼倉庫的完整備份。
github

2、Git簡介

git是一個分佈式版本控制軟件,最初由林納斯·託瓦茲(Linus Torvalds)創做,於2005年以GPL發佈。最初目的是爲更好地管理Linux內核開發而設計。vim

2.1 Git歷史

自2002年開始,林納斯·託瓦茲決定使用BitKeeper做爲Linux內核主要的版本控制系統用以維護代碼。由於BitKeeper爲專有軟件,這個決定在社區中長期遭受質疑。在Linux社區中,特別是理查德·斯托曼與自由軟件基金會的成員,主張應該使用開放源代碼的軟件來做爲Linux核心的版本控制系統。林納斯·託瓦茲曾考慮過採用現成軟件做爲版本控制系統(例如Monotone),但這些軟件都存在一些問題,特別是性能不佳。現成的方案,如CVS的架構,受到林納斯·託瓦茲的批評。centos

2005年,安德魯·垂鳩寫了一個簡單程序,能夠鏈接BitKeeper的存儲庫,BitKeeper著做權擁有者拉里·麥沃伊認爲安德魯·垂鳩對BitKeeper內部使用的協議進行逆向工程,決定收回免費使用BitKeeper的受權。Linux內核開發團隊與BitMover公司進行蹉商,但沒法解決他們之間的歧見。林納斯·託瓦茲決定自行開發版本控制系統替代BitKeeper,以十天的時間,編寫出第一個git版本。服務器

3、Git 工做流程

  • Workspace:工做區
  • Index / Stage:暫存區
  • Repository:倉庫區(或本地倉庫)
    +Remote:遠程倉庫

3.1工做區

程序員進行開發改動的地方,是你當前看到的,也是最新的。架構

日常咱們開發就是拷貝遠程倉庫中的一個分支,基於該分支進行開發。在開發過程當中就是對工做區的操做。app

3.2暫存區

.git目錄下的index文件, 暫存區會記錄git add添加文件的相關信息(文件名、大小、timestamp...),不保存文件實體, 經過id指向每一個文件實體。可使用git status查看暫存區的狀態。暫存區標記了你當前工做區中,哪些內容是被git管理的。curl

3.3本地倉庫

保存了對象被提交 過的各個版本,比起工做區和暫存區的內容,它要更舊一些。

git commit後同步index的目錄樹到本地倉庫,方便從下一步經過git push同步本地倉庫與遠程倉庫的同步。

3.4遠程倉庫

遠程倉庫的內容可能被分佈在多個地點的處於協做關係的本地倉庫修改,所以它可能與本地倉庫同步,也可能不一樣步,可是它的內容是最舊的。

【總結】

  • 任何對象都是在工做區中誕生和被修改;
  • 任何修改都是從進入index區纔開始被版本控制;
  • 只有把修改提交到本地倉庫,該修改才能在倉庫中留下痕跡;
  • 與協做者分享本地的修改,能夠把它們push到遠程倉庫來共享。

下面這幅圖更加直接闡述了四個區域之間的關係

HEAD,它始終指向當前所處分支的最新的提交點。你所處的分支變化了,或者產生了新的提交點,HEAD就會跟着改變。

4、安裝Git

4.1環境說明

[root@mico ~]# rpm -qa centos-release
centos-release-7-5.1804.4.el7.centos.x86_64
[root@mico ~]# uname -a
Linux mico 3.10.0-862.11.6.el7.x86_64 #1 SMP Tue Aug 14 21:49:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@mico ~]# getenforce
Disabled
[root@mico ~]# 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)

4.2yum安裝Git

centos自帶git

[root@mico ~]# rpm -qa git
git-1.8.3.1-14.el7_5.x86_64

安裝方法

yum install git -y

4.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.22.0.tar.gz
cd git-2.22.0
make configure
./configure --prefix=/usr
make  
make install

5、初次運行Git前的配置

5.1配置Git

命令集

git config --global user.name "mico"  #配置git使用用戶
git config --global user.email "admin@mico.com"  #配置git使用郵箱
git config --global color.ui true  #語法高亮
git config --list # 查看全局配置

** 配置過程**

[root@mico ~]# git config --global user.name "mico"  #配置git使用用戶
[root@mico ~]# git config --global user.email "admin@mico.com"  #配置git使用郵箱
[root@mico ~]# git config --global color.ui true  #語法高亮
[root@mico ~]# git config --list # 查看全局配置
user.name=mico
user.email=admin@mico.com
color.ui=true

生成的配置文件

[root@mico ~]# cat ~/.gitconfig 
[user]
    email = admin@mico.com
    name = mico

5.2 獲取幫助

使用Git時須要獲取幫助,有三種方法能夠找到Git命令的使用手冊:

git help <verb>
git <verb> --help
man git-<verb>

例如,要想得到配置命令的手冊,執行

git help config

6、獲取Git倉庫(初始化倉庫)

# 建立目錄
mkdir git_data
# 進入目錄
cd git_data/
# 初始化
git init
# 查看工做區狀態
git status

操做過程

[root@mico practices]# mkdir git_data
[root@mico practices]# cd git_data/
[root@mico git_data]# git init
初始化空的 Git 版本庫於 /root/practices/git_data/.git/
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
無文件要提交(建立/拷貝文件並使用 "git add" 創建跟蹤)

7、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 對象

經常使用操做示意圖

文件的狀態變化週期

7.1建立文件

[root@mico git_data]# touch README
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
# 未跟蹤的文件:
#   (使用 "git add <file>..." 以包含要提交的內容)
#
#   README
提交爲空,可是存在還沒有跟蹤的文件(使用 "git add" 創建跟蹤)

7.2添加文件跟蹤

[root@mico git_data]# git add ./*
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
# 要提交的變動:
#   (使用 "git rm --cached <file>..." 撤出暫存區)
#
#   新文件:    README
#

文件會添加到.git隱藏目錄

[root@mico 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

10 directories, 15 files

由工做區提交到本地倉庫

[root@mico git_data]# git commit -m "first commit"
[master(根提交) 45a5f78] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README

查看git的狀態

[root@mico git_data]# git status
# 位於分支 master
無文件要提交,乾淨的工做區

查看git的狀態

[root@mico 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
│   ├── 45
│   │   └── a5f78aedaceb9b7082e3f7292f8ab1ac519d02
│   ├── 54
│   │   └── 3b9bebdc6bd5c4b22136034a95dd097a57d3dd
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

15 directories, 21 files

7.3添加新文件

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.

7.4刪除git內的文件

命令說明

沒有添加到暫存區的數據直接rm刪除便可
已經添加到暫存區數據:
git rm --cached database 
#→將文件從git暫存區域的追蹤列表移除(並不會刪除當前工做目錄內的數據文件)
git rm -f database
#→將文件數據從git暫存區和工做目錄一塊兒刪除

命令實踐

[root@mico git_data]# touch 123
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
# 未跟蹤的文件:
#   (使用 "git add <file>..." 以包含要提交的內容)
#
#   123
提交爲空,可是存在還沒有跟蹤的文件(使用 "git add" 創建跟蹤)
[root@mico git_data]# git add 123
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
# 要提交的變動:
#   (使用 "git rm --cached <file>..." 撤出暫存區)
#
#   新文件:    123
#
[root@mico git_data]# rm 123 -f
[root@mico git_data]# ls
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
# 要提交的變動:
#   (使用 "git rm --cached <file>..." 撤出暫存區)
#
#   新文件:    123
#
# 還沒有暫存以備提交的變動:
#   (使用 "git add/rm <file>..." 更新要提交的內容)
#   (使用 "git checkout -- <file>..." 丟棄工做區的改動)
#
#   刪除:      123
#
[root@mico git_data]# git rm --cached 123
rm '123'
[root@mico git_data]# git status
# 位於分支 master
#
# 初始提交
#
無文件要提交(建立/拷貝文件並使用 "git add" 創建跟蹤)

重命名暫存區數據

  • 沒有添加到暫存區的數據直接 mv/rename 更名便可
  • 已經添加到暫存區的數據
git mv <old-file-name> <new-file-name>

7.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@mico git_data]# git log
commit c2caa1467c39f006cffbcafa838d575c526f4347
Author: TRsky <625310581@qq.com>
Date:   Thu Jul 11 10:07:57 2019 +0800

    show test

commit 90370a8eb959ccb2f63f7a75e4334e908315b31b
Author: TRsky <625310581@qq.com>
Date:   Thu Jul 11 10:07:22 2019 +0800

    the first commit

7.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@mico git_data]# git log
commit c2caa1467c39f006cffbcafa838d575c526f4347
Author: TRsky <625310581@qq.com>
Date:   Thu Jul 11 10:07:57 2019 +0800

    show test

commit 90370a8eb959ccb2f63f7a75e4334e908315b31b
Author: TRsky <625310581@qq.com>
Date:   Thu Jul 11 10:07:22 2019 +0800

    the first commit

還原數據

[root@mico git_data]# git reset --hard 90370
HEAD 如今位於 90370a8 the first commit
[root@mico git_data]# ls
README
[root@mico git_data]#

7.7還原將來數據

什麼是將來數據?就是你還原到歷史數據了,可是你後悔了,想撤銷更改,可是git log已經找不到這個版本了。

git reflog   #→查看將來歷史更新點

測試命令

[root@mico git_data]# git reflog
90370a8 HEAD@{0}: reset: moving to 90370
c2caa14 HEAD@{1}: commit: show test
90370a8 HEAD@{2}: commit (initial): the first commit
[root@mico git_data]#

7.8標籤使用

前面回滾使用的是一串字符串,又長又難記。
git tag v1.0         #→當前提交內容打一個標籤(方便快速回滾),每次提交均可以打個tag。
git tag         #→查看當前全部的標籤
git show v1.0         #→查看當前1.0版本的詳細信息
git tag v1.2 -m "version 1.2 release is test"         #→建立帶有說明的標籤,-a指定標籤名字,-m指定說明文字
git tag -d v1.0         #→咱們爲同一個提交版本設置了兩次標籤,刪除以前的v1.0

命令實踐

[root@mico git_data]# git reset --hard 90370
HEAD 如今位於 90370a8 the first commit
[root@mico git_data]# git reset --hard c2caa
HEAD 如今位於 c2caa14 show test
[root@mico git_data]# git tag v20190711
[root@mico git_data]# git tag
v20190711
[root@mico git_data]# git show v20190711
commit c2caa1467c39f006cffbcafa838d575c526f4347
Author: Mico <admin@mico.com>
Date:   Thu Jul 11 10:07:57 2019 +0800

    show test

diff --git a/test b/test
new file mode 100644
index 0000000..e69de29

7.9對比數據

git diff能夠對比當前文件與倉庫已保存文件的區別,知道了對README做了什麼修改後,再把它提交到倉庫就放多了。

git diff README

8、分支結構

在實際的項目開發中,儘可能保證master分支穩定,僅用於發佈新版本,平時不要隨便直接修改裏面的數據文件。

那在哪幹活呢?幹活都在dev分支上。每一個人從dev分支建立本身我的分支,開發完合併到dev分支,最後dev分支合併到master分支。因此團隊的合做分支看起來會像下圖那樣。

8.1分支切換

[root@mico git_data]# git branch linux
[root@mico git_data]# git branch
  linux
* master
[root@mico git_data]# git checkout linux
切換到分支 'linux'
[root@mico git_data]# git branch
* linux
  master
[root@mico git_data]#

在Linux分支進行修改

[root@mico git_data]# cat README 
[root@mico git_data]# echo "2019年7月11號">>README
[root@mico git_data]# git add .
[root@mico git_data]# git commit -m "2019年7月11號11點0分"
[linux 20cefd6] 2019年7月11號11點0分
 1 file changed, 1 insertion(+)
[root@mico git_data]# git status
# 位於分支 linux
無文件要提交,乾淨的工做區

回到master分支

[root@mico git_data]# git checkout master
切換到分支 'master'
[root@mico git_data]# cat README 
[root@mico git_data]# git log -1
commit c2caa1467c39f006cffbcafa838d575c526f4347
Author: TRsky <admin@mico.com>
Date:   Thu Jul 11 10:07:57 2019 +0800

    show test

合併代碼

[root@mico git_data]# git merge linux
更新 c2caa14..20cefd6
Fast-forward
 README | 1 +
 1 file changed, 1 insertion(+)
[root@mico git_data]# git status
# 位於分支 master
無文件要提交,乾淨的工做區
[root@mico git_data]# cat README 
2019年7月1號

8.2合併失敗解決

模擬衝突,在文件的同一行作不一樣的修改
在master分支進行修改

[root@mico git_data]# cat README 
2019年7月1號
[root@mico git_data]# echo "this is master" >> README 
[root@mico git_data]# git commit -a -m "mico 2019年7月11日 "
[master 5b3e0ce] mico 2019年7月11日
 1 file changed, 1 insertion(+)

切換至linux分支

[root@mico git_data]# git checkout linux
切換到分支 'linux'
[root@mico git_data]# git branch
* linux
  master
[root@mico git_data]# cat README 
2019年7月1號
this is linux
[root@mico git_data]# git commit -a -m "2019年7月11日 linux" 
[linux 1973909] 2019年7月11日 linux
 1 file changed, 1 insertion(+)

回到master分支,進行合併,出現衝突

[root@mico git_data]# git checkout master
切換到分支 'master'
[root@mico git_data]# git merge linux
自動合併 README
衝突(內容):合併衝突於 README
自動合併失敗,修正衝忽然後提交修正的結果。

解決衝突

[root@mico git_data]# cat README 
2019年7月1號
<<<<<<< HEAD
this is master
=======
this is linux
>>>>>>> linux
[root@mico git_data]# vim README 
[root@mico git_data]# git commit -a -m "2019年7月11號 merge"
[master 67484d9] 2019年7月11號 merg

手動修改衝突的部分並從新提交

8.3刪除分支

由於以前已經合併了linux分支,因此如今看到它在列表中。 在這個列表中分支名字前沒有 * 號的分支一般可使用 git branch -d 刪除掉;你已經將它們的工做整合到了另外一個分支,因此並不會失去任何東西。

查看全部包含未合併工做的分支,能夠運行 git branch --no-merged:

git branch --no-merged
  testing

這裏顯示了其餘分支。 由於它包含了還未合併的工做,嘗試使用 git branch -d 命令刪除它時會失敗:

git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.

若是真的想要刪除分支並丟掉那些工做,如同幫助信息裏所指出的,可使用 -D 選項強制刪除它。

刪除分支

git branch -d 刪除分支
git push origin --delete 刪除遠程分支

命令實踐

[root@mico git_data]# git branch
  linux
* master
[root@mico git_data]# git branch -d linux
已刪除分支 linux(曾爲 1973909)。
[root@mico git_data]# git branch
* master
[root@mico git_data]#

【學習整理】

相關文章
相關標籤/搜索