我寫東西廢話向來很多,這次不扯東扯西,爭取20分鐘之內(nèi)進入正題。
Just kidding.
今天來介紹一下Git和Github。本文必將有不少奇怪和模糊(但足夠初學者大致理解)的比喻以及極度口語化的文字,請慎重閱讀。
Git & Github:
Git是一個版本控制軟件。你在寫代碼的時候想要測試一個新功能,卻并不想在已經(jīng)穩(wěn)定的版本上做實驗(萬一刪刪改改出了問題,想要恢復到之上個版本怎么辦?),這時就需要版本控制,將當前的代碼保護起來,另起爐灶;如果測試結(jié)果不滿意,把不穩(wěn)定的爐灶全部推倒,還能滾回之前好用的版本。
你用git控制的文件和這些文件的修改記錄都是保存在本地的,為了多人協(xié)作/不把雞蛋放在一個籃子里,某位古神(應(yīng)該是Linus)創(chuàng)建了網(wǎng)站github。你可以用git在本地控制每個文件,記錄每一次增刪,然后把這些文件連同所有的修改記錄推送到github上。
好的,跟我重復重點:
Git是本地的版本控制軟件,可以跟蹤文件的所有修改記錄;
Github是修改記錄和文件的在線保存地。
Github和多人協(xié)作:
張三等人一起用github開發(fā)一個軟件,他們認為該軟件主要有3個功能。
張三寫好了功能1,測試穩(wěn)定了;
李四在張三的基礎(chǔ)上寫好了功能2,測試穩(wěn)定了;
王五覺得自己能寫出更高效的功能2,就從張三的版本上另起爐灶,寫了功能2',測試穩(wěn)定了,三人討論后決定采用2'版本,于是王五把自己的功能2'推送回了主程序,成為主程序的一部分;
張三和李四也一起寫好了功能3,和王五同步完成工作;
bad bad example, just for reference.
最簡單的git指令以及工作流程
定義
- zelda.txt是我需要版本控制的文件
- 我的項目名稱叫mario
往下看之前確認你知道cd是什么意思。
另外強烈建議邊看教程邊動手做一遍。
1. 創(chuàng)建repository
為了版本控制任何文件,你首先要創(chuàng)建一個修改記錄儲藏中心,又叫做repository。
這個中心可以
- 從無到有生成(如果你在寫一個全新的項目)
或者
- 從別人已有的儲藏中心拷貝一份過來(如果你想接著別人的進度繼續(xù)寫)
對于1,你又有兩種方法
a. cd到任意一個文件夾里,比如說~/Desktop/,用git init mario來創(chuàng)建新的repository。這步之后你會在桌面上看到一個叫做mario的文件夾,點進去,把你的zelda.txt文件拷貝進去,之后就可以在mario這個repository之中開始版本控制啦。
b. 到github官網(wǎng),點擊一個綠色的按鍵(new repository),在新頁面中給新repository起名叫mario,確定;然后他會在新頁面中有一個地方讓你復制鏈接(非常類似于https://github.com/chenxi-ge/mario.git的一個鏈接);復制,cd到任意一個文件夾里,用git clone 剛才的鏈接來把在線創(chuàng)建的repository聯(lián)動到本地。
對于2,直接用git clone 別人的repository就可以了。
好的,重復重點:
本地生成,git init folder_name
在線拷貝下來(不管是自己的還是別人的),git clone repo_url
插一句,Github是可以免費使用的。但免費使用的代價是,你也要保持所有的代碼開源:任何人都可以查看你的代碼,你也可以下載別人的代碼,程序員們在互相學習中成長。開源是我非常欽佩和堅持的精神——不然寫啥教程啊。
當然對于企業(yè)用戶,每人每月7刀,可以創(chuàng)建私人repository用于公司項目,也挺好。
2. 管理文件
那么現(xiàn)在你有一個文件夾,叫mario,在本地;這個文件夾里有一個幽靈(.git)在監(jiān)視著所有你讓他監(jiān)視的文件;還有一個你剛剛拷貝進去的zelda.txt。
現(xiàn)在這個zelda.txt是沒有被監(jiān)視的,幽靈也是有拖延癥的,不會主動幫你干活的。
何以見得?用git status查看當前管理進度。
git status之后,你會看到zelda.py是在'Untracked Files'里面的,并且是紅色的。于是我們使用git add zelda.txt ,告訴git開始監(jiān)視zelda.txt的每一行增刪(把這個文件add到監(jiān)視列表里)。
增加之后再用git status,會發(fā)現(xiàn)文件進入了'Changes to be committed'的列表里,并且名字前面顯示'new file'。
那么我們來談?wù)刢ommit。什么叫commit呢?就是告訴git:在這兒存?zhèn)€檔,記錄一下當前文件和上一次commit的差異。這樣追根溯源,之后就能恢復每個文件每個版本。
我習慣在add新文件之后進行一次commit。
git commit -a -m 備注內(nèi)容是commit的常用方法,這里-a 是要求“記錄所有修改”,-m是提示后面緊跟著備注,而備注內(nèi)容當然是人類能看懂的語言,不好好寫吊起來打。
在commit之后,再再再git status一下,發(fā)現(xiàn)所有的改動都已提交,無比清爽。
我猜這兒正經(jīng)教程要開始講什么叫stage,不然沒法講清
git commit -a的-a是什么。然而這種會搞亂新手的東西我也不能說完全能講清,想了解的請自己去看官方文檔。
這時我們手賤去改動一下zelda.txt的內(nèi)容,然后git status,會發(fā)現(xiàn)zelda.txt又變成了modified,并且是紅色狀態(tài)。很好,如果改動是你需要的,就commit;如果是commit之后發(fā)現(xiàn)不需要的(比如十幾個commit后發(fā)現(xiàn)性能反而降低了),之后會講如何回滾。
在commit之前,如果你想了解一下你的改動,用git diff可以做到這一點。但綠色代表什么,加減號又代表什么,請查閱文檔。
好的重復重點,
git add 跟蹤文件
git status 查看當前跟蹤進度
git commit 存檔一下
3. 版本控制
最后光速講一下log, reset和push然后我就去睡覺。
首先,之前吹了半天版本控制,到底怎么才能回滾到之前的一個穩(wěn)定可用版本呢?
首先是查看記錄,用git log可以查看到歷史上所有的commit編號、commit的提交者和提交時間,還有當時的備注。假設(shè)你在有一個穩(wěn)定可用版本時commit了一下,這條commit記錄會留在log上。
然后是回滾版本,用git reset --hard log編號。所謂log編號是用git log查看時在每個commit最頂端的一串30個字母左右的亂碼,在reset的時候只要輸入前六位就可以回滾版本。執(zhí)行完git reset指令后,再次查看zelda.txt就會發(fā)現(xiàn)回到了那條特定的commit時的樣子。
新手不必在意git reset log編號和有--hard的版本不一樣,前者是回滾所有commit但不修改本地文件,后者是回滾所有commit并且修改本地文件。
最后就是git push。之前所有的版本控制都是在本地的,如果想把本地的所有修改都推送到github上存儲怎么辦呢?git push origin master,認準這一條。其中git push很顯然是推送,origin master是說推送目標是主分支,對于沒有開其他分支的你——你要能讀到這兒,肯定是還沒用到啦——也是唯一選擇。
git push的頻率當然可以自己定,我習慣是每寫好一個功能/最多15分鐘commit一下,而每寫完一個項目(比如說一次作業(yè)),如果是連續(xù)的幾個小時寫完就最后push一次,否則今天的份額寫完了就push。
PS,如果忘記在寫完項目之后做git push,這個project就拿零分了。
重點?
git log 查看所有commit
git reset 回滾版本
git push 推送修改到Github——在線的數(shù)據(jù)中心
4. 坑
說了是坑嘛,肯定不會填的。
這個教程最主要是面向新手,展示一個文件跟蹤的流程,用到的都是最基本的幾個指令:git init, git clone, git add, git commit, git log, git push, git reset,讓人能跟蹤一個文件,不斷記錄修改,可以方便回滾,也可以提交到github,這些足夠啦。
度過了最開始的confusion,任何一個官方文檔不比我說的嚴謹標準一萬倍么。
所以這一塊主要是說一下還有哪些沒說到的,留給讀者自行探索吧。
-
git merge,git fetch,git branch分支控制 -
git stash暫存修改 -
git pull下載別人的修改