Table of Contents
Overview
What I Want
- GitHub Repositoryの任意のサブディレクトリのみをローカル側で取得する
Git version
1
2
% git --version
git version 2.31.1
サブディレクトレリ取得までの手順
手順
1: ローカル側で空ディレクトリを作る
1
2
3
% mkdir <directory name>
% cd ./<directory name>
% git init
2: sparsecheckout の設定
1
% git config core.sparsecheckout true
3: 取得元のリポジトリを設定
1
% git remote add origin https://github.com/<username>/<repository name>.git
4: 取得したいディレクトリをsparse-checkoutに設定
1
% echo <subdirectory name> > .git/info/sparse-checkout
仮に特定のファイルのみ取得したい場合は、上書きリダイレクション >
を用いて
1
% echo <path/to/file name> > .git/info/sparse-checkout
更に別ファイルを追加したい場合は, 追記リダイレクション >>
を用いて
1
2
3
% echo add-sub-directory >> .git/info/sparse-checkout
# ツリー情報を更新する
% git read-tree -m -u HEAD
5: pullする
1
% git pull origin main
なおここでの手順では紹介しないが, main
branchはcloneしてもよいが特定のbranchのファイルを
ローカルへ落とす際にsparse-checkoutを設定するという方法も考えられます.
1
% git clone --filter=blob:none https://github.com/hoge/fuge.git
というように--filter=blob:none
を設定するとブロブレスクローンが実行できます.
blobとはここではgit objectのうちのファイルとみなしてもらって大丈夫です.
Sparse checkout設定とは?
Sparse checkout
では, 作業ディレクトリをコンパクトにすることができます. skip-worktree bit を使って, 作業ディレクトリにあるファイルを見る価値があるかどうかを Git に伝えます. skip-worktree bitが設定されている場合, そのファイルは作業ディレクトリでは無視されます. Git はこれらのファイルの内容を入力しません. そのため, 多くのファイルがあるリポジトリで作業をしていて, 現在のユーザーにとって重要なファイルがほんの少ししかない場合などにSparse checkoutが役立ちます.
Sparse checkout
の設定は, .git/info/sparse-checkout
に格納されています. Gitは作業ディレクトリを更新するときに, このファイルに基づいてインデックスのskip-worktree bitを更新します. このファイルのパターンにマッチするファイルが作業ディレクトリに現れ, それ以外のファイルは現れません.
sparse-checkoutの確認
sparse-checkoutの確認したい場合,
1
2
3
4
5
% git sparse-checkout list
## 設定されていない場合
% git sparse-checkout list
warning: this worktree is not sparse (sparse-checkout file may not exist)
変更したい場合は, 元々の設定が消えて指定したPathのみが設定されますが
1
% git sparse-checkout set <path>
または, Pathを直接上書きする形でも可能です.
1
% echo <path/to/file name> > .git/info/sparse-checkout
sparse-checkoutの無効化と解除
sparse-checkoutの機能をdisableする場合, 無効化(disable)と設定解除する2つの方法があります.
基本的にはdisable
の場合だけで十分です.
無効化(disable)
これは設定ファイルは残るが, 機能は無効化されるコマンドです
1
% git sparse-checkout disable
このコマンド実行後, working directoryは.gitignore
で指定されたオブジェクト以外のすべてのオブジェクトをrestoreします.
設定解除
手順としては
.git/info/sparse-checkout
に全体を対象とするよう/*
を指定するgit read-tree
でツリー情報を読み込み直す.git/info/sparse-checkout
を削除sparsecheckout
を無効にする
1
2
3
4
% echo "/*" > .git/info/sparse-checkout
% git read-tree -mu HEAD
% rm .git/info/sparse-checkout
% git config core.sparsecheckout false
Remote repositoryの特定のファイルのみをダウンロードしたい場合
private repositoryの特定のブランチの特定のファイルのみをローカルへダウンロードしたい場合を考えます.
このとき, curl
とPATを上手く組み合わせることで実現することが出来ます.
前準備として,
- private repositoryやprojectへのアクセス権限が与えられたPATを取得
- 上記のPATを
$TOKEN
に格納する
その後,
1
2
## -s optionはsilentの意味
% curl -s https://$TOKEN@raw.githubusercontent.com/<user or org>/<repositoryname>/<branch>/<path>
とすると, private repositoryの任意のファイルをローカルへダウンロードすることが出来ます.
git-curl
という名前で以下のようにシェルスクリプト化し,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
## get a single file from a github repository
## Author: Ryo Nakagami
## Revised: 2024-01-23
set -e
## variables
URL=$1
TOKEN=hogehogehoge ##BE CAREFUL THIS IS SENSITIVE INFO
HEADER=https://
DOTCOM=@raw.githubusercontent.com/
## substition
UPDATEED_URL=${URL/https:\/\/github.com\//}
## main
curl -s $HEADER$TOKEN$DOTCOM$UPDATEED_URL
その後, 実行権限とPATHを通して
1
% git-curl https://github.com/user-name/repository-name/branch-name/path/test.txt
と実行するとローカルにダウンロードすることが出来ます. ただし, PATを平文で保存するのは良くない and 同じサーバー内の第三者がpsを叩くとPATが見れてしまうので, あまり推奨はできません.
盗み見されてしまう場合
2つのターミナルを立ち上げ,
curl
実行役ターミナル- 盗聴用ターミナル
のふたつを用意します.
まず実行側でシェルスクリプト化したコマンドを実行してみます
1
% git-curl https://github.com/RyoNakagami/RyoNakagami.github.io/main/_includes/plotly/20210122_simulation.html
同時に, うまいタイミングで盗聴側で以下のコマンドを実行します
1
2
3
4
% while true; do ps aww | fgrep curl && break; done
86766 pts/0 S+ 0:00 /bin/bash /home/ryo_billiken/bin/git-curl https://github.com/RyoNakagami/RyoNakagami.github.io/main/_includes/plotly/20210122_simulation.html
86767 pts/0 R+ 0:00 curl -s https://hokkaidowadekkaido@raw.githubusercontent.com/RyoNakagami/RyoNakagami.github.io/main/_includes/plotly/20210122_simulation.html
86770 pts/3 S+ 0:00 grep -F curl
すると上記のようにPAT(hokkaidowadekkaido
)が見れてしまいます.
PAT自体を暗号化して参照するようにはできますが, 最終的にcurl
でPATが平文で見えてしまうのでやはり推奨できない方法と言うことが出来ます.
References
(注意:GitHub Accountが必要となります)