---
# System prepended metadata

title: Git Commit
tags: [git, git commit template]

---

# Git Commit

先找一個您手邊的git倉庫看一眼log

```=cmd
git log
#顯示第一行訊息
git log --oneline

#顯示 指定tag1與tag2 間的訊息
git log [tag1]..[tag2] --oneline

#指定tag1與tag2 指定顯示格式並匯出log檔案
git log --pretty=format:%h,%an,%ae,%s [tag1]..[tag2] > fileName.csv
```

如果出現的log會讓你 **渾身發癢 不可直視 有股衝動想刪除的時候**

可以參考以下做法 "疼惜自己,關懷別人"

如果沒有以上病徵, 那作參考即可
祝大家身體健康~ 萬事如意~
\>.^

## 1.Git Commit 規範參考

```git=
<type>: <subject>
//空行,空行,空行
<body>
``` 

各個標籤內容:
:::info
type:
* feat：新功能（feature）
* fix：修正bug
* docs：說明文件（documentation）
* style： 格式（不影響程式運作的更新）
* refactor：重構（即不是新增功能，也不是修改bug的程式更新）
* test：測試功能更新
* chore：構建過程或插件工具的更新異動
:::

:::info
subject:
* 以動词開頭，使用第一人稱現在式，比如change，而不是changed或changes
* 首字母小寫
* 结尾不加句點（.）
* 50字以內
* 側重描述功能而非內容
:::

:::info
body:
* 分段描述對應的細節
* 每段建議50/72字長度限制
* 首字母小寫
:::

## 可以接受的Commit

1. 這是一個 ~~標準範例?~~
```
feat: 一個載入後預設頁面功能

1.需額外加入判斷是否為TDSUser,是的話預設TaiwanCanHelp
2.User找來他主管跟我主官輸贏後請我幫忙把預設項目進行勾選
3.千萬部要學這種Commit info讓下個讀的Owner嚇到吃手手
```
2. 當一行可以說明的時候 千萬不要寫到三行...  ~謎之音:這樣有比較好?~
```
feat: User自以為勾選
```

### 要背嗎? 不! 我們來產生一個Commit參考檔

1. 前往路徑
C:\Users\\[Account]\

2. 在路徑下新增 .gitmessage 檔 (C:\Users\\[Account]\\.gitmessage)
並貼上以下內容 (==可依喜好自行調整==)
```
//這裡有空行,避免輸入一行commit的時候出現一堆隱藏訊息
# head: <type>: <subject>
# - type: feat, fix, docs, style, refactor, test, chore
# - subject: start with verb (such as 'change'), 50-character line
#
# body: 72-character wrapped. This should answer:
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# footer: 
# - Include a link to the ticket, if any.
# - BREAKING CHANGE
```
3. 新增 .gitconfig 檔
   (C:\Users\\[Account]\\.gitconfig)或有此檔案可直接進行修改即可
```
[user]
    email = user@gmail.com
    name = user
[core]
    excludesfile = C:\\Users\\[Account]\\.gitignore
[commit]
    template = C:\\Users\\[Account]\\.gitmessage
[alias]
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
```
4. 到某個git專案中再測試一下commit
```
git add .
git commit
#然後是不是有看到這份template檔?
```

:::warning 
Q:如何產生一個 .xxx 的檔案?
A:新增檔案重新命名後輸入 .xxx. 即可
.
Q:為何麼還有一個 .gitignore ?
A:聰明的你可以想一下他的作用
.
Q:.gitconfig檔中的\[alias\]是啥?
A:複製進去後您可以直行指令"git lg"來查看結果,然後有沒有其他你想[簡化](https://git.wiki.kernel.org/index.php/Aliases#Use_graphviz_for_display)的指令
:::

## 是不是至少多空一行Log世界會更美好?

請自行輸入以下Commit六次, 請自行替換X為數字
```
feat: this is feature [X]

1.do something first
2.do something else
3.fix some problem
```
再看一下log
```
git log --oneline
```
有比較舒服了嗎? 
~迷之音:如果沒有感覺,那也是蠻好的至少沒強迫症...~


P.S.測試後SVN也適用

## 其他常用指令參考


### 產生一個裸倉庫進行git遠端倉庫
```
#產生一個 orgin/master
>git init --bare d:/GitRepo/myProject.git

#以此裸倉進行專案複製
>git clone d:/GitRepo/myProject.git

#切換進入專案後進行開發
>cd myProject

#...加入檔案並commit到master後...
#將加入檔案更新到裸倉庫
>git push

#將其他人的資料拉回master
>git pull
#or
>git pull --rebase
```
#### 想把落落長的指令簡化?

```
git log --all --decorate --oneline --graph
# 或至少可以背的短一點
# 請參考 .gitconfig 中的 [alias] 標簽
git lg
```

#### 比對兩個檔案差異

```
#先查看log上的HashId
git log --oneline
git diff [oldversion] [newversion] > [輸出檔案路徑]

git diff                #工作目錄 vs 索引
git diff HEAD           #工作目錄 vs HEAD
git diff --cached HEAD  #索引 vs HEAD
git diff --cached       #索引 vs HEAD
git diff HEAD^ HEAD     #HEAD^ vs HEAD
```

# Problem resolve.

## merge後出現 ? (master|MERGING)

### 基本作法
>git status 查看有異常檔案
>一個一個修正,可快速搜尋 ===
>全部修正後在執行 git add .
>git commit '本次衝突更新說明'

### 快速比較差異
```
git diff --ours

//比較時去除空白
git diff --theirs -b

//以某一邊的版本進行修正
git checkout --theirs <conflict file>

//以遠端版本進行修正
git checkout origin/master <confilct files>
```

## 兩個Commit合併指令
[參考兩個Commit合併](https://gitbook.tw/chapters/rewrite-history/merge-multiple-commits-to-one-commit.html)
```
>git log --oneline

#此處的SHAID為要合併的兩個Commit的前一個標籤位置
>git rebase -i 'SHAID' 

==[VIM初始狀態]=======================================
#進入VIM編輯器挑選合併標籤
pick SHAID3 '時間點遠的標籤,Command'
pick SHAID2 '時間點中的標籤,Command'
pick SHAID1 '時間點近的標籤,Command'

==[VIM編輯狀態]========================================
#squash會一直找到Pick後合併, 以下修改會將 SHAID2,SHAID1 與 SHAID3 合併
pick SHAID3 '時間點遠的標籤,Command'
squash SHAID2 '時間點中的標籤,Command'
squash SHAID1 '時間點近的標籤,Command'

#完成選擇後儲存並退出(:wq), git會再次進入VIM, 但此次為更新Commit command

#更新要保留Command儲存並退出(:wq)即可完成
```

> 如有錯誤請再告知

參考來源:
[git commit說明](http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html)
[git commit膜版](https://gist.github.com/jmaxhu/8e7fb69a7dcec1b9b953)
[git 自訂指令](https://git.wiki.kernel.org/index.php/Aliases#Use_graphviz_for_display)
[git 高級合併](https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%AB%98%E7%BA%A7%E5%90%88%E5%B9%B6)
[git 實戰版本](https://git-tutorial.readthedocs.io/zh/latest/conflict.html)

###### tags: `git` `git commit template`