Magitの歴史修正機能

MagitのRewritingがよく分からなかったので、色々触っていたらなんとなく理解したけどgit rebase -iとどこが違うんだろう?

ちなみに、M-x magit-statusを毎度叩くのも飽きたのでC-x gに割り当てました。

(global-set-key (kbd "C-x g") 'magit-status)

Rewritingの使い方

まずはl lでログリストを出して、修正の起点のコミットログでr b(begin)を押す。

すると、magit-statusでそれ以降のコミットログがpendingされたコミットになっているので、修正したい順番にAを押していく。きちんとコミットされるとpendingのステータスが*(未使用)から.(使用済み)に変わる。r .とかr *でも状態変更はできる。

これはgit rebase -iでコミットログの順番を変えるのとほとんど一緒だと思う。

まとめてコミットしたい場合はaをつかえばいいんだけど、コンフリクトしたりしてなんか挙動がいまいち掴みきれていない。

最初の方はなかなか思い通りにいかなくて最初からやり直したいことが多いが、そういう場合に破棄するのはr a(abort)でOK。

慣れるまではcloneしてテスト用のリポジトリで作業してみて、OKだったらもとのリポジトリで修正すんのがいいのかもしれない。

Reflogの使い方

l hでReflogが出るのでAを押すとコミットが取り込まれる。

ProductName 実用Git
Jon Loeliger
オライリージャパン / 2940円 ( 2010-02-19 )


Magit初心者が絶対に覚えておくべきコマンド

Git初心者が絶対に覚えておくべきコマンドをMagitでやるには。

git-commit --amend

通常コミットするときはステージに上った状態でcを押しコミットログのためのメッセージを編集した後C-c C-cします。

ここでC-c C-cではなくC-c C-aするとamandのための編集画面になります。

Amend: "yes"
-- End of Magit header --
second commit # コミットログメッセージ

あらためてC-c C-cすればamendされます。

git-reset

magit-statusしてステータス画面を出したあと、Headの行にカーソルをあわせてxを押す。

デフォルトは git reset HEAD^となります。

ログ画面でxを押すと対応するとこまでresetされます。

git-reflog

magitの場合、元サイトのようなミスは起こりにくいと思いますが。

magit-statusでr bを押すとrewriteがはじまるので、aとかAとか押したりして歴史の修正をしていく。

実際やってみたけど、ちょっとややこしいのでRewritingのセクションをきちんと読んだほうがいいのか。

あとでちゃんと理解しておこうっと。

EmacsでHaskellをつかうために

flymakeがあるのが当たり前になってしまっているので、Haskellで書いてる時にもダメなところはダメって言ってもらわないとちょっと気持ち悪い。

Haskellでもflymakeを使えるようにするためにMac/emacsでHaskell環境を作るを参考に自分のflymake-init.elに追加した。

ついでにhaskell-modeも新しいのを入れるためにgit cloneしておいた。

おまけ

Emacsの画面分割を快適にする

キーバインドにもデザインのセンスが必要だなぁとしみじみ

僕はCtrl+Tabにあてました(Ctrl-tはdmacroにあててるので)。

(global-set-key (kbd "<C-tab>") 'other-window-or-split)

CoffeeLintでflymakeするように設定した

最近順調にバージョンが上がっているCoffeeLintを使ってみた。CoffeeLintのサイトから辿れるcoffeelintnodeはサバクラの構成っぽくてちょっと使いづらそうだったので、flymakeの設定を書いてみた。

flymake-cursorにも対応させてあるので下のスクリーンショットのミニバッファーにエラー内容が表示されてる。

flymake_coffee

自分でelispを書く場合、この本はとても良かった。この本を片手に他の人の書いたelispを読むのも楽しい。

ProductName Emacs Lispテクニックバイブル
るびきち
技術評論社 / 3129円 ( 2011-11-26 )


それからcoffeelintのパスがnvmのちょっとアレなパスで直書きしたくなかったのと、coffeelintが結構死ぬので、flymakeが巻き添えを食わないようにする設定のやり方を参考にさせてもらった。

昨日書いたpythonのflymake部分を切り離してinit-flymake.elに統合したので、coffeescriptだけ設定したい場合は下のelispからpythonの設定を削除すれば動くと思います。

(defadvice flymake-post-syntax-check (before flymake-force-check-was-interrupted)
  (setq flymake-check-was-interrupted t))
(ad-activate 'flymake-post-syntax-check)

(add-hook 'find-file-hook 'flymake-find-file-hook)

(when (load "flymake" t)
;; flymake+pyflakes+pep8
; http://d.hatena.ne.jp/cou929_la/20110525/1306321857
  (defun flymake-pyflakes-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "pycheckers" (list local-file))))
  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.py\\'" flymake-pyflakes-init))
;; flymake+coffeelint
; http://blog.kzfmix.com/entry/1334315825 
  (defun flymake-coffeelint-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "coffeelint" (list "--csv" local-file))))
  (add-to-list 'flymake-err-line-patterns
                 '(".+,\\(.+\\),\\(.+\\),\\(.+\\)"
                   nil 1 nil 3)) 
  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.coffee\\'" flymake-coffeelint-init)))

(load-library "flymake-cursor")

magitの使い方も覚えたので、Flask+Spineのコーディングが快適にできそう。

EmacsのPython開発環境を整えた

macbookを買ってからずっとcarbon emacsを使っていたんだけど、思うところあって23系に変更した。

ここを参考にしながらソースコードを落としてきてインストールした。

python開発環境はemacs-for-pythonがよさそうだったんだけど自分の環境ではpyflakesが動かなかったので、深入りする前にやめた。今度また時間があるときにチャレンジする。

結局以下のサイトを参考にしてflymake, pyflakes, pep8, virtualenv, noseが動くようにしておいた。

emacs

出来上がったelisp

(add-hook 'python-mode-hook
                   '(lambda()
                        (setq indent-tabs-mode nil)
                        (setq indent-level 4)
                        (setq python-indent 4)
                        (setq tab-width 4)))

;; flymake+pyflakes+pep8
; http://d.hatena.ne.jp/cou929_la/20110525/1306321857

(add-hook 'find-file-hook 'flymake-find-file-hook)
(when (load "flymake" t)
  (defun flymake-pyflakes-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list (expand-file-name "~/bin/pycheckers")  (list local-file))))
  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.py\\'" flymake-pyflakes-init)))

(load-library "flymake-cursor")

;; virtualenv
; https://github.com/aculich/virtualenv.el
(require 'virtualenv)

;; nose.el
; https://bitbucket.org/durin42/nosemacs/src/9302529e68be/nose.el
(require 'nose)
(add-hook 'python-mode-hook
          (lambda ()
            (local-set-key "\C-ca" 'nosetests-all)
            (local-set-key "\C-cm" 'nosetests-module)
            (local-set-key "\C-c." 'nosetests-one)
            (local-set-key "\C-cpa" 'nosetests-pdb-all)
            (local-set-key "\C-cpm" 'nosetests-pdb-module)
            (local-set-key "\C-cp." 'nosetests-pdb-one)))

M-x virtualenv-workonでvirtualenvが使えるうえにemacsからnosetestsをはしらせることが出来るので快適だ。

ProductName エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス / 3780円 ( 2010-05-28 )


magit(emacs+git)は快適な予感がする

EmacsからGitを扱いたくなったので、Magitを入れてみた。

ProductName 入門Git
濱野 純(Junio C Hamano)
秀和システム / 2310円 ( 2009-09-19 )


眺めただけでは快適なのかどうなのかよくわからんので、「chapter4の独りで使う」をmagitでやってみた。

gitの初期化

M-x magit-initでディレクトリを指定すればgitリポジトリの初期化をしてくれます。ディレクトリが存在しなければ作成してくれる。

M-x magit-init
magit4と打つ

これでmagit4というディレクトリが作られてgitリポジトリが初期化される

最初のコミット

C-x C-fでindex.htmlを作成します。ファイルの中身

<html>
  <head>
<title>Shizugit</title>
</head>
<body>
<h1>Shizugit</h1>
<p>Shizugitでは、参加者を募集しています。
最新の版管理システムgitについて熱く語り合いましょう。
</p>
<address>
<a href="mailto:magit@test.com">kzfm</a>
</address>
</body>
</html>

C-x C-sで保存します。

さて、ここでおもむろにM-x magit-statusと打つとmagit-modeのバッファーが開きます(下段)。

magit1

カーソルをindex.htmlにあわせてs キーを打つとステージングされます。これはgit add index.htmlと同じ事です。逆を行いたい場合(アンステージ)はuキーです。

magit2

この状態でcを押すとコミットログ編集画面がでるので「第一回参加募集」とでも書いておきます。

C-c C-cを打てばコミットが作られます。

magit3

変更の記録

index.htmlのaddressタグの直前に静岡っぽいテーマを挿入してみます。

<p>第一回会合では、セミナーも開催します</p>
<ul>
<li>お茶の淹れ方
<li>静岡酵母について
<li>Sphinxとか
</ul>

セーブ(C-x C-s)します。

変更を見るには先ほどのmagit-modeでindex.htmlにカーソルをあわせてdを押します。これはつまりgit diffです。先程追加した部分が差分として表示されてます。

magit4

TODO: git diff HEADのやり方を調べる

コミットを作成します。なにもステージングしてない状態でcを押すと、ステージングしてない変更をステージングするかどうか聞いてくるのでyを押してコミットします。

変更履歴を見る

これで2つのコミットログができているはずなので、変更履歴を見てみます。M-x magit-statusでmagit-modeのバッファーを表示してlキーを二回叩きます。

magit5

部分変更の記録

論理的に異なる2つの変更を施します。みんな大好きSEO対策と、おやつのアナウンスです。index.htmlは次のようになります。

<html>
  <head>
<title>Shizugit</title>
<meta name="keywords" content="SEO,SEO対策,SEOアクセス解析,アクセスアップ,SEOツール">
</head>
<body>
<h1>Shizugit</h1>
<p>Shizugitでは、参加者を募集しています。
最新の版管理システムgitについて熱く語り合いましょう。
</p>
<p>第一回会合では、セミナーも開催します</p>
<ul>
<li>お茶の淹れ方
<li>静岡酵母について
<li>Sphinxとか
</ul>
<p>おやつは杉山フルーツの生ゼリーですYo!</p>
<address>
<a href="mailto:magit@test.com">kzfm</a>
</address>
</body>
</html>

それぞれの変更を個別にコミットしたくなる(git add -p) わけですが、magit-statusバッファーのindex.htmlにカーソルをあわせてタブキーを押すと、ハンクが表示されるのでハンクをsでステージします。

下の図は、メタ情報の追加をコミットしたあとの状態です。

magit6

分割してコミットした後のログは以下になります。メタ情報とおやつ情報の2つに分けてコミットしました。

magit7

変更の取り消し

magit-statusバッファーでl l でログを表示させ、おやつ情報のコミットにカーソルをあわせてvを押します。その後cを押してコミット編集画面で編集したらC-c C-cでコミットします。

magit8

杉山フルーツの生ゼリーは美味しいんだけど、そこそこの値段がするので、毎回は出せないですね。

コミットを捨てる

index.cssというファイルを作成し、追加してコミットします。

このコミットを捨てたい時には、magit-statusバッファーでxを押すとresetするかどうか聞いてくるのでyをおすだけです。これはお手軽ですね

コミットをやり直す

コミット編集画面をもう一度表示させてC-c C-aでOK

結論

キーバインドは覚えるまで苦労しそうだけど、一度覚えれば忘れなさそうだしmagitをメインに使っていこうかなと。

  • chapter4のgitの操作はほとんどmagitで操作できた
  • キーバインドに慣れればmagitは快適に使えそう
  • 入門Gitは良書

ProductName 入門Git
濱野 純(Junio C Hamano)
秀和システム / 2310円 ( 2009-09-19 )


Emacs実践入門どうしようかと悩み中

正直欲しい

ただ、Emacsの本は出るたびに買っているから、コレクターみたいになっているので困っている。あとEmacs派みたいに思われているが、そんなことはなくて一番使いやすいので使っているだけです。

ちなみにこの前WIdows server2008に入れてデフォルトのままで使おうとしたら使いづらすぎて発狂しそうになった。HTMLのテンプレートを書いていたんだけどかな漢字変換システムがおかしなことになっていて、思ったように感じが出てこなくてイライラしてた。

やっぱ.emacsとelispをリポジトリで管理しないとダメだなぁと。それかbuildoutとかfabricみたいなのでEmacs環境構築を自動化できないかなぁ。

あとで考える。

Emacsのcoffee-modeに" -> "を挿入するショートカットキーを設定した

CoffeeScriptはfunctionが->になっただけでしょっちゅう->を打たなければならない。

これは面倒なのでショートカットキーを割り当てた。

(require 'coffee-mode)

(add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))
(add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))

(add-hook 'coffee-mode-hook '(lambda ()
                             (local-set-key "\C-j" (lambda ()
                             (interactive)(insert " -> ")))
                 ))

;; CoffeeScript uses two spaces.
(defun coffee-custom ()
  "coffee-mode-hook"
 (set (make-local-variable 'tab-width) 2))

(add-hook 'coffee-mode-hook
  '(lambda() (coffee-custom)))

これでそこそこ便利になったが、もうちょっとカイゼンする余地はあるんだろうなぁ。

おまけ

静岡javascript勉強会が10/1にあります。node.jsやjQueryMobileのトークも入ってて盛りだくさんなのでおもしろそうですね。枠が埋まっているけど、キャンセル待ちに入れておくといいと思います。

残念なことに僕がキャンセル第一号ですけどねー

Emacsでunindentationするには負の数を入れる

インデントするにはC-u C-x C-iとかC-u n(空白文字の数) C-x C-iなのはちょっと前に覚えたのだけど、逆に4文字字上げしたい場合には

C-u -4 C-x C-i

とやればよいということに気づいたが、ちょっとめんどくさい。数字打たなくてもいい方法ってあるのかな?