Kerry 的筆記本
  • Table of contents
  • Kerry的Mac裝機必要
  • ASP.NET Core 教育訓練文件
    • .NET 9 OpenAPI 介紹與教學
    • 目錄
    • ASP.NET Core Authentication系列(一)理解Claim, ClaimsIdentity, ClaimsPrincipal
    • ASP.NET Core Authentication系列(三)Cookie選項
    • ASP.NET Core Authentication系列(二)實現認證、登錄和註銷
    • ASP.NET Core Authentication系列(四)基於Cookie實現多應用間單點登錄(SSO)
    • ASP.NET Core Consul 教學
    • ASP.NET Core Hangfire 排程管理
    • ASP.NET Core KeyCloak 實作
    • ASP.NET Core NLog-依照Environment使用Nlog.Config檔案
    • ASP.NET Core NLog-如何使用 NLog 將 log 寫到檔案
    • ASP.NET Core Nlog-發送訊息到ElasticSearch
    • 目錄
    • ASP.NET Core Quartz.NET 管理介面
    • ASP.NET Core RDLC 報表設計
    • ASP.NET Core SFTP (使用第三方套建 SSH.Net) - 類別庫為案例
    • ASP.NET Core 中使用 HttpReports 進行接口統計,分析, 可視化, 監控,追踪等
    • ASP.NET 使用 MassTransit 與 RabbitMQ,實現事件發佈、訂閱
    • Asp.Net Core 分散式Session – 使用 Redis
    • ASP.NET Core 前台會員修改個人資料
    • ASP.NET Core 前台會員忘記密碼與重設密碼
    • ASP.NET Core 前台會員登入
    • ASP.NET Core 前台會員註冊
    • ASP.NET Core 呼叫 API 發生 CORS 錯誤
    • ASP.NET Core 如何套網頁設計樣版
    • ASP.NET Core 客製化Model Validation 預設錯誤訊息
    • ASP.NET Core 後台查詢頁面教學
    • ASP.NET Core 網站生命週期
    • ASP.NET Feature Management 使用說明與教學
    • ASP.NET RulesEngine 介紹
    • ASP.NET WinForms APP 程式安裝檔
    • LinePay 支付完成後返回 LINE 應用而不跳出外部瀏覽器
    • EntityFramework
      • EF Core Migrations 完整教學手冊
      • EntityFramework Core DB Migrations
      • 使用 Entity Framework Core (EF Core) 的 Migrations 功能進行版本控制
    • NET 6
      • .NET 6 Autofac範例
      • .NET 6 Automapper範例
      • .NET 6 BenchmarkDotNet範例
      • .NET 6 Bogus範例
      • .NET 6 Dapper範例
      • .NET 6 Dapper語法說明
      • .NET 6 EFCore範例
      • .NET 6 EFCore語法說明
      • .NET 6 EPPlus圖表範例
      • .NET 6 EPPlus範例
      • .NET 6 Hangfire範例
      • .NET 6 HttpClient單元測試範例
      • .NET 6 MailKit前置作業
      • .NET 6 MailKit範例
      • .NET 6 Moq範例
      • .NET 6 NLog範例
      • .NET 6 NLog進階範例
      • .NET 6 Serilog範例
      • .NET 6 Serilog進階範例
      • .NET 6 Telegram.Bot前置作業
      • .NET 6 Telegram.Bot範例
      • .NET 6 Text.Json範例
      • .NET 6 swagger授權
      • .NET 6 swagger範例
      • .NET 6 xUnit範例
      • .NET 6 取得appsettings檔案內容
      • .NET 6 更改回傳Json時為大駝峰命名
      • .NET 6 解決System.Text.Json序列化後會將所有非ASCII轉為Unicode
    • WDMIS
      • CORS
      • FeatureManagement
      • Serilog
      • Spectre.Console
      • 資料模型實戰:從 MSSQL 設計到 .NET 8 WebAPI 實作(以刀具管理為例)
  • Azure
    • 如何在 ASP.NET CORE 5.0 WEB 應用程序中實現 AZURE AD 身份驗證
    • Azure App Configuration 使用教學
    • Azure Blob Storage
    • Azure DevOps 持續整合(CI) + Artifacts
  • CSharp
    • ASP.NET await 與 wait 的差異
    • AutoMapper —— 類別轉換超省力
    • C# 中的 HTTPClient — 入門指南
    • C# 正則表達式:從零到英雄指南
    • C# 集合, List<> 取交集、差集、聯集的方法
    • C#單元測試教學
    • CORS 介紹與設定方式
    • CSharp Coding Conventions
    • Using jQuery Unobtrusive AJAX in ASP.NET Core Razor Pages
    • 深入Dapper.NET源碼
    • 菜雞與物件導向
      • 菜雞與物件導向 (0): 前言
      • 菜雞與物件導向 (1): 類別、物件
      • 菜雞與物件導向 (10): 單一職責原則
      • 菜雞與物件導向 (11): 開放封閉原則
      • 菜雞與物件導向 (12): 里氏替換原則
      • 菜雞與物件導向 (13): 介面隔離原則
      • 菜雞與物件導向 (14): 依賴反轉原則
      • 菜雞與物件導向 (15): 最少知識原則
      • 菜雞與物件導向 (2): 建構式、多載
      • 菜雞與物件導向 (3): 封裝
      • 菜雞與物件導向 (4): 繼承
      • 菜雞與物件導向 (5): 多型
      • 菜雞與物件導向 (6): 抽象、覆寫
      • 菜雞與物件導向 (7): 介面
      • 菜雞與物件導向 (8): 內聚、耦合
      • 菜雞與物件導向 (9): SOLID
      • 菜雞與物件導向 (Ex1): 小結
  • DBeaver
    • 如何強制讓 DBeaver 在 Mac 上使用英文介面
  • DesignPattern
    • OAuth
    • Repository 模式 (Repository Pattern)
    • Single Sign On 實作方式介紹 (CAS)
    • 【SOP製作教學】新手適用,SOP範例、流程圖、製作流程全公開!
    • 【SOP製作教學】流程圖教學、重點範例、BPMN符號介紹!
    • 【SOP製作教學】流程圖符號整理、BPMN2.0進階符號教學!
    • 多奇數位 C# 程式碼撰寫規範 (C# Coding Guideline)
    • 軟體分層設計模式 (Software Layered Architecture Pattern)
    • 開源程式碼檢測平台 SonarQube
    • 菜雞新訓記
      • 菜雞新訓記 (0): 前言
      • 菜雞新訓記 (1): 使用 Git 來進行版本控制吧
      • 菜雞新訓記 (2): 認識 Api & 使用 .net Core 來建立簡單的 Web Api 服務吧
      • 菜雞新訓記 (3): 使用 Dapper 來連線到資料庫 CRUD 吧
      • 菜雞新訓記 (4): 使用 Swagger 來自動產生可互動的 API 文件吧
      • 菜雞新訓記 (5): 使用 三層式架構 來切分服務的關注點和職責吧
      • 菜雞新訓記 (6): 使用 依賴注入 (Dependency Injection) 來解除強耦合吧
      • 菜雞新訓記 (7): 使用 Fluent Validation 來驗證參數吧
  • DevOps
    • Repository 模式 (Repository Pattern)
    • pipeline工具研究
    • 單例模式 (Singleton Pattern)
    • 單元測試
    • 軟體分層設計模式 (Software Layered Architecture Pattern)
    • 雙重檢查鎖定模式 (Double-Checked Locking Pattern)
  • Docker
    • Docker 中部署 .NET 8 Web App 並支援 HTTPS
    • Docker指令大全
    • 第七章 安裝Nomad
    • Docker - 第三章 | 安裝 MSSQL
    • Docker - 第九章 | 安裝 datalust seq
    • 第二章 docker-compose 教學
    • Docker - 第五章 | 安裝 Redis
    • 第八章 安裝SonarQube
    • Docker - 第六章 | 安裝RabbitMQ
    • 第十一章 安裝 VtigerCRM
    • 第十二章 安裝KeyCloak
    • Docker - 第十章 | 安裝 Redmine
    • 第四章 安裝MySQL
    • Docker Desktop (含更改 Docker Image 路徑)
  • Git
    • Git Flow 指令大全(完整指令整理) 🚀
    • Git 安裝及配置SSH Key
    • Git 建立到上傳
    • 將現有專案的遠端儲存庫直接更改為新的儲存庫
    • Git 流程規劃
    • Git 語法大全
    • 30 天精通 Git 版本控管
      • 30 天精通 Git 版本控制
        • 第 01 天:认识 Git 版本控制
        • 第 02 天:在 Windows 平台必装的三套 Git 工具
        • 第 03 天:建立仓库
        • 第 04 天:常用的 Git 版本控制指令
        • 第 05 天:了解仓库、工作目录、物件与索引之间的关系
        • 第 06 天:解析 Git 资料结构 - 物件结构
        • 第 07 天:解析 Git 资料结构 - 索引结构
        • 第 08 天:关于分支的基本观念与使用方式
        • 第 09 天:比对文件与版本差异
        • 第 10 天:认识 Git 物件的绝对名称
        • 第 11 天:认识 Git 物件的一般参照与符号参照
        • 第 12 天:认识 Git 物件的相对名称
        • 第 13 天:暂存工作目录与索引的变更状态
        • 第 14 天: Git for Windows 选项设定
        • 第 15 天:标签 - 标记版本控制过程中的重要事件
        • 第 16 天:善用版本日志 git reflog 追踪变更轨迹
        • 第 17 天:关于合并的基本观念与使用方式
        • 第 18 天:修正 commit 过的版本历史记录 Part 1
        • 第 19 天:设定 .gitignore 忽略清单
        • 第 20 天:修正 commit 过的版本历史记录 Part 2
        • 第 21 天:修正 commit 过的版本历史记录 Part 3
        • 第 22 天:修正 commit 过的版本历史记录 Part 4 (Rebase)
        • 第 23 天:修正 commit 过的版本历史记录 Part 5
        • 第 24 天:使用 GitHub 远端仓库 - 入门篇
        • 第 25 天:使用 GitHub 远端仓库 - 观念篇
        • 第 26 天:多人在同一个远端仓库中进行版控
        • 第 27 天:通过分支在同一个远端仓库中进行版控
        • 第 28 天:了解 GitHub 的 fork 与 pull request 版控流程
        • 第 29 天:如何将 Subversion 项目汇入到 Git 仓库
        • 第 30 天:分享工作中几个好用的 Git 操作技巧
      • zh-tw
        • 第 01 天:認識 Git 版本控管
        • 第 02 天:在 Windows 平台必裝的三套 Git 工具
        • 第 03 天:建立儲存庫
        • 第 04 天:常用的 Git 版本控管指令
        • 第 05 天:了解儲存庫、工作目錄、物件與索引之間的關係
        • 第 06 天:解析 Git 資料結構 - 物件結構
        • 第 07 天:解析 Git 資料結構 - 索引結構
        • 第 08 天:關於分支的基本觀念與使用方式
        • 第 09 天:比對檔案與版本差異
        • 第 10 天:認識 Git 物件的絕對名稱
        • 第 11 天:認識 Git 物件的一般參照與符號參照
        • 第 12 天:認識 Git 物件的相對名稱
        • 第 13 天:暫存工作目錄與索引的變更狀態
        • 第 14 天: Git for Windows 選項設定
        • 第 15 天:標籤 - 標記版本控制過程中的重要事件
        • 第 16 天:善用版本日誌 git reflog 追蹤變更軌跡
        • 第 17 天:關於合併的基本觀念與使用方式
        • 第 18 天:修正 commit 過的版本歷史紀錄 Part 1
        • 第 19 天:設定 .gitignore 忽略清單
        • 第 20 天:修正 commit 過的版本歷史紀錄 Part 2
        • 第 21 天:修正 commit 過的版本歷史紀錄 Part 3
        • 第 22 天:修正 commit 過的版本歷史紀錄 Part 4 (Rebase)
        • 第 23 天:修正 commit 過的版本歷史紀錄 Part 5
        • 第 24 天:使用 GitHub 遠端儲存庫 - 入門篇
        • 第 25 天:使用 GitHub 遠端儲存庫 - 觀念篇
        • 第 26 天:多人在同一個遠端儲存庫中進行版控
        • 第 27 天:透過分支在同一個遠端儲存庫中進行版控
        • 第 28 天:了解 GitHub 的 fork 與 pull request 版控流程
        • 第 29 天:如何將 Subversion 專案匯入到 Git 儲存庫
        • 第 30 天:分享工作中幾個好用的 Git 操作技巧
  • Hands-On Labs - LineBotSDK 實作手札 (C#, .net core)
    • 00. 如何申請LINE Bot
    • CLI
      • 使用CLI來發送新的Channel Access Token(LINE Bot)
      • 使用CLI免費發送LINE Notify通知
    • basic
      • 如何發送LINE訊息(Push Message)
      • 如何發送LINE Template Messages
      • 如何發送ImageMap訊息
      • 如何發送Flex Message
      • 如何在訊息後面加上QuickReply快捷選項
    • liff
      • Lab 21: 建立第一個LIFF應用
    • webhook
      • 如何建立可Echo的基本LINE Bot
      • 如何在WebHook中取得用戶個人資訊(名稱、頭像、狀態)
      • 如何在WebHook中取得用戶上傳的圖片(Bytes)
  • Markdown
    • Markdown Cheatsheet 中文版
    • Markdown語法大全
    • 使用HackMD建立書本目錄
    • 使用HackMD建立簡報
  • SAP ABAP
    • ABAP開發環境和總體介紹
    • SAP MM模塊常用表總結
    • SAP QM數據庫表清單
    • SAP欄位與表的對應關係
  • SQL Server
    • [SQL SERVER] Like in
    • SQL Server 中,移除資料庫中所有的關聯限制
    • SQL Server 刪除資料庫中所有資料表
    • SQL Server View、Function 及 Stored Procedure 定義之快速備份
    • SSMS v18 清除登入畫面中,下拉選單歷史紀錄
    • [MS SQL]如何透過Database Mail進行郵件發送
    • [SQL SERVER]撰寫Stored Procedure小細節
    • 使用 Data Migration Assistant 移轉 SQL Server 資料庫與帳戶
    • 使用SSIS創建同步資料庫數據任務
  • Tools
    • 免費 FTP 伺服器 FileZilla Server 安裝教學 (新版設定)
  • VisualStudio
    • .NET CLI 指令碼介紹
    • Visual Studio 使用 Git 版本控制
    • 使用 Visual Studio 2022 可透過 .editorconfig 鎖定文字檔案的儲存編碼格式分享
  • Web API
    • ASP.NET Core 6 Web API 進行 JWT 令牌身份驗證
    • [ASP.NET Core]如何使用SwaggerAPI說明文件
    • ASP.NET Core Web Api實作JWT驗證筆記
    • ECFIT API 範例
    • JWT Token Authentication And Authorizations In .Net Core 6.0 Web API
    • 微服務架構 - 從狀態圖來驅動 API 的設計
  • Windows
    • [C#] 伺服器監控常用語法 (事件檢視器、CPU 硬碟使用率、程式執行狀況)
    • Configure IIS Web Server on Windows Server 2019
    • Log Paser Studio 分析 IIS W3C Log
    • Windows Server 2019 如何安裝 IIS 運行 ASP.NET 專案
    • 如何檢查安裝在 IIS 上的 .NET Core Hosting Bundle 版本
    • [IIS] 如何解決網站第一個請求 Request 特別慢 ?
    • IIS 不停機更版設置
    • SQL Server 2019 Standard 繁體中文標準版安裝
    • WINDOWS共用資料夾的網路認證密碼放在哪?如何清除?
    • 如何設定 ASP.NET CORE 網站應用程式持續執行在 IIS 上
  • 專案管理
    • SSDLC (Secure Software Development Life Cycle)
    • 系統開發原則
    • MIS及專案管理-使用Redmine
      • 第10章 - [日常管理]MIS部門週會工作進度追蹤
      • 第11章 - [日常管理]MIS部門主管月會報告管理
      • 第12章 - [日常管理]機房工作日誌
      • 第13章 - [日常管理]MIS部門耗用工時及工作進度檢討
      • 第14章 - [日常管理]MIS文件知識庫
      • 第15章 - [日常管理]整理及管理分享
      • 第16章 - [異常管理]使用者問題回報系統
      • 第17章 - [異常管理]資安事件及異常紀錄
      • 第18章 - [異常管理]整理及管理分享
      • 第19章 - [變革管理]MIS的專案及專案管理五大階段
      • 第1章 - [MIS及專案管理]中小企業MIS的鳥事
      • 第20章 - [變革管理]MIS的新專案管理:起始階段
      • 第21章 - [變革管理]MIS的新專案管理:規劃階段
      • 第22章 - [變革管理]MIS的新專案管理:執行階段
      • 第23章 - [變革管理]MIS的新專案管理:監控階段
      • 第24章 - [變革管理]MIS的新專案管理:結束階段
      • 第25章 - [變革管理]整理及管理分享
      • 第26章 - [ISMS管理]ISMS平台整體規劃
      • 第27章 - [ISMS管理]ISMS文管中心
      • 第28章 - [ISMS管理]ISMS表單紀錄的管理
      • 第29章 - [ISMS管理]整理及管理分享
      • 第2章 - [MIS及專案管理]專案管理的概念及MIS應用
      • 第30章 - 初心、來時路及感謝:系列文章總結回顧
      • 第3章 - [MIS及專案管理]管理工具的選擇
      • 第4章 - [Redmine]Redmine的安裝及設定
      • 第5章 - [Redmine]Redime系統邏輯說明
      • 第6章 - [Redmine]自行建立及維護表單
      • 第7章 - [Redmine]專案版面的規劃
      • 第8章 - [日常管理]AR管理
      • 第9章 - [日常管理]資訊服務申請
  • 微服務架構
    • DDD + CQRS + MediatR 專案架構
    • 微服務架構 #2, 按照架構,重構系統
    • 淺談微服務與網站架構的發展史
    • API First Workshop 設計概念與實做案例
      • API First #1 架構師觀點 - API First 的開發策略 - 觀念篇
      • API First #2 架構師觀點 - API First 的開發策略 - 設計實做篇
    • 基礎建設 - 建立微服務的執行環境
      • Part #1 微服務基礎建設 - Service Discovery
      • Part #2 微服務基礎建設 - 服務負載的控制
      • Part #3 微服務基礎建設 - 排隊機制設計
      • Part #4 可靠的微服務通訊 - Message Queue Based RPC
      • Part #5 非同步任務的處理機制 - Process Pool
    • 實做基礎技術 API & SDK Design
      • API & SDK Design #1, 資料分頁的處理方式
      • API & SDK Design #2, 設計專屬的 SDK
      • API & SDK Design #3, API 的向前相容機制
      • API & SDK Design #4, API 上線前的準備 - Swagger + Azure API Apps
      • API & SDK Design #5 如何強化微服務的安全性 API Token JWT 的應用
    • 建構微服務開發團隊
      • 架構面試題 #1, 線上交易的正確性
      • 架構面試題 #2, 連續資料的統計方式
      • 架構面試題 #3, RDBMS 處理樹狀結構的技巧
      • 架構面試題 #4 - 抽象化設計;折扣規則的設計機制
    • 架構師觀點 - 轉移到微服務架構的經驗分享
      • Part #1 改變架構的動機
      • Part #2 實際改變的架構案例
    • 案例實作 - IP 查詢服務的開發與設計
      • 容器化的微服務開發 #1 架構與開發範例
      • 容器化的微服務開發 #2 IIS or Self Host
  • 系統評估
    • RPA 與 WebAPI 評估
    • 數位轉型:從現有系統到數位化的未來
    • 數位轉型:從現有系統到數位化的未來
  • 面試
    • CV_黃子豪_2024
    • HR 問題集
    • .NET 工程師 面試問題集
    • 資深工程師 問題集
    • 資深開發人員 / 技術主管
    • 題目
Powered by GitBook
On this page
  • 了解版本紀錄的過程
  • 復原意外地變更
  • 紀錄版本變更的原則
  • 只顯示特定分支的 reflog 紀錄
  • 顯示 reflog 的詳細版本記錄
  • 刪除特定幾個版本的歷史紀錄
  • 設定歷史紀錄的過期時間
  • 清除歷史紀錄
  • 今日小結
  • 參考連結
  1. Git
  2. 30 天精通 Git 版本控管
  3. zh-tw

第 16 天:善用版本日誌 git reflog 追蹤變更軌跡

Previous第 15 天:標籤 - 標記版本控制過程中的重要事件Next第 17 天:關於合併的基本觀念與使用方式

Last updated 1 year ago

其實學習 Git 版本控管的指令操作並不難,但要弄清楚 Git 到底對我的儲存庫做了什麼事,還真不太容易。當你一步步了解 Git 的核心與運作原理,自然能有效掌控 Git 儲存庫中的版本變化。本篇文章,就來說說 Git 如何記錄我們的每一版的變更軌跡。

了解版本紀錄的過程

在清楚理解 Git 基礎原理與物件結構之前,你不可能了解版本紀錄的過程。而當你不了解版本紀錄的過程,自然會擔心「到底我的版本到哪去了」,也許有人跟你說「我們用了版本控管,所以所有版本都會留下,你大可放心改 Code」。知道是一回事,知不知道怎麼做又是一回事,然後是不是真的做得到又是另外一回事。我們在版控的過程中盡情 commit 建立版本,但如果有一天發現有某個版本改壞了,或是因為執行了一些合併或重置等動作導致版本消失了,那又該怎麼辦呢?

還好在 Git 裡面,有一套嚴謹的紀錄機制,而且這套機制非常開放,紀錄的檔案都是文字格式,還蠻容易了解,接下來我們就來說明版本紀錄的過程。

我們先進入任何一個 Git 工作目錄的 .git/ 資料夾,你可以看到一個 logs 目錄,如下圖示:

這個 logs 資料夾下有個 HEAD 檔案,這檔案紀錄著「當前分支」的版本變更紀錄:

我們開啟該檔看看其內容 (其中物件 id 的部分我有刻意稍作刪減,以免每行的內容過長):

0000000 f5685e0 Will <xxxx@gmail.com> 1381718394 +0800	commit (initial): Initial commit
f5685e0 38d924f Will <xxxx@gmail.com> 1381718395 +0800	commit: a.txt: set 1 as content
38d924f efa1e0c Will <xxxx@gmail.com> 1381734238 +0800	commit: test
efa1e0c af493e5 Will <xxxx@gmail.com> 1381837967 +0800	commit: Add c.txt

從這裡你將可看出目前在這個分支下曾經記錄過 4 個版本,此時我們用 git reflog 即可列印出所有「歷史紀錄」的版本變化,你會發現內容是一樣的,但順序正好顛倒。從文字檔中看到的內容,「第一版」在最上面,而透過 git reflog 則是先顯示「最新版」最後才是「第一版」:

這時我們試圖建立一個新版本,看看記錄檔的變化,你會發現版本被建立成功:

從上圖你可以發現到,這裡有個特殊的「參考名稱」為 HEAD@{0},這裡每個版本都會有一個歷史紀錄都會有個編號,代表著這個版本的在記錄檔中的順位。如果是 HEAD@{0} 的話,永遠代表目前分支的「最新版」,換句話說就是你在這個「分支」中最近一次對 Git 操作的紀錄。你對 Git 所做的任何版本變更,全部都會被記錄下來。

復原意外地變更

初學者剛開始使用 Git 很有可能會不小心執行錯誤,例如透過 git merge 執行合併時發生了衝突,或是透過 git pull 取得遠端儲存庫最新版時發生了失誤。在這種情況下,你可以利用 HEAD@{0} 這個特殊的「參考名稱」來對此版本「定位」,並將目前的 Git 儲存庫版本回復到前一版或前面好幾版。

例如,我們如果想要「取消」最近一次的版本紀錄,我們可以透過 git reset HEAD@{1} --hard 來復原變更。如此一來,這個原本在 HEAD@{0} 的變更,就會被刪除。不過,在 Git 裡面,所有的變更都會被記錄,其中包含你做 git reset "HEAD@{1}" --hard 的這個動作,如下圖示:

這代表甚麼意義呢?這代表你在執行任意 Git 命令時,再也不用擔心害怕你的任何資料會遺失,就算你怎樣下錯指令都沒關係,所有已經在版本庫中的檔案,全部都會保存下來,完全不會有遺失的機會。所以,這時如果你想復原剛剛執行的 git reset "HEAD@{1}" --hard 動作,只要再執行一次 git reset "HEAD@{1}" --hard 即可,是不是非常棒呢!你看下圖,我把剛剛的 9967b3f 這版本給救回來了:

紀錄版本變更的原則

事實上在使用 Git 版控的過程中,有很多機會會產生「版本歷史紀錄」,我說的並不是單純的 git log 顯示版本紀錄,而是原始且完整的變更歷史紀錄。這些紀錄版本變更有個基本原則:【只要你透過指令修改了任何參照(ref)的內容,或是變更任何分支的 HEAD 參照內容,就會建立歷史紀錄】。也因為這個原則,所以指令名稱才會稱為 reflog,因為是改了 ref (參照內容) 才引發的 log (紀錄)。

例如我們拿 git checkout 命令還切換不同的分支,這個切換的過程由於會修改 .git\HEAD 參照的內容,所以也會產生一個歷史紀錄,如下圖示:

還有哪些動作會導致產生新的 reflog 紀錄呢?以下幾個動作你可以參考,但其實可以不用死記,記住原則就好了:

  • commit

  • checkout

  • pull

  • push

  • merge

  • reset

  • clone

  • branch

  • rebase

  • stash

除此之外,每一個分支、每一個暫存版本(stash),都會有自己的 reflog 歷史紀錄,這些資料也全都會儲存在 .git\logs\refs\ 資料夾下。

只顯示特定分支的 reflog 紀錄

在查詢歷史紀錄時,你也可以針對特定分支(Branch)進行查詢,僅顯示特定分支的變更歷史紀錄,如下圖示:

顯示 reflog 的詳細版本記錄

我們已經學會用 git reflog 就可以取出版本歷史紀錄的摘要資訊。但如果我們想要顯示每一個 reflog 版本中,每一個版本的完整 commit 內容,那麼你可以用 git log -g 指令顯示出來:

刪除特定幾個版本的歷史紀錄

基本上,版本日誌(reflog)所記錄的只是變更的歷程,而且預設只會儲存在「工作目錄」下的 .git/ 目錄裡,這裡所記錄的一樣只是 commit 物件的指標而已。無論你對這些紀錄做任何操作,不管是竄改、刪除,都不會影響到目前物件儲存庫的任何內容,也不會影響版本控管的任何資訊。

如果你想刪除之前紀錄的某些紀錄,可以利用 git reflog delete ref@{specifier} 來刪除特定歷史紀錄。如下圖示:

註:這些版本日誌預設並不會被同步到「遠端儲存庫」,以免多人開發時大家互相影響,所以版本日誌算是比較個人的東西。

設定歷史紀錄的過期時間

當你的 Git 儲存庫越用越久,可想見這份歷史紀錄將會越累積越多,這樣難道不會爆掉嗎?還好,預設來說 Git 會幫你保存這些歷史紀錄 90 天,如果這些紀錄中已經有些 commit 物件不在分支線上,則預設會保留 30 天。

舉個例子來說,假如你先前建立了一個分支,然後 commit 了幾個版本,最後直接把該分支刪掉,這時這些曾經 commit 過的版本 (即 commit 物件) 還會儲存在物件儲存區 (object storage) 中,但已經無法使用 git log 取得該版本,我們會稱這些版本為「不在分支線上的版本」。

如果你想修改預設的過期期限,可以透過 git config gc.reflogExpire 與 git config gc.reflogExpireUnreachable 來修正這兩個過期預設值。如果你的硬碟很大,永遠不想刪除紀錄,可以考慮設定如下:

git config --global gc.reflogExpire "never"
git config --global gc.reflogExpireUnreachable "never"

如果只想保存 7 天,則可考慮設定如下:

git config --global gc.reflogExpire "7 days"
git config --global gc.reflogExpireUnreachable "7 days"

除此之外,你也可以針對特定分支設定其預設的過期時間。例如我想讓 master 分支只保留 14 天期,而 develop 分支可以保留完整記錄,那麼你可以這樣設定:(注意: 以下範例我把設定儲存在本地儲存庫中,所以使用了 --local 參數)

git config --local gc.master.reflogExpire "14 days"
git config --local gc.master.reflogExpireUnreachable "14 days"

git config --local gc.develop.reflogExpire "never"
git config --local gc.develop.reflogExpireUnreachable "never"

上述指令寫入到 .git\config 的內容將會是:

[gc "master"]
	reflogExpire = 14 days
	reflogExpireUnreachable = 14 days
[gc "develop"]
	reflogExpire = never
	reflogExpireUnreachable = never

清除歷史紀錄

若要立即清除所有歷史紀錄,可以使用 git reflog expire --expire=now --all 指令完成刪除工作,最後搭配 git gc 重新整理或清除那些找不到、無法追蹤的版本。如下圖示:

今日小結

Git 的版本日誌(reflog)幫我們記憶在版控過程中的所有變更,幫助我們「回憶」到底這段時間到底對 Git 儲存庫做了什麼事。不過你也要很清楚的知道,這些只是個「日誌」而已,不管有沒有這些日誌,都不影響我們 Git 儲存庫中的任何版本資訊。

我重新整理一下本日學到的 Git 指令與參數:

  • git reflog

  • git reflog [ref]

  • git log -g

  • git reset "HEAD@{1}" --hard

  • git reflog delete "ref@{specifier}"

  • git reflog delete "HEAD@{0}"

  • git reflog expire --expire=now --all

  • git gc

  • git config --global gc.reflogExpire "never"

  • git config --global gc.reflogExpireUnreachable "never"

參考連結



註:從上述範例所看到的 7 days 這段字,我找了好久都沒有看到完整的說明文件,最後終於找到 Git 處理日期格式的原始碼(C語言),有興趣的也可以看看:

http://git.kernel.org/cgit/git/git.git/tree/date.c
git-reflog(1) Manual Page
git-gc(1) Manual Page
http://git.kernel.org/cgit/git/git.git/tree/date.c
HOME
回目錄
前一天:標籤 - 標記版本控制過程中的重要事件
下一天:關於合併的基本觀念與使用方式
image
image
image
image
image
image
image
image
image
image
image