質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Git

Gitはオープンソースの分散バージョン管理システム(DVCS)です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

3474閲覧

gitでコミットを効率よく整理するテクニックありますか?

Chironian

総合スコア23272

Git

Gitはオープンソースの分散バージョン管理システム(DVCS)です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

2グッド

2クリップ

投稿2016/11/30 02:44

編集2016/12/01 02:27

ソースを修正する時、必ずしも1トピックに絞れないと思います。
現トピック対応中に、コーディング規約から外れた記述を見つけて修正した、他のバグを修正した等により、複数のトピックの修正が入り混じってしまいます。

しかし、できるだけ1つのコミットは1つのトピックに限定した方が良いと聞きます。1コミットを1トピックに絞れれば、修正箇所の確認が容易になるので、あまり手間の掛からない場合は対応しておくと好ましいと理解しています。

さて、私の知識の範囲では、冒頭の状態に遭遇した時、トピック毎にコミットを分けるには下記手順しか思いつきません。(トピック毎にブランチを作りmasterへ反映したらブランチを削除することを想定してます。)

  1. 気がついた別トピックの修正を行う前に、現在の修正をスタッシュし、masterへ切り替える
  2. 別トピックの修正をmasterに反映し、コミットする。
  3. masterに現トピックのブランチをリベースする
  4. スタッシュを戻して、作業再開

正直、手間がかかりすぎると感じて、ここまではやっていません。

皆さんは1コミット1トピックを保つための努力をどの程度払ってますか?
また、上記のような面倒な手順を踏まずに1コミット1トピックに整理する良い方法はないでしょうか?


C++プロジェクトをGitHubで公開してます。ある程度1コミットのトピックを絞るよう努力してますが、更に努力するべきか、もう少し手を抜いても良いものか、めどを付けたいです。
バージョン管理ツールを深く使った経験がないため、加減に悩んでいます。


【追記】
どうも整理不足だったようです。すいません。

トピック = ブランチ ∋ コミット というGitHub Flow的な運用を想定しています。
1つのブランチに複数のコミットを含みます。そして、GitHub Flowの解説を見る限り、1つのブランチには1つのトピックしか含まないようです。(1連の修正に複数の異なるトピックを含まない方が好ましいことは理解しています。)
そのための、可能な運用は下記と思います。

  1. 手間が掛かってでも1ブランチ=1トピックへ整理する
  2. 1つのブランチに多少の異なるトピックが入り混じることを妥協する
  3. 手前をかけずに1.をやる方法がある

もし、3.の「手間をかけずにコミットを整理する方法」があれば是非教えてください。

もし、1.の場合、コンフリクトが比較的発生しやすいと思います。新たな別トピックの変更が現在のブランチで既に修正したのと同じ行を修正していたら、ブランチを分ける時にコンフリクトし、ブランチをマージする時に再度コンフリクトする筈です。すごく無駄な作業のように感じます。

2.が現実的な妥協と感じているのですが、3.のテクニックが存在するかもしれないですし、他によい運用があるかもしれません。
実際にGitHub Flowベースで運用されている方がどのようにされているのか、アドバイス頂ければ幸いです。

matobaa, yohhoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

いろんな方針は考えられるとは思いますが、ぱっと思いつくことを書きます。

おっしゃるように

  • 「1つのコミットに入り交じるよりはまし」

なので、まずは、1コミットを1つの意図に限定すべきです。

「2. masterに反映し、コミットする。3. masterに現トピックのブランチをリベース」ということは、トピックに関係なく受け入れられる(global な)変更は、すぐに master に入れたい…ということだと思います。
ブランチを変えると待ち時間があるときもありますし、思考の流れが妨げられるので、ブランチ (A) はそのままで、

  • コミット時に、「本来のトピック(ブランチ A)と関係ないコミット (B)」と分かるように(メッセージの工夫など) しておく

と良いと思います。その次は、git rebase (-i) や、git cherry-pick が使えそうです。

git cherry-pick

落ち着いたとき、履歴の整理をしたくなった時などに、master ブランチを checkout してから、B にあたるコミットを(あれば)どんどん cherry-pick します。場合によっては、git commit --amend でメッセージを書き換えるなどしても良いと思います。
こうすると、master とブランチ A には重複するコミットがありますが、トピックブランチ A を git rebase する際に、cherry-pick したコミットは不要になっているはずですので(既に上流にあるので)、消えるはずです。

git rebase -i

もしくは、整理の際に「過去の履歴の順番を入れ替える」ことができる git rebase -i を使っても良いと思います。
git rebase -i HASH として、HASH には分岐点の1つ親を指定しておきます。その後、コミット群 B は歴史の古い方、本来のトピックのコミットは後ろの方に動かします。そうすると

  • master から、「コーディング規約から外れた記述を見つけて修正」等の、小さい変更のコミット群がまず並び
  • その後に本来のトピックのコミットが並ぶ

状況が達成できます。あとは簡単です。小さい変更のコミット群が終わったところに別名をつけ、git merge (--ff でもよいでしょう) をしてあげれば、git cherry-pick 完了後と似た状態が達成できます。本来のトピック A のコミットはそのあとに続くので、そのまま歴史がつながった状態になります。

複数の意図のコミットが混ざってしまった場合も、git rebase -i で、当該コミットを e あるいは edit をつけてやると、「そのコミットがあったころの状態」に歴史を戻せます。その後 git add -pgit reset を上手に使うと、コミットを分割できます。git rebase --continue で、残りの歴史を再現できます。分割さえできればあとは上記の手順が使えます。
詳しくは git rebase -i で調べるのが一番です。

気分にもよるのですが、自分は、「コミットは分ける」が「いろんな変更が混じってもあまり気にしない」で作業を続け、落ち着いた後で「歴史の順番を改竄して辻褄を合わせる」ということをすることがあります。長い歴史を書き換えるときはコンフリクトが恐ろしいことになる場合があります。前もって git tag でタグ付けしておくか、作業量のブランチで作業することで、いつでも戻れるようにしておくことをお勧めします。

他のトピックブランチ (C) にあった方が良いコミット

本来は別ブランチ (C) にあった方が良いコミット (D) は

  • とりあえずブランチ A で作業を進めてしまい
  • 後で本来のブランチ C で、コミット D をcherry-pick して
  • ブランチ A からはコミット D を消す

と、手間はかかりますが、後でやればよいので、気分的には低減されるかなと思います。

分かりにくいかもしれませんから、気になればコメントしてください。

投稿2016/12/07 13:57

takotakot

総合スコア1111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2016/12/07 14:11

回答、ありがとうございます。 そのまま細かくコミットしておいて、後で整理するのですね。なるほど!! かなり気分的に楽になりそうな感じがします。しばらくそれでやってみます。 ありがとうございました。
guest

0

ベストアンサー

私の会社の場合masterをほとんど触りません。
・masterから開発用ブランチ[develop]を作ります。
・[develop]ブランチから更にブランチを生やして作業する。
・作業が終わると都度developにマージする。

1番左が親分となるdevelopブランチです。
developからブランチを生やすと大体のデータが揃うのでブランチをまたぐといった事がかなり少ないです。

質問意図と違っていたらすみません。。

イメージ説明

投稿2016/12/02 11:26

takamiii_158cm

総合スコア84

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2016/12/02 13:03

回答、ありがとうございます。 1つ教えてください。1つのブランチで作業中に、そのブランチと無関係なバグを見つけた時、そのバグ用にブランチを新たに作りますか? それとも現在のブランチで修正されますか? ケースバイケースとは思いますが、雰囲気的にどんな時にブランチを別に作り、どんな時にそのまま作業する感じでしょうか?(厳密である必要はないです。実際に運用されている雰囲気を知りたいのです。)
takamiii_158cm

2016/12/03 15:14

無関係なバグが案件全体に関わるcssやjsの調整になる時は親分のブランチ【develop】で修正を行います。 他のブランチも最終的にdevelopにマージするものなので、という考え方です。 ブランチと無関係なバグが簡単な修正(css1行書き換えるだけとか)でしたら、現在のブランチでそのまま作業をし、コミットメッセージに作業内容を記載します。 うちの会社はコミットメッセージにもルールを決めています。 バックログと連携させているので バックログ課題NO / 案件名 / 作業内容 / 修正内容 という感じです。 例) 課題1458 / ユニクロ冬キャン / 下層ページガワ作成 / 文言挿入 ここのコミットメッセージに バグ修正 などと記載してコミットしています。 何かの参考になりましたら幸いでございます。。
Chironian

2016/12/03 15:50

たいへん参考になります。ありがとうございます。 「大規模」なバグはdevelopを修正し、「小規模」なバグは現ブランチで修正すると言うことですね。 納得できました。 何が「大規模」で何か「小規模」なのかはプロジェクトやリーダ、担当者によって判断は異なると思います。この辺は経験を積みつつ自分の方針を固めていこうと思います。 ありがとうございました。
Chironian

2016/12/03 15:53

「大規模」なバグはdevelop(大本のブランチ)で修正し、「小規模」なバグは現ブランチで修正するということですね。なるほどです。 実際に両者の運用を行っていることをお聞き出来て、たいへん有用でした。ありがとうございます。 「大規模」「小規模」の判断はプロジェクトやリーダ、担当者で異なると思います。私も私自身の方針を経験を積みつつ固めて行きたいと思います。 もう一度、ありがとうございました。
Chironian

2016/12/03 17:56

ぎゃ。2つコメントしてました。1つ目は投稿ボタンを押したら、いつまでも応答が無かったので消えたと思って、再度コメントした次第です。 teratailって作った書き込みを消さないよう頑丈に作られているのですね~。
guest

0

gitコマンドですが、
git add -p
をする事で、コミット対象をインタラクティブに選択する事が出来たはずです。
複数の項目を修正したとしても、これでcommitを小分けにすることが可能かと思います。

投稿2016/11/30 05:28

dohq

総合スコア232

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2016/11/30 06:11

回答ありがとうございます。 なるほど。それでしたらスタッシュして修正してコミット後にスタッシュを戻せば簡単そうですね。 でも、既に現トピックをコミットしていると、途中で無関係なコミットが割り込んでしまいます。 それも避けた方が良いように感じてますが、1つのコミットに入り交じるよりはましですね。 う~ん、実際に運用されている方はどのようにされているのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問