[hg]研究筆記 Mercurial 的 dirstate

  • 3796
  • 0

[hg]研究筆記 Mercurial 的 dirstate

Mercurial 開始是由 Mackall 發表的分散式版本管理系統(DVCS)[1],是 open source project。

屬於相同類型的還有 git,由 linux 之父 Linus Torvalds 起頭設計開發,也是 open source project。

兩者公開的時間很接近,都在2005 年的時候發表。目的也是相同,想要用在 linux kernel 版本管理。

雖然後來 linux kernal 的版本管理是用 git,但是 mercurial 還是有被其他的 project 使用,例如 Mozilla, Nginx, Python…等,以及 Mercurial 自己。

Mercurial 在追蹤 working directory 的時候使用 dirstate 記下許多的資料[2],包含:

  • 目前 checked out 的版本(們)
  • 被複製或改名的檔案們
  • 被 Mercurial 管理的檔案們

對於每個被 Mercurial 管理的檔案,以下的資料會被記錄下來:

  • 檔案大小 (in byte)
  • 檔案模式 (以 posix 類系統的 0644 的東西)
  • 檔案修改時間
  • 檔案的狀態

檔案的狀態有以下幾種:

  • n - normal
  • a - added
  • r - removed
  • m - 3-way merged

Mercurail 就是靠這些資訊,可以很快地決定在 working directory 裡有哪些檔案被改變。

我們可以用以下的指令,把某個 working directory 的 dirstate 列出來:

hg debugstate
n 666       3941 2008-08-21 11:29:21 setup.py
n 666        997 2008-08-21 11:29:21 templates/changelog-gitweb.tmpl
n 666        155 2008-08-21 11:29:21 templates/changelog-rss.tmpl
n   0         -1 unset               templates/changelog.tmpl
n   0         -1 unset               templates/changelogentry-gitweb.tmpl

對於檔案狀態是 n 的檔案,Mercurial 會比對檔案修改時間及檔案大小,來決定檔案是否有變化。被認為有變化的檔案才會在下次 commit 時被加入 commit 列表。

但是檔案大小被標記成 -1 及檔案修改時間被標記成 unset 的檔案,則會依照實際檔案內容有無變更來決定。因為要看檔案內容是否有無變更,時間上的花費會比較多。

dirstate 裡的資訊實際上是儲存在 .hg 裡的 dirstate 檔案中。它的格式是:

<p1 binhash> # 20 byte (160 bit, sha1)
<p2 binhash> # 20 byte (160 bit, sha1)
<list of dirstate entries>
每一個 entry,由下列格式組成:
2 bytes: status, ascii code, 例 64=n
4 bytes: mode, 轉成 8 進位,會等同於在 debugstate 裡看到的數字。但在 windows 系統會有點不一樣。[3]
4 bytes: size, 檔案大小。
4 bytes: mtime, 轉成整數,當成 timestamp。datetime.fromtimestamp(timestamp) 可得到正確 datetime object。
4 bytes: length, 接下來的資料長度。接下來通常是 filename。[4]
n bytes: filename。
entry 的 status 的值是以下幾種:
  • n: normal
  • m: merged
  • a: added
  • r: removed

Mercurial 就是靠著這些資訊決定 working directory 是否有改變。接下來要看的應該是這些資訊是如何更新的。

[1] Distributed revision control, http://en.wikipedia.org/wiki/Distributed_revision_control

[2] Dirstate, http://mercurial.selenic.com/wiki/DirState

[3] 舉例,dirstate 的 mode 為 81b6,轉成 8 進位是 100666。在 linux 下 debugstate 顯示是 666,但在 windows 下,卻會顯示 644。我不確定這是不是故意的。

[4] 照官方 wiki 解釋,如果是 copy 的檔案,該資料會是 <filename> + '\0' + <source>

 

 

 

分享