Gitでブランチを間違えて作業した上にpushまでしちゃった場合の対処方法
時間ができたのでHandBrake 0.9.5の日本語化に着手しているのだが、うっかり0.9.4のブランチで作業してしまったあげく、SourceForge.JP上のリポジトリにpushしてしまい途方に暮れる。
まあこういうミスをやる人は少ないだろうが、何かのヒントになるかもしれないので対処法をメモしておく。まず、「git log」コマンドで巻き戻したいcommitのハッシュを調べる。
$ git log : : commit 1485a5a2bbbb43eedbe131c919b7d604bcbd506d Author: unknownDate: Tue Jan 5 19:19:44 2010 +0900 update Installer, changelog, readme
今回は、この「1485a5a2bbbb43eedbe131c919b7d604bcbd506d」というcommitまで巻き戻すことにする。作業中のブランチが操作したいものであることを確認したうえで、「git reset <対象のハッシュ>」を実行する。
$ git branch -a jp-0.9.3 * jp-0.9.4 master original remotes/origin/HEAD -> origin/master remotes/origin/jp-0.9.3 remotes/origin/jp-0.9.4 remotes/origin/master remotes/origin/original $ git reset 1485a5 Unstaged changes after reset: M Jamrules M Makefile M win/C#/Installer/Installer.nsi M win/C#/InstallerJp/doc/AUTHORS M win/C#/InstallerJp/doc/CREDITS M win/C#/InstallerJp/doc/NEWS M win/C#/Properties/AssemblyInfo.cs M win/C#/frmAbout.Designer.cs
「git log」で巻戻ったことを確認する。
$ git log commit 1485a5a2bbbb43eedbe131c919b7d604bcbd506d Author: unknownDate: Tue Jan 5 19:19:44 2010 +0900 update Installer, changelog, readme
バージョン管理されているファイル自体は巻き戻されていないので、「-f」オプション付きでチェックアウトしてファイルも巻き戻す。
$ git checkout -f
ここまでの作業でローカルブランチの巻き戻しは完了。続いてリモートブランチの巻き戻しを行う。ただし、当然ながらそのままpushすることはできない。
$ git push Enter passphrase for key '/d/Users/hirom/.ssh/id_dsa': To hylom@git.sourceforge.jp:/gitroot/handbrake-jp/handbrake-jp.git ! [rejected] jp-0.9.4 -> jp-0.9.4 (non-fast-forward) error: failed to push some refs to 'hylom@git.sourceforge.jp:/gitroot/handbrake- jp/handbrake-jp.git' To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. 'git pull') before pushing again. See the 'Note about fast-forwards' section of 'git push --help' for details.
そこで、いったんリモートブランチを削除した上で再度pushする。まずは削除。リモートブランチの削除は、「git push <リモートリポジトリ> :<対象リモートブランチ>」で行える。
$ git push origin :jp-0.9.4 Enter passphrase for key '/d/Users/hirom/.ssh/id_dsa': To hylom@git.sourceforge.jp:/gitroot/handbrake-jp/handbrake-jp.git - [deleted] jp-0.9.4
あとは再度ローカルリポジトリをpushするだけ。
$ git push origin jp-0.9.4:jp-0.9.4 Enter passphrase for key '/d/Users/hirom/.ssh/id_dsa': Counting objects: 233, done. Delta compression using up to 2 threads. Compressing objects: 100% (146/146), done. Writing objects: 100% (165/165), 30.48 KiB, done. Total 165 (delta 119), reused 0 (delta 0) To hylom@git.sourceforge.jp:/gitroot/handbrake-jp/handbrake-jp.git * [new branch] jp-0.9.4 -> jp-0.9.4
お粗末様でした。
BSD版sedとGNU版sed
BSD版のUNIX toolsと、GNU版のUNIX toolsでは微妙に受け付けるコマンドラインオプションが違うのは有名な話。たとえばGNU版の「cp -a」はBSD版では「cp -pr」に相当する。
で、Mac OS XのコマンドラインツールはBSD版なのだが、「sed -e “s/ /\n/g”」が効かなくて困った。Mac OS X付属のsedは置換後の文字の指定にエスケープシーケンスが使えないらしい。
これの簡単な解決はこちら。
perl -pe "s/ /\n/g"
「perl -p」でsedっぽい動作をさせられる、という話でした。よくこんなの覚えてたな>自分。ラクダ本の最初のほうとかに書いてあったんだっけ? ラクダ本を読んだのは多分10年くらい前だと思うんだけど、IT業界の進化は早いとか言われていて3年前の知識はもう古いとか言われているけど意外に昔覚えたことってふと全然違うことで役立つことがあるから侮れないね。
gfxbootで日本語表示可能なブートローダを作成しようとする
GParted Live CD をWindows Vista上でUSBメモリにインストールしようとしたらUAEの仕様がアレでハマる。
GParted Live CDのUSBメモリ用配布アーカイブにはWindows用のISOLINUXインストーラが付属していて、USBメモリにファイル一式をコピー→バッチファイル実行でブータブルUSBメモリができあがるはずなのだが、VistaだとUSBメモリのブートローダ領域への書き込みには管理者権限がいるそうだ。そりゃそうだ。しかし、かといってバッチファイルを「管理者として実行」するとエラー。なぜかバッチファイルを「管理者として実行」すると、system32ディレクトリがカレントディレクトリになるのが原因。なんじゃそりゃ。
しょうがないのでバッチファイルをいじくってたらつい日本語化してしまい、ついでにじゃぁほかの部分も日本語化するか、どうせ設定ファイルいくつか書き換えればできるだろと手をつけたのがハマり始まり。そんな簡単なモンじゃなかった。
Ubuntuのインストーラとかはブート時にブートメニューが日本語で表示されるんだけど、これはgfxbootというものを使っているらしい。gfxbootはSYSLINUX/ISOLINUX/GRUBなどで利用できるプログラムで、それぞれパッチが当てられたSYSLINUX/ISOLINUX/GRUBが必要。原理としてはSYSLINUX/ISOLINUX/GRUBがgfxbootのランタイム(gfxmenu)を起動→gfxmenuがメニュースクリプトを実行、という感じ。このメニュースクリプトは独自言語で記述しておいて、あらかじめバイトコンパイルして1ファイルにまとめた上でブートローダと一緒に置いておくのだが、この独自言語がスタック志向の非常に面倒臭い言語で困る。プログラム中でメモリを動的に割り当てられたり、ファイルのリードもできるのだが、完全に独自仕様(しいて言えばPostScriptに似ているらしい)。
gfxbootを使っているUbuntuやopenSUSEのブートローダは、基本的にはスクリプト部分は手を加えずに設定ファイルで画像なりメニュー項目をいじれるようになっているんだが、さすがにGParted Live CDを起動したらUbuntuのメニューが、というのはダサいのでざくっと手をいれてみようとしたが2時間くらい格闘して一時中断。これは週末に持ち越しだな。
ちなみに gfxboot reference と Gfxboot – openSUSE あたりが参考資料。日本語の情報はほぼ皆無(笑)。