Git 版本控制 常用篇

CHIEN CHUN-YU
DAAI
Published in
13 min readAug 8, 2019

你還不知道甚麼是版本控制嗎? 你還在用傳統的方式 備份資料 開發專案嗎? 透過這篇文章改變現在的你..而在未來的你可能成為 git 大神呢! 或者...參考這篇 Git Intro 了解一下基本概念吧!

Git 和 GitHub

開發一個專案, 版本控制是非常重要的! 你問我它能帶來哪些利益呢?參考這篇吧 Benfits of Version Control 或者..看下去! 本篇簡單的介紹完概念後....會開始介紹 git 常用的指令,以下部分會以 GitHub 作為支援 git 程式碼存取遠端托管平台(Remote Repository Server)

上圖可明顯看到不同的運作流程, Git 可以分為 Local(本地)和 Remote(遠端)兩個環境, 由於 Git 屬於分散式的版本控制系統, 所以開發者可以在離線 Local 環境下開發, 等到有網路時再將自己的程式 push 到 Remote 環境或 pull 下其他開發者程式碼進行整合. 在 Local 中我們又分為 workspace(工作資料夾)、staging area(暫存區)和 local repositories(檔案庫).

而 Git 中若是有和其他開發者一起合作,則會需要分配不同功能的 branch 和運作流程及處理不同 branch 之間 merge 時可能產生 conflict 的問題。

Important Advantage(重要的優點)

  1. 如果連線遠端可達到備份的效果
  2. code review 時,知道自己改了什麼
  3. 透過 log 或 reflog 回到過去或現在的版本
  4. 透過不同的 branch 做協同開發
  5. 透過 git flow 更了解專案功能的分配及流程

What tool do i need? (註冊及下載工具)

註冊 Github 帳戶( https://github.com/) 作為遠端平台

下載 Git Bash( https://git-scm.com/downloads) 作為下指令端

Set Your ID(設定識別資料)

Git 在安裝後, 首先應該做的事是設定使用者名稱及電子郵件。 這一點很重要,因為每次 Git 的提交都會使用到(email 代表著你 github 的帳號).

git config --global user.name <name>

Ex: git config --global user.name Alex

git config --global user.email <email>

Ex: git config --global user.email P76064538@mail.ncku.edu.tw

git config --list

補充: 也可直接到 config 做編輯

git config --global --edit

Create Git Project(建立 git 專案)

如何產生一個 git project 呢? 有兩種方式(可在 project 中看到 .git 檔):

  1. 將已存在的 git project clone 下來
  2. 將自己的 project 變成 git project(如果要進行遠端存取,請務必要先在 github 建一個 repository 並取得 remote 網址)

Method 1

git clone <remote 網址>

Ex: git clone https://github.com/Alex-CHUN-YU/Word2vec.git

Method 2

step 1: git init

step 2: git add README.md

step 3: git commit -m 'first commit'

step 4: git remote add <remote name><remote 網址>

Ex: git remote add origin https://github.com/Alex-CHUN-YU/Word2vec.git

step 5: git push -u <remote name><branch name>

Ex: git push -u origin master

Ex: git push --set-upstream origin master

Git Basic Instruction(git 基本指令)

那….我們開始了解一些重要的指令吧~

將單一檔案或所有檔案加入暫存區(staging area)

git add <file>

Ex: git add README.md

git add -A 或 git add --all 或 git add .

檢視你目前是否有加入暫存區(staging area)

git status

將檔案加入檔案庫(local repository),這邊的 m 表示為 message 故如果你今天改了 README.md 即可將 message 做這樣的紀錄

git commit -m "your record message"

Ex: git commit -m "update readme"

加入暫存區(staging area)想反悔怎麼辦?

git rm --cached <file name> 或 git restore --staged <file name>

Ex: git rm --cached README.md 或 git restore --staged README.md

或者已經加入檔案庫(local repository)想反悔丟回暫存區(staging area)呢? 此部分是將 local repository 版本回遠端 branch master 的最新版本! 如果不太懂? 可以先往下看!

git reset --soft origin/master

查看 Commit 的紀錄(GitHub UI)

git log 或 git log --graph

將檔案庫(local repository) 提交到遠端檔案庫(remote repository)

git push

保持與遠端檔案庫的同步性

git pull

Git Diff(內容/版本比較)

了解一下每次 commit 的不同吧~ 當然透過 github 這個網站的 UI (使用者介面)較清楚的呈現你新增或刪除了哪些檔案或內容.

在 git add 之前, 除了透過 git status 看看狀況外, 也可以透過 diff 比較一下差別

git diff

那如果你已經加入暫存區(Staging Area)的話呢, 也就是在 git commit 之前

git diff --cached

或者已經 git commit 後(加入 local repository), 也可比較一下 old commit 和 new commit 的差別吧,通常使用 commit id 的前四碼即可

git log

git diff <old commit id> <new commit id>

Ex: git diff 1153 a193

Git Restore a Previous Version(git 版本回復)

想回到過去的版本該怎麼做呢?

如同前面所說的 commit id 可使用前四碼即可(如果有 commit id 前 4 碼與其它 id 有重複的狀況可到第5碼..以此類推),當輸入 git log 時即可從 history 中看到每次 commit 的紀錄(commit id)

git log

git reset <commit id>

Ex: git reset 1153 或 git reset --mixed 1153

註: 如果你使用的是 git reset <commit id> 代表著你使用的是 git reset -- mixed <commit id>,故依然保留原本 reset 回去前的資料

啊如果又反悔想回到最新呢?

git reflog

git reset <commit id>

Ex: git reset a193 或 git reset --mixed 1153

如果你使用的是 mixed 或 soft 的參數時 reset 前的資料都是保留下來的!reset 後想把本地的資料全部清空~只保留最新 commit 的狀況可以這麼做! (此部分也常使用在清除不需要的資料)

git checkout <file name> 或 git restore <file name>

Ex: git checkout README.md 或 git restore README.md

git checkout <all file> 或 git restore <all file>

Ex: git checkout . 或 git restore .

眼尖的讀者們應該會發現上面流程會有兩個以上的步驟來完全 reset 回去!那有沒有方法可以直接回復到跟版本一模一樣資料呢? 是有的!! 就是直接在 reset 加上 hard 這個參數即可做到

git reset --hard <commit id>

Ex: git reset --hard a193

上面部分皆為本地端檔案庫的操作,如要 push 更新到遠端,請將檔案庫(local repository) 強制提交到遠端檔案庫(remote repository)

git push -f 或 git push --force

Git Stash(重視 commit)

如果你想要將每次的修改,視為一個重要的進度,而不隨便就 commit 上去,此時的你如果做到一半? 突然又被 boss 要求去修改其他 branch 該怎麼辦? 就是它啦! git stash ~ 它可以幫你先暫存起來,等你有空回來再繼續撰寫你未完成的工作,不過記得要將它從 stash list 中拿回來喔。

將檔案(必須存在 staging area)加入 stash list

git stash

如果你想把 untracked(新的檔案,未在目前版本中出現)的檔案也加入呢?

git stash -u

或如果你想要為你的 stash 留下訊息呢? -u 代表 untracked 也加入,-m 就是你的 message

git stash save -u -m "message"

Ex: git stash save -u -m "not finish yet"

加入後,來~我們看看裡面有什麼? 如果存在! 恭喜你成功了~

git stash list

老闆交代的問題~我解決了! 哥要回原本的 branch 做事了! 透過 stash id 取回你要的吧

git stash apply <stash id>

git stash apply stash@{0}

此時你會發現 stash list 竟然還存在 stash id ? 沒關係! 我們可以移掉它!

git stash drop <stash id>

git stash drop stash@{0}

甚麼! 怎麼這麼麻煩! 取回來還要自己刪除喔==" 別急~ git 都幫你想好了~一次進行 apply + drop 也就是...

git stash pop <stash id>

git stash pop stash@{0}

ㄚㄚㄚ~我 stash list 中有好幾個 stash 都忘記 drop 掉捏! 怎麼辦?

git stash clear

補充: 以上是一個保存資料又不 commit 的方法,而另一種方式是你可以利用上一個主題教的先 commit ,之後你回來 branch 後再 reset 回去原本的 commit id 這樣是比較直觀一點的,哪種方法好? 就看你囉~

Git Branch Application(git 分支運用)

分支顧名思義就是將原始專案複製一份出來囉,之後到一個進度在 merge 上去原本的專案。這在開發專案或與其他開發者合作是經常使用到的.

Git Branch

檢視現在存在的本地分支與遠端分支,還有你所在的分支

git branch

git branch -a

創造一個分支,假設你處在 master 就是複製一份一樣的資料到 branch dev 裡

git branch <branch name>

Ex: git branch dev

轉換到新的分支

git checkout <branch name> 或 git switch <branch name>

Ex: git checkout dev 或 git switch dev

如果你今天開發完想合併分支呢? 先切到 master 在 merge dev(口訣: 小的 merge 大的)

git merge <branch name>

Ex: git merge dev

刪除 local 分支

git branch -d <branch name>

Ex: git branch -d dev

刪除 remote 分支

git push --delete <remote name><branch name>

Ex: git push --delete origin dev

Git Flow(git 開發專案流程)

如果有很多程式設計師同時開發一個專案, 如何有效的合作呢?而不是總是一直 commit 或 push 吧?前面所提到的 branch 設計也是一門學問呢!可參考這篇 Git flow ~

Extra(補充)

Github Project 提供了兩種存取方式

HTTPS: 上傳資料時(push..)需要輸入帳密, 如果不需要大多是帳密 Key Chain 已存在電腦內(如果帳戶要更換可將原本 github key chain 做刪除)

SSH: 必須先在電腦內設定好金鑰(公私鑰),上傳資料(push..)時不需要輸入額外帳密(教學)

Project README.md

建議在每個專案底下都要有一個 README.md,此檔案就是英文的 read me 囉! 也就是代表著整個專案的介紹、運作、設定或教學等。

.gitignore

這部份可有可不有,總之如果你不想把每個檔案都 git commit 的話,且不想在 git status 的時候一直存在它要求你 commit,你就可考慮用它,當然建議此檔案(.gitignore)也是要 git commit 會較好,因為它代表著我有某些檔案是存在但不需要 commit 上去,以方便提醒使用者。對了~ .gitignore 裡只要將相對路徑加入檔案內容中以跳行形式分開即可,如下圖所示:

.gitignore

而 .gitignore 如何生成呢? 你只要創一個檔案命名成這樣即可,或者直接在終端機下 touch .gitignore 也是一樣的效果。

Conclusion(結言)

那除了以上這些常使用到的指令以外, 其實還有許多指令或參數可以讓你在版本控制(Version Control)上更加得心應手!

當然!!!觀念也是很重要的~

非常感謝你閱讀完這篇文章,如果你覺得這篇文章對你有幫助, 請在底下幫我拍個手 ^^ 如果你有任何問題或者文章內容有誤請務必留言或寄信給我, 這樣對我幫助會很大, 再次感謝你~

信箱: ncku4alex@gmail.com

Github: https://github.com/Alex-CHUN-YU

Reference

  1. https://backlog.com/git-tutorial/
  2. https://www.atlassian.com/git/tutorials/
  3. https://blog.techbridge.cc/2018/01/17/learning-programming-and-coding-with-python-git-and-github-tutorial/
  4. https://gitbook.tw

--

--

CHIEN CHUN-YU
DAAI
Editor for

Hi~ My name is Alex ! I am a data engineer ! Data include data waiting for you to explore. BTW, a true master is an eternal student!