git 實作練習 3

@ver 0.1.3 @date 2020-02-21 22:02:21 (星期5)

@ver 0.1.2 @date 2019-04-13 23:21:03 (星期六)

@ver 0.1.1 @date 2019-03-04 22:06:13 (星期一)

  1. git 快速鍵

### 省時省力快速鍵

以下好用的 git 全域簡捷快速鍵, 請先執行設定, 或者直接複製主機已設好的 cp -fp /home/alex/.gitconfig ~/.gitconfig 覆蓋自己的版本

> 如果使用 cp -fp 要再做一次 user.name, user.email 的設定, 否則會變成 alex > > git config --global user.name > > git config --global user.email

#### 命令 ``` git config --global --replace-all core.pager "less -F -X" git config --global alias.a "add" git config --global alias.b "branch" git config --global alias.c "commit" git config --global alias.cm "commit -m" git config --global alias.ca "commit -a" git config --global alias.cam "commit -a -m" git config --global alias.co "checkout" git config --global alias.cob "checkout -b" git config --global alias.d "diff" git config --global alias.ds "diff --stat" git config --global alias.dc "diff --cached" git config --global alias.f "fetch" git config --global alias.i "init" git config --global alias.m "merge" git config --global alias.pu "push" git config --global alias.pl "pull" git config --global alias.s "status -s" git config --global alias.st "status"

git config --global alias.l1 "log --oneline" git config --global alias.l "log --date=iso --pretty=format:'[%C(red)#%h%C(reset)] %C(bold blue)%cn%C(reset), %C(green)%cr%Creset : %C(yellow)%d%C(reset) %s'" git config --global alias.ld "log --date=iso --pretty=format:'[%C(red)#%h%C(reset)] %C(bold blue)%cn%C(reset), %C(green)%cd%Creset : %C(yellow)%d%C(reset) %s'" git config --global alias.ln "log --date=iso --numstat --pretty=format:'[%C(red)#%h%C(reset)] %C(bold blue)%cn%C(reset), %C(green)%cd%Creset : %C(yellow)%d%C(reset) %s'" git config --global alias.ls "log --date=iso --stat --pretty=format:'[%C(red)#%h%C(reset)] %C(bold blue)%cn%C(reset), %C(green)%cr%Creset : %C(yellow)%d%C(reset) %s'" git config --global alias.lg "log --date=iso --graph --pretty=format:'[%C(red)#%h%C(reset)] %C(bold blue)%cn%C(reset), %C(green)%cr%Creset : %C(yellow)%d%C(reset) %s'"

git config --global alias.bx "for-each-ref --sort=-committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - [%(color:red)%(objectname:short)%(color:reset)] %(authorname), (%(color:green)%(committerdate:relative)%(color:reset)) : %(contents:subject)'"

git config --global alias.li "log --date=iso" ```

  1. revision range 釋疑

可以把它廣泛稱做 修訂提交記錄範圍, 許多命令及操作都會用到, 例如 git loggit diff ... 等

每一次提交, 就是一次 revision, 名詞, 中文翻譯為 修訂修正. 而 version 比較偏向是 版本. 所以這裡用修訂. 隨著 git 提交次數變多, 三不五時需要查找過去的 commit 相關資訊或 diff 程式碼差異, 為了避免一次列出 洛洛長 太多資訊影響判斷, 我們用 revision range 來限制顯示或比對的範圍.

### 重要 : revision range 的符號簡介

數量 : 可加在任何 revision range 之後, -1 列出最近 1 個提交, -2 列出最近 2 個, -3 列出最近 3 個, -999 列出最近 999 個. 這個命令類似我們常用的 head -88 filenametail -33 filename. HEAD : 是一個象徵性的指標, 通常會指向某個 branch (master 也算 branch) 最近一次 commit 的內容, 基本上 HEAD 代表現在工作區的指標, 但在查詢 log 或 diff 時可能會用到其他(例如 : master, origin, origin/master, origin/HEAD). HEAD^ : 後綴 ^ 往前 1 個提交, ^^ 往前 2 個, ^^^ 往前 3 個 HEAD~1 : 後綴 ~1 往前 1 個提交, ~2 往前 2 個, ~3 往前 3 個 HEAD@{1} : 後綴 @{1} 往前 1 個提交, @{2} 往前 2 個, @{3} 往前 3 個 ^HEAD : 在 HEAD 之前的前綴 ^ 符號, 代表邏輯 not, 跟後綴功能不同, 比較像 regex 空格 : 標示兩個指標的前後範圍, 從 A 到 B. .. : 雙點語法, A..B (兩個點) 表示只在 B 有的. 它指定了兩個引用中的任何一個都可以訪問的所有提交, 但不能同時訪問它們. 回顧示例歷史記錄中的示例提交歷史記錄以進行範圍選擇. * ... : 三點語法, 指定範圍, A...B (三個點) 表示只在 A 或 B 其中一邊. 指定兩個引用中的任何一個都可以訪問的所有提交, 但不能同時訪問它們.

### 使用 revision range 查看 log

git log 是用來查看修訂提交歷史記錄. 我們就邊查看 commit 提交 log, 邊學習 revision range, 以下都會使用 ~/.gitconfig 設定的 alias.l 以方便驗證並檢視結果, 請務必先設定

#### 命令執行及結果說明 shell # 基本用法 git log # 最後一次提交, 反序列出到第一次, 直到永遠 git l # 使用 Alias 最後一次提交, 反序列出到第一次, 直到永遠 # 列出提交數量 git l -1 # 最後一次提交, 反序列出到第一次, 但只列出最近 1 個 git l -2 # 最後一次提交, 反序列出到第一次, 但只列出最近 2 個 git l -3 # 最後一次提交, 反序列出到第一次, 但只列出最近 3 個 git l -4 # 最後一次提交, 反序列出到第一次, 但只列出最近 4 個 git l -999 # 最後一次提交, 反序列出到第一次, 但只列出最近 999 個 # 後綴 ^ 符號, 從那一次提交開始 git l HEAD # 最後一次提交, 反序列出到第一次, 同 git l git l HEAD^ # 倒數第二次提交, 反序列出到第一次 git l HEAD^^ # 倒數第三次提交, 反序列出到第一次 git l HEAD^^^ # 倒數第四次提交, 反序列出到第一次 # 後綴 ~ 符號, 從那一次提交開始(同上) git l HEAD~3 # 倒數第四次提交, 反序列出到第一次, 同上 git l HEAD~999 # 倒數第 999 次提交, 反序列出到第一次 # 後綴 ^~ 符號 + 列出提交數量 git l HEAD -1 # 最後一次提交, 反序列出最近 1 個, 等同於 git l -1 git l HEAD -2 # 最後一次提交, 反序列出最近 2 個, 等同於 git l -2 git l HEAD^ -3 # 倒數第二次提交, 反序列出最近 3 個 git l HEAD~3 -4 # 倒數第四次提交, 反序列出最近 4 個 # 後綴 ^~ 符號 + 空格或雙點語法, 注意 : 在 HEAD 之前的前綴 ^ 代表邏輯 not git l HEAD~6..HEAD~1 # 倒數第二次提交, 倒數第六次結束, 反序列出最近 5 個 git l ^HEAD~6 HEAD~1 # 倒數第二次提交, 倒數第六次結束, 反序列出最近 5 個 git l HEAD~1 --not HEAD~6 # 倒數第二次提交, 倒數第六次結束, 反序列出最近 5 個 git l HEAD~1..HEAD~6 # 不顯示 git l ^HEAD~1 HEAD~6 # 不顯示 git l HEAD~6 --not HEAD~1 # 不顯示 # 後綴 ^~ 符號 + 三點語法 git l HEAD~6...HEAD~1 # 倒數第二次提交, 倒數第六次結束, 反序列出最近 5 個 git l HEAD~1...HEAD~6 # 倒數第二次提交, 倒數第六次結束, 反序列出最近 5 個, 同上 git l HEAD~6...HEAD~6 # 不顯示

  1. git log 探索

### 標準 commit 訊息

log修訂提交歷史記錄 的檢閱器, 我們先分析它的標準 commit 訊息

#### 命令 bash git log [各式各樣的參數]

#### 執行結果 shell [alex@nvda /tmp/prj1 ]$ git log 1 commit 821764e6ecfc1b3d6dafba18361a5d8f1e494af8 2 Author: alex <alex@forblind.org.tw> 3 Date: Fri Mar 1 13:48:47 2019 +0800 4 5 從暫存區(索引)移除不要追踪的檔案 6 7 commit cd002dc3023c214120b3eb9e50a177d28a66fb26 8 Author: alex <alex@forblind.org.tw> 9 Date: Fri Mar 1 10:44:21 2019 +0800 10 11 實測 .gitignore 完成 12 13 commit f2ed5d757c9a81de0d1ccd601af1e4a6a48333e4 14 Author: alex <alex@forblind.org.tw> 15 Date: Tue Feb 19 16:24:19 2019 +0800 16 17 第一次提交到 git repo [alex@nvda /tmp/prj1 ]$

#### 訊息解釋 plaintext 每一組 log 有多行, 包括幾個資訊 第一行 commit 後面是 40 bytes 的 SHA1 Hash. 第二行 Author: 是作者姓名及他的電子郵件, 這個值在 git config --global 設定過. 第三行 Date: 日期, 目前是預設美式日期時間格式. Tue Feb 19 16:24:19 2019 +0800 第四行空行, 接著好幾行是我們提交訊息, 最後再接一個空行.

### 簡易 commit 訊息

為了快速方便查閱, 有很多格式可以設定簡化的顯示訊息, 參考 Git 基礎 - 檢視提交的歷史記錄

以下兩個常用範例, 我們已定義在先前的 git config --global 裡的 alias.lalias.ld, 主要是時間顯示方式, 各有方便之處

#### 命令 bash git l [各式各樣的參數]

#### 執行結果 shell [alexkuo : /tmp/prj1 ] ➠ $ git l 1 [#821764e] alex, 6 weeks ago : (HEAD -> master) 從暫存區(索引)移除不要追踪的檔案 2 [#cd002dc] alex, 6 weeks ago : 實測 .gitignore 完成 3 [#f2ed5d7] alex, 8 weeks ago : 第一次提交到 git repo [alexkuo : /tmp/prj1 ] ➠ $

#### 訊息解釋 plaintext 簡化單行之一 log 有 4 或 5 個部份 1. 七碼 HASH : [#821764e] 中括號#為 SHA1 Hash 前七碼 2. 姓名 : alex 為提交者姓名 3. 時間 : 6 weeks ago , 提交時的時間, 但用相對於現在的時間多久來顯示 4. (HEAD -> master) : git HEAD 索引位置指示, 只有第一個會有 5. 提交內容 : 提交內容的第一行, 如果有多行, 也只會顯示第一行

#### 命令 bash git ld [各式各樣的參數]

#### 執行結果 shell [alexkuo : /tmp/prj1 ] ➠ $ git ld 1 [#821764e] alex, 2019-03-01 13:48:47 +0800 : (HEAD -> master) 從暫存區(索引)移除不要追踪的檔案 2 [#cd002dc] alex, 2019-03-01 10:44:21 +0800 : 實測 .gitignore 完成 3 [#f2ed5d7] alex, 2019-02-19 16:24:19 +0800 : 第一次提交到 git repo [alexkuo : /tmp/prj1 ] ➠ $

#### 訊息解釋 plaintext 簡化單行之二 log 有 4 或 5 個部份 1. 七碼 HASH : [#821764e] 中括號#為 SHA1 Hash 前七碼 2. 姓名 : alex 為提交者姓名 3. 時間 : 2019-03-01 13:48:47 +0800 , 提交時的時間, 用 iso 格式顯示 4. (HEAD -> master) : git HEAD 索引位置指示, 只有第一個會有 5. 提交內容 : 提交內容的第一行, 如果有多行, 也只會顯示第一行

  1. git diff 第一次接觸

### 基本操作說明

diff 用來檢視文件差異

#### 命令 bash git diff [各式各樣的參數]

### 工作區已提交到最後版本

#### 命令 bash git diff git diff HEAD

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git diff [alex@nvda ~/ak1 ]$ git diff HEAD [alex@nvda ~/ak1 ]$

這兩個命令都相同, 表示現在工作區跟最後一次提交的差異, 因為最後版本已提交, 又沒有任何修改, 所以 git 沒有任何回應. 也就是說最後一個參數若為空白, 等同於指向 HEAD

現在修改 routes/web.php resources/views/abcd.blade.php 這兩個檔, 再做一次 diff

#### 命令 bash vi routes/web.php vi resources/views/abcd.blade.php vi resources/views/my.blade.php git diff

#### 執行結果 [alex@nvda ~/ak1 ]$ git diff 1 diff --git a/resources/views/abcd.blade.php b/resources/views/abcd.blade.php 2 index d5e6c3e..b42885c 100644 3 --- a/resources/views/abcd.blade.php 4 +++ b/resources/views/abcd.blade.php 5 @@ -1 +1,2 @@ 6 -你好, 我是 ben 7 +你好, 我不是 ben 8 +<p>這是測試</p> 9 diff --git a/routes/web.php b/routes/web.php 10 index 643ecee..0444bda 100644 11 --- a/routes/web.php 12 +++ b/routes/web.php 13 @@ -15,7 +15,7 @@ Route::get('/', function () { 14 return view('welcome'); 15 }); 16 17 -Route::get('/a', function () { 18 +Route::get('/abcd', function () { 19 return view('abcd'); 20 }); 21 [alex@nvda ~/ak1 ]$ $

#### 訊息解釋 plaintext 每一組檔案區塊都從 diff --git 開始, 有幾個基本資訊 : 1 diff --git a/resources/views/abcd.blade.php b/resources/views/abcd.blade.php 第一行 diff --git 後面是兩組檔名, a/... 指向最後提交 HEAD 的檔案, b/... 則是工作區檔案 2 index d5e6c3e..b42885c 100644 第二行 index ... 檔案編碼記號, 暫時不用看它 3 --- a/resources/views/abcd.blade.php 第三行 (舊)最後提交在 HEAD 的檔案 4 +++ b/resources/views/abcd.blade.php 第四行 (新)現在工作區的檔案 5 @@ -1 +1,2 @@ 第五行 段落新舊差異位置指引 6 -你好, 我是 ben 7 +你好, 我不是 ben 8 +<p>這是測試</p> 第六行~第八行 第一個字元 '-' 舊檔案的內容, '+' 新檔案的內容, 這裡表示刪掉第六行, 增加了第七, 八行 一個檔案可能有很多段差異, 都是從 [段落新舊差異位置指引] 的 [@@ ...... @@] 開始 在顯示差異時, 可能會有一些第一個字元不是 '-' 也不是 '+', 代表兩個檔案相同的地方, diff 是用行為單位來比對 9 diff --git a/routes/web.php b/routes/web.php 第九行 又是新的一個檔案差異開始

剛剛這個指令, 並沒有下任何參數, 預設值就是 現在工作區最後一次提交(HEAD) 的所有檔案差異比對

### 指定檔案差異比對

#### 命令 bash git diff routes/web.php

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git diff routes/web.php 1 diff --git a/routes/web.php b/routes/web.php 2 index 643ecee..0444bda 100644 3 --- a/routes/web.php 4 +++ b/routes/web.php 5 @@ -15,7 +15,7 @@ Route::get('/', function () { 6 return view('welcome'); 7 }); 8 9 -Route::get('/a', function () { 10 +Route::get('/abcd', function () { 11 return view('abcd'); 12 }); 13 [alex@nvda ~/ak1 ]$ $

### 增加 revision range 差異比對, 第一次只設定多一個 HEAD

#### 命令 bash git diff HEAD

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git diff HEAD 1 diff --git a/resources/views/abcd.blade.php b/resources/views/abcd.blade.php 2 index d5e6c3e..b42885c 100644 3 --- a/resources/views/abcd.blade.php 4 +++ b/resources/views/abcd.blade.php 5 @@ -1 +1,2 @@ 6 -你好, 我是 ben 7 +你好, 我不是 ben 8 +<p>這是測試</p> 9 diff --git a/resources/views/my.blade.php b/resources/views/my.blade.php 10 new file mode 100644 11 index 0000000..cf0bcd3 12 --- /dev/null 13 +++ b/resources/views/my.blade.php 14 @@ -0,0 +1,2 @@ 15 +<div>測試差異</div> 16 + <p>第二段</p> 17 \ No newline at end of file 18 diff --git a/routes/web.php b/routes/web.php 19 index 643ecee..0444bda 100644 20 --- a/routes/web.php 21 +++ b/routes/web.php 22 @@ -15,7 +15,7 @@ Route::get('/', function () { 23 return view('welcome'); 24 }); 25 26 -Route::get('/a', function () { 27 +Route::get('/abcd', function () { 28 return view('abcd'); 29 }); 30 [alex@nvda ~/ak1 ]$ $

看起來跟 git diff 相同, 但又有點不同, 仔細比較, 才發現多了新建立的 resources/views/my.blade.php 檔案差異比對, 其實這可看可以不看, 因為既然是新的, 找不到舊檔, 也沒什麼好比對. 但是它還是不辭辛勞的把它列出來.

### 增加 revision range 差異比對, 第二次改用 HEAD^ HEAD 兩個

HEAD^ 就是比對上次(倒數第二次)提交, 跟 HEAD 最後(倒數第一次)提交的檔案差異. 習慣把更舊的版本放前面, 較新的版本放後面, 看到記號 - 開頭的那一行就當作刪掉內容, 記號 + 開頭的那一行就當作新增內容.

#### 命令 bash git diff HEAD^ HEAD

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git diff HEAD^ HEAD 1 diff --git a/resources/views/abcd.blade.php b/resources/views/abcd.blade.php 2 new file mode 100644 3 index 0000000..d5e6c3e 4 --- /dev/null 5 +++ b/resources/views/abcd.blade.php 6 @@ -0,0 +1 @@ 7 +你好, 我是 ben 8 diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php 9 index 599264c..5ba7e32 100644 10 --- a/resources/views/welcome.blade.php 11 +++ b/resources/views/welcome.blade.php 12 @@ -82,6 +82,7 @@ 13 <div class="content"> 14 <div class="title m-b-md"> 15 Alex's Laravel 16 + <span>改</span> 17 </div> 18 19 <div class="links"> 20 diff --git a/routes/web.php b/routes/web.php 21 index 810aa34..643ecee 100644 22 --- a/routes/web.php 23 +++ b/routes/web.php 24 @@ -14,3 +14,8 @@ 25 Route::get('/', function () { 26 return view('welcome'); 27 }); 28 + 29 +Route::get('/a', function () { 30 + return view('abcd'); 31 +}); 32 + [alex@nvda ~/ak1 ]$ $

#### 訊息解釋 shell 在這兩次不同提交裡, 三個不同檔案的 diff 結果 1 diff --git a/resources/views/abcd.blade.php b/resources/views/abcd.blade.php 2 new file mode 100644 3 index 0000000..d5e6c3e 4 --- /dev/null 5 +++ b/resources/views/abcd.blade.php 第二行 因為剛好 a/resources/views/abcd.blade.php 是新的檔案, 所以會有顯示 new file mode 100644 第四行 --- /dev/null 表示此檔案, 舊的 HEAD^ 那一階段並不存在 第五行 +++ b/resources/views/abcd.blade.php 新檔案, 提交在 HEAD 裡

  1. 編寫優良的 git 提交訊息

原文網頁

參考 : 撰寫有效的-git-commit-message

使用 git 提交 (commit) 程式碼修訂時, 有沒有思考一下好好的寫提交訊息嗎 ? 讓工作伙伴看得懂你的修改目的 ?

### 文章作者建議好的 git 提交訊息要包含

1. { style=list-style-type:decimal; } 主旨(Subject) : 必填, 一小段簡短的總結, 小於 50 個字元, 就像電子郵件的主旨一樣, 例如 修正部份會員無法登入完成信用卡刷卡 API工作中... 2. 說明(Body) : 不一定要有, 主要是寫變更了那些? 為何變更? 建議每行少於 72 個字元, 儘可能詳細, 可以多寫幾行. 3. 結尾(Bottom line) : 不一定要有, 如果使用問題追踪系統, 這裡可以寫解決了那一個問題的問題編號, 例如 Resolves #N / Closes #N, N 是問題編號.

### 作者示範 git commit 的訊息, 如下

#### 原文訊息 ``` Fix error when protocol is missing

First, it checks if the protocol is set. If not, it changes the url and add the basic http protocol on the beginning. Second, it does a "preflight" request and follows all redirects and returns the last URL. The process then continues with this URL.

Resolves #17 ```

#### 訊息對照說明 plaintext 第 1 行, `Fix error ...` 是主旨 第 2 行, 空行, 分隔主旨跟說明 第 3~6 行, 說明, 清楚描述此次做了那些修正 第 7 行, 空行, 分隔說明跟結尾 第 8 行, 結尾, 寫出解決問題編號 #17

#### 中文翻譯 ```plaintext 修正有時 protocol 協議消失的錯誤

1. 檢查 protocol 是否已設定. 如果沒有, 變更 url 並 在開始時增加基本 http protocol. 2. 執行 "preflight" 並跟隨所有重導向及 返回到最後. 此程序會持續在此 URL 作業

解決 #17 ```

### 不良的提交訊息示範

下列訊息, 很簡短, 但不夠有力, 可能只有提交的人才知道改了什麼

#### 訊息主旨 plaintext cd3e27a contact page aee9d0d comments eac95e5 list of online users, some other changes because of server fae5636 little edit

### 優良的提交訊息示範

以下這些訊息, 雖然簡短, 但看起來還可理解, 請參考

#### 訊息主旨 plaintext 43ec6aa Fix error when the URL is not reachable 4fe84ab Add error message if something went wrong 753aa05 Add server fingerprint check df3a662 Fix shadow box closing problem

  1. 版本字號

維基 - 軟體版本號

主版本號.子版本號[.修正版本號[.編譯版本號]]

Major.Minor[.Revision[.Build]]

例如 : 0.1.8, 1.12.35, 2.0, 7.2.3 build-2189

### 版本更動策略建議

1. First : 專案剛開始建立基礎版本時, 版本號可以為 0.1 或 0.1.0, 也可以為 1.0 或 1.0.0, 如果你為人很低調, 我想你會選擇那個主版本號為 0 的方式 :-D 2. Revision : 當專案進行中, 做了局部修改或 bug 修正時, 主版本號(Major)和子版本(Minor)號都不變, 修正版本號(Revision)加 1. 3. Minor : 當專案在原有的基礎上增加部分功能, 主版本號(Major)不動, 子版本號(Minor)加 1, 修正版本號(Revision)再歸零. 4. Major : 當專案進行了重大修改或局部修正累積較多, 而導致專案整體變化時, 主版本號(Major)加 1, 其餘歸零. 5. Build : 編譯版本號(build)一般是編譯器在編譯過程中自動產生, 我們只記錄, 不進行人為控制. 6. 另外在版本號後會加入後綴, 如 Alpha(內部測試版), Beta(外部測試版), Gamma(成熟版), RC (Release Candidate)(發佈候選版), Release(正式版), Stable(穩定版) 等, 大家參考使用.

  1. 本章總結

### 本章使用 git 命令總結 bash git config --global alias.XYZ = "..." # 全域設定 git XYZ 簡捷快速鍵 'revision range' # 修訂提交記錄範圍 git log # 修訂提交歷史記錄的檢閱器 git diff # 文件差異檢視, 預設從 `HEAD(舊)` 到 `工作區(新)` 差異, 只有曾經提交過的檔案 git diff HEAD # 從 `HEAD(舊)` 到 `工作區(新)` 差異, 會顯示新建立在工作區的檔案 git diff routes/web.php # 從 `HEAD(舊)` 到 `工作區(新)` 差異, 指定 routes/web.php git diff HEAD^ HEAD # 從 `HEAD^(舊)` 到 `HEAD(新)` 差異 git diff HEAD^^ HEAD # 從 `HEAD^^(舊)` 到 `HEAD(新)` 差異 git diff HEAD^^ HEAD routes/web.php # 從 `HEAD^^(舊)` 到 `HEAD(新)` 差異, 指定 routes/web.php good git commit message # 優良的 git 提交訊息 Major.Minor.Revision.Build # 版本字號

  1. 補充之一

@date 2020-02-21 22:03:24 (星期5)

解決 git diff 出現 ^M 的 LF 與 CRLF 的問題

使用前

[alexkuo : ~ ] ➠ $ git diff HEAD~ HEAD~~
      1 diff --git a/ooo.php b/ooo.php
      2 index 7270d7b..3d2bb8d 100644
      3 --- a/ooo.php
      4 +++ b/ooo.php
      5 @@ -1,7 +1,7 @@
      6  <?php
      7  // 設定環境參數 及 引入檔案
      8  session_start();
      9 -ini_set("display_errors", "Off"); // 顯示錯誤是否打開( On=開, Off=關 )
     10 +ini_set("display_errors", "On"); // 顯示錯誤是否打開( On=開, Off=關 )^M
     11  error_reporting(E_ALL & ~E_NOTICE);
     12  date_default_timezone_set('Asia/Taipei');
     13  ini_set('upload_max_filesize', '256M');
[alexkuo : ~ ] ➠ $

問題 : 第 10 行最後有 ^M

解決方法 : 請執行

git config --global core.whitespace cr-at-eol
[alexkuo : ~/jobs ] ➠ $ git diff HEAD~ HEAD~~
      1 diff --git a/ooo.php b/ooo.php
      2 index 7270d7b..3d2bb8d 100644
      3 --- a/ooo.php
      4 +++ b/ooo.php
      5 @@ -1,7 +1,7 @@
      6  <?php
      7  // 設定環境參數 及 引入檔案
      8  session_start();
      9 -ini_set("display_errors", "Off"); // 顯示錯誤是否打開( On=開, Off=關 )
     10 +ini_set("display_errors", "On"); // 顯示錯誤是否打開( On=開, Off=關 )
     11  error_reporting(E_ALL & ~E_NOTICE);
     12  date_default_timezone_set('Asia/Taipei');
     13  ini_set('upload_max_filesize', '256M');
[alexkuo : ~/jobs ] ➠ $

結論 : 第 10 行最後的 ^M 已消失

另外, 關於 autocrlf, 可參考 Git 的 core.autocrlf 參數

  1. 補充之二

git diff 權限 755 644

@date 2020-02-21 22:20:28 (星期5)

權限問題

[alexkuo : ~/jobs ] ➠ $ git diff
     23 diff --git a/.htaccess b/.htaccess
     24 old mode 100644
     25 new mode 100755
     26 diff --git a/controllers/.htaccess b/controllers/.htaccess
     27 old mode 100644
     28 new mode 100755

執行以下命令把所有 755 的檔案, 一次全改為 644 , 可解決上述問題
cd ~/jobs
find . -type f -perm 755 -print -exec chmod 644 {} \;

以下命令請參考
find /var/www/html -type d -exec chmod u=rwx,go=rx {} \;
find /var/www/html -type f -exec chmod u=rw,go=r {} \;
find /var/www/html -type f -perm 700 -print
find /var/www/html -type f -perm 700 -print -exec chmod 755 {} \;