SourceTreeのGit-Flow機能は納得の行かない動作をする
公開日 更新日 2016/02/12
以前、こちらの記事(WindowsへGitとSourceTreeのインストール&セットアップ)にて、GUI画面でのGitソースツリー管理ができるSourceTreeをセットアップしました。
しばらくは問題なく使えていたのですが、その後使い慣れてみるとどうしても納得のいかない動作をする点が気になりだしました。
どうにかならないのかとWEB検索をしていたのですが、結局回避方法がないという結論になりましたので、一度整理しておこうかと思います。
Contents
Git-Flowについておさらい
Git-Flowは開発ブランチの規則についての成功事例を体系的にまとめたパターン。
Git-Flowに従ってブランチを作っていくと失敗という失敗がなく、というかごくごく当たり前の使い方を定形動作する機能にまとめたものです。
独自にブランチの使い方を考えても、結果としてGit-Flowと大体同じ形に落ち着くだろうと思われるので、素直に取り入れておくべきものでしょう。
最近経験した感じでは、とりあえず導入して様子を見るというだけでも十分効果が出せるため、そのままGit-Flowが馴染んでいくというお試し的な使い方で良いのだと思います。
Git-Flowについては、見えないチカラさんのA successful Git branching model を翻訳しました、にある翻訳記事が一番参考になります。
SourceTreeのGit-Flow機能について
Git-Flowというのは、ブランチの作り方をまとめた手順のようなものなので、Gitのコマンドを駆使してあげないといけなかったりします。
それほど難しいことはしていないとは言え、コマンド誤りにより取り返しの付かない履歴が残ってしまうという点では、普段あまり使わないのであれば、極力失敗しにくいやり方にしたいものです。
そこで、GUI上でマウスを活用しながらGit-Flowの操作としてブランチ名やブランチ削除の一連の操作を一貫して規定した機能として提供できるようにしたのがSourceTreeのGit-Flow機能だったりします。
Git-Flow専用のボタンが用意され、直感的に操作できているのでやり過ぎじゃないかと思えるぐらいいたれりつくせりな感じ。
問題点
SourceTreeのGit-Flow機能を覚えればもう何も覚えることはないとさえ思えたのですが、残念ながら1点どうしても納得のできない動作をするため、使用を断念せざるを得ませんでした。
問題と思ったのは次のようなケースでマージするときのSourceTreeの動作です。
- featureブランチをdevelopへマージする場合
- 開いているfeatureブランチが1つだけだった場合
- GUIダイアログでリベースせず、新規マージとして設定した
3点目のリベースしない設定というのがポイントで、上記の条件でマージするケースだと本来マージ時にdevelopブランチとは別にfeatureブランチの痕跡とわかるマージ線が残らないといけません。
これはA successful Git branching model を翻訳しましたによると、次のように記載のある部分です。
開発済みの機能を develop ブランチに取り込む
–no-ff フラグは、たとえマージがfast-forwardで実行できるとしても、新しいコミットオブジェクトを作成する。
これは、履歴にフィーチャーブランチが存在したという情報を失うのを避けるのと、機能の追加に使った全てのコミットをひとまとめにしておける。
しかしながら、SourceTreeでリベースしない設定でマージした場合、プレビューではマージ線が残っているのに、マージ後の結果は、残念ながらリベースされマージ線は破棄されてしまいます…。
Gitのデフォルト動作を–no-ffにしても結果は変わらず
Gitには最近デフォルト動作をリベースしないように出来るようになったそうです。
以下の設定をしておくと、すべてマージ線が生きるようにマージできるとのこと。
1 |
git config --global merge.ff false |
これをSourceTreeの組み込みgitに対して設定してみましたが、これでもまだ依然としてSourceTreeからのfeatureブランチのマージはリベースされてしまいました。
.git/configファイルのオプションを設定しても結果は変わらず
.git/configにて以下のように設定してみましたがやはりリベースされてしまいます。
もしかしてこちらは定義方法が悪いだけかも?
1 2 3 4 |
[branch "develop"] mergeoptions = --no-ff [branch] autosetuprebase = never |
SourceTreeの動作を調査して原因を推定
SourceTreeはオープンソースではないのですが、WEBを検索してみたところ以下の記事が参考になります。
– Question –
For what I’ve learn about git-flow, when someone finish a feature (or a hotfix, is the same), git flow should be merge the feature branch into develop (and also into master in case of hotfix branch) using –no-ff options.
Using git-flow with SourceTree (all version, Windows and Mac), this does not happen.– Answer –
This is actually what standard git-flow does – if there are no commits on the develop branch since the feature was started, it does not use the –no-ff option. SourceTree is just calling the git-flow script and this has been its behaviour for a long time.A few people have expressed that they don’t like this, and I think at least one person has forked git-flow to change this behaviour, so far we’ve stuck to the stock version. This is the code in the git-flow scripts that makes the choice:
12345 if [ "$(git rev-list -n2 "$DEVELOP_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; thengit merge --ff "$BRANCH"elsegit merge --no-ff "$BRANCH"fi
このやりとりから、SourceTreeのGit-Flow機能ではdevelopブランチからfeatureブランチ開始後に、コミットが他になかった場合にリベースされてしまうとのこと。
後続に記載のシェルの記載から、マージ対象のリビジョンが1個だったら–ffが指定されてます。
内部の実装なのであくまで推測ではありますが、ここで引用されたシェルを見た感じでは、グローバルオプションでデフォルト値を指定したところで、引数の–ffが優先されたということでしょう。
ちなみにこのシェル表記のキーワードを適当にかいつまんでさらに検索してみると、GitHubのgitflowプロジェクトに行き着きました。
おそらく元となったプロジェクトのもともとのソースコードでもこういう実装であり、gitflowってリベースされる場合があったということですね。
個人的にはコミットされた修正がブランチで作業されたものであれば、必ずブランチとして記録してほしいので、現行ブランチが1つだけだったとしてもユーザーが記録を残したいという指示をした(–no-ffの動作を指定した)のであればそのように動いて欲しいと思ってます・・・。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# merge into BASE git_do checkout "$DEVELOP_BRANCH" if [ "$(git rev-list -n2 "$DEVELOP_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then git_do merge --ff "$BRANCH" else if noflag squash; then git_do merge --no-ff "$BRANCH" else git_do merge --squash "$BRANCH" git_do commit git_do merge "$BRANCH" fi fi |
WEB界隈で提案されている回避策
このSourceTreeにおけるGit-Flowのシェルの動作を何とかして、–no-ffにならないかと考えてみましたが、gitflowがインストールされているわけではなく、改ざん対象のファイルは簡単には見つけられませんでした。
そこで、SourceTreeの機能で何とかならないのかと検索してみました。
調べた範囲で出来うるものを次に示したいと思います。
(が、残念ながら代替操作はなさそうな感じです。)
カスタム操作を使う
カスタム操作とは、登録したコマンドに対して引数をコマンド実行時の値によって動的に組み替えて実行できる仕掛けとのこと。
とはいえGit-Flow機能の一部としてみせることは出来ないため、あくまでカスタム操作としての登録となる。
今回の件で言えば、ブランチの作成時にはGit-Flow機能でできるけど、終了時にはメニューバーなどからカスタム操作を選択というチグハグとなるため、違和感がある。
つまりこれは非採用でしょう。
手動でGitコマンドを駆使してgit-flowを実現
ブランチの作成や終了などのGitコマンドを駆使して、git-flowが実現するように運用するという回避。
あくまで回避であってこれが通常動作になるのは、いくらなんでもちょっと無理があるでしょうね。
Gitシェルにgitflowをインストール
もはやSourceTreeでは同しようもないから、SourceTreeを使わずにgitflowを実現するという案。
これは最後の手段なんだと思いますが、他に選択肢がない以上はどうしようもないのでしょうか…。
まとめ
SourceTreeを使ってGit-Flowを実現するために1点どうしても納得できない動作があり、これはどうあがいてもなおせないよ感がします。
もしかしたらSourceTree開発元であるAtlassianにプッシュすればなんとかなるかも??
回避策ではありませんが代替ツールで実現するようです
WEBを調べつくして、回避策がなく現状どうしようもないことはわかったのですが、代替ツールとしてSmartGitを使うとGit-Flowを使えてマージ履歴が残るという、まさに私が求めている使い方ができることがわかりました。
SmartGit導入の記録はこちらの記事にまとめました。
変更暦
- 2014/11/3:初版
- 2014/12/1:代替ツールであるSmartGitの記事への参照を追加。
レスポンシブ広告
関連記事
-
ログインページの表示を自分だけ許可することでセキュリティ確保
WordPressのログインページは、他一般的なWEBサービス同様にURLが固定 …
-
スマホやタブレットからパソコンを起動する
我が家のパソコンはリビングから離れた部屋にあるので、ちょっとした作業をするために …
-
WindowsへGitとSmartGit/Hgのインストール&セットアップ
SourceTreeは綺麗で使いやすかったのですが、Git-Flow機能がどうし …
-
EclipseのGradleプロジェクトでJMockitを使う設定をする
Javaの開発で使うツールと言えば、EclipseとJUNITは絶対にはずすこと …
-
Visual Studio CodeでPHPファイルのフォーマッタを使う
突然ですが、最近Visual Studio Codeを使ってPHPアプリの開発に …
-
WindowsへGitとSourceTreeのインストール&セットアップ
STINGERテンプレートへの独自の修正が多くなってしまったので、変更箇所の目的 …
-
PowerShellスクリプトを動かすための設定
PowerShellは最近のWindowsで追加されたスクリプト言語で、今のWi …
-
GitHubへのWEBサイト作成用Markdown原稿をプレビューする環境をセットアップ
ソースリポジトリ管理サービスで一番有名であるGitHubにアカウントを取得後、G …
-
Android Studioをインストール
せっかくタブレットをゲットしたので、勉強も兼ねてAndroidアプリ開発をはじめ …
- PREV
- Web制作者のためのCSS設計の教科書
- NEXT
- 記事一覧に表示する各記事の抜粋を綺麗に整形表示する
Comment
[…] […]