Programming」カテゴリーアーカイブ

Gitでコンフリクトを起こしたくなくて

Gitは分散型バージョン管理システムなので、
ソースコードの同じような箇所を複数の人が修正したら当然コンフリクトが発生する。

コンフリクトを回避するにはマージツールなどを使えばいいんだけど、正直やりたくないのが本音だ。
他人のソースを理解し、そのように採用するか、その作業は思ったより負担になることが多い。
俺の技術不足?それはその通りだ。
でも、それを嘆いてもソースが読めるようになるわけではない。
そこで、コンフリクトを極力起こさないように、ある方法を用いている。

それは非常に単純で、「新規追加機能やクラスは極力別ファイルにする」というものだ。
ファイルが違えば、コンフリクトなど起き得ない。
それに、クラスを別ファイルにすることで、ソース全体への視認性も向上する。

勿論、ソースを見て、ファイルを分けるべきでないなら、分けてはならない。
あくまでTipsなので、それで全体が振り回されるのはいけない。

あ、言うまでもないけど、こんなことしなくてもコンフリクトの原因をすぐに理解し、その修正をすぐに行える人はこんなことすべきでないと思います。
初戦は自分の未熟さをカバーするための回避策です。

なんだこの内容の無さ。

GitHubとBitbucket

世の中ソーシャルコーディングの時代なのか、Gitレポジトリのホスティングサービスが主流になっている。

有名なのはご存知GitHubだが、もう一つ代表的なのにBitbucketがある。
両者ともGitを扱い、PullRequestがあったりと基本的な機能は同じだが、絶対的に違う点がいくつかある。
1)プライベートレポジトリの作成
GitHubは無料プランである限り、プライベートレポジトリは作成できず、常に全世界公開状態ですが、Bitbucketは対照的で、無料プランでもプライベートレポジトリが作成可能です。
ただし、レポジトリにアクセスできるユーザーは最大で5人までという条件があります。
つまり、Bitbucketは大人数での開発には向きません。
個人や少人数で、かつあまり見られたくない開発作業にはドンピシャリです。
2)日本語化
GitHubは完全に英語ですが、Bitbucketは日本語にも対応しています。
多少怪しい日本語ではありますが、誤解が生じないレベルで理解できるので、我らが英語の出来ない日本人には安心感があります。
ただ、一部の日本語が文字化けします。例えばコミットメッセージでよく「実装」という言葉を使っているのですが、これが「実�」と化けます。
まぁ正直、違いは1)に集約される。
SNS的側面を併せ持つGitHubと、あくまでレポジトリのホスティングサービスに徹するBitbucketといったところか。
で、これの使い分けだけど、僕は基本的にはGitHubを使い、見られては行けないコードが含まれているもの(何かのAPIのキーをベタ書きしているコードとか)はBitbucketを使うようにしている。
一時期は全部Bitbucketでやってたんだけど、「人に見られることがない」と思うと平気で汚くてその場しのぎのコードだらけになるんだよね。
GitHubに置いても誰かが見に来ることなんて無いんだけど、「見られる可能性がある」という事実だけで、良いコードを書こうとする意識が働く。
そういうところにこそ、GitHubを使う本当の意味があったりするのかな、と最近思う。
(大体、個人で使うならバージョン管理だけをすればいいから、Gitだけで十分のはずだ)
後、「GitHubを使うとなんかカッコイイ」「GitHubを使っていると、今時のプログラマって感じがする」、という、ミーハーな理由もある。
プログラマでこの先もやっていくとは思えないけどね。
早く帰国して公務員になりたい。

全角半角を区別せずに文字列を比較する。

Dictionary<string,object>のキーについて、ある文字列と全角半角を無視して比較を行おうとしていた。
最初は
Dictionary<string,object> dic=new Dictionary<string,object>(StringComparer.CurrentCultureIgnoreCase);
と設定すればいけるだろうと考えていたが、これでは全角半角は区別してしまうみたいだ。
他のCultureでも同様だ。

仕方ないので、以下のようにやった。

もっと良いやり方があるような気がするのだけど。

DataTableの特定の行を別のDataTableに格納する。

「DataTableのある特定の行を抽出し、その結果を格納したDataTableを作る」という操作が必要になった。

何も悩む所は無いと思ったのだが、意外と何回も失敗し、最終的にカンニングをしたので、備忘録として書き記す。

つまり、DataRowはDataTableに所属するオブジェクトなので、
違うDataTableに追加するには全く新しい行を作成して追加しなくてはいけないということ。

もっとスマートにできないのかな。
わざわざSelectしたものをさらにDataTableにするというのがそもそもスマートじゃないのかもしれない。

git rebaseでコミット履歴を修正する

前回メモしたIssueからPullRequestを作成するをワークフローに入れるとある問題が生じる。

それは、空のコミットを作成しているせいで、そのPullRequestをMasterブランチにマージした場合、masterブランチに余計な空コミットが作成されてしまうという点だ。

正直言って、僕は「それでもいいじゃん、変更が追いにくくなるわけでもないし」という考えをしてしまうのだが、会社では可能な限りコミットは綺麗にする方針なので、コミットを修正する方針をとっている。
この変更なのだが、vimが使えないと辛い。
ネットで調べても「vim?使えて当然だろ」と言わんばかりの資料ばかり。
知らないのが悪い、自分で解決しろ、というプログラマのこういうところが嫌だ。
(自分の向上心のなさを棚に上げる)

とりあえず、仕事で使っている最低限のコミット修正、rebaseの使い方を書いていく。


1)commitを行い、pushできる状態にしておく

2)ログを確認し、どのコミットを修正したいか確認する

ex)今回は3番目のfixというコミットを、2番目のwriteというコミットに統合させることを目的とします

3)rebaseコマンドを打ち込む

  • git rebase -i HEAD~(戻る分のコミット数)
  • ex)git rebase -i HEAD~2

4)採用する修正(=最新の修正)のpickをfixupに書き換える

rebaseコマンドを行った途端こんな画面に。
入力する前にキーボードでiを押して入力モードにする。
今回はfixというコミットを採用するので、fixの行をpickからfixupに変更する。
入力したらescキーを押し、コマンドモードに戻る。

5)編集を完了させる

  • コマンドモードで”:wq“と打ち、Enterを押す

6)成功したかgit logで確認

成功。コミットが2つになっている。
“create”コミットの内容は編集前の”create”と”fix”を合わせたものになっている。
リネームが必要な場合は後述参照。

7)成功してれば、pushする。ただし、コミットの書き換えで競合が起こるので、強制pushする

  • git push origin +”ブランチ名”

僕のワークフローでは6)の後、もう一回rebaseでコミット名の修正をしています。
コミット名の修正は”pick”を”reword”として編集完了すればリネーム画面が開かれます。

vim触ったことなかったんだけどメリットが分からない。
どうも、PC初心者です。

IssueからPullRequestを作成する

hubコマンドで僕が一番使うのがIssueをPullRequestに変更するコマンド。

(っていうかこれしか使わない。極力複雑なことは便利であってもしたくないのです)

理由は仕事でのワークフローがIssueごとにPullRequestを作成して、
レビューを貰ってマージするという方式だから。
正直Issueいらないんじゃないかなって思ってる。
このコマンド、将来的には無くなるらしい。
けど今は使っているので、使い方をメモしておく。

1)PullRequest用のブランチを作成する
  • git checkout -b "ブランチ名"
2)PullRequest作成のためにコミットが必要なので、空のコミットを行う
  • git commit --allow-empty -m "コミットのメッセージ"
3)リモートレポジトリ(ってかGitHub)上にpushする
  • git push origin "ブランチ名"
4)hubコマンドでissueを現ブランチから作成されたPullRequestに変更する
  • hub pull-request -i "Issue番号" -b "ベースにするブランチ名"

以上。
4)の”-b”をずっと”branch”だと勘違いしていた。
“base”の意味だそうです。
2)が必要だったり、このワークフローあまりよくない気がするな。

手元に資料がない状態で書いてるので間違ってるところがあるかも。
資料見て間違ってたら修正します。


追記20140515
2)のコマンドが間違っていたので修正。

追記20140517
言うまでもありませんが、既に変更が加わっている場合はわざわざ2)をする必要はありません。
普通にコミットしてください。
自分のワークフローでは「作業前にプルリクエストを作成する」というルールがあるので、
作業前に空コミットを作成してプルリクエスト作成可能状態にしているのです。

DataTableのFindメソッド

仕事上、.NetのDataTableをよく触る。
主キーが設定されている場合はFindメソッドさんを使えば目的の行を取り出せる。

上記は主キーが”5″である行を取得している。

で、このFindメソッドだけど、どうやら引数の末尾のスペースは考慮しないらしい。
つまり、
dt.Rows.Find(“5”)と
dt.Rows.Find(“5 “)
は同じ結果になってしまう。
回避方法は今のところ不明。
DatatableのSelectメソッドも同様でした。
DataTableの情報には末尾空白のものを持たさないように工夫すべきなのかな。

今日の仕事でここで一瞬詰まった。
コード眺めると何の問題もなさそうだし。
デバッグしたらすぐにおかしいことに気がついたけど、
これは実装中は気付かないなぁ。

調べてみたけどあんまり文献がなかった。常識なのかな。
そういえばSQLのwhere句でも似たようなことがあった気がする。
あんまり覚えていないけど。

Rubyとか知らないけどHubコマンドを導入する方法

GitHubのプルリクエストの作成とか、そういうものをGitBashやコマンドラインからできる凄いやつ、
それがhubコマンドです。
GitHub社製です。

で、こやつはRubyで作られてるらしいんだけど、僕Ruby触ったことないヘボだからよくわからなかった。
試行錯誤して何とか導入したので、とりあえず何をやったかメモ。
絶対に最適方法じゃないけど、「Rubyとか何やねん。Hubコマンド入れたらもうそれでいいねん」という僕と同じ境遇の人の何かの助けになれば。


・前提

  • Windows8.1,Rubyを導入していない
  • GitやGitHubの基本的な作業はできる

1)Rubyのダウンロードページ(https://www.ruby-lang.org/ja/downloads/)に行き、画面最下部の”RubyInstaller”をクリックする。

2)Downloadをクリック

3)RubyInstallersで最新のものをクリックしてダウンロード

  • 2014/05/12時点ではRuby 2.0.0-p481でした。64ビットのやつでも別になんでもいいと思う。

4)インストーラに促されるがままRubyをインストール

  • 途中で3つチェックボックスがある。どっちでもいいと思うけど僕は全部にチェック入れた。
5)インストールできたら続いてhubレポジトリへ(https://github.com/github/hub)
6)hubコマンドレポジトリをローカルにクローンする
  • git clone git@github.com:github/hub.git
7)クローンしたディレクトリに移動し、gem install hubを実行
  • cd hub
  • gem install hub
8)”Successfully installed hub”みたいな画面が出れば完了

以上です。
ちなみに今回はgem install hubでインストールしましたが、これは推奨されない方法です。
他のインストール方法はhttps://github.com/github/hubのREADME.mdに載っています。
ただ、僕はPCリテラシーやRuby知識が「rake?何やこいつ」状態(かつ、調べる時間もなかった)ので、何とかインストールできたこの方法を用いました。
推奨されない方法ですが。
Rubyもやろうって思ってたんだよなぁ。
思ってからもう半年過ぎた。

Githubのissueは削除できない

タイトルの通り、GitHubのissueって削除できないのね。
変なissue作ると永遠に残るという鬼畜仕様。

仕事用アカウントで個人プロジェクトにissue登録しちゃって、それが「Repositories contributed to」にでてきてしまい、仕事用アカウントから個人アカウントがバレるという状態。

バレてもいいんだけど、会社の人に趣味でやってるコードに口出しされたくないんだよなぁ。
向上心?知らん。
【教訓】
会社では業務プロジェクトしか触らないようにする(当たり前)

github作業の一連プロセス

仕事でgithubを使うことになったので使い方のメモ


・前提
github上に目的のレポジトリが既に存在している。
gitやSSH等の設定済

1)レポジトリをローカルにクローンする

  • git clone <リモートレポジトリ>
2)ブランチを作成する場合は作成する
  • git branch -b <ブランチ名>
3)作業終了後、gitの追跡対象になっていないファイルを追跡対象にする
  • git add –all
  • (–allとすることで現在のディレクトリ全てをaddできる)
  • (“git add .“でも良いが、これは削除ファイルに対応していないので、”git rm <ファイル名>“が必要になる場合がある。細かいことを設定しないなら–allの方が楽)
4)コミットする
  • git commit -m <コメント>
5)リモートレポジトリにプッシュする
  • git push
  • (ローカルでブランチを作成した場合は以下のようにする)
  • git push origin <ブランチ名>

以上。
ところどころでgit statusしてちゃんと操作出来てるか確認するとミスを減らせる。
gitって思ったよりちゃんとメッセージ表示してるのね。
失敗した時はググる前にちゃんとメッセージ読むとgitへの理解が深まるかもって思ったり。