iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 29
1
自我挑戰組

毫無基礎學習 Ruby on Rails 的 甘苦心得系列 第 29

DAY 29 程式碼時光機 Git版控

為什麼要使用Git版控?

不管老手或新手在寫程式的時候都會犯錯,有時錯誤嚴重到會希望有一部時光機,讓時間倒流回犯錯之前。正因為這種錯誤,每個程式工程師都應該在開發專案中使用版本控制;不使用版本控制的後果,就等於電腦不備份一樣,一個突然的意外或資料遺失就會讓整個專案受到極大影響。

版本控制能讓你回溯之前的專案版本,可以回復遺失的資料,或是查看程式碼的進程。另外,使用版本控制後,與其他人合作同一個專案就容易得多。

我剛開始學Git以為 GitHub 和 Git 是同一樣東西,但這是錯的。Git 是一個在你自己電腦本機端運行的版本控制系統,而 GitHub 則是一個線上服務,讓你將 Git 版本資訊儲放至雲端,就像是 iCloud 雲端硬碟,但它是專屬於程式碼的應用,而且功能更強大。

https://ithelp.ithome.com.tw/upload/images/20191013/20118842RD0i5DFkPP.png

下圖示 Git 是如何運作的。

https://ithelp.ithome.com.tw/upload/images/20191013/20118842jcxM2UUNXC.png

Working Directory 存放你正在編輯的檔案
Staging Area 則存放 commit (提交) 前的檔案
commit 這些檔案時,檔案就會加到你的本機儲存區
當你進行 push,就會將你的本機儲存區和遠端儲存區同步,我們用的遠端儲存區就是 GitHub。每次進行 push,就可將在本機端的改動加到遠端儲存區;換而言之,進行 pull 的話,就可以將在遠端儲存區的改動,加入到本機儲存區中。

舉個例子:

假設你和夥伴正在合作開發一個簡單的專案,當你今天想新增功能的部分,首先你需要從遠端儲存區進行 pull,確保你的版本已包含其他夥伴做過的程式碼改動。然後,你可以開始編寫程式碼,此時檔案就在你的 working directory。當你完成了一個功能、或是某個重要的部分後,就 git add 檔案到 staging。如果你加入了任何檔案或圖片,亦要把它們加到 staging。現在你可以準備 commit 了,commit 的時候,請加入注釋說明做過的改動。最後,你可以用 git push 同步本機儲存區與遠端區。你的夥伴也需要進行 pull,這樣就可以知道你在 setting 頁面做了什麼改動。

說明一些 Git 的指令:

git init: 這個指令可以初始化 Git 專案目錄

git status: 這個指令可以顯示你 git 儲存區的狀態。在你的指令列中,設定了沒被追蹤的檔案 (不在 staging) 顯示為紅色,有被追蹤的檔案 (在 staging) 則顯示為綠色

git add: 這個指令可以把你的檔案加到 staging

git commit: 這個指令可以 commit 你在 staging 的檔案到本機儲存區。

git push: 這個指令可以將你做的改動 push 到遠端儲存區 (GitHub)。

git pull: 這個指令可以將改動從遠端儲存區 pull 回來。你與夥伴開發同一個專案時,你會需要將其他夥伴的改動 pull 回來,並同步至你的本機儲存區中。

git checkout:在 Git 裡面,Checkout 代表著切換分支。比如說,當我想要處理主要分支的另一個功能,我就要 checkout 主要分支,在主要分支編寫程式碼;當我想要開發 resverse,我就要 checkout Reserve 分支再繼續編寫。

以下是我整理出來的筆記

# windows-
$ which git                                # 查電腦裡git版本
$ which apt-get install git
$ sudo sudo apt-get install git             #sudo獲得權限

# Mac-
# Homebrew安裝                        
$ brew install git
$ git --version                                     # 查詢git版本
$ git config --list                                 # 查看git config
$ git config --global user.name "user"              # 設定User訊息
$ git config --global user.email "user@gmail.com"

初始化git

$ mkdir git-demo                            # 建立新資料夾git-
$ cd demo                                   # 進入git-practice資料 夾
$ git init                                  # 初始化GIT版本控制
$ git status                                # 查看目前狀態
$ touch 01.html                             # 建立一個01.html檔案

加入暫存區 add

$ git add 01.html                            # 將01.html加入暫存區
$ git add *.html                             # 所有.html檔案加入暫存 
$ git add --all                              # 將所有檔案加入暫存區
$ git add .                                  # 將所有檔案加入暫存區

commit

$ git commit -m "init commit"           # 創建commit命名init commit 
$ git commit --allow-empty -m "blank"   # 允許創建空的commit
$ git commit -a -m "update content"     # 將未add檔案commit

Git 新增/改名/移除

$ git rm welcome.html                          # 移除
$ git rm welcome.html --cached                 # 將此檔案Untracked
                                               #(不是真的刪除)
$ git mv hello.html world.html                 # 重新命名
# 追加檔案並重新命名上一次commit
$ git commit --amend -m "Welcome To Facebook"  
# 追加檔案不重新命名上一次commit
$ git commit --amend --no-edit

查看 log

$ git log                               # 查看紀錄
$ git log --oneline --graph             # 查看oneline/graph格式化紀錄
$ git log --oneline --author="Sherly"          
$ git log --oneline --author="Sherly\|Eddie"
$ git log --oneline --grep="wtf"

# 搜尋在所有Commit檔案中符合特定條件的
$ git log -S "Ruby"

# 搜索時間條件               
$ git log --oneline --since="9am" --until="12am"
$ git log --oneline --since="9am" --until="12am" --after="2019-01"

branch 分支相關

$ git branch                                # 查看目前Branch
$ git branch BranchName                     # 建立名為BranchName的分支
$ git branch -m BranchName BranchNewName    # 重新命名
$ git branch -d BranchName                  # 刪除branch
$ git branch -D BranchName                  # 強制刪除即使分支尚未被合併
$ git checkout BranchName              # 切換分支
$ git checkout -b BranchName           # 建立且切換分支
$ git checkout -b bird 654fce7         # 在commit:654fce7建立且切換分支
$ git branch BranchName 654fce7        # 在commit:654fce7建立分支
$ git merge BN                         # 將當前分支合併到BN分支
$ git merge BN --no-ff                 # 當前分支合併到BN分支,不快轉
$ git merge b234b6a                    # 將當前分支合併到commit:b234b6a
$ git rebase BN                        # 合併至BN並且以BN當作參考基準

checkout (移動head去查看)

$ git checkout 01.html                      # 01.html回到上一版
$ git checkout .                            # 所有檔案回到上一版
$ git checkout HEAD~2 01.html               # 02.html回到上兩版
$ git checkout HEAD~2 .                     # 所有檔案回到上兩版
  
$ git blame FILENAME                        # 查看每一行程式碼修改歷史
$ git blame -L 5,10 FILENAME                # 同上指定行數5~10
$ git log -p FILENAME

reset

$ git reset e12d8ef^                  # reset到commit:e12d8ef的上一版
$ git reset master^                   # reset到master分支的上一版
$ git reset HEAD^                     # reset到head的上一版
$ git reset HEAD~2                    # reset到head的上2版
$ git reset b174a5a --hard            # 用--hard模式reset
                                      #(完全清除目錄以及暫存區)
$ git reset HEAD^ --hard                        
$ git reset ORIG_HEAD --hard          # 回到上一個關鍵版本
$ git reflog                          # 查看歷史紀錄(一個月內)

merge解決衝突

$ git rebase --continue              # 當遇到合併衝突時,解決後繼續
$ git checkout --ours animal.jpg     # 當遇到衝突時,選擇目前分支的檔案
$ git checkout --theirs animal.jpg   # 當遇到衝突時,選擇合併分支的檔案

tag標籤

$ git tag 1.0.0 23d54dfc           # 將commit:23d54dfc 建立tag 1.0.0
$ git checkout 1.0.0               # 查看1.0.0標籤版本

GitHub

$ git remote add origin url        # 在遠端加入origin節點
$ git push origin master           # 當前分支推到遠端origin的master分支
$ git push origin aaa:master       # 將本地aaa分支推到遠端origin的master分支
$ git push -u origin master        # -u設定upstream,之後可以直接推送
$ git fetch origin master          # 將遠端origin的master版本拉下來 
                                   #(尚未merge)
$ git pull origin master           # git pull = fetch + merge
$ git pull --rebase                # pull使用rebase
$ git push -f                      # --force強迫push
$ git clone url                    # 複製一份到電腦

參考資料:
Git版控


上一篇
DAY 28 使用 render/jbuilder 輸出 JSON 格式
下一篇
DAY 30 學習沒有終點
系列文
毫無基礎學習 Ruby on Rails 的 甘苦心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言