從小白到大神-一文教你如何使用Git和Github

目錄

前言

Git教程

Git安裝(Windows環境)

理論基礎

實戰教程

初始化Git

查看當前狀態

回到過去

版本對比

修改最後一次提交、刪除文件和重命名文件

創建和切換分支

合併和刪除分支

Github教程

創建倉庫

分支

分支的含義

創建一個分支

提交修改

發起Pull request操作


前言

作爲一個程序員!怎麼能Github也不認識呢!沒錯,在寫這篇博客前我對Github的瞭解就是一個Copy代碼的倉庫,根本沒想過在裏面搞一個自己的倉庫,現在我來了,因爲我再也不想用文件夾去做版本控制了,這不符合我一個極客的身份!!!

Git教程

Git安裝(Windows環境)

下載地址:Git官方下載地址

> git config --global user.name "FishC_Service"
> git config --global user.email "[email protected]"
#檢查信息是否寫入成功
git config --list #如果正常顯示信息則成功

理論基礎

保存機制:當版本中有文件發生變動,Git會將整個文件複製保存。

執行 git log --oneline --decorate --graph --all 命令:

三棵樹的概念:工作區域(本機存放項目代碼的地方),暫存區域(臨時存放你的改動,保存即將提交的文件信息列表),Git倉庫(安全存放數據,包含所有版本的數據,其中HEAD指向最新放入倉庫的版本)

工作流程:在工作目錄中添加修改文件---將需要進行版本管理的文件放入暫存區域---將暫存區域的文件提交Git倉庫

實戰教程

初始化Git

#初始狀態在C盤中,更改路徑
C:\Users\lenovo>F:
F:\>
F:\>cd MyProject
F:\MyProject>
#初始化Git項目,成功後創建有一個.git隱藏文件
F:\MyProject>git init
Initialized empty Git repository in F:/MyProject/.git/
#在文件夾MyProject中添加一個文本文件README,md格式指Markdown格式(建議使用Notepad++編輯)
#然後輸入以下命令將文件加入暫存區
F:\MyProject>git add README.md
#將文件提交到git倉庫(-m表示添加本次提交的說明,強制要求寫的)
F:\MyProject>git commit -m "add a readme file"
[master (root-commit) 9e08cf4] add a readme file
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

小貼士:如何將Github上別人的代碼據爲己有

F:\>Clone>git clone 目標

查看當前狀態

On branch master: 我們位於一個叫做“master”的分支裏,這是默認的分支
nothing to commit, working directory clean : 說明你的工作目錄目前是“乾淨的”,沒有需要提交的文件(意思就是自上次提交後,工作目錄中的內容壓根兒就沒改動過)。

在工作目錄中添加LICENSE文件,使用NotePad++添加MIT協議(意味着別人只要在軟件包含上邊的版權聲明,就可以對你的程序爲所欲爲了(包括“使用、複製、修改、合併、出版發行、散佈、再授權和/或販售軟件及軟件的副本”)。)

Copyright (C) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

輸入git status,提示如下:

F:\MyProject>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        LICENSE(紅色)

nothing added to commit but untracked files present (use "git add" to track)

Untracked表示存在未跟蹤文件(紅色標識),指的是新添加且未被添加至暫存區域的文件。圓括號是git給的建議。

使用 git add <file> 命令將待提交的文件添加到暫存區域。

F:\MyProject>git add LICENSE

F:\MyProject>git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   LICENSE(綠色)

use "git reset HEAD <file>..." to unstage 的意思是“如果你反悔了,你可以使用 git reset HEAD 命令恢復暫存區域”。如果後面接文件名,表示恢復該文件;如果不接文件名,則表示上一次添加的文件。

F:\MyProject>git reset HEAD

F:\MyProject>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        LICENSE(紅色)

nothing added to commit but untracked files present (use "git add" to track)

再次添加到暫存區域,然後執行 git commit -m "add a license file" 命令:

F:\MyProject>git add LICENSE

F:\MyProject>git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   LICENSE


F:\MyProject>git commit -m "add a license file"
[master 9fdf9f4] add a license file
 1 file changed, 7 insertions(+)
 create mode 100644 LICENSE

F:\MyProject>git status
On branch master
nothing to commit, working tree clean

修改文件

打開 LICENSE 文件,將 Copyright (C) <year> <copyright holders> 改爲 Copyright (C) 2016 FishC,保存……

執行 git status 命令:

F:\MyProject>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:   LICENSE(紅色)

no changes added to commit (use "git add" and/or "git commit -a")

由於你對工作目錄的文件進行了修改,導致這個文件和暫存區域的對應文件不匹配了,所以 Git 又給你提出兩條建議:

  1. 使用 git add 命令將工作目錄的新版本覆蓋暫存區域的舊版本,然後準備提交
  2. 使用 git checkout 命令將暫存區域的舊版本覆蓋工作目錄的新版本(危險操作:相當於丟棄工作目錄的修改)

一種特殊情況,先對新版本進行提交,然後再次修改LICENSE文件內容

F:\MyProject>git add LICENSE

F:\MyProject>git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   LICENSE(綠色)
F:\MyProject>git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   LICENSE(綠色)

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:   LICENSE(紅色)

這次情況是:被綠的 LICENSE 說明文件存放在暫存區域(待提交),同時紅色的 LICENSE 說明文件還在工作目錄等待添加到暫存區域。

這種情況你應該意識到這裏存在兩個不同版本的 LICENSE 文件,這時如果你直接執行 commit 命令,那麼提交的是暫存區域的版本(FishC),如果你希望提交工作目錄的新版本(FishC.com),那麼你需要先執行 add 命令覆蓋暫存區域,然後再提交……

當然有一步到位的操作

F:\MyProject>git commit -am "change the license file"
# -a的意思就是add操作

小貼士:如何查看歷史操作記錄和倉庫提交的版本

git log

回到過去

有關退回的命令有兩個:reset和checkout

先執行git log命令,將此時Git倉庫可視化

三棵樹的可視化

回滾快照

註釋:快照即提交的版本,每個版本就是一個快照

執行:git reset HEAD~

註釋:HEAD 表示最新提交的快照,而 HEAD~ 表示 HEAD 的上一個快照,HEAD~~表示上上個快照,如果表示上10個快照,則可以用HEAD ~10

此時我們的快照回滾到了暫存區域,第一次執行reset命令後的倉庫和三棵樹可視化如下所示

git reset HEAD~ 命令其實是 git reset --mixed HEAD~ 的縮寫, --mixed 選項是默認的。

  • 默認
  • git reset HEAD~ 命令其實影響了兩棵樹:首先是移動 HEAD 的指向,將其指向上一個快照(HEAD~);然後再將該位置的快照回滾到暫存區域。
  • --soft選項
  • git reset --soft HEAD~ 命令就相當於只移動 HEAD 的指向,但並不會將快照回滾到暫存區域。相當於撤消了上一次的提交(commit)。一不小心提交了,後悔了,那麼你就執行 git reset --soft HEAD~ 命令即可(此時執行 git log 命令,也不會再看到已經撤消了的那個提交)。
  • --hard選項
  • reset 不僅移動 HEAD 的指向,將快照回滾動到暫存區域,它還將暫存區域的文件還原到工作目錄。

回滾指定快照

reset 不僅可以回滾指定快照,還可以回滾個別文件。

命令格式爲: git reset 快照 文件名/路徑

這樣,它就會將忽略移動 HEAD 的指向這一步(因爲你只是回滾快照的部分內容,並不是整個快照,所以 HEAD 的指向不應該發生改變),直接將指定快照的指定文件回滾到暫存區域。

不僅可以往回滾,還可以往前滾!

這裏需要強調的是:reset 不僅是一個“復古”的命令,它不僅可以回到過去,還可以去到“未來”。

唯一的一個前提條件是:你需要知道指定快照的 ID 號。

那如果不小心把命令窗口關了不記得ID號怎麼辦?

git reflog #Git記錄的每一次操作的版本ID號

版本對比

準備工作:創建MyProject2新文件夾,初始化Git;創建game.py文件,寫入內容;創建README.md文件,寫入內容;執行 git add README.md game.py 命令將文件添加到暫存區域,接着執行 git commit -m "猜數字遊戲" 提交項目的第一個快照;修改game.py和README文件內容;

比較暫存區域和工作目錄

直接執行 git diff 命令是比較暫存區域與工作目錄的文件內容:

這裏可能出現一個問題,直接執行的結果出現中文亂碼。在cmd界面的冒號:後面輸入q退出,使用Notepad++打開README文件,點擊編碼→轉爲UTF-8編碼。(舊版本中選擇UTF-8(無BOM),新版中的UTF-8默認爲無BOM)重新執行git diff發現還是不行!怎麼肥四??在本菜查遍各網站論壇之後,終於找到了解決方法
執行以下三條命令(別問我明明是四條爲啥說三條...)
git config --global i18n.commitencoding utf-8
git config --global i18n.logoutputencoding utf-8

export LESSCHARSET=utf-8 ## linux bash配置環境變量
set LESSCHARSET=utf-8 #windows配置環境變量
git diff

現在來解釋一下上面每一行的含義:

  • 第一行:diff --git a/README.md b/README.md
  • 表示對比的是存放在暫存區域的 README.md 和工作目錄的 README.md
  • 第二行:index 7966837..472a180 100644
  • 表示對應文件的 ID 分別是 7966837 和 472a180,左邊暫存區域,後邊當前目錄。最後的 100644 是指定文件的類型和權限
  • 第三行:--- a/README.md
  • --- 表示該文件是舊文件(存放在暫存區域)
  • 第四行:+++ b/README.md
  • +++ 表示該文件是新文件(存放在工作區域)
  • 第五行:@@ -1 +1,2 @@
  • 以 @@ 開頭和結束,中間的“-”表示舊文件,“+”表示新文件,後邊的數字表示“開始行號,顯示行數”
  • 第六、七行:

  • 這是將兩個文件合併顯示的結果,前邊有個 + 的綠色的那一行說明是新文件獨有的,淺灰色的則是兩個文件所共有的內容。所以,+1,2 表示新文件在合併顯示中從第 1 行開始,顯示 2 行。那爲啥 -1 後邊沒有顯示的行數?因爲在合併顯示的結果中,舊文件已經完全包含在新文件中了(也就是舊文件沒有自己“獨有的”內容)。
  • 第八行:\ No newline at end of file
  • 這是 Git 出於善意的提醒:文件不是以換行符結束。爲什麼會有這樣多此一舉的提醒呢?仔細推敲下你就會明白了:diff 將兩個文件合併打印,到達最後一個字符的時候,無論文件中是否存在換行符,diff 都需要打印一個換行符!爲啥?爲了好看唄!!所以如果你的文件最後一個字符不是以換行符結尾,但 diff 又自行添加了一個換行符,所以它覺得有義務提醒你它這麼做了!

最後的(:)是什麼?
意思是窗口太小,沒辦法顯示全部,正在等待命令(Vim編程知識)

移動命令
j、k:向下移動一行/向上移動一行
f、b:向下翻頁/向上翻頁
d、u:向下翻半頁/向上翻半頁
跳轉命令
g、G:跳轉到第一行/跳轉到最後一行
先輸入數字(如3),再輸入g,表示跳轉到該行(如第3行)
搜索命令
輸入斜槓(/)或問號(?),後面接搜索關鍵字
區別:斜槓(/)表示從當前位置向下搜索,問號(?)表示從當前位置向上搜索。
接着輸入 n 表示順着當前的搜索方向快速跳轉到下個匹配的位置,大寫的 N 則是與當前搜索方向相反。
退出和幫助
在點點(:)後邊輸入 q,表示退出 diff;輸入 h 表示進入幫助界面,你會看到很多命令和功能,輸入 q 可以退出幫助界面。

比較歷史快照

我們執行 git commit -am "添加功能:玩家只有三次機會" 命令,添加並提交工作目錄中的所有文件。執行 git log 命令,可以看到現在 Git 倉庫中已經有兩個快照了:

執行 git diff 6e26975 ed3708c 命令,即可比較 Git 倉庫中兩個快照的差異:

比較當前工作目錄和Git倉庫中的快照

準備工作:稍微改動README.md內容,可視化Git倉庫及三棵樹

比較之前版本的快照與當前工作目錄內容
輸入 git diff ed3708c 命令即可

比較當前版本快照與當前工作目錄內容
輸入 git diff HEAD 命令即可

比較Git倉庫與暫存區域

準備工作:執行 git add README.md 命令,將第三版的 README.md 文件添加到暫存區域。可視化三棵樹

比較最新提交的快照和暫存區域的文件,只需要執行 git diff --cached 命令;當然也可以指定其他快照,就是需要多寫上一個 ID 值,即git diff --cached ID號。

小總結

修改最後一次提交、刪除文件和重命名文件

Situation One:版本剛一提交(commit)到倉庫,突然想起漏掉兩個文件還沒有添加(add)
Situation Two:版本剛一提交(commit)到倉庫,突然想起版本說明寫得不夠全面,無法彰顯你本次修改的重大意義……

由於使用reset命令過於繁瑣,需要提交一個新的版本,這裏可以使用帶 --amend 選項的 commit 命令,(即git commit --amend)Git 會“更正”最近的一次提交。由於這裏沒有-m說明,會進入以下頁面:

這個界面其實只是讓你編輯提交說明而已。如果不需要修改,可以連續按下兩個大寫Z來退出,或者按下(:)再輸入q!退出,Git會保留舊的提交說明。如果需要提交說明又不想用這麼繁瑣的方式,輸入git commit --ammend -m “新的提交說明” 即可。

刪除文件

問題1:不小心刪除工作目錄中的文件怎麼辦?先查看狀態

提醒使用 checkout 命令可以將暫存區域的文件恢復到工作目錄。

問題2:如何徹底刪除文件(假設你下載了一個圖片到工作目錄,又提交到了倉庫)

執行 git rm 圖片名,此時工作目錄中的圖片被刪除,但Git status中依舊存在記錄

意思是說它在倉庫的快照中發現有個叫 yellow 的東西,但似乎在暫存區域和當前目錄不見了!此時可以執行 git reset --soft HEAD~ 命令將快照回滾到上一個位置,然後重新提交,就可以了。

注意:rm 命令刪除的只是工作目錄和暫存區域的文件(即取消跟蹤,在下次提交時不納入版本管理)

問題3:我在工作目錄中增加一個 test.py 文件,然後執行 git add test.py 命令將其添加到暫存區域,此時我修改 test.py 文件的內容,那麼暫存區域和工作目錄就是兩個不同的 test.py 文件了,此時如果我執行 git rm test.py 命令,Git 會下意識地阻止我,這是怎麼辦?

 

因爲兩個不同內容的同名文件,誰知道你是不是搞清楚了都要刪掉?還是提醒一下好,別等一下出錯了又要賴機器……
根據提示,執行 git rm -f test.py 命令就可以把兩個都刪除。

問題4:我只想刪除暫存區域的文件,保留工作目錄的,應該怎麼操作?

執行 git rm --cached 文件名 命令。

重命名文件:git ren 舊文件名 新文件名

小貼士:如何讓Git 識別某些格式的文件,然後自主不跟蹤它們?

比如工作目錄中有三個文件1.temp、2.temp 和 3.temp,我們不希望後綴名爲 temp 的文件被追蹤,可是每次執行git status都會出現:

解決辦法:在工作目錄創建一個名爲 .gitignore 的文件。windows需要在命令行窗口創建(.)開頭的文件。執行 echo *.temp > .gitignore 命令,創建一個 .gitignore 文件,並讓 Git 忽略所有 .temp 後綴的文件(gitignore文件夾也可以忽略):

創建和切換分支

來到之前創建的MyProject2,對應的倉庫和三棵樹如下

執行git status發現README.md還沒有提交,對應三棵樹如下

創建分支:git branch feature

註釋:查看分支狀況,如果希望以“精簡版”的方式顯示,可以加上一個 --oneline 選項(即 git log --decorate --oneline),這樣就只用一行來顯示一個快照記錄。

可以看到最新的快照後邊多了一個 (HEAD -> master, feature),它的意思是:目前有兩個分支,一個是主分支(master),一個是剛纔我們創建的新分支(feature),然後 HEAD 指針仍然指向默認的 master 分支。

切換分支 git checkout feature

現在我們進行一次提交,暫存區(上文)還有一個README文件沒有提交

切換HEAD指針回master分支 git checkout master,會發現上一次修改已經沒有了

現在對 README.md 文件進行修改(隨便改改),然後執行 git commit -m "再次修改說明文件":

執行 git log --oneline --decorate --graph --all 命令(--graph 選項表示讓 Git 繪製分支圖,--all 表示顯示所有分支)

合併和刪除分支

合併分支:git merge feature,將 feature 分支合併到 HEAD 所在的分支(master)上,但並不成功,因爲合併README文件有衝突

然後 Git 會在有衝突的文件中加入一些標記,不信你打開 README.md 文件看看:

以“=======”爲界,上到“<<<<<<< HEAD”的內容表示當前分支,下到“>>>>>>> feature”表示待合併的 feature 分支,之間的內容就是衝突的地方。現在我們將 README.md 統一修改(去掉 <<<<<<< HEAD 等內容)
保存文件,然後提交快照:

執行git log --decorate --all --graph --oneline 命令,可以看到此時的分支已經自動合併了:

當然,不存在矛盾的話就無需修改,執行 git checkout -b feature2 命令(相當於 git branch feature2 和 git checkout feature2 兩個命令的合體),在工作目錄中隨便創建一個feature2.txt文件並提交快照(可以看到,feature2 分支比 master 分支快了一步。現在我們切換回 master 分支,並將 feature2 分支合併進來:)

刪除分支:git branch -d feature

註釋:注意:如果試圖刪除未合併的分支,Git 會提示你“該分支未完全合併,如果你確定要刪除,請使用 git branch -D 分支名 命令。

小貼士

cheakout命令功能:從快照或暫存區域中拷貝文件到工作目錄;切換分支

比如執行 git checkout HEAD~ README.md 命令會將上一個快照中的 README.md 文件複製到工作目錄和暫存區域中:

如果命令中沒有指定具體的快照 ID,則將從暫存區域恢復指定文件到工作目錄(git checkout README.md):

 

checkout和reset的區別(reset老老實實做撤銷,checkout老老實實做切換分支,不要互相搞混!!!)

恢復文件:它們的區別是 reset 命令只將指定文件恢復到暫存區域(--mixed),而 checkout 命令是同時覆蓋暫存區域和工作目錄。

恢復快照:reset 命令是用來“回到過去”的,根據選項的不同,reset 命令將移動 HEAD 指針(--soft) -> 覆蓋暫存區域(--mixed,默認)-> 覆蓋工作目錄(--hard)。

對於 reset --hard 命令來說,checkout 命令更安全。因爲 checkout 命令在切換分支前會先檢查一下當前的工作狀態,如果不是“clean”的話,Git 不會允許你這樣做;而 reset --hard 命令則是直接覆蓋所有數據。另一個區別是如何更新 HEAD 指向,reset 命令會移動 HEAD 所在分支的指向,而 checkout 命令只會移動 HEAD 自身來指向另一個分支。例如(圖1爲原始狀態):


Github教程

創建倉庫

倉庫是用來組織項目的,可以存放項目所需要的任何內容。我們推薦你在項目中包含一個 README 文件,或者建立一個可以查看項目信息的文件。在 GitHub 上,一旦你創建一個新的倉庫,就可以很容易地創建一個 README 文件和 license 文件(用於聲明版權)。

分支

分支的含義

創建一個分支

提交修改

針對readme-edit分支中的文件進行修改,這些修改隻影響了 readme-edits 分支的 README 文件,而 master 的 README 文件並沒有被改變,所以現在兩個分支的內容已經不同了。

發起Pull request操作

現在你擁有一個非 master 分支的修改,你可以發起一個 pull request。
Pull Requests 是 GitHub 實現合作的核心。當你發起一個 pull request 的時候,表示你希望別人將你修改的內容進行審查然後合併到他們的分支中去。
Pull Requests 會顯示每個分支的不同之處,添加(綠色)和刪減(紅色)的地方都會顯示出來。
只要執行一次提交,就可以開啓一個 pull request 和討論,不需要你將所有的代碼都完成。
通過使用 GitHub 的 @ 通知系統,你可以獲得指定小夥伴或團隊(無論他們身在何處)對 pull requset 的反饋消息。
你也可以在自己的倉庫中開啓 pull requests 並將它們合併進來。這是你在進行大項目開發前先熟悉 GitHub 流程的好方法。

比較對象和查看內容

合併修改(給你的合併操作加一些說明)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章