Git分散式版本控制系統
1. Git概述
1.1 Git簡介
Git是一款免費、開源的分散式版本控制系統,用於明捷高效處理任何或小或大的專案。Git是Linus為了幫助管理Linux核心開發而開發的一個開源版本控制軟體。
1.2 Git的優點
- 更順暢的工作流程,開發過程中,完全可以離線操作
- 快速,Git分散式架構使得本地倉庫包含所有的歷史版本資訊,可以在不同的版本之間快速切換
- 彈性的本地分支,在svn下,建一個分支需要把原始碼複製到另外一個資料夾,而在Git下,建立分支的代價是非常小的,只需一條命令
- 倉庫目錄結構簡潔,用Git複製一個專案,只會在專案根目錄建立一個.git的目錄,而其他目錄很乾淨
- 內容按元資料方式儲存,所有的版本資訊都位於.git目錄下
- 完整性好,更易於協作開發
- 使用者群大,現在已經有成千上萬個開源專案採用Git來做專案管理,github上更是有無數個程式碼倉庫
2. Git的工作原理
2.1 基本概述
在Git中的絕大多數操作都只需要訪問本地檔案和資源,不用連網,因為Git在本地磁碟上就儲存著當前專案的歷史更新,所以處理起來速度很快。
如果想要看當前版本的檔案和一個月前的版本之間有何差異,Git會取出一個月前的快照和當前檔案作一次差異運算,而不用請求遠端伺服器來做這件事。
2.2 Git的狀態
對於任何一個檔案,在Git內部都只有三種狀態:已修改(modified)、已暫存(storaged)和 已提交(committed)
- 已修改:表示修改了某個檔案,但是還沒有提交儲存
- 已暫存:表示把已修改的檔案放在下次提交時要儲存的清單中
- 已提交:表示該檔案已經被安全的儲存在本地資料庫中了
2.3 Git檔案流轉的區域
- 使用Git管理專案時,檔案流轉的區域:Git的工作目錄、暫存區域、本地倉庫、遠端倉庫
1)工作區
本地電腦存放專案檔案的地方
2)暫存區:(Index/Stage)
本地專案目錄中的 .git 目錄稱之為版本庫。
.git 目錄包含了兩個部分,一個是暫存區(Index或者Stage),就是暫時存放檔案的地方,通常使用add命令將工作區的檔案新增到暫存區裡。
3)本地倉庫
.git 目錄中還包括git自動建立的maste分支,並且將HEAD指標指向master分支。
使用commit命令可以將暫存區中的檔案新增到本地倉庫中。
4)遠端倉庫
不是在本地倉庫中,專案程式碼在遠端git伺服器上,比如專案放在github上,就是一個遠端倉庫,通常使用clone命令將遠端倉庫拷貝到本地倉庫中,開發後推送到遠端倉庫中即可。
2.4 Git的基本工作流程
1)工作流程
每個專案都有一個Git目錄(如果是 git clone 出來的話,就是其中 .git 的目錄;如果是 git clone --bare 的話,新建的目錄本身就是Git目錄)。它是Git用來儲存元資料和物件資料庫的地方。每次克隆映象倉庫的時候,實際拷貝的就是這個目錄裡面的資料。
從專案中取出某個版本的所有檔案和目錄,用以開始後續工作的叫工作目錄。這些檔案實際上都是從 Git 目錄中的壓縮物件資料庫中提取出來的,接下來就可以在工作目錄中對這些檔案進行編輯。
所謂的暫存區域只不過是一個簡單的檔案,一般都放置Git目錄中。有時會把這個檔案叫做索引檔案,但是標準叫法還是暫存區域。
- 在工作目錄中修改某些檔案
- 對修改或的檔案進行快照,然後儲存到暫存區域
- 提交更新,將保持在暫存區域的檔案快照轉儲到Git目錄中
2)可以從檔案所處的位置來判斷狀態
- 如果是Git目錄中儲存著特定版本檔案,就屬於已提交狀態
- 如果做了修改並已放入暫存區域,就屬於已暫存狀態
- 如果自上次取出後,做了修改但是還沒有放到暫存區域,就是已修改狀態
3. Git的使用方法
3.1 基本使用命令
1)基本使用
git config --global user.name "xxx" // 配置使用者名稱 //上傳本地 repository 到伺服器上的時候,在 Github 上會顯示這裡配置的上傳者資訊 git config --global user.email "xxx" // 配置郵箱 // 以上配置資訊執行一次即可 git init /path // 建立本地倉庫(repository),初始化 // 會在目錄下建立一個 .git 目錄,.git 目錄裡儲存了所有的版本資訊、標記等資訊 git add xxx.html // 從本地倉庫增刪,結果將會儲存到本機的快取裡面 git add -A // 提交全部修改 git add . // 管理全部沒有被管理的檔案 git commit -m "註釋" // 提交,把本機快取中的內容提交到本機的 HEAD 裡面 git status // 檢視狀態 git log // 檢視版本,以確定需要回到的時刻點 git log --pretty=oneline // 每行顯示一條版本記錄 git log --graph // 以簡單的圖的方式來顯示 git reset --hard 6774dbf8d5116fa6b99875db461321b8eaad60c1 // 進行版本回退,後面的字元就是git log命令顯示結果中的版本號 git reflog // 回到過去的版本號後,如果想要回到最新的版本的時候,就要用這裡命令來找到最新的版本號,然後再用reset回到那個版本號 git config --list // 檢視配置列表 git rm xxx // 從本地倉庫刪除指定檔案,將檔案從暫存區中刪除 git rm -r xxx // 從本地倉庫刪除指定資料夾
2)推送到遠端
git clone https://github.com/hgzerowzh/blog_website.git // 將github上的倉庫克隆到本地,它內部已經起了別名了,也就是後面再進行推送的時候,已經不需要再添加了 git add readme.txt git remote add origin [email protected]:xxx/first.git // 把本地倉庫和遠端倉庫關聯起來,如果不執行這個命令,則每次 push 的時候都需要指定遠端伺服器的地址 git remote -v // 檢視origin的相關資訊 git push origin master //把本地的commit push到遠端伺服器 // origin 也就是之前 git remote add origin 那個命令裡面的 origin,origin 替代了伺服器倉庫地址:git push [email protected]:xxx/first.git master // master表示推送的是本地的master分支 // 如果顯示沒有許可權,則要去修改 .git/config檔案中的origin配置段:url = https://使用者名稱:密碼@github.com/使用者名稱/倉庫名.git git pull origin master //從遠端伺服器pull新的改動 // 上面一個命令等同於以下兩個命令: git fetch origin master git merge origin/master git push origin master //把本地的 commit push 到遠端倉庫中 //可以使用 .gitignore 檔案忽略指定的內容 # 使用ssh認證只需要把生成的公鑰上傳到github上即可 // 生成公私鑰:ssh-keygen -t rsa -C "註冊郵箱"
3.2 撤銷
1)撤銷的相關命令
# 將暫存區的檔案覆蓋工作目錄中的檔案,不加 -- 檔名 則表示覆蓋全部檔案 git checkout -- 檔名 # 刪除工作區檔案,並且也從暫存區刪除對應檔案的記錄 git rm xxx.file # 將檔案從暫存區中刪除,但是工作區依然還有該檔案 git rm --cached 檔名 # 取消暫存區已經暫存的檔案 git reset HEAD ... git reset HEAD~2 # 往前撤銷2次 # 將git倉庫中指定的更新記錄恢復出來,並且覆蓋暫存區和工作目錄 git reset --hard commitID # git reset的引數: --soft 快取區和工作目錄都不會改變,只會改變庫裡面的 --mixed 預設選項,快取區和你指定的提交同步,但工作目錄不會受影響(沒有提交的東西需不需要保留) --hard 快取區和工作目錄都同步到你指定的提交
2)git reset說明
# 當檢測到檔案路徑時,git reset將快取區同步到你指定的那個提交 # 比如,下面這個命令會將倒數第二個提交中的foo.py加入到快取區中,供下一個提交使用 git reset HEAD~2 foo.py # 執行git reset HEAD foo.py會將當前的foo.py從快取區中移除出去, # 而不會影響工作目錄中對foo.py的更改 # --soft 、--mixed、--hard對檔案層面的git reset毫無作用 # 因為快取區中的檔案一定會變化,而工作目錄中的檔案一定不變
3)使用場景
3.3 分支管理
1)分支:生成副本,避免影響開發主線
- 主分支(master):第一次向git倉庫提交更新記錄時自動產生的一個分支
- 開發分支(develop):作為開發的分支,基於master分支建立
- 功能分支(feature):作為開發具體功能的分支基於開發分支建立
2)分支管理命令
git branch // 檢視分支 git branch 分支名稱 // 建立分支 git checkout 分支名稱 // 切換分支(切換指標) git merge 被合併的分支 // 合併分支,要先切回master分支,然後在master分支上合併其他分支 git branch -d 分支名稱 // 刪除分支,分支合併後才允許被刪除,可以用-D大寫強制刪除 # 在刪除分支的時候,一定要先退出要刪除的分支,然後才能刪除 git branch --merged // 檢視已經被merge的分支 git branch --no-merged // 檢視還沒有被merge的分支
- 線上程式碼出bug緊急修復:
- 建立一個新的分支,在這個分支上對bug進行修復
- 修復完成之後,將新的分支合併到主分支(master)中去,然後刪除這個bug分支
3)衝突的產生
- 比如沒有拉取就進行提交操作,可能就會產生衝突
- 解決方法:先pull一下,然後需要開發之間進行協商,進行程式碼的取捨,然後重新提交
- 如果是分支合併出現了衝突,就需要手動進行衝突修復
3.4 rebase的使用
將多個提交記錄整合
記錄合併語法:
- git rebase -i HEAD~3
- 將從HEAD開始的三條記錄進行合併
- git rebase -i 記錄編號
- 將從HEAD開始到此記錄編號的所有記錄全部合併
然後進行記錄合併:
- s 表示將當前版本合併到它上一個版本中去
- 下面表示將v3和v4的記錄都合併到v2中去
接著修改提交記錄:
- 原本是這樣:
- 修改成:
最後檢視提交記錄:
- 注意:不要合併已經push到遠端倉庫的記錄
3.5 打tag並推送到遠端
# 檢視log git log # 為當前分支打上tag:v1 git tag -a v1 -m "第一版" # 將tag推送到遠端倉庫 git push origin --tag # 建立dev並切換到dev分支 git checkout -b dev # 把dev分支推送到遠端倉庫 git push origin dev
3.6 忽略檔案
某些檔案我們不想讓其提交到遠端倉庫,此時就可以使用“忽略檔案”機制來實現需求。
忽略檔案需要新建一個 .gitignore的檔案,該檔案用於宣告忽略檔案或不忽略檔案的規則,規則對當前目錄及其子目錄生效。
常見規則的寫法:
/mtk/ // 過濾整個資料夾 *.zip // 過濾所有.zip檔案 /mtk/do.c // 過濾某個具體檔案 !index.php // 不過濾具體某個檔案
3.7 將專案推送到Github
1)建立本機金鑰對
# 在gitbash中鍵入如下命令
ssh-keygen -t rsa -C "hgzerowzh"
命令執行成功後會在 ~/.ssh/ 目錄中建立一對金鑰,其中以 .pub結尾是公鑰。
2)在github上建立倉庫後進入設定
- 在操作之前要先建立一個倉庫
3)將程式碼推送到github
# 將本地倉庫和遠端倉庫關聯起來 git remote add origin https://github.com/hgzerowzh/gittest.git # 將程式碼推送到遠端倉庫 git push origin master
- 命令執行完後,會要求輸入使用者名稱和密碼,填寫後login即可
4)推送成功
$ git push origin master Logon failed, use ctrl+c to cancel basic credential prompt. Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 4 threads Compressing objects: 100% (7/7), done. Writing objects: 100% (11/11), 910 bytes | 303.00 KiB/s, done. Total 11 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), done. To https://github.com/hgzerowzh/gittest.git * [new branch] master -> master
4. 搭建Git伺服器
4.1 整體環境
- 服務端:
c7_node_03
10.0.0.203 - 客戶端:
c7_node_04
10.0.0.204 - 軟體安裝:
服務端和客戶端都安裝git
yum install git -y
4.2 服務端建立倉庫
useradd -m git passwd git // 輸入git使用者的密碼 su - git mkdir project.git cd project.git [git@c7_node_03 project.git]$ git init --bare Initialized empty Git repository in /home/git/project.git/ // 如果是 git clone 出來的話,就是其中 .git 的目錄 // 如果是 git clone --bare 的話,新建的目錄本身就是Git目錄
4.3 客戶端從倉庫拉取和提交程式碼
mkdir git cd git/ git clone git@10.0.0.203:/home/git/project.git cd project/ echo "NO.1" > 1.html git config --global user.name "hgzero" // 設定使用者名稱(倉庫名) git config --global user.email "[email protected]" // 設定郵件地址 git add . // 將當前目錄加入暫緩區 git commit -m "NO.1" // 提交到本地倉庫,會輸出很多歡迎資訊,用於協同操作提示作用 git remote add orgin git@10.0.0.203:/home/git/project.git // 確認本地和遠端的狀態是否正常 git push origin master // 本地推送到遠端伺服器 # 然後再更新一個版本 vim 1.html // 新增點內容,做點修改 git add 1.html git commit -m "NO.2" git push
5. Windows下使用Git
一些Git圖形化工具:
- GitHub for Desktop
- Source tree
- TortoiseGit
Windows下安裝Tortoisegit之前,需要安裝msysgit,這樣tortoisegit才能正常運轉
- Tortoisegit
- msysgit
更詳細的Git教程: