gitのcommit logの名前、Authorを間違えた、しかも2つも、私ってほんとバカ、そんな時

直前が修正はcommit –amend –authorで変更できます。

git commit --amend --author="hoge <hoge@example.com>"

問題は、2つも間違ってやっちまった場合。

ログの確認

とりあえず、git logを眺めてみます。

git log

結果はこちら。

commit 5450b0d86ed1310550a934f884b9eb08b515880c
Author: unknown
Date: Thu Aug 8 19:50:20 2013 +0900

修正2

commit d6212fb1aeb141552a892f2417fb0cb648a7a74d
Author: unknown
Date: Wed Aug 7 21:00:25 2013 +0900

修正1

commit 05dd166e88af43b90d95e1551d779fc72907478d
Author: hoge <hoge@example.com>
Date: Wed Aug 7 20:28:40 2013 +0900

First Commit!

履歴の改変

履歴改変なので、git rebaseを使います。
最新から2つなので以下のように。

git rebase -i HEAD~2

リビジョン指定する場合は、変更したいりビジョンの1つ前のものを指定するとそれ以降変更できます。

git rebase -i 05dd166e88af43b90d95e1551d779fc72907478d

すると既定のエディタが立ち上がり以下のような表示になります。

pick d6212fb 修正1
pick 5450b0d 修正2

# Rebase 05dd166..5450b0d onto 05dd166
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

今回はAuthorを変更したいので、「pick」の部分を「edit」へ変更します。

1つ目の履歴改変

保存すると、変更する最初の履歴の処理に移ります。

Stopped at d6212fb... 修正1
You can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

commit –amendした後にrebase –continueしろとのことなので言われるママに。

git commit --amend --author="hoge <hoge@example.com>"

修正され、リビジョンが新しいものが振られました。

[detached HEAD ad48807] 修正1
1 file changed, 1 insertion(+), 4 deletions(-)

続いて、rebase –continue

git rebase --continue

2つ目の履歴改変

次のコミットに移りました。

Stopped at 5450b0d... 修正2
You can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

同じようにcommit –amend

git commit --amend --author="hoge <hoge@example.com>"

こちらも新しいリビジョンが振られました。

[detached HEAD 219cca8] 修正2
3 files changed, 7 insertions(+), 5 deletions(-)

同じく、rebase –continue

git rebase --continue

すると成功したようです。

Successfully rebased and updated refs/heads/master.

確認

ログを確認してみます。

git log

結果は以下のように、Authorが変更され、新しいリビジョンが振られました。

commit 219cca8098e26938c8b7da88d5b32adf4bc040b2
Author: hoge <hoge@example.com>
Date: Wed Aug 7 21:00:25 2013 +0900

修正2

commit ad4880774556f7be4dbda943c9cb1d6567e2c4f0
Author: hoge <hoge@example.com>
Date: Wed Aug 7 20:28:40 2013 +0900

修正1

commit 05dd166e88af43b90d95e1551d779fc72907478d
Author: hoge <hoge@example.com>
Date: Wed Aug 7 18:07:38 2013 +0900

First Commit!

修正できました。おめでとう。

カテゴリー: 日記 タグ:

weinreでAndroidのブラウザのデバッグ

OSXでweinreのインストール。

まず、node.jsのインストール。
現在の最新版は0.8.18。

続いて、npmコマンドでのweinreのインストール。

npm install weinre

weinreの実行。

~/node_modules/weinre/weinre

ログにあるようにhttp://localhost:8080/にアクセスし起動のチェック。

「Target Script」にあるスクリプトを読み込むことで対象ページで読み込むことでデバッグ可能となる。
サンプルでは以下のようになっている。
#以降でチャンネルを指定できる。

<script src="http://localhost:8080/target/target-script-min.js#anonymous"></script>

現状だとlocalhostからのアクセスしか許可されないので、weinreをboundHostオプションを指定して起動しなおす。

~/node_modules/weinre/weinre --boundHost 0.0.0.0

対象のページにweinreを実行しているホストのIPをしてスクリプトを埋め込む。

<script src="http://x.x.x.x:8080/target/target-script-min.js#anonymous"></script>

確認は#以降で指定したチャンネルを以下のように指定する。

http://localhost:8080/client/#anonymous

カテゴリー: android タグ:

strtotimeの「-1 month」は1ヶ月前ではない

以下に期待するのは「2012年02月」

echo date('Y年m月', strtotime('-1 month', strtotime('2012-03-31')));

答えは「2012年03月」

実際に「-1 month」がどのくらいの値を返してるを以下で調べてみた。


for ($i = 1; $i <= 12; $i++) { $date = sprintf(‘2012-%02d-01′, $i); $day = strtotime($date) – strtotime(‘-1 month’, strtotime($date)); printf(“%s %d\n”, $date, $day / 86400); } [/php] 対象日、それに対する「-1 month」での日数の順に表示した結果は以下の通り [bash] 2012-01-01 31 2012-02-01 31 2012-03-01 29 2012-04-01 31 2012-05-01 30 2012-06-01 31 2012-07-01 30 2012-08-01 31 2012-09-01 31 2012-10-01 30 2012-11-01 31 2012-12-01 30 [/bash] この結果から、「-1 month」は対象日の先月分の日数をマイナスする処理ということがわかる。 strtotimeで「-1 month」を用いて1ヶ月前の月を取得したい場合、対象日を月の初め、1日をする必要がある。

カテゴリー: php タグ:

CakePHP2.xでimg以下のfaviconを指定したい

<?php echo $this->Html->meta('icon', $this->Html->assetUrl('favicon.png', array('pathPrefix' => IMAGES_URL))) ?>

faviconのファイル名はfavicon.png
assetUrlでimgディレクトリのパスを生成。
assetUrlメソッドはHelperのメソッドなのでHtmlヘルパーじゃなくて可。

カテゴリー: php タグ:

javascriptでarray_intersect

ようは、共通項
Simplest code for array intersection in javascript – Stack Overflow
一番に上ってるのダサくね。
Javascript array difference – Stack Overflow
array_diffのほうは良い感じなのに。

ってことで

Array.prototype.intersect = function(a) {
    return this.filter(function(i) {return a.indexOf(i) != -1;});
};

////////////////////
// Examples
////////////////////

console.log([1,2,3,4,5,6].intersect( [3,4,5] ));
// => [3, 4, 5]

console.log(["test1", "test2","test3","test4","test5","test6"].intersect(["test1","test2","test3","test4"]));
// => ["test1", "test2", "test3", "test4"]
カテゴリー: javascript タグ:

GoogleIMEの設定

SSHを介してVimを使う人に感動的なESCキーを押すとESCキーが効きつつIMEがオフになる設定(Google日本語入力とVimの相性は最強!) – しふーのブログ

ことえりからインポートした設定+上記の設定をエクスポートした内容。
エクスポートファイルのデフォルトのファイル名はkeymap.txt

status	key	command
Composition	Backspace	Backspace
Composition	Ctrl ;	DisplayAsHalfWidth
Composition	Ctrl :	DisplayAsHalfAlphanumeric
Composition	Ctrl '	DisplayAsHalfAlphanumeric
Composition	Ctrl 0	DisplayAsHalfAlphanumeric
Composition	Ctrl 2	ConvertWithoutHistory
Composition	Ctrl 6	DisplayAsHiragana
Composition	Ctrl 7	DisplayAsFullKatakana
Composition	Ctrl 8	DisplayAsHalfWidth
Composition	Ctrl 9	DisplayAsFullAlphanumeric
Composition	Ctrl a	MoveCursorToBeginning
Composition	Ctrl b	MoveCursorLeft
Composition	Ctrl d	Delete
Composition	Ctrl e	MoveCursorToEnd
Composition	Ctrl Eisu	ToggleAlphanumericMode
Composition	Ctrl f	MoveCursorRight
Composition	Ctrl g	Cancel
Composition	Ctrl h	Backspace
Composition	Ctrl j	DisplayAsHiragana
Composition	Ctrl k	DisplayAsFullKatakana
Composition	Ctrl l	DisplayAsFullAlphanumeric
Composition	Ctrl Left	MoveCursorToBeginning
Composition	Ctrl m	Commit
Composition	Ctrl m	Commit
Composition	Ctrl Option 1	DisplayAsHiragana
Composition	Ctrl Option 2	DisplayAsFullKatakana
Composition	Ctrl Option 3	DisplayAsFullAlphanumeric
Composition	Ctrl Option 4	DisplayAsHalfWidth
Composition	Ctrl Option 5	DisplayAsHalfAlphanumeric
Composition	Ctrl Right	MoveCursorToEnd
Composition	Delete	Delete
Composition	Eisu	ToggleAlphanumericMode
Composition	Enter	Commit
Composition	ESC	Cancel
Composition	F10	DisplayAsHalfAlphanumeric
Composition	F2	ConvertWithoutHistory
Composition	F6	DisplayAsHiragana
Composition	F7	DisplayAsFullKatakana
Composition	F8	DisplayAsHalfKatakana
Composition	F9	DisplayAsFullAlphanumeric
Composition	Left	MoveCursorLeft
Composition	Option a	DisplayAsHalfWidth
Composition	Option c	DisplayAsFullAlphanumeric
Composition	Option F1	DisplayAsHiragana
Composition	Option F2	DisplayAsFullKatakana
Composition	Option F3	DisplayAsFullAlphanumeric
Composition	Option F4	DisplayAsHalfWidth
Composition	Option F5	DisplayAsHalfAlphanumeric
Composition	Option j	MoveCursorLeft
Composition	Option l	MoveCursorRight
Composition	Option s	DisplayAsHalfAlphanumeric
Composition	Option Space	InsertFullSpace
Composition	Option x	DisplayAsFullKatakana
Composition	Option z	DisplayAsHiragana
Composition	Right	MoveCursorRight
Composition	Space	Convert
Composition	Tab	PredictAndConvert
Conversion	Backspace	Cancel
Conversion	Ctrl ;	DisplayAsHalfWidth
Conversion	Ctrl :	DisplayAsHalfAlphanumeric
Conversion	Ctrl '	DisplayAsHalfAlphanumeric
Conversion	Ctrl 0	DisplayAsHalfAlphanumeric
Conversion	Ctrl 6	DisplayAsHiragana
Conversion	Ctrl 7	DisplayAsFullKatakana
Conversion	Ctrl 8	DisplayAsHalfWidth
Conversion	Ctrl 9	DisplayAsFullAlphanumeric
Conversion	Ctrl a	SegmentFocusFirst
Conversion	Ctrl b	SegmentFocusLeft
Conversion	Ctrl d	SegmentFocusRight
Conversion	Ctrl e	ConvertPrev
Conversion	Ctrl f	SegmentFocusRight
Conversion	Ctrl h	Cancel
Conversion	Ctrl i	SegmentWidthShrink
Conversion	Ctrl j	DisplayAsHiragana
Conversion	Ctrl k	DisplayAsFullKatakana
Conversion	Ctrl l	DisplayAsFullAlphanumeric
Conversion	Ctrl Left	SegmentFocusFirst
Conversion	Ctrl m	Commit
Conversion	Ctrl n	ConvertNext
Conversion	Ctrl o	SegmentWidthExpand
Conversion	Ctrl Option 1	DisplayAsHiragana
Conversion	Ctrl Option 2	DisplayAsFullKatakana
Conversion	Ctrl Option 3	DisplayAsFullAlphanumeric
Conversion	Ctrl Option 4	DisplayAsHalfWidth
Conversion	Ctrl Option 5	DisplayAsHalfAlphanumeric
Conversion	Ctrl p	ConvertPrev
Conversion	Ctrl q	SegmentWidthShrink
Conversion	Ctrl Right	SegmentFocusLast
Conversion	Ctrl s	SegmentFocusLeft
Conversion	Ctrl w	SegmentWidthExpand
Conversion	Ctrl x	ConvertNext
Conversion	Down	ConvertNext
Conversion	Enter	Commit
Conversion	ESC	Cancel
Conversion	F10	DisplayAsHalfAlphanumeric
Conversion	F6	DisplayAsHiragana
Conversion	F7	DisplayAsFullKatakana
Conversion	F8	DisplayAsHalfWidth
Conversion	F9	DisplayAsFullAlphanumeric
Conversion	Left	SegmentFocusLeft
Conversion	Option a	DisplayAsHalfWidth
Conversion	Option c	DisplayAsFullAlphanumeric
Conversion	Option F1	DisplayAsHiragana
Conversion	Option F2	DisplayAsFullKatakana
Conversion	Option F3	DisplayAsFullAlphanumeric
Conversion	Option F4	DisplayAsHalfWidth
Conversion	Option F5	DisplayAsHalfAlphanumeric
Conversion	Option i	ConvertPrev
Conversion	Option k	ConvertNext
Conversion	Option s	DisplayAsHalfAlphanumeric
Conversion	Option x	DisplayAsFullKatakana
Conversion	Option z	DisplayAsHiragana
Conversion	PageDown	ConvertNextPage
Conversion	PageUp	ConvertPrevPage
Conversion	Right	SegmentFocusRight
Conversion	Shift Down	ConvertNextPage
Conversion	Shift Left	SegmentWidthShrink
Conversion	Shift Right	SegmentWidthExpand
Conversion	Shift Space	ConvertPrev
Conversion	Shift Tab	ConvertPrev
Conversion	Shift Up	ConvertPrevPage
Conversion	Space	ConvertNext
Conversion	Tab	PredictAndConvert
Conversion	Up	ConvertPrev
DirectInput	Ctrl Shift r	Reconvert
Precomposition	Backspace	Revert
Precomposition	Ctrl Backspace	Undo
Precomposition	Ctrl Eisu	ToggleAlphanumericMode
Precomposition	Ctrl Shift r	Reconvert
Precomposition	Eisu	ToggleAlphanumericMode
Precomposition	Shift Space	InsertAlternateSpace
Precomposition	Space	InsertSpace
Suggestion	Ctrl n	PredictAndConvert
Suggestion	Down	PredictAndConvert
Suggestion	Shift Enter	CommitFirstSuggestion
DirectInput	Escape	CancelAndIMEOff
Precomposition	Escape	CancelAndIMEOff
Composition	Escape	CancelAndIMEOff
Conversion	Escape	CancelAndIMEOff
Suggestion	Escape	CancelAndIMEOff
Prediction	Escape	CancelAndIMEOff
Composition	Hankaku/Zenkaku	IMEOff
Composition	Kanji	IMEOff
Composition	OFF	IMEOff
Composition	ON	IMEOn
Conversion	Hankaku/Zenkaku	IMEOff
Conversion	Kanji	IMEOff
Conversion	OFF	IMEOff
Conversion	ON	IMEOn
DirectInput	Hankaku/Zenkaku	IMEOn
DirectInput	Kanji	IMEOn
DirectInput	ON	IMEOn
Precomposition	Hankaku/Zenkaku	IMEOff
Precomposition	Kanji	IMEOff
Precomposition	OFF	IMEOff
Precomposition	ON	IMEOn
カテゴリー: 日記 タグ:

twitter日本語ハッシュタグの対応

2011 年 7 月 13 日 このエントリーをはてなブックマークに追加 コメント 17 件

Twitterブログ: #日本語ハッシュタグ
こちらの対応。

以前はハッシュタグの対応に正規表現を利用していたかと思いますが、最近はstatusからハッシュタグ情報がとれます。
GET statuses/show/:id | Twitter Developers
include_entities=trueでhashtagsがとれてその中にハッシュタグ情報が。

APIのバグかと思われますが、「ー」で終了しているタグがhashtagsにはいってきません。
api.twitter.com/1/statuses/show/90961863306772481.xml?include_entities=true
バグレポートすればそのうち直るのかな。

searchAPIにはそもそもハッシュタグ情報が含まれないので現状では解決策なし。
GET search | Twitter Developers

カテゴリー: 日記 タグ:

Androidでtwitter4jを利用してOAuth認証(ブラウザ)

他のIntentから遷移し、URL表示しないブラウザを立ち上げ認証したらhogehoge。

public class OAuthActivity extends Activity {
    final private String CONSUMER_KEY = "xxxxxx";
    final private String CONSUMER_SECRET = "xxxxxx";

    private String CALLBACK_URL = "myapp://oauth";
    private OAuthAuthorization oauth;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WebView webview = new WebView(this);
        setContentView(webview);

        Configuration config = new ConfigurationBuilder().build();
        oauth = new OAuthAuthorization(config);
        oauth.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        oauth.setOAuthAccessToken(null);
        try {
            String url = oauth.getOAuthRequestToken(CALLBACK_URL).getAuthorizeURL();
            webview.loadUrl(url);
        } catch (TwitterException e) {
            Toast.makeText(this, R.string.twitter_failed, Toast.LENGTH_LONG).show();
            finish();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        Uri uri = intent.getData();
        if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
            String verifier = uri.getQueryParameter("oauth_verifier");
            try {
                AccessToken at = oauth.getOAuthAccessToken(verifier);
                Log.d(getLocalClassName(), "screen_name = " + at.getScreenName());
                Log.d(getLocalClassName(), "access_token = " + at.getToken());
                Log.d(getLocalClassName(), "access_token_secret = " + at.getTokenSecret());
                // hogehoge
                Toast.makeText(this, R.string.twitter_login_success, Toast.LENGTH_LONG).show();
                finish();
            } catch (Exception e) {
                Log.w(getLocalClassName(), e.getMessage());
                Toast.makeText(this, R.string.twitter_login_failed, Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }
}

AndroidManifest.xml該当箇所。
lunchModeで多重起動させない。
あとヒストリー残さない。
ブラウザから「myapp://oauth」でIntentが起動するように。

        <activity
            android:name=".OAuthActivity"
            android:launchMode="singleTask"
            android:noHistory="true"
            >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="myapp" android:host="oauth" />
            </intent-filter>
        </activity>
カテゴリー: android タグ: , , ,

Mac OS XにPEARのインストール

Mac OS XにPEARのインストール – ぱんぴーまっしぐら
うまく行かなくなってたので。

$ curl -O http://pear.php.net/go-pear.phar
$ php go-pear.phar

パイプでつなぐとreadlineがうまくいかないので別で実行。
ユーザー環境にインストールしようとするのでそのままEnter

~/pear/bin/pear help
カテゴリー: php タグ: ,

Androidで画像を選択し、画像を切り抜く(クロップ)するサンプル

layoutはボタン置いてあるだけなので省略。
ボタンクリック>ギャラリーから画像選択>クロップ>なんかするhogehoge。
クロップ後のサイズ(outputX、outputY)が大きすぎるとエラーでて利用できない。
壁紙サイズは無理。

package com.example.crop;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

    final private int REQUEST_CODE_GALLERY = 10;
    final private int REQUEST_CODE_CROP = 11;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button button_background = (Button)findViewById(R.id.button_background);
        button_background.setOnClickListener(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
            case REQUEST_CODE_GALLERY:
                Intent intent = new Intent("com.android.camera.action.CROP");
                intent.setData(data.getData());
                intent.putExtra("outputX", 48);
                intent.putExtra("outputY", 48);
                intent.putExtra("aspectX", 1);
                intent.putExtra("aspectY", 1);
                intent.putExtra("scale", true);
                intent.putExtra("return-data", true);
                startActivityForResult(intent, REQUEST_CODE_CROP);
                break;
            case REQUEST_CODE_CROP:
                Bundle ext = data.getExtras();
                if (ext != null) {
                    Bitmap bitmap = ext.getParcelable("data");
                    // hogehoge
                }
                break;
            }
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button_background:
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(intent, REQUEST_CODE_GALLERY);
            break;
        }
    }
}
カテゴリー: android タグ: