1.什麼是git
git就是 分佈式 版本控制 軟件
軟件:git也應該是從別的地方下載下來安裝到我們電腦上的軟件。
版本控制:跟畢業論文一樣,先寫好版本1然後交給導師,導師說不行,然後再改爲版本2,然後循環下去,這就是版本。寫論文的時候我們用的是拷貝文件的方式來做版本控制。
版本控制經歷了4種發展狀態:
1、文件拷貝方式,例如論文
2、爲本地版本控制,對比於1的方式,本地版本控制在本地只會看見一個文件,在這個文件的背後通過這個本地版本控制軟件把以前所有的版本都給你保存起來了。類似於打遊戲的存檔,你是看不見的,而是偷偷的給你存到某個地方去了。以後你想回到某個版本,只需要通過軟件或者某個命令即可回到指定版本。對比1的方式,進步的點有電腦上不會看到那麼多的文件了
3.集中式的版本控制
他會把所有的版本存到集中式的服務器中。集中式的本地是無法保存版本的,只能推到中心上去,缺點就是中心服務器掛掉了就沒辦法了。代表的軟件有:svn
4.分佈式版本控制
優點就是即使中心服務器掛掉了也沒關係,我們自己的電腦上有一份,我就在自己的電腦上用,以後弄了個新的中心服務器,我可以把本地的版本全都推上去。相當於把版本分佈的放在每一臺電腦上都拷貝了一份,即使某一個單點故障了,它都不影響咱們代碼的完整性。
2.git的作用
用於回滾。比如線上功能不行,要刪掉的時候,我們可以快速回滾代碼。
3.git的安裝
git軟件只需要安裝在本地,則可以在本地完成v1,v2,v3的版本控制。如果想在中心也有,就需要在類似github的網站上存儲。
linux,mac,win系統的安裝方式均不同。linux和mac可以通過命令安裝,而win可以下載安裝包進行安裝。
這裏省略。可以去官網查看安裝。
4.git管理文件的邏輯
- 先進入要管理的文件夾
- 初始化這個要管理的文件夾 git init
- 添加要管理的文件 git add .
- 生成版本 git commit -m 'v1'
其實在第四步之前應該有一個配置個人信息的步驟[僅需要在最開始的時候執行一次即可]
- git config --global user.email "[email protected]"
- git config --global user.name "Your name"
如果後續我們修改了要管理的文件夾裏面的文件,我們在生成新的版本
git add .
git commit -m 'v2'
查看全部版本記錄
git log
5.git三大區域
6.git回滾
回滾至之前的版本:
git log 查看版本
git reset --hard 版本號 進行回滾
如果我們還想回到約飯功能需要用到新的命令
回滾至之後的版本
git reflog
git reset --hard 版本號 進行回滾
7.git的分支
分支的作用:分支可以給使用者提供多個環節的可以,意味着你可以把你的工作從開發主線上分離開來,以免影響開發主線。
新建分支會通過指針指向master上的版本
舉個例子,原來項目裏面有100個文件,我們後來修改了10個文件,新增了20個文件。
在git中的體現就是有c1版本變成了c2版本,而c2版本只保留了新增及發生變化的文件,而90個未修改的文件在c2版本里面不會被保存。
那麼如果在c2與c1之間創建聯繫呢?就存在指針這個東西。c2版本是指向c1的,以後我們拿c2的版本,就會在c2中拿對比c1有變化的文件及通過指針再拿c1裏面沒有變化的文件。這也就保證了存儲空間及速度更快。
隨着時間的推移我們又新開發了一個版本c3,c3是在c2的基礎上發生變化,所以c3裏面也會保留自己更改的部分,而沒修改的部門還是通過指針的形式指向了上一個版本即c2。
分支的應用場景:
比如我們現在在開發網站的新功能,但是開發到一半的時候,線上的網站出現了bug,這個時候我們應該把開發一半的功能暫存起來,來修復線上的bug。這就用到了分支來暫存。
主幹線叫master
分支的名字可以隨便定義。
分支相當於創建了一個相互隔離的環境,不影響master,而在分支開發完成後需要合併到master上面的。
查看目前你所處在的分支
git branch
創建新的分支
git branch 分支名
切換分支
git checkout 分支名
注意切換分支是不影響master的。
現在我們在dev分支修改了代碼,可以看下圖的git變化,我們添加並提交分支內容
可以看到下圖,c4版本是dev分支的。
這個時候我們切換到master ,
git checkout master
會發現剛纔在dev分支修改的內容不見了,切換回dev分支修改的代碼又回來了。
按照之前上述講的場景邏輯,我們在dev分支裏面開發了一半,這時候線上代碼有bug,我們要修復bug,我們需要新創建一個分支名爲bug
然後我們修復bug
上圖即爲在bug分支裏面bug已經修復完畢,我們默認master分支是線上代碼。所以我們要把bug分支合併到master裏面。
想要合併分支:
- 第一步:切換回master分支,相當於站在master上把bug分支的代碼拉過來
- 第二步:合併分支,git merge 分支名
- 第三步:如果合併完分支,該分支沒有用了就可以刪除了 git branch -d 分支名
到此線上bug已經修復完畢,我們回到之前開發一半代碼的dev分支繼續開發。
注意:dev分支是由創建dev分支時候的master版本作爲指針的,所以dev分支是沒有剛纔咱們修復線上bug的代碼的。
但是先不用管,我們這個dev分支就是用來開發新功能的,我們繼續開發,現在開發完畢,我們提交。
我們需要合併分支,所以先切回master,進行合併
注意上圖:報了一個錯,叫衝突,此時在代碼裏面會顯示兩個版本的代碼變化,如下圖,因爲git不知道怎麼爲你解決,所以我們只能手動找到這個文件,把衝突解決了。產生衝突的原因是因爲我們的dev和bug分支都來自同一個master版本,而bug在解決完的時候已經合併到了master分支裏面併產生了新的master版本,而後我們在合併bug分支的時候,由於master版本有了變化且在同一行代碼處做了修改則纔會產生衝突,所以才需要手動解決。
解決完了之後我們需要提交新的版本
最後的分支結構圖如下:
8.github
github是代碼託管的網站,是可以和git做無縫銜接的。
git是一個軟件。
除了github網站外還有gitlab網站等
github是網站,gitlab是開源的工具,支持自己的公司搭建一個代碼託管倉庫。
如果想讓github幫你託管,需要做以下幾件事
- 註冊github賬號
- 創建倉庫
- 把本地代碼推送到github的倉庫,如果本地有v1,v2,v3版本,那麼這三個版本都會在github上存儲。如果有分支也會在github上保留分支。
9.基於github做代碼託管
首先在github上創建一個倉庫,建議倉庫名和代碼有關。
勾引 Initialize 則會創建一個readme文件,用來介紹這個項目是幹什麼的
下面的.gitignore則是讓git忽略掉文件夾裏面的文件
license則是許可證,就類似於別人看到你的許可證裏面寫的,你可以拿去學習,但是不能商用的說明。
創建之後github會有一些命令提示/
origin可以代指github的地址。
git push就是把本地的master分支推送到github上。
如果推送dev分支則寫git push -u origin dev
github和本地的git託管的格式是一摸一樣的。
我們現在本地有代碼則可以直接使用
git remote add origin github倉庫的地址
git push -u origin master
注意這裏可能會需要你輸入github的賬號和密碼。
我們還可以推送dev分支到github上
把github上的代碼克隆到本地
git clone github上的倉庫地址
查看分支的時候發現從github上clone下來的沒有dev分支,其實不是的,只是沒有顯示。但是我們可以直接切換分支
緊接着我們在本地編寫代碼,編寫完成需要推送到github
向遠程倉庫推送代碼
git push -u origin 要推送的本地分支名稱
我們換到最前的電腦,繼續開發,就需要先同步github上的代碼,所以
從遠程倉庫拉代碼到本地
git pull origin 遠程倉庫的分支
注意:只有從無到有的才clone,已經存在部分代碼,需要更新本地代碼,則需要用此命令。
接着開發,然後我們需要再推送到github上,
項目開發完了。
github遠程分支的合併,可以在本地的git庫先合併好,然後再推送到github的master分支上。
git checkout master
git merge dev
git push origin master
10.忘記推送代碼,而產生衝突
由於在公司寫了一半的功能,但是沒有推送到github上,
導致回到家中拉去代碼的時候發現公司寫一半功能的代碼沒有了。
所以我們可以在家中寫新的其他功能,寫完我們提交到github上。
第二天我們到公司,第一步應該說是拉在家寫的代碼,但是本地寫一半功能的代碼怎麼辦呢?這裏再拉在家寫的代碼的時候就是合併,合併就會產生衝突。有相同的部分就會衝突,就要手動解決衝突。
下面是代碼模擬實現。
跳過一些在家寫代碼及上傳到github的步驟,直接演示在公司開發的情景。
由上圖可知在pull的時候a1產生了衝突。因爲我們在公司改過a1,在家裏也改過a1,他們改的是同一行就可能產生衝突。
我們手動介入解決衝突。然後可以提交到github。
11.git rebase
rebase的中文叫 變基
主要功能是讓你的代碼提交的git記錄變得簡潔。
應用場景可以分爲三種。
場景一:
假如老闆佈置了一個很大的任務,我們需要五天來開發完,所以我們每天都會提交新版本,這些版本對我們自己是有意義的,但是對於老闆是沒意義的,老闆只要最初始的代碼和第五天開發完成的代碼。所以我們需要rebase,rebase可以把多個提交記錄整合爲一個提交記錄。
下面是代碼還原場景演示
看上圖可知我們現在有4條提交記錄。現在我們想把某些記錄整合爲一條,
方式一:
git rebase -i 版本號
注意:git就會把我們現在所在的地和v2所在的版本的中間這三次記錄做合併
方式二:
git rebase -i HEAD~3
從當前開始找最近的3條記錄,讓這3條記錄進行合併
回車執行,會顯示如下:
我們把v3和v4變成s
其中s就是,讓當前這個s版本合併到他上一個版本去。最後就是 v3和v4都會合併到v2
寫完之後需要保存,
:wq
出現下圖,讓我們填寫合併信息的。
我們可以按照下圖進行填寫,
然後再 :wq
最後就變成下圖所示即爲完成
注意事項:
在做記錄合併的時候,切記,如果某個版本已經push提交到遠程倉庫了的記錄,最好不要把該記錄做rebase合併,儘量合併的是那些沒有提交到版本庫的記錄。因爲如果你搞了之後,接下來在rebase,遠程倉庫有記錄,你本地也有記錄,兩個歷史記錄不一樣就會很麻煩。但是也能做,但是在這裏不建議這樣。
場景二:
gitrebase可以把c3版本的提交記錄歸併搭配master上去。
我們把dev分支合併到master上面。
或者用git log --graph 顯示版本日誌
或者用 git log --graph --pretty=format:"%h %s"來進行簡化
h代表哈希值,s代表提交的一個記錄
先切換到dev分支,然後rebase master
然後切換回master分支,再把dev分支給merge回來就ok了
場景三:
在三里屯寫了v1版本,但是沒有上傳,然後在家裏又開發了v2版本上傳到github了。轉天回到三里屯要從github上下載代碼到本地,就會產生合併,合併就會產生分叉。
不產生分叉就需要這麼做:原來我們從github上下載代碼是用的git pull。現在我們不用git pull,用git fetch命令。
之前咱們說過git pull等於git fetch + git merge
現在我們不用merge了,我們用git rebase
總結:
我們由原來的 git pull origin dev 變成了
git fetch origin dev 然後緊接着執行
git rebase origin/dev
總結:
注意事項:
如果git rebase 的時候,可能會產生衝突,如果產生衝突,彆着急,產生衝突會告訴我們,我們繼續解決衝突。解決完衝突會告訴我們繼續執行 git add...等等的命令,然後再告訴我們要執行git rebase --continue
continue是繼續的意思。
實例:
我們先切換到dev分支。編寫1.py文件
然後切換到master分支也編寫相同的1.py文件
然後我們到dev分支執行git rebase master 就會報錯了。
出現上圖報錯,告訴我們有衝突,現在處於git中斷的狀態。
然後我們手動解決衝突,修改1.py文件。
所以看上圖,我們也rebase完成了。
12、beyond compare軟件快速解決衝突
現在我們先模擬衝突,如下圖
以前我們是找到衝突的文件手動解決,現在我們用beyond compare工具就不用手動解決了。
1.首先安裝beyond compare軟件
2.在git中配置:
git config --local merge.tool bc3
git config --local mergetool.path '/usr/local/bin/bcomp'
git config --local mergetool.keepBackup false
merge就是合併的意思,tool是工具。第一行命令就是合併工具起了個名叫bc3
第二行命令的意思就是這個工具的路徑在哪
第三行名的意思是,讓beyond compare軟件幫我們解決衝突的時候不用保留備份了。就是源文件不用保留了
--local的意思是:只對當前項目有效
3.應用beyond compare解決衝突
git mergetool
執行上面的命令,beyond compare就會自動運行起來。
解決完點保存就行。這樣就不用vim去解決了。直接,明瞭。
9、git常用命令
初始化
讓git幫助我們管理當前文件夾
git init
檢測當前目錄下文件的狀態
即是否被git管理。
git status
把沒有被git管理的文件,讓git把它們管理起來
git add .
生成版本
git commit -m 'v2'
查看版本
git log
以圖形顯示版本
git log --graph
簡化圖形顯示版本
git log --graph --pretty=format:"%h %s"
h代表哈希值,s代表提交的一個記錄
回滾至之前的版本
git log 查看版本
git reset --hard 版本號 進行回滾
回滾至之後的版本
git reflog 查看版本
git reset --hard 版本號 進行回滾
三種狀態的變化
- 紅色:新增的文件/修改了原老文件 -> git add 文件名 或者 .
- 綠色:git已經管理起來了 -> git commit -m '描述信息'
- 生成版本
把已修改文件變成修改之前的狀態,即還原文件
git checkout -- 文件名
把以添加到暫存區的文件回到未添加之前的狀態
git reset HEAD 文件名
查看所處分支
git branch
創建新的分支
git branch 分支名
切換分支
git checkout 分支名
合併分支
注意:需要先切換爲master分支,再執行merge命令
git merge 分支名
刪除分支
git branch -d 分支名
給遠程倉庫起別名
git remote add origin 遠程倉庫地址
這裏的origin是別名。可以叫任何都行。
向遠程倉庫推送代碼
git push -u origin 要推送的本地分支名稱
從遠程倉庫克隆代碼
git clone 遠程倉庫地址
這裏注意,在clone的時候內部其實做了起別名的這件事。默認就叫origin,以後再用直接用這個origin即可,不用再起別名了。
從遠程倉庫拉代碼到本地
git pull origin 遠程倉庫的分支
注意:只有從無到有的才clone,已經存在部分代碼,需要更新本地代碼,則需要用此命令。
上面這一句代碼等同於兩句代碼:
git fetch origin dev 把代碼從遠程倉庫先不拉到本地的工作區,而是先拉到版本庫
git merge origin/dev 把版本庫的代碼更新到本地工作區,注意要寫 origin/分支,因爲會加一個遠程倉庫的前綴
合併git提交記錄
方式一:
git rebase -i 版本號
注意:git就會把我們現在所在的地和v2所在的版本的中間這三次記錄做合併
方式二:
git rebase -i HEAD~3
從當前開始找最近的3條記錄,讓這3條記錄進行合併