diff --git a/zh-cn/18.md b/zh-cn/18.md index 1ec84d9..01245f7 100644 --- a/zh-cn/18.md +++ b/zh-cn/18.md @@ -1,26 +1,22 @@ -第 18 天:修正 commit 过的版本历史记录 Part 1 -============================================================= +# 第 18 天:修正 commit 过的版本历史记录 Part 1 当你使用 Git 进行版本控制时,我们会利用 `git commit` 建立许多版本,由于 Git 属分布式版本控制机制,对于版本控制方面没有太多的权限设计,跟其他如 Subversion 或 TFVC 这类版控系统相比,Git 提供更多「修正版本记录」的机制,让你在「分享」版本给其他人的时候,能够预先做个整理。 -版本控制的基本原则 -------------------- +## 版本控制的基本原则 我们在进行版本控制时,无论是 Git, Subversion 或 TFVC 都一样,维持一个良好的版本记录有助于我们追踪每个版本的更新历程 (当有需要做这件事的时候)。以我个人的经验,我们很难有机会,也不太想去追踪我们某个项目中软件开发的进程,我们许多项目累积的版本记录数量有多达数千笔,谁会有这种闲工夫去追查历史呢? -然而实际上,当软件的臭虫(Bug)发生的时候,我们会需要去追踪特定臭虫的历史记录,以查出该臭虫真正发生的原因,这个时候就是版本控制带来最大价值的时候。 +然而实际上,当软件的臭虫 (Bug) 发生的时候,我们会需要去追踪特定臭虫的历史记录,以查出该臭虫真正发生的原因,这个时候就是版本控制带来最大价值的时候。 也因此,要怎样维持一个好的「版本记录」也是非常重要的,这边有一些控制原则可以分享给大家: * 做一个小功能修改就建立版本,这样才容易追踪变更 * 千万不要累积一大堆修改后才建立一个「大版本」 -* 有逻辑、有顺序的修正功能,确保相关的版本修正可以按顺序提交(commit),这样才便于追踪 +* 有逻辑、有顺序的修正功能,确保相关的版本修正可以按顺序提交 (commit),这样才便于追踪 不过,人非圣贤、孰能无过,哪个人能确保团队所有人都能时时刻刻照着上述原则进行版控?哪个人不是「想到哪改到哪」呢?这样的要求变得有点緣木求魚、不切实际。所以,我们需要有一套「修改版本」的机制,让版本提交到远端服务器上的时候,就已经是完美的版本状态。 - -修正 commit 历史记录的理由 ---------------------------- +## 修正 commit 历史记录的理由 到目前为止,我还没提到关于「远端仓库」的细节,所以大部分的 Git 操作都还专注在本地端,也就是在工作目录下的版本管控,这个仓库就位于你的 `.git/` 目录下。然而,之后我们即将提到「远端仓库」的应用,到时就不只一个人拥有仓库,所需要注意的细节也就更多。 @@ -30,17 +26,16 @@ 所以,到底什么样的使用情境会需要去修改版本记录呢?以下几点各位可以参考看看。 -假设我们现在有 [A] -> [B] -> [C] 三个版本: +假设我们现在有 \[A] -> \[B] -> \[C] 三个版本: -* 可能 [C] 版本你发现 commit 错了,必须删除这一版本所有变更 -* 你可能 commit 了之后才发现 [C] 这个版本其实只有测试代码,你也想删除他 +* 可能 \[C] 版本你发现 commit 错了,必须删除这一版本所有变更 +* 你可能 commit 了之后才发现 \[C] 这个版本其实只有测试代码,你也想删除他 * 其中有些版本的记录消息有错字,你想修改消息文字,但不影响文件的变更历程 -* 你可能想把这些版本的 commit 顺序调整为 [A] -> [C] -> [B],让版本演进更有逻辑性 -* 你发现 [B] 这个版本忘了加入一个重要的文件就 commit 了,你想事后補救这次变更 +* 你可能想把这些版本的 commit 顺序调整为 \[A] -> \[C] -> \[B],让版本演进更有逻辑性 +* 你发现 \[B] 这个版本忘了加入一个重要的文件就 commit 了,你想事后補救这次变更 * 在你打算「分享」分支出去时,发现了代码有瑕疵,你可以修改完后再分享出去 -修正 commit 历史记录的注意事项 ------------------------------ +## 修正 commit 历史记录的注意事项 Git 保留了「修改版本历史记录」的机制,主要是希望你能在「自我控制版本」到了一定程度后,自己整理一下版本记录的各种信息,好让你将版本「发布」出去后,让其他人能够更清楚的理解你对这些版本到底做了哪些修改。 @@ -51,28 +46,29 @@ Git 保留了「修改版本历史记录」的机制,主要是希望你能在 * 你可以任意修改某个支线上的版本,只要你还没「分享」给其他人 * **当你「分享」特定分支给其他人之后,这些「已分享」的版本历史记录就別再改了!** -准备本日练习用的版本库 ----------------------- +## 准备本日练习用的版本库 之前我们曾在【第 04 天:常用的 Git 版本控制指令】学过 `git reset` 的用法,主要用来 **重置目前的工作目录**。不过,相同的指令,也可以用来修正版本历史记录。 在开始说明前,我们一样先用以下指令建立一个练习用的工作目录与本地仓库: - mkdir git-reset-demo - cd git-reset-demo - git init +```sh +mkdir git-reset-demo +cd git-reset-demo +git init - echo. > a.txt - git add . - git commit -m "Initial commit (a.txt created)" +echo. > a.txt +git add . +git commit -m "Initial commit (a.txt created)" - echo 1 > a.txt - git add . - git commit -m "Update a.txt!" +echo 1 > a.txt +git add . +git commit -m "Update a.txt!" - echo 1 > b.txt - git add . - git commit -m "Add b.txt!" +echo 1 > b.txt +git add . +git commit -m "Add b.txt!" +``` ![image](figures/18/01.png) @@ -80,17 +76,19 @@ Git 保留了「修改版本历史记录」的机制,主要是希望你能在 ![image](figures/18/02.png) - -删除最近一次的版本 -------------------- +## 删除最近一次的版本 我们参考上图,用文字表达这三个版本的顺序如下: - [83a841] > [0576e0] > [aef2a5] +```txt +[83a841] > [0576e0] > [aef2a5] +``` 现在,我想把最后一个版本删除,变成: - [83a841] > [0576e0] +```txt +[83a841] > [0576e0] +``` 那么,你可以执行 `git reset --hard "HEAD^"` 即可删除 `HEAD` 这个版本: **请注意**:在「命令提示字元下」 `^` 是特殊符号,所以必须用雙引号括起来! @@ -99,12 +97,11 @@ Git 保留了「修改版本历史记录」的机制,主要是希望你能在 此时你可以看见,原本的最新版被删除了,那是因为刚刚我们执行 `git reset --hard "HEAD^"` 这个动作,把 `HEAD` 指向的位址改到了前一个版本 ( `HEAD^` ),所以你打 `git log` 就看不到这个版本了。 -事实上,原本你感觉被删除的版本,其实一直储存在 Git 的物件储存区(object storage)里,也就是这笔资料一直躺在 `.git\objects\` 目录下。我们还是可以用 `git show 83a841` 取得该版本 ( 即 commit 物件 ) 的详细资料: +事实上,原本你感觉被删除的版本,其实一直储存在 Git 的物件储存区 (object storage) 里,也就是这笔资料一直躺在 `.git\objects\` 目录下。我们还是可以用 `git show aef2a5` 取得该版本 (即 commit 物件) 的详细资料: ![image](figures/18/04.png) -删除最近一次的版本,但保留最后一次的变更 ------------------------------------- +## 删除最近一次的版本,但保留最后一次的变更 还记得吗?无论你对 Git 仓库做了什么事,都是可以还原的,只要执行 `git reset --hard ORIG_HEAD` 即可。 @@ -116,8 +113,7 @@ Git 保留了「修改版本历史记录」的机制,主要是希望你能在 这代表着,你可以保留最后一次的变更,再加上一些变更后,重新执行 `git commit` 一次,并重新设定一个新的记录消息。 -重新提交一次最后一个版本 (即 `HEAD` 版本) ------------------------------------------ +## 重新提交一次最后一个版本 (即 `HEAD` 版本) 如果你发现不小心执行了 `git commit` 动作,但还有些文件忘了加进去 (`git add [filepath]`) 或只是记录消息写错,想重新補上的话,直接执行 `git commit --amend` 即可。这个动作,会把目前记录在索引中的变更文件,全部添加到当前最新版之中,并且要求你修改原本的记录消息。 @@ -129,38 +125,34 @@ Git 保留了「修改版本历史记录」的机制,主要是希望你能在 我把记录消息修改成以下文字,并且存档后退出,版本就会建立完成: - Add b.txt! - Add c.txt! +```txt +Add b.txt! +Add c.txt! +``` 执行的结果如下,但最值得注意的是,最新版的 `HEAD` 已经是完全不同的 commit 物件了,所以用 `git log` 所看到的 commit 物件绝对名称跟之前已经不一样了。 ![image](figures/18/08.png) -今日小结 -------- +## 今日小结 -今天简单的学到如何对【最新版】(`HEAD`)进行版本的变更,大多用在不小心 `git commit` 错的情況,事实上还会有更多调整版本历史记录的方式,这些会在之后的文章中出现。 +今天简单的学到如何对【最新版】(`HEAD`) 进行版本的变更,大多用在不小心 `git commit` 错的情況,事实上还会有更多调整版本历史记录的方式,这些会在之后的文章中出现。 我重新整理一下本日学到的 Git 指令与参数: * git reset --hard "HEAD^" * git reset --soft "HEAD^" -* git reset --hard ORIG_HEAD +* git reset --hard ORIG\_HEAD * git commit --amend -参考连结 -------- +## 参考连结 * [git-reset(1) Manual Page](https://www.kernel.org/pub/software/scm/git/docs/git-reset.html) +--- - - -------- * [回目录](README.md) * [前一天:关于合并的基本观念与使用方式](17.md) * [下一天:设定 .gitignore 忽略清单](19.md) -------- - - +--- diff --git a/zh-cn/figures/18/04.png b/zh-cn/figures/18/04.png index a077259..600febf 100644 Binary files a/zh-cn/figures/18/04.png and b/zh-cn/figures/18/04.png differ diff --git a/zh-tw/18.md b/zh-tw/18.md index 734f16c..c0d9cdf 100644 --- a/zh-tw/18.md +++ b/zh-tw/18.md @@ -1,26 +1,22 @@ -第 18 天:修正 commit 過的版本歷史紀錄 Part 1 -============================================================= +# 第 18 天:修正 commit 過的版本歷史紀錄 Part 1 當你使用 Git 進行版本控管時,我們會利用 `git commit` 建立許多版本,由於 Git 屬分散式版本控管機制,對於版本控管方面沒有太多的權限設計,跟其他如 Subversion 或 TFVC 這類版控系統相比,Git 提供更多「修正版本記錄」的機制,讓你在「分享」版本給其他人的時候,能夠預先做個整理。 -版本控管的基本原則 -------------------- +## 版本控管的基本原則 我們在進行版本控管時,無論是 Git, Subversion 或 TFVC 都一樣,維持一個良好的版本紀錄有助於我們追蹤每個版本的更新歷程 (當有需要做這件事的時候)。以我個人的經驗,我們很難有機會,也不太想去追蹤我們某個專案中軟體開發的進程,我們許多專案累積的版本紀錄數量有多達數千筆,誰會有這種閒工夫去追查歷史呢? -然而實務上,當軟體的臭蟲(Bug)發生的時候,我們會需要去追蹤特定臭蟲的歷史紀錄,以查出該臭蟲真正發生的原因,這個時候就是版本控管帶來最大價值的時候。 +然而實務上,當軟體的臭蟲 (Bug) 發生的時候,我們會需要去追蹤特定臭蟲的歷史紀錄,以查出該臭蟲真正發生的原因,這個時候就是版本控管帶來最大價值的時候。 也因此,要怎樣維持一個好的「版本紀錄」也是非常重要的,這邊有一些控管原則可以分享給大家: * 做一個小功能修改就建立版本,這樣才容易追蹤變更 * 千萬不要累積一大堆修改後才建立一個「大版本」 -* 有邏輯、有順序的修正功能,確保相關的版本修正可以按順序提交(commit),這樣才便於追蹤 +* 有邏輯、有順序的修正功能,確保相關的版本修正可以按順序提交 (commit),這樣才便於追蹤 不過,人非聖賢、孰能無過,哪個人能確保團隊所有人都能時時刻刻照著上述原則進行版控?哪個人不是「想到哪改到哪」呢?這樣的要求變得有點緣木求魚、不切實際。所以,我們需要有一套「修改版本」的機制,讓版本提交到遠端伺服器上的時候,就已經是完美的版本狀態。 - -修正 commit 歷史紀錄的理由 ---------------------------- +## 修正 commit 歷史紀錄的理由 到目前為止,我還沒提到關於「遠端儲存庫」的細節,所以大部分的 Git 操作都還專注在本地端,也就是在工作目錄下的版本管控,這個儲存庫就位於你的 `.git/` 目錄下。然而,之後我們即將提到「遠端儲存庫」的應用,到時就不只一個人擁有儲存庫,所需要注意的細節也就更多。 @@ -30,17 +26,16 @@ 所以,到底甚麼樣的使用情境會需要去修改版本紀錄呢?以下幾點各位可以參考看看。 -假設我們現在有 [A] -> [B] -> [C] 三個版本: +假設我們現在有 \[A] -> \[B] -> \[C] 三個版本: -* 可能 [C] 版本你發現 commit 錯了,必須刪除這一版本所有變更 -* 你可能 commit 了之後才發現 [C] 這個版本其實只有測試程式碼,你也想刪除他 +* 可能 \[C] 版本你發現 commit 錯了,必須刪除這一版本所有變更 +* 你可能 commit 了之後才發現 \[C] 這個版本其實只有測試程式碼,你也想刪除他 * 其中有些版本的紀錄訊息有錯字,你想修改訊息文字,但不影響檔案的變更歷程 -* 你可能想把這些版本的 commit 順序調整為 [A] -> [C] -> [B],讓版本演進更有邏輯性 -* 你發現 [B] 這個版本忘了加入一個重要的檔案就 commit 了,你想事後補救這次變更 +* 你可能想把這些版本的 commit 順序調整為 \[A] -> \[C] -> \[B],讓版本演進更有邏輯性 +* 你發現 \[B] 這個版本忘了加入一個重要的檔案就 commit 了,你想事後補救這次變更 * 在你打算「分享」分支出去時,發現了程式碼有瑕疵,你可以修改完後再分享出去 -修正 commit 歷史紀錄的注意事項 ------------------------------ +## 修正 commit 歷史紀錄的注意事項 Git 保留了「修改版本歷史紀錄」的機制,主要是希望你能在「自我控管版本」到了一定程度後,自己整理一下版本紀錄的各種資訊,好讓你將版本「發布」出去後,讓其他人能夠更清楚的理解你對這些版本到底做了哪些修改。 @@ -51,28 +46,29 @@ Git 保留了「修改版本歷史紀錄」的機制,主要是希望你能在 * 你可以任意修改某個支線上的版本,只要你還沒「分享」給其他人 * **當你「分享」特定分支給其他人之後,這些「已分享」的版本歷史紀錄就別再改了!** -準備本日練習用的版本庫 ----------------------- +## 準備本日練習用的版本庫 之前我們曾在【第 04 天:常用的 Git 版本控管指令】學過 `git reset` 的用法,主要用來 **重置目前的工作目錄**。不過,相同的指令,也可以用來修正版本歷史紀錄。 在開始說明前,我們一樣先用以下指令建立一個練習用的工作目錄與本地儲存庫: - mkdir git-reset-demo - cd git-reset-demo - git init +```sh +mkdir git-reset-demo +cd git-reset-demo +git init - echo. > a.txt - git add . - git commit -m "Initial commit (a.txt created)" +echo. > a.txt +git add . +git commit -m "Initial commit (a.txt created)" - echo 1 > a.txt - git add . - git commit -m "Update a.txt!" +echo 1 > a.txt +git add . +git commit -m "Update a.txt!" - echo 1 > b.txt - git add . - git commit -m "Add b.txt!" +echo 1 > b.txt +git add . +git commit -m "Add b.txt!" +``` ![image](figures/18/01.png) @@ -80,17 +76,19 @@ Git 保留了「修改版本歷史紀錄」的機制,主要是希望你能在 ![image](figures/18/02.png) - -刪除最近一次的版本 -------------------- +## 刪除最近一次的版本 我們參考上圖,用文字表達這三個版本的順序如下: - [83a841] > [0576e0] > [aef2a5] +```txt +[83a841] > [0576e0] > [aef2a5] +``` 現在,我想把最後一個版本刪除,變成: - [83a841] > [0576e0] +```txt +[83a841] > [0576e0] +``` 那麼,你可以執行 `git reset --hard "HEAD^"` 即可刪除 `HEAD` 這個版本: **請注意**:在「命令提示字元下」 `^` 是特殊符號,所以必須用雙引號括起來! @@ -99,12 +97,11 @@ Git 保留了「修改版本歷史紀錄」的機制,主要是希望你能在 此時你可以看見,原本的最新版被刪除了,那是因為剛剛我們執行 `git reset --hard "HEAD^"` 這個動作,把 `HEAD` 指向的位址改到了前一個版本 ( `HEAD^` ),所以你打 `git log` 就看不到這個版本了。 -事實上,原本你感覺被刪除的版本,其實一直儲存在 Git 的物件儲存區(object storage)裡,也就是這筆資料一直躺在 `.git\objects\` 目錄下。我們還是可以用 `git show 83a841` 取得該版本 ( 即 commit 物件 ) 的詳細資料: +事實上,原本你感覺被刪除的版本,其實一直儲存在 Git 的物件儲存區 (object storage) 裡,也就是這筆資料一直躺在 `.git\objects\` 目錄下。我們還是可以用 `git show aef2a5` 取得該版本 (即 commit 物件) 的詳細資料: ![image](figures/18/04.png) -刪除最近一次的版本,但保留最後一次的變更 ------------------------------------- +## 刪除最近一次的版本,但保留最後一次的變更 還記得嗎?無論你對 Git 儲存庫做了什麼事,都是可以還原的,只要執行 `git reset --hard ORIG_HEAD` 即可。 @@ -116,8 +113,7 @@ Git 保留了「修改版本歷史紀錄」的機制,主要是希望你能在 這代表著,你可以保留最後一次的變更,再加上一些變更後,重新執行 `git commit` 一次,並重新設定一個新的紀錄訊息。 -重新提交一次最後一個版本 (即 `HEAD` 版本) ------------------------------------------ +## 重新提交一次最後一個版本 (即 `HEAD` 版本) 如果你發現不小心執行了 `git commit` 動作,但還有些檔案忘了加進去 (`git add [filepath]`) 或只是紀錄訊息寫錯,想重新補上的話,直接執行 `git commit --amend` 即可。這個動作,會把目前紀錄在索引中的變更檔案,全部添加到當前最新版之中,並且要求你修改原本的紀錄訊息。 @@ -129,38 +125,34 @@ Git 保留了「修改版本歷史紀錄」的機制,主要是希望你能在 我把紀錄訊息修改成以下文字,並且存檔後退出,版本就會建立完成: - Add b.txt! - Add c.txt! +```txt +Add b.txt! +Add c.txt! +``` 執行的結果如下,但最值得注意的是,最新版的 `HEAD` 已經是完全不同的 commit 物件了,所以用 `git log` 所看到的 commit 物件絕對名稱跟之前已經不一樣了。 ![image](figures/18/08.png) -今日小結 -------- +## 今日小結 -今天簡單的學到如何對【最新版】(`HEAD`)進行版本的變更,大多用在不小心 `git commit` 錯的情況,事實上還會有更多調整版本歷史紀錄的方式,這些會在之後的文章中出現。 +今天簡單的學到如何對【最新版】(`HEAD`) 進行版本的變更,大多用在不小心 `git commit` 錯的情況,事實上還會有更多調整版本歷史紀錄的方式,這些會在之後的文章中出現。 我重新整理一下本日學到的 Git 指令與參數: * git reset --hard "HEAD^" * git reset --soft "HEAD^" -* git reset --hard ORIG_HEAD +* git reset --hard ORIG\_HEAD * git commit --amend -參考連結 -------- +## 參考連結 * [git-reset(1) Manual Page](https://www.kernel.org/pub/software/scm/git/docs/git-reset.html) +--- - - -------- * [回目錄](README.md) * [前一天:關於合併的基本觀念與使用方式](17.md) * [下一天:設定 .gitignore 忽略清單](19.md) -------- - - +--- diff --git a/zh-tw/figures/18/04.png b/zh-tw/figures/18/04.png index a077259..600febf 100644 Binary files a/zh-tw/figures/18/04.png and b/zh-tw/figures/18/04.png differ