影片網址:https://youtu.be/WWntXUUVnG8
教學文件:https://quip.com/wHoZADrso6Sx
3-2-GitHub Fork 將數據庫複製一份到自已的數據庫列表中
1-還原技巧
1 2 3 4 5 6 7 | mkdir protect // 前往桌面後,建立一個資料夾 protect cd protect // 進入資料 git init // 建立本地數劇庫 touch index.html // 新建 index 檔 touch all.css // 新建 all.css 檔 git add . // 加入索引 git commit -m 'add index' // 加入提交訊息 add index |
目前有一個 commit 記錄點。
接著在 index.html 的結構與 <h1>1234</h1>, all.css 加入 body{color: red;} 內容。
切回到終端機上輸入下面指令。
1 2 | git add . git commit -m 'add title style' |
目前的話有二個 commit 記錄點,將資料夾加入到 sourcetree 裡,確任裡面有二個 commit 記錄點。
1-1-還原記錄點 git reset HEAD^ (將原本提交的記錄點退回到工作目錄狀態)
在到 index.html 裡的 <h1>1234這是標題~~</h1> 加入字串內容 這是標題~~,改完後切到終端機輸入下面指令。
1 2 | git add . git commit -m "add title style" |
目前有三個 commit 記錄點。
後來發現在第三個 commit 記錄點裡,所修改的內容是不需要,要將此 commit 記錄點捨棄。
使用 git reset HEAD <參數> , HEAD 就是當前所在的位置,如果要往回退一個記錄點並將記錄點捨棄的話,就在加上一個 ^ (如果要括棄二個記錄點,就是使用 ^^ 二個),輸入下面的完整指令就會退回一個記錄點並括棄當前的記錄點。
1 | git reset HEAD^ |
20211021-使用 git reset 指令在 master 分支上,無法直接透過 git reset HEAD^ 的方式,將 commit 做退一次的動作,會回應 no matches found: HEAD^。
在 master 主要分支上,要執行退 commit 動作的話,只能使用 git reset <hash 4 碼 or 全碼> 的方式,指定要退的 commit 記錄點。
指令輸入完成後切換到 souretree 上查看,原本第三個記錄點的 master 退到第二點,而第三個記錄點就會成為目前工作目錄的的狀態 (等同於第二個記錄點上檔案有更動續未加入索引),上面寫著 Uncommitted changes 的訊息。
另外還原後的 index.html 內的標題多加入字串 這是標題~~ 也還是在。
目前的資料夾狀態,就是將原本提交到本地數據數的記錄點,將狀態退回到工作目錄上,等待要處理第二個記錄點後的修改。
加入二個字元 !! ,並查看 sourcetree 裡也還是 Uncommitted changes 的狀態。
接著在終端機輸入
1 2 | git add . git commit -m "正確的標題名稱" |
輸入完成後在查看 sourcetree 的 commit 訊息與修改的內容都同樣修正。
1-2-直接退到指定的記錄點上,還原時略過將工作目錄狀態
輸入指令後帶上參數 --hard ,就會退到指定的還記錄點上,而還原時略過工作目錄的狀態。
輸入下面指令後,直接還原到第二次 commit 的記錄點狀態。
1 | git reset HEAD^ --hard |
目前輸入指令的情形是由原本的三個記錄點,退回為二個記錄點的狀態。
git reset 指的是在目前的 HEAD 與分支,前往到某個分支上,而後方的 HEAD^ 是以目前的 HEAD 為目前路徑,向前 (之前記錄點) 退一個記錄點
2-checkout 與 reset 差異
2-1-checkout HEAD 到指定的記錄點上
可直接移動 HEAD 的位置,在目前的分支上移到指定的記錄點上。
1 | git checkout <commit 的 HASH1 編號> |
使用 git log 指令來查 commit 的 HASH1 的編號,例如最新的 commit 記錄點的編號就是 08398c,第一個 comit 為 8f65749,比照 sourcetree。
終端機上輸入指令 git checkout 8f65749 ,此時在終端機上的分支狀態就會提示到 HEAD 目前的記錄點編號。
此時查看 HEAD 就會跳到指定的記錄點上,與分支 master 上的點是分開的。
目前的 HEAD 移動的記錄位置,就在 master 分支的後方, HEAD 可以任意切換到指定分支的記錄點上。
而 git reset 的部份,主要是針的還的記錄點, HEAD 與 master 分支記錄點,會同時移動到指定的記錄點上。
透過 git checkout <commit 編號> , HEAD 的位置可以任意移動,所以如果要切到遠端分支上取用檔案狀態的話,就可以將 HEAD 切到指定的遠端分支上的 commit 記錄點上。
2-2-使用 checkout 切換 HEAD 流程操作
2-2-1-例題一 (HEAD 切換到指定的 commit 記錄點上)
目前還在 bugFix 分支上,要將 HEAD 獨立出來切換,前往 c4 的位置上。
輸入指令 git checkout c4 就可以將 HEAD 獨立出分支外。
2-2-2-例題二 (HEAD 切換到指定的 commit 記錄點上)
將 master 的 HEAD 切換到 c3。
1 | git checkout c3 |
2-2-3-例題三 (git reset 退到指定的 commit 記錄點後與其他分支合併後在新增 commit 記錄點 )
原本的 c6 有使用 git reset 讓 bugFix 分支還原到 c5 上,現在希望 master 可以到 c6 的位置上。
git checkout master 將 HADE 切到 master 分支上。
git reset 算是還原,可以 HEAD 標籤與 master 分支記錄點上,前往到某處過去,接著輸入 git reset c6。
可以把原有的記錄點所對應上檔案
master – c2(all1.css), c4(all2.css)
bugFix – c3(all1.js), c5(all2.js), c6(all3.js)這裡要注意,如果是在實際使用終端機指令時,是將 master 移動到 c6 上,但實際操作發現要配合上 --hard 參數使用 git reset,工作目錄上的檔案才會清空完整的移動到 c6 上。
得到的檔案會有 all1.js, all2.js, all3.js如果在沒加 --hard 參數,由 c4 的 master 與 HEAD 還遠到 c6 ,但工作目錄上依然會帶有著 c4 c2 的相關內容。
得到的檔案會有 all1.css, all2.css,而此時會超過 c6 的還原點的工作目錄的狀態 (已追蹤),而 all1.js, all2.js, all3.js 會是刪除而不見於資料夾內。可使用 git reflog 指令,可查看所用過記錄點的 HASH1 的編號。
將 bugFix 分支退到 c0,輸入指令 git checkout bugFix,將 bugFix 分支還原到 c0,輸入指令 git reset c0。
目前的 HEAD 位置與 bugFix 同在 c0 ,要將 HEAD 移動到 c1,輸入指令 git checkout c1。
git reset 可以將 HEAD 與分支標籤,一起移動到與加入到某個 commit 記錄點上,雖然 commit 點被還原過看不到,不過還是可以透過 git reset 指令前往。
2-2-4-例題四 (git reset <退回 commit> 與 git revert <捨棄並另新增 commit> – 二者的使用差異)
1 | git reset c1 // or git reset Head^ |
輸入指令後目前的狀態。
1 2 | git checkout pushed //切換到 pushed git revert HEAD |
git revert HEAD 主要是要還原,所以才會由 c2 產生 c2`,主要是將 c2 捨棄另外產生一個記錄點 `c2。
什麼時後使用 git checkout、什麼時後使用 git reset。
– 如果是要還原刪除記錄點,就是使用 git reset,刪除記錄點就會與分支標籤與 HEAD 同時移動到還原的記錄點上 (後退)。
– git checkout 主要是查看,可以將 HEAD 做切換到指定分支上,在指定的記錄點上也可以。
1 2 3 4 5 | touch hello cd hello git init touch index.html touch all.css |
將專案資料夾所加的 index.html 與 all.css 檔加入索引。
1 2 | git add . git ci -m 'add index' |
分別加入二個 commit 記錄點。
1 2 3 | git index2.html git add . git commit -m 'add index2' |
1 2 3 | touch index3.html git add . git commit -m "add index3" |
目前有三個 commit 記錄點。
如果不要第三個記錄點,留二個記錄點的話,可以使用指令 git reset HEAD^ 留著目前工作的檔案 (成為檔案更動過的狀態),如果要直接退到指定的記錄點,就在加上參數 --head,這裡是輸入的完整指令為 git reset HEAD^ --head。
2-3-使用 git reset 退回記錄點後,想在回到還沒退回前的狀態 (誤刪記錄點的處理方式)
目前的話專案資料夾內,只有二個記錄點,是由之前第三個的記錄點所退下來,但退回時發現還有重要的檔案在第三個記錄點想在返回,此時想在救回記錄點的話可以針對第三個記錄點的 HASH-1 編號來處理,但目前的話因為刪除第三個記錄點而列出,此時可以使用 git reflog 查看。
比較 git log 的話,可以看到刪除第三個記錄點的狀態,可以看到對應的 HASH-1 編號與目前 HEAD 的所在分支是 master。
要查看所有的歷史記錄,使用 git reflog ,會列出所有操作資料都列出,之前第三點記錄點的 commit 內容為 add index3 ,所以找到要反迴的記錄點編號,將編號複製起來後按下 q 鍵退出列表頁面。
使用 git reset <HASH-1 編號> ,可以將 HEAD 與分支標籤同時反迴到之前的第三記錄點上。
輸入指令 git checkout <HASH-1 編號> 後的還原情形,除了回到第三個記錄點上的話,另外也會將更動的檔案帶到工作目錄上。
比較 git checkout <HASH-1 編號> 的話,是將 HEAD 單獨移到 (前往) 指定的記錄點上,要前進到指定的記錄點上的話,就需要使用 git reset <HASH-1 編號>。
在 git checkout <HASH-1 編號> 指令後方加上 --haed 參數,讓工作目錄的檔案清空完整的退到第三個記錄點上而 index3.html 檔也會在專案資料夾內。
3-發 PR 流程
PR 指的是
以 bootstrap 的 GitHub 為例,針對 open source 開發者所寫的程式碼,在程式碼中如果要錯或是要更新,就可以使用 PR 功能,針對開發者所發的 commit 記錄點,在合併到遠端分支上的流程。
3-1-GitHub 發 PR 的情境
1. Ray 是開發者,並擁有一個 master 開發分支
2. 洧杰很喜歡這個專案,但發現有個小問題於是 fork 了他的專案
3. fork 後在 master 上新增了一個 commit 並下了 PR
4. Ray 認為洧杰 真是天才,於是 merge 了他的 PR
3-2-GitHub Fork 將數據庫複製一份到自已的數據庫列表中
目前情境是要由第一點要到情境的第二點,要將對方的 GitHub 專案加到自已的 GitHub 數劇庫列表中,這加入的部份是透過 Fork 功能加入。
將 GitHub 上的數劇庫給複製一份下來 ( git clone repos),這個觀念指的是 Fork,fork 在英文指的是叉子意指叉一份專案到自已的 GitHub 上,Fork 下來後就會看到加到列表上去。
如果有去 Fork 其他要協作的 GitHub 專案的話,就會在自已的 Repositories 列表上看到,其中 Forked from hsiangfeng/1107-Pull-request 指的是原本 Fork 的對應與 GitHub 專案來源,點按下去之後就會回到之前 Fork 來源頁面。
而點進去專案數據庫中其實和一般使用 GitHub 的內容一樣,
目前到情境第三點,將專案由 GitHub fork 到自已的專案列表中。
3-3-將 GitHub fork 在 master 新增 commit
到本地端的桌面輸入 git clone <路徑>,下載後在移動到專案資料夾內。
將專案的檔案修改後 index.html 檔 ( 1234 後方在加上 3322),接著在終端機輸入指令。
1 2 | git add . git commit -m 'add line 2' |
目前的本地端有三個 commit 記錄點。
接著輸入指令 git push origin master 將本地端的 master 推到遠端 GitHub 分支上。
推送上自已 GitHub 遠端分支上。
目前在遠端分支上的 HEAD 也到第三個 commit 上,在自已的 GitHub Fork 專案中也可以看到所推上去的 commit 記錄。
3-4-發 PR ( Pull requests )
點按自已的 GitHub Fork 專案中的 Pull requests 項目,如果要發送給對方做請求遠端分支合併,點按 New pull request
接者會出現 Comparing changes 的頁面內容,裡面會有要發出請求合併的選項,右方是將自已的 repository 上的 master 分支,左方是將送出請求到另外開發者對方的遠端分支上,而 base 就是指定對方要合併的分支名稱。
點按後會出現合併分支的請求訊息,在輸入完主旨與內容後在按下 Create pull request 的按鈕送出請求合併的訊息。
目前是希望透過請求,將自已 GitHub 新的 commit 透過 PR 來合併到對方專案上的 commit 上。
按下 Create pull request 按鈕,會產生 PR 到對方開發者的 GitHub 過去,會出現提示訊息 This branch has no conflicts with the base branc ,提示沒有產生衝突出現。
接著如果沒有問題,對方開發者也會回應 PR 請求內容,將所提出的 PR 做通過的動作,將所提出請求的 PR 完成合併的動作。
切換到對方開發者 GitHub 帳號,看到 commits 有五筆。
而下方就會有發送 PR 的資料,另外合併後會在另外產生一個 commit 記錄出來,在合併的訊息中會提到,透過 PR 進來的 commit 可能不只一個會有多個的 commit ,合併的 commit 會提到透過 PR 所新增進來的 commit 記錄的內容。
發 PR 就是將自已的 GitHub 的 master 遠端分支,透過 PR 的方式 (GitHub 請求分支合併),將自已的 GitHub 遠端分支,讓原本專案的分支合併管理者,決定是不是要將分支做合併的動作。
本地 to 遠端 => push
遠端 to 遠端 or 遠端 to 本 => pull
遠端 to 遠端 => PR
4-衝突
1 2 3 | mkdir hell2 git init touch index.html |
開啟 index.html 加入內容,加入 HTML 結構與 <h1>標題</h1>。
1 2 | git add . git commit -m 'add index' |
接著在 index.html 在多加入 <h2>標題二</h2>。
1 2 | git add . git commit -m 'add h2' |
目前的 commit 有二個
4-1-產生衝突
加入新的分支 dev 與將 HEAD 切換分支過去。
1 2 | git branch dev git checkout dev |
目前的分支結構會如下圖。
接著將原本的 <h1>標題</h1> 修改成 <h1>標題 dev</h1>,目前的分支結構圖。
HEAD 切換分支到 master 上。
1 | git checkout master |
目前的分支結構圖。
此時的 index.html 上的 <h1>標題 dev</h1> 因為切回 master 分支後,就改回原本的 <h1>標題</h1>,在修改成 <h1>新增標題 master</h1>。
1 2 | git add . git commit -m 'add 標題' |
目前的分支結構圖,由於 master 的 commit 是比較晚產生,所以記錄點會是在比較後面。
比照 dev 與 master 所修改過的 <h1></h1> 內容,在分支最新的 commit 都有各自最新的記錄。
4-2-解決衝突
目前的 HEAD 在 master 分支上,使用合併分支指令 git merge dev ,輸入完指令後就會提示自動合併 index.html 檔,但下方的 CONFLICT (content): merge conflict in index.html 產生衝突。
Automatic merge failed; 自動合併失敗, fix conflicts and then commit the result. 修正衝突在進行 commit。
輸入 git status 查看目前的狀態,裡面會提示 Unmerged paths:,需要先將合併衝突解決。
開啟 VSCode 查看合併後的程式碼,在發生衝突的地方會多個 <<<< HEAD (上方箭頭) 與 >>>>> dev (下方箭頭) ,而中間有 ==== 來分隔,用來區分目前在的分支也就是 master 分支,而合併的目標分支上所產生的錯誤。
在 VSCode 上可以使用動作選項, Accept Current hange (保留 HEAD 分支)、 Accept Incoming Change (保留指定合併 Dev 分支),這裡是選保留 HEAD 選項 Accept Current hange
如果二個分支合併所產生的衝突都要保留,就可以選用 Accept Both Changes 項目,將二個分支上的內容做保留的動作。
另外也可以手動刪除合併提示來保留自已要的部分,因為 VSCode 上所對應給開發者的部份設計的不錯,所以可以直接透過選項設定就好。
將確任好合併分支後所產生衝突選項後,確任好所更分的內容,接著將檔案存檔,接著到終端機上輸入 git stutus 查看,此時也還是會提示 Unmerged paths,在更動存檔的檔案需要透過 git add . git add <單一資料名.副檔名> ,將合併衝突修正後的檔案加入索引,接著在輸入 git commit 會切換到 VSCode 裡。
在 VSCode 上會出現提示的頁面,上面提到合併的分支以 dev 分支為主,另外下方的 Conflicts: 就會列出所變更過的檔案,也就是 index.html 這支檔案,查看完後可以不用編蟈內容直接將視窗關閉,在關閉後就合併成功。
切換到 SoureTree 上查看,就可以看到合併後所產生新的 commit,裡面就會有合併分支預設的名字。
4-3-重新製作一次決解衝突
1 2 | git checkout dev git merge master // 將 dev 分支現在沒有的 commit 合併進來 |
開啟分支 dev 裡的 index.html 將 <h2>標題二</h2> 改成 <h2>標題二 dev</h2>,改完後存檔切到終端機輸入指令。
1 2 | git add . git commit -m 'add dev h2' |
目前的 dev h2 的 commit 就加入到 dev 分支內
接下來切換到 master 分支上,輸入指令 git checkout master ,在 index.html 檔上就將原本的 <h2>標題二</h2> 修改成 <h2>標題二 master</h2>,接著切到終端機輸入指令。
1 2 | git add . git commit -m 'add h2' |
此時就會讓 master 與 dev 分支有各自的 commit 記錄點,而裡面的差異只有 index.html 裡的 <h2>標題二</h2> 修改的內容。
HEAD 在 master 分支接著要合併 dev 分支,輸入指令 git merge dev 來合併,此時就會產生衝突出現,在目前的狀態是合併但還沒有結束,在 SourceTree 時就會出現 Uncommitted changes 的 commit 記錄點,而目前的狀態就是停在工作目錄上,需要將衝突的檔案處理過,透過 git add 加到索引,才能在使用 git commit 加到數據庫中。
目前的檔案裡提示衝突處理,如果二個分支內容都要保留的話,就要使用 Accept Both Changes,點按後存檔。
目前還是在工作目錄的狀態,使用 git add . 或是 git add index.html 將改過的檔案加入索引中。
完成加入索引後,在使用指令 git commit 加入數劇庫中,同時會開啟合併的 COMMIT_EDITMSG 內容頁。
關閉合併的 COMMIT_EDITMSG 內容頁,切換到 SourceTree 此時就會完成合併的動作。
有發生衝突的檔案,就會自動加到工作目錄上,在處理完衝突的內容後存檔後,在加檔案加入到索引之中,最後在加入到本地數據庫上。
在處理完衝突也加入索引中,此時要使用 git commit 指令加入到數據庫中,此時也可以使用 git commit -m '更新資料' 來自訂合併的訊息。
5-遠端衝突
目前的開發者與 GitHub 分支的關係,目前都有著一樣的 commit 記錄。
接著開發者 Ray 在自已的本地端新增了一個 commit 並推上 GitHub 上面。
目前的 SourceTree 上修改了第六行的位置,而開發者洧杰還沒開發好,此時同樣的也改了第六行的位置內容,在自已本地端也新增一個 commit 記錄點,而此時開發者洧杰也改好了自已的本地 commit 記錄點。
接著就要將 commit 記錄推到 GitHub 上面,此時會產生推不上遠端分支的情形,使用 git push 將開發者洧杰的本地端記錄要做推上去的動作,此時在終端機上就會出現提示訊息,裡面提到遠端分支上有新的資料,需要先使用指令 git pull 將遠端資料拉下來後,才能進行推上遠端分支的部份。
目前的 SourceTree 上就會出現遠端分支 origin/master 分支是與 origin/HEAD 在同一個記錄點上,而本地端上的分支內容比遠端分支新。
接著就要使用指令 git pull 來做分支合併的動作,而合併的過程中就會提示到衝突,裡面的 CONFLICT (content): 就會提到 index.html 裡出現了衝突的部份。
在 SourceTree 裡就會出現多一個 Uncommitted changes 的記錄點,在遠端分支與本地分支上方多一個灰色線與 commit 記錄點,主要是產生衝突的關係,需先將衝突排除後才能將處理過的本地 commit 推送上遠端分支上。
處理產生衝突的檔案,經過確任是開發者洧杰所加入的部份比較重要,所以在 VSCode 裡要選用 Accept Current Change 的部份,接著在存檔。
確任完發生衝突將狀態排除後,到終端機上輸入指令 git add .,此時本地分支就會多一個合併遠端分支的 commit 記錄點,但目前只是將修改過的檔案加入到索引中。
接著在輸入 git commit 就可以將更動過的檔案,加入新的 commit 記錄點,將提示的頁面關閉就完成衝突合併,此時的 SourceTree 上的遠端分支與本地分支的二條件就會交會於同一個本地 commit 記錄點上。
目前的遠端資料還是在 origin/HEAD 的 commit 記錄點上,而本地端的 add line6 就是本地開發者所處理的 commit 記錄點,將遠端分支透過合併與處理過衝突排除後,就會交會在新的本地端記錄點上。
在還沒將本地分支推上遠端分支上時,GitHub 上原有 8 個 commit 記錄。
使用指令 git push origin master 指令後,遠端分支會多二個 commit 記錄點。
在開發者洧杰因為處理完 GitHub 遠端分支所更新的衝突處理,所以會在原本二個的 commit 上方多一個處理遠端衝突的 commit 記錄點。
在本地端處理完成的二個 commit 記錄點,透過 git push 將二個 commit 記錄點推上遠端上支。