經過 Git 來管理多媒體文件

在咱們有關 Git 不爲人知的用法系列的最後一篇文章中,瞭解如何使用 Git 跟蹤項目中的大型多媒體文件。前端

Git 是專用於源代碼版本控制的工具。所以,Git 不多被用於非純文本的項目以及行業。然而,異步工做流的優勢是十分誘人的,尤爲是在一些日益增加的行業中,這種類型的行業把重要的計算和重要的藝術創做結合起來,這包括網頁設計、視覺效果、視頻遊戲、出版、貨幣設計(是的,這是一個真實的行業)、教育……等等。還有許多行業屬於這個類型。linux

在這個 Git 系列文章中,咱們分享了六種不爲人知的 Git 使用方法。在最後一篇文章中,咱們將介紹將 Git 的優勢帶到管理多媒體文件的軟件。git

Git 管理多媒體文件的問題

衆所周知,Git 用於處理非文本文件不是很好,可是這並不妨礙咱們進行嘗試。下面是一個使用 Git 來複制照片文件的例子:github

$ du -hs
108K .
$ cp ~/photos/dandelion.tif .
$ git add dandelion.tif
$ git commit -m 'added a photo'
[master (root-commit) fa6caa7] two photos
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dandelion.tif
$ du -hs
1.8M .
複製代碼

目前爲止沒有什麼異常。增長一個 1.8MB 的照片到一個目錄下,使得目錄變成了 1.8 MB 的大小。因此下一步,咱們嘗試刪除文件。bash

$ git rm dandelion.tif
$ git commit -m 'deleted a photo'
$ du -hs
828K .
複製代碼

在這裏咱們能夠看到有些問題:刪除一個已經被提交的文件,仍是會使得存儲庫的大小擴大到原來的 8 倍(從 108K 到 828K)。咱們能夠測試屢次來獲得一個更好的平均值,可是這個簡單的演示與個人經驗一致。提交非文本文件,在一開始花費空間比較少,可是一個工程活躍地時間越長,人們可能對靜態內容修改的會更多,更多的零碎文件會被加和到一塊兒。當一個 Git 存儲庫變的愈來愈大,主要的成本每每是速度。拉取和推送的時間,從最初抿一口咖啡的時間到你以爲你可能斷網了。服務器

靜態內容致使 Git 存儲庫的體積不斷擴大的緣由是什麼呢?那些經過文本的構成的文件,容許 Git 只拉取那些修改的部分。光柵圖以及音樂文件對 Git 文件而言與文本不一樣,你能夠查看一下 .png 和 .wav 文件中的二進制數據。因此,Git 只不過是獲取了所有的數據,而且建立了一個新的副本,哪怕是一張圖僅僅修改了一個像素。異步

Git-portal

在實踐中,許多多媒體項目不須要或者不想追蹤媒體的歷史記錄。相對於文本或者代碼的部分,項目的媒體部分通常有一個不一樣的生命週期。媒體資源通常按一個方向產生:一張圖片從鉛筆草稿開始,以數字繪畫的形式抵達它的目的地。而後,儘管文本可以回滾到早起的版本,可是藝術製品只會一直向前發展。工程中的媒體不多被綁定到一個特定的版本。例外狀況一般是反映數據集的圖形,一般是能夠用基於文本的格式(如 SVG)完成的表、圖形或圖表。函數

因此,在許多同時包含文本(不管是敘事散文仍是代碼)和媒體的工程中,Git 是一個用於文件管理的,可接受的解決方案,只要有一個在版本控制循環以外的遊樂場來給藝術家遊玩就行。工具

Graphic showing relationship between art assets and Git
Graphic showing relationship between art assets and Git

一個啓用這個特性的簡單方法是 Git-portal,這是一個經過帶有 Git 鉤子的 Bash 腳本,它可將靜態文件從文件夾中移出 Git 的範圍,並經過符號連接來取代它們。Git 提交連接文件(有時候稱道別名或快捷方式),這種符號連接文件比較小,因此全部的提交都是文本文件和那些表明媒體文件的連接。由於替身文件是符號連接,因此工程還會像預期的運行,由於本地機器會處理他們,轉換成「真實的」副本。當用符號連接替換出文件時,Git-portal 維護了項目的結構,所以,若是你認爲 Git-portal 不適合你的項目,或者你須要構建項目的一個沒有符號連接的版本(好比用於分發),則能夠輕鬆地逆轉該過程。gitlab

Git-portal 也容許經過 rsync 來遠程同步靜態資源,因此用戶能夠設置一個遠程存儲位置,來作爲一箇中心的受權源。

Git-portal 對於多媒體的工程是一個理想的解決方案。相似的多媒體工程包括視頻遊戲、桌面遊戲、須要進行大型 3D 模型渲染和紋理的虛擬現實工程、帶圖以及 .odt 輸出的書籍、協做型的博客站點、音樂項目,等等。藝術家在應用程序中以圖層(在圖形世界中)和曲目(在音樂世界中)的形式執行版本控制並很多見——所以,Git 不會向多媒體項目文件自己添加任何內容。Git 的功能可用於藝術項目的其餘部分(例如散文和敘述、項目管理、字幕文件、致謝、營銷副本、文檔等),而結構化遠程備份的功能則由藝術家使用。

安裝 Git-portal

Git-portal 的 RPM 安裝包位於 klaatu.fedorapeople.org/git-portal,可用於下載和安裝。

此外,用戶能夠從 Git-portal 的 Gitlab 主頁手動安裝。這僅僅是一個 Bash 腳本以及一些 Git 鉤子(也是 Bash 腳本),可是須要一個快速的構建過程來讓它知道安裝的位置。

$ git clone https://gitlab.com/slackermedia/git-portal.git git-portal.clone
$ cd git-portal.clone
$ ./configure
$ make
$ sudo make install
複製代碼

使用 Git-portal

Git-portal 與 Git 一塊兒使用。這意味着,如同 Git 的全部大型文件擴展同樣,都須要記住一些額外的步驟。可是,你僅僅須要在處理你的媒體資源的時候使用 Git-portal,因此很容易記住,除非你把大文件都當作文本文件來進行處理(對於 Git 用戶不多見)。使用 Git-portal 必須作的一個安裝步驟是:

$ mkdir bigproject.git
$ cd !$
$ git init
$ git-portal init
複製代碼

Git-portal 的 init 函數在 Git 存儲庫中建立了一個 _portal 文件夾而且添加到 .gitignore 文件中。

在平日裏使用 Git-portal 和 Git 協同十分平滑。一個較好的例子是基於 MIDI 的音樂項目:音樂工做站產生的項目文件是基於文本的,可是 MIDI 文件是二進制數據:

$ ls -1
_portal
song.1.qtr
song.qtr
song-Track_1-1.mid
song-Track_1-3.mid
song-Track_2-1.mid
$ git add song*qtr
$ git-portal song-Track*mid
$ git add song-Track*mid
複製代碼

若是你查看一下 _portal 文件夾,你會發現那裏有最初的 MIDI 文件。這些文件在本來的位置被替換成了指向 _portal 的連接文件,使得音樂工做站像預期同樣運行。

$ ls -lG
[...] _portal/
[...] song.1.qtr
[...] song.qtr
[...] song-Track_1-1.mid -> _portal/song-Track_1-1.mid*
[...] song-Track_1-3.mid -> _portal/song-Track_1-3.mid*
[...] song-Track_2-1.mid -> _portal/song-Track_2-1.mid*
複製代碼

與 Git 相同,你也能夠添加一個目錄下的文件。

$ cp -r ~/synth-presets/yoshimi .
$ git-portal add yoshimi
Directories cannot go through the portal. Sending files instead.
$ ls -lG _portal/yoshimi
[...] yoshimi.stat -> ../_portal/yoshimi/yoshimi.stat*
複製代碼

刪除功能也像預期同樣工做,可是當從 _portal 中刪除一些東西時,你應該使用 git-portal rm 而不是 git rm。使用 Git-portal 能夠確保文件從 _portal 中刪除:

$ ls
_portal/    song.qtr             song-Track_1-3.mid@  yoshimi/
song.1.qtr  song-Track_1-1.mid@  song-Track_2-1.mid@
$ git-portal rm song-Track_1-3.mid
rm 'song-Track_1-3.mid'
$ ls _portal/
song-Track_1-1.mid*  song-Track_2-1.mid*  yoshimi/
複製代碼

若是你忘記使用 Git-portal,那麼你須要手動刪除 _portal 下的文件:

$ git-portal rm song-Track_1-1.mid
rm 'song-Track_1-1.mid'
$ ls _portal/
song-Track_1-1.mid* song-Track_2-1.mid* yoshimi/
$ trash _portal/song-Track_1-1.mid
複製代碼

Git-portal 其它的惟一功能,是列出當前全部的連接而且找到裏面可能已經損壞的符號連接。有時這種狀況會由於項目文件夾中的文件被移動而發生:

$ mkdir foo
$ mv yoshimi foo
$ git-portal status
bigproject.git/song-Track_2-1.mid: symbolic link to _portal/song-Track_2-1.mid
bigproject.git/foo/yoshimi/yoshimi.stat: broken symbolic link to ../_portal/yoshimi/yoshimi.stat
複製代碼

若是你使用 Git-portal 用於私人項目而且維護本身的備份,以上就是技術方面全部你須要知道關於 Git-portal 的事情了。若是你想要添加一個協做者或者你但願 Git-portal 來像 Git 的方式來管理備份,你能夠建立一個遠程位置。

增長 Git-portal 遠程位置

爲 Git-portal 增長一個遠程位置是經過 Git 已有的遠程功能來實現的。Git-portal 實現了 Git 鉤子(隱藏在存儲庫 .git 文件夾中的腳本),來尋找你的遠程位置上是否存在以 _portal 開頭的文件夾。若是它找到一個,它會嘗試使用 rsync 來與遠程位置同步文件。Git-portal 在用戶進行 Git 推送以及 Git 合併的時候(或者在進行 Git 拉取的時候,其實是進行一次獲取和自動合併),都會執行此操做。

若是你僅克隆了 Git 存儲庫,那麼你可能永遠不會本身添加一個遠程位置。這是一個標準的 Git 過程:

$ git remote add origin git@gitdawg.com:seth/bigproject.git
$ git remote -v
origin git@gitdawg.com:seth/bigproject.git (fetch)
origin git@gitdawg.com:seth/bigproject.git (push)
複製代碼

對你的主要 Git 存儲庫來講,origin 這個名字是一個流行的慣例,將其用於 Git 數據是有意義的。然而,你的 Git-portal 數據是分開存儲的,因此你必須建立第二個遠程位置來讓 Git-portal 瞭解向哪裏推送和從哪裏拉取。取決於你的 Git 主機,你可能須要一個單獨的服務器,由於空間有限的 Git 主機不太可能接受 GB 級的媒體資產。或者,可能你的服務器僅容許你訪問你的 Git 存儲庫而不容許訪問外部的存儲文件夾:

$ git remote add _portal seth@example.com:/home/seth/git/bigproject_portal
$ git remote -v
origin git@gitdawg.com:seth/bigproject.git (fetch)
origin git@gitdawg.com:seth/bigproject.git (push)
_portal seth@example.com:/home/seth/git/bigproject_portal (fetch)
_portal seth@example.com:/home/seth/git/bigproject_portal (push)
複製代碼

你可能不想爲全部用戶提供服務器上的我的賬戶,也沒必要這樣作。爲了提供對託管資源庫大文件資產的服務器的訪問權限,你能夠運行一個 Git 前端,好比 Gitolite 或者你可使用 rrsync (受限的 rsync)。

如今你能夠推送你的 Git 數據到你的遠程 Git 存儲庫,並將你的 Git-portal 數據到你的遠程的門戶:

$ git push origin HEAD  
master destination detected
Syncing _portal content...
sending incremental file list
sent 9,305 bytes  received 18 bytes  1,695.09 bytes/sec
total size is 60,358,015  speedup is 6,474.10
Syncing _portal content to example.com:/home/seth/git/bigproject_portal
複製代碼

若是你已經安裝了 Git-portal,而且配置了 _portal 的遠程位置,你的 _portal 文件夾將會被同步,而且從服務器獲取新的內容,以及在每一次推送的時候發送新的內容。儘管你不須要進行 Git 提交或者推送來和服務器同步(用戶可使用直接使用 rsync),可是我發現對於藝術性內容的改變,提交是有用的。這將會把藝術家及其數字資產集成到工做流的其他部分中,並提供有關項目進度和速度的有用元數據。

其餘選擇

若是 Git-portal 對你而言太過簡單,還有一些用於 Git 管理大型文件的其餘選擇。Git 大文件存儲(LFS)是一個名爲 git-media 的停工項目的分支,這個分支由 GitHub 維護和支持。它須要特殊的命令(例如 git lfs track 來保護大型文件不被 Git 追蹤)而且須要用戶維護一個 .gitattributes 文件來更新哪些存儲庫中的文件被 LFS 追蹤。對於大文件而言,它支持 HTTP 和 HTTPS 遠程主機。因此你必須配置 LFS 服務器,才能使得用戶能夠經過 HTTP 而不是 SSH 或 rsync 來進行鑑權。

另外一個相對 LFS 更靈活的選擇是 git-annex。你能夠在個人文章 管理 Git 中大二進制 blob 中瞭解更多(忽略其中 git-media 這個已經廢棄項目的章節,由於其靈活性沒有被它的繼任者 Git LFS 延續下來)。Git-annex 是一個靈活且優雅的解決方案。它擁有一個細膩的系統來用於添加、刪除、移動存儲庫中的大型文件。由於它靈活且強大,有不少新的命令和規則須要進行學習,因此建議看一下它的文檔

然而,若是你的需求很簡單,你可能更加喜歡整合已有技術來進行簡單且明顯任務的解決方案,則 Git-portal 多是對於工做而言比較合適的工具。


via: opensource.com/article/19/…

做者:Seth Kenlon 選題:lujun9972 譯者:svtter 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關文章
相關標籤/搜索