git 是一個分散式版本控制軟體,最初由林納斯·托瓦茲創作,於2005年以GPL釋出。最初目的是為更好地管理Linux核心開發而設計。應注意的是,這與GNU Interactive Tools不同。 git最初的開發動力來自於BitKeeper和Monotone。

Learning Git

Git Commands Work


Git Tools
Git Server

Git Installation

Git Client

# CentOS/RedHat 5/6
# Install from source
# Get the required version of GIT from
yum install zlib-devel openssl-devel cpio expat-devel gettext-devel
tar xzf git-2.0.5.tar.gz
cd git-2.0.5
./configure --prefix=/opt/git-2.0.5
make install 

Git Tips

# Using git to edit the configuration
git config global --edit

# List the global configurations
git config --global --list

# Using vi/cat to edit the configuration
vi ~/.gitconfig

# Set the author's email address and name
git config --global ""
git config --global "Alang Hsu"

# Set default editor
git config --global core.editor "vi"

# Set default branch name
git config --global init.defaultBranch "main"


	email =
	name = Alang Hsu
	editor = vi
	defaultBranch = main
mkdir test-git-push
cd test-git-push
git init
git config --global "<user-name>"
git config --global "<your-email-addr>"
echo "Test Git Push only" >
git add .
git commit -m "Initial commit"
git remote add origin https://<user-name>
git remote -v
git push -u origin master

專案目錄下的檔案或子目錄的更名動作,必須使用 git 指令。

git mv <old-folder> <new-folder>
Commit 訊息

簡單的 commit 訊息

git commit -m "Fixed a typo in somewhere"

免 add 快速 commit (僅限 edited & deleted)

git commit -am "<commit-message>"


# 設定 Vim 作為編輯器
git config --global core.editor "vim"

# 不要加 -m 參數
git commit 

Commit 訊息編寫原則

  1. 用一行空白行分隔標題與內容
  2. 限制標題最多只有 50 字元
  3. 標題開頭要大寫
  4. 標題不以句點結尾
  5. 以祈使句撰寫標題
  6. 內文每行最多 72 字
  7. 用內文解釋 what 以及 why vs. how

檢視 Comments

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

修改最後一筆 Comment

git commit -v --amend
Clone for specified branch version
# Specified version
git clone -b 8.3.0 /var/www/opensips-cp
SSH Key Authentication
# 建立 ssh-key
# 預設路徑: ~/.ssh/id_rsa (private key) , ~/.ssh/ (public-key)
ssh-keygen -t rsa -b 4096 -C "alang@my-linux-desktop"

# Gitlab 網站匯入 public ssh-key
# 測試 ssh key authentication
# 如果輸出 Welcome to GitLab, @alang! 表示連線認證成功
ssh -T

# 下載專案
# NOTE: 位址必須是 開頭。
# 如果使用 https:// 則必須改用 Personal Token 認證方式  
git clone
# 還沒執行 git add 前,比對目前檔案與最近一次 commit 版本的內容差異
git diff file

# 比對兩個檔案的內容差異
git diff --word-diff file1 file2

# 檢視兩個 Commit 版本的內容差
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
git diff <old-commit-id> <new-commit-id>
Undo in Git

Local unstaged changes (還沒有 add)

git status
git restore <filename>

Local staged changes (已經 add 還沒有 commit)

git status
git restore --staged <filename>
git restore <filename>

Local committed changes (已經 commit 還沒有 push)

git status
git log
git reset --soft HEAD~
git log

NOTE: 上述指令是回復最新的 commit,如果是更早的 commit,可以執行 git reset <commit-id>,而 commit-id 可以從 git log --oneline 找到。

不過,如果 commit 已經 push 到遠端庫,必須改用 git revert

Public committed changes (已經 push) 

git log --oneline
git revert <last-commit-id> --no-edit
git push
git log

NOTE: 在執行 git revert後,log 會多一條 Revert "XXXX" 的 commit 紀錄,原先的 commit 紀錄也會保留。

Git Prompt with bash


# Kali-like Prompt with Git status

git_stats() {
  local STATUS=$(git status -s 2> /dev/null)
  local UNTRACKED=$(echo "$STATUS" | grep '^??' | wc -l)
  local STAGED=$(($(echo "$STATUS" | grep '^M ' | wc -l) + $(echo "$STATUS" | grep '^D ' | wc -l) + $(echo "$STATUS" | grep '^R ' | wc -l) + $(echo "$STATUS" | grep '^C ' | wc -l)+$(echo "$STATUS" | grep '^A ' | wc -l)))
  local DRC=$(($(echo "$STATUS" | grep '^ D' | wc -l) + $(echo "$STATUS" | grep '^ R' | wc -l) + $(echo "$STATUS" | grep '^ C' | wc -l)))
  local MODIFIED=$(echo "$STATUS" | grep '^ M' | wc -l)
  local STATS=''
  if [ $UNTRACKED != 0 ]; then
    STATS="\e[43m untr: $UNTRACKED "
  if [ $MODIFIED != 0 ]; then
    STATS="$STATS\e[43m mod: $MODIFIED "
  if [ $DRC != 0 ]; then
    STATS="$STATS\e[43m drc: $DRC "
  if [ $STAGED != 0 ]; then
    STATS="$STATS \e[42m staged: $STAGED "
  if [ ! -z "$STATS" ]; then
  echo -e "\e[30m $STATS\e[0m"

function origin_dist {
 local STATUS="$(git status 2> /dev/null)"
 local DIST_STRING=""
 local IS_AHEAD=$(echo -n "$STATUS" | grep "ahead")
 local IS_BEHIND=$(echo -n "$STATUS" | grep "behind")
 if [ ! -z "$IS_AHEAD" ]; then
  local DIST_VAL=$(echo "$IS_AHEAD" | sed 's/[^0-9]*//g')
 elif [ ! -z "$IS_BEHIND" ]; then
  local DIST_VAL=$(echo "$IS_BEHIND" | sed 's/[^0-9]*//g')
 if [ ! -z "$DIST_STRING" ]; then
  echo -en "\e[97;45m $DIST_STRING"

__PS1_GIT_BRANCH='`__git_ps1` '
__PS1_GIT_STATS='`git_stats` '

if $(__git_ps1 2>/dev/null);then
    PS1="\[\033[38;5;209m\]┌──[\[\033[38;5;141m\]\u\[\033[38;5;209m\]@\[\033[38;5;105m\]\h\[\033[38;5;231m\]:\w\[\033[38;5;209m\]]\[\033[33m\]${__PS1_GIT_BRANCH}${__PS1_GIT_DIST}${__PS1_GIT_STATS}\[\033[00m\]\n\[\033[38;5;209m\]└─\\[\033[38;5;209m\]\\$\[\033[37m\] "
    source /usr/share/git-core/contrib/completion/
    PS1="\[\033[38;5;209m\]┌──[\[\033[38;5;141m\]\u\[\033[38;5;209m\]@\[\033[38;5;105m\]\h\[\033[38;5;231m\]:\w\[\033[38;5;209m\]]\[\033[33m\]${__PS1_GIT_BRANCH}${__PS1_GIT_DIST}${__PS1_GIT_STATS}\[\033[00m\]\n\[\033[38;5;209m\]└─\\[\033[38;5;209m\]\\$\[\033[37m\] "
Git Rebase


[GitHub] 無法 git push


remote: Support for password authentication was removed on August 13, 2021.
remote: Please see for information on currently recommended modes of authentication.
fatal: '' 身份驗證失敗

解決方案:從 2021/8/13 起,GitHub 在 push 專案時不再接受密碼認證,替代方法可以使用一個較快速的 personal token。

先從 GitHub 網站新增一個 personal token

GitHub > Setting > Developer Settings > Personal Access Token > Tokens (classic)

這個 token 是用來取代密碼,git push 時出現密碼詢問,就輸入 token。

如果不想每次都輸入 token,可以將 token 記憶在系統裡

git config --global credential.helper cache

更換 token 後,刪除舊的 token

git config --global --unset credential.helper
git config --system --unset credential.helper
git clone 錯誤訊息

(gnome-ssh-askpass:23713): Gtk-WARNING **: cannot open display



永久解法: 編輯 ~/.bash_profile

# Fixed for the error with the git

Git 進階使用

使用 rev-parse
# Getting the top-level directory
git rev-parse --show-toplevel

# Find your way home
git rev-parse --show-cdup

## Current location
# 判斷是否在專案目錄 <git-repo>/.git 底下 
git rev-parse --is-inside-git-dir
# 判斷是否在專案目錄 <git-repo> 底下 (不包含 .git 目錄下)
git rev-parse --is-inside-work-tree

Contribute to Github

Steps to contribute your changes / patches in open source repository.

Preparing your Fork

1. Hit 'fork' on Github, creating e.g. yourname/theproject

2. Clone your project:

git clone

3. Create a branch:

cd theproject
git checkout -b foo-the-bars 3.5.
Making your Changes

1. Add changelog entry crediting yourself.

2. Write tests expecting the correct/fixed functionality; make sure they fail.

3. Hack, hack, hack.

4. Run tests again, making sure they pass.

5. Commit your changes:

git commit -m "Foo the bars"
Creating Pull Requests

1. Push your commit to get it back up to your fork:

git push origin HEAD

2. Visit Github, click handy “Pull request” button that it will make upon noticing your new branch.

3. In the description field, write down issue number (if submitting code fixing an existing issue) or describe the issue + your fix (if submitting a wholly new bugfix).

4. Hit ‘submit’! And please be patient - the maintainers will get to you when they can.