版本控制

說到版本控制,腦海裡總會浮現大學畢業是寫畢業論文的場景,你電腦上的畢業論文一定出現過這番景象!

畢業論文_初稿.doc
畢業論文_修改1.doc
畢業論文_修改2.doc
畢業論文_修改3.doc
畢業論文_完整版1.doc
畢業論文_完整版2.doc
畢業論文_完整版3.doc
畢業論文_最終版1.doc
畢業論文_最終版2.doc
畢業論文_死也不改版.doc
...

以上就是使用最原始的方式進行版本控制,但是這種方式有顯著缺點:

  • 多個檔案,保留所有版本時,需要為每個版本儲存一個檔案...
  • 協同操作,多人協同操作時,需要將檔案打包發來發去...
  • 容易丟失,被刪除意味著永遠失去...(可以選擇網盤)

為了解決以上版本控制存在問題,應運而生了一批版本控制工具:VSS、CVS、SVN、Git等,其中Git屬於絕對霸主地位。

注意:一般版本控制工具包含兩部分

  • 客戶端(本地):本地編寫內容以及版本記錄
  • 服務端(網盤):將內容和版本記錄同時儲存在遠端(可有可無)

GIT介紹

Git 是一個開源的分散式版本控制軟體,用以有效、高速的處理從很小到非常大的專案版本管理。 Git 最初是由Linus Torvalds設計開發的,用於管理Linux核心開發。Git 是根據GNU通用公共許可證版本2的條款分發的自由/免費軟體,安裝參見:http://git-scm.com/

GitHub是一個基於Git的遠端檔案託管平臺(同GitCafe、BitBucket和GitLab等)。

Git本身完全可以做到版本控制,但其所有內容以及版本記錄只能儲存在本機,如果想要將檔案內容以及版本記錄同時儲存在遠端,則需要結合GitHub來使用。使用場景:

  • 無GitHub:在本地 .git 資料夾內維護歷時檔案
  • 有GitHub:在本地 .git 資料夾內維護歷時檔案,同時也將歷時檔案託管在遠端倉庫

其他:

集中式:遠端伺服器儲存所有版本,使用者客戶端有某個版本
    分散式:遠端伺服器儲存所有版本,使用者客戶端有所有版本

Git使用之小P創業史:初創期

小P是一個年輕有為程式設計師,從小立志要幹出一番大事,某個深夜小P在網上查詢**老師主演的學習視訊,花了1個小時才找到想要的資源,小P想到和自己一樣的有為青年每天花費大量的時間尋找喜歡老師的作品,感覺自己幹大事的機會來了,毅然決然選擇創業,建立一個**平臺,提供**老師的所有資源!!!

創業初期,小P獨自封閉開發一個月,第一個版本終於上線:

回顧開發過程,其中辛酸只有小P自己知道。上線完成後的某一天,小P猛然看到自己開發目錄,臥槽這拓麻也太亂了,加入那天程式出問題回滾到上個版本的時候,自己都找不到確定版本,並且我老子做的這個系統日後是要成千上萬人來維護開發,這種通過原始檔案來儲存版本的形式簡直Low到爆啊。

開始調研:小P發現了版本控制神奇Git,但是都是道聽途說,到底牛逼成什麼樣子也不清楚,所以抱著試試看的態度,小P開始使用Git進行版本控制。

MacBook-Pro-4:pondo wupeiqi$ pwd                   # 進入程式目錄
/Users/wupeiqi/PycharmProjects/pondo
MacBook-Pro-4:pondo wupeiqi$ git init # git初始化
Initialized empty Git repository in /Users/wupeiqi/PycharmProjects/pondo/.git/

初始化後,會在當前目錄自動建立 .git 資料夾,該檔案是Git中最重要的資料夾,因為Git相關檔案以及版本都將儲存在該資料夾中,有了它,媽媽再也不用擔心我好多檔案來記錄版本了,通過Git命令可以將所有版本儲存在 .git 檔案中,兩條命令建立一個版本:

MacBook-Pro-4:pondo wupeiqi$ git status                     # 檢視當前git狀態
On branch master Initial commit Untracked files:
(use "git add <file>..." to include in what will be committed) .idea/
app01/
db.sqlite3
manage.py
pondo/
readme
templates/ nothing added to commit but untracked files present (use "git add" to track)
MacBook-Pro-4:pondo wupeiqi$ git add . # 添加當前目錄下所有檔案到版本庫
MacBook-Pro-4:pondo wupeiqi$ git commit -m '第一次提交' # 提交到版本庫,並填寫版本說明,以便以後回滾。
[master (root-commit) df47fe4] 第一次提交
33 files changed, 879 insertions(+)
create mode 100644 .idea/dictionaries/wupeiqi.xml
create mode 100644 .idea/encodings.xml
create mode 100644 .idea/inspectionProfiles/profiles_settings.xml
...

注意:執行git commit 命令時,可能會提示進行使用者和郵箱的配置,該配置用於記錄當前版本由那個使用者提交

  • git config --local user.name '武沛齊'
  • git config --local user.email '[email protected]'

Git把管理的檔案分為了兩個區域四個狀態。

工作區:當前開發程式所在目錄稱為工作區,即:工作開發都是在該目錄,該區域的檔案會有狀態的變化且狀態由git自動檢測,如果程式中檔案做任何操作(增、刪、改),檔案狀態均會被檢測到,可以使用 【git status】命令檢視。

MacBook-Pro-:pondo wupeiqi$ ls                # 檢視原程式目錄
app01 db.sqlite3 manage.py pondo readme static templates
MacBook-Pro-:pondo wupeiqi$ git status # 檢視git當前狀態
On branch master
nothing to commit, working tree clean
MacBook-Pro-:pondo wupeiqi$ touch a.py # 建立新檔案
MacBook-Pro-:pondo wupeiqi$ ls
a.py app01 db.sqlite3 manage.py pondo readme static templates
MacBook-Pro-:pondo wupeiqi$ git status # 檢視git當前狀態,檢測到:工作區 a.py 發生變化
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed) a.py nothing added to commit but untracked files present (use "git add" to track)

版本庫:工作區檢測到有檔案發生變化,那麼意味著較上一個版本之後對程式進行了修改,修改完成之後,可以當做下一版本進行提交,那麼就是執行 【git add .】 將所有檔案提交到暫存區,然後再執行【git commit -m '又一個版本'】提交到版本庫的分支即可,之後可以使用【git log】命令檢視版本記錄。

MacBook-Pro-:pondo wupeiqi$ ls
a.py app01 db.sqlite3 manage.py pondo readme static templates MacBook-Pro-:pondo wupeiqi$ git status # 檔案顏色為紅色,表示在工作區的被修改狀態
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed) a.py
nothing added to commit but untracked files present (use "git add" to track) MacBook-Pro-:pondo wupeiqi$ git add . # 將所有相較上一次版本之後所有的修改新增到暫存狀態 MacBook-Pro-:pondo wupeiqi$ git status # 檔案顏色為綠色,表示在版本庫的暫存狀態
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage) new file: a.py MacBook-Pro-:pondo wupeiqi$ git commit -m '又一次提交' # 提交到版本庫的分支
[master f139d5d] 又一次提交
file changed, insertions(+), deletions(-)
create mode a.py MacBook-Pro-:pondo wupeiqi$ git log # 檢視歷史版本提交記錄(根據版本commit值可以進行回滾)
commit f139d5d0a648af06d8a1ecadd90faf572afc388a
Author: 武沛齊 <[email protected]>
Date: Fri Aug :: + 又一次提交 commit df47fe49fc1f14d9cdd1534baa96f46ec71a9934
Author: 武沛齊 <[email protected]>
Date: Fri Aug :: + 第一次提交

目前已使用Git的四個命令,這四個命令已經可以代替本地多個檔案儲存版本的方式:

  • git init,初始化,表示即將對當前資料夾進行版本控制。
  • git status,檢視Git當前狀態,如:那些檔案被修改過、那些檔案還未提交到版本庫等。
  • git add 檔名,將指定檔案新增到版本庫的暫存狀態。
  • git commit -m '提交資訊',將暫存區的檔案提交到版本庫的分支。
  • git log,檢視提交記錄,即:歷史版本記錄

調研完,小P好氣自己喲,這麼6的東西為什麼沒有早發現,從此小P的版本管理就告別繁雜的檔案夾了,趕緊搞起來。

MacBook-Pro-4:pondo wupeiqi$ ls
app01 db.sqlite3 manage.py pondo static templates MacBook-Pro-4:pondo wupeiqi$ git init
Initialized empty Git repository in /Users/wupeiqi/PycharmProjects/pondo/.git/ MacBook-Pro-4:pondo wupeiqi$ git config --local user.name '武沛齊' MacBook-Pro-4:pondo wupeiqi$ git config --local user.email '[email protected]' MacBook-Pro-4:pondo wupeiqi$ git add . MacBook-Pro-4:pondo wupeiqi$ git commit -m '專案首次移植到Git控制版本' [master (root-commit) 6c439d2] 專案首次移植到Git控制版本
32 files changed, 870 insertions(+)
create mode 100644 .idea/dictionaries/wupeiqi.xml
create mode 100644 .idea/encodings.xml
...

恰好,此時需要開發一個非洲專區的功能,再也不用重新copy一遍檔案了,在工作區直接開始搞起來,30分鐘開發測試完成,又一個版本完成了咯!!!

MacBook-Pro-4:pondo wupeiqi$ git status            # 非洲專區功能的開發,僅對app01/views.py進行了修改
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: app01/views.py no changes added to commit (use "git add" and/or "git commit -a") MacBook-Pro-4:pondo wupeiqi$ git add . MacBook-Pro-4:pondo wupeiqi$ git commit -m '非洲專區上線'
[master 0972f4b] 非洲專區上線
1 file changed, 3 insertions(+), 1 deletion(-)
MacBook-Pro-4:pondo wupeiqi$

非洲專區上線一個月後,接連收到使用者投訴,原來清新脫俗的小P那裡去了?怎麼變得如此重口味?想回到過去....

小P向來秉承為人民服務的原則,人民不想看那一定要修改。決定:回滾,回到上一個版本。

那麼問題來了?

一個月過去了,程式碼修改的位置早就忘記了,怎麼修改,總不能再開發一遍吧。機智的小P猜想Git既然這麼牛逼,應該會提供這樣的功能,經過一番查詢,果不其然Git提供了這個回滾的功能。

回滾到指定版本:

MacBook-Pro-4:pondo wupeiqi$ git log
commit 0972f4bb43104baee15aeec2dd62bd0a307ec837
Author: 武沛齊 <[email protected]>
Date: Fri Aug 11 10:54:42 2017 +0800 非洲專區上線 commit 6c439d2fd0d943f36f3ee84e158ff86b052961d2
Author: 武沛齊 <[email protected]>
Date: Fri Aug 11 10:42:09 2017 +0800 專案首次移植到Git控制版本 MacBook-Pro-4:pondo wupeiqi$ git reset --hard 6c439d2fd0d943f36f3ee84e158ff86b052961d2
HEAD is now at 6c439d2 專案首次移植到Git控制版本 # 命令執行完,工作區的所有檔案就變成未開發非洲專區功能之前了,太爽了有麼有....

回滾倒是完成了,小P在想如果某一天想要在回有非洲專區功能的版本怎麼辦呢?來來來,不能像以往通過【git log】來檢視記錄再回滾了,再回去需要這麼搞:

MacBook-Pro-4:pondo wupeiqi$ git reflog
6c439d2 HEAD@{2}: reset: moving to 6c439d2fd0d943f36f3ee84e158ff86b052961d2
0972f4b HEAD@{3}: commit: 非洲專區上線
6c439d2 HEAD@{4}: commit (initial): 專案首次移植到Git控制版本 MacBook-Pro-4:pondo wupeiqi$ git reset --hard 0972f4b
HEAD is now at 0972f4b 非洲專區上線

Git使用之小P創業史:成長期

企業想要不被淘汰,就要跟緊時代步伐,近日直播行業日趨火熱,小P的也希望自己的平臺加入直播功能,已經評估預計2個月開發完成,小P開始沒日沒夜的幹了起來...

一個月過去了,開發任務和按照預期有條不紊的進行著,直播功能也已完成一半,就是在此時線上執行平臺出現Bug需要緊急修復,怎麼辦?怎麼辦??怎麼辦???

小P出了幾個解決方案:

  • 正在開發程式碼不動,拷貝一份線上執行的程式碼進行修改         ------> 不行,又踏馬回去拷貝去了。
  • 把開發了一個月的程式碼刪掉,修改Bug,然後再重頭開始      ------> 不行,一定是傻逼才這麼幹,我不是傻逼。
  • 聽說git的stash可以                                                       ------> 聽說過,沒見過
  • 聽說git的branch可以                                                     ------> 聽說過,沒見過

方案一:stash

stash用於將工作區發生變化的所有檔案獲取臨時儲存在“某個地方”,將工作區還原當前版本未操作前的狀態;stash還可以將臨時儲存在“某個地方”的檔案再次拿回到工作區。

acBook-Pro-4:pondo wupeiqi$ vim app01/views.py             # 開發直播功能,剛開發到一半

MacBook-Pro-4:pondo wupeiqi$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: app01/views.py no changes added to commit (use "git add" and/or "git commit -a") MacBook-Pro-4:pondo wupeiqi$ git stash # 將開發到一半的直播功能,臨時儲存到“某個地方”
Saved working directory and index state WIP on master: 0972f4b 非洲專區上線
HEAD is now at 0972f4b 非洲專區上線 MacBook-Pro-4:pondo wupeiqi$ git status # 工作區回到當前版本未做任何操作前
On branch master
nothing to commit, working tree clean MacBook-Pro-4:pondo wupeiqi$ vim pondo/settings.py # 緊急修復bug
MacBook-Pro-4:pondo wupeiqi$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: pondo/settings.py
no changes added to commit (use "git add" and/or "git commit -a") MacBook-Pro-4:pondo wupeiqi$ git add . # 新增到修改bug的程式碼到暫存狀態
MacBook-Pro-4:pondo wupeiqi$ git commit -m '緊急修復bug' # 提交修復Bug的程式碼到分支
[master 1300d33] 緊急修復bug
1 file changed, 1 insertion(+) MacBook-Pro-4:pondo wupeiqi$ git stash pop # 將開發到一半的直播功能從“某個地方”再次拿會工作區繼續開發
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: app01/views.py no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (059d78ca8fa204f9559bd3ce0ae76235969b4301)

特別的:執行 git stash pop 命令時,可能會遇到衝突,因為在緊急修復bug的程式碼和通過stash儲存在“某個地方”的程式碼會有重合部分,所以執行 git stash pop 時候就會出現衝突,有衝突解決衝突即可。

a. 原來內容:
from django.shortcuts import render,HttpResponse def index(request):
return render(request,'index.html') def africa(request):
return HttpResponse('非洲專區') b. 開發到一半直播功能:
from django.shortcuts import render,HttpResponse def index(request):
return render(request,'index.html') def africa(request):
return HttpResponse('非洲專區') def live(request):
print('開發到一半')
return HttpResponse('....') c. 執行git stash,回到當前版本未修改狀態:
from django.shortcuts import render,HttpResponse def index(request):
return render(request,'index.html') def africa(request):
return HttpResponse('非洲專區') d. 修復Bug並提交:
from django.shortcuts import render,HttpResponse def index(request):
return render(request,'index.html') def africa(request):
return HttpResponse('非洲xxxxx專區') e. 繼續開發直播功能 git stash pop,此時會出現衝突:
MacBook-Pro-:pondo wupeiqi$ git stash pop
Auto-merging app01/views.py
CONFLICT (content): Merge conflict in app01/views.py 表示app01/views.py存在衝突需要解決,此時檔案內容為: from django.shortcuts import render,HttpResponse def index(request):
return render(request,'index.html') def africa(request):
<<<<<<< Updated upstream: # 修復Bug時更改的內容
return HttpResponse('非洲xxxx區')
======= # 修復Bug前正在開發新功能時的內容
return HttpResponse('非洲專區') def live(request):
print('剛開發到一半')
return HttpResponse('直播功能')
>>>>>>> Stashed changes 需要自行解決衝突,然後繼續開發,如: from django.shortcuts import render,HttpResponse def index(request):
return render(request,'index.html') def africa(request): return HttpResponse('非洲xxxx區') def live(request):
print('剛開發到一半')
return HttpResponse('直播功能')

git stash pop 出現衝突

stash相關常用命令:

  • git stash             將當前工作區所有修改過的內容儲存到“某個地方”,將工作區還原到當前版本未修改過的狀態
  • git stash list        檢視“某個地方”儲存的所有記錄
  • git stash clear     清空“某個地方”
  • git stash pop       將第一個記錄從“某個地方”重新拿到工作區(可能有衝突)
  • git stash apply     編號, 將指定編號記錄從“某個地方”重新拿到工作區(可能有衝突)
  • git stash drop      編號,刪除指定編號的記錄

方案二:branch

分支學習:branch稱為分支,預設僅有一個名為master的分支。一般開發新功能流程為:開發新功能時會在分支dev上進行,開發完畢後再合併到master分支。

MacBook-Pro-:pondo wupeiqi$ git branch dev                 # 建立新分支,即:拷貝一份當前所在分支程式碼到新分支
MacBook-Pro-:pondo wupeiqi$ git checkout dev # 切換到dev分支
MacBook-Pro-:pondo wupeiqi$ vim app01/views.py # 開發功能
MacBook-Pro-:pondo wupeiqi$ git status # 檢視狀態,即:在dev分支修改了app01/views.py檔案
On branch dev
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: app01/views.py no changes added to commit (use "git add" and/or "git commit -a")
MacBook-Pro-:pondo wupeiqi$ git add . # 將修改檔案新增到版本庫的暫存區
MacBook-Pro-:pondo wupeiqi$ git commit -m '新功能開發完畢' # 將暫存區的內容提交到當前所在分支,即:dev分支
[dev 32b40cd] 新功能開發完畢
file changed, insertions(+)
MacBook-Pro-:pondo wupeiqi$ git checkout master # 切換回master分支
Switched to branch 'master'
MacBook-Pro-:pondo wupeiqi$ git merge dev # 將dev分支內容合併到master分支
Updating 0972f4b..32b40cd
Fast-forward
app01/views.py | ++
file changed, insertions(+)

一般流程示例(上圖)

學習參考上圖,小P也可以按照著這樣的流程進行開發,如果遇到上文開發到一般需要臨時修復Bug的情況,可以按照下圖的流程進行:

MacBook-Pro-4:pondo wupeiqi$ git branch                     # 當前在master分支
* master MacBook-Pro-4:pondo wupeiqi$ git branch dev # 建立dev分支用於開發新功能 MacBook-Pro-4:pondo wupeiqi$ git checkout dev # 切換到dev分支
Switched to branch 'dev' MacBook-Pro-4:pondo wupeiqi$ vim app01/views.py # 開發新功能到一半,需要緊急修復Bug MacBook-Pro-4:pondo wupeiqi$ git add . MacBook-Pro-4:pondo wupeiqi$ git commit -m '新功能開發一半'
[dev b3ac2cb] 新功能開發一半
1 file changed, 2 insertions(+) MacBook-Pro-4:pondo wupeiqi$ git checkout master # 切換回master分支
Switched to branch 'master' MacBook-Pro-4:pondo wupeiqi$ git branch bug # 建立bug分支 MacBook-Pro-4:pondo wupeiqi$ git checkout bug # 切換到bug分支
Switched to branch 'bug' MacBook-Pro-4:pondo wupeiqi$ vim pondo/settings.py # 修改bug MacBook-Pro-4:pondo wupeiqi$ git add . # 提交bug MacBook-Pro-4:pondo wupeiqi$ git commit -m '緊急修復bug' # 提交bug
[bug f42f386] 緊急修復bug
1 file changed, 1 insertion(+), 1 deletion(-) MacBook-Pro-4:pondo wupeiqi$ git checkout master # 切換會master
Switched to branch 'master' MacBook-Pro-4:pondo wupeiqi$ git merge bug # 將bug分支內容合併到master分支,表示bug修復完畢,可以上線
Updating 0972f4b..f42f386
Fast-forward
pondo/settings.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-) MacBook-Pro-4:pondo wupeiqi$ git checkout dev # 切換到dev分支,繼續開發新功能
Switched to branch 'dev' MacBook-Pro-4:pondo wupeiqi$ vim app01/views.py # 繼續開發其他一半功能 MacBook-Pro-4:pondo wupeiqi$ git add . # 提交新功能 MacBook-Pro-4:pondo wupeiqi$ git commit -m '繼續開發完成' # 提交功能
[dev c0bfb27] 繼續開發完成
1 file changed, 1 insertion(+) MacBook-Pro-4:pondo wupeiqi$ git checkout master # 切換回master分支
Switched to branch 'master' MacBook-Pro-4:pondo wupeiqi$ git merge dev # 將dev分支合併到master分支
Merge made by the 'recursive' strategy.
app01/views.py | 3 +++
1 file changed, 3 insertions(+)

注意:git merge 時也可能會出現衝突,解決衝突的方式上述stash相同,即:找到衝突檔案,手動修改衝突並提交,此處不再敖述。

branch相關常用命令:

  • git branch 分支名稱             建立分支
  • git checkout 分支名稱          切換分支
  • git branch -m 分支名稱        建立並切換到指定分支
  • git branch                          檢視所有分支
  • git branch -d 分支名稱         刪除分支
  • git merge 分支名稱              將指定分支合併到當前分支

Git使用之小P創業快速發展期

小P不忘初心始終如一的為廣大有為青年提供資源,使得網站的訪問量不斷攀升,已經出具規模並賺了一些錢,有錢就要造麼,索性國貿租了一間寫字樓用於辦公,並且也完善運營市場團隊。。屌絲終歸是屌絲,小P還是離不開寫程式碼的習慣,所以開發的任務還是由自己一人承擔,小P從此開始了白天在國貿寫程式碼,晚上回天通苑寫程式碼。PS:有錢,公司一臺新電腦,家裡一臺原來老電腦。。。。。 媽的,故事怎麼才能變得有趣呢?太拓麻難了。

小P心裡開始尋思,我愛寫程式碼,公司寫,家裡寫,如果每天來回帶一個U盤拷貝著實麻煩,Git有沒有類似於雲盤似得東西可以進行資料同步呢?答案肯定是有。 必須有,不然老子真的就編不下去了。

GitHub,一個基於Git實現的程式碼託管的平臺,可以將內容以及版本記錄在遠端也儲存一份,這樣就不用U盤咯(類似於雲盤)。PS: 類似GitHub的產品還有許多,如:GitLab、Bitbucket、碼雲等。

基於GitHub實現程式碼託管,需要一下步驟:

  • 註冊GitHub
  • 建立倉庫,建立完倉庫後會有一個URL代指該倉庫,如:
  • git可以是用該URL進行向遠端推送版本資訊或獲取版本資訊

小P學會使用Git和GitHub之後,就可以基於GitHub進行程式碼遠端託管。

在家裡,小P開發完畢部分功能將程式碼推送到GitHub。

MacBook-Pro-4:pondo wupeiqi$ git remote add origin https://github.com/WuPeiqi/pondo.git   # 為地址起一個別名origin
MacBook-Pro-4:pondo wupeiqi$ git push origin master # 將本地master分支內容以及版本資訊推送到GitHub
Username for 'https://github.com': # 輸入GitHub使用者名稱
Password for 'https://[email protected]': # 輸入GitHub密碼
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 270 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/WuPeiqi/pondo.git
634aac4..274f1e4 master -> master
MacBook-Pro-4:pondo wupeiqi$ git push origin dev # 將本地dev分支內容以及版本資訊推送到GitHub
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 261 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/WuPeiqi/pondo.git
274f1e4..50e2169 dev -> dev

在公司,新電腦第一次使用,需要將程式碼從GitHub中獲取並繼續開發,開發完事下班就下班回家。

MacBook-Pro-4:github wupeiqi$ git clone https://github.com/WuPeiqi/pondo.git    # 將專案從GitHub中獲取
Cloning into 'pondo'...
remote: Counting objects: 31, done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 31 (delta 2), reused 30 (delta 1), pack-reused 0
Unpacking objects: 100% (31/31), done.
MacBook-Pro-4:github wupeiqi$ cd pondo/
MacBook-Pro-4:pondo wupeiqi$ git Branch # 預設獲取到得只有master分支
* master
MacBook-Pro-4:pondo wupeiqi$ git branch dev origin/dev # 建立dev分支且和遠端dev分支同步
Branch dev set up to track remote branch dev from origin.
MacBook-Pro-4:pondo wupeiqi$ git checkout dev # 切換到dev分支
Switched to branch 'dev' MacBook-Pro-4:pondo wupeiqi$ vim app01/views.py # 繼續開發新功能 MacBook-Pro-4:pondo wupeiqi$ git add . # 新增檔案到版本庫的暫存狀態
MacBook-Pro-4:pondo wupeiqi$ git commit -m '公司開發功能1' # 提交新功能到版本庫的分支
[dev 9281447] 公司開發功能1
1 file changed, 1 insertion(+), 1 deletion(-)
MacBook-Pro-4:pondo wupeiqi$ git push origin dev # 提交dev分支內容到遠端GitHub託管倉庫的dev分支
Username for 'https://github.com': wupeiqi
Password for 'https://[email protected]':
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 427 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/WuPeiqi/pondo.git
50e2169..9281447 dev -> dev

在家裡,由於白天在公司已經開發一部分功能並提交到GitHub,家裡電腦的程式碼還是昨晚的版本,所以需要從GitHub拉去最新程式碼,然後繼續開發。

MacBook-Pro-4:pondo wupeiqi$ git checkout dev                                   # 切換到dev分支
Already on 'dev'
MacBook-Pro-4:pondo wupeiqi$ git pull origin dev # 從遠端GitHub倉庫獲取dev分支最新內容,併合併到本地
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 2), reused 4 (delta 2), pack-reused 0
Unpacking objects: 100% (4/4), done.
From https://github.com/WuPeiqi/pondo
* branch dev -> FETCH_HEAD
50e2169..9281447 dev -> origin/dev
Updating 50e2169..9281447
Fast-forward
app01/views.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
MacBook-Pro-4:pondo wupeiqi$ vim app01/views.py # 繼續開發新功能
MacBook-Pro-4:pondo wupeiqi$ git add . # 新增檔案到版本庫的暫存狀態
MacBook-Pro-4:pondo wupeiqi$ git commit -m '家裡開發功能1' # 提交新功能到版本庫的分支

 在公司,由於昨天晚上在家已經開發了一部分功能,在公司需要先把昨晚開發的功能從GitHub中拉取,並繼續開發。

MacBook-Pro-4:pondo wupeiqi$ git checkout dev                                   # 切換到dev分支
MacBook-Pro-4:pondo wupeiqi$ git fetch origin dev # 從GitHub倉庫獲取dev分支最新內容到版本庫的分支
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/WuPeiqi/pondo
* branch dev -> FETCH_HEAD
150d891..65b6604 dev -> origin/dev
MacBook-Pro-4:pondo wupeiqi$ git merge origin/dev # 將版本庫的分支內容合併到工作區
Updating 150d891..65b6604
Fast-forward
readme | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
MacBook-Pro-4:pondo wupeiqi$ vim app01/views.py # 繼續開發新功能
MacBook-Pro-4:pondo wupeiqi$ git add . # 新增檔案到版本庫的暫存狀態
MacBook-Pro-4:pondo wupeiqi$ git commit -m 'xxxxxxxxxxx' # 提交新功能到版本庫的分支

長此以往,將Git和GitHub結合使用做到避免電腦損壞造成資料丟失以及多地開發的問題,上文執行過程中執行 【git pull origin 分支】命令等同於【git fetch origin 分支】+ 【git merge origin/分支】,並且在執行過程中可能會出現衝突,原因是由於原生代碼和獲取的最新程式碼有重合部分,那麼就需要自己手動解決衝突然後再繼續開發。

Git使用之小P創業成熟期

小P的公司發展越來越好,但是公司產品單一是嚴重缺點,經過學習考察小P決定再招聘3個Python程式開發另外一個產品“約P”平臺來豐富公司業務線,為使用者提供一整套服務。

小P的Slogan:看了想要,想要就約。 不要問我怎麼想要的,我自己也不知道    哈哈哈哈哈哈哈哈

“約P”平臺需要三人協同開發,GitHub中多人協同開發和單人開發還是有點差別,協同開發一般有兩種方式:

  • 合作者,將其他使用者新增到倉庫合作者中之後,該使用者就具有向當前倉庫提交程式碼。
  • 組織,建立一個組織,然後再該組織下可以建立多個專案,組內成員可以向組內所有專案提交程式碼。PS:也可以對某個專案指定合作者

協同開發命令和以上步驟類似,此處就不再重新寫程式碼,而是使用檔案描述三人協同開發整個過程。

  • 建立程式
    • 使用者A建立程式,提交到GitHub
    • 使用者B克隆專案
    • 使用者C克隆專案
  • 開發功能
    • 使用者A開發功能1
    • 使用者B開發功能2
    • 使用者C開發功能3
  • 提交
    • 使用者A提交功能1,並push(A使用者手速快,先提交。)
    • 使用者B提交功能2,無法push,因為GitHub上已經有其他人提交的新程式碼。
      解決方法:從GitHub上獲取最新程式碼併合併到本地,提交自己開發的功能2。
    • 使用者C提交功能3,無法push,無法提交,因為GitHub上已經有其他人提交的新程式碼。
      解決方法:從GitHub上獲取最新程式碼併合併到本地,提交自己開發的功能3。
  • 獲取最新程式碼
    • 使用者A獲取最新程式碼
    • 使用者B獲取最新程式碼
    • 使用者C獲取最新程式碼

在上面紅色標註的解決方法位置可以有三種方式操作,三者都可以完成合並並提交新功能,但是日誌記錄會有差異,如:前兩者版本記錄中會出現合併,而第三種可以保證版本記錄乾淨整潔。

  • 先 git pull origin master   然後 git push origin master
  • 先 git fetch origin master 然後 git merge origin/master   再 git push origin master
    使用者A:
    touch 4.py
    git add .
    git commit -m '功能4'
    git push origin master 使用者B:
    touch 5.py
    git add .
    git commit -m '功能5' git push origin master # 報錯,因為GitHub中已經有人提交新程式碼 git pull origin master git push origin master

  • 先 git fetch origin master 然後 git rebase origin/master  再 git push origin master
    使用者A:
    touch 4.py
    git add .
    git commit -m '功能4'
    git push origin master 使用者B:
    touch 5.py
    git add .
    git commit -m '功能5' git push origin master # 報錯,因為GitHub中已經有人提交新程式碼 git fetch origin master git rebase origin/master git push origin master  

使用Git之小P創業上市期

終於終於小P等到了公司上市實現財務自由,但作為一個技術屌還是脫離不了屌絲的本質,所以每天都是逛逛github,看看別人有什麼好的專案,自己可以給他挑挑bug裝裝逼,但是別人不可能給小P搞成合作者什麼的,那怎麼才能給別人貢獻程式碼呢?那就是fork了。。。。

  • 找到想搞的專案,fork一下,然後這個專案就在自己倉庫出現了
  • 從自己倉庫獲取程式碼並進行編輯提交
  • 建立並提交一個pull request,然後等待原作者是否同意這個pull request,如果同意那麼在作者的原始碼中就推出現小P提交的功能

其他補充

1. 配置檔案

Git的配置檔案有三個:

  • 系統配置: /private/etc/gitconfig
  • 使用者配置: ~/.gitconfig
  • 專案配置:.git/config

2. 使用者憑證

由於Git和Github互動操作可能會很頻繁,那麼一定少了使用者授權的操作,為了防止每次操作重複輸入使用者名稱和密碼,Git提供了兩種解決方法:

  • 祕鑰
    首先建立一對祕鑰  ssh-keygen -t rsa,然後將 id_rsa.pub (公鑰)內容拷貝到github中,日後操作無需再輸入使用者名稱和密碼。
    注意:這種方式需要使用GIt中 [email protected]:WuPeiqi/xxxxx.git 格式地址。
  • 密碼
    Https訪問git時,避免每次操作需要輸入使用者名稱和密碼,可以在配置檔案中新增如下配置項:
        [credential]
        helper = store/cache/第三方

    store:
            表示將使用者名稱和密碼儲存在硬碟上
            第一次輸入過使用者名稱和密碼之後,使用者名稱和密碼就會儲存在當前使用者根目錄的 .git-credentials 檔案中,內容格式為:https://使用者名稱:密碼@github.com

            自動新增配置命令:git config credential.helper store
    cache:
            表示將使用者名稱和密碼儲存在快取中
            第一次輸入過使用者名稱和密碼之後,使用者名稱和密碼就會儲存在快取中,預設超時時間是 900 秒,快取相關檔案儲存在當前使用者根目錄的 git-credential-cache 中
            自動新增配置命令:
                   git config credential.helper cache
                   git config credential.helper 'cache --timeout=300'

    相關操作:
            清除快取:git credential-cache exit
            指定超時:
                [credential]
                helper = cache --timeout=300
    注意:
             這種方式需要使用GIt中 https://github.com/WuPeiqi/xxxx.git 格式地址。
             指定使用者名稱和密碼: https://使用者名稱:密碼@github.com/wupeiqi/xxx.git

就醬紫,以後想到再加吧...

  以斜槓“/”開頭表示目錄;

  以星號“*”通配多個字元;

  以問號“?”通配單個字元

  以方括號“[]”包含單個字元的匹配列表;

  以歎號“!”表示不忽略(跟蹤)匹配到的檔案或目錄;

.gitignore

    git tag -a v1.0 -m '版本介紹'        本地建立Tag
git show v1.0 檢視
git tags -n 檢視本地Tag
git tag -l 'v1.4.2.*' 檢視本地Tag,模糊匹配
git tag -d v1.0 刪除Tag
git push origin :refs/tags/v0.2 更新遠端tag
git checkout v.10 切換tag
git fetch origin tag V1.2 git push origin --tags
git pull origin --tags git clone -b v0.1

版本相關

# Byte-compiled / optimized / DLL files

# pycharm
.idea/
.DS_Store
offline-script/
media/ # database migrations
*/migrations/*.py
!*/migrations/__init__.py __pycache__/
*.py[cod]
*$py.class # Django stuff:
*.log
local_settings.py
*.sqlite3 # C extensions
*.so # Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST # PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec # Installer logs
pip-log.txt
pip-delete-this-directory.txt # Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/ # Translations
*.mo
*.pot # Flask stuff:
instance/
.webassets-cache # Scrapy stuff:
.scrapy # Sphinx documentation
docs/_build/ # PyBuilder
target/ # Jupyter Notebook
.ipynb_checkpoints # IPython
profile_default/
ipython_config.py # pyenv
.python-version # celery beat schedule file
celerybeat-schedule # SageMath parsed files
*.sage.py # Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/ # Spyder project settings
.spyderproject
.spyproject # Rope project settings
.ropeproject # mkdocs documentation
/site # mypy
.mypy_cache/
.dmypy.json
dmypy.json