Git 是如何工作的
本地建庫
Git 是一個分布式版本控制系統,當你準備使用git 來管理檔案的版本時,首先在你本地需要一個git 庫用來存儲git 的送出記錄,這裡有兩種方式用來建立本地庫
一、使用git init 在本地初始化一個git 庫
初始化一個git 庫
當執行完git init 指令後,git 将會在項目目錄下建立一個隐藏目錄 .git 。這個時候就說明本地的庫已經建立成功,可以正常使用git 提供的各種指令去管理版本。
git 建立這個 .git 目錄是用來做什麼的呢?
.git 是 git 存儲資料的目錄,我們也可以通過直接拷貝.git目錄的方式直接複制出一個git庫。預設情況下 .git 包含了以下檔案:
- HEAD 檔案、(尚待建立的)index 檔案,和 objects 目錄、refs 目錄。 這些條目是 Git 的核心組成部分。
- objects 目錄存儲所有資料内容;
- refs 目錄存儲指向資料(分支)的送出對象的指針;HEAD 檔案訓示目前被檢出的分支;
- index 檔案儲存暫存區資訊。
- description 檔案僅供 GitWeb 程式使用,我們無需關心。
- config 檔案包含項目特有的配置選項。
- info 目錄包含一個全局性排除(global exclude)檔案,用以放置那些不希望被記錄在 .gitignore 檔案中的忽略模式(ignored patterns)。
- hooks 目錄包含用戶端或服務端的鈎子腳本(hook scripts)
在使用git init 指令成功建立本地庫後可能需要關聯到遠端庫
ssh 協定:
git remote add origin [email protected]:serio/gitdemo.git
http/https 協定:
git remote add origin http://172.10.100.188/serio/gitdemo.git
如不想每次push的時候都輸入密碼:
git config --global credential.helper store
二、使用git clone從遠端庫clone 一個到本地庫
Clone 有兩種方式一個是使用http/https 協定、還有一種就是ssh 協定
http/https協定:
ssh協定:
假如你沒有将你的公鑰配置到遠端庫所在的伺服器上将會報以上這個錯誤。
那如何生成公私鑰,如何配置呢?
Windows 上公私鑰可以通過 msysgit 軟體包的 ssh-keygen 生成,這裡會提示公私鑰存放目錄和密碼,截圖中我都是預設目錄和無密碼設定
這裡可以看到公私鑰已經生成到 c/Users/苦參/.ssh 目錄下
然後将 id_rsa.pub 檔案中的内容全文拷貝到伺服器上即可
Gitlab: http://172.10.100.188/profile/keys
Gihub:https://github.com/settings/keys
在你配置好公鑰後就可以順利的使用ssh協定去pulll 遠端的代碼
使用 git 管理版本
一、開始使用git 管理版本前
配置使用人名稱、郵箱
git config --global user.name 名稱
git config --global user.emal 郵箱
這個配置是用來記錄送出人名稱和郵箱,如果加了--blobal 将設定成全局配置,預設為local。除了使用指令行配置之外還可以直接修改配置檔案進行配置。
全局配置檔案位于使用者目錄下,比如我的就是C:\Users\苦參\.gitconfig,本地配置檔案位于項目.git/config
git config --global pull.rebase true
配置拉取遠端分支代碼時候将預設merge改為rebase
git config --global branch.autoSetupRebase always
配置所有分支拉取遠端代碼時候将預設merge改為rebase
為什麼要将 pull 預設的merge 設定成rebase?
當我們在開發的時候在本地develop分支commit 了兩次(C) 和 (D),而這個時候另外一個開發在他的develop分支送出了(E)、(F),同時他push到了遠端的develop,這個時候我們正常情況下向遠端push代碼是不被git允許。我們需要通過pull指令從遠端擷取一次代碼,預設pull 指令由兩個指令組成 git fetch + merge FETCH_HEAD,當我們執行git pull 的時候将發生以下操作
pull 之前
origin/develop
|
+−−−− (E)−−−−(F)
/
(A) −− (B)−−−−−−− (C) −− (D)
|
Develop
預設pull 之後
origin/develop
|
+−−−− (E)−−−−(F)−−−−−−−−−−−−−−−−
/ \
(A) −− (B) −−−−−−−−(C) −− (D)−−−−(G − merge commit)
|
develop
如果是使用pull --rebase的之後
(A) −− (B)−−−−−−− (E) −− (F) −−−−−−− (C') −− (D')
| |
origin/develop develop
如果使用預設的 merge 去遠端pull 代碼,當遠端分支和你本地分支都有在同一個commit後commit過的時候,系統将會自動将這兩個commit 合并到一個變更記錄裡做送出操作
這将導緻我們在後期 git log 的時候發現 會多出來一個commit ,同時 --graph 的時候會發現分支線出現多條影響送出日志的追蹤。
二、常用指令和常見問題
git 指令有兩種一個是高層指令、另外一個是底層指令,這裡隻要講的是常用的高層指令,如果度底層指令感興趣可以去閱讀底層指令
檢視目前狀态
git status
忽略檔案
在.gitignore 檔案中添加需要忽略的檔案即可
驗證忽略格式
git check-ignore */target/*
建立分支
git checkout -b 分支名
git branch 分支名
git checkout -b develop origin/develop
删除分支
删除本地分支
git branch -d 分支名
删除遠端分支
git push o rigin :分支名
合并分支
假如需要将develop分支合并到master分支上
先将HEAD切到master上
git checkout master
通過merge 指令将develop 合并過來
git merge develop
解決沖突
如何解決沖突
當一個檔案在兩個分支同時修改同一個地方時,merge 或者 rebase 将有将會有沖突産生,git 在 merge/rebase 過程中将通過
<<<<<<<=======>>>>>>> 這個三個符号标記出不同版本的修改記錄,這個時候需要手動去解決沖突,删除不需要的版本留下需要的版本
Here are lines that are either unchanged from the common
ancestor, or cleanly resolved because only one side changed.
<<<<<<< yours:sample.txt
Conflict resolution is hard;
let's go shopping.
=======
Git makes conflict resolution easy.
>>>>>>> theirs:sample.txt
And here is another line that is cleanly resolved or unmodified.
如果是merge的時候出現沖突
解決完沖突後
git add .
git merge --continue
如果是rebase的時候出現沖突
git add .
git rebase --continue
沖突的時候如何取消merge 或者 rebase
git merge --abort
git rebase --abort
檢視修改記錄
# 送出記錄
git log
# 本地操作記錄
git reflog
放棄修改
放棄存放到暫存區的修改
git reset HEAD 檔案
放棄工作區的修改
git checkout HEAD 檔案
将工作區修改存放到stash中
git stash
從stash 中取出修改
git stash apply stash@{0}
從stash中取出并删除stash
git stash pop stash@{1}
顯示所有的stash
git stash list
復原代碼
復原本地庫代碼
git reset 版本号 --hard
如果加上如果不加--hard git 将會把放棄的commit還原到工作區
臨時将目前指針指向到指定版本号中
git checkout 版本号
復原遠端版本
當隻有一個commit需要復原的時候可以通過revert復原,revert 指令将會送出一份删除了指定版本commit
比如這裡需要復原D的代碼
(A) −− (B) −−−−−−−−(C) −− (D)
git revert D
(A) −− (B) −−−−−−−−(C) −− (D)−− (D')
這個将會有産生一個新的送出記錄 D' ,而 D' 送出的将是删除 D的修改後的狀态
git revert 版本号
git push
當需要復原很多代碼的時候
同過reset 将本地庫復原到指定版本
git push :develop
推送本地分支到遠端分支
git push origin develop
打标簽
git tag -a标簽名 -m “注釋”
顯示所有标簽
git tag
删除标簽
git tag -d 标簽名
推送到遠端
git push origin 标簽名
删除遠端标簽
Git push origin :标簽名
GIt 分支模型
關于分支模型可以去看我另外一篇文章
推薦閱讀
教程:https://www.liaoxuefeng.com
推薦閱讀:https://git-scm.com/book/zh/v2
git 指令手冊: https://git-scm.com/docs