読者です 読者をやめる 読者になる 読者になる

新春座談会 このコンピュータ書がすごい 2017年版 の個人的なメモ

今回で9回目らしいです。

本については気になったものをピックアップ。本の説明についての引用は高橋さんや出版社さんが説明された内容(を大雑把にメモしたもの)。

今回も高橋さんは大量の本を紹介されていました。どうやってあれほど紹介できるようになるのやら、毎年驚きとともに感謝しています。

高橋さんと少しお話させていただいたのですが、守備範囲が広いですね。

ちなみに本のタイトルを書いたものは、気になった本=自分は読んでいない本、ということで今後読みたいメモです。


2016年のトピック::機械学習人工知能

2016年に本がたくさん出て、たくさん売れている。

エンジニア向けというよりも一般書的なところでもたくさん本がでた。

詳しい本はデータサイエンスや数学的なところの知識が必要な内容のものも多い。

コードを扱うようなものについては、Pythonで書かれているものが多い。

応用みたいな話でチャットボットの本も出ている。

機械学習プロフェッショナル』

ウェブデータの機械学習 (機械学習プロフェッショナルシリーズ)

ウェブデータの機械学習 (機械学習プロフェッショナルシリーズ)

http://www.kspub.co.jp/book/series/S043.html

基礎的な内容、応用的な内容、がシリーズの中に混在している。

ウェブ絡みの人なら、ウェブデータの機械学習を読んで見る、みたいなことをおすすめ。

ピックアップして読んでみたい。

機械学習入門』

機械学習入門 ボルツマン機械学習から深層学習まで

機械学習入門 ボルツマン機械学習から深層学習まで

コードやプログラムがでてこないで、(機械学習の)概念を理解していく本。

わかりやすい、ということで概念を学べるようなので、全く詳しくない自分的には機械学習の事始めに読みたい。

『ゼロから作る Deep Learning』

9月に発売して1月に重版。5万部。

Pythonコードを使ってコードを書いていくということなので、上の『機械学習入門』を読んだ次に、手を動かしてみたら、いい感じに機械学習関連のプログラミングを覚えていけるかも。


2016年のトピック::Python

プログラミング言語Pythonの本が多く出た。機械学習がらみのところも多そう。

2006年から発行されている『みんなのPython』が機械学習のコンテンツも増えてリニューアルされている。

Pythonからはじめる数学入門』

Pythonからはじめる数学入門

Pythonからはじめる数学入門

機械学習関連でPythonを使う、と決めてしまえば、必要になる数学もPythonを使って一緒に勉強してしまうという方法がいいのかもしれない。


2016年のトピック::クラウドアジャイル・DevOps・CI/CD・マイクロサービス

個人や組織内で足りていなかったスキルなんだけど、クラウドがでてSaaSなどで提供されるものが増えて、導入がすすめやすくなった。

DevOpsの関連でChatOpsなんかも。Slackとかを使ったもの。

クラウド関連では、OpenStackやDockerを扱った本もいくらか出ている。

パブリッククラウドの本としてはAWSとAzureの本が多めに出てるらしい。GCPはどうなんだろう?

『Cloud First Architecture 設計ガイド』

Cloud First Architecture 設計ガイド

Cloud First Architecture 設計ガイド

この本をベースに、トピックにしてみました。

特に自分が使っているのはパブリッククラウドで、でも使えているのは一部で、みたいな状態なので、全体的な話を理解するために読んでみるのは面白いかもしれない。


2016年のトピック::フィンテック、ブロックチェーン、仮想通貨

いろんなものが「フィンテック」という言葉でまとめられている。一般向けの読み物も多い。

(このあたりは興味がなさすぎで、すみません。話はちゃんと聞いてました。)


2016年でのランキング(とか)から

2016年の年間ランキングの中で2016年発売の本が入ったのは、『ゼロから作る Deep Learning』のみ。

ランキングについては、ムックなどは覗かれているという話。ランキングのルールは、あれこれ省かれてる、とのこと。

高橋さんはEmacsらしい。自分はVimです。

Go言語の本も5冊くらい出ている。

Selenium実践入門』

Selenium実践入門 ―― 自動化による継続的なブラウザテスト (WEB+DB PRESS plus)

Selenium実践入門 ―― 自動化による継続的なブラウザテスト (WEB+DB PRESS plus)

フロントエンドテストだけでなく、スクレイピングにも使われている。

自分はPhantomJSを頑張ってますが、扱いやすいものに変えていきたい。

『たのしい Ruby 第5版』

たのしいRuby 第5版

たのしいRuby 第5版

ドラスティックには変えていない。Ruby2で書き直した。

タイミングがだいぶずれてしまいますが、新版おめでとうございます!

新人研修向けの本がどんどん更新されていく。。。

『グラス片手にデータベース設計 販売管理システム編 第2版 』

グラス片手にデータベース設計 販売管理システム編 第2版 (DB Magazine Selection)

グラス片手にデータベース設計 販売管理システム編 第2版 (DB Magazine Selection)

販売管理システムについてのデータベース設計に触れている情報がなかなかない。

具体的なケースとして、データベース設計を学べるのは良さそう。販売管理システムというかなりカタイ設計が必要なものを扱っているのもうれしい。

『ブラウザハック』

ブラウザハック

ブラウザハック

ブラウザの攻撃手法をまとめた本。

これは前から気になっていた本。分厚いし優先順位をガッツリ落としていたけど、そろそろ始めなければ。

同一ドメインポリシーについて攻撃の話とかはちゃんと学んでおいたほうがよさそう。

『現場のインフラ屋が教える インフラエンジニアになるための教科書』

現場のインフラ屋が教える インフラエンジニアになるための教科書

現場のインフラ屋が教える インフラエンジニアになるための教科書

イマドキのインフラエンジニアになりたい人向け。

目次を見ると、クラウドを混ぜつつインフラのことを説明されているみたいで、個人的には勉強を進めたい。

まつもとゆきひろ 言語のしくみ』

言語をつくりたい人むけ。言語の設計にはどんな問題があってどう作っていけばいいのか。

自分は言語を作りたい人ではないのですが、興味強めです。


その他個人的に気になる本

『コンピュータシステムの理論と実装』

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

2015年の本ですが。大学で情報工学をやってなかったりして、どうしてもプログラムの裏側が理解できていないことが多いので、勉強に手を付けたい。

cronでメール以外の方法で結果を通知する

cronって便利なんだけど、結果を確認するのがめんどくさい。

メールを全部見るのも今っぽくない。

でもRundeckとか他のジョブスケジューラを使い始めると、実行時に依存するものが増えるのでそれはそれで微妙。

じゃあ、メールで送っている内容と同じようなものを別のプログラムが取得できるか、ということ。

ソースコード確認

最初に考えたのがコマンドからパイプで繋いで最後に別のプログラムが情報をとる、というもの。

標準出力、標準エラー出力は取得可能。 実行したコマンドは、、、?

実行したコマンドはパイプで繋いでる数が少なくて時間がかかればプロセスリストから見つけられるけど、なんか違う。

じゃあCronがメールの件名につけている実行したコマンドはどうやって?ということでソース(とりあえずcronie)をおってみた。

cronie.git - Unnamed repository; edit this file to name it for gitweb.

コマンドを実行してその結果のメールを組み立てる部分。

cronie.git - Unnamed repository; edit this file to name it for gitweb.

entry->cmdという形で取得しているので、内部的にcronのファイルを構造化して、それを実行中に保持しているに過ぎないということ。

ちなみにentrystruct

cronie.git - Unnamed repository; edit this file to name it for gitweb.

外部のコマンドがうまーくやるにはちょっと厳し目か。

crond

次に考えたのがcrondコマンドの実行時オプション。何か良さげなものがないか?

% man crond

途中いっぱい省略するけど、-mオプションで実行可能なコマンドを渡すと、本来メール送信用に組み立てたテキストを、標準入力に渡すよ、という感じ。

OPTIONS -m This option allows you to specify a shell command to use for sending Cron mail output instead of using sendmail(8) This command must accept a fully formatted mail message (with headers) on standard input and send it as a mail message to the recipients specified in the mail headers. Specifying the string off (i.e., crond -m off) will disable the sending of mail.

実験

検証環境

% cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

% ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

結果を受け取るプログラム

rubyで受け取ってみる。

/tmp/mail.rb

#!/home/admin/.rbenv/shims/ruby
text = STDIN.read
File.open "/tmp/stdin.mail.#{Time.now.to_i}", "w" do |writer|
  writer.puts text
end

とりあえずでこやつには実行権限も付与。

% chmod 775 /tmp/mail.rb

crondの起動時オプション

/etc/sysconfig/crondで起動時のオプションを指定できる。

# Settings for the CRON daemon.
# CRONDARGS= :  any extra command-line startup arguments for crond
CRONDARGS="-m /tmp/mail.rb"

cronのジョブ

とりあえず適当に、標準出力がちょっと長くなりそうなやつを。

/etc/cron.d/my.admin

MAILTO=sugilog@test.example
 * * * * * root /usr/bin/sar -P ALL

実行

まずはcrondを再起動

% systemctl restart crond
% ps aux | grep crond | grep -v grep

root       5948  0.0  0.0 126332  1712 ?        Ss   10:52   0:00 /usr/sbin/crond -n -m /tmp/mail.rb

cronの実行結果を確認してみる。

From: "(Cron Daemon)" <root>
To: sugilog@test.example
Subject: Cron <root@sugilog> /usr/bin/sar -P ALL
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
Precedence: bulk
X-Cron-Env: <XDG_SESSION_ID=70>
X-Cron-Env: <XDG_RUNTIME_DIR=/run/user/0>
X-Cron-Env: <LANG=ja_JP.UTF-8>
X-Cron-Env: <MAILTO=sugilog@test.example>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>

Linux 3.10.0-327.22.2.el7.x86_64 (sugilog)      2016年12月20日  _x86_64_        (4 CPU)

07時37分20秒       LINUX RESTART

07時40分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
(以下省略)

その他

ちなみに、-mで渡したスクリプトがイケてなくと何かしら失敗していると、ログにそれっぽい出力がある。

Dec 20 10:47:01 sugilog CROND[5604]: (root) CMD (time /usr/bin/sar -P ALL)
Dec 20 10:47:01 sugilog CROND[5603]: (root) MAIL (mailed 8204 bytes of output but got status 0x0001#012)

あとは

cronから標準入力で渡されるテキストはメール形式なので、メールとしてパースすれば、構造化されたデータとして扱える。

例えばruby

require "rubygems"
require "mail"

text = STDIN.read

message = Mail.new(text)
message.header_fields.each do |field|
  puts "#{field.name} = #{field.value}"
end
puts message.body
From = "(Cron Daemon)" <root>
To = sugilog@test.example
Subject = Cron <root@sugilog> /usr/bin/sar -P ALL
Content-Type = text/plain; charset=UTF-8
Auto-Submitted = auto-generated
Precedence = bulk
X-Cron-Env = <XDG_SESSION_ID=70>
X-Cron-Env = <XDG_RUNTIME_DIR=/run/user/0>
X-Cron-Env = <LANG=ja_JP.UTF-8>
X-Cron-Env = <MAILTO=sugilog@test.example>
X-Cron-Env = <SHELL=/bin/sh>
X-Cron-Env = <HOME=/root>
X-Cron-Env = <PATH=/usr/bin:/bin>
X-Cron-Env = <LOGNAME=root>
X-Cron-Env = <USER=root>
Linux 3.10.0-327.22.2.el7.x86_64 (sugilog)      2016年12月20日  _x86_64_        (4 CPU)

07時37分20秒       LINUX RESTART

07時40分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
(以下省略)

参考

qiita.com

RubyのMixinを簡単にだけ整理したメモ

たまにはRubyを。

元ネタというかメインで参照したのはこちら

www.sitepoint.com

prependって結局どうなんだっけ?prependをクラスメソッドにするにはどうするんだっけ?というところを整理したかったので。

実行環境は、ruby2.3.1p112

ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

サンプルコード

Abstract moduleを各クラスに突っ込む。

module Abstract
  def self.included(klass)
    puts ""
    puts "Included hook: #{klass}"
    puts "ancestors: #{klass.ancestors}"
    puts "singleton: #{klass.singleton_class.ancestors}"
  end

  def self.prepended(klass)
    puts ""
    puts "Prepended hook: #{klass}"
    puts "ancestors:  #{klass.ancestors}"
    puts "singleton: #{klass.singleton_class.ancestors}"
  end

  def self.extended(klass)
    puts ""
    puts "Extended hook: #{klass}"
    puts "ancestors: #{klass.ancestors}"
    puts "singleton: #{klass.singleton_class.ancestors}"
  end

  def say
    puts "Hello, World!"
  end
end

class Include
  include Abstract

  def say
    puts "Hello!"
  end
end

Include.new.say

class Prepend
  prepend Abstract

  def say
    puts "Hello!"
  end
end

Prepend.new.say

class Extend
  extend Abstract

  def self.say
    puts "Hello!"
  end
end

Extend.say

class SelfPrepend
  class << self
    prepend Abstract

    def say
      puts "Hello!"
    end
  end
end

SelfPrepend.say

class ClassPrepend
  singleton_class.prepend Abstract

  def self.say
    puts "Hello!"
  end
end

ClassPrepend.say

アウトプット

Included hook: Include
ancestors: [Include, Abstract, Object, Kernel, BasicObject]
singleton: [#<Class:Include>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Hello!

Prepended hook: Prepend
ancestors:  [Abstract, Prepend, Object, Kernel, BasicObject]
singleton: [#<Class:Prepend>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Hello, World!

Extended hook: Extend
ancestors: [Extend, Object, Kernel, BasicObject]
singleton: [#<Class:Extend>, Abstract, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Hello!

Prepended hook: #<Class:SelfPrepend>
ancestors:  [Abstract, #<Class:SelfPrepend>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
singleton: [#<Class:#<Class:SelfPrepend>>, #<Class:#<Class:Object>>, #<Class:#<Class:BasicObject>>, #<Class:Class>, #<Class:Module>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Hello, World!

Prepended hook: #<Class:ClassPrepend>
ancestors:  [Abstract, #<Class:ClassPrepend>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
singleton: [#<Class:#<Class:ClassPrepend>>, #<Class:#<Class:Object>>, #<Class:#<Class:BasicObject>>, #<Class:Class>, #<Class:Module>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Hello, World!

理解したこと

prependはancestorsで考えたときに、子孫側に挿入される。

include/extendはancestorsで考えたときに、祖先側に挿入される。

extendは、singleton_class(特異クラス)に対して挿入される。

クラスメソッド(として扱うもの)をprependする書き方は2パターンある。(詳しく追っていないので、どちらかがまずい方法だ、みたいなツッコミ歓迎。)

Goで同時実行数を制限しながらループを並列処理する。

Web+DB Press Vol95 のGoの記事を読んで理解するために自分でも書いてみた。

WEB+DB PRESS Vol.95

WEB+DB PRESS Vol.95

自分の環境は go1.7.3 darwin/amd64

同時実行数制限付きでループを並列処理する。

秒単位でスリープ処理を入れてしまっているので、実行時間は長いです。そこはお勉強用ということで。

出力結果

time:2016-12-02 14:40:49.5804542 +0900 JST      index:-1        item:-1
sleepなし。順番不定。
time:2016-12-02 14:40:49.580639488 +0900 JST    index:2 item:3
time:2016-12-02 14:40:49.580686796 +0900 JST    index:3 item:4
time:2016-12-02 14:40:49.580652343 +0900 JST    index:0 item:1
time:2016-12-02 14:40:49.580703936 +0900 JST    index:4 item:5
time:2016-12-02 14:40:49.580712672 +0900 JST    index:5 item:6
time:2016-12-02 14:40:49.580725039 +0900 JST    index:6 item:7
time:2016-12-02 14:40:49.580731445 +0900 JST    index:1 item:2
sleepあり。順番に出力。
time:2016-12-02 14:40:50.582086998 +0900 JST    index:0 item:1
time:2016-12-02 14:40:51.581872261 +0900 JST    index:1 item:2
time:2016-12-02 14:40:52.581816362 +0900 JST    index:2 item:3
time:2016-12-02 14:40:54.583265777 +0900 JST    index:3 item:4
time:2016-12-02 14:40:56.583142187 +0900 JST    index:4 item:5
time:2016-12-02 14:40:58.582018719 +0900 JST    index:5 item:6
time:2016-12-02 14:41:01.584457553 +0900 JST    index:6 item:7
sleepあり。Sleepの短い順番に出力。
time:2016-12-02 14:41:03.585628436 +0900 JST    index:1 item:2
time:2016-12-02 14:41:04.58563381 +0900 JST     index:0 item:3
time:2016-12-02 14:41:05.585852568 +0900 JST    index:3 item:2
time:2016-12-02 14:41:06.585637432 +0900 JST    index:2 item:5
time:2016-12-02 14:41:06.585995853 +0900 JST    index:5 item:1
time:2016-12-02 14:41:12.586825274 +0900 JST    index:4 item:8

セマフォ取得用のオブジェクトで、同時実行数の制限。deferで開放しないと詰まる。

WaitGroupでプログラムの待ちを設定。ないと、スリープ処理をしてる間にプログラムが終了してしまう。deferでセマフォを開放するタイミングで一緒にWaitGroupも減らす。

Certificate Managerを試す、、、ためのメール受信の設定

ケース

AWS Certificate Managerを使用して、SSL/TLS証明書を取得して、HTTPS接続を確立したい。

ドメインは、(お名前.comとかで)適当に取得しておいたものを使う。

問題

AWS Certificate Managerは、証明書の発行のときに、検証Eメールを送信する。自分(もしくは関係者)が、証明書の発行を承認する必要があるから。そりゃ当然なわけ。

送信先は、ヘルプにかかれている。2種類あって、WHOISに書かれたメールアドレスと、登録しようとしているドメインに適当なアカウント名をくっつけたメールアドレス。

Email is sent to the following three registered contact addresses in WHOIS:

  • Domain registrant
  • Technical contact
  • Administrative contact

Email is also sent to the following five common system administration addresses where your_domain is the domain name that you entered when you initially requested the certificate.

  • administrator@your_domain
  • hostmaster@your_domain
  • postmaster@your_domain
  • webmaster@your_domain
  • admin@your_domain

で、エンタープライズな人たちなら特に問題じゃないわけだけど。。。

その検証Eメールを受信できる状態じゃないと、前へ進めない。

お名前.comなんかでドメインを取得すると、whoisへの情報登録を代行してくれる。

代行してくれた登録情報は、お名前.comの会社の情報になるので、whoisの情報には、自分個人の情報は含まれていない、ということ。

個人利用にはありがたい代行サービスなんだけど、今回だけは、それが微妙。

目的

ということで、

AWS Certificate Managerが送信する送信先をつくります。

やり方

同じくAWSのサービスの、SESを使って、メールを受信する。

例として、example.jpというドメインを持っていて、そのサブドメインapp.example.jpSSL/TLS証明書を発行する。ために、admin@app.example.jpを受信できるようにする。

SESはこの記事を書いている時点(2016/11/08)では、まだ日本に提供されていないっぽいので、リージョンは適当に選んで使う。

事前準備:Route 53 の設定

もしDNSを設定していない状態であれば、Route 53にexample.jpを登録する。

とりあえずHosted Zoneにexample.jpを登録するだけでOK。

(ということで、Route 53を使う前提で書きます。)

ドメインの登録

  1. 左ペインのDomainsを選ぶ。
  2. Verify a New Domainボタンを押す。
  3. Domainを入力する。
    • 今回のケースで登録するドメインは、app.example.jp
  4. DNSの設定について書かれている画面に切り替わる。
  5. Use Route 53で先に進む。
  6. Domain Verification Record(TXTレコード) と Email Receiving Reocrd(MXレコード)どちらも登録したいので、両方チェックを入れて、Create Record Sets
  7. 少し待つと、ドメインのステータスがverifiedに変わる。

受信設定

  1. 左ペインのRule Setsを選ぶ。(Email Receivingの下)
  2. View Active Rule Setボタンを押す。
  3. Create Ruleボタンを押す。
  4. Recepientは空のままNext Step。(今回の場合は。本当は絞ったほうが良いはず。)
  5. Add actionで、S3を選ぶ。
    • S3のバケットとかは適当に。新しく作るなり、
    • prefixは、必要に応じて。app.example.jp/みたいにアカウント名を入れておくと便利そう。
    • 今回の場合は暗号化は不要。(本当は暗号化したほうが良いはず。)
  6. Next Stepで先に進む。
  7. Rule nameは適当に。
  8. 他、デフォルトのままで、Next Step
  9. Create Rule

テスト

  1. 左ペインのDomainsを選ぶ。(戻る)
  2. 登録したドメイン(例:app.example.jp)を選ぶ。
  3. Send a Test Emailを押す。
  4. メールの内容を適当に入力して、送信。
    • Toアドレスをadmin@app.example.jpみたいにしておくと、Certificate Managerが送信先に指定するメールアドレスみたくなる。
  5. S3をチェック。
    • Ruleで設定したバケット、prefixの場所にメールがあるか?
    • メールの内容が先ほど適当に入力したメールの内容に一致するか?

後は

Certificate Managerであれこれするだけ。

ELBの資料を読んだメモ

自分が業務で使いそうな範囲でメモに起こす。

aws.typepad.com

ELB = L4のロードバランサー(Classic Load Balancer = CLB) + L7ベースのロードバランサー(Application Load Balancer = ALB)

ELB

ELBは複数AZをまたいで負荷分散が可能。

ヘルスチェックは細かく指定可能。以下の表は引用。 ウェブアプリケーションで未熟な状態なら、PingパスでDBの接続とかあれこれチェックできる状態にしておくのも一つの手か?

項目 メモ
Ping プロトコル HTTP 200が返るか?
Ping ポート 80
Ping パス /index.html HTTP/HTTPS利用の場合
タイムアウト時間 20秒
ヘルスチェック間隔 30秒
異常判定までの回数 4回
正常判定までの回数 2回

正常との判定が遅いと追加したインスタンスが使える前に時間がかかる。 逆に異常との判定が厳しすぎても過負荷時に処理できるインスタンスを減らしてしまうことも。

Route 53以外でDNSを使うときは、CNAMEで設定してELBに向ける。

サーバー証明書はELBにアップロード。Let's Encryptを使うときはどうする?的な話は別途調べる。→AWS Certificate Managerを使用する。証明書に対しての料金がかからない理解。アップロード作業も不要。

サーバーへの接続のソースIPはELBのIPアドレスになるので、X-Forwarded-Forヘッダーを見る。

ELBにもセキュリティグループを設定できるので、今までEC2に設定していたセキュリティグループはELBだけを受け付けるようにして、ELB側で制限をかける。

ALB

コンテクストベースルーティングで、ルールにURLのパスが使える。振り分け先にはターゲットグループ(バックエンドサーバーをまとめたグループ)を指定。

WebsocketやHTTP/2にも対応。

料金 ALBの使用時間と、Load Balancer Capacity Units (LCU) の使用量で課金。

LCU 以下の3つのディメンションを測定し、使用量が最も高いディメンションのみ請求。

とりあえず変なことしなければ、CLBよりちょろっと安く済ませられるらしい。

ディメンションの項目から考えると、HTTP/2にちゃんと対応したほうが安くなるのか?

Git(hub)でフォークしたリポジトリに、オリジナルリポジトリの変更を取り込む

いつも忘れて調べなおすことになるので、メモ。

ケース

例えば、こんなリポジトリ

github.com

オリジナルのプラグインでほんのすこしだけカスタマイズしたいから、ちょっとだけ修正して使ってる、みたいな。

で、時間が経って、変更されているものもあるから取り込みたい。

というときの作業。

参照

結論、Githubのヘルプを見ればいいわけですね。はい、いつも見ます。いつもたどり着くのに時間がかかりますが。

https://help.github.com/articles/fork-a-repo/help.github.com

https://help.github.com/articles/syncing-a-fork/help.github.com

この記事のこの後の内容は、ヘルプの内容をただただ自分のためにメモしたものです。

作業

ざっくり書くとこんな感じでしょうか。

git clone ${forked_repo} ${forked_repo_dir}
cd ${forked_repo_dir}
git remote add upstream ${original_repo}
git fetch upstream
git checkout master # forked master
git merge upstream/master

自分の(忘れた後の)理解のために、細かく書いていくと、、、

フォークしてカスタマイズしたリポジトリGitHub - sugilog/molokai: Molokai color scheme for Vimに、オリジナルのリポジトリGitHub - tomasr/molokai: Molokai color scheme for Vimの修正内容を取り込む。

自分のリポジトリclone

git clone git@github.com:sugilog/molokai.git ~/workspace/molokai
cd ~/workspace/molokai

オリジナルのリポジトリupstreamという名前でリモートブランチとして登録。名前はかぶらなきゃOK。

git remote add upstream https://github.com/tomasr/molokai.git
git fetch upstream

自分のリポジトリのブランチをcheckout。とりあえずmaster

git checkout master

最後に、オリジナルの内容をマージ。

git merge upstream/master

あとはコンフリクトを直すなりなんなり。

結論、マージ作業なわけです。

GithubのウェブUIからのプルリク作業に慣れてきった生活で、簡単なマージ作業でさえ忘れてしまう。。。

最後に

molokai、お世話になってます。

github.com