Bareリポジトリだけで編集を全部やる
概要
gitのbareリポジトリとはワーキングディレクトリを持たないリポジトリである。
このリポジトリに変更を加えたい場合は基本的にはnon bareリポジトリとしてcloneしてそのワーキングディレクトリ内のファイルを編集してコミットしてプッシュすると思う。
ただし今回はなぜかcloneをせずに全てbareリポジトリ上で作業を完結させたいという目的が発生したのでそれぞれの方法をまとめてみた
bare リポジトリの作成
--bare
パラメータを付けてinitすると作成される
git init --bare <repo-name>.git
ブランチの作成
これは簡単
※commitが一つも無い状態だとエラーになるので注意
git branch new-branch-name
作成されたことを確認
$ git branch
develop
* master
初回コミット(空コミット)
treeオブジェクトを作成
$ git write-tree
4b825dc642cb6eb9a060e54bf8d69288fbee4904
作成したtreeオブジェクトを元にcommitオブジェクトを作成
$ git commit-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 -m 'first commit'
5cbe1e2c54da44015b5b1ee3e6e56614bb2e6bc8
refs を更新する
git update-ref refs/heads/master 5cbe1e2c54da44015b5b1ee3e6e56614bb2e6bc8
ファイルの追加(更新)
追加するファイルを作成する
echo 'version1' > version.txt
ファイルオブジェクトを追加
git hash-object -w version.txt
5bdcfc19f119febc749eef9a9551bc335cb965e2
追加されたオブジェクトの中身を確認してみる
$ git cat-file -p 5bdcfc19f119febc749eef9a9551bc335cb965e2
version1
indexに追加する
git update-index --add --cacheinfo 100644 5bdcfc19f119febc749eef9a9551bc335cb965e2 version.txt
indexからtreeオブジェクトを作成する
$ git write-tree
5b931184deb66f3bed6c4379bfad773b1e65dd3a
上記で作成したtreeオブジェクトを元にcommitオブジェクトを作成、初期コミットとつなげたいので -p
で親コミットを指定する
$ git commit-tree 5b931184deb66f3bed6c4379bfad773b1e65dd3a -m 'add version' -p 5cbe1e2c54da44015b5b1ee3e6e56614bb2e6bc8
76b1c8f63514249280853fabd5b143ad85a48172
作成したcommitオブジェクトを元にrefs を更新する
git update-ref refs/heads/master 76b1c8f63514249280853fabd5b143ad85a48172
ファイルの追加(フォルダ内ファイル)
ファイルの追加と大部分が被るので差分だけ。
update-indexに追加するパスにフォルダを含めるだけ。
git update-index --add --cacheinfo 100644 5bdcfc19f119febc749eef9a9551bc335cb965e2 test/version.txt
ファイル削除
ファイル削除はあらかじめcloneしたnon-bareリポジトリでファイルを追加してpushしておいた(file1.txt, file2.txt)(めんどくさかったので...)
HEADのcommitオブジェクトのハッシュを取得する
git rev-parse HEAD
aea7957d49a7d2e9515c569c146556bbb27171b2
commitオブジェクトに関連づくtreeオブジェクトのハッシュを確認する
git cat-file -p aea7957d49a7d2e9515c569c146556bbb27171b2
(略)
tree 561a7dd62dfb5fe3d7d8319e68dff75edf27064c
(略)
treeオブジェクトを元にindexに展開
git read-tree 561a7dd62dfb5fe3d7d8319e68dff75edf27064c
indexの内容を確認
$ git ls-files -s
100644 7284ab4d2836271d66b988ae7d037bd6ef0d5d15 0 file1.txt
100644 7284ab4d2836271d66b988ae7d037bd6ef0d5d15 0 file2.txt
今回はfile1.txtを削除する
git rm --cached file1.txt
indexを元にtreeオブジェクトを作成する
git write-tree
561a7dd62dfb5fe3d7d8319e68dff75edf27064c
上記のtreeオブジェクトを元にcommitオブジェクトを作成する
git commit-tree 561a7dd62dfb5fe3d7d8319e68dff75edf27064c -m 'delete file1.txt' -p f2d7479
aea7957d49a7d2e9515c569c146556bbb27171b2
作成したcommitオブジェクトを元にrefs を更新する
git update-ref refs/heads/master aea7957d49a7d2e9515c569c146556bbb27171b2
ファイル移動(リネーム)
基本的に上記手順のファイル削除とファイル追加を合わせたような手順なので重要な部分だけ記載する。
indexの状態を確認する。これらの値は後で利用する。
$ git ls-files -s
100644 7284ab4d2836271d66b988ae7d037bd6ef0d5d15 0 file2.txt
file2.txtを一時的に削除
git rm --cached file2.txt
mode
, hash
等は変えずにパスだけ変えて(file2.txt -> fileA.txt)indexに追加する
git update-index --add --cacheinfo 100644,7284ab4d2836271d66b988ae7d037bd6ef0d5d15,fileA.txt
indexを確認
$ git ls-files -s
100644 7284ab4d2836271d66b988ae7d037bd6ef0d5d15 0 fileA.txt
移行のツリーオブジェクト作成、コミットオブジェクト作成...は同じ手順なので省略
Discussion