いのでんの進捗

ゆっくりのんびり強くなっていきたいブログ。

Kubernetesの勉強

はじめに

ネットワーク研にいるのに、k8s も知らないのはなんかダメだなぁと思ったので勉強してみる。

参考

www.shoeisha.co.jp


kubernetes とは?

Kubernetes とは、オープンソースコンテナーオーケストレーションツールである。

そもそもコンテナとは

コンテナとは、ホスト OS 上に論理的な区画を作り、あるアプリケーションを動作させるのに必要なモジュール(ライブラリとかアプリケーションとか)を一つにまとめたもの。

なぜ他の仮想が技術に比べて軽量?

コンテナは Linux の通常のプロセスとほぼ同じ処理らしいが、それぞれのプロセスを 1 つのグループとして管理する(Linux で言えば namespace や cgroups などのカーネル機能とか) ことで、名前空間やリソースを他のプロセスやコンテナから隔離することができる。

  • ホスト型
    • Oracle VM VirtualBox など
    • ゲスト OS over 仮想化ソフトウェア over ホスト OS over ハードウェア
  • スーパバイザ型
    • Windows Hyper-V など
    • ゲスト OS over ハイパーバイザー over ハードウェア

コンテナオーケストレーションツールの必要性

コンテナオーケストレーションツールとは、すなわちコンテナを統合管理できるツールのこと。

シングルホストでは手軽なコンテナも、マルチホストで運用する際は、以下のような要求を満たさなければならない。

  • コンテナの操作(起動、停止、削除)
  • ホスト間のネットワーク接続
  • ストレージ管理
  • コンテナ-ホスト間のスケジューリング機能

Kubernetes の特徴

  • 複数サーバでのコンテナ管理
  • コンテナのデプロイ
  • コンテナ間のネットワーク管理
  • コンテナの負荷分散
  • コンテナの監視
  • コンテナのアップデート
  • 障害発生時の自動復旧

【Scala】勉強ログ(随時更新)

まえがき

ただの個人用勉強ログです。
COVID-19 の おかげ せいで N 予備校の講座が無料で見れるのでやっていく。

Scala とは?

環境

  • WSL1
  • Open JDK 11.0.3(?) for Linux (以前入れたっぽい)
  • sbt 1.3.8 (Scala Build Tool?)
  • VSCode
  • Scala (Metals) : VSCode の拡張。これだけで補完と format が効くっぽい。2020?年から ENSIME から Metals へ移行したよう。

REPL 立ち上がらない

sbt console
>>> [warn] No sbt.version set in project/build.properties, base directory: /$CURRENT_DIRCTORY/Go-Tutorial
>>> [error] java.nio.file.AccessDeniedException: /$HOME/.cache/coursier
>>> [error] Use 'last' for the full log.
>>> Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? r

なぜか ~/.cache の所有者が root だったので自分に変更。

sudo chown [username]:[groupname] ~/.cache

数値表現

値型 範囲 記述例
Byte 1 Byte 符号付き整数 1.toByte
Short 2 Byte 符号付き整数 1.toShort
Int 4 Byte 符号付き整数(-214748368 ~ 2147483647) 1
Long 8 Byte 符号付き整数 1L
Float 4 Byte 浮動小数点数 1.0F
Double 8 Byte 浮動小数点数(-1.7976931348623157E308 ~ 1.7976931348623157E308) 1.0

Map()(連想配列) の更新

今までのイメージ

// JavaScript
aaa = { a: 1, b: 2 };
aaa["a"] = 3;
console.log(aaa) >>> { a: 3, b: 2 };

Scala

// 更新というか新規作成
val aaa = Map(2->1, 3->2)
val aaa2 = aaa + (3 -> (aaa.getOrElse(3, 0) + 1))  // 二重かっこにするのを忘れないように。
println(aaa2)
>>> Map(2 -> 1, 3 -> 3)

文字列検索

索引型検索

  • 文章のなかから予め単語の文字列を抜き出して、その単語ごとに索引を作っておく
  • 単語ごとに、対象の文章の中の頻度や場所に応じてスコアが計算される
  • 例)検索エンジンなど

非索引型検索

  • 与えられた文字の情報のみで検索
  • 検索のたびに、対象の文章データを全て走査

文字列String

  • Scala の String 型は、Java の String 型を踏襲。APIJava 11 String を参考。
  • 基本的にダブルクォーテーションを使う。シングルクォーテーションは Char 型。

ビット演算

計算 演算子 記述例 結果 補足
ビット単位 AND & -1 & 2 2
ビット単位 OR | -1 | 2 -1
ビット単位 XOR ^ -1 ^ 2 3
ビット単位補数 ~ ~0 -1 全ビットを反転させる
右ビットシフト(MSB 埋め) >> -1 >> 31 -1
右ビットシフト(0 埋め) >>> -1 >> 31 1
左ビットシフト(0 埋め) << 1 << 1 2 2 のべき乗

ビット演算を使ってアルゴリズムを考えられるようになりたい

用語

用語 説明
構文(Syntax) class, val, if プログラムが構造を持つための規則
式(Expression) 1, 1+1, "hoge" 評価することで値となるもの
評価 Scala の式をコンパイルすること
文(Statement) val i = 1 評価しても値にならないもの。

Unit

ifwhile といった式は()を返す。これはUnit と言われる型のオブジェクトの値である。

C 言語や Java でいうところの void にあたる。

クラスとオブジェクト

クラス

簡単に言うと、「複数のオブジェクトを作るためのひな形」。

クラスから作られるオブジェクトを「インスタンス」、状態を「フィールド」、振る舞いを「メソッド」と言う。またフィールドとメソッドを合わせて「メンバー」という。

ケースクラス

ふつうのクラスとほぼ一緒。
ケースクラスは不変なデータを作るのに適しており、パターンマッチングで有用である。

例えば変数宣言におけるパターンマッチは、タプルによる分割代入のような値の取り出しのことを指す。

case class CPoint(x: Int, y: Int)

val cp1 = CPoint(5,6)
val CPoint(a, b) = cp1

>>> a: Int = 5
>>> b: Int = 6

一瞬、val CPoint() って何やと思うけど、ここで大事なのはa, bの方。

その他、sealed classを用いることで enum を実装できる。逆に Java にはあるのになんで Scala はこれなんだろうか…

なお上記で「ほぼ一緒」と言ったが、通常のクラスと「同値性」が異なる。

簡単に言えば、ケースクラスではインスタンスが異なる場合であっても持っているフィールドが同じであれば同値と見なされる。値っぽい挙動。

ちなみに hashCodeequalsというメソッドをオーバーライドすれば通常のクラスにおいてもこの同値性を変更することが出来る。

オブジェクト

数あるオブジェクトの中でも、object キーワードを使って作成したオブジェクトは、他と異なりたったひとつのインスタンス(これを「シングルトンオブジェクト」という)しか持たない。Scala では「オブジェクト」という単語が、一般的なオブジェクト全般を指す場合と、シングルトンオブジェクトを指す場合とがあるので注意。

ユースケースとしては

  • グローバルな状態やユーティリティメソッドを表現するため
  • オブジェクトを作り出すためのメソッドを提供するため
  • アプリケーションなどのシングルトンオブジェクトをつくるため

があげられる。

コンパニオンオブジェクト

コンパニオンオブジェクトとは、クラス名と同じ名前を持つオブジェクトのこと。 applyメソッドを定義することで、new演算子を利用せずにインスタンスを作ること(これを「ファクトリメソッド」という)ができる。

なんでコンパニオンオブジェクトがあるの?(めっちゃ重要)

なんでclassだけじゃなくてobjectでコンパニオンオブジェクトを書かなきゃいけないのか全く分からなかったが、以下の記事を読んで納得できた。

https://qiita.com/geshi/items/0a789724b2419bd56204

意識しなければいけないのは、Scala は静的型付け言語であること。
先のブログの文章を引用すると、

しかし、静的型付き言語ではクラスに型を定義する必要があるので(Ruby と違うところ)、 型を定義されたクラスと、クラスを生成するものが必要となります。

ということになる。なので Scala で書くクラスには大概 object が必要となる(多分)。そしてその機能としては initialize メソッドとほぼ同じと考えていてよさそう。

ちなみにクラスに対して定義するものはコンパニオンオブジェクト、インスタンスに対して定義するものはクラスに書く。

【WSL】Windowsファイルの権限変更(+VSCode Remote Developmentの実行)

TL;DR

  1. WSLからマウントしたWindowsファイルシステム群のデフォルトパーミッションを変更した備忘録
  2. 脳死でファイルのパーミッション644 にすると、VSCode Remote Development が実行できなくて死ぬ
  3. 誰か適切な権限教えて乁(˙꒳˙乁)クレヨ......

WSLのパーミッション変更

デフォルトパーミッション

WSLからマウントしたWindowsファイルシステム群 (以下WSL-WinFS)は、デフォルトではパーミッションが777(= -rwxrwxrwx)とされています。つまり「『所有者・所有グループ・その他』が『読み込み・書き込み・実行』可能」ということ。さすがに気持ち悪いので、変更しましょう。

やり方

Linuxコマンド umask により変更することも可能ですが、WSLを立ち上げるたびに設定が初期化されてしまう(らしい)ので、/etc/wsl.conf に設定を書き込む*1 ことでこれを保持しましょう。初期状態ではおそらく存在しないので、新規作成します。

# /etc/wsl.conf の中身 <- comment
[automount]
enabled = true
root = /mnt/
options = "metadata,fmask=133,dmask=022"

権限に関するオプションを以下に抜粋。

  • fmask
    • すべてのファイルに対して除外するアクセス許可の 8 進数のマスク
  • dmask
    • すべてのディレクトリに対して除外するアクセス許可の 8 進数のマスク
  • umask
    • すべてのファイルとディレクトリに対して除外するアクセス許可の 8 進数のマスク

上記confファイルにより、dmask=022は777 - 022 = 755、すなわち drwxr-xr-xfmask=133は777 - 133 = 644 すなわち -rw-r--r-- となります。

補足1: 権限記号読み方

権限記号は、

  • 先頭1文字目がディレクトリorファイルの識別(dor-)
  • 以降3文字区切りで「所有者」「所有グループ」「その他」ごとの権限

を表現しています。

また権限は以下の表にもとづいて、数値で表されます。

記号 権限 数字
r 読み込み 4
w 書き込み 2
x 実行 1
- 権限なし 0

これより、-rwxrwxrwx777(= 4+2+1 / 4+2+1 / 4+2+1)、-rw-r--r--644(= 4+2+0 / 4+0+0 / 4+0+0)というように8進数表記に変換されます。

補足2: /etc/fstab

マウントに関する設定としては/etc/fstabを作成する方法が一般的(?)と思われますが、上記URLでも述べられているように

注: これらのオプションは、自動的にマウントされたドライブすべてのマウント オプションとして適用されます。 特定のドライブのみのオプションを変更するには、代わりに /etc/fstab を使用します。

という使い分けがなされるようです。自分の場合はCドライブしかないのでwsl.conf を用いました。

ちなみに、bashzshの場合 .profileumask 022 と記述する方法もありますが、Rails等で自動生成されるファイルはそれに従ってくれないらしいです(要検証)。

VSCode Remote Developmentの起動

VSCode Remote Development(以下VS-RD) により、WSLを利用した開発がかなり快適になりました。WSL2が実装されればもう言うことなしです(それもうUbuntuで良くない?)。

さて、VS-RDを起動してみましょう。前述のパーミッション変更により、当然Permission Denied と言われ、接続に失敗します。しかたないのでWarningのポップアップの隙間から見える $HOME(多分)/.vscode/extensions/ms-vscode-remote.remote-wsl-0.42.3/scripts/wslCode.sh をchmodで644->755に変更します。

しかしまだ起動せず……。
エラーログも見えないのでどのファイルを実行しているかもよく分かりません。うーむmm…。

結局

fmaskとdmaskで各々権限を設定せず、umask=022で一括755にして現状対処することに。このあたりの "Linux感" がまだ身についてないのでこのままで良いか怪しいところ…。

変にいじってパーミッション破壊を起こしたくもないので放置。書きながらユーザ・権限周りの知識が怪しいことに気づいたので再度OSの授業を復習しようと決めました。以上。

【latex】overleaf(uplatex) でディレクトリ構造の図を書く

まえがき

latexでツリー図を書こうと思ったが、Overleafでは tree.sty が使えない1ので、代替packageを探した。 意外と記事がヒットしなかったので簡単にまとめる。

描画したい図

一般的な木構造に加え、ディレクトリ構造も描画できると嬉しい。

結論: forest package

個人的にはforest が最適だったのでこれを紹介する。ちなみに公式docでもお気持ち紹介されている2

www.ctan.org

Tikzをベースにしているので、オプション等は共通した文法である。例) grow'=0

描画可能な図(一例)

f:id:puyobyee18:20191224132545p:plainf:id:puyobyee18:20191224132550p:plain
tree & dirctories

書き方

上述の図のソースコードは以下の通り。

% main.tex
\documentclass[11pt, uplatex]{jsreport}
\usepackage[edges]{forest}

% 場合によっては以下も必要かもしれない。自分の環境では不要だった。
% \usepackage{tikz}
% \usetikzlibrary{trees}
% tree

\begin{forest}
 [VP, for tree={parent anchor=south, child anchor=north}
 [DP[John,tier=word]]
 [V’
 [V[sent,tier=word]]
 [DP[Mary,tier=word]]
 [DP[D[a,tier=word]][NP[letter,tier=word]]]
 ]
 ]
\end{forest}
% directory

\begin{forest}
 for tree={grow'=0,folder,draw}
 [/
  [home
   [saso
    [Download]
    [TeX]
   ]
   [alja]
   [joe]
  ]
  [usr
   [bin]
   [share]
  ]
 ]
\end{forest}
% 念のためlatexmkrc
$latex = 'uplatex';
$bibtex = 'pbibtex';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'mendex %O -o %D %S';
$pdf_mode = 3; 

詳細は http://ftp.jaist.ac.jp/pub/CTAN/graphics/pgf/contrib/forest/forest-doc.pdf を参照されたい。

注意

上述のdirectory を描画する際、コードにインデント(スペース1つで良い)をつけないと以下のように、Package pgfkeys Error: I do not know the key '/tikz/grow' というエラーが発生した。latexのブロック定義ってインデントだっけ?

f:id:puyobyee18:20191224132549p:plain
Package pgfkeys Error: I do not know the key '/tikz/grow'


  1. overleaf で使えるパッケージのリスト(公式Doc) に含まれていない。

  2. Using the forest package to create trees in LaTeX - Overleaf, Online LaTeX Editor

【GitHub】草、生やしていますか?

はじめに

いの です。
とある事情で2月までデスマ状態なのですが、VTuberを見ながらどうにか精神を保っています。

GitHubのContributionについて

いわゆる「草」です。
最近までインターンもやっており、研究の進捗もgit管理しているのできっと大草原になっていることだろう…と思ったものの、

f:id:puyobyee18:20191011130650p:plain
gh_pre_contribution

砂漠地帯ですね…
さすがにもう少し進捗を産んでいるのでは?と思い、公式doc*1を見直してみました。

曰く、

  • The email address used for the commits is associated with your GitHub account.
  • The commits were made in a standalone repository, not a fork.
  • The commits were made:
    • In the repository's default branch (usually master)
    • In the gh-pages branch (for repositories with Project Pages sites)

このうち自分は1つ目の「メールアドレスの設定」を見逃していたようです。早速修正しましょう。

contributionに関連するメールアドレス

今回登場するメードアドレスには以下の2種類があります。

  • GitHubのアカウントに登録されているメアド
  • commitに紐付いているメアド

一つずつ見ていきましょう。

GitHub

これは GitHubに紐づく メアドです。
Github > Settings > Public profile > Public email」から適当なメールアドレスを選択します。自分の場合、そもそもメアドをpublicにしていなかったので、「Settings > Emails」内の Keep my email addresses private のチェックを外しました。

Git側

ローカル の設定も確認しましょう。
該当するディレクトリで git config user.email コマンドを打つことで確認できます。先程GitHub側で設定したメアドと一致しているか確認しましょう。
なお、 --global オプションをつけることでグローバルの設定を一括で変更できますが、どうやらcontributionに反映させるには各ディレクトリからpushしないといけないようです。

おわり

以上の操作が済んだらprofileページで確認してみます。きっとcontributionに草が生い茂っていることでしょう。

f:id:puyobyee18:20191011130643p:plain
gh_contributions

まぁまぁだな…

あとがき

先日はVsingerの花譜を紹介しましたが、今回紹介するのはにじさんじ所属の「健屋花那(すこやかな)」さんです。

youtu.be

デビューから数週間にもかかわらず、登録者数は8万人越え。見た目はもちろんのこと、滲み出る博識さも気に入っています。 まぁなにより可愛いんですけど。

なにかと魅力的なナース姿であることもあってか、ファンアートも充実しています(ハッシュタグ #いらすこや で検索!)。
けろりらさん作のアニメーション(https://twitter.com/kerorira1/status/1182243727219163136)もかなりの人気度。本人のことを知らない人でも思わず手を止めてしまうのではないでしょうか…

【Node.js】Webpack でバンドルしたファイル群を Heroku にデプロイしたときに環境変数を適切に使いたい

タイトルながい

あらすじ

Github Pages をはじめ、シンプルな HTML と JS で構成された web ページなら無料で公開できるサービスは五万とあります。

ただ今回自分の作ったものには API key が含まれていたため、Heroku にデプロイすることにしました。
Heroku なら設定も楽だし大丈夫っしょ~~なんて思ってたら 1 日溶けました。つらい。
つらいのでブログにまとめました。誰かの 1 日を守れたら幸いです。

構成

<project>
|_ app/
    |_ index.html
    |_ src/
        |_ index.html
        |_ index.js
    |_ dist/
        |_ bundle.js
|_ .env(git管理外)
|_ webpack.config.js
|_ package.json
|_ app.js

やりたいこと

node ./app.js でexpressを用いたサーバを立て、src/ 以下の index.htmlindex.js を読み込む静的ページを構成。
この js ファイル内で API key を使用するため、.env環境変数を入れておきます。
また index.js は他モジュールを読み込んでいるので babel で es5 へ変換しつつ webpack でバンドルさせます。

1. dotenv

ググったらいっぱい出てくるので説明は割愛。

環境変数.env ファイルで管理するときに用いられるモジュールとして有名なものですが、webpack でバンドルしてしまうとバンドル後の js ファイルに直接書き込まれてしまうっぽい。secure じゃないので却下。

2. dotenv-webpack

上記の問題を解決した(?)モジュールが dotenv-webpack
これは dotenvWebpack.DefinePlugin をラップしたもので、環境変数の呼び出し方はほとんど dotenv と相違ありません。

github.com

dotenv は js ファイル内で require('dotenv').config() と呼び出していましたが、dotenv-webpackwebpack.config.js 内に諸設定を書き込みます(以下参照)。

/* webpack.config.js*/
const Dotenv = require('dotenv-webpack');
module.exports = {
  // 中略
  plugins: [new Dotenv()],
  // 中略
};

これで OK。 あとは呼び出したいところで process.env.SAMPLE_API_KEY と書けば API key が使用できます。

2. 余談

ちなみに .env: でなく = なので注意。

# .env
SAMPLE_API_KEY="hogehoge"

3.Heroku へのデプロイ

Heroku で環境変数の管理をするなら heroku-config をインストールしましょう。楽です。説明は割愛。

ローカルでも動くしあとはdeployだけすればおっけー!なーんて思ってたら

f:id:puyobyee18:20190714120431p:plain

うーん

結論

ローカルなら動く、さらに言えば手元でバンドルしてからデプロイしたらAPIが正しく設定されるようのでHeroku側でwebpackを動かしたときに config vars が読み込めていないっぽい。

一行一行設定を変えつつデプロイして、を繰り返した結果、 webpack.config.js に以下の設定を加えることで解決した。

plugins: [
  new Dotenv({
    systemvars: true,
  }),
],

公式のREADME曰く、

load all the predefined 'process.env' variables which will trump anything local per dotenv specs.

ということらしいのだが、なぜこの設定で行けるようになるのかは謎。

とりあえずデプロイできてよかった。

私の webpack.config.js

諸事情によりレポジトリは公開できませんが、package.jsonwebpack.config.js だけ公開しておきます(一部改変)。参考にしてください。

/* package.json */
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node ./app.js",
    "deploy": "git push heroku staging:master",
    "build": "npx webpack",
    "heroku-postbuild": "webpack -p"
  },
  "devDependencies": {
    "dotenv-webpack": "^1.7.0",
    "eslint": "^5.16.0",
    "eslint-config-prettier": "^4.3.0",
    "eslint-plugin-prettier": "^3.1.0",
    "prettier": "^1.17.1",
  },
  "dependencies": {
    "webpack": "^4.35.3",
    "webpack-cli": "^3.3.5",
    "@babel/core": "^7.5.4",
    "@babel/preset-env": "^7.5.4",
    "babel-loader": "^8.0.6",
    "@babel/polyfill": "^7.4.4",
    "express": "^4.17.1",
  }
}
/* webpack.config.js */
const path = require('path');
const Dotenv = require('dotenv-webpack');

module.exports = {
  // メインとなるJavaScriptファイル(エントリーポイント)
  // aync/await を使うには `@babel/polyfill` を以下のように設定する
  entry: ['@babel/polyfill', './app/src/index.js'],

  // ファイルの出力設定
  output: {
    //  出力ファイルのディレクトリ名
    path: path.resolve(__dirname, 'app/dist'),
    // 出力ファイル名
    filename: 'bundle.js',
  },

  node: {
    fs: 'empty',
  }, // これもよく分からないけどとりあえずemptyにしておけば動いた。
  mode: 'development',
  plugins: [
    new Dotenv({
      path: path.resolve(__dirname, './.env'), // いらないかも。
      systemvars: true,
    }),
  ],
  module: {
    rules: [
      {
        // 拡張子 .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: 'babel-loader',
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES2019 を ES5 に変換
                '@babel/preset-env',
              ],
            },
          },
        ],
      },
    ],
  },
};

あとがき

最近、Vsinger の 花譜 ちゃんにめちゃくちゃハマっています。
15 歳と思えぬ力強い歌声、カンザキイオリさんの楽曲の魅力を持て余すことなく歌い切る表現力 ――――― 。

今後も、もっともっと活躍してほしいです。
8/1 の初の単独ライブ『不可解』、院試のせいで行けないので泣いてる。2nd LIVE に期待。

youtu.be

ラプラスかわいい

【Git】個人用備忘録

Git 備忘録

Git で知らなかったことまとめ。随時更新していきます

対象: なんとなく Git の仕組みが分かってきた人・add,commit,push,pull,checkout,branch は一応使える人

ToC

  • index, HEAD の違い
  • add のオプションまとめ
  • commit を削除する
  • commit をまとめる
  • 差分を見る
  • rebase 使い方
  • branch削除方法

☆index, HEAD の違い

要更新


☆add まとめ

$ git add ... の選択肢は以下の3つ。

  • file 名そのまま: ディレクトリを指定すればそれがステージングにあがる。 ex) $ git add ./app/models/clinic.rb
  • フォルダ名 フォルダ内を再帰的に add してくれる。 ex) $ git add ./app
  • まとめて追加 3 種類(⇒参考)

    • $ git add . バージョン管理されていないファイルは追加されない。 すなわち新たに追加されたもの変更があったものが対象。 Git ver.1 まではこうであったが、現在は追加変更削除いずれも追加される。
    • $ git add -u バージョン管理されているファイルをすべて追加。 すなわち変更があったもの削除されたものが対象。
    • $ git add -A[--all] 全てが追加される。

    $ git add .$ git add -Aの違い 前者はカレントディレクトリ下のファイルをすべて追加するが、後者はプロジェクトのどこからでも該当ファイルをステージングにあげるという違いが存在する。


☆commit の削除方法

  • commit を削除したことを残す $ git revert <commit>で削除可能。コンフリクトがおきたらがんばれ。 なお<commit>のところには commit ID を入力すればよい。

☆commit をまとめる方法

  1. $ git log --onelineでまとめたいコミットを確認。
$ git log --oneline

# 1a2b3c <commit msg3>
# 4d5e6f <commit msg2>
# 7g8h9i <commit msg1>
  1. $ git rebase -i HEAD~<n>により、HEAD から n 個の commit をまとめる。
  2. vim が展開するので、以下のように合成元をfixupに書き換える。:wqで保存。
pick 7g8h9i <commit msg1>
- pick 4d5e6f <commit msg2>
- pick 1a2b3c <commit msg3>
+ fixup 4d5e6f <commit msg2>
+ fixup 1a2b3c <commit msg3>

※やばいときは$ git rebase --abortで rebase を取りやめる。

参考


☆diff により差分を見る方法

git diffで差分を見れる。アレコレ書こうと思ったけど普通にこの Qiita が優秀だったので読みましょう。

参考 ⇒忘れやすい人のための git diff チートシート


☆rebase まとめ(含: stash, fetch)

git rebaseとは?

歴史のを改変するコマンド。以下の図が分かりやすい。

rebasemerge(則ちpull)のコミットログ比較(⇒参考)

rebaseとmergeの比較

分かりやすい。

やり方

ブランチ名は上記画像に則る。

  1. git fetch git fetch はリポジトリと結びついているorigin/masterが最新になる。(正確にはリモートのmasterブランチをもとに、ローカルにFETCH_HEADというブランチが構築され、それが最新状態になる。) 他人からの変更があった場合、こまめにやるのがよさそう。 ちなみにgit pullは、この fetch の作業が終わったのち作業ディレクトリに結び付く master を origin/master をもとに更新する。
  2. git rebase origin/develop featureブランチの"元"を上記図 D から引っ張るようにする。うまくいけば 3 へ。 以下うまくいかない場合
    • featureに commit が残っているとき この場合は、rebase をする前にgit stash saveを行う。この stash コマンドにより作業を一時退避させることができる。退避させたのち rebase を行い、git stash applyで適用する。以下便利なコマンド。
      • git stash list: stash の一覧を確認したい場合。
      • git stash apply <stash_name>: <stash_name>を適用する。コンフリクト起こしたときはがんばれ。
      • git stash drop <stash_name>: stash を削除するコマンド。適宜消すべし。
      • git stash pop <stash_name>: 適用と削除を一気に行うコマンド。自信がないうちは apply でいいよ。
    • conflict を起こしたとき Aborted! やらなにかしら吐いて rebase が一時中断される。 git statusで確認すると、コンフリクトを起こしているファイルはboth modifiedとなっているハズ。 適当なエディタ等でコンフリクトを solve したら、該当ファイルを add するのを忘れないように。 さらにそののちcommit はせずgit rebase --continueで rebase 処理を再開させる。この手順じゃないとうまくいかなかった。
    • よく分からなくなってしまったとき git rebase --aborted一択。rebase を実行する前の状態まで戻してくれるので、ヤバい!と思ったらこれを行う。
  3. git push --force origin feature あまりやりたくはないが push --force をやる。

一連の流れ

$ git fetch
$ git stash # プッシュしていないcommitがあったとき
$ git rebase origin/master
$ git status # コンフリクトがありそうなとき
$ git diff -- FILE_NAME # 差分を確認
$ git add FILE_NAME
$ git rebase --continue
$ git stash pop
$ git push --force origin mybranch

☆branch削除方法

ローカル

# コミット済み(HEADにmerge済?)の場合
git branch --delete my-branch
# 上記を問わない場合
git branch -D foo

リモート

# 一覧表示
git branch --remote
# 消し方は一通り
git push --delete origin my-branch