コミット間の待機時間が長すぎる場合はどうすればよいですか?


100

私はいたずらだった...あまりにも多くの「カウボーイコーディング」、十分なコミット。さて、ここで私は多大なコミットをしています。はい、ずっとコミットしていたはずですが、今は遅すぎます。

何が良いですか?

  1. 私が変更したすべてのものをリストする1つの非常に大きなコミットを行う
  2. ファイルには複数の修正、変更、追加のメソッド名などがあるため、コンパイルできない可能性のある小さなコミットに分割してみてください
  3. 適切なコミットのためだけにファイルの部分的な復元を行ってから、新しい変更を元に戻します。

注:現時点では、このプロジェクトに取り組んでいる唯一のプログラマーです。少なくともより多くのプログラマを雇うまで、これらのコミットコメントのいずれかを見るのは私だけです。

ところで:私はSVNとSubclipseを使用しています。これらの変更を行う前に、新しいブランチを作成しました。

詳細:そもそもどうやってこの状況に陥ったのかということに関して、別の質問をしました。アプリケーションの接着剤を書き換える準備をする方法


2
どのバージョン管理プログラムを使用していますか?多くのモジュールには、編集を「ハンク」に分割できるモジュール、つまり変更された行のグループがあり、任意の方法で編集をグループ化し、1つのファイルのmodを複数の変更セットに配布できます。たとえば、mercurialには「shelve」という拡張子が付いています。もちろん、プロセスにとって重要な場合は、変更の各バッチがコンパイルされるかどうかを確認する必要があります。トラブルに見合うだけの価値があるかどうかは、あなたとあなたの店次第です。
アレクシス

6
少なくともブランチでチェックインするので、変更を失うことはありません。
ロリーハンター14

2
質問をし続け、さらに長く待つか、実際にコミットして、作成する混乱に対処することができます...そして...再びしないでください!
ヘイレム14

40
#1、許しを祈り、それから出て行って罪を犯さないように:)
ペテロ14

5
あなた自身に問うべきより重要な質問は、「これが再び起こるのを防ぐために、どうすれば悪い習慣を変えることができるか」です。少なくとも1日に1回、より頻繁にコミットする理由はないはずです。
ドックブラウン14

回答:


52

回答するには、これらのコミットの結果を将来どのように使用するかを自問する必要があります。最も一般的な理由は次のとおりです。

  • バグが導入されたリリースを確認するには。
  • 特定のコード行が存在する理由を確認します。
  • 別のブランチにマージします。
  • 顧客またはテスターがそのバージョンで見ている問題のトラブルシューティングのために以前のバージョンをチェックアウトできるようにするため。
  • 特定のパーツをリリースに含めたり除外したりできるようにするため。

最初の2つの理由は、変更されたコードの各行に等しく適用されるチェックインメッセージを作成できると仮定すると、1回の大きなチェックインでも同様に処理できます。あなたが唯一のプログラマである場合、小さなコミットでマージが簡単になるわけではありません。未提出の変更の一部のみでリリースまたはテストを行う予定がない場合、最後の2つの理由は当てはまりません。

小さなコミットを行う理由は他にもありますが、それは変更の途中であり、その時間が過ぎているためです。これらの理由は、間違いや実験的な変更をバックアウトしやすくし、大きな恐ろしいマージをせずに同僚と同期しやすくすることです。

あなたが説明したあなたの状況の私の理解から、この時点であなたのコミットを分割することはほとんどまたはまったく利益がないようです。


素晴らしい答えです!小規模なコミットを行わなかったことについて後悔はしていませんが、良い生産性を可能な限り生産的に戻すために何をすべきかについては、ずっと良いと感じています。
durron597 14

1
3と5についての他のことは、それらを実現するために現在行う作業は、実際に必要になるまで待ってから同じ作業を行うことができるということです。あなたがしたことの記憶がなくなっているので、おそらく将来的にはいくらか難しくなるでしょう。しかし、再び、あなたはおそらくそれを必要としないでしょう。
スティーブジェソップ14年

私の経験では、バージョン管理コメントに頼ってコードが存在する理由(つまり、理由1と2)を伝えるのは面倒で壊れやすいです。ブランチでSVNを使用している場合、とにかく、コミット履歴はマージ時に失われます(gitのような最新のものを使用した方が良いでしょう)。したがって、これらはコメント付きで提供するのが最適です。
ハンスピーターシュトルー

1
@hstoerr-Subversion 1.5以降を使用している場合、マージ時に--reintegrateオプションを使用して履歴を保存できます。
ダスティンケンドール14年

1
ここではgit add -pがあなたの親友です。私はその機能に夢中になりました。このようにして、コーディング標準の変更を別々のコミットでコミットし、関連するコードの変更を隔離したままにすることができます。
スパイディー14

39

何をするにしても、コンパイルできないことがわかっているコードのチェックインを避けるようにしてください。

3番目のオプションが実行可能だと思う場合、コミットのシーケンスがコンパイルできないシステムを作成しないことを保証できる限り、それはそれを行う良い方法かもしれません。それ以外の場合は、1つの大きなコミットを実行します。いですが、簡単で迅速で、完了します。今後、より頻繁コミットします


オプション3は可能ですが、非常に時間がかかります。オプション1
durron597 14

3
機能ブランチ(または同様のもの)でコンパイルまたはビルドさないコードをコミットすることのマイナス面は何ですか?私は本当にひどいコミットが他の人によって回避されると想像しますが、それが最初にそれらを回避する唯一の本当の理由です(もちろん、コミットがリリースされていないことを前提としています)。
ケニーエビット14

3
「コンパイルされませんコードをチェックイン避ける」のみ共有コードベース/ブランチに適用されます。ワンマンプロジェクトまたはワンマン開発ブランチでは、変更をVCに取り込むだけで、物が失われないようにすることがより重要だと主張します。
スティーブンC 14

3
たとえば、@ StephenCは、git-bisectなどのツールを破壊するためです。コードが常にコンパイル/実行され、常にコンパイルされる場合は回帰を見つける必要がある場合は、バイナリ検索を行うことができます(コードのチャンクに回帰がある場合は、狭めるのではなく読むために大きな変更が残っていることは言及していませんダウン)。
マチェイピエチョトカ14

@MaciejPiechotka-プライベートブランチで特定のツールを使用する必要があり、コードをコンパイルする必要がある場合は、そうする必要があるのは明らかです。しかし、それは1人のプロジェクト/ブランチでは一般的ではありません。
スティーブンC

19

頻繁に、小さく、意味のあるコミットを行う最も重要な理由は、コードの履歴の理解を支援することです。特に、理解できる差分を生成することが難しい場合、コードがどのように変更されたかを理解することは非常に困難です。

オプション1は、行った変更の履歴を難読化しますが、それ以外の場合は問題は発生しません。

オプション2は、行った変更の履歴を難読化しますが、オプション1よりも多少小さいかもしれませんが、コミットが明確であると仮定または結論付けた場合、他の問題を引き起こす可能性があります。これがオプション1よりも好まれる強い実用的な理由がない限り、これはそれよりも理想的ではありません。

オプション3は最良であり、他のすべては同等ですが、他の場所で説明したように、「極端な」時間を必要とするか、他の重要なコストが発生する場合、予想される利益とそれらのコストを比較する必要がありますよりクリーンなコミットを作成します。

提供された情報に基づいて、オプション1を選択します。変更をコミットするように促すリマインダーを設定する必要があるかもしれません。

プロトタイピングと書き換え

特に唯一のプログラマーであることについてのあなたのメモと、比較的新しいコードベースで作業しているという私の疑いに照らして、覚えておくべきもう1つの考慮事項は、おそらくあなたが「既存のコードを維持または拡張するのではなく、新しいコードのプロトタイプを作成しています。おそらく、この2つの間にそれほど鋭い区分はありませんが、それでも有用な区別だと思います。

新しいコードのプロトタイプを作成するときは、変更を保存するときはいつでも、ほぼ確実にブランチでコミットしますが、おそらく別のプロジェクトでコミットします。または、バージョン管理の範囲外で作業することもできます。代わりに、検討しているさまざまな仮説または設計の実行可能性に関する証拠の収集に集中できます。C#コードのVisual Studioの代わりにLINQPadなど、さまざまなツールを使用して小さなプロトタイプを作成することがよくあります。

特定の仮説または設計を検証したら、メインプロジェクト、理想的にはブランチでそれを書き直し、変更の性質に関して他の人(将来のあなたを含む)の理解に最も役立つ小さな有意義なコミットを行います。あなたが作っています。


1
いい答えだ; ケニーは、プロトタイピングに関するより具体的な詳細にリンクするための優れた記事やその他の知識ベースを持っていますか?プロトタイピングの私のバージョンは、「ノートブックやホワイトボードにスケッチ」である
durron597

@ durron597、私の頭上にあるリンクを探すことさえできません。十分に解釈された(動的にコンパイルされた)プログラミング言語をいじってみたので、「プロトタイピング」のアイデアは斬新だとは思いもしませんでした!そして、私は非常に多くのC、C ++、およびJavaプログラムを(何度も)書き直したので、それも珍しいとは思わず、少なくとも一部にとっては斬新だとは思わなかった。
ケニーエビット14

12

唯一の合理的な答えは、決してtrunkを壊さないことですが、不可能な場合もあります。たとえば、コミットが多すぎるとsvnがコミットを中断する可能性があります(オプションか機能かどうかはわかりません)。このような特別な場合には、チェックインするだけです。あなたは一人のプログラマーなので、誰も邪魔することはありません。

したがって、オプション1に進みます。不可能な場合は、オプション2を選択します。

オプション3には多くの労力が必要であり、それだけの価値はありません。


1
または、コンパイルしていないバージョンに「コンパイルしない」というタグを付けます
ラチェットフリーク14

2
@ratchetfreak:タグはトランク上の「コメント」として機能しないため、SVNの「タグ」はあまり役に立ちません。
ドックブラウン14

@DocBrownコミットメッセージに追加することを意味
ラチェットフリーク14

5
:@ratchetfreak私は" - doesntのCOMPILE ABCにチェックPART X / N"としてそれを行うだろう
BЈовић

オプション3はそれほど労力を必要としません。もう一つの答えは、使用して迅速かつ容易にそれを行う方法について説明しますgit add --patchgit stash。状況は、時代遅れのソース管理ツールと知識のためだけに困難に思えます。
ロンマクニール14

7

ファイルには複数の修正、変更、追加のメソッド名などがあるため、コンパイルできない可能性のある小さなコミットに分割してみてください

同様の状況に陥ったとき、次の手法を使用しました。

  1. 特定の機能に関連するコードのみを追加します。 git add --patch
  2. 他のすべての変更を隠します: git stash save --keep-index
  3. テストの実行/コンパイルの試行
  4. すべてに問題がない場合は変更をコミットし、そうでない場合は1に進みます

私はSVNに精通していないので、これが特定の状況に当てはまるかどうかはわかりませんが、基本は同じである必要があります-コードの小さな部分を分離し、個別にテストします。


私はこれが好きですが、残念ながら、私のToDoリストにある多くのことの1つ(あなたが会社で唯一の技術者であるときはたくさんあります)はSVNからgitに切り替えることです。 。
durron597 14

1
使用するに--patchは十分なl33tではないため、さまざまなエディターペインで[元に戻す] を使用して、以前の作業状態に移行し、コミットします。その後、次のコミットにやり直します。[元に戻す]状態のときにコードに少し追加する誘惑があるため、このプロセスを開始する前に常にバックアップを作成します。
joeytwiddle

gitを使用すると、コミットの前にインタラクティブに追加(add -i)してから、ブランチを個別に検証することもできます。
リーゼボッシュ14

3

方法4の方法:リポジトリの現在の状態を一時的な場所にバックアップし、リポジトリを元の状態に戻し、行ったすべての変更のリストを作成し(一時バックアップを引き続き確認できます)、手動で再実装(およびコンパイル)そしてテスト!)別々のコミットとして。

これは簡単です。コードをすでに作成しているので、一時バックアップからコピーして貼り付ける部分を把握するのはほんの少しです。

すべての変更をきれいに再実装し、コミットが自己完結型、小規模、およびコンパイルであることを確認したら、一時バックアップを削除できます。すべてが(コミットの時刻/日付を除く)ほぼ正確になります。あなたが最初からそれをやったならそうだったでしょう。


これは、オプション3を実行する方法にすぎません。おそらく最良の方法です、本当ですが、それでもかなり時間がかかります。
durron597 14

1つの大きなコミットを行ったときに、149行のメッセージの追加/削除/送信がありました。これを行うには少なくとも半日かかります。
durron597 14

@ durron597私は同意しません、これは#3とは異なると思います。149行について、クリーンなコミット履歴をどの程度重視していますか?半日過ごす価値はありますか?とにかく、他のメソッドがどの行をどのコミットに入れるべきかを理解する必要がないので、どちらの方法でも149行を調べる必要があります。時間の差はわずかです。
スーパーベスト14

へえ。私はバージョン管理を使用するのに十分な経験がありますが、それを私の尻を救うことができた経験がありません:)
durron597 14

リポジトリ全体をバックアップする必要はありません。「バックアップ」コミットを行い、でHEADをロールバックできgit reset HEAD~ます。git reflog後で必要になった場合でも、コミットはそのままです。リセットを実行する前にブランチを分岐(および作業ブランチに切り替え)して、「バックアップ」コミットに名前を付けることもできます。必要ない場合は、後でブランチを削除します。編集:OPがsvnにあることに気づかずに申し訳ありません!
joeytwiddle

3

あなたは唯一のプログラマです。あなたがしたことの重要な部分を詳述する単一の大規模なチェックインを行うだけです。

あなたがしたことの「部分」をロールバックする可能性がありますか?そうでない場合は、絶対にオプション1に進みます。

バージョン管理システムにコードをチェックインする理由はいくつかあります。そして、それらすべてが、あなたが唯一の開発者である場合、安全性を中心に展開します。つまり、ねじを締めたり、機械が死んだりした場合、いつでも最後のチェックポイントに戻ることができます。

後でプロジェクトに参加するプログラマーは、コンパイルされていないバージョンにロールバックしたくないでしょう。だから、私見、オプション2は狂気です。

オプション3は時間の無駄遣いのように聞こえます。もし私があなたの上司であり、あなたがこれを何時間も無駄にしているのを見たら、あなたの時間の価値について少し話をするでしょう。

反復するには:コードをチェックインすることにより、マシンで障害が発生した場合に、お尻をカバー/保存します。ワンマンチームでは、それ以外はすべてウィンドウドレッシングです。


1
小さなコミットを使用する理由は、ロールバックだけではありません。それは特に正当な理由ではありません。主な理由は、変更が導入された時期と理由を確認できることと、原因不明の問題に直面した場合のトラブルシューティングを容易にすることです。後になってプロジェクトに参加する別のプログラマー、少なくとも時折「WTF」になり、最初に書き込まれた、または最後に変更されたコミットを参照するコード行に遭遇することがあります。そのコミットが500件を変更する1つの巨大なコミットである場合、履歴から有用な情報を取得することは不可能です。
アーロンノート14年

ちなみに、これがGitを使用するチームが一般的にマージコミットを嫌い、リベースを要求/要求する理由です。bisect多くの変更が1つの巨大なコミットに詰め込まれているため、マージコミットの中断や、問題を特定するために一般的に使用されるその他の手法。
アーロンノート14年

1
個人的なレベルでは、コードベースを根本的に変更しない限り、大規模なコミットをしてはいけないことに同意します。しかし、私たちは本質的に切り離されて働いており、今は正しいことをやり直そうとしている単一のプログラマーについて話している。その場合、1つの大きなコミットが望ましいと思います。
NotMe 14

1
@Aaronaught 3か月後に自分が「別のプログラマー」になることができると付け加えます。
マチェイピエチョトカ14年

1
また、アーキテクチャの変更やその他の「破壊的な」変更のための実行可能な戦略としての分岐にも反対する必要があります。それは単にマージの競合とマージ後のバグという悪夢につながります。長い目で見れば、大きな変更を後方互換性のあるより小さな変更に分割する方法を見つけ出すこと、または最悪のシナリオでは、ファウラー、ハンブル、その他の人々がブランチと呼ぶものを使用することははるかに簡単です抽象化(実際にはブランチではありません)。これらの戦略はどちらも、小規模で集中的なコミットを意味します。
アーロンノート14年

2

私のルールは次のとおりです。深刻なコードレビューなしにチェックインしない。私は自分でだ場合、私はコードを自分で確認する必要がありますが、それはなります見直されます。他の人がレビューできないほど多くのコード変更があるため、自分でレビューすることはできません)。

誰もが完全に破ることのできないルールは次のとおりです。ビルドさえしないコードはチェックインせず、機能しないコードのチェックインを真剣に避けます。

解決策:変更したコードをコピーして、元のポイントに戻ります。一度に1つの変更を元のコードにマージし、レビューし、テストし、チェックインします。説明したプログラミング方法では、そのようにしていくつかの重大なバグを見つけることができます。

また、良いプログラミング習慣を身につける良い方法でもあります。


これは論理的には上記のGitベースの回答(git add --patchおよびgit stash)と同じものであり、最新のDVCSでは簡単に処理できるが古いシステムでは処理できないシナリオの良い例です。
ロンマクニール14

1

心配しすぎていると思います。あなたが唯一のプログラマであり、あなたが反対する仕様書を持っていないなら、それはあなたが何をするか完全にあなた次第です。大規模なコミットを行ったとしても、誰もあなたを罰することはないと思うので、あなたが遭遇する唯一の問題は、コミット内の個々のファイルの変更をロールバックできないなどの技術的な問題です。ただし、現時点ではレポジトリを単独で管理しているため、これも大きな懸念事項ではありません。

実用主義と独断主義の間には線が引かれます。チームであなたがしたことは良い考えではなく、おそらく今後も繰り返されるべきではありませんが、あなたの状況では、私は大規模なコミットを提出するだけです。


1
これは前に既に12点の答えに掲載されたものに比べて大幅何も追加していないようだ
ブヨ

-1

問題は、コミット間の長い遅延ではなく、コードをコンパイルできない状態に長時間保持しているという事実にあります。まず、「長い」の定義は何ですか?一部の人にとっては、移行状態の5分間は多すぎますが、コンパイラを実行しなくても数日間コードを磨くことができます。

実際、それは問題ではありません。重要なのは、コードの制御を失い、コードが管理不能になったことです。これは正常なことです。技術的な負債があることを意味し、リファクタリングを検討する時が来ました。あなたはイライラしていますか?コードはコンパイルされず、ユニットテストさえありませんか?この場合のリファクタリングについてどう思いますか?心配ない。「カウボーイコーディング」を終了し、クリーニングを開始します。理想的には、いくつかのテストを書いてみてください。時間がありませんか?さて、小さな改善から始めましょう。

一部の変更はテストを必要としません。変数の名前をより適切なものに変更したり、繰り返しコードを別の関数に移動したりするなど、コードをよりよく理解できます。その後、より大きな変更を行うことができます。繰り返しますが、可能であればテストを作成してください。コードを管理しやすくします。

その後、次の変更が「長すぎる」ことを意味しないことがわかります(それが何を意味するにせよ)。


2
彼は長い間コードをコンパイルできないままにしていたとは言わなかった。リポジトリ内のコードは長い間変更されていませんでした-古いが、まだコンパイル可能です。彼の作業コピーのコードは頻繁に更新されましたが、コミットされていませんでした。ここでは、「コーディングカウボーイ」ではない、実際のコードの品質に、彼のSCMのワークフローを参照する-問題の何も彼のコードはリファクタリングが必要な場合があります示唆していない
IDAN Arye

@IdanArye元の質問...Try to break it into smaller commits that likely won't compile...からあなたのコードをコミットすることを妨げる何かが既に良い歌であるなら、そのコードは管理するのが難しいです。「コミット」は、作業を継続する方法の1つにすぎません。もっと極端な場合-「何かがソースファイルを保存できない場合」を考えることができます。それで、それは何でしょうか?自分の変化を恐れているのではないでしょうか。なぜそれができますか?...私はあなたがポイントだと思います
AlexT

2
私には、彼がコミットするのを妨げたのは単なる怠lazだったようです。
イダンアリー14

@IdanAryeあなたはすべての点で正しいです。それに加えて、十分なTDDを実行していません。これは別の問題です。
durron597 14

@AlexTは、2つのバグを修正し、そのうちの1つが新しく開発された方法を必要とするシナリオを検討します。適切にコミットしていた場合は、1つのバグを修正し、コミットしてから、もう1つのバグを修正します。そうでない場合は、コミットするときに、両方の変更を同じコミットに含めるか、最初のバグ修正を2番目の変更でコミットする必要があります。ただし、コミットされたバージョンには新しいメソッド呼び出しがないため、コンパイルしません。
durron597 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.