タグ別アーカイブ: git

空のディレクトリをgit管理下に入れるワンライナー(empty directories)


背景

chefを利用する機会が増えてきて汎用的な社内クックブックを作る状況が増えてきた昨今、

knife コマンドでクックブックをジェネレートするコマンドを実行すると

$ knife cookbook create COOKBOOK_NAME -o site-cook-books

バババっと以下のように基本的なディレクトリ構成で出力されるが、幾つか のディレクトリがある。

COOKBOOK_NAME
├── CHANGELOG.md
├── README.md
├── attributes
├── definitions
├── files
│   └── default
├── libraries
├── metadata.rb
├── providers
├── recipes
│   └── default.rb
├── resources
└── templates
    └── default
        └── sudoers.erb
attributes/, definitions/, files/default/, libraries/, proiders/, resources/ がそれぞれ空のディレクトリになっている

gitは空のディレクトリを管理下に置けないので、Railsに習って .keep という空ファイルを置くことにした。
(全てのリポジトリでディレクトリ構成の見た目を変えたくなかったので空のディレクトリもgit管理下に置くことにした。)


空のディレクトリに.keepを作るシェルのワンライナー

参考:
find/xargsを使った検索に便利なコマンド一覧

findで空のディレクトリを検索して、空のディレクトリに対して.keepという空ファイルをtouchで作成する。
Redhat系とUNIX(BSD)系では使えるオプションが違うようなので以下の用プラットフォームに合わせて実行する。

  • Redhat系
    -i オプションを指定することで ‘{}’で xargsに渡される値を取得できる
$ find . -type d -empty -print0 |xargs -0 -i touch '{}'/.keep
  • Unix系(MacOS)
    -Iオプションで % という文字列を xargsに渡される値として参照できるようにする
$ find . -type d -empty -print0 |xargs -0 -I % touch %/.keep

[git]タグの打ち方・消し方


githubを使ってソースを管理している時にあるタイミングでタグを打ちたいと思うことってありますよねー。僕はあリます。
ということで、中々タグを打つ機会ってないので、調べてみました!!

タグの打ち方

以下のようにtestという名前でタグを作ります

% git tag -a test -m "create test tag"

タグの確認

以下のようにすると現在のタグを確認することができます。

% git tag
test

作ったタグをリモートgitサーバへ転送する(githubなど)

リモートサーバ側にもtagを作成することができます。

% git push --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 162 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/yusabana/pratter.git
 * [new tag]         test -> test

タグのチェックアウト

作成したタグをチェックアウトしたりする。

単純にチェックアウトしてタグの中身を見る
この場合、ブランチは no branch 状態になる

% git checkout tags/test


tag から branch を生成してチェックアウトする
testタグからtest-branchというブランチを生成する

% git checkout -b test-branch tags/test

タグを削除する

ローカルからtagを削除するには以下のようにする

% git tag -d test

ローカルでtagを削除した状態でpushするとリモートにあるタグも削除することが出来る

% git push origin :test
To https://github.com/yusabana/pratter.git
 - [deleted]         test

タグを確認する

リモートにあるタグを一覧する

git ls-remote --tags

gistを便利に使うためのコマンドラインツール「gist」


githubのgistって便利ですよねー。ソースコード単位で変更管理が出来る。
サンプルなどを載せるのには最適ですね。
ただ、毎回ブラウザでアクセスして、テキストエリアに貼り付けてって面倒臭いですねー。それを解消するためのツールが「gist」

    【インストール方法】
    自分はMacでbrewを使っているので
    % brew install gist

以下のようにやるとちゃちゃっとgistにアップできます。gistのmanページに記載されていますー!!

    % gist < file.txt
    % echo secret | gist --private
    % echo "puts :hi" | gist -t rb
    % gist script.py
    % gist -
    この場合、ユーザの設定もしていないのであれば Anonymous としてアップされる

githubのアカウントの設定方法とアカウント情報をgitconfigに直で書くのではなく、includeを使って別ファイルを用いた処理について書きます!!
ちょっとハマった部分もありメモ代わりに


gistコマンドにgithubのアカウント設定

事前にgithubのアカウントは所持していることが前提となります。githubのアカウントを設定することで設定したアカウントでgistに投稿することができます。
単純に $HOME/.gitconfig に以下の内容を入れればOK

    % vi ~/.gitconfig
    [github]
    user     = USERNAME
    password = PASSWORD

ただ私の場合、設定ファイルはdotfilesとしてgithubで管理しています。gitconfigもgithub上に上げているので生パスワードを.gitconfigに書くのには抵抗が。。。

そこで、 Include ですよねーー。ユーザ名とパスワードは別ファイルにしてincludeさせる。別ファイルはgitignoreに設定してリポジトリへの更新対象外にする。ということです。
設定方法はこれまた単純に、.gitconfigに[Include]ディレクティブを追加するだけです。

    【gitconfigでインクルードする設定】
    % vi ~/.gitconfig
    [include]
    path = ~/dotfiles/.gitconfig.local

更に.gitconifg.localに [github]ディレクティブを設定します。

    【インクルードするファイルの設定】
    % vi ~/.gitconfig.local
    [github]
    user     = USERNAME
    password = PASSWORD

gistにアップして試してみる

いざ、やってみましょう。ちゃんとアカウントに紐付いてアップできるかなー

    % echo "Hello World" | gist -o

あれーー??Anonymousになってる。。。???

Includeの設定が効いてないのか??
ということで調べてみよう。。。


gistコマンドのコードを見てみる

gistはRubyのスクリプトで書かれているので何となく分かるだろうということで調査してみる!!!
brewでインストールしたので、「/usr/local/bin/gist」というファイルが実行ファイルになる。

    % vi /usr/local/bin/gist
    …略
    def config(key)
      env_key = ENV[key.upcase.gsub(/\./, '_')]
      return env_key if env_key and not env_key.strip.empty?
      str_to_bool `git config --global #{key}`.strip
    end
    …略

なるほどなー「git config –global」で情報を取得しているんだなーというところで確認してみる。

    % git config --global -l
    include.path=~/dotfiles/.gitconfig.local
    user.name=yusabana
    user.email=EMAIL
    color.ui=auto
    alias.st=status
    …略
    % git config -l
    include.path=~/dotfiles/.gitconfig.local
    github.user=********
    github.password=*******
    user.name=yusabana
    user.email=EMAIL
    color.ui=auto
    alias.st=status
    …略

上記2つの出力を見比べてみると「–global」の場合、「github.user」, 「github.password」の2つの設定includeのファイルの中身が展開されていない?!!!!これが原因じゃないか??
更に調べてみると、「–includes」 というオプションがあるではないか

    % git config --global --includes -l
    include.path=~/dotfiles/.gitconfig.local
    github.user=********
    github.password=*******
    user.name=yusabana
    user.email=EMAIL
    color.ui=auto
    alias.st=status
    …略

ちゃんとgithub.user, github.passwordが展開されていますねー
ということで、gistの実行ファイルを書き換えてみました。

    % vi /usr/local/bin/gist
    …略
    def config(key)
      env_key = ENV[key.upcase.gsub(/\./, '_')]
      return env_key if env_key and not env_key.strip.empty?
      str_to_bool `git config --global --includes #{key}`.strip
    end
    …略

これで修正は完了!!


もう一度gistを使って試してみる

今度こそ、、ちゃんとアカウントに紐付いてアップできるかなー

    % echo "Hello World" | gist -o

良し!!!いけました!!!

何とかコード修正も普通にgitコマンドを使っているところだったから問題なくいけましたねー!!
ちょっとgistコマンドのgithubのpull request 見ると同様の事を上げている方がいたので、自分もコメント入れておきました。

https://github.com/defunkt/gist/pull/113

ただ、これ見ると5ヶ月以上も更新してくれていないので、更新されるのを待つのもあれなので、スクリプトを修正しておこう。
また、これらを調べているうちに、「gisty」ってコマンドもあることを知った。これのほうが変更管理も出来るようで便利そう。gistコマンドは初回アップロードのみしか出来ないので。。。

今度はgistyを使ってみます!:)

git-diff で知っておくと役立つオプション


 

そんなこんなで、gitを使うようになって約3ヶ月ほど、ソースをマージしたり、管理することが多くなったので、diffについて良い感じのオプションを出してみますー

% git diff [option] [対象]

-b (インデントの空白を無視する(インデントの違いはdiffの差分に出さない))
-w (whitespaceを完全に無視)
-B (空の改行を無視)
–cached (addしたものステージングしたファイルと現在の差分を見る)
–word-diff (diffをwordごとに出来る)

[git]コマンドラインログビューワー tig が便利!!


git でビジュアル的にログとかを見たいなぁーって時は 以下のgitkを使っていた。

% gitk

普通にアプリとして、Gitのクライアントが立ち上がる。

ただログとかを見るだけなら tig のほうが便利そう!!

インストール

普通にhomebrew でインストールできる

% brew install tig
インストール場所は以下
% which tig
/usr/local/bin/tig
使用する
% tig