1. 初識 Git
1.1 Git 是什么?
Git 是一個開源的分布式版本控制系統,用于高效地跟蹤和管理項目代碼的變更歷史(不僅僅是代碼,還有其它格式也是可以的~)
1.2 為什么要有 Git
在學習或者是工作的時候,比如編寫各種文檔,為了防止文檔丟失,更改失誤,我們不得不復制出一個副本,保留歷史記錄,方便找回歷史記錄,比如:
“設計文檔-v1”
“設計文檔-v2”
“設計文檔-v3”
“設計文檔-確定版”
“設計文檔-最終版”
每個版本有各自的內容,但最終會只有?份文檔是需要被使用的,在此之前的?作都需要這些不同版本的報告,于是每次都是復制粘貼副本,文件就越來越多,不僅文件多,更重要的是,隨著版本數量的不斷增多,我們可能記不太清每一個版本具體修改的哪些內容,文檔如此,我們編寫的項目代碼也如此!
那么,如何解決呢?
答:版本控制器?,記錄每次修改以及版本迭代的一個管理系統,目前,最主流的版本控制器就是 Git,可以控制電腦上所有格式的文件
為了能夠更方便管理這些不同版本的?件,便有了版本控制器! 所謂的版本控制器,就是能讓你了解到?個文件的歷史,以及它的發展過程的系統。通俗的講就是?個可以記錄?程的每?次改動和版本迭代的?個管理系統,同時也方便多人協同作業,目前最主流的版本控制器就是 Git,Git 可以控制電腦上所有格式的文件,例如doc、excel、dwg、dgn、rvt等等,對于我們開發?員來說,Git 最重要的就是可以幫助我們管理軟件開發項目中的源代碼文件!
【注意事項】
所有的版本控制系統,Git也不例外,其實只能跟蹤文本文件的改動,比如 txt文件,網頁,所有的程序代碼等等,版本控制系統可以告訴你每次的改動,比如在第10行加了"name",在第12行刪除了一個"Windows",而圖片、視頻等這些二進制文件,雖然也能由版本控制系統管理,但沒辦法跟蹤文件的變化,只能把?進制文件每次改動串起來,即只知道圖片從90KB改成了100KB,但到底改了啥,版本控制系統無法記錄,所有并不知道,也沒法知道~
2.?安裝 Git
接下來,我們來進行實操!安裝 Git ~
Git 是開放源代碼的代碼托管工具,最早是在?Linux?下開發的,當然,最開始也只能應用于 Linux 平臺,后面慢慢的被移植到 Windows下,現在 Git 可以在 Linux、Unix、Mac 和 Windows 這幾大平臺上正常運行了~
2.1 Linux-Ubuntu?安裝 Git
這里介紹 Ubuntu 下的安裝(因為?Centos?現在不維護了~,因此,本文不作過多介紹)
在 Ubuntu 安裝 git 相當簡單~ 一起來看看!
- 首先查看系統有沒有安裝過 Git,輸入命令:
git --version
- 如果出現 git 版本號已經安裝:
- 如果出現這類提示,則沒安裝
Command 'git' not found, but can be installed with:
sudo apt install git
- 沒有則進行安裝,輸入安裝命令:
sudo apt-get install git -y
(在安裝過程中,出現了圖形化界面,回車即可~)
再次輸入?git --version
,就可以看到 git 版本號啦!此時,安裝完成!(是不是非常簡單!)
2.2 Windows 安裝 Git
Git 官網直接下載:Git 下載官網
- 選擇 Windows 操作系統
- 根據自己的電腦選擇相應的下載
下載完成后,找到下載到的文件,進行雙擊進行安裝
-
接著,按照指示,一步步安裝~
非常簡單的~ 按照指示點下一步就好啦(勇敢牛牛,不怕困難!)
- 檢測是否安裝好 Git,打開 Git Bash
- 檢測是否安裝好 Git,打開 Git Bash
輸入:git -- verison
,出現對應安裝的 git 版本號,就是安裝成功啦!!!
3. Git 初始化與配置
Git 的安裝是很簡單的,現在我們來看看 Git 的初始化與配置~
3.1 創建 Git 本地倉庫
可以將倉庫理解成是進行版本控制的一個文件目錄,如果我們想要對文件進行版本控制,就必須先創建一個倉庫出來!
創建?個 Git 本地倉庫對應的命令為?git init
?,注意命令要在文件目錄下執行,例如:
3.2 配置 Git
當安裝 Git 后首先要做的事情就是設置你的用戶名稱和 e-mail 地址,這是非常非常重要的,配置命令為:
git config [--global] user.name "Your Name"
git config [--global] user.email "email@example.com" # 把 Your Name 改成你的用戶名
# 把 email@example.com 改成你的郵箱的格式,只要格式正確即可
注意?--global
?是?個可選項,如果使用了該選項,就表示這臺機器上所有的 Git 倉庫都會使用這個配置,如果你希望在不同倉庫中使用不同的 name 或 e-mail ,即可以不要?--global
?選項,但需要注意的是,執行命令時必須要在倉庫里面~
查看配置命令為:
git config -l
刪除對應的配置命令為:
git config?[--global]?--unset user.name
git config?[--global]?--unset user.email
4. Git 工作流程 - 認識工作區、暫存區、版本庫
-
工作區:是在電腦上要寫的代碼或者是文件的目錄
-
暫存區(stage/index):一般存放在 .git 目錄下的 index 文件(.git/index)中,把暫存區有時也叫作索引(index)
-
版本庫(repository):也叫倉庫,工作區有?個隱藏目錄 .git ,它不算工作區,而是 Git 的版本庫,這個版本庫里面的所有文件都可以被 Git管理起來,每個文件的修改、刪除,Git 都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以"還原"
- 左側為工作區,右側為版本庫,Git 的版本庫里存放了很多東西,其中最重要的是暫存區
- 在創建版本庫的時候, Git 會自動為我們自動創建一個唯一的 master 的分支,以及指向 master 的一個指針 HEAD (分支與HAED后續介紹)
- 當對工作區修改或者是新增的文件,執行?
git add
?命令,暫存區目錄樹的文件索引會被更新 - 當執行提交操作?
git commit
?時,master 分支會做相應的更新,可以簡單理解為暫存區的目錄樹才會被真正寫到版本庫中
由上述描述我們便能得知:通過新建或粘貼進?錄的?件,并不能稱之為向倉庫中新增?件,?只是在?作區新增了?件。必須要通過使??git add?和?git commit?命令才能將?件添加到倉庫中進?管理!!!
添加文件
在包含 .git 的?錄下新建?個 ReadMe ?件,我們可以使??git add?命令可以將?件添加到暫存
區:
??添加?個或多個?件到暫存區:?git add?[file1] [file2] ...
??添加指定?錄到暫存區,包括??錄:?git add?[dir]
??添加當前?錄下的所有?件改動到暫存區:?git add?.
再使? git commit 命令將暫存區內容添加到本地倉庫中:
? 提交暫存區全部內容到本地倉庫中: git commit -m "message"
? 提交暫存區的指定?件到倉庫區: git commit [file1] [file2] ... -m "message"
注意 :git commit?后?的?-m?選項,要跟上描述本次提交的 message,由????完成,這部分內容絕對不能省略,并要好好描述,是?來記錄你的提交細節,是給我們?看的。
例如:
我們還可以多次 add 不同的?件,?只 commit ?次便可以提交所有?件,是因為需要提交的?件是通通被 add 到暫存區中,然后?次性 commit 暫存區的所有修改.如:
Git 工作流程:
- 工作區:開發者實際編輯代碼的目錄
- 暫存區:通過?
git add
?將修改添加到暫存區,準備提交 - 本地倉庫(Local Repository):通過?
git commit
?將暫存區的修改保存到本地倉庫,生成一個提交記錄(上述介紹的是本地倉庫) - 遠程倉庫(Remote Repository):通過?
git push
?將本地提交推送到遠程倉庫,如Gitee、GitHub(后續介紹如何連遠程倉庫)
截??前為?,我們已經更夠將代碼直接提交?本地倉庫了。我們可以使??git log?命令,來查看
下歷史提交記錄:
該命令顯?從最近到最遠的提交?志,并且可以看到我們 commit 時的?志消息。
如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上?--pretty=oneline?參數:
需要說明的是,我們看到的??串類似 5a250e...2111e0?的是每次提交的?commit id?(版本
號),Git 的?commit id?不是1,2,3……遞增的數字,?是?個 SHA1 計算出來的?個?常?的數字,??六進制表示.
查看.git 文件
先來看看我們的?.git?的?錄結構:
1.index?就是我們的暫存區,add 后的內容都是添加到這?的。
2.HEAD?就是我們的默認指向 master 分?的指針。
?默認的 master 分?,其實就是:
打印的 5a250e9e1895753939dfcf9cba0719ee6d2111e0是什么東西呢?保存的就是當前最新
的?commit id?。
3. objects 為 Git 的對象庫,??包含了創建的各種版本庫對象及內容。當執? git add 命令
時,暫存區的?錄樹被更新,同時?作區修改(或新增)的?件內容被寫?到對象庫中的?個新的
對象中,就位于 ".git/objects" ?錄下,讓我們來看看這些對象有何?處:
查找 object 時要將?commit id?分成2部分,其前2位是?件夾名稱,后38位是?件名稱。
找到這個?件之后,?般不能直接看到??是什么,該類?件是經過?sha?(安全哈希算法)加密過的?件,好在我們可以使? git cat-file?命令來查看版本庫對象的內容:
其中,還有?? tree c9b796e175c00c170f3e2b54ce4e2dd73cf43af9 ,我們使?同樣的?
法,看看結果:
再看 ReadMe 對應的?a0423896973644771497bdc03eb99d5281615b51 :
總結?下,在本地的 git 倉庫中,有?個?件或者?錄很特殊
? index: 暫存區, git add 后會更新該內容。
? HEAD: 默認指向 master 分?的?個指針。
? refs/heads/master: ?件?保存當前 master 分?的最新 commit id 。
? objects: 包含了創建的各種版本庫對象及內容,可以簡單理解為放了 git 維護的所有修改。
修改文件
Git ?其他版本控制系統設計得優秀,因為 Git 跟蹤并管理的是修改,???件。
什么是修改??如你新增了??,這就是?個修改,刪除了??,也是?個修改,更改了某些字符,也是?個修改,刪了?些?加了?些,也是?個修改,甚?創建?個新?件,也算?個修改。
讓我們將 ReadMe ?件進??次修改:
此時,倉庫中的 ReadMe 和我們?作區的 ReadMe 是不同的,如何查看當前倉庫的狀態呢??git
status?命令?于查看在你上次提交之后是否有對?件進?再次修改。
上?的結果告訴我們,ReadMe 被修改過了,但還沒有完成添加與提交。
?前,我們只知道?件被修改了,如果能知道具體哪些地?被修改了,就更好了。有人會說,我剛改的我知道呀!可是,你還記得你三天前寫了什么代碼嗎?或者沒寫?
git diff [file] 命令?來顯?暫存區和?作區?件的差異,顯?的格式正是Unix通?的diff格
式。也可以使? git diff HEAD -- [file] 命令來查看版本庫和?作區?件的區別。
知道了對 ReadMe 做了什么修改后,再把它提交到本地倉庫就放?多了。
git add 之后,就沒有看到上??no changes added to commit (use "git add" and/or "git commit -a") 的消息了。接下來讓我們繼續?git commit?即可:
版本回退
執??git reset?命令?于回退版本,可以指定退回某?次提交的版本。要解釋?下“回退”本質是
要將版本庫中的內容進?回退,?作區或暫存區是否回退由命令參數決定:
git reset?命令語法格式為:?git reset?[--soft?| --mixed?| --hard] [HEAD]
? HEAD 說明:
? 可直接寫成 commit id,表?指定退回的版本
? HEAD 表?當前版本
? HEAD^ 上?個版本
? HEAD^^ 上上?個版本
? 以此類推...
? 可以使? ?數字表?:
? HEAD~0 表?當前版本
? HEAD~1 上?個版本
? HEAD^2 上上?個版本
? 以此類推...
值得說的是,Git 的版本回退速度?常快,因為 Git 在內部有個指向當前分?(此處是master)的
HEAD 指針, refs/heads/master ?件?保存當前 master 分?的最新 commit id 。當我們
在回退版本的時候,Git 僅僅是給 refs/heads/master 中存儲?個特定的version,可以簡單理解
成如下?意圖:
【操作一】提交 version3 后,發現 version3 編寫有誤,想回退到 version2,重新基于 version2 開始寫,這里希望工作區的內容也回退到 version2 版本,因此需要?--hard
?參數,如下:
可以看到 Read 文件的內容,已經回退到 version2 了,使用?git log
?查看提交?志,也發現 HEAD 指向了 version2
【操作二】后悔回退到 version2,想再回到 version3
可以繼續使用 git reset 命令,回退到 version3 版本,but 我們必須要拿到 version3 的 commit id 去指定回退的版本,從上圖中,看到 git log 并不能打印出 version3 的 commit id ,如果運氣好的話,可以在終端找之前的記錄,運氣不好的話,commit id 已經被我們搞丟啦,不過不用擔心!Git 還提供了?個 git reflog 命令,可以補救?下,該命令用來記錄本地的每?次命令!!!
【操作三】在實際開發中,由于長時間開發,導致 commit id 早就找不到了,但是又想回到 version3,貌似現在不可能~
我們要知道 Git 版本回退速度非常快,因為 Git 在內部有個指向當前分支,這里是 HEAD 指針默認指向 master 分支,在.git 隱藏文件中refs/heads/master 文件里面保存了當前 master 分支的最新 commit id,當我們在回退版本的時候, Git 僅僅是給 refs/heads/master 中存儲?個特定的 version,可以簡單理解為下圖:
可以查看 refs/heads/master 文件內容,保存了最新的 commit id,如下:
如果是操作二,回退到 version3 版本,則保存的 commit id 為 version3 的
撤銷修改
情況?:對于?作區的代碼,還沒有?add
萬幸!才寫了一行內容,就發現需要刪除了,萬一寫了很多,一直都沒有提交,可能都忘記自己新增的哪些內容了,那如何刪除呢?
Git 為我們提供了更好的方式!!!
我們可以使??git checkout -- [file]?命令讓?作區的
?件回到最近?次?add?或?commit?時的狀態。 要注意?git checkout -- [file]?命令中的
--?很重要,切記不要省略,?旦省略,該命令就變為其他意思了
情況?:已經?add?,但沒有?commit
add 后還是保存到了暫存區呢?怎么撤銷呢?
讓我們來回憶?下學過的?git reset?回退命令,該命令如果使??--mixed?參數,可以將暫存區
的內容退回為指定的版本內容,但?作區?件保持不變。那我們就可以回退下暫存區的內容了!!
我們可以講版本回退到當前版本庫版本
git reset --mixed HEAD File
git reset? --hard? HEAD File
情況三:已經 add ,并且也 commit 了
不要擔?,我們可以 git reset --hard HEAD^ 回退到上?個版本!不過,這是有條件的,就是
你還沒有把??的本地版本庫推送到遠程。
?刪除本地倉庫中的文件
在 Git 中,刪除也是一個修改操作
下面演示刪除 file4 文件:
使用?rm file4
??
這樣直接刪除是沒有用的,此時只是刪除了工作區的 file4,git status 會告訴你哪些文件被刪除了,但是,這個時候,工作區和版本庫就不一致了,要刪除文件,除了要刪除工作區的文件,還要清除版本庫的文件
到這里,有兩種情況:
【情況一】確實需要從版本庫刪除該文件
使用?git rm [文件名]
,將文件從工作區和暫存區中刪除,并且 commit ~
【情況二】刪錯了
使用?git checkout -- file4
?來恢復, 刪除也是修改哦,這是剛剛學過的命令~
5.Git分支管理
在版本回退?,每次提交,Git都把它們串成?條時間線,這條時間線就可以理解為是?個分?。截?到?前,只有?條時間線,在Git?,這個分?叫主分?,即 master 分?。
再來理解?下HEAD,HEAD 嚴格來說不是指向提交,?是指向master,master才是指向提交的,所以,HEAD 指向的就是當前分?。
每次提交,master分?都會向前移動?步,這樣,隨著你不斷提交,master分?的線也越來越?,?HEAD只要?直指向master分?即可指向當前分?。
通過查看當前的版本庫,我們也能清晰的理出思路:
cat .git/HEAD
---》ref: refs/heads/master
cat .git/refs/heads/master
----》5476bdeb12510f7cd72ac4766db7988925ebd302
創建分支
Git ?持我們查看或創建其他分?,在這?我們來創建第?個??的分??dev?,對應的命令為:
git branch #查看當前本地所有分?
----》* master
git branch dev #新建分?dev
git branch
---》dev
---》* master
當我們創建新的分?后,Git 新建了?個指針叫 dev,?*?表?當前?HEAD?指向的分?是?master?分
?。另外,可以通過?錄結構發現,新的?dev?分?:
ls .git/refs/heads/
---》dev master
cat .git/refs/heads/*
-》5476bdeb12510f7cd72ac4766db7988925ebd302
-》5476bdeb12510f7cd72ac4766db7988925ebd302
發現?前 dev 和 master 指向同?個修改。并且也可以驗證下 HEAD ?前是指向?master?的。
cat .git/HEAD
---》ref: refs/heads/master
切換分支
那如何切換到 dev 分?下進?開發呢?使??git checkout?命令即可完成切換,?例如下:
git checkout dev
-》Switched to branch 'dev'
git branch
-》* dev
-》master
cat .git/HEAD
-》ref: refs/heads/dev
我們發現 HEAD 已經指向了 dev,就表?我們已經成功的切換到了 dev 上!
接下來,在?dev?分?下修改 ReadMe ?件,新增??內容,并進??次提交操作:
vim ReadMecat ReadMe
-》hello bit
-》write aaa for new branchgit add .git commit -m"modify ReadMe"
-》[dev 3740dce] modify ReadMe
-》1 file changed, 1 insertion(+)
現在,dev 分?的?作完成,我們就可以切換回 master 分?:
git checkout master
-》Switched to branch 'master'
cat ReadMe
-》hello bit
切換回 master 分?后,發現ReadMe?件中新增的內容不?了!!
但是在 dev 分?上,內容還在。為什么會出現這個現象呢?我們來看看 dev 分?和 master 分?指向,發現兩者指向的提交是不?樣的:
因為我們是在dev分?上提交的,?master分?此刻的提交點并沒有變,此時的狀態如圖如下所示:
當切換到 master 分?之時,HEAD 就指向了 master,當然看不到提交了!?
合并分支
為了在 master 主分?上能看到新的提交,就需要將?dev?分?合并到?master?分?,?例如下:
git branch
-》* dev
-》mastergit checkout master # 切換到 master 上進?合并
-》Switched to branch 'master'
git merge dev # 合并 dev 分?
-》Updating 16623e1..3740dce
-》Fast-forward
-》ReadMe | 1 +
-》1 file changed, 1 insertion(+)
cat ReadMe
-》hello bit
-》write aaa for new branch
git merge?命令?于合并指定分?到當前分?。合并后,master 就能看到 dev 分?提交的內容
了。此時的狀態如圖如下所?。
Fast-forward 代表“快進模式”,也就是直接把master指向dev的當前提交,所以合并速度?常快。
當然,也不是每次合并都能 Fast-forward。
刪除分支
合并完成后, dev 分?對于我們來說就沒?了, 那么dev分?就可以被刪除掉,注意如果當前正處于某分?下,就不能刪除當前分?,如:
git branch
-》* dev
-》master
git branch -d dev
-》error: Cannot delete branch 'dev' checked out at '/home/hyb/gitcode'
?可以在其他分?下刪除當前分?,如
git checkout master
Switched to branch 'master'
git branch -d dev
Deleted branch dev (was bdaf528).
因為創建、合并和刪除分??常快,所以Git?勵你使?分?完成某個任務,合并后再刪掉分?,這和直接在master分?上?作效果是?樣的,但過程更安全.
合并沖突
可是,在實際分?合并的時候,并不是想合并就能合并成功的,有時候可能會遇到代碼沖突的問題。為了演?這問題,創建?個新的分? dev1 ,并切換??標分?,我們可以使? git checkout -
b dev1 ?步完成創建并切換的動作,?例如下
git checkout -b dev1
Switched to a new branch 'dev1'git branch
* dev1
master
在?dev1?分?下修改?ReadMe??件,更改?件內容如下,并進??次提交,如:
cat ReadMe
hello bit
write bbb for new branch # 將 aaa 該為 bbbgit add .git commit -m"modify ReadMe"
[dev1 0854245] modify ReadMe
1 file changed, 1 insertion(+), 1 deletion(-)
切換??master?分?,觀察?ReadMe??件內容:
git checkout master
Switched to branch 'master'
?cat ReadMe
hello bit
write?aaa?for new branch
我們發現,切回來之后,?件內容由變成了?的版本,這種現象很正常,我們現在也完全能理解。
此時在 master 分?上,我們對 ReadMe ?件再進??次修改,并進?提交,如下:
[wmh@hcss-ecs-1036 gitcode]$ git branch
dev1
* master
[wmh@hcss-ecs-1036 gitcode]$ vim ReadMe
[wmh@hcss-ecs-1036 gitcode]$ cat ReadMe
hello bit
write ccc for new branch
[wmh@hcss-ecs-1036 gitcode]$ git add .
[wmh@hcss-ecs-1036 gitcode]$ git commit -m"modify ReadMe"
[master c10f6d0] modify ReadMe
1 file changed, 1 insertion(+), 1 deletion(-)
現在,?master?分?和?dev1?分?各?都分別有新的提交,變成了這樣:
這種情況下,Git 只能試圖把各?的修改合并起來,但這種合并就可能會有沖突,如下所?:
[wmh@hcss-ecs-1036 gitcode]$ git merge dev1
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
[wmh@hcss-ecs-1036 gitcode]$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")
發現 ReadMe ?件有沖突后,可以直接查看?件內容,要說的是 Git 會? <<<<<<<,=======,
>>>>>>> 來標記出不同分?的沖突內容,如下所?:
此時我們必須要?動調整沖突代碼,并需要再次提交修正后的結果!!(再次提交很重要,切勿忘
記)
到這?沖突就解決完成,此時的狀態變成了:
分支管理策略
通常合并分?時,如果可能,Git 會采??Fast forward?模式。還記得如果我們采??Fast
forward?模式之后,形成的合并結果是什么呢?
在這種?Fast forward?模式下,刪除分?后,查看分?歷史時,會丟掉分?信息,看不出來最新提
交到底是 merge 進來的還是正常提交的。
但在合并沖突部分,我們也看到通過解決沖突問題,會再進??次新的提交,得到的最終狀態為:
那么這就不是?Fast forward?模式了,這樣的好處是,從分?歷史上就可以看出分?信息。例如我
們現在已經刪除了在合并沖突部分創建的?dev1?分?,但依舊能看到 master 其實是由其他分?合并得到
Git ?持我們強制禁??Fast forward?模式,那么就會在 merge 時?成?個新的?commit?,這樣,
從分?歷史上就可以看出分?信息
git merge --no-ff -m "msg" branch_name
bug分支
假如我們現在正在 dev2 分?上進?開發,開發到?半,突然發現 master 分?上?有 bug,需要
解決。在Git中,每個 bug 都可以通過?個新的臨時分?來修復,修復后,合并分?,然后將臨時分?刪除。
可現在 dev2 的代碼在?作區中開發了?半,還?法提交,怎么辦?
Git 提供了?git stash?命令,可以將當前的?作區信息進?儲藏,被儲藏的內容可以在將來某個時
間恢復出來。
[wmh@hcss-ecs-1036 gitcode]$ git stash
Saved working directory and index state WIP on dev2: 41b082f modify ReadMe
[wmh@hcss-ecs-1036 gitcode]$ git status
On branch dev2
nothing to commit, working tree clean
? git status 查看?作區,就是?凈的(除?有沒有被 Git 管理的?件),因此可以放?地創建分
?來修復bug。
儲藏 dev2 ?作區之后,由于我們要基于master分?修復 bug,所以需要切回 master 分?,再新
建臨時分?來修復 bug,?例如下:
[wmh@hcss-ecs-1036 gitcode]$ git checkout master # 切回master
Switched to branch 'master'
[wmh@hcss-ecs-1036 gitcode]$ git checkout -b fix_bug # 新建并切換到 fix_bug 分?
Switched to a new branch 'fix_bug'
[wmh@hcss-ecs-1036 gitcode]$ vim ReadMe
[wmh@hcss-ecs-1036 gitcode]$ cat ReadMe
hello bit
write bbb for new branch
a,b,c,d,e # 修復bug--忘記寫e
[wmh@hcss-ecs-1036 gitcode]$ git add ReadMe # 重新add,commit
[wmh@hcss-ecs-1036 gitcode]$ git commit -m"fix bug"
[fix_bug 4bbc0c4] fix bug
1 file changed, 1 insertion(+), 1 deletion(-)
修復完成后,切換到?master?分?,并完成合并,最后刪除?fix_bug?分?。
?此,bug 的修復?作已經做完了,我們還要繼續回到?dev2?分?進?開發。切換回?dev2?分?
[wmh@hcss-ecs-1036 gitcode]$ git checkout dev2
Switched to branch 'dev2'
[wmh@hcss-ecs-1036 gitcode]$ git status
On branch dev2
nothing to commit, working tree clean
?作區是?凈的,剛才的?作現場存到哪去了???git stash list?命令看看
[wmh@hcss-ecs-1036 gitcode]$ git stash list
stash@{0}: WIP on dev2: 41b082f modify ReadMe
?作現場還在,Git 把 stash 內容存在某個地?了,但是需要恢復?下,如何恢復現場呢?我們可以使? git stash pop?命令,恢復的同時會把 stash 也刪了,?例如下:
[wmh@hcss-ecs-1036 gitcode]$ git stash pop
On branch dev2
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (4f873250b3503687b5efd26196776aee7e3724c2)
再次查看的時候,我們已經發現已經沒有現場可以恢復了。
但我們注意到了,修復 bug 的內容,并沒有在?dev2?上顯?。此時的狀態圖為:
Master 分??前最新的提交,是要領先于新建 dev2 時基于的 master 分?的提交的,所以我們
在 dev2 中當然看不?修復 bug 的相關代碼。
我們的最終?的是要讓 master 合并 dev2 分?的,那么正常情況下我們切回 master 分?直接合
并即可,但這樣其實是有?定?險的。
是因為在合并分?時可能會有沖突,?代碼沖突需要我們?動解決(在 master 上解決)。我們?法保證對于沖突問題可以正確地?次性解決掉,因為在實際的項?中,代碼沖突不只?兩?那么簡單,有可能??上百?,甚?更多,解決的過程中難免?誤出錯,導致錯誤的代碼被合并到 master 上。 此時的狀態為:
解決這個問題的?個好的建議就是:最好在??的分?上合并下?master?,再讓?master?去合并
dev?,這樣做的?的是有沖突可以在本地分?解決并進?測試,?不影響?master?。此時的狀態
為:.
6.Git遠程操作
下面演示在gitee上創建遠程倉庫
創建遠程倉庫
上面的.gitignore是為了在上傳時過濾掉不重要的文件,分支模型選單分支模型就夠用了,或者選生產/開發模型。
當然,如果創建倉庫的時候沒有添加.gitignore文件,可以在本地倉庫創建.gitignore文件
將遠程倉庫克隆到本地
下面僅介紹兩種方式:HTTPS,SSH
SSH
然后查看是否有 id_rsa 和 id_rsa.pub這兩個文件
如果沒有的話,需要創建ssh.key
ssh-keygen -t rsa -C "your_email@example.com"
注意:上面的郵箱要和gitee上綁定的郵箱一致
如果有的話,打開看一下
將上面的內容全部復制下來,然后再打開gitee的設置
配置SSH公鑰
三板斧
git?add
git commit -m "XXX"
git push
當我們從遠程倉庫克隆后,實際上 Git 會?動把本地的 master 分?和遠程的 master 分?對應起來,并且,遠程倉庫的默認名稱是?origin?。在本地我們可以使??git remote?命令,來查看遠程庫的
信息,如:
git remote
或者,??git remote -v?顯?更詳細的信息:
git remote -v? origin
提交時要注意,如果我們之前設置過全局的 name 和 e-mail,這兩項配置需要和 gitee 上配置的用戶名和郵箱?致,否則會出錯。或者從來沒有設置過全局的 name 和 e-mail,那么我們第?次提交時也 會報錯。這就需要我們重新配置下了,同樣要注意需要和 gitee 上配置的??名和郵箱?致。如何配置 已講過,在這?就不再贅述。
到這?我們已經將內容提交?本地倉庫中,如何將本地倉庫的內容推送?遠程倉庫呢,需要使??git? push 命令,該命令?于將本地的分?版本上傳到遠程并合并,命令格式如下:
拉取遠程倉庫內容
給命令配置起別名
在我們使? Git 期間,有些命令敲的時候著實讓?頭疼(太?了。。),幸運的是,git?持對命令進?簡化!
舉個例?,將?git status?簡化為?git st?,對應的命令為:
git config --global alias .st status
--global?參數是全局參數,也就是這些命令在這臺電腦的所有Git倉庫下都有?。如果不加,那只
針對當前的倉庫起作?。
標簽管理
標簽 tag ,可以簡單的理解為是對某次 commit 的?個標識,相當于起了?個別名。例如,在項?
發布某個版本的時候,針對最后?次 commit 起?個 v1.0 這樣的標簽來標識?程碑的意義。
這有什么?呢?相較于難以記住的 commit id , tag 很好的解決這個問題,因為 tag ?定要給?
個讓?容易記住,且有意義的名字。當我們需要回退到某個重要版本時,直接使?標簽就能很快定位到。
創建標簽
在Git中打標簽?常簡單,?先,切換到需要打標簽的分?上
然后,敲命令 git tag [name] 就可以打?個新標簽
可以?命令 git tag 查看所有標簽
可以? git show [tagname] 查看標簽信息。
當然,并非只能給最新的提交打標簽,使用如下命令查看commit id,然后在git tag [版本] [commit id]
Git 還提供可以創建帶有說明的標簽,?-a指定標簽名,-m指定說明?字,格式為:
git tag -a [name] -m "XXX" [commit_id]
刪除標簽
因為創建的標簽都只存儲在本地,不會?動推送到遠程。所以,打錯的標簽可以在本地安全刪除。
推送標簽
如果要推送某個標簽到遠程,使?命令
git push origin <tagname>
當然,如果你本地有很多標簽,也可以?次性的全部推送到遠端:
git push origin --tags
本地刪除遠程標簽
git push origin --delete <標簽名>
7.多人協作一
目標:遠程?master?分支下 file.txt 文件新增代碼 “aaa”,“bbb”
實現:由開發者1新增aaa,開發者2新增bbb
條件:在一個分支下協作完成
我們創建一個分支 dev,在分支 dev 上完成這些操作
git branch
?查看本地分支,只有一個 master ;git branch -r
?查看遠程分支,我們可以看到遠程里面也只有 master,沒有新創建的 dev
將 dev 分支從遠程拉取下來
在?windows?上面模擬開發者2,首先需要將倉庫克隆到 windows 下,隨便選取一個目錄,shift + 右鍵
此時我們準備工作完成,接下來我們讓開發者1新增 aaa,開發者2新增 bbb
我們可以分別用Linux機器和Windows機器來模擬開發者1和開發者2,依舊是采用我們上面已經創建的倉庫?remote-gitcode
。
1. 開發者1 創建一個分支dev
開發者1 創建一個分支?dev
,然后開發者1和開發者2都同時在這個分支上進行操作。
👉 你在哪個分支上工作,就從那個分支 push 自己:
2. 開發者2 拉取遠程倉庫
打開 bash 進行 clone 遠程倉庫:
當 clone 的時候,本地倉庫就只有?master
?分支,那么就要獲取?dev
?分支。如果本地還沒有?dev
,Git 會自動從遠程的?origin/dev
?創建一個對應的本地分支,并自動追蹤它。
git checkout -b dev origin/dev
將本地?dev
?分支和遠程的?dev
?分支進行建立鏈接,開發者2的本地也具有?dev
?分支了。
3. 開發者1 對遠程倉庫進行推送
切換到開發者2中,可以看到正常的進行對?file.txt
?文件進行修改,可是 push 的時候卻發生錯誤,提示當前的本地與遠程倉庫有區別!
我們應該先進行 pull 來更新本地倉庫!
git pull origin dev
再次 push 又會發現失敗,出現合并沖突問題,需要手動進行解決!!!
解決完沖突后,這里要特別注意,要重新進行?add .
?和?commit -m
?來重新進行推送,再次進行 push 就可以上傳成功,開發者2 新添加的?bbb
?內容成功推送。
此時可以在遠程的?dev
?分支上看到我們想要得到的結果:file.txt
?文件內有開發者1添加的“aaa”,有開發者2添加的?bbb
。
接下來就可以用?master
?來合并?dev
?分支!!!
可以看到?master
?分支上沒有這兩行代碼!
4. 將內容合并至 master
4.1 提交 Pull?Request
開發者1 和開發者2 在遠程倉庫創建一個 Pull Request,提交合并請求。
4.2 本地操作:
- 在?
dev
?分支和?master
?分支上,執行如下命令:
git checkout master
git merge dev
git push origin master
由于在?master
?上進行?merge?dev
,可能會導致沖突,因此應該在本地的?dev
?上進行 merge?master
。這樣就算有沖突,也可以在本地解決。解決完沖突后,再用?master
?來 merge?dev
,就不會有問題。
步驟如下:
這樣就可以看到?master
?分支上的?file.txt
?被同步更新了。
完成后,可以同時讓開發者1和開發者2對?dev
?分支進行刪除。
8.多人協作二
1. 本地創建分支
要保證本地的?master
?是最新的,先?pull
?操作,然后再次創建?dev
?分支。
開發者1 操作
開發者2 操作
可以看到每次開發都是自己創建的分支,然后進行 push,每次都能成功,不會遇到沖突的問題。因為我們是在最新的?master
?上創建的分支,然后自己創建的分支只有自己開發的時候能夠用上,所以不會出現 push 沖突的問題。
2. 拉取遠程的 feature-2 分支
突然,開發者2生病了,開發者1需要擔起開發?feature-2
?分支的重任!這時需要從遠程拉取?feature-2
?分支進行開發。此時,我們又回到了多人開發一中的情形,開發者1和開發者2在同一個分支開發。
拉取遠程分支內容
使用如下命令拉取遠程?feature-2
?分支的內容:
git pull origin feature-2
拉取到遠程的?origin/feature-2
?分支后,本地沒有這個分支,所以需要創建并切換至?feature-2
?分支。
git checkout -b feature-2 origin/feature-2
此時,開發者1就能夠在?feature-2
?分支上繼續開發
3. 合并 feature-1 和 feature-2 至 master
現在就是又遇到了合并feature-1的問題,為了避免沖突 我們就還是再feature-1分支上來合并master
每次feature-1合并master之前 就要先保證master是最新的,所以要切換到master進行pull再用master進行合并merge
當我們merge master的時候跳轉到當前頁面就說明沒用任何問題,沒用產生沖突,ctrl + x 就會退出該頁面!
?最后,開發者1和開發者2將各自的?feature-1
?和?feature-2
?分支合并到?master
?分支上。
4. 刪除遠程分支
刪除遠程分支后,本地仍然可以看到已刪除的遠程分支。此時,可以使用以下命令移除遠程已刪除的分支記錄:
git remote prune origin
以上就是Git企業常用的內容了,需要我們勤加聯系!!!!