哇賽!一個不知不覺已經來到最後一篇了!今天來點 Git 吧!
Git 是一個非常不錯的協作工具,在開發專案上使用能夠很輕鬆的掌握各個檔案,廢話不多說,就來看看這次的最終章 - Git!
Git 像是時光機,能保存檔案,也能回顧過去的紀錄,是一種記載著連續性歷史紀錄的系統。
有接觸 Git 工具的人可能會說:「 Git 是一種分散式版本控制系統。」
聽到這會覺得,每個字都看得懂,但是,仍然不知道實質上是做些什麼?
來看看自己是不是有過數個檔案、數本報告改了又改,檔案命名換了又換,到最後要繳交的時候,根本搞不清楚自己要的最終版本是哪一個? 又或者,當與別人一起共同編輯資料,如果對方沒說明,不會知道資料哪裡變更了?
這種時候,Git 真的就是最好的幫手,因為他可以紀錄每個檔案在何時被新增、何時被修改或者被誰異動過,就這樣紀錄著每個檔案!
首先,Git 免費且開源 (Open Source) ,大家都可以搜尋 Git 網站,下載並使用!
當知道 Git 會保留歷史紀錄,使我們完全可以在發生狀況的當下,一一檢視哪裡出問題以及該找誰負責,對於想要有效率地檢視檔案內容哪裡有變動的人來說,真的是一個很方便的工具!
而,Git 之所以稱之為分散式版本控制系統,源自於他不需要伺服器軟體,就可以運作版本控制,不用擔心伺服器壞了或者沒有網路的環境就無法運作。一般而言,大部分 Git 的操作都在本地數據庫 (Local Repository) 裡執行,也就是在自己的電腦上完成操作,所以使用上可以不用過於擔心。
git --version
- log out the versiongit config
- list view current settingsgit config --global user.name ”your name”
git config --global user.email ”your email”
cd the directory which you want to use git
-> git init
Working Tree
The space that you create the file and still edit them.
Staging Area
After editing, entering the command git add, then the file will be staged.
Repository
The staged files need to be save into git. Thus, entering the command git commit -m “the description of what you have revised or why you committed”, then the files will be saved.
Working Tree or Changes not staged for commit
Untracked files or Modified filesgit add
>
Staging Area
Changes to be committedgit commit
>
Repository
Committed
git add - add untrack files to staging area
git add . (. = here) - add all the files here
git add --all or git add -A - add all the files
git restore - discard the changes in working tree
git restore . - discard all the changes here
git commit -m "message" - commit tracked files to local repository
git clone 'URL' - fetch the online sources URL(such as GitHub) to the local repository
git pull - fetch and merge the remote repository to my files
git push - push to remote repository
git blame `file name` - log out the file information
git branch - see all the branches
git branch `branch name` - add a new branch
git branch -m <old_name> <new_name> - rename the branch
git branch -d `branch name` - delete a branch
git checkout - save the deleted file & switch the branch
git log - log out the records
git log -- oneline - log out the simplified records
git log -p `file name` - log out the specified file record
l - show the detailed list
ls - show the file name
ls *.html (`*` means all) - show all the HTML file
git merge -m “merge message” - merge branches (merge consults)
git mv - renamed the file in git
git rebase - change the base of branches
git reflog or git log -g - see all the edited records
git reset HEAD, branch, commit - gets rid of all the current staged files and gives us control over where HEAD should point to.
git reset HEAD\^ - return the previous one move
git reset HEAD~`number` - backward to wanted moves
git reset HEAD\^ --mixed - (drfault) the hidden file will go to working tree
git reset HEAD\^ --soft - the hidden file will go to staging area
git reset HEAD\^ --hard - the hidden file will disappear
git restore - save the deleted file (return to the previous move)
git rm - remove the file from git
rm - remove the directory in git
rm *.html - remove all the html files
rm -rf - force to remove the ./git directory in the folder
git switch - switch the HEAD of branch
git switch `commit number` --detach - switch the HEAD of commit files
git commit 並不是將暫存區的檔案清空再放入資料庫。
實際上,git commit 是將暫存區的內容保存到本地資料庫中,創建一個新的提交(commit)。
當使用 git add 命令將修改的檔案加入暫存區後,
這些修改的檔案會成為下一個提交(commit)的一部分。
當執行 git commit 時,
Git 會將這些暫存區中的檔案儲存為一個新的提交,
並將其保存到本地資料庫中。
可以的!
git add 指令會將文件的內容加入到 Git 的暫存區(index)中,
暫存區是一個存放即將提交的文件和更改的區域。
在執行 git add 後,Git 將文件的內容儲存到暫存區中,
但尚未正式提交到 Git 儲存庫的歷史記錄中。
因此,即使沒有進行 commit,文件的更改仍然可以在暫存區中找到。
當使用 git restore 或 git checkout 等命令時,Git 會根據暫存區中的內容來恢復文件。
暫存區允許在 commit 之前對文件進行檢查和修改,並可以根據需要將這些更改提交到儲存庫中。
最後,當執行 git commit 命令時,
Git 將暫存區中的內容正式提交到儲存庫中,並創建一個新的 commit 紀錄。
而,這些更改就成為了儲存庫的歷史記錄中的一部分,
並且可以通過 commit 的 SHA-1 鍵值來追蹤和檢查。
git rebase --interactive commit_number
-> git rebase -i commit_number
EDITOR='code --wait' git rebase -i commit_number
這項指令可以在 VSCode 編輯(要注意順序跟在 git graph 相反)
(如果沒有寫 EDITOR='code --wait'
就會進入 Vim 的編輯器去編輯)
當執行剛剛的指令後, VSCode 會開啟一個檔案,
並在想要更改的 commit 將 pick 改成 reword 存檔並關掉檔案,
VSCode 就會跳出另一個視窗讓你修改 commit。
另外在介紹另一個動詞,squash !
squash 是一種合併(merge)多個連續的 commit 記錄成單一的 commit 的操作。
想要更改的 commit 將 pick 改成 squash 存檔並關掉檔案,
VSCode 就會跳出另一個視窗讓你修改 commit,這時就能將多個 commits 合成一個 commit。
Remark:
在執行 EDITOR='code --wait' 之前,
透過 Settings 去尋找:
確保有將 VSCode 開啟 Shell Command: Install 'code' command in PATH
在不同的分支上開發新功能、解決 bug,完成後就需要把功能合併回主要的分支。
合併分支的方式主要有兩種:merge
與 rebase
。merge
的特點是不改變過去 commit 的歷史記錄,而 rebase
會在合併的當下重新改寫過去 commit 的歷史記錄。
git merge:
git checkout main
git merge feature
git merge feature
,會產生一個新的合併 commit,可以選擇使用 default message: Merge branch 'feature'
將兩個分支的歷史記錄整合在一起,可以從上下圖看出 merge
保留原始分支的歷史記錄,因此可以清晰地看到哪些更改是在哪個分支上進行的。git merge
通常用於將一個分支的更改合併到主分支或其他長期穩定的分支上。fast-forward 合併時,Git 簡單地將 main
的 HEAD 移動到 feature
分支的最新提交,不會產生合併提交。
這樣的合併非常乾淨,因為不會產生多餘的合併提交,但它無法保留特性分支的歷史記錄。
no-fast-forward 合併方式保留了分支的歷史記錄,但會產生一個合併 commit
(如上圖),以標識這個合併操作。
git rebase:
git checkout feature
git rebase main
git rebase main
將 feature
分支的更改暫時存取,然後合併在 main
的最新 commit
之上,從下圖可發現原本
feature
的SHA-1
值為e66f7db1
,
當使用rebase
後,此SHA-1
值就會變為新的8332a9fe
。
commit
歷史記錄,因為是在一個分支上連續進行的更改,而不是合併的多個 commit
。git rebase
通常用於保持分支的歷史記錄簡潔,特別是當你想要將一個分支的更改整合到另一個分支中,而不希望建立多餘的合併提交。當執行 git rebase
時,可能會遇到合併衝突(merge conflicts)。
這些衝突發生在 Git 嘗試將一個分支的變更應用到另一個分支的過程中,但無法自動解決變更之間的衝突。
在專案上其實很常見,所以要有耐心的且知道大家的 code 在寫什麼才不會弄錯不要的 code 到專案上唷!
當 Git 嘗試將兩個分支上的相同文件的相同部分合併在一起時,如果他們的內容不一致,就會產生內容衝突。
<<<<<<< HEAD
This is the new content from the current branch.
=======
This is the old content from the branch being rebased.
>>>>>>> branch-name
在這種情況下,你需要手動選擇要保留的內容,然後刪除 <<<<<<<
、=======
和 >>>>>>
標記。
解決衝突後,你需要執行 git add
以加入已解決的文件。
然後執行 git rebase --continue
以繼續 rebase 。
除了上述之外,文件刪除/重命名衝突、檔案和目錄移動衝突,也是會需要我們手動解衝突的狀況!
整理一下解決合併衝突的一般步驟:
git add
將已解決的文件標記為已解決。git rebase --continue
繼續 rebase 操作,直到沒有其他衝突。cat `file_name` - 可以看到檔案
cat index.html
git cat-file commitnum -t - 可以看出是什麼類型
git cat-file commitnum -p - 可以看出內容物
用於將一個命令的輸出作為另一個命令的輸入。兩者之間有前後關係!
In Unix-based systems, the pipe symbol is extensively used in the command-line interface (CLI) to chain multiple commands together, allowing the output of one command to be processed or used as input for another command.
cat index.html | grep n 可以抓出有包含 n 的字
cat index.html | grep n | grep d 可以抓出有包含 n 的字以及包含 d 的字
cat index.html | git hash-object --stdin
git hash-object --stdin
:在 Git 使用 cherry-pick 指令的場景通常是想將特定的 commit 變更合併到當前的分支中,
而不是將整個分支合併。這可以選擇性地導入某個 commit 的修改,而不需要合併整個分支的歷史。
cherry-pick 的基本語法如下:
git cherry-pick <commit-hash>
其中 <commit-hash>
是你擷取的 commit 的 SHA-1 值。
(我通常直接使用 VSCode 裡的 Extension -> Git Graph 來操作 cherry-pick)
使用 cherry-pick 之後,Git 會將該 commit 的變更應用到當前分支中,並創一個新的 commit。這個新的 commit 和原始 commit 的內容是相同的,但它有不同的 SHA-1 值,
因為它是在不同的時間和不同的歷史上提交的。
需要注意的是,如果你使用 cherry-pick 來選擇並擷取某個 commit,
則這個 commit 及其相關的變更會被完整複製到目標分支中。
這包括新增的檔案、修改的檔案和刪除的檔案等。
因此,在使用 cherry-pick 時,
需要確保這個 commit 的變更不會與目標分支中的其他變更產生衝突。
迅速地介紹完 Git ,希望大家在使用上都能得心應手!
文章同步於個人部落格:Viiisit!(歡迎參觀 ୧ʕ•̀ᴥ•́ʔ୨)
哇哇哇!我完賽了!ヽ(●´∀`●)ノ
謝謝大家的關注!之後會持續更新自己的部落格 Viiisit!
歡迎大家多多關注~~~