The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

Git 學習筆記 (1):安裝、選項設定、在本地使用 Git 工具

之前常想,Git 這麼複雜的東西,怎麼國外這麼多人在用啊?今天徹底研究了一番之後發現,Git 真的比 SVN 強大太多,只是分散式版控機制確實跟自己以往熟悉的 SVN 或 TFS 差好多,用舊有的思維模式 (Mindset) 學習新技術還真的有點辛苦,今天算是重新打造全新的思維模式,收穫還不少。這篇文章是我 Git 學習筆記的第一篇,寫了十幾個小時,洋洋灑灑的印出來應該也有幾十頁,還覺得很多東西沒講清楚,歡迎各位留言大家一起學習囉! (^_^)

§ Git 工具安裝 ( Windows ) §

要安裝 Git for Windows 可以先到以下網站下載並安裝:

以下是 msysGit 在 GitHub 上面的專案網址:

安裝好之後,所有文件會有一���離線版,資料夾路徑如下:

  • C:\Program Files (x86)\Git\doc\git\html

安裝 Git for Windows 時,安裝到 Adjusting your PATH environment 步驟時,請選擇 Run Git from the Windows Command Prompt 這個選項,相容性比較高,問題也會少很多:

 

或者,你也可以直接安裝 GitHub for Windows 工具,他有內建一個以 Windows PowerShell 為主的 Git Shell 執行環境,已內建 Git for Windows 工具。另外,微軟也有推出 Visual Studio Tools for Git 擴充套件,不過安裝這套的基本要求是要要事先安裝 Visual Studio 2012Visual Studio 2012 Update 3 才行。我則是三套都裝了:

 

本篇文章會以 Git for Windows 指令列工具為主。

 

§ Git 工具的選項設定 §

 

設定 Git 執行環境的三個層級 ( : 執行 git config --help 可以取得完整指令說明 )

  • 系統層級 (System-level configuration) (設定於整台電腦,所有使用者的預設值)
  • 使用者層級 (User-level configuration) (設定於目前登入的使用者)
    • git config --global --list
    • 預設路徑: C:\Users\<使用者帳號>\.gitconfig      (這是個檔案)
    • 常用指令
      • 最常見的設定就是 user 區段下的 name 與 email 參數,第一次用 Git 一定要設定!
        • git config --global user.name "John Doe"
        • git config --global user.email "johndoe@example.com"
      • 在 Linux 底下可以指定編輯器
        • git config --global core.editor vim
      • 在Windows底下,最好打開 core.autocrlf 選項,讓 commit 的檔案沒有 CR 字元
        ( 純 Windows 開發環境,可以設定為 false;跨平台協同開發,建議設定為 true )
        • git config --global core.autocrlf true
      • 自動訂正打錯的參數,例如 git statsu 會自動修正為 git status 讓你不用重打一次
        • git config --global help.autocorrect 1
  • 儲存區層級 (Repository-level configuration)
    • git config --list
    • 預設路徑: <Git儲存區>\.git\config

Git 執行環境中,三個不同設定層級的套用順序

  • 儲存區層級 (優先權最高) > 使用者層級 > 系統層級 (優先權最低)
  • 使用 git config --list 取出參數時,會顯示所有層級的參數,但越下方的參數優先權越高。
    如下範例,user.email 出現過兩次,下方的 user.email 將會被套用 (因為它定義在儲存區層級)
    G:\GitRepo>git config --list
    core.symlinks=false
    core.autocrlf=true
    color.diff=auto
    color.status=auto
    color.branch=auto
    color.interactive=true
    pack.packsizelimit=2g
    help.format=html
    http.sslcainfo=/bin/curl-ca-bundle.crt
    sendemail.smtpserver=/bin/msmtp.exe
    diff.astextplain.textconv=astextplain
    rebase.autosquash=true
    user.name=John Doe
    user.email=johndoe@example.com
    help.autocorrect=1
    core.autocrlf=true
    core.filemode=false
    core.bare=false
    core.logallrefupdates=true
    core.symlinks=false
    core.ignorecase=true
    core.hidedotfiles=dotGitOnly
    user.email=
  • 取得特定選項的值 (這就是最終套用各層級參數的結果)
    • git config user.name
    • git config user.email
  • 刪除特定選項的值 (會從設定檔中移除該設定)
    • git config --unset user.email            (刪除儲存區層級的設定值)
    • git config --global --unset user.email   (刪除使用者層級的設定值)
  • 除了透過指令設定外,其實你也可以直接透過 Notepad 編輯設定檔
    • 系統層級預設路徑: C:\Program Files (x86)\Git\etc\gitconfig
    • 使用者層級預設路徑: C:\Users\<使用者帳號>\.gitconfig
    • 儲存區層級預設路徑: <Git儲存區>\.git\config   

 

§ 在本地 (本機) 使用 Git 版本控管工具 §

 

取得 Git 指令列工具版本

  • git --version

建立本地儲存區 (local repository) ( : 從指令來看,比較像是初始化 Git 目錄的意思 )

  • git init
    建立好的所有儲存區檔案 (repository files) 都會儲存在目前目錄的 .git 目錄下。

取得目前 Git 工作目錄的狀態

  • git status
    用這個指令可以取得當前目錄的版控狀態,例如有檔案被變更、刪除、新增或其他。

新增檔案 ( 將尚未被 Git 追蹤的新增檔案加進去 )

  • git add .
    git add <filename.ext>
    上述指令最後若加上一個小數點 ( . ) 代表目前目錄,它會自動把所有尚未版控的檔案 (Untracked files) 加入到 Git 的追蹤清單中,也代表這些檔案才會經由 Git 進行版本控管。
  • 如果你新增了一個檔案 a.txt,此時你用 git status 會看到以下畫面:
  • 如果執行了 git add . 之後,就會變成以下畫面:

提交變更 ( 將 Git 狀態中所有異動的部分送進 儲存區 ) ( Note: 儲存區 = Repository )

  • git commit
    git commit -m "<要留下的版本紀錄訊息>"

    提交變更一定要填寫紀錄,所以會自動開啟 Notepad ( 或 vim ) 讓你輸入紀錄,輸入完儲存並關閉 Notepad,就會自動提交變更完成。

查看歷史紀錄

  • git log
    git log --stat
    git log --pretty=oneline 
    查詢紀錄時,你就會發現有幾個重要的欄位,分別是:
    • commit 後面接著一串亂碼 ( SHA1 Hash ) 代表這個版本的唯一記號
    • Author 代表提交這次變更的作者,這裡的資料是由提交的人當下設定的 user.name 與 user.email 參數,所以如果有人有改名過,從這裡可能不好看出到底是誰改的,或覺得紀錄有點亂,這可能一開始大家要先講好比較不會亂。
    • Date 代表這個版本被提交的日期
    • 最後,就是當時留下的紀錄訊息。

更新檔案 (不包括刪除檔案喔)

  • git add -u
    如果你在 Git 的工作副本目錄下有更新檔案,其實 Git 並不知道你改了,所以如果你直接執行 git commit 指令企圖提交變更的話,會立刻看到以下訊息:

    這裡你會看到 “Changes not staged for commit” 這句話,當中的 “not staged” 這個字照字面翻譯是「不在舞台上」的意思。
  • 舉個例子來說:假設是一個舞團指揮,目前正在編舞 (程式開發中),排練時有個舞台可以練習,而這個舞台就是你的 Git 工作區 (目前這個目錄),該舞團有個工具可以控制舞台上所有事情 (就是你的 Git 工具),而舞台上所有 舞者 (目錄下的所有檔案) 都會聽指揮的命令。今天,舞台上有一個 舞者 (a.txt) 自己發明了一個新舞步 (檔案被更新),但 指揮 並不知道,當 指揮 詢問每位舞者的狀態 ( git status ) 時,發現了這個舞者 (a.txt) 發明了新舞步,他必須決定是否要把舞步編進舞冊上 ( git commit )。此時,假設指揮同意了這個舞步變更,他就必須把這個檔案加到編舞裡去,你就要輸入 git add -u 命令讓他上台試跳,如果跳的不錯,這時輸入 git commit 才會真正把舞步編進舞冊上。
  • 註 1:你直接輸入 git add . 而不加上 -u 參數,也可以把這些變更過的檔案加入追蹤。不加上 -u 則代表「新增」與「變更」都會一併提交追蹤。
  • 註 2:使用 git add 的時候,最後一個參數可以放小數點 ( . ),也可以放檔名或特定目錄下的檔名,甚至於輸入 萬用字元 ( * ) 也可以。

刪除檔案

  • git rm '<filename>'
    直接標記刪除檔案
  • git add –u <path\filename.ext>
    git add -u

    先透過檔案總管把檔案刪除,然後再透過 git add 標註刪除,不過在下指令的時候,一定要加上 -u 參數,才能把要刪除的檔案標示為 staged (代表可被 commit 的意思)。

重置檔案狀態 (不會變更檔案內容)

  • git reset HEAD [<path\filename>]
    git reset HEAD

    如果你發現這這個變更過的編舞實在太醜,不想將他提交變更,則可以利用 git reset HEAD 指令將這些變更都退回 “未追蹤” (Untracked) 狀態,也代表未來執行 git commit 時不會提交這些變更。

請注意:這裡的 HEAD 代表的是目前版本庫中的最新版,而 reset HEAD 的意思,就是將當前目錄特定檔案重置為 HEAD 版本的狀態,所以 HEAD 版本之後的所做的變更,都會變成 not stageduntracked 狀態。 ( 重置的動作,並不會修改任何檔案的內容 )

復原檔案變更 (Undo Changes)

  • git checkout -- .
    git checkout -- <filename.ext>
    當修改了工作目錄中版控中的檔案,如果檔案還處於 “not staged” 狀態,就可以透過這個指令,重新取出 (Checkout) 檔案,然後讓上一個版本的內容蓋掉這個檔案的內容。不過,如果該檔案已經被標示為 “staged” 的話 ( 也就是已經透過 git add . 指令標示成 staged 的話 ),執行這個指令就不會蓋掉這些檔案,你必須先執行 git reset HEAD 才能將檔案回復為 “not staged” 狀態。

請注意:這裡的 -- 等同於 HEAD 的意思,是 HEAD 的簡寫。

清除未追蹤的檔案 ( Clean untracked files )

  • git clean
    git clean –n
       (僅列出要清空的檔案清單)
    git clean -f   (執行刪除動作,把那些要清空的檔案逐一刪除)

    自動清除沒那些不在追蹤行列的檔案有時候很方便,例如我們用 Visual Studio 經常會產生很多暫存檔,用了 git 之後,直接執行 git clean -f 就可以把那些多餘的檔案清空。

同時有檔案新增與檔案更新的狀態怎樣控制

  • 假設我們先異動過 a.txt 檔案,然後新增一個 b.txt 檔案,此時輸入 git status 指令結果如下:

    此時你會發現,a.txt 屬於 “not staged” 的狀態,而 b.txt 屬於 “Untracked” 的狀態。這代表 a.txt 本來就是在控管的行列內,只是因為他變了,不會被編進舞蹈 (not staged) 之中而已;而 b.txt 根本不是舞團的成員,可能只是某個小屁孩在舞台上亂跳而無法控管 (Untracked),他跳的所有舞蹈也不會編進正式舞蹈之中。
  • 如果你想一次把所有新增檔案與更新檔案加入編舞,可以輸入以下指令:
    git add .
  • 如果你只想把舞團成員的編務納入編舞的話,則可以輸入以下指令:
    git add -u
  • 如果你只想把未控管 (Untracked) 的檔案加入編舞,則必須指定檔名來加入,如下指令:
    git add b.txt
  • 要取消所有變更狀態,也就是全部都不納入編舞,可以輸入以下指令:
    git reset HEAD
  • 重新全部加入,然後將 b.txt 這個新增檔案重置成未追蹤 (Untracked) 的狀態
    git reset HEAD b.txt
  • 重新全部加入,然後將所有 a.* (使用萬用字元) 取消納入編舞
    git reset HEAD a.*
  • 最後我們取消 a.txt 變更過的內容,回復到原本版本庫中的內容 (上一個版本),可輸入以下指令:
    git checkout -- a.txt 

 

摘要複習一下上述學到的

  • 所謂 staged 代表要把檔案可以被 commit 的意思 (可以納入舞冊)
  • 所謂 not staged 代表檔案有變更,但不會被 commit 進版本庫 (有變更舞步但不被採納)
  • 所謂 untracked 代表是該檔案尚未被追蹤,也不會被 commit 進版本庫 (在舞台上亂跳的小屁孩)
  • 把所有檔案標示可以被提交,使用 git add . 指令 (允許納入舞冊,但還沒真的納入)
  • 把所有檔案新增或更新的標示取消,使用 git reset HEAD 指令
  • 任意時刻查詢工作目錄的狀態,使用 git status 指令
  • 僅把更新的檔案標示為可提交,使用 git add -u . 指令 (只把舞團成員的變更納入)
  • 將所有標示為可提交的檔案送入版本庫,使用 git commit 指令
  • 查看歷史紀錄使用 git log 指令
  • 要把 HEAD 版本之後所做的變更全部還原 (Undo All),可以輸入以下指令:
    git reset HEAD
    git checkout --

 

查看不同版本之間的變更比較

  • 比較 版控中的最新版 ( HEAD ) 與 目前工作目錄檔案 的版本差異
    git diff HEAD
    git diff --staged
  • 比較 版控中的倒數第二版 ( HEAD~1HEAD^ ) 到 版控中的最新版 ( HEAD ) 的版本差異
    git diff HEAD~1..HEAD
    git diff HEAD^..HEAD
    注意: HEAD 代表最新版,而 HEAD~1 即代表「最新版再往前一版」的意思。
  • 若要明確比對兩個版本,則需先透過 git log 取得 commit id (用 SHA1 Hash 的那串亂碼),然後再透過 git diff <OldCommitID>..<NewCommitID> 進行比對。從下圖你可以看到,當我們用 git log 取得版本歷史紀錄時,每個版本都會有個很長的 commit id,如果手動輸入這些 ID 真的會要人命,所以 git 再讓你輸入時,可以最少輸入 commit id 最前面四個字元,就能代表這個版本,使用時的範例如下:
    ( 注意: 輸入版本號時,記得舊版本要先輸入,打上兩個小數點,再打新的版本號 )

 

變更檔名

  • 變更檔名這件事比較奇怪一點,如下圖示,當你把原本版控中的檔案 a.txt 更名為 a.log 之後,你會發現使用 git status 會看到兩個變更,一個被刪除的檔案、一個被新增的檔案:

    然而,如果你這時執行 git add . 是不行的,他會出現以下警告訊息

    要解決「檔案重新命名」的問題,有兩種方式可以解決。
    1. 因為一個是「刪除檔案」,另一個是「新增檔案」,分別要下的指令是以下兩個:
    git add .
    git add -u
    所以上述兩個指令都輸入一次,重新命名就會被正確標註:

    2. 另外 git add 還有一個 -A 參數可用,只要下一個指令,就可以將所有檔案標示為 staged
    git add –A <path\filename.ext>
    git add -A

請注意:在變更檔名時,只有當檔案內容沒有變更的情況下,才會被 Git 視為是 rename 標示!

 

重新提交版本

如果你在執行了 git commit 指令提交變更之後才發現漏了一個檔案,或是 Log 不小心打錯字了,你可以透過一個 --amend 參數幫助你重新提交一次版本,你可以在這次提交變更的時候,新增檔案、刪除檔案、變更檔案、檔案更名,甚至於修正原本寫好的 Log 內容都可以。其指令輸入範例如下:

git commit --amend

以下為實際範例:

1. 我們先用 git log 顯示版本歷史紀錄

   

2. 然後新增一個檔案後,再利用 --amend 重新提交一次變更 (順便修改成不一樣的 Log 訊息)

echo. > amend_test.txt
git add .
git commit --amend -m "Rename a.txt -> a.log!"

3. 再看一次 git log 顯示版本歷史紀錄,你可以看到版本並沒有變多,不過 commit id 已經不一樣了!

   

 

重置版本 / 復原版本

推薦閱讀:

git reset 有個用法如下:

git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]

由於原文的說明好難懂,我看了好久還是似懂非懂,我已經盡量寫清楚了,如果有錯誤的地方,歡迎不吝告知,感恩!

以下是官網對 git reset 的摘錄:

git reset [<mode>] [<commit>]

This form resets the current branch head to <commit> and possibly updates the index (resetting it to the tree of <commit>) and the working tree depending on <mode>. If <mode> is omitted, defaults to "--mixed". The <mode> must be one of the following:

--soft

Does not touch the index file nor the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

--mixed

Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.

--hard

Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.

--merge

Resets the index and update the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). If a file that is different between <commit> and the index has unstaged changes, reset is aborted.

In other words, --merge does something like a git read-tree -u -m <commit>, but carries forward unmerged index entries.

--keep

Resets index entries and updates files in the working tree that are different between <commit> and HEAD. If a file that is different between <commit> and HEAD has local changes, reset is aborted.

我們先不討論複雜的版控的分支架構,如下圖,我們總共 commit 了三次,各別的 commit id 為 C0, C1, C2 與 C3,而目前箭頭指向的地方則是代表 HEAD,所以 HEAD 等於 C3

假設我們 HEAD 等於 C3 的情況,結果發現 C3 這個版本不是很乾淨,例如漏 commit 了一個檔案,或 Log 寫錯了要改,在本文稍早有個「重新提交版本」部分,有提到一個 --amend 參數可以幫你重新 commit 一次,並且覆蓋掉最新的這一版。除了重新提交版本外,我們也可以利用 git reset 指令, 將 HEAD 指標移向 C2 版本,移動完成後的結果大概如下圖解:

其重點在於 git reset 一定會修正 HEAD 指向的版本,但主要是有兩個東西可能會被改變,分別是:

  • 重置 index 檔案 ( .git/index ),此檔案紀錄了你在工作目錄下的各種檔案與版本資訊
  • 重置 working tree 檔案,這裡的 working tree 就是指你的工作目錄下的所有相關檔案

你可以輸入以下 5 種的其中一種模式進行重置,用以決定是否更新 indexworking tree 檔案:

第一種:使用 --soft 參數

git reset --soft HEAD~1

: HEAD~1 代表 HEAD 往前一版的意思。以上圖為例,當 HEAD 等於 C3 時,當下的 HEAD~1 就等於 C2

使用 --soft 參數,執行完後會修正 HEAD 指向的版本 (這五種模式都會修正 HEAD 指向的版本),而且不會重置 index 也不會重置 working tree。這句話的意思是指,執行完後:

  • 不會重置 index 檔案 ( .git/index ),代表你在工作目錄下所做的任何檔案標記 (標記新增、刪除、更新、更名、…),所有標記要 commit 的檔案狀態,都不會異動。
  • 不會重置 working tree 檔案,代表工作目錄下的檔案,所有檔案內容都不會被異動,雖然版本變成上一版 (或任意版本),但本次修正的檔案完全不會被蓋掉。

注意: 檔案內容被重置index 狀態被重置,是兩件事。

 

第二種:使用 --mixed 參數

本文稍早寫過,若要把 HEAD 版本之後所做的變更全部還原 (Undo All),可以輸入以下指令:

git reset HEAD 
git checkout --

事實上,這段程式等同於以下:

git reset --mixed HEAD
git checkout --

也等於這樣,git reset 預設的模式就是 --mixed 與預設 commit 也是 HEAD 等等,都可以自動省略

git reset
git checkout --

使用 –mixed 參數,會重置 index不會重置 working tree。這句話的意思是指,執行完後:

  • 重置 index 檔案 ( .git/index ),代表你在工作目錄下所做的任何檔案標記 (標記新增、刪除、更新、更名、…) 通通都會被重置,也就是若有檔案被標註新增,執行完後檔案會變成 untracked 狀態。
  • 不會重置 working tree 檔案,代表工作目錄下的檔案,所有檔案內容都不會被異動,雖然版本變成上一版 (或任意版本),但本次修正的檔案完全不會被蓋掉。我們以上圖 C3 重置成 C2 為例,C3 之後所做的變更,當執行了 git reset --soft C2 之後,代表原本 C3 的變更與 C3 到目前所作的變更,其變更的內容都在,指令執行完後,原本工作目錄下的檔案內容都是原封不動的,所以當你執行 git status 的時候,就會發現從 C2 到現有的這個目錄,所有的變更都屬於 unstaged 的狀態。

 

第三種:使用 --hard 參數

git reset --hard HEAD~1

使用 --hard 參數,會重置 index會重置 working tree。這句話的意思是指,執行完後:

  • 重置 index 檔案 ( .git/index ),代表你在工作目錄下所做的任何檔案標記 (標記新增、刪除、更新、更名、…) 通通都會被重置,也就是若有檔案被標註新增,執行完後檔案會變成 untracked 狀態。
  • 重置 working tree 檔案,代表工作目錄下的檔案,只要是 tracked 的檔案,全部都會被蓋掉 (或透過 git add 新增進去但尚未 commit 的新增檔案也會被刪除)。注意:那些 unstaged 的檔案,其實都是 tracked 的檔案,因為 unstaged 的檔案已經是被追蹤的檔案了,只是被修改或刪除,還沒被標記可被 commit 而已,這些檔案在透過 git reset --hard 之後,所有變更都會消失。

注意: 透過 git reset --hard 之後,現有尚未 commit 的檔案變更都會消失,而且救不回來喔!所以通常在執行危險的命令前,常有人會把目前尚未 commit 的檔案先 commit 成一個新版本,然後建立好一個新的分支 (Branch),然後再將現有的 master 分支 reset 成舊版,然後再繼續改。

範例如下,我們先把尚未簽入的檔案都給加入並 commit 提交變更,在把提交後的結果透過分支來做一個類似備份的動作: ( : 之後的文章會介紹到 git stash 的用法,他可以把不完整的檔案暫存起來 )

git add -A
git commit -m "Backup for this time"
git branch Backup01
git reset --hard HEAD~1

改完之後,如果想把備份的資料合併回來,可以用以下指令: 
注意: 合併後會建立一個新版本,���原本尚未 commit 的版本還要再 commit 一次。

git merge Backup01

如果確認沒問題,可以用以下指令把剛建立的 Backup01 分支給刪除:

git branch Backup01 -D

 

第四種:使用 --merge 參數

git reset --merge ORIG_HEAD

使用 --merge 參數,有點類似 --hard 參數,會重置 index會重置 working tree,但有些條件,只有當指定的 <commit> 版本與目前 HEAD 當中檔案不一致的時候,才會重置目前 working tree 下面的檔案內容為 <commit> 這個版本下的內容,而其他的本地檔案變更則會被保留。

這參數通常用在使用 git pull 從遠端合併變更進來,不過你可能在此時,已經有些檔案已經變更過,再加上 git pull 從遠端合併過的結果後,你的工作目錄可能會髒掉 (例如有些檔案合併後不能用),這時如果你用 git reset --hard ORIG_HEAD 雖然可以回復到合併前的上一版,但你所有的本地變更都會消失。此時你如果用 git reset --merge ORIG_HEAD 的話,就會僅針對「合併所變更的那些檔案」進行重置,就不會影響到你其他已經變更的檔案。以下是使用範例:

$ git pull                         <1>
Auto-merging nitfol
Merge made by recursive.
nitfol | 20 +++++----
...
$ git reset --merge ORIG_HEAD <2>

第五種:使用 --keep 參數

git reset --keep <commit>

使用 --keep 參數,有點類似 --merge 參數,會重置 index會重置 working tree,更新的條件也跟 --merge 一樣,只有當指定的 <commit> 版本與目前 HEAD 當中檔案不一致的時候,才會重置目前 working tree 下面的檔案內容為 <commit> 這個版本下的內容。但跟 --merge 參數不一樣的地方在於,當你指定的 <commit> 版本中的變更檔案與你本地變更的檔案有重疊到時,因為他會強制保留 <commit> 這邊的版本,所以本次的 git reset 命令會被中斷,不會被執行。這樣可以比較安全的重置到特定版本。

 

§ 設定 .gitignore 忽略清單 §

在開發專案時,工作目錄下可能經常會有新的檔案產生 (可能是透過 Visual Studio 工具產生的那些暫存檔案或快取檔案),可能有許多檔案並不需要列入版本控管,所以必須要排除這些檔案,我們稱為「忽略清單」檔案。

在 Git 裡面,是透過 .gitignore 檔案來進行定義,主要的目的是排除一些不需要加入版控的檔案,列在裡面的檔名或路徑 (可包含萬用字元),都不會出現在 git status 的結果中,但僅限於 untracked 檔案而已,那些已經列入版控的檔案,不受 .gitignore 檔案控制。

.gitignore 檔案內容範例如下:

# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
[Bb]in/
[Oo]bj/
 
# mstest test results
TestResults
[Tt]est[Rr]esult*
 
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
 
# User-specific files
*.suo
*.user
*.sln.docstates
 
# Build results
[Dd]ebug/
[Rr]elease/
x64/
 
# Others
sql
*.Cache
ClientBin
[Ss]tyle[Cc]op.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
 
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML

詳細說明文件如下:

也可參考我之前寫給 SVN 的文章:

 

§ 復原 Git 操作過程中的所有變更 §

在 Git 裡,所有指令操作都會被留下紀錄,也代表,無論你怎麼用,只要是 commit 過的版本,預設就一定會留在版本庫裡,即便你做了一些非常危險的指令操作也都一樣,都是能夠復原的!

額外提醒:有一種情況不能復原檔案內容,就是你在 commit 之前就把版本給還原,那就救不回來囉!

  • git reflog
    git reflog show master
    取得 Git 管理日誌,你可以透過這份日誌,找到可以讓你還原的版本。透過 git reset 指令。

1. 我先透過 git reset 指令刪除最後一個版本:

git reset --hard HEAD~1

 

2. 然後透過 git reflog 取得管理日誌,並得知:

 

3. 最後得知你想要還原回去的版本,再透過 git reset 指令回復到日誌的上一個版本

git reset HEAD@{1}

 

 

當你知道如何復原變更之後,在使用 Git 的同時,相對的也會安心許多,因為你至少知道所有的 commit 都會保存下來,沒有資料會不見。

 

總結

這是我今天的學習紀錄,學習過程順便筆記與反覆驗證的結果,內容有點雜亂,但照著做應該能做出來,使用 Git 重點還是在觀念,否則一直鬼打牆真的很累,而且也會很灰心的。

研究後發現,Git 博大精深,東西太多了,今天寫了一整天,卻還沒講到分支與合併的細節,以及如何跟遠端的 Git 專案協同作業,下次繼續,非要戰勝 Git 不可!

 

相關連結