說到版本控制,腦海裏總會浮現大學畢業是寫畢業論文的場景,你電腦上的畢業論文必定出現過這番景象!html
畢業論文_初稿.doc 畢業論文_修改1.doc 畢業論文_修改2.doc 畢業論文_修改3.doc 畢業論文_完整版1.doc 畢業論文_完整版2.doc 畢業論文_完整版3.doc 畢業論文_最終版1.doc 畢業論文_最終版2.doc 畢業論文_死也不改版.doc ...
以上就是使用最原始的方式進行版本控制,可是這種方式有顯著缺點:python
爲了解決以上版本控制存在問題,應運而生了一批版本控制工具:VSS、CVS、SVN、Git等,其中Git屬於絕對霸主地位。git
注意:通常版本控制工具包含兩部分github
Git 是一個開源的分佈式版本控制軟件,用以有效、高速的處理從很小到很是大的項目版本管理。 Git 最初是由Linus Torvalds設計開發的,用於管理Linux內核開發。Git 是根據GNU通用公共許可證版本2的條款分發的自由/免費軟件,安裝參見:http://git-scm.com/sql
GitHub是一個基於Git的遠程文件託管平臺(同GitCafe、BitBucket和GitLab等)。django
Git自己徹底能夠作到版本控制,但其全部內容以及版本記錄只能保存在本機,若是想要將文件內容以及版本記錄同時保存在遠程,則須要結合GitHub來使用。使用場景:vim
其餘:緩存
集中式:遠程服務器保存全部版本,用戶客戶端有某個版本
分佈式:遠程服務器保存全部版本,用戶客戶端有全部版本服務器
$ pwd # 進入程序目錄 /Users/maple/PycharmProjects/pondo $ git init # git初始化 Initialized empty Git repository in /Users/maple/PycharmProjects/pondo/.git/
$ 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) $ git add . # 添加當前目錄下全部文件到版本庫 $ git commit -m '第一次提交' # 提交到版本庫,並填寫版本說明,以便之後回滾。 [master (root-commit) df47fe4] 第一次提交 files changed, 879 insertions(+) create mode 100644 .idea/dictionaries/maple.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml ...
注意:執行git commit 命令時,可能會提示進行用戶和郵箱的配置,該配置用於記錄當前版本由那個用戶提交app
Git把管理的文件分爲了兩個區域四個狀態。
工做區:當前開發程序所在目錄稱爲工做區,即:工做開發都是在該目錄,該區域的文件會有狀態的變化且狀態由git自動檢測,
若是程序中文件作任何操做(增、刪、改),文件狀態均會被檢測到,可使用 【git status】命令查看。
1 $ ls # 查看原程序目錄 2 app01 db.sqlite3 manage.py pondo readme static templates 3 4 $ git status # 查看git當前狀態 5 On branch master 6 nothing to commit, working tree clean 7 8 $ touch a.py # 建立新文件 9 $ ls 10 a.py app01 db.sqlite3 manage.py pondo readme static templates 11 12 $ git status # 查看git當前狀態,檢測到:工做區 a.py 發生變化 13 On branch master 14 Untracked files: 15 (use "git add <file>..." to include in what will be committed) 16 17 a.py 18 19 nothing added to commit but untracked files present (use "git add" to track)
版本庫:工做區檢測到有文件發生變化,那麼意味着較上一個版本以後對程序進行了修改,修改完成以後,能夠當作下一版本進行提交,
那麼就是執行 【git add .】 將全部文件提交到暫存區,而後再執行【git commit -m '又一個版本'】提交到版本庫的分支便可,以後可使用【git log】命令查看版本記錄。
$ ls a.py app01 db.sqlite3 manage.py pondo readme static templates $ 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) $ git add . # 將全部相較上一次版本以後全部的修改添加到暫存狀態 $ git status # 文件顏色爲綠色,表示在版本庫的暫存狀態 On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: a.py $ git commit -m '又一次提交' # 提交到版本庫的分支 [master f139d5d] 又一次提交 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a.py $ git log # 查看歷史版本提交記錄(根據版本commit值能夠進行回滾) commit f139d5d0a648af06d8a1ecadd90faf572afc388a Author: maple <you@example.com> Date: Fri Aug 11 10:03:14 2018 +0800 又一次提交 commit df47fe49fc1f14d9cdd1534baa96f46ec71a9934 Author: maple <you@example.com> Date: Fri Aug 11 08:40:49 2018 +0800 第一次提交
目前已使用Git的四個命令,這四個命令已經能夠代替本地多個文件保存版本的方式:
git log 查看版本信息
git reset --hard 版本號 回滾到到想要的的版本
想再次回滾到最新的版本,就不能用git log 查看版本信息了。要這麼搞:
git reflog 查看版本號
git reset --hard 版本號
stash用於將工做區發生變化的全部文件獲取臨時存儲在「某個地方」,將工做區還原當前版本未操做前的狀態;stash還能夠將臨時存儲在「某個地方」的文件再次拿回到工做區。
$ vim app01/views.py # 開發直播功能,剛開發到一半 $ 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") $ git stash # 將開發到一半的直播功能,臨時存儲到「某個地方」 Saved working directory and index state WIP on master: 0972f4b 非洲專區上線 HEAD is now at 0972f4b 非洲專區上線 $ git status # 工做區回到當前版本未作任何操做前 On branch master nothing to commit, working tree clean $ vim pondo/settings.py # 緊急修復bug $ 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") $ git add . # 添加到修改bug的代碼到暫存狀態 $ git commit -m '緊急修復bug' # 提交修復Bug的代碼到分支 [master 1300d33] 緊急修復bug file changed, 1 insertion(+) $ 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-4:pondo maple$ 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相關經常使用命令:
分支學習:branch稱爲分支,默認僅有一個名爲master的分支。通常開發新功能流程爲:開發新功能時會在分支dev上進行,開發完畢後再合併到master分支。
$ git branch dev # 建立新分支,即:拷貝一份當前所在分支代碼到新分支 $ git checkout dev # 切換到dev分支 $ vim app01/views.py # 開發功能 $ 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") $ git add . # 將修改文件添加到版本庫的暫存區 $ git commit -m '新功能開發完畢' # 將暫存區的內容提交到當前所在分支,即:dev分支 [dev 32b40cd] 新功能開發完畢 file changed, 2 insertions(+) $ git checkout master # 切換回master分支 Switched to branch 'master' $ git merge dev # 將dev分支內容合併到master分支 Updating 0972f4b..32b40cd Fast-forward app01/views.py | 2 ++ file changed, 2 insertions(+) 通常流程示例(上圖)
學習參考上圖,小P也能夠按照着這樣的流程進行開發,若是遇到上文開發到通常須要臨時修復Bug的狀況,能夠按照下圖的流程進行:
$ git branch # 當前在master分支 * master $ git branch dev # 建立dev分支用於開發新功能 $ git checkout dev # 切換到dev分支 Switched to branch 'dev' $ vim app01/views.py # 開發新功能到一半,須要緊急修復Bug $ git add . $ git commit -m '新功能開發一半' [dev b3ac2cb] 新功能開發一半 file changed, 2 insertions(+) $ git checkout master # 切換回master分支 Switched to branch 'master' $ git branch bug # 建立bug分支 $ git checkout bug # 切換到bug分支 Switched to branch 'bug' $ vim pondo/settings.py # 修改bug $ git add . # 提交bug $ git commit -m '緊急修復bug' # 提交bug [bug f42f386] 緊急修復bug file changed, 1 insertion(+), 1 deletion(-) $ git checkout master # 切換會master Switched to branch 'master' $ git merge bug # 將bug分支內容合併到master分支,表示bug修復完畢,能夠上線 Updating 0972f4b..f42f386 Fast-forward pondo/settings.py | 2 +- file changed, 1 insertion(+), 1 deletion(-) $ git checkout dev # 切換到dev分支,繼續開發新功能 Switched to branch 'dev' $ vim app01/views.py # 繼續開發其餘一半功能 $ git add . # 提交新功能 $ git commit -m '繼續開發完成' # 提交功能 [dev c0bfb27] 繼續開發完成 file changed, 1 insertion(+) $ git checkout master # 切換回master分支 Switched to branch 'master' $ git merge dev # 將dev分支合併到master分支 Merge made by the 'recursive' strategy. app01/views.py | 3 +++ file changed, 3 insertions(+)
注意:git merge 時也可能會出現衝突,解決衝突的方式上述stash相同,即:找到衝突文件,手動修改衝突並提交,此處再也不敖述。
branch相關經常使用命令:
GitHub,一個基於Git實現的代碼託管的平臺,能夠將內容以及版本記錄在遠程也保存一份,這樣就不用U盤咯(相似於雲盤)。PS: 相似GitHub的產品還有許多,如:GitLab、Bitbucket、碼雲等。
基於GitHub實現代碼託管,須要一下步驟:
小P學會使用Git和GitHub以後,就能夠基於GitHub進行代碼遠程託管。
在家裏,小P開發完畢部分功能將代碼推送到GitHub。
$ git remote add origin https://github.com/maple-shaw/pondo.git # 爲地址起一個別名origin $ git push origin master # 將本地master分支內容以及版本信息推送到GitHub Username for 'https://github.com': # 輸入GitHub用戶名 Password for 'https://maple-shaw@github.com': # 輸入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/maple-shaw/pondo.git 634aac4..274f1e4 master -> master $ 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/maple-shaw/pondo.git 274f1e4..50e2169 dev -> dev
在公司,新電腦第一次使用,須要將代碼從GitHub中獲取並繼續開發,開發完事下班就下班回家。
$ git clone https://github.com/maple-shaw/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. $ cd pondo/ $ git Branch # 默認獲取到得只有master分支 * master $ git branch dev origin/dev # 建立dev分支且和遠程dev分支同步 Branch dev set up to track remote branch dev from origin. $ git checkout dev # 切換到dev分支 Switched to branch 'dev' $ vim app01/views.py # 繼續開發新功能 $ git add . # 添加文件到版本庫的暫存狀態 $ git commit -m '公司開發功能1' # 提交新功能到版本庫的分支 [dev 9281447] 公司開發功能1 file changed, 1 insertion(+), 1 deletion(-) $ git push origin dev # 提交dev分支內容到遠程GitHub託管倉庫的dev分支 Username for 'https://github.com': maple Password for 'https://maple-shaw@github.com': 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/maple-shaw/pondo.git 50e2169..9281447 dev -> dev
在家裏,因爲白天在公司已經開發一部分功能並提交到GitHub,家裏電腦的代碼仍是昨晚的版本,因此須要從GitHub拉去最新代碼,而後繼續開發。
$ git checkout dev # 切換到dev分支 Already on 'dev' $ 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/maple/pondo * branch dev -> FETCH_HEAD 50e2169..9281447 dev -> origin/dev Updating 50e2169..9281447 Fast-forward app01/views.py | 2 +- file changed, 1 insertion(+), 1 deletion(-) $ vim app01/views.py # 繼續開發新功能 $ git add . # 添加文件到版本庫的暫存狀態 $ git commit -m '家裏開發功能1' # 提交新功能到版本庫的分支
在公司,因爲昨天晚上在家已經開發了一部分功能,在公司須要先把昨晚開發的功能從GitHub中拉取,並繼續開發。
$ git checkout dev # 切換到dev分支 $ 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/maple-shaw/pondo * branch dev -> FETCH_HEAD 150d891..65b6604 dev -> origin/dev $ git merge origin/dev # 將版本庫的分支內容合併到工做區 Updating 150d891..65b6604 Fast-forward readme | 5 ++++- file changed, 4 insertions(+), 1 deletion(-) $ vim app01/views.py # 繼續開發新功能 $ git add . # 添加文件到版本庫的暫存狀態 $ git commit -m 'xxxxxxxxxxx' # 提交新功能到版本庫的分支
久而久之,將Git和GitHub結合使用作到避免電腦損壞形成數據丟失以及多地開發的問題,上文執行過程當中執行 【git pull origin 分支】命令等同於【git fetch origin 分支】+ 【git merge origin/分支】,
而且在執行過程當中可能會出現衝突,緣由是因爲本地代碼和獲取的最新代碼有重合部分,那麼就須要本身手動解決衝忽然後再繼續開發。
GitHub中多人協同開發和單人開發仍是有點差異,協同開發通常有兩種方式:
協同開發命令和以上步驟相似,此處就再也不從新寫代碼,而是使用文件描述三人協同開發整個過程。
在上面紅色標註的解決方法位置能夠有三種方式操做,三者均可以完成合並並提交新功能,可是日誌記錄會有差別,如:前二者版本記錄中會出現合併,而第三種能夠保證版本記錄乾淨整潔。
用戶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
用戶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
怎麼才能給別人貢獻代碼呢?那就是fork了。。。。
1. 配置文件
Git的配置文件有三個:
2. 用戶憑證
因爲Git和Github交互操做可能會很頻繁,那麼必定少不了用戶受權的操做,爲了防止每次操做重複輸入用戶名和密碼,Git提供了兩種解決方法:
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/maple-shaw/xxxx.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 版本相關