[GitBucketで学ぶバージョン管理] #09 - 流れを止めないために

前回までで、もしもメンバーと共同で作業しているときにお互いの変更が被ってしまっても協調して変更をマージすることができるというのを勉強しました。これによって、お互いにプロダクトをよりよくしていくことができます。


さて、今回はそれに引き続いてそうした良い流れを止めないためにいくつかtipsのようなものがありますので、それらについてお話ししたいと思います。


流れを止めないために

良い流れを止めてしまう原因として、思い当たるところを挙げていきたいと思います。

  • 変更がされたが連絡されていない、発信・共有がされていない
  • 意図しない変更を共有してしまった
  • 変更の履歴が意図していない内容なので編集したい
  • どの履歴がどの変更なのか簡単にさがしたい
  • 作業には必要だけどリポジトリへ保存したくない

こうしたような場合、解決できないと手間がかかったり大変なことが起きてしまったりします。すると改善するどころか、バージョン管理をしなくなってしまう可能性もあります。えらいことですね。ということで、ひとつずつ見ていきましょう。


変更されたが連絡されていない

本講座ではあなたと架空のメンバー、アギトさんの2名だけです。しかし、前回のような競合はメンバーが多ければ多いほど発生しやすくなります。阿吽(あうん)の呼吸でやっていると、いつしかコミュニケーションを具体的にしなくなったりもするでしょう。そうすると何か大きな変更をしたのに、メンバーによってはそれを取り込んでから変更しなければ適切なバージョン管理とは言えないという状況に陥る場合があります。つまり、変更されたら連絡することができるという仕組みがあるといいですね。


そうした場合は管理者としてGitBucketへログインし、システム設定でメールの設定を行うとプッシュがされたりした場合にメンバーへメールで通知できるようになります。

メールでも気づかない場合もありますので、変更したらメンバーへ声をかけるようにするというアナログな方法も良いでしょう。


意図しない変更を共有してしまった

これも操作ミスで発生することがあります。例えば、前回作成したtest2リポジトリへコミットするはずだったものを誤ってmasterへプッシュしてしまった場合にどうするか、です。こうした場合は1つ前のコミットへ戻すという方法があるでしょう。

git push -f origin HEAD~:master

「-f」オプションは「強制的に」という意味を表すものです。普通にgit pushしたのではエラーになって操作を阻まれてしまうのですが、これをすることで力づくで書き換えをすることができます。ただし、こうした強制力をもった操作はできるだけ最後の手段にしたほうがよいでしょう…「HEAD」というのがブランチの最新を指すキーワードで、「~」記号(チルダ記号)はその1つ前を指しています。ということで、masterブランチの最新より1つ前をoriginへ強制的にアップロードしてしまうというものです。


もしも手元のmasterリポジトリへ意図しない変更が含まれた状態の最新を取り込んでしまっている場合は、ローカルも変更内容を巻き戻す必要があります。

git reset HEAD~

こちらを実行することで最新より1つ前の状態へリセットすることができます。


変更の履歴が意図しない内容なので編集したい

このケースはメッセージが不適切でわかりにくいな、とかこのファイルは含めるべきじゃなかったな、などという場合です。まずはコミットメッセージを修正する方法です。「--amend」オプションをつけるとコミットしたときの内容を修正することができます。

git commit --amend -m "something."

どんな内容をどんな意図で変更したのか、わかりやすく書くのは難しいですね。さらに、git logで履歴を見た時に「あ、このユーザーでコミットするのではなかった」ということもあるでしょう。そういうときには先ほどのオプションに加えて、「--author」もつけましょう。

git commit --amend -m "something." --author="agito <agito@mail.com>"

次はファイルの内容をコミットしなおしたい場合です。こちらはブランチの保存している履歴を1つ巻き戻して、作業フォルダ内のファイルを再度コミットしなおすという方法です。今度は「git reset」を使って1つ前の履歴まで巻き戻すのですが、オプションに「--soft」をつけてコミット対象のファイルが舞台には上がっている状態にします。

git reset --soft HEAD~

これによってさらにファイルへ適切な変更を加えて再度コミットしなおすことができます。ただし、これらの修正は共有されていない段階でのことです。共有済みの場合はメンバーへ影響が発生しますので、コミットする際には後から巻き戻さなくてよいように注意しましょう。


どの履歴がどの変更なのか簡単に探したい

よくあるのが、「あのブランチってもういらないよね」となったときに、本当にそうなのか調べてからにしたい、ということがあるでしょう。あるいは、あのコミットの内容って具体的にはどんなものだったかな?ということもあるでしょう。普通に「git log」したのでは結局「どのリリースのものだったかな」となってしまうことがあると思います。


まずはブランチです。すでにマージされた実験的なブランチは不要になるでしょう。git branchコマンドでマージ済みのものを表示するのであれば、「--merged」をつけます。そうすると、マージ済みのものだけが表示されます。この中から本当に不要なブランチを探して削除するようにしてください。


次に、git logを見るときの話です。コミットごとにユニークな英数字がつけられているのはご存知のとおりでしょう。しかし、それがどういったものなのかはパッと見ただけでは判別がつかないと思います。そうしたときには、そういった英数字に名前を付けてしまうということができます。名前は「タグ」と呼ばれていて、タグをつけるには「git tag」コマンドを実行します。


例えば、前回の最後のマージに「v.1.0」というようにバージョン1を付けるとします。

commit 5628d8064921016e4cf6e04ee2e06238c2f86308
Merge: ed1a810 47bf312
Author: nalulabo <nalu.labo@gmail.com>

Date: Mon Mar 7 13:20:34 2016 +0900

Merge pull request #2 from nalulabo/test2

アギトさんの修正を取り込んでHTMLを改善しました

このとき、英数字を使ってタグをつけるには次のようにします。

git tag v.1.0 5628d8064921016e4cf6e04ee2e06238c2f86308

こうすると、履歴に名前が付きます。このタグがどんな変更だったかを見るには次のようにコマンドを実行します。

git show v.1.0

すると、タグ名がついた履歴が表示されます。

tag v.1.0
Tagger: m0t0k1 <motoki8791@gmail.com>
Date: Mon Mar 7 15:41:49 2016 +0900

v.1.0

commit 5628d8064921016e4cf6e04ee2e06238c2f86308

Merge: ed1a810 47bf312

Author: nalulabo <nalu.labo@gmail.com>

Date: Mon Mar 7 13:20:34 2016 +0900

Merge pull request #2 from nalulabo/test2

アギトさんの修正を取り込んでHTMLを改善しました

これであとから見直したときに「バージョン1の変更はこんな感じか」と見ることができます。


作業には必要だけどリポジトリへ保存したくない

はじめからリポジトリには保存したくないけど、作業用に必要なファイルを置いておきたいということもあるでしょう。そうした場合には「.git」フォルダがある同じフォルダ内へ「.gitignore」ファイルを作成すると、リポジトリへ含めたくないファイルを指定することができます。


たとえば、一時的に使用するようなフォルダとして「temp」といったようなものをつくって、この中へ作業のときに利用するリポジトリとは直接関係のないファイルをすべて入れておくとします。そういうときには「.gitigore」ファイルへ次のように記載すればコミットするとき、あるいは舞台へあげるときにも無視してくれるようになります。

temp/*

このほかにも、ファイル単位で指定することや、拡張子で指定することもできます。

*.pdf
.DS_STORE

こうすることで余計なファイルをリポジトリへ保存しなくて済みます。


また、舞台へ上げたくないと後から気づいたファイルがあったときには、コミットしていなければファイル単位で舞台から降ろすこともできます。ここでは試しにつくってみた「third.js」というJavaScriptファイルが誤って舞台へあがってしまったとしたときの操作を示しています。

git reset HEAD third.js

これでgit statusすると「Untracked files」として表示されてくると思いますので、舞台から降ろすことができています。なお、同じ操作は次のコマンドでも行うことができます。

git rm --cached third.js


その他の操作

ここまでの操作で、タグ付けしてしまったけど間違ってた!という場合にはタグを削除することができます。タグは削除しても履歴が消えるわけではありません。

git tag -d v.1.0

さらに、これを中央のデータベースへアップロードしてしまっている場合はタグを削除したという情報をアップロードする必要があります。

git push origin :v.1.0

あるいは次のようにします。

git push --delete v.1.0

その他、実験の最中に「本流のブランチで何らかの作業をしなければならない、だけど作業中の状態は残しておきたい!」ということも発生すると思います。その時には一時的に避難することができます。いま「third.js」ファイルをtest2ブランチで作成していたけど、hotfix20160308ブランチで作業をする必要があるとします。まだコミットできるような状態ではありません。そうしたときにはまず舞台に上がっていなければ「git add」します。そして次のコマンドを実行しましょう。

git stash

すると、次のようなメッセージが表示され、作業フォルダ内からつくりかけの「third.js」は消えます。

Saved working directory and index state WIP on test2: 47bf312 resolved the conflict with hotfix20160307
HEAD is now at 47bf312 resolved the conflict with hotfix20160307

この状態は追跡中のファイルを一時的に保管してくれているようになっています。保管されている状態は次のコマンドで見ることができます。

git stash list

このコマンドを実行すると次のようなメッセージが表示されます。

stash@{0}: WIP on test2: 47bf312 resolved the conflict with hotfix20160307

つまり先ほどの変更途中の状態は「stash@{0}」へ補完されているということです。これを他の作業が終了して作業フォルダへ戻すには次のようにすれば戻すことができます。ただ、舞台に上がった状態ですので、不要なファイルがあれば舞台から降ろすようにしましょう。

git stash pop

もしもこうした一時退避が複数ある場合は保管されているものを指定して戻します。

git stash pop stash@{0}

どんな内容だったかを確認するのであれば、「git stash show」を利用してください。

git stash show stash@{0}

変更内容まで確認する場合はさらに「-p」オプションをつけると差異まで表示してくれます。

git stash show -p stash@{0}

このように出力されます。

diff --git a/third.js b/third.js
new file mode 100644
index 0000000..7fd0004

--- /dev/null

+++ b/third.js

@@ -0,0 +1 @@

+this is third js

\ No newline at end of file


最後に

今回は良い流れを妨げそうな事柄について回避する方法をお話ししてきました。バージョン管理に直接関係がないかもしれませんが、マネジメントしていくうえで必要になってくる雑務も片付けておくことで流れをよりスムーズにすることができます。

もんが(なるーらぼ)

個人でプログラミングの学習サイト「なるーらぼ」を運営しています。
https://nalu-labo.amebaownd.com
PowerShell入門の電子書籍2冊も出版しています。
http://www.amazon.co.jp/dp/B017LJOCJ2

なるーらぼ

ごく自然にプログラミングを楽しむことができる世界をつくるお手伝いをしています

0コメント

  • 1000 / 1000