git hash-object -wの挙動を追ってみた

echo hello > hello.txt
git hash-object -w hello.txt
このコマンドをたたくと、
.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a
というblobファイルが作られます。

git add hello.txtとほぼ同じ挙動なのですが、本当に同じかどうかソースコード(v1.8.4)を追って確かめてみました。
ソースコード的にはこのへんです。わりと読みやすくてステキ。
https://github.com/git/git/blob/v1.8.4/builtin/hash-object.c#L29

(ちなみにgit addの調査はこちら↓)
git add fileの挙動を追ってみた。

git hash-object -wのスタックトレース

gdbでスタックトレースを見てみるとこんな感じです。
#0  write_loose_object (sha1=0x7fffffffe3c0 "\316\001\066%\003\v\250\333\251\006\367V\226\177\236\234\243\224FJ", hdr=0x7fffffffe3a0 "blob 6", hdrlen=7, buf\
=0x7d33d0, len=6, mtime=0) at sha1_file.c:2872
#1  0x00000000004e7494 in write_sha1_file (buf=0x7d33d0, len=6, type=<value optimized out>, returnsha1=0x7fffffffe660 "\316\001\066%\003\v\250\333\251\006\3\
67V\226\177\236\234\243\224FJ\377\177") at sha1_file.c:2954
#2  0x00000000004e7559 in index_mem (sha1=0x7fffffffe660 "\316\001\066%\003\v\250\333\251\006\367V\226\177\236\234\243\224FJ\377\177", buf=0x7d33d0, size=6,\
 type=<value optimized out>, path=<value optimized out>, flags=<value optimized out>) at sha1_file.c:3060
#3  0x00000000004e7939 in index_core (sha1=0x7fffffffe660 "\316\001\066%\003\v\250\333\251\006\367V\226\177\236\234\243\224FJ\377\177", fd=6, st=<value opti\
mized out>, type=OBJ_BLOB, path=0x7fffffffec24 "hello.txt", flags=3) at sha1_file.c:3095
#4  index_fd (sha1=0x7fffffffe660 "\316\001\066%\003\v\250\333\251\006\367V\226\177\236\234\243\224FJ\377\177", fd=6, st=<value optimized out>, type=OBJ_BLO\
B, path=0x7fffffffec24 "hello.txt", flags=3) at sha1_file.c:3139
#5  0x0000000000436166 in hash_fd (fd=6, type=<value optimized out>, write_object=1, path=0x7fffffffec24 "hello.txt") at builtin/hash-object.c:21
#6  0x00000000004363be in cmd_hash_object (argc=1, argv=<value optimized out>, prefix=0x0) at builtin/hash-object.c:129
#7  0x0000000000404bf7 in run_builtin (argc=3, argv=0x7fffffffe980) at git.c:303
#8  handle_internal_command (argc=3, argv=0x7fffffffe980) at git.c:466
#9  0x0000000000404e22 in run_argv (argc=3, av=<value optimized out>) at git.c:512
#10 main (argc=3, av=<value optimized out>) at git.c:595
見にくいのでメモリアドレスと引数を省略すると下記のような感じ。
#0  write_loose_object  at sha1_file.c:2872
#1  write_sha1_file at sha1_file.c:2954
#2  index_mem at sha1_file.c:3060
#3  index_core at sha1_file.c:3095
#4  index_fd  at sha1_file.c:3139
#5  in hash_fd  at builtin/hash-object.c:21
#6  in cmd_hash_object at builtin/hash-object.c:129
#7  in run_builtin  at git.c:303
#8  handle_internal_command at git.c:466
#9  run_argv at git.c:512
#10 main at git.c:595
index_fd以降はgit addと同じ挙動であることがわかりました。

また、git addとgit hash-object -wの主な違いは、indexファイルに書き込むか書き込まないかの違いであることも、ソースコードレベルでわかりました。

すっきりすっきり。
カテゴリ:

人気記事