git


Posted by a113062130630210 on 2022-06-21

git 介紹

git是一個版本控制的軟體,今天在開發一個程式或專案的時候,一定不是馬上就寫出來,是經過很多次的修改才完成的,而git就是一個方便管理這些版本、在這些版本移動、合併不同版本的軟體

github 介紹

github是一個給大家放 git repository的地方,repository是儲存庫的意思,通常大家會直接說repo,因為git是一個管理版本的軟體,repo就是用來儲存不同版本的地方。
今天如果要開發一個東西,就要先開一個git repo,在那個git repo裡面做事,git才會幫我們管理這些版本
github就是一個可以放repo的地方(github是個網站),有點類似雲端硬碟,但上面就只能放git repo,把repo放在github上,就可以透過網路在其他地方下載你要的檔案(clone)。多人開發專案的時候,可以透過把修改的部份推上去github(push),再讓其他人拉下來(pull),他就可以有你開發的部份了。

安裝git

For window users: download git bash
For macOS users: 可以直接在terminal打git指令,如果系統發現你還沒安裝過,便會自動提示你安裝
For linux users: sudo apt-get install git-all

git 基礎

git操作最基本會牽涉到四個地方: Working Directory, Staging Area, Local Repository, Remote Repository

  • Working Directory: 你在使用的資料夾,可以想成是你的工作臺
  • Staging Area: 在repo跟Directory之間的一個暫存空間,有點像是把一個工作臺完成的貨物送往倉庫的卡車
  • Local Repository: 儲存各個版本的地方,可以想成是你的大倉庫
  • Remote Repository: 儲存各個版本的地方,只是他在遠端(ex: github),可以想成是你的遠端大倉庫

最基本的git操作大概會是這樣的流程

  1. 在Working Directory編輯修改一些檔案
  2. 用add指令,將他們放上送往repo的卡車(Staging Area)
  3. 用commit指令,卡車就會出發,把上面的資料送進倉庫(Local Repository)

像這樣子整個步驟做完,repo就會多出一個commit,相反的,也可以把東西從倉庫拿回工作臺,把commit送進去之後,如果想回到特定的某一次版本,可以透過checkout指令,切換到特定的"commit"或是"branch"找到特定版本,git會從Local Repository把當時的檔案叫回Working Directory

基本指令(本地端操作)

基本設定 git config

開始之前,要設定git config

$ git config --global user.name "你的名字"
$ git config --global user.email "你的信箱"

創建git repo(git init)

使用git init之後,可以在當前目錄創一個repo
實際上它會為當前目錄創一個.git檔(裡面紀錄這個git repo的資料),接下來就可以在這個資料夾底下使用各種git指令
如果在後面多加一個參數 "資料夾名稱",它會把那個名字的資料夾創出來,順便在裡面init一個repo

$ git init
$ git init dir_name

把檔案add到Staging Area git add (檔案)

當新增某個檔案、修改某個檔案內容時,要先將這些檔案用git add指令把它加入到Staging Area(待提交的名單),在這之後才可以用commit指令把它提交到repo

$ git add path/to/the/file
$ git add .
$ git add --all

清除Staging Area的內容 git reset

可以用這個指令來清掉暫存區的內容,git reset可以接指定檔案,就只把那個檔案從staging area清掉

$ git reset
$ git reset path/to/the/file

(還有另一個清掉add檔案的方式是git rm --cached path/to/file,但比較接近把repo的該檔案刪除)

提交Staging Area的內容 git commit

把現在的狀態commit成一個快照存到repo裡面(快照就像是把現在的狀態拍張照,然後下次回來這一個commit的時候,就可以讓所有檔案全部回到這張照片的樣子)
使用git commit之後,預設的編輯器會跑出來,請你填commit message(讓你紀錄這次的commit做了什麼)
如果不想要進入編輯器,可以直接git commit -m "commit message"
如果想要讓這一次的commit直接跟上一次的commit包在一起(可能是補了一些應該要放在上一次commit的東西時),可以使用參數 --amend,會把新的東西跟舊的東西一起打包

$ git commit 
$ git commit -m "commit message"
$ git commit --amend

查詢Staging Area狀態 git status

可以用status查看現在的狀態
$ git status

查詢commit紀錄 git log

可以透過git log看到以前的紀錄,會顯示每一筆的commit message跟哪些檔案被新增修改,還有每一個commit的hash value,想要顯示詳細一點可以用參數 --stat,或是用參數 --p

$ git log
$ git log --stat
$ git log --p

切換到某一個commit或branch git checkout(<commit>|<branch>)

每一個commit會有一個hash值,可以寫git checkout hash值,就可以回到那一次的樣子,但回到過去的只有head,整個main還是在後面那樣,所以如果在這個過去commit了,就會開出一條新的分支

$ git checkout hash
$ git checkout main

.gitignore

有時候我們會希望某些檔案不要被add到Staging Area,這時候可以在建立git repo的資料夾新增一個叫.gitignore的檔案,並寫上想要忽略的檔案名單,之後所有add都會忽略列在.gitignore裡的那些檔案

# 忽略 secret.yml
secret.yml
# 忽略所有副檔名是.exe
*.exe
# 忽略.vscode/ 底下的檔案
.vscode/

這樣符合名單的檔案就會被忽略,git status也不會把他們列出來,如果真的想要把他們add進去,要用git add -f 檔案名稱

基本指令(與遠端互動)

複製遠端repo到本地端 git clone <repo>

把遠端一個repo,clone到本地端

上傳本機資料到遠端 git push [remote] [branch]

對於已經從遠端clone到本地端的repo,可以把本地端新的資料push上去到遠端,後面可以填要對哪一個remote,push上去哪一個branch(因為可以設很多個remote端,但預設會是最近一次的那個remote)

獲取遠端資料並合併到本機 git pull [remote] [branch]

對於已經從遠端clone到本地端的repo,可以把遠端新的資料pull下來到本地端,跟push一樣,後面可以填要從哪一個remote,pull哪一個branch下來

git 進階

分支的概念

因為git是一個可以讓多人同時合作進行專案的系統,所以為了讓所有人都能不受別人影響製作自己的檔案,因此git提供了branch這個功能
創建repo時,git會自動創造一個main分支,而每個branch都會有一個指標,用來紀錄branch最新的一個commit,每次commit就是把一筆新的資料存入repo,會紀錄下現在資料夾內檔案的狀態,而是在哪個branch上commit,那個branch的指標就會指到這個最新的commit,要將檔案統一時,只要將所有branch合併起來就完成了

查看分支git branch

$ git branch
* master

前面有星星代表所在的分支,如果只要看自己現在在哪個分支,用git status也可以

新增分支 git branch

$ git branch new_branch
這樣就創造了一個新的branch叫new_branch,他的指標會和現在所在branch指向相同的commit

  • 在git裡面有一個特殊的名字叫head,代表你現在所在的地方,所以分支名字記得不要叫head

切換分支 git checkout

$ git checkout new_branch
Switched to branch 'new_branch'

同時新增和切換分支 git checkout -b

$ git checkout -b another_branch
Switched to a new branch 'another_branch'

可以一次完成新建和切換分支

合併分支 git merge

$ git checkout main
Switched to branch 'main'
$ git merge another_branch
Updating 790da90..c730450
Fast-forward
 somefile | 2+-
 1 file changed, 1 insertion(+), 1 deletion(-)

代表已經把another_branch合併到main這個branch裡面了,一定要先切換到要merge別人的branch上
Fast-forward代表合併的兩個branch是一前一後的關係,並不存在分歧(當前的這個branch在新的branch分裂出去之後沒有其他的commit),那git就會直接將當前這個branch的指標向前拉到有變動的branch的指標的位置

Merge其實是把要被merge的branch(another_branch)上的那些修改重新在當前的branch(main)再做一次,但有時候兩個不同branch都分別更動了同一個檔案,且更動內容不一樣的時候,如果git能夠自行處理哪些需要被留著(兩個branch改的是不同區塊),那最好,但如果同一個區塊同時被兩個branch改到的時候,就要手動recover了

刪除分支git branch -d

$ git branch -d another_branch
Deleted branch another_branch(was 3s08a2j)

和新增branch一樣是用git branch指令,只是要加上-d或-D,-d只會刪除已經push且被merge掉的branch,-D可以強制刪除branch,不管它有沒有push或被merge

Github

設定帳號的SSH KEY:

  1. 在terminal上輸入ssh-keygen產生ssh key
  2. 複製公鑰(id_rsa.pub)
  3. 用瀏覽器登入github,進入帳戶設定裡的ssh設定
  4. 選擇New ssh key,把剛剛複製的公鑰貼在key的欄位

將本地端repo更新上github git remote addgit push

一開始按github的新增repo的時候,上面的repo會是完全空的,可以在repo頁面找到Quick setup,選擇ssh並複製旁邊的URL,複製完便可使用以下的指令

$ cd local_dir
$ git remote add origin [repo_url]
$ git push -u origin main

其他指令

  • git diff: 比較兩個commit的不同之處
  • git show: 顯示某個commit的內容
  • git reset: 回復到某個commit的內容
  • git reflog: 回復到某個head指向的commit變更時的內容
  • git stash: 把做的修改儲存起來
  • git fetch: pull = fetch + merge
  • git rebase: 另一種merge的方式,把另一個branch的commit一個一個apply到當前的branch上
  • git cherry-pick: 把某些特定的commit撿到當前的branch上
  • git gc: 當git專案過於龐大的時候可以刪減一些用不到的資訊









Related Posts

r3:0 異世界網站挑戰攻略與心得

r3:0 異世界網站挑戰攻略與心得

Filecoin 礦工前置作業 - 1

Filecoin 礦工前置作業 - 1

[GIT101] Git 超新手入門

[GIT101] Git 超新手入門


Comments