opsだけどgitを使ってみた~その1

こんにちは。小宮です。 opsだけどgitを使ってみた~その1ということで、githubもgitlabもgitも初心者なので忘れないようにメモ。 今回はたどたどしくpushするところくらいまでにします。branch切ってみるとこは初回から書くとおなかいっぱいになりそうなので。 たぶんその2までです。その2はbranchとtagとconfrictのことを書いています。

背景とメリットデメリット

・背景  昨今の継続的インテグレーションだとかでchefでサーバ構築の需要があってその流れ弾に当たった機会を得たため、  そのリポジトリをバージョン管理する必要が生じましてgitをつかうことに。最初は会社のエンタープライズ版のgithubに保存してもらっていたんですが、  VPN経由でのやり取りの需要からgitlabの導入を行うことになりました。 ・gitのメリット  ヒストリ追わなくていい。見える化。ファイル内の差分が見やすいので確認がブラウザで容易に可能になる ・gitのデメリット  同僚がつかいはじめてくれない(必要にせまられないと忙しくてスルー傾向)  まあなんか気持ちはわかります。私もきっかけは半ば強制的な感じでした。

githubとgitlabの違い  gitコマンド的にはあんま変わんない気もしますが、制度がオープン(エンタープライズはクローズ可)かクローズでいけるか、  gilabの場合は容量制限もディスク容量とかの環境次第でユーザ権限を細かく設定できたりなどするのがいい感じです。  もっというとVPN越しにしかつながらないようにしたいとかの自由がききます。共有Webサービスつかうか自前構築のつかうかの差です。  gilab導入の手間は最近はchefで気軽に入るレシピもあり軽減されてきたようです。

githubの場合、二段階認証をなんとかする

 詳細な説明は省きますが、まずgithubに登録して会社のgithubの二段階認証をなんとかします  →会社で用意していただいたマニュアルのとおりに実施。   要はgmailの2段階認証みたいなことで携帯にSMS通知が届いて認証する仕組みのセットアップです。

 接続するホストでsshの鍵の作成と、作成した公開鍵の登録をgithub側のユーザプロファイルで行います。

pushするホストでgitを初期設定する

まずgitコマンド打つ人のユーザ情報を登録です。

git config --global user.email "komiyay@xxxxx"`
git config --global user.name "Yxxx Komiya"

設定ファイルにメモリ制限やスレッド数を指定しないとOutOfMemoryエラーが出ます。

$ vi ~/.gitconfig
[user]
        email = komiyay@xxxxx
        name = Yxxx Komiya
[core]
        packedGitWindowSize = 128m
        packedGitLimit = 128m
[pack]
        windowMemory = 128m
        threads = 2
        deltaCacheSize = 128m
        packSizeLimit = 128m

※m1.smallくらいでこの設定にしました。t1.microだとメモリエラー出ました。

メモリエラーメッセージ:

fatal: Out of memory, malloc failed9.59 MiB | 4.16 MiB/s
error: pack-objects died with strange error
gitリポジトリを登録してaddとcommitしてpush

作っていただいた(※)github側のリポジトリの説明にあるとおりコマンドを実行していきます。 ※リポジトリ作成権限はもらってないです(会社のプライベートリポジトリで有料な為) 登録したいchefのリポジトリに移ってから以下を実行します。

touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:Isaoxxxx/xxx-chefrepo.git
git push -u origin master

git remote addして確認すると以下のように表示されるようになります。

$ git remote -v
origin  git@github.com:Isaoxxxx/xxx-chefrepo.git (fetch)
origin  git@github.com:Isaoxxxx/xxx-chefrepo.git (push)
git pushに失敗

理由はうっかり100MB以上の大きなファイルを含んだ状態でcommitしてしまったためです。(githubの場合。gitlabは特に制限なし) 100MB以上だめなんじゃミドルウェアのアーカイブとか割とダメそうです。 remote_fileリソース使うかgit cloneしたあとにダウンロードするか必要なようです。

$ git push -u origin master
Warning: Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts.
Counting objects: 557, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (451/451), done.
Writing objects: 100% (557/557), 587.22 MiB | 11.26 MiB/s, done.
Total 557 (delta 126), reused 0 (delta 0)
remote: error: GH001: Large files detected.
remote: error: Trace: 5f467e50268ce9aec1f53188e8e52882
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File site-cookbooks/java/files/default/usr/local/src/jdk-7u45-linux-x64.rpm is 116.91 MB; this exceeds GitHub's file size limit of 100 MB
remote: error: File site-cookbooks/mysqld/files/default/usr/local/src/MySQL-5.6.15-1.linux_glibc2.5.x86_64.rpm-bundle.tar is 294.62 MB; this exceeds GitHub's file size limit of 100 MB
remote: error: File site-cookbooks/play/files/default/usr/local/src/play-2.2.1.zip is 104.82 MB; this exceeds GitHub's file size limit of 100 MB
To git@github.com:Isaoxxxx/xxx-chefrepo.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@github.com:Isaoxxxx/xxx-chefrepo.git'

エラーメッセージ内のURL↓英語。 Working with large files · GitHub Help なんだかgit rmしてgit commitしただけではだめでした。 以下URLにあるとおり特殊な操作が必要でした。 100MB超のファイルをコミットしてしまい githubに pushを拒否された時

$ git filter-branch --force --index-filter 
  'git rm --cached --ignore-unmatch site-cookbooks/play/files/default/usr/local/src/play-2.2.1.zip' 
  --prune-empty --tag-name-filter cat -- --all

$ git filter-branch --force --index-filter 
  'git rm --cached --ignore-unmatch site-cookbooks/java/files/default/usr/local/src/jdk-7u45-linux-x64.rpm' 
  --prune-empty --tag-name-filter cat -- --all

$ git filter-branch --force --index-filter 
  'git rm --cached --ignore-unmatch site-cookbooks/mysqld/files/default/usr/local/src/MySQL-5.6.15-1.linux_glibc2.5.x86_64.rpm-bundle.tar' 
  --prune-empty --tag-name-filter cat -- --all

$ git commit --amend -CHEAD

気を取り直してgit pushしたところ、成功。

$ git push -u origin master
Counting objects: 533, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (439/439), done.
Writing objects: 100% (533/533), 79.03 MiB | 5.44 MiB/s, done.
Total 533 (delta 119), reused 0 (delta 0)
To git@github.com:Isaoxxxx/xxx-chefrepo.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

githubを確認してみると登録成功していました。

上げてはいけないファイルを上げていた対応

確認してみるとうっかりdata_bag_keyも一緒にupしてしまっていたのでgithub上で削除しました。 ブラウザ上で編集したので今度はマージした後じゃないとpushできないエラーが。競合してる風。

$ git push -u origin master
To git@github.com:Isaoxxxx/xxx-chefrepo.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:Isaoxxxx/xxx-chefrepo.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

マージってどうやるんだっけか。ということで少し調べてみると、 とりあえずfetchしてpullしてpushするのがいいようでした。 pullというのは内部でfetch + mergeに相当する処理をするんだそうで。

この状態でgit pullしたところ、ローカルのファイルが案の定消えました。 そもそもこの鍵はコピーしたバックアップファイルにすぎないのと.gitignoreに登録済みなので、 もっかいコピーして戻しました

$ cp -p ../.chef/encrypted_data_bag_secret  ./data_bag_key
$ cat .gitignore
/cookbooks/
data_bag_key

$ git statusしてみても特に更新ファイルはない状態。 ということでgit pushしてブラウザから確認したところ、更新した.gitignoreは更新されており、 消して.gitignoreに追加したdata_bag_keyは見当たらなかったので意図したとおりになったようです。

上げちゃいけないファイルを上げてしまったときにブラウザから消すんじゃなくてコマンドでやるには、 公開してはいけないファイルを誤ってgitに追加してしまった場合を参考にさせていただきました。

git filter-branch --index-filter 'git update --index --remove "ファイル名"' HEAD
git commit -a
git push ...

という風にやるのがいいようです。

まとめ

ローカルリポジトリを更新したら

git add
git commit -m "history"
git push

リモートリポジトリで更新してたら

git fetch
git pull

ローカルリポジトリで共有したくないファイルは.gitignoreに追加 ローカルリポジトリでaddしたあとでcommit前にファイルごと消す時は、

git rm filename

ローカルリポジトリでaddしたあとでcommit前にインデックスだけ消す時は、

git reset HEAD -- <file>

逆引きも便利でした。 基本操作 | 逆引きGit | サルでもわかるGit入門 〜バージョン管理を使いこなそう〜 chef的には、あとはREADMEをちゃんと書いて使いまわしやすくする等が必要そうです。

現在は成り行きでgitlabを主に利用しています。特にクローズドが好ましいということでは無いです。

読んでいただいてありがとうございました。 つづきはこちらです。