1. 程式人生 > >Git&GitHub-基礎教程

Git&GitHub-基礎教程

輸出 1.2 撤銷 auth ini diff ftw hang out

目錄

  • 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. 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 changed1個文件被改動(我們新添加的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 commitgit 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-基礎教程