寫在前面:
你好,歡迎關注!
- 我熱愛技術,熱愛分享,熱愛生活, 我始終相信:技術是開源的,知識是共享的!
- 博客裏面的內容大部分均爲原創,是自己日常的學習記錄和總結,便於自己在後面的時間裏回顧,當然也是希望可以分享自己的知識。目前的內容幾乎是基礎知識和技術入門,如果你覺得還可以的話不妨關注一下,我們共同進步!
- 個人除了分享博客之外,也喜歡看書,寫一點日常雜文和心情分享,如果你感興趣,也可以關注關注!
- 公衆號:傲驕鹿先生
部分內容轉自: https://www.cnblogs.com/best/p/7474442.html
目錄
前言
本文不對Git進行詳解,若想詳細學習,可以看以下地址的博文,強烈推薦。https://www.cnblogs.com/best/p/7474442.html
還有一個過關式遊戲的教程,有模型解讀知識,強烈推薦。https://learngitbranching.js.org/?demo
一、什麼是Git以及Git的工作原理
1、什麼是Git?
Git 是一個開源的分佈式版本控制系統,用於敏捷高效地處理任何或小或大的項目。
Git 是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。
Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分佈式版本庫的方式,不必服務器端軟件支持。
2、Git的工作原理
2.1、工作區域
Git本地有三個工作區域:工作目錄(Working Directory)、暫存區(Stage/Index)、資源庫(Repository或Git Directory)。如果在加上遠程的git倉庫(Remote Directory)就可以分爲四個工作區域。文件在這四個區域之間的轉換關係如下:
- Workspace:工作區,就是你平時存放項目代碼的地方
- Index / Stage:暫存區,用於臨時存放你的改動,事實上它只是一個文件,保存即將提交到文件列表信息
- Repository:倉庫區(或本地倉庫),就是安全存放數據的位置,這裏面有你提交到所有版本的數據。其中HEAD指向最新放入倉庫的版本
- Remote:遠程倉庫,託管代碼的服務器,可以簡單的認爲是你項目組中的一臺電腦用於遠程數據交換
本地的三個區域確切的說應該是git倉庫中HEAD指向的版本
- Directory:使用Git管理的一個目錄,也就是一個倉庫,包含我們的工作空間和Git的管理空間。
- WorkSpace:需要通過Git進行版本控制的目錄和文件,這些目錄和文件組成了工作空間。
- .git:存放Git管理信息的目錄,初始化倉庫的時候自動創建。
- Index/Stage:暫存區,或者叫待提交更新區,在提交進入repo之前,我們可以把所有的更新放在暫存區。
- Local Repo:本地倉庫,一個存放在本地的版本庫;HEAD會只是當前的開發分支(branch)。
- Stash:隱藏,是一個工作狀態保存棧,用於保存/恢復WorkSpace中的臨時狀態。
2.2、工作流程
git的工作流程一般是這樣的:
1、在工作目錄中添加、修改文件;
2、將需要進行版本管理的文件放入暫存區域;
3、將暫存區域的文件提交到git倉庫。
因此,git管理的文件有三種狀態:已修改(modified),已暫存(staged),已提交(committed)
2.3、圖解教程
個人認爲Git的原理相比別的版本控制器還是複雜一些的,有一份圖解教程比較直觀:
二、Git常用命令
git diff # 對比工作區和本地倉庫
git diff --cached # 對比緩存區和本地倉庫
git log # 查看當前版本之前所有的提交記錄
git reflog # 查看所有的提交記錄
git log -n 2 # 顯示最近幾條數據
git log -p # 對比每提交的差異
git log --format="%an:%ae:%s" # 自定義輸出格式
git reset --hard 版本號 # 回滾到指定版本
git chekout --file # 將文件回滾到最近的一次提交
git status # 查看狀態
git reset HEAD file # 將指定的文件從緩存區拉取到工作區
# 工作區必須有變動
# 保存開發狀態
git stash # 快照
git stash pop # 恢復並刪除快照
git stash list # 查看所有快照
git stash apply stash{id} # 恢復指定快照
git stash drop # 刪除快照
git branch # 查看分支
git branch dev # 創建dev分支
git checkout dev # 切換到dev分支
git branch -d dev # 刪除分支
git checkout -b dev1 # 創建分支並切換分支
# 合併分支,在合併到的分支上執行
git merge dev # 在master主分支上執行,(將dev的代碼合併到master)
# 衝突
# 不同的分支在對同一行代碼進行修改,在代碼合併時會發生衝突
"""
1、合併時間不能太長,一般2-3天合併一次
2、完成一個小功能合併一次
3、合併的時候所有人都要在
"""
# 克隆分支
git checkout -b dev origin/dev [指定以origin/dev爲模板創建一個分支
# 刪除遠程倉庫的分支
git checkout --delete origin
# tag
git tag # 查看標籤
git tag -a name -m '提交信息'
git tag -a name -m '提交信息' hash值 # 以哈希值爲模板創建一個標籤tag
git tag -d name # 刪除本地tag
git push origin :refs/tags/v0.5 # 刪除遠程倉木的tag(給遠程倉庫推送了一個空的tag
# 忽略文件
# 把不想上傳的文件寫在.gitignore文件中
vim .gitignore
- db.py
# rebase
變基 將提交記錄變成一條直線
# 切換git用戶
git config --global --unset user.name "xxx"
git config --global --unset user.email "xxx"
三、Git衝突怎麼引起的,怎麼解決
1、git衝突的場景
- 情景一:多個分支代碼合併到一個分支時;
- 情景二:多個分支向同一個遠端分支推送代碼時;
實際上,push操作即是將本地代碼merge到遠端庫分支上。關於push和pull其實就分別是用本地分支合併到遠程分支 和 將遠程分支合併到本地分支,所以這兩個過程中也可能存在衝突。
git的合併中產生衝突的具體情況:
<1>兩個分支中修改了同一個文件(不管什麼地方)
<2>兩個分支中修改了同一個文件的名稱
兩個分支中分別修改了不同文件中的部分,不會產生衝突,可以直接將兩部分合並。
2、衝突解決方法
- 情景一:在當前分支上,直接修改衝突代碼--->add--->commit。
- 情景二:在本地當前分支上,修改衝突代碼--->add--->commit--->push
注:借用vim或者IDE或者直接找到衝突文件,修改。
3、實戰演示
(1)情景
本地庫中兩個不同分支,修改同一個文件同一代碼塊,兩分支先後將修改合併到master分支上,master在合併第二個分支代碼時,報錯:合併衝突。
(2)本地庫
<1>master分支
<2>建立兩個分支
<3>兩分支修改提交
aBranch分支:
bBranch分支:
(3)合併分支產生衝突
合併aBranch分支(將aBranch分支合併到當前master分支上):
注:
git merge:默認情況下,Git執行"快進式合併"(fast-farward merge),會直接將Master分支指向Develop分支。
使用--no-ff參數後,會執行正常合併,在Master分支上生成一個新節點。爲了保證版本演進的清晰,建議採用這種方法。
再合併bBranch分支,產生衝突:
mergeTest.txt 文件內容:
(4)解決衝突
--->在當前分支上(master),找到衝突文件,直接修改衝突代碼,add,commit。
注:簡單方法,使用vim修改,cat查看衝突文件。(注意要刪除git自動生成的衝突代碼分隔符)
(5)完成衝突解決
注:提交或者合併都會生成git節點。每個節點對應一個代碼版本
四、架構師職責:Git Flow規範團隊git使用規程
雖然Git是非常優秀的的版本管理工具,但是我們面對版本管理的時候,依然有非常大得挑戰,我們都知道大家工作在同一個倉庫上,那麼彼此的代碼協作必然帶來很多問題和挑戰,如下:
- 如何開始一個Feature的開發,而不影響別的Feature?
- 由於很容易創建新分支,分支多瞭如何管理,時間久了,如何知道每個分支是幹什麼的?
- 哪些分支已經合併回了主幹?
- 如何進行Release的管理?開始一個Release的時候如何凍結Feature, 如何在Prepare Release的時候,開發人員可以繼續開發新的功能?
- 線上代碼出Bug了,如何快速修復?而且修復的代碼要包含到開發人員的分支以及下一個Release?
大部分開發人員現在使用Git就只是用三個甚至兩個分支,一個是Master, 一個是Develop, 還有一個是基於Develop打得各種分支。這個在小項目規模的時候還勉強可以支撐,因爲很多人做項目就只有一個Release, 但是人員一多,而且項目週期一長就會出現各種問題。
1、Git Flow
就像代碼需要代碼規範一樣,代碼管理同樣需要一個清晰的流程和規範。
2、Git Flow常用的分支
- Production 分支
也就是我們經常使用的Master分支,這個分支最近發佈到生產環境的代碼,最近發佈的Release, 這個分支只能從其他分支合併,不能在這個分支直接修改
- Develop 分支
這個分支是我們是我們的主開發分支,包含所有要發佈到下一個Release的代碼,這個主要合併與其他分支,比如Feature分支
- Feature 分支
這個分支主要是用來開發一個新的功能,一旦開發完成,我們合併回Develop分支進入下一個Release
- Release分支
當你需要一個發佈一個新Release的時候,我們基於Develop分支創建一個Release分支,完成Release後,我們合併到Master和Develop分支
- Hotfix分支
當我們在Production發現新的Bug時候,我們需要創建一個Hotfix, 完成Hotfix後,我們合併回Master和Develop分支,所以Hotfix的改動會進入下一個Release
3、Git Flow如何工作
初始分支
所有在Master分支上的Commit應該Tag
Feature 分支
分支名 feature/*
Feature分支做完後,必須合併回Develop分支, 合併完分支後一般會刪點這個Feature分支,但是我們也可以保留
Release分支
分支名 release/*
Release分支基於Develop分支創建,打完Release分之後,我們可以在這個Release分支上測試,修改Bug等。同時,其它開發人員可以基於開發新的Feature (記住:一旦打了Release分支之後不要從Develop分支上合併新的改動到Release分支)
發佈Release分支時,合併Release到Master和Develop, 同時在Master分支上打個Tag記住Release版本號,然後可以刪除Release分支了。
維護分支 Hotfix
分支名 hotfix/*
hotfix分支基於Master分支創建,開發完後需要合併回Master和Develop分支,同時在Master上打一個tag
Git Flow代碼示例
a. 創建develop分支
git branch develop
git push -u origin develop
b. 開始新Feature開發
git checkout -b some-feature develop
# Optionally, push branch to origin:
git push -u origin some-feature
# 做一些改動
git status
git add some-file
git commit
c. 完成Feature
git pull origin develop
git checkout develop
git merge --no-ff some-feature
git push origin develop
git branch -d some-feature
# If you pushed branch to origin:
git push origin --delete some-feature
d. 開始Relase
git checkout -b release-0.1.0 develop
# Optional: Bump version number, commit
# Prepare release, commit
e. 完成Release
git checkout master
git merge --no-ff release-0.1.0
git push
git checkout develop
git merge --no-ff release-0.1.0
git push
git branch -d release-0.1.0
# If you pushed branch to origin:
git push origin --delete release-0.1.0
git tag -a v0.1.0 master
git push --tags
f. 開始Hotfix
git checkout -b hotfix-0.1.1 master
g. 完成Hotfix
git checkout master
git merge --no-ff hotfix-0.1.1
git push
git checkout develop
git merge --no-ff hotfix-0.1.1
git push
git branch -d hotfix-0.1.1
git tag -a v0.1.1 master
git push --tags
4、Git flow工具
實際上,當你理解了上面的流程後,你完全不用使用工具,但是實際上我們大部分人很多命令就是記不住呀,流程就是記不住呀,腫麼辦呢?
總有聰明的人創造好的工具給大家用, 那就是Git flow script.
安裝
- OS X
brew install git-flow
- Linux
apt-get install git-flow
- Windows
wget -q -O - --no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash
使用
-
初始化: git flow init
-
開始新Feature: git flow feature start MYFEATURE
-
Publish一個Feature(也就是push到遠程): git flow feature publish MYFEATURE
-
獲取Publish的Feature: git flow feature pull origin MYFEATURE
-
完成一個Feature: git flow feature finish MYFEATURE
-
開始一個Release: git flow release start RELEASE [BASE]
- Publish一個Release: git flow release publish RELEASE
-
發佈Release: git flow release finish RELEASE
別忘了git push --tags -
開始一個Hotfix: git flow hotfix start VERSION [BASENAME]
-
發佈一個Hotfix: git flow hotfix finish VERSION