🏹

Gitコマンド入門::Gitオブジェクト(update-ref)第五十四回

5 min read

みなさんこんにちは! 今回もGit本家のサイトを参考にして進めていきますね。
今回は、git update-ref コマンドで、ローカルブランチを作成します! 勿論、只のテキストファイルであり、ファイル中身はコミットのハッシュ値なので、linuxのecho コマンドでも作成できますけど、そこまで、お行儀が悪いことをするもなんですからね~

前回、第五十三回の記事はこちらから!

https://zenn.dev/shiozumi/articles/98a9eabe91682a

git本家本元の情報はこちらから!

https://git-scm.com/book/ja/v2

今日の課題も前回同様、ここを参考にしています!

https://git-scm.com/book/ja/v2/Gitの内側-Gitの参照

10.3 Gitの内側 - Gitの参照

Gitの参照の一番上からはじめます!

リポジトリ環境はこちらから、git clone してください!

git clone https://github.com/shiozumi-makoto/20210319.git

git clone https://github.com/shiozumi-makoto/20210319.git

// 中略~
To https://github.com/shiozumi-makoto/20210319.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

$ ls -a 20210319/
.  ..  .git  bak  new.txt  test.txt

// 20210319 フォルダーが作成されますね!

refs の環境は、このようになっています!

find .git/refs と、find .git/refs -type f で確認してみましょう。

$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/heads/master // <!-- 既に master ブランチがあります!
.git/refs/tags
.git/refs/remotes
.git/refs/remotes/origin
.git/refs/remotes/origin/HEAD // <!-- HEADもですね!

$ find .git/refs -type f
.git/refs/heads/master
.git/refs/remotes/origin/HEAD

git reset --hard を行っているので、master ブランチがあります。
又、GitHubリポジトリにもpushしてあるので、remotes/origin がある状態です。

では、いきなり勝手にブランチ作成!(笑)

そのまえに、コミット値を調べてからの~

$ git log --pretty=oneline master
1e3f4892a273326780b4fb8b44a5b76469b5ffa2 (HEAD -> master, 省略~) third commit
514ff38588f46b1459da95dc7ce671d3209c440a second commit
8cab88d049aa2c32533dd2c7aef02470d493d0ce first commit
// どのハッシュ値でもよいですが、今回は、second commit 514ff38 ~以下省略

今回は、second commit 514ff38(~以下省略)から、ローカルtestブランチを作成します!

git update-ref refs/heads/test 514ff38

$ git update-ref refs/heads/test 514ff385
 
$ git branch -avv
* master                1e3f489 [origin/master] third commit
  test                  514ff38 second commit <!-- 作成OK!
  remotes/origin/HEAD   -> origin/master
  remotes/origin/master 1e3f489 third commit
  
// ローカルtestブランチが作成されました。ハッシュ値も、514ff38 ですね。

git log --pretty=oneline test
$ git log --pretty=oneline test
514ff38588f46b1459da95dc7ce671d3209c440a (test) second commit
8cab88d049aa2c32533dd2c7aef02470d493d0ce first commit

$ find .git/refs -type f
.git/refs/heads/master
.git/refs/heads/test // <!-- 新しく、test ファイルが追加!
.git/refs/remotes/origin/HEAD

cat .git/refs/heads/test
514ff38588f46b1459da95dc7ce671d3209c440a
// ファイルの中身は、勿論、commit のハッシュ値です!

$ git cat-file -p 514ff38
tree 0155eb4229851634a0f03eb265b69f5a2d56f341
parent 8cab88d049aa2c32533dd2c7aef02470d493d0ce
author Makoto Shiozumi <shiozumi@esmile-hd.com> 1616125383 +0900
committer Makoto Shiozumi <shiozumi@esmile-hd.com> 1616125383 +0900

second commit

// もう、すっかりお馴染みの、cat-file -p ですね!

$ git switch test
Switched to branch 'test'
// 勿論、testブランチの選択も可能です!(当たり前)

$ ls -a
.  ..  .git  new.txt  test.txt
// bak フォルダー消えました。ファイルの状態も完璧です!

git update-ref -d refs/heads/test

では、今度は、削除してみましょう!

$ git switch master

$ git update-ref -d  refs/heads/test

$ git branch -avv
* master                1e3f489 [origin/master] third commit
  remotes/origin/HEAD   -> origin/master
  remotes/origin/master 1e3f489 third commit
// ローカルtestブランチもありません。

$ find .git/refs -type f
.git/refs/heads/master
.git/refs/remotes/origin/HEAD
// refs/heads/test ファイルも削除されましたね!

では最後に、echoコマンドで作成!

$ echo 514ff38588f46b1459da95dc7ce671d3209c440a >> .git/refs/heads/test
// ほんと、こんなことしていいのかい?!(^▽^;)

$ git switch test
Switched to branch 'test'
// 選択できちゃうし・・・

$ git branch -avv
  master                1e3f489 [origin/master] third commit
* test                  514ff38 second commit
  remotes/origin/HEAD   -> origin/master
  remotes/origin/master 1e3f489 third commit

// ローカルtestブランチ出来てます!

// さらに、強引に削除!
$ rm .git/refs/heads/test

// master に切り替えて!
$ git switch master

// 無事、完了!
$ git branch -avv
* master                1e3f489 [origin/master] third commit
  remotes/origin/HEAD   -> origin/master
  remotes/origin/master 1e3f489 third commit

結局、最後にechoコマンドで、強引にブランチ作成をして、rmコマンドで削除までやってしまいましたけど、平成生まれの育ちのよい若い人たちは、マネしないように!(苦笑)

まとめ

いや~、こんなに手軽に、ローカルブランチの追加削除が出来てしまうと、なんだか、ブランチのイメージが軽くなりましたね。その昔は、git branch -D で削除したりするときも、ちょっと、ドキドキしたりしていたものですけどね。(^▽^;) 要は、任意の時点のコミット値を保管して置くだけの、単なるテキストファイルです。ハッシュ値の指す、実際のオジェクトは、.git/objects/に、しっかり残っていますから、そんなに重さのある物ではなかった! ということで、お手軽で便利なブランチをもっと活用できるようになりましょう!

ほんとのまとめ

肝心なことを、すっかり忘れていました。そもそも、このコマンド、どういうシーンで使うのでしょうか? 私も、まだ全然わかりませ~ん!! いやいや、これまた勉強不足でごめんなさい。何はともあれ、まずは、ブランチの仕組みだけでも理解して置きましょう!

それでは、今回はここまで、お疲れ様でした!

https://zenn.dev/shiozumi/articles/d28f7fa1faa9b5
https://twitter.com/esmile2013