作者: Tina
目錄
是否有遇到過寫着寫着想回到之前版本,卻又不記得具體實現;又或是想和隊友共享代碼,每次修改發送文件;抑或是想換個電腦寫卻不想用email等搬運全部文件這類煩不勝煩類似的問題,偉大的程序員們自然早就爲我們造好了輪子,那就是版本控制的利器——Git以及cloud based Github。本教程也主要講Git與Github的使用。
1. 背景介紹
本來想粗暴寫一下安裝使用教程,想了想還是先寫一點背景介紹,不感興趣可以直接跳過。
版本控制
首先我們需要了解一個概念——Version Control,也就是版本控制。當我們寫代碼的時候總會有意無意製造出一些bug,有時候我們會想返回前一次沒有問題的時候,因此這就是我們爲什麼需要版本控制。
簡單來說,版本控制就是在不同時間節點保存你的程序,然後你可以通過它回看甚至回到之前保存的版本。
什麼是Git
Git是在2005年的時候初次開發出來的版本控制利器,並風靡全球。Git是一個安裝並管理本地系統的工具而且可以給你提供現有文件的你保存的不同版本。因爲是本地的,下載之後就不再需要網絡也可以使用。
什麼是Github
Github有一點像可視化的Git,並且是在線的服務。讓你可以在線管理你的Git倉庫(這個具體會在後面講)。通過Github,你可以分享你的程序,讓其他合作者一起進行編輯。它不僅保存了Git的全部功能,還進行了擴充,它可以讓你在任意電腦任意地區訪問,只要你有權限。它最大的優點就是它是一個很龐大的數據庫,你可以搜索,閱讀甚至使用別人寫好的程序。當然Github還有很多替代物如Gitlab之類,本文就不贅述了。
Git vs. Github
簡單的說,Git是一個幫助你管理和追蹤本地源碼歷史的版本控制工具,而Github則是一個基於雲端運用Git技術的讓你管理Git倉庫的服務。
2. Git
首先,我們來康康Git的使用。
注意:所有和Git相關的命令都是git
開頭噢。
安裝
如果已經安裝過,可以跳過。
Linux
如果是Fedora或其他類似的 RPM-based distribution, 譬如RHEL 和 CentOS:
$ sudo dnf install git-all
或Debian-based distribution像Ubuntu
$ sudo apt install git-all
macOS
可以先試
$ git --version
如果沒有安裝,應該會彈出安裝請求,也可以去https://git-scm.com/download/mac 下載。
Windows
這個稍微有點煩,見https://git-scm.com/book/en/v2/Getting-Started-Installing-Git 。
新建一個Git倉庫
安裝好之後我們就可以開始用了,Git的一個倉庫(Repo)就是你的一個項目。我們首先新建一個文件夾
$ mkdir firstRepo
$ cd firstRepo
初始化一個倉庫
$ git init
這時候會顯示這麼一行
Initialized empty Git repository in /Users/tina/Desktop/firstRepo/.git/
,
後面一部分是你當前倉庫的路徑,會根據路徑不同進行變化。通過.git
我們可以知道Git其實是創建了一個隱藏文件夾,所以我們運行ls
這個命令,並不會看到有關Git的信息。
添加文件
我們依然先在當前目錄建文件,文件類型無所謂。這裏就用txt
文件了。
$ touch first.txt
$ ls
first.txt
此時我們可以看見文件裏有一個文件叫first.txt
,但是這個文件並不在我們Git倉庫裏(劃重點),爲了看倉庫裏有什麼,我們使用
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
first.txt
nothing added to commit but untracked files present (use "git add" to track)
這個命令我們之後具體講,現在我們看到untracked files
這裏,這個的意思就是說這些個文件在當前目錄下但是沒有保存到我們倉庫裏,所以Git不會對它的改變進行追蹤。把文件添加到倉庫裏,我們使用
$ git add first.txt
此時first.txt
已經被加進去了。如果我們想添加多個文件呢,可以把想加入的文件用空格隔開,寫在後面,像這樣
$ git add file1 file2
不過我們還有一個更簡單的方法,那就是.
$ git add .
這樣可以把當前目錄下全部的沒有track的文件都加進來(是不是很方便!)
刪除文件
提到添加就不得不說刪除,如果一個文件不想被跟蹤了怎麼辦呢,那就刪掉啦。
$ git rm file
注意:這個操作不會在當前目錄刪除文件
一個比較重要的flag
--force
顧名思義, 這個flag是用來強制刪除文件的。一般來說,如果你的文件沒有被commit(下面就講這個),是不可以被刪除的,但是加上這個flag就可以刪除了。
“截圖”
~~咳,實話實話,我也不知道commit怎麼準確翻譯成中文。~~現在我們來看Git非常非常重要的一個命令,commit
。它其實就是類似一個截圖,存下來你當前的項目完成情況並保存下來,以後可以回顧甚至回到當前節點。至於怎麼回到我們後面再講,現在就來進行“截圖”。這個截圖只是對於Git追蹤的文件,所以它與add是不可分割的。
$ git commit -m "Your message about the commit"
[master (root-commit) b345d9a] This is my first commit!
1 file changed, 1 insertion(+)
create mode 100644 first.txt
這樣就建了一個新的commit啦,看到這個b345d9a
東西了麼,這個是一個commit id
。但是如果你對文件進行了修改,又運行了這個語句,你會看到這麼一行Already Up to date
. Bug?Nonono, 這就是需要我們add
來參與了。因爲在Git心裏,你的文件還是上一次add
來的,他一看,文件和上一次commit
的沒有變化呀,不截圖不截圖。所以我們要重新add
一遍,這個時候的add
就是一個更新的操作了,我們每次commit
之前都要先add
再commit。
不過,這兩步某些情況下是可以合併的,變成
$ git commit -am "Your message about the commit"
這樣做就是更新我跟蹤的所有文件並進行現有成果截圖,但是如果你新建的文件還是要用單獨的add
來進行添加哦。
注意:這個語句千萬不要瞎寫哦,以後你可能會用到
分支
雖然我一直刻意沒有提到上面出現過幾次的一個詞master
,它是什麼呢,它是我們的主分支。想象一棵樹,它就是我們的樹幹。分支的作用是當你想修改某個部分的代碼,添加新功能,但卻不想影響之前寫好的代碼,就可以分出一個branch
,在上面進行。不同分支之間不會相互干擾,除非你進行合併等操作。
我們初始化一個Git倉庫時,主分支就已經存在,在此基礎上,我們可以新建自己的branch。使用
$ git branch branchName
$ git branch
* master
branchName
第一個命令是新建,第二個是列出全部分支。*表示當前所在分支。切換分支我們使用
$ git checkout branchName
$ git branch
master
* branchName
通常來說,我們新建一個分支就是爲了切換到新分支,所以我們可以把上兩步合二爲一
$ git checkout -b <my branch name>
注意:我們新建分支的內容是和你建分支時所在的一致,要注意新建分支時所在的branch哦,通常情況我們都是在master上加分支。
在進行寫代碼,修改之後,我們想把分支上內容合併至master,使用
$ git checkout master
$ git merge branchName
這裏稍微有一些饒人,我們需要在master上進行merge
操作來使得master與分支一致。現在我們來簡單講解下merge
。
假設在master上我們有幾次commit後,新建一個分支A,幾次commit之後,我們想把A合併到master上。合併之前,
common base—— — commit —— commit (master)
|— commit —— commit (A)
合併後
common base—— — commit —— commit (master) —— new merge commit
|— commit —— commit (A) ——|
這個時候master上就有了A上面的內容啦。
merge分爲兩種,一種是fast forward
, 另外一種是3-way merge
。
第一種很直接,合併前
common base—— (master)
|— commit —— commit (A)
合併後
common base—— —— new merge commit
|— commit —— commit (A) ——|
就不細講Git原理,康圖。
第二種其實就是第一個那個圖。小朋友,你是否有很多問號,爲什麼就這樣合併起來,而沒有衝突。merge的過程很容易產生的問題就是衝突!儘管Git的merge已經很nb了,但依然不可避免產生衝突,但這些我們可以很容易地解決。
衝突
這是Git裏經常遇到並且要解決的問題!當你merge不同分支時,很容易遇到。爲了讓大家直觀感受,我們創造一個衝突。
$ git checkout master
$ echo 'this is conflicted text from master' > first.txt
$ git commit -am 'added one line'
[master 8cc7111] added one line
1 file changed, 1 insertion(+)
$ git checkout branchName
Switched to branch 'branchName'
$ echo 'this is conflicted text from feature branch' > first.txt
$ git commit -am 'added one line'
[a 23f5790] added one line
1 file changed, 1 insertion(+)
$ git checkout master
Switched to branch 'master'
$ git merge branchName
Auto-merging first.txt
CONFLICT (content): Merge conflict in first.txt
Automatic merge failed; fix conflicts and then commit the result.
YES!!衝突出現了,現在我們要解決它。這個時候打開此文件
$ vim first.txt
vim是最好的text editor!
我們會看到這個
<<<<<<< HEAD
this is conflicted text from master
=======
this is conflicted text from feature branch
>>>>>>> branchName
<<<<<<<
和=======
是告訴我們哪裏有衝突,並且是哪個branch。就這個而言前第二行是master上內容而第四行則是branchName上的內容,我們選取需要內容後記得刪除135行哦!
Vim使用i
進行編輯,完成後esc
然後打:q
推出。這個時候衝突已經解決完啦,我們需要進行一次commit來結束這次的合併操作。
$ git commit -am 'solve conflict'
其他
git status
其實算是看當前分支的一個狀態吧,可以看到是否有未被追蹤的文件,有沒有變化沒有被commit。使用
$ git status
git log
簡單粗暴,顯示commit記錄,使用
$ git log
會顯示出一串commit記錄,每個包括id,作者,時間,分支,以及commit的時候的那個message。
切換到某次commit
$ git checkout specific-commit-id
這個commit id
就需要我們去git log
裏面找來,嗯就是那一長串看不懂的hash。至於你具體想切換到哪個,就看你commit的時間以及你自己寫的commit信息啦(滑稽)瞎寫的話現在就作繭自縛了嘻嘻。
結語
Git大致就講這麼多啦,想更瞭解具體的Git,闊以參考document。https://git-scm.com/doc
3. Github
不得不說Github是真的好用,造好的輪子隨便用,甚至還可以找到作業答案,當然要自己寫作業了!,而且Github推出的Github desktop是真香。使用很簡單,無師自通。言歸正傳,我們來康康Github怎麼用。
註冊及安裝
想註冊的話你需要準備的東西有:一個或多個郵箱。一個賬號可以綁定N個郵箱,然後去https://github.com/ 進行註冊。如果是學生且想免費申請Github pro可以訪問https://education.github.com/pack 。
申請完之後我們打開命令行
$ git config --global user.name "<your_name_here>"
$ git config --global user.email "<[email protected]>"
注意:寫名字時去除括號但保留引號,郵箱使用申請時的郵箱。以及,如果只是想在當前倉庫用的話,去掉global
就ok了
現在我們連接ssh到Github,這樣就可以通過ssh進行clone操作而不是http。先複製ssh key
$ pbcopy < ~/.ssh/id_rsa.pub
然後去Github網頁,點擊頭像,出現下拉菜單,點擊Settings
,在用戶設置的菜單欄選擇SSH and GPG keys
,點擊New SSH key
,在title
欄寫上你設備的名字,方便你辨認,把剛剛複製好的key複製到key
那裏。然後點擊添加,如果出現輸密碼框就輸入密碼。
新建倉庫
先去Github上建立一個新倉庫,點擊Repositories
旁New
按鈕,填寫Repo的名字後就可以確認建立。新建完後自動跳轉到這個初始頁面,在這裏我們可以看到這個倉庫的https地址,點擊旁邊的複製按鈕備用。
連接倉庫
現在,之前Git裏的操作都可以正常用了,不過效果依然存在本地,想要和雲端連接,我們需要學一些新操作。首先和remote連接
$ git remote add origin remote repository URL
這裏的URL就是上一步操作複製得到的。然後
$ git push -u origin master
運行完之後,我們就可以在Github上看到啦。每當我們想要發佈一個新的分支的時候,都需要運行這個命令,要將master改成分支的名字即可。
更新
當remote和本地的版本不一致時,我們會需要進行更新,可能是本地快於remote也可能是remote快於本地。我們使用git pull
來拉取remote的更新,使用前要記得先commit本地的版本哦。如果要更新remote版本,我們直接用git push
就可以做到了。
克隆
在Github上打開你要克隆的倉庫主頁,點擊Clone or Download,然後可以選擇用https
還是ssh
進行克隆,複製鏈接,打開命令行
$ git clone url
如果不是你的倉庫,只能使用https
哦,或者也可以選擇下載。
Github網頁
既然他是有網頁版的,那自然不能忽略網頁版提供的服務。
搜索
我要說的搜索是在頁面頂部Navigation bar裏的那個搜索框,在哪裏可以進行關鍵詞搜索,能檢索到有相關信息的公開倉庫。在搜索結果的頁面,我們可以選取特定語言(這個項目使用的語言),結果的排序方法等等。還有其他一些信息,就自己去看啦。
每個倉庫都會顯示stars
,一般來說stars
越多,認可度越高,也就越好。
關於Repo
因爲要素過多有很多內容,我就選取部分說明,其他的功能自己康康就好啦。
文件
點到自己的任意一個倉庫,我們可以直接在網上編輯文件。點開文件A,然後點擊Edit
就可以進行修改,修改完成後使用下方的commit
進行保存。也可以直接新建文件,上傳文件,刪除文件等。不過比較神奇的操作是新建文件夾。具體如下:
點擊Create New File
,在文件名的地方輸入文件夾名稱並加上/
, 神奇的事情發生了,文件夾就建好了。不過不可以建空文件夾哦,所以它會強行讓你寫一個文件名。
合作
如果想和組員共同編輯一個倉庫,我們點擊settings
,然後Manage Access
,這個時候會讓你輸入一下密碼。進去後可以修改當前倉庫權限以及邀請合作者,提供輸入合作人的Github名字來進行查找和添加。
其他
怎麼fetch一個雲端的分支(不在本地的)?
$ git checkout --track origin/daves_branch
如果不想用命令行怎麼辦?
Github Desktop你值得擁有:https://desktop.github.com/
4. 寫在最後
感謝大家看完我的廢話教程,這大概是本人多年一年的使用經常用到的部分,希望可以給你們帶來幫助。