1. 程式人生 > 其它 >Git分散式版本控制系統

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目錄中。有時會把這個檔案叫做索引檔案,但是標準叫法還是暫存區域。

  1. 在工作目錄中修改某些檔案
  2. 對修改或的檔案進行快照,然後儲存到暫存區域
  3. 提交更新,將保持在暫存區域的檔案快照轉儲到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才能正常運轉

更詳細的Git教程: