Git&GitHub-基礎教程
目錄
- 1. Git簡介
- 1.1 什麽是版本控制系統?
- 1.2. Git的歷史
- 1.3. 什麽是分布式?什麽是集中式?
- 2. Git安裝
- 3. 創建一個版本庫
- 4. Git的語法教程
- 4.1. 提交一個文件到版本庫
- 4.2.修改文件內容並提交
- 確定倉庫狀態和更改內容後,即可提交
- 4.3. 版本回退
- (1) 回退前先多提交幾個版本
- (2). 版本回退到歷史版本
- 4.4. 工作區和暫存區
- (1)工作區
- (2)版本庫(repository)
- (3)實例演示
- 4.5. 管理修改
- 4.6. 撤銷修改
- 1)情況1:未添加到暫存區
- 2)情況2:添加到暫存區
- 4.7. 文件刪除和恢復
- 1)情況1:真的要刪除文件:
git rm
git commit
- 2)情況2:你刪錯了,想恢復這個文件:
git checkout -- text.txt
- 1)情況1:真的要刪除文件:
1. Git簡介
Git是目前世界上最先進的分布式版本控制系統
1.1 什麽是版本控制系統?
我們從一個例子入手來理解版本控制系統,我最近在寫一篇論文,每做一個更改(刪除某一段),我都要保存成一個格外的版本,例如"GAR-V1", "GAR-V2", "GAR-V3",但是等過一段時候之後,我就經常忘記我到底做了什麽修改,給我的科研進度造成了不少的困擾..
於是我想,如果有一個軟件,不但能自動幫我記錄每次文件的改動,還可以讓同事協作編輯,這樣就不用自己管理一堆類似的文件了,也不需要把文件傳來傳去。如果想查看某次改動,只需要在軟件裏瞄一眼就可以,豈不是很方便?
版本 | 文件名 | 用戶 | 用戶 | 用戶 |
---|---|---|---|---|
1 | GAR.doc | 張三 | 刪除了Introduction最後一段 | 2018.12.2 13:32 |
2 | GAR.doc | 張三 | 增加了Literature Review的第一句話 | 2018.12.6 10:21 |
3 | GAR.doc | 李四 | 調整了Table1 的數據 | 2018.12.13 17:21 |
1.2. Git的歷史
Linux誕生(1991)->Linux手動收集開源代碼(2002)->BitKeeper版本控制系統托管Linux(2002-2005)->Andrew試圖破解BitKeeper被發現,BitKeeper收回免費托管權(2005)->Linux自己寫了Git,也就是Git的誕生(2005)
1.3. 什麽是分布式?什麽是集中式?
集中式:
集中式版本控制系統,版本庫是集中存放在中央服務器的,而幹活的時候,用的都是自己的電腦,所以要先從中央服務器取得最新的版本,然後開始幹活,幹完活了,再把自己的活推送給中央服務器。
集中式的缺點
集中式版本控制系統最大的毛病就是必須聯網才能工作,如果在局域網內還好,帶寬夠大,速度夠快,可如果在互聯網上,遇到網速慢的話,可能提交一個10M的文件就需要5分鐘
分布式:
分布式版本控制系統根本沒有“中央服務器”,每個人的電腦上都是一個完整的版本庫,這樣,你工作的時候,就不需要聯網了,因為版本庫就在你自己的電腦上。既然每個人電腦上都有一個完整的版本庫,那多個人如何協作呢?比方說你在自己電腦上改了文件A,你的同事也在他的電腦上改了文件A,這時,你們倆之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。
在實際使用分布式版本控制系統的時候,其實很少在兩人之間的電腦上推送版本庫的修改,因為可能你們倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。因此,分布式版本控制系統通常也有一臺充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣幹活,只是交換修改不方便而已。
分布式優點
- 安全性高: 每個人電腦裏都有完整的版本庫,某一個人的電腦壞掉了不要緊,隨便從其他人那裏復制一個就可以了
- 免費
2. Git安裝
先從Git官網下載安裝程序,然後默認安裝就可以了
安裝完成後,在開始菜單裏找到“Git”->“Git Bash”,蹦出一個類似命令行窗口的東西,就說明Git安裝成功!
安裝完成後,還需要最後一步設置,在命令行輸入:
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
3. 創建一個版本庫
什麽是版本庫呢?版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄裏面的所有文件都可以被Git管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。
創建一個版本庫非常簡單,首先,選擇一個合適的地方,創建一個空目錄,通過git init
命令把這個目錄變成Git可以管理的倉庫
$ git init
Initialized empty Git repository in D:/git_test/.git/
瞬間Git
就把倉庫建好了,而且告訴你是一個空的倉庫(empty Git repository)
,細心的讀者可以發現當前目錄下多了一個.git
的目錄,這個目錄是Git
來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裏面的文件,不然改亂了,就把Git
倉庫給破壞了。
4. Git的語法教程
4.1. 提交一個文件到版本庫
先在剛剛創建好的repository下(D:/git_test)創建一個readme.txt
文件,內容如下:
Git is a version control system.
Git is free software.
提交新添加的文件到倉庫只需要兩步:添加(add) + 提交(commit)
第一步: 用命令git add filename.txt
告訴Git,把文件添加到repository:
$ git add readme.txt
第二步: 用命令git commit -m "description"
告訴Git,把文件提交到倉庫
$ git commit -m "write to readme"
[master (root-commit) f7f8050] write to readme
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
git commit
命令執行成功後會告訴你,1 file changed
1個文件被改動(我們新添加的readme.txt文件);2 insertions:
插入了兩行內容(readme.txt有兩行內容)。
為什麽Git添加文件需要add和commit兩步?
因為commit
可以一次提交很多文件,所以你可以多次add
不同的文件
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
4.2.修改文件內容並提交
現在我們修改一下readme.txt文件內容為:
Git is a version control system.
Git is wonderful.
Git is free software.
現在我們可以通過git status
來查看結果:
$ 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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
git status
命令可以讓我們時刻掌握倉庫當前的狀態,上面的命令輸出告訴我們,readme.txt被修改過了,但還沒有準備提交的修改。
查看具體修改內容: 使用命令git diff
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index d8036c1..6e4b78e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,3 @@
-Git is a version control system.
+Git is wonderful.
-Git is free software.
\ No newline at end of file
上面顯示我們新添加了一行文字
確定倉庫狀態和更改內容後,即可提交
第一步: add
$ git add readme.txt
查看repository狀態:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
上面告訴我們,將要提交的修改包括readme.txt
第二步:commit
$ git commit -m "add new line"
[master 4fb84da] add new line
1 file changed, 1 insertion(+)
查看repository狀態:
$ git status
On branch master
nothing to commit, working tree clean
4.3. 版本回退
(1) 回退前先多提交幾個版本
我們先重復修改幾次文本並提交
Git is a version control system.
Git is wonderful.
GitHub my lover.
然後提交:
$ git add readme.txt $ git commit -m "delete software" [master 1094adb] delete software 1 file changed, 1 insertion(+), 1 deletion(-)
現在讓我們來想一下到底有幾個版本被提交到倉庫中了:
但是我們在實際工作中,無法記住這麽多版本,我們可以通過命令git log
來查看歷史記錄
$ git log
commit 5103166639e21fa3c8884f890ec53c0c4541f6d4 (HEAD -> master)
Author: haoch <[email protected]>
Date: Thu Jan 3 13:19:54 2019 +0900
delete software
commit 9fbb43595b5aee1773fdd2db42427d9af9275db0
Author: haoch <[email protected]>
Date: Thu Jan 3 13:19:28 2019 +0900
github infor
commit 4fb84da7882c74cc6dbd0b22ee64d8cf366e6a64
Author: haoch <[email protected]>
Date: Thu Jan 3 13:15:00 2019 +0900
add new line
commit f7f80507a255a347a92117ff3bb75ddca837b91a
Author: haoch <[email protected]>
Date: Thu Jan 3 12:25:06 2019 +0900
write to readme
我們也可以通過另外一個命令來簡化歷史記錄的顯示git log --pretty=oneline
$ git log --pretty=oneline
5103166639e21fa3c8884f890ec53c0c4541f6d4 (HEAD -> master) delete software
9fbb43595b5aee1773fdd2db42427d9af9275db0 github infor
4fb84da7882c74cc6dbd0b22ee64d8cf366e6a64 add new line
f7f80507a255a347a92117ff3bb75ddca837b91a write to readme
(2). 版本回退到歷史版本
現在-》過去
在Git中,HEAD
表示當前版本, ‘HEAD^‘表示上一個版本, ‘HEAD^^‘表示上上一個版本, HEAD~10
表示第前10個版本
現在,我們需要把當前版本delete software
回退到 github infor
$ git reset --hard HEAD^
HEAD is now at 9fbb435 github infor
我們在來看看歷史記錄git log
$ git log
commit 9fbb43595b5aee1773fdd2db42427d9af9275db0 (HEAD -> master)
Author: haoch <[email protected]>
Date: Thu Jan 3 13:19:28 2019 +0900
github infor
commit 4fb84da7882c74cc6dbd0b22ee64d8cf366e6a64
Author: haoch <[email protected]>
Date: Thu Jan 3 13:15:00 2019 +0900
add new line
commit f7f80507a255a347a92117ff3bb75ddca837b91a
Author: haoch <[email protected]>
Date: Thu Jan 3 12:25:06 2019 +0900
write to readme
過去-》現在
其中已經沒有了版本號delete software
,好比你從21世紀坐時光穿梭機來到了19世紀,想再回去已經回不去了,腫麽辦?
辦法其實還是有的,只要上面的命令行窗口還沒有被關掉,你就可以順著往上找啊找啊,找到那個delete software
的commit id是510316...,於是就可以指定回到未來的某個版本:
$ git reset --hard 510316
HEAD is now at 5103166 delete software
當你把電腦也關了,第二天起來想回到delete software
版本怎麽辦?可以使用git reflog
來查看每個提交的commit id
在用以上的方法即可
$ git reflog
5103166 (HEAD -> master) HEAD@{0}: reset: moving to 510316
9fbb435 HEAD@{1}: reset: moving to HEAD^
5103166 (HEAD -> master) HEAD@{2}: commit: delete software
9fbb435 HEAD@{3}: commit: github infor
4fb84da HEAD@{4}: commit: add new line
f7f8050 HEAD@{5}: commit (initial): write to readme
HEAD的作用
相當於C語言中的指針一樣
4.4. 工作區和暫存區
(1)工作區
就是你在電腦裏能看到的目錄, 例如我的git_test
文件夾
(2)版本庫(repository)
工作區有一個隱藏目錄.git
,這個不算工作區,而是Git的版本庫。
Git的版本庫裏存了很多東西,其中最重要的就是稱為stage(或者叫index)
的暫存區,還有Git為我們自動創建的第一個分支master
,以及指向master
的一個指針叫HEAD
。
前面講了我們把文件往Git版本庫裏添加的時候,是分兩步執行的:
git add
把文件添加進去,實際上就是把文件修改添加到暫存區;
git commit
提交更改,實際上就是把暫存區的所有內容提交到當前分支。
為我們創建Git版本庫時,Git自動為我們創建了唯一一個master
分支,所以,現在,git commit
就是往master
分支上提交更改。
(3)實例演示
讓我們通過一個例子來演示工作區和版本庫的作用
先對readme.txt
進行一些更改為加一段文字I come from China:
Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
然後在工作區新增一個名字為license.txt
文件,內容隨意
用git status
查看狀態
$ 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: readme.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
license.txt
no changes added to commit (use "git add" and/or "git commit -a")
上面告訴我們:readme.txt
被修改了,但是licese.txt
因為沒有被添加,所以是無法跟蹤的untracked
我們通過add
將兩個文件都添加後再查看狀態:
$ git add readme.txt license.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: license.txt
modified: readme.txt
現在暫存區的狀態就變成這樣了:
git add
就是把所有的修改都放到暫存區中,然後執行一次git commit
就可以一次性把暫存區的所有修改提交到分支
$ git commit -m "how it works"
[master 45700b2] how it works
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 license.txt
一旦提交後,如果你又沒有對工作區做任何修改,那麽工作區就是“幹凈”的:
$ git status
On branch master
nothing to commit, working tree clean
現在暫存區就是這樣的:
4.5. 管理修改
修改readme.txt
內容為添加一行:
I love China
通過git add
添加
再次修改修改readme.txt
內容為添加一行:
Do you like China?
再通過git commit
提交,在查看狀態
$ 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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
讓我們來回顧一下:
第一次修改 -> git add
-> 第二次修改 -> git commit
Git管理的是修改,當你用git add
命令後,在工作區的第一次修改被放入暫存區,準備提交,但是,在工作區的第二次修改並沒有放入暫存區,所以,git commit
只負責把暫存區的修改提交了,也就是第一次的修改被提交了,第二次的修改不會被提交。
提交後,用git diff HEAD -- readme.txt
命令可以查看工作區和版本庫裏面最新版本的區別:
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 812e617..d5258f9 100644
--- a/readme.txt
+++ b/readme.txt
@@ -2,4 +2,5 @@ Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
-I love China
\ No newline at end of file
+I love China
+Do you love china?
\ No newline at end of file
第二次修改確實沒有被提交。
如何提交第二次修改
第一次修改 -> git add
-> 第二次修改 ->git add
-> git commit
4.6. 撤銷修改
比如說你的文件裏面加了一段不好的話,你想刪除他的方法:
Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
I love China
Do you love china?
My stupid techer
此時,你可以使用以下命令來丟棄工作區的修改:
$ git checkout -- readme.txt
命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作區的修改全部撤銷,這裏有兩種情況:
一種是
readme.txt
自修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;一種是
readme.txt
已經添加到暫存區後,又作了修改,現在,撤銷修改就回到添加到暫存區後的狀態。
總之,就是讓這個文件回到最近一次git commit
或git add
時的狀態。
1)情況1:未添加到暫存區
現在再來看readme.txt
的內容:
Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
I love China
2)情況2:添加到暫存區
加入你在commit
之前發現了這個問題,可以用以下命令撤銷暫存區的修改
git reset HEAD <file>
就是把暫存區的修改退回到工作區
然後在工作區中使用情況1中的命令來刪除修改
$ git checkout -- readme.txt
再次查看時候,已經回到了原來的版本了
Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
I love China
4.7. 文件刪除和恢復
Git是管理修改的,刪除也是一種修改,也可以被管理
在工作區新建一個文件 text.txt
並且添加提交
$ git add text.txt
$ git commit -m "add text.txt"
[master b84166e] add text.txt
1 file changed, 1 insertion(+)
create mode 100644 text.txt
一般情況下,你通常直接在文件管理器中直接把文件刪除了
$ rm text.txt
Git知道你刪除了文件,因此,工作區和版本庫就不一致了,git status
命令會立刻告訴你哪些文件被刪除了:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: text.txt
no changes added to commit (use "git add" and/or "git commit -a")
1)情況1:真的要刪除文件:git rm
-> git commit
$ git rm text.txt
rm ‘text.txt‘
$ git commit -m "remove text.txt"
[master 1f108b4] remove text.txt
1 file changed, 1 deletion(-)
delete mode 100644 text.txt
2)情況2:你刪錯了,想恢復這個文件:git checkout -- text.txt
git checkout
其實是用版本庫裏的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。
Git&GitHub-基礎教程