Gits Submodules Foreach and LFS

git 好好用,不只是程式的版本控制,日常生活也都可以多加利用喔!

git 好好用

大概 git 剛出來沒多久的時候,就開始把自己的設定檔以及筆記等等文字檔案, 都用這個分散式版本管理了,大部份也就我個人一個人在 git commit, 所以倒也不是真的要做什麼版本管理,大概也只有一個 master branch, 好用就好用在 git 同步很方便,透過 ssh 就可以到處 git pull 或是 git push,也不用一直需要有個中央 server 才能把手上做到一個小階段的事情 commit,有需要再 push 回去就可以了。

git server

剛開始時候,真的是用自己放在學校的 ssh server,也因為這樣在 server 上的 repository 就真的是放在某處的資料夾,所以需要切成另一個 branch, 不然遠端會 push 不上來。

後來高級了一點,開始用 gitolite 架設 git server,使用起來覺得相當方便, 尤其是有 wildcard 的權限管理,可以想到就動態開一個新的 repository

gitolite 好用是好用,但就缺了一項 https,有些時候因為所在的環境需要, 有 https 可以 access,還是會比較方便一點,另外就是也可以直接網頁登錄看, 不然像是在手機上要看個什麼檔案,還需要開個 git 一下, 也是有點大費周張的感覺。

所以現在有用 gitea 架設了目前個人專用的 git server,也覺得超好用的喔,推推。 也有 api 可以使用相當方便,像是當時候就用了 api 來搬移之前放在 gitolite 上的 repositories,記得有接近 50 個,不然的話一個一個手動開想到就淚了。

至於為什麼不用 gitlab? 因為我租的 VPS RAM 太少跑不動,哈哈!

git repositories

本來呢是真的只用一個大 repository 來紀錄事情的,想說把所有的東西都 commit 到這裡,但後來覺得這樣會讓 log 有點雜亂,也認為長久這樣下去也不是辦法, 所以就會拆成多個比較小一點的 repositories

但有些東西也還是想要放在一起更新,後來也有少許的 repositories 開始有一點點相依的關係了,想想看別人都怎麼做的呢? 這時候就想到了用 上的 repo 來管理多個 repositories 吧!

repo 是一支很神奇的程式,是自己更新自己的,而且很後來才支援 python3, 因此還需要修改一下或是裝一下 python2 才能讓 repo 正常動作。 終於去年的某一天,repotermux不能正常使用了

於是就開始換成原生的 git submodules

git submodules

照著網路上的教學,把 submodules 設定好了,但本來 git submodule 其實是要定板用的,因此用起來就是有點多此一舉大材小用。

所以就來自己寫個方便用的 Makefile,來更新 submodules

將所有的 submodules pull 到最新的 master

1
2
3
4
5
6
.PHONY: pull
pull:
@ git pull && \
git submodule foreach --recursive --quiet pwd | \
xargs -P4 -i bash -c \
"cd {} && git config --get remote.origin.url && git pull"

自動 push 現在的 submodules 版本:

1
2
3
4
MSG ?= 'submodule sync'
.PHONY: push
push:
@ git commit -a -m "$(MSG)" || echo && git push

這樣可以省事一點,可以一步地很快更新到多個 repositories 到最新狀態。

git lfs

上網查多半看到建議,git 上不要 commit binary 檔案,原因就不細說了, 之前就真的看到有 repository 把每次發佈的 binary 版本都放上 github, 後來去 clone 的時候,得先抓下 4 GiB 的資料量。萬一不小心 commit 進去了, 要把這些刪掉也是相當麻煩的一件事。

而通常測試會用到的資料,也可能都會是大的 binary 檔, 因此之前的作法是放在某一台公用的 server,所以除了 clone 之外, 也還另外需要多一個步驟把這些檔案抓下來,可能還會因為環境不允許也不能正常存取。

所以有了 lfs(Large File Storage),查了一下發覺工作邊用的 gitlab 預設就有支援 lfs,而個人自己的 gitea 也有支援了,只要設定檔設定一下就可以

1
2
; Enables git-lfs support. true or false, default is false.
LFS_START_SERVER = true

使用起來也覺得相當方便,甚至是需要時候再來下載這些被 track 的大型檔案們

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git lfs install

$ GIT_LFS_SKIP_SMUDGE=1 git clone gitea:your_repo
$ cd your_repo
$ git lfs ls-files
fd1ec2d6dc - stages/models/lfs/data.tar.gz
$ ls -l stages/models/lfs/data.tar.gz
-rw-r--r-- 1 yumaokao yumaokao 134 12月 14 22:34 stages/models/lfs/data.tar.gz

$ git lfs fetch
$ git lfs checkout
$ ls -l stages/models/lfs/data.tar.gz
-rw-r--r-- 1 yumaokao yumaokao 156435433 12月 14 22:39 stages/models/lfs/data.tar.gz

雖然真的太大的檔案也是要斟酌一下,但比起以往實在是方便不少。

而現在也才用了些許的 lfs 功能,應該之後會持續大量使用,更有點心得之後, 再來這裡分享。