howto/git

一行メモ


ファイルの追加・名前変更・削除

ファイルを追加(追跡対象にする。ステージに載せる)

  例) find . -type d -empty -not -path './.git*' -exec touch {}\/.gitkeep \;
git add .         # カレント以下のファイル(ディレクトリ含む)をステージに追加する
git add ファイル  # ファイルをステージに追加する
git add -u        # 追跡対象のファイルで修正があったものをステージに追加する

ファイル名変更

git mv 変更前のファイル名 変更後のファイル名    # 単に mv? して、git commit -a してもOK?

ファイルの削除

git rm [--cached] 削除ファイル  # --cachedがあるとステージからも削除し、追跡対象からはずす。
                                # 間違ってaddしたファイルをステージだけからいったん削除したいときは、
                                # git reset HEAD file を使う(説明を参照のこと)。

git ls-files -o  # 全ての未管理ファイルを表示

git update-index --skip-worktree ファイル名
  # 指定した作業領域上のファイルの変更を、維持するように登録する
  # (マージしても変更されなく、維持される)
git update-index --no-skip-worktree ファイル名
  # 上記の登録を解除する
git ls-files -v | grep  ^S
  # skip-worktreeしたファイルを確認する

エラー対応: unable to read askpass

$ git push
(gnome-ssh-askpass:hogehoge): Gtk-WARNING **: cannot open display:
error: unable to read askpass response from '/usr/libexec/openssh/gnome-ssh-askpass'
Username for 'https://github.com':
などと、表示される場合の対応。

- 無視して、つづけて問題無い。
 (GUI環境で無いために、パスワードキャッシュがうまく動かなかったらしい)

- unset SSH_ASKPASS
  をすると表示されなくなる。

commit, reset, merge など

コミット

git commit -m 注釈     # ステージ済みをコミットする
git commit -a -m 注釈  # 追跡対象(のみ!)をステージしてコミットする
git commit --amend     # 直前のコミットを上書きする(直前のコミットをやり直せる)。ただしpush後にすると、
                         両者のmergeが必要となる。

コミットするときの注意点

    ⇒ むずかしいのでほどほどで対応すればよい。

    ⇒ 上記のコミット例、git commit -a -m 注釈 は、コミットメッセージの詳しい説明を省略している。
    ⇒ コミットメッセージは英語でする。日本語は使わないこと。

リセット

git reset HEAD file    # ステージにあるfileを取り除く。そのfileは作業ディレクトリに移動する(マージされるようだ)。
git reset --hard       # 現在のブランチを、チェックアウトの時点まで取り消す(修正中ファイルは削除される!)
git checkout -- file   # fileをチェックアウトの時点にもどす(fileの修正箇所は削除される元に戻る!)

マージ

status, diff, show, log

git status [-s]    # -sは簡潔表示であり、gitで管理していないファイルは「?? ファイル名」で表示される。

git diff [ファイル]  # 作業ディレクトリとステージの比較(ステージにファイルが無ければコミット済みと比較される)
git diff --cached [ファイル]           # ステージとコミット済みの比較

git diff A B    # 差分をみる。AやBは SHA1[:ファイル]|タグ
git diff A..B   # 〃
git diff A...B  # AとBとの共通の親と, Bの差分

git diff master..origin/master    # リモートリポジトリ(origin/master)との差分をみる(fetch済みであること)

git diff -w  #  ファイル内のスペースの違いを無視
git diff -b  #  ファイル内のスペースの数の違いを無視

git diff --name-only
  # ファイル名だけを比較する
  # 削除されたファイルは表示されないようだ(git diffをすると詳細がわかる)
 git diff --name-status    # ファイル名だけでなく、変更か追加か削除かも表示
git diff コミット名1 コミット名2 -- ファイル名
  # 両方のコミットで、ファイルを比較

git diff コミット名1:ファイル名1 コミット名2:ファイル名2
  # 各コミットのファイルを比較

git show オブジェクト[:ファイル]  # SHA1で指定したオブジェクト(コミット、ツリー、ファイル)を表示する。
                                  # :ファイル で限定もできる。

git log -5 --oneline --decorate --graph --all [--stat] [-p]  # --graphにより図形表示される
                                                             # --author=パタン でuser.nameの選択ができる
                                                             # --decorateによりHEADの位置がわかる
                                                             # -pはソースの差分が出る。
                                                             # --statはサマリーが出る。
                                                             # -5は 5件だけ表示

git log --since="50 minutes ago" [ファイル名]    # 50分前からのログのみ表示

git log --no-merges issue54..origin/master    #ログのフィルター記法
 #origin/masterには含まれるが、issue54には含まれないコミットのログだけを表示

git log contrib --not master  # masterに無くcontribブランチにあるコミットのログを表示

grep

git grep --heading --line-number -3 'readGrid'
    # ファイル名を先頭に、行番号を行頭に、検索文字列の前後各3行、をマッチしたもの
    # について表示する

git grep -w 文字列  # 単語境界での検索
         -F         # 正規表現を利用しない
         -l         # マッチしたファイル名だけ表示
    # 作業領域で追跡対象のファイルを対象に検索が行われる。

$ git grep -l 文字列 | xargs sed -i '' -e 's/文字列/置換文字列/g'
                        # なお、-iが空でなければその拡張子でバックアップが作られるらしい。

git rev-list {--all|ブランチ名} | xargs git grep '文字列'
    #すべてのブランチか、指定したブランチについて、検索が行われる。

blame

git blame [-C] -L n,m file    # fileに対して、n~m行目の最後のコミットをリストアップする
                              # -Cがあると別の所からのコピーがあれば示してくれる

その他 gitに bisectというものもあり(二分探索によるデバッグ支援)。

clean 作業ディレクトリの不要なファイルを削除する

git clean -n で確認して git clean -f で追跡対象以外(無視するファイルは除く)を
削除できる。(カレントディレクトリのみ対象にしたいときは-dを付ける。
無視するファイルも消す?ときは-xを付ける。対話的に消したいときは-iを付ける?)

branch

git branch ブランチ         # ブランチを作成
git branch -vv              # ブランチを表示
git branch -d ブランチ      # ブランチを削除(ローカルのブランチ)
ローカルにある◯/◯のリモートブランチと、ローカルリポジトリのブランチをすべて表示
git branch -a

ローカルにある◯/◯のリモートブランチを削除する
  git branch -d|-D -r originfuji/masterfuji    #-Dはマージしていなくても削除する場合

リモートリポジトリのブランチを削除する(pullやcloneされた別のリポジトリは、その人が消さない限りそのまま残る)
  git push origin --delete origin nwp2
  git push origin :nwp2
  git push origin :refs/heads/nwp2
らしい

git branch --merged       # 現在作業中のブランチにマージされたブランチのリストを表示
git branch --no-merged    # 現在作業中のブランチにマージされていないブランチのリストを表示

git branch ブランチ1 リモートリポジトリ/ブランチ2    # リモートリポジトリ/ブランチ2を追跡
                                                       # するブランチ1を作る
git branch --set-upstream=リモートリポジトリ/ブランチ2 ブランチ1  # リモートリポジトリのブランチ2を追跡
                                                                    # するようにブランチ1を設定する
--set-upstream の省略形は -u である。
git branch -m 古いブランチ名 新しいブランチ名  #ブランチ名を変更する
git branch -m 新しいブランチ名                 #現在のブランチ名を変更する

fetch, pull, push

git fetch [リモートリポジトリ] [ブランチ]  # リモートリポジトリから最新情報を取得する
git fetch --all   # 登録されている全てのリモートリポジトリから最新情報を取得する
git fetch --tags  # リモートリポジトリにあるタグも取得する

git pull [リモートリポジトリ]    # fetchし、mergeする(pull=fetch+mergeに相当)

git push [リモートリポジトリ] [ブランチ] [--tags]
    # 競合が発生した場合は pushはできない(pullして競合解決してから pushする)。
    # --tagsはタグもプッシュする
(その他参考)
リモートリポジトリに無いブランチをpushする例
  master     8ed9219 [origin/master] Merge branch 'master' into HEAD
  masterfuji 8ed9219 [originfuji/master: ahead 3] Merge branch 'master' into HEAD
があり、今使っているブランチが masterfujiであり、pushしたいとして、git pushしたとする。
ブランチが、リモートリポジトリに無い(masterfuji?)ときに
  git push
すると、サゼッションが出る。それに従うとよい。すなわち、
  リモートリポジトリの masterとして pushする場合:
    git push originfuji HEAD:master
  リモートリポジトリに今使っているブランチ名で新しく追加する場合:
    git push [--tags] originfuji masterfuji  #このやり方は、現在のブランチをoriginfuji/masterfujiという
                                    #ブランチ(新たに作成or更新するようだ)にpushするときにも有効である。
とする。

新しいブランチを作り、追いかける手順(例)

作業領域やステージはcommit,push済であるとする。
$ git branch nwp      # 現在の状態で、ブランチnwpを作成
$ git checkout nwp    # ブランチnwpに移動(作業ディレクトリのファイルは同じものである)
なお、ここでaddやcommitをしても良い。
$ git push --set-upstream origin nwp  # リモートリポジトリoriginのブランチnwp(作成される)にpushする。
                                      # ブランチnwpは、origin/nwpを追跡するように設定される(オプション
                                      # --set-upstreamによる)。
$ git remote -v ; git branch -vv  # 確認
作業領域やステージはcommit,push済であるとする。
$ git fetch
$ git checkout --track origin/nwp
$ git remote -v ; git branch -vv  # 確認

tag

git tag                                      # タグを表示
git tag [-a] タグ [SHA1ハッシュ] [-m 注釈]   # タグを付ける(-aと-mで1行の注釈を入れれる。-aのみは注釈を入れるため
                                             # エディタが立ち上がる)
git tag -d タグ名     #タグ名を削除する
git show タグ名       #タグ名の情報を表示
git fetch --tags   #リモートリポジトリのタグを取得する
git push --tags                      #リモートリポジトリに無いタグを、全て送る
git push --delete リポジトリ タグ名  #リポジトリ(originなど)のタグ名を削除
git push origin :refs/tags/タグ名    #タグ名と同名のブランチがあるとき、タグ名を削除する
git push origin :refs/heads/ブランチ名  #ブランチを削除

checkout

git checkout [-b] ブランチ [タグ|リモートリポジトリ/ブランチ]    # ブランチに移動。-bがあればブランチ作成後、移動する。
                       # タグがあれば、その所にブランチを作る(ただしコミットするとブランチは進みタグとズレるので注意)。
                       # リモートブランチがあれば、その所にブランチを作る。
                       # 追跡対象外のファイルなどは、そのまま残される。
git checkout --track リモートリポジトリ/ブランチ    # git checkout -b ブランチ リモートリポジトリ/ブランチ と同じ。
                       # 作成されたブランチはリモートブランチ(追跡ブランチ、上流ブランチ)を追跡するように設定される。
git checkout [SHA1|タグ|masterなど]    # 指定のものをチェックアウトする。
                       # ブランチ名(masterなど)ではなく、SHA1(ハッシュ値)を指定した時、detached HEADになが、
                       # 普通どおり修正してコミットできる(ブランチ名を新たにつける方が取り扱いやすい)。

その他のコマンド等

gitk    # GUIツール
git help コマンド名
git grep 文字列 [タグ|SHA1]      # 該当プロジェクトで文字列検索
.gitignore 設定ファイル    # 無視するファイルを書き入れる(*.oなど)。ディレクトリ階層に再帰的に適用
git config [--global] -l    # .git/configを表示
git config [--global] -e    # .git/configを編集
HEAD    # 現在作業中のローカルブランチを示す
git diff差分はそのままでパッチファイルになっている。
また、パッチファイルを使って、リダイレクションでパッチをあてることが出来る。
patch [--dry-run] -p1 < パッチファイル    #パッチファイルをあてる場合
                                          #--dry-runは何が行われるかを表示するだけ。

リポジトリの作成・移動

ベアリポジトリ

・作成方法1

cd ディレクトリ.git  # 拡張子を慣習的につける
git init --bare

ローカルリポジトリ

・作成方法1(新規作成)

cd 作業ディレクトリ
git init
・作成方法2(リモートリポジトリのクローン)

git clone リモートリポジトリ [作業ディレクトリ]
  # リモートリポジトリは [ssh://[user@]host.xz[:port]]/path_to_repo.git などのurlで指定する。
  # 自動的に、origin という登録名でurlが登録され、リモートブランチ(origin/master)を追跡するブランチ master が作られる。
  # 作業ディレクトリを省略すると、リモートリポジトリのディレクトリ名(ディレクトリ名.gitの.gitの前の部分)となる。
  # 作業ディレクトリを指定する場合は空ディレクトリでなくてはならない。

リモートリポジトリの移動に伴う設定の変更

リモートリポジトリの移動自体は単にまるごとディレクトリを移動するだけである。
これに追従しているリポジトリは
    git remote set-url origin 新しいリモートリポジトリ
などとして、登録名の内容を更新する(originを消して作ってもよいだろう)。

空のリモートリポジトリ(ベアリポジトリ)にpushする(新規のベアレポジトリにファイルを追加する)例

git add ファイル
git remote add origin リモートリポジトリ  # リモートリポジトリを登録名originとして、登録する
git remote -v ; git branch -vv
git commit -m "注釈"
git push --set-upstream origin master     # --set-upstreamは現在のプランチの追跡先を、origin/masterとする設定も登録する

リモートリポジトリの登録、変更、削除

git remote add リモートリポジトリの登録名 リモートリポジトリのurl
git remote rename リモートリポジトリの変更前の登録名 リモートリポジトリの変更後の登録名
git remote rm 削除するリモートリポジトリの登録名
git remote set-url origin 変更後のリポジトリのURL

git remote [-v]  # 一覧表示

最初設定すると良いこと

git config --global user.name   "yourname"   # 実行すると ~/.gitconfigに保存される
git config --global user.email  "youremail"  # --global無しだとレポジトリ毎の.git/configに保存される
git config --global core.editor emacs
git config --global push.default simple      # simple(デフォルト)、matching(2.0以前のデフォルト)

git config --global credential.helper 'cache --timeout=1800'  # 数分間だけ認証をキャッシュする。
                                                              #httpsのみ?sshのヘルパーを動かす?

はじめてのGit

以下の文章のオリジナルは、word文章として ここ にある。

2017/06/23 okazaki,i
はじめてのGit

- 以下のファイル名、ディレクトリ名、注釈などはすべて英語とする(日本語は避ける)

概要や予備知識

o ローカルリポジトリ(自分が作業に使っているリポジトリのこと。目の前にあるものなので、ローカルなリポジトリである。
  単にリポジトリとも呼んだりする)

・作業ディレクトリをもつ(開発するソースコードなどのファイルやディレクトリが置かれる)。

・作業ディレクトリには ".git"というディレクトリがあり、コミット済やステージングしたファイル、リモートリポジトリの
  情報などが保存されている(これがリポジトリの本体)。

・作業ディレクトリにあるファイルのうち、追跡対象として登録されているものだけをgitは版管理する(コミットされた版に
  対して、ありとあらゆる事ができる。版は分岐でき、各分岐はブランチと呼ぶ)。

・作業ディレクトリ上で、(1) ファイルを新規作成や修正して新しい版を作り、(2) ステージに載せて(ステージに登録、
  ステージングなどとも言われる。ステージのことをインデックスやキャッシュとも言われる)、(3) コミットをすることで、
  新しい版が.gitディレクトリに保存される。

・作業ディレクトリにある追跡対象になっているファイルはおよそ次の状態のいずれかである。

1) コミット済(版として登録されているファイルと同じ)

2) ステージ済(コミットする予定として登録されているファイルと同じ)

3) 修正中(未コミットであり、ステージにも未登録な版のファイル。ステージ登録後にコミットせずに修正することもできる)

・ふつう、ローカルリポジトリは追跡しているリモートリポジトリを持つ。リモートリポジトリは他のリポジトリのことである
  (同じマシン上のときもあれば、異なるマシン上のリポジトリのときもある)。リモートリポジトリから新しい版を取り寄せ
  たり(pull)、リモートリポジトリに新しい版を送ったり(push)できる。

・リモートリポジトリは名前(originなど)を付けて複数登録できる。

・新規にローカルリポジトリを作ると、ブランチはmasterになっている。ローカルリポジトリが他のリポジトリを追跡するよう
  に作成(clone)した場合には、追跡しているリポジトリのURLがoriginに登録されている。

o リモートリポジトリ

・ローカルリポジトリ以外のリポジトリである。
・ふつうは、ベアリポジトリである。

o ベアリポジトリ

・作業ディレクトリを持たないリポジトリ(ローカルリポジトリの.gitディレクトリのみから成る)である。
・作業ディレクトリを持たないため、ここで作業をしてpushやpullするような事はできない。


最初に一度だけする設定(マシン毎)

 $ git config --global user.name     "名前"
 $ git config --global user.email    "メールアドレス"
 $ git config --global core.editor   emacs
 $ git config --global push.default  simple
 

使い方の例(リポジトリの作成)

o ローカルで、あるディレクトリを対象にして、自分だけが使う場合

  $ cd ディレクトリ
  $ git init
 

o 既存のベアリポジトリをクローンして利用する場合

  $ git clone ベアリポジトリのURL  作業ディレクトリ名
 

o 新規にベアリポジトリを作り、利用する場合

  あるマシンで
  $ mkdir ベアリポジトリのディレクトリ名.git
  $ cd ベアリポジトリのディレクトリ名.git    #(*)
  $ git init --bare

  あるマシンで
  $ cd ディレクトリ(作業ディレクトリにするディレクトリ)
  $ git init
  $ git remoteadd origin  上記(*)のベアリポジトリのURL
     #URLは ssh://xxx@yyy:/~/ベアリポジトリのディレクトリ名.git など
  $ git add ファイルやディレクトリ  #下記参照
  $ git commit -m "注釈"            #下記参照
  $ git push --set-upstream origin master


使い方の例(作業)

o ファイルをステージングし、ローカルリポジトリにコミットする

  $ git add ファイル  #ファイル(ディレクトリも指定が可能)をステージングする。
                      #初めてaddされたファイルであれば、自動的にgitで版管理する追跡対象になる。
 
  $ git commit-m "注釈"  #ステージングされたファイルをローカルリポジトリにコミットする。
                         #注釈は英語で!


o ローカルリポジトリの更新内容をリモートリポジトリに送る
  $ git push


o リモートリポジトリの更新内容を作業ディレクトリに取り込む
  $ git pull
 

o 新しくローカルリポジトリにブランチを作る
  $ git checkout -b ブランチ  #ブランチを作成し、作成したブランチに移動する


o 既存のブランチに移動する(ブランチを切り替える)
  $ git checkout ブランチ     #既存のブランチに移動する(未コミットなどがあれば移動できない)
 

o 新しくローカルリポジトリにブランチを作り、リモートリポジトリにpushする(リモートリポジトリに同名のブランチが
  無いとき)
  $ git checkout -b ブランチ  #ブランチを作成し、作成したブランチに移動する
  $ git push --set-upstream  origin ブランチ
      #リモートリポジトリoriginにブランチをpush(作成)し、ローカルリポジトリのブランチが
      #originの作成(push)したブランチを追従するように設定する。


o リモートリポジトリにあるブランチを追跡するように、ローカルリポジトリに同名のブランチを作成し、作成したブランチ
  に移動する(ローカルリポジトリに同名のブランチが無いとき)
  $ git checkout --track origin/ブランチ


o 更新内容の表示など
  $ git fetch                       #リモートリポジトリの更新内容を読み込む
  $ git remote -v ; git branch -vv  #リモートリポジトリを表示;ブランチを表示
  $ git status                      #作業ディレクトリの状態表示
  $ git log -15 --oneline --decorate --graph--all  #コミットログを表示
  $ gitk --all                                      #コミットログを表示(GUIによる)


o 今、作業ディレクトリがあるブランチであり、ここにoriginのmasterブランチをマージしたいとき
  $ git merge origin/master


練習1

ivy.eit.hirosaki-u.ac.jpにログインして、"最初に一度だけする設定"をする。

次に、適当なディレクトリで、

$ git clone git://git.kernel.org/pub/scm/git/git.git #作業ディレクトリ名を省略した
$ cd git
$ git remote -v
$ git branch -vv
$ git status
$ git log  --oneline --decorate --graph --all
   一画面下にスクロール SPC
   一画面上にスクロール w
   一行上にスクロール   j
   一行下にスクロール   k
   下に検索             /    ⇒ origin/masterという文字列を検索してみる
   上に検索             ?
   次のもの検索         n
   一番下を表示         ESC >
   一番上を表示         ESC <
   終了 q

$ DISPLAY=hogehoge:0 gitk --all
$ DISPLAY=hogehoge:0 gitk
$ DISPLAY=hogehoge:0 gitk --all &
$ git log   --oneline --decorate --graph --all | tail
$ git checkout -b mytest e83c51633
$ git help checkout
$ git status
$ git log   --oneline --decorate --graph --all | tail
$ make  #失敗するので、
Makefileの
  LIBS= -lssl
を
  LIBS= -lssl -lcrypto -lz
に変更して、再度makeする
$
$ git status
$ git add -u
$ git status
$ git commit -m "modify Makefile"
$ git status
$ git branch -vv
$ git log   --oneline --decorate --graph --all | head ; echo ... ; \
  git log  --oneline --decorate --graph --all | tail
また、gitkのメニューから更新を選んで、ログを確認して、終了q。


練習2(1のつづき)
$ mkdir ../hoge; cd../hoge  #適当なディレクトリを作り、移動する
$ cp../git/{*.[ch],Makefile,README} .
$ ls
Makefile  cache.h    commit-tree.c  read-cache.c  show-diff.c     write-tree.c
README    cat-file.c init-db.c      read-tree.c   update-cache.c
$ git init
$ git add *.[ch] Makefile README
$ git status
$ git commit -m "the first commit"
$ git log   --oneline --decorate --graph --all
$ git remote -v ; git branch-vv

たとえば、emacsでMakefileをオリジナルのもの(LIBS= -lssl)に戻す。
$ git diff
$ git add Makefile
$ git commit -m "make Makefile the original"
$ git log   --oneline --decorate --graph --all
$ git checkout -b testb
$ git branch -vv
emacsで MakefileのLIBSを -lssl -lcrypto -lz にする。
$ git add Makefile
$ git commit -m "modify Makefile"
$ git log   --oneline --decorate --graph --all
$ git branch -vv
$ git checkout master
$ git branch -vv
emacsで MakefileのLIBSを -lssl -lcrypto にする。
$ git add Makefile
$ git commit -m "modify Makefile, again"
$ git log   --oneline --decorate --graph --all


遊び(練習1のつづき)
cd ../gitなどで、練習1のディレクトリに移動する。
最初のgitを動かしてみる。そのままでは実行時にエラーになるようなので、
read-cache.cの228行目付近のif文をコメントアウトして、makeし直す。
-               if (size > sizeof(structcache_header))
+//             if (size > sizeof(structcache_header))
                        map = mmap(NULL, size,PROT_READ, MAP_PRIVATE, fd, 0);
$ ./init-db  # .dircacheディレクトリが作成される(.git相当)
$ ./update-cache *.[ch] Makefile README  #update-cacheが git add相当
$ ./write-tree                           #write-tree,commit-treeが git commit相当
6ca44177a19e6ca8f2f761b7415a4360d2db6b8e
$ ./commit-tree 6ca44177a19e6ca8f2f761b7415a4360d2db6b8e <<eof
the first commit
eof
Committing initial tree 6ca44177a19e6ca8f2f761b7415a4360d2db6b8e
bab38708b02450867071a94a9fce18123597835d
$ cat `./cat-file bab38708b02450867071a94a9fce18123597835d | sed 's/:.*$//'` #コミットの表示
tree6ca44177a19e6ca8f2f761b7415a4360d2db6b8e
author okazaki,isao,,<okazaki@ivy> Fri Jun 23 14:41:39 2017
committer okazaki,isao,,<okazaki@ivy> Fri Jun 23 14:41:39 2017

the first commit

$ ./read-tree 6ca44177a19e6ca8f2f761b7415a4360d2db6b8e #コミットの内容(ツリー)
100664 Makefile(dfa152bcc0e5f29d5a2db9a482d7e65660a6fe61)
100664 README (665025b11ce8fb16fadb7daebf77cb54a2ae39a1)
100664 cache.h(9e1bee21e17c134a2fb008db62679048fc819528)
100664 cat-file.c(fd690acc02ef9c06d7c4c3541f69b10ca4b4f8c9)
100664 commit-tree.c(a4a8c3d9ef0c4cc6c82b96b5d1a91ac6d3bed466)
100664 init-db.c(0eaa053919e0cc400ab9bc40d9272360117e6978)
100664 read-cache.c(4d3c01ab27d6745be53d5caf862e5ce4d939961c)
100664 read-tree.c(ec0f167a6a505659e5af6911c97f465506534c34)
100664 show-diff.c(00a29c403e751c2a2a61eb24fa2249c8956d1c80)
100664 update-cache.c(aff074c63ac827801a7d02ff92781365957f1430)
100664 write-tree.c(7abeeba116b2b251c12ae32c7b38cb048199b574)
$ ./show-diff
Makefile: ok
README: ok
cache.h: ok
cat-file.c: ok
commit-tree.c: ok
init-db.c: ok
read-cache.c: ok
read-tree.c: ok
show-diff.c: ok
update-cache.c: ok
write-tree.c: ok

次に、emacsでread-cache.cの228行目付近にfprintfを追加(追加内容は以下のdiff参照)。
$ ./show-diff
Makefile: ok
README: ok
cache.h: ok
cat-file.c: ok
commit-tree.c: ok
init-db.c: ok
read-cache.c:  4d3c01ab27d6745be53d5caf862e5ce4d939961c

--- -   2017-06-23 14:54:17.547672847 +0900
+++ read-cache.c        2017-06-23 14:53:00.644494732 +0900
@@ -228,6 +228,8 @@
                map = NULL;
                size = st.st_size;
                errno = EINVAL;
+fprintf( stderr, "size= %d\n", size );
+fprintf( stderr,"sizeof = %d\n", sizeof(struct cache_header) );
 //            if (size > sizeof(struct cache_header))
                        map = mmap(NULL, size,PROT_READ, MAP_PRIVATE, fd, 0);
        }
read-tree.c: ok
show-diff.c: ok
update-cache.c: ok
write-tree.c: ok
$ ./update-cacheread-cache.c
$ ./write-tree
792883deac0a678d1975ddb4acce30ed15010149
$ ./commit-tree 792883deac0a678d1975ddb4acce30ed15010149 \
             -p bab38708b02450867071a94a9fce18123597835d <<eof
add fprintf
eof
8af70d35558e4226155fdad489654a0ece5ee196
$ cat `./cat-file 8af70d35558e4226155fdad489654a0ece5ee196 | sed 's/:.*$//'`
tree 792883deac0a678d1975ddb4acce30ed15010149
parent bab38708b02450867071a94a9fce18123597835d
author okazaki,isao,,<okazaki@ivy> Fri Jun 23 15:14:12 2017
committer okazaki,isao,,<okazaki@ivy> Fri Jun 23 15:14:12 2017

add fprintf

最初のコミットのツリー(6ca44177a19e6ca8f2f761b7415a4360d2db6b8e)の
read-cache.c(4d3c01ab27d6745be53d5caf862e5ce4d939961c)を取り出し、diffを
とってみる。

$ ./cat-file 4d3c01ab27d6745be53d5caf862e5ce4d939961c
temp_git_file_nV0xt4: blob
$ diff temp_git_file_nV0xt4read-cache.c
230a231,232
> fprintf( stderr,"size = %d\n", size );
> fprintf( stderr,"sizeof = %d\n", sizeof(struct cache_header) );

使い方は次を参考にすると良い。
 "git(1)の最初のコミットをビルドして使ってみた"http://qiita.com/gfx/items/826b5f846e6a960adcff
 "Gitの最初の姿"http://daretoku-unix.blogspot.jp/2015/03/git.html
 "初期のGitコマンドのソースコード"http://tanakahx.github.io/blog/2014/06/08/initial-git-source-code/

ソースからgitをインストールする例

ブラウザからダウンロード https://github.com/git/git/archive/master.zip
$ unzip git-master.zip
$ cd git-master
$ autoconf
$ ./configure --prefix=$HOME/bin
$ make all      # doc info はめんどいらしいので除く
$ make install  # install-doc install-html install-info は除く
# バージョンは、2.2.0.GITだった。
| git-master/INSTALLには次のように記載あり
| $ make prefix=$HOME/bin all doc info
| $ make prefix=$HOME/bin install install-doc install-html install-info

ブラウザからダウンロード https://www.kernel.org/pub/software/scm/git/ の git-manpages-2.2.0.tar.gz
$ tar xvfz git-manpages-2.2.0.tar.gz  -C $HOME/bin/share/man  # man{1,5,7}に追加される
MANPATH=$HOME/bin/share/man:$MANPATH を .bashrcに追加する

(補足) zlibが無かった場合には makeできないので、下のようにzlibをインストール後に、
再度 git-masterディレクトリで ./configure --prefix=$HOME/bin --with-zlib=$HOME/bin
としてから makeする。
  $ wget http://zlib.net/zlib-1.2.8.tar.gz
  $ md5sum zlib-1.2.8.tar.gz
  $ tar xvfz zlib-1.2.8.tar.gz
  $ cd zlib-1.2.8
  $ ./configure --prefix=$HOME/bin
  $ make
  $ make install

マニュアル・リンクなど


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS