GitとCVSバージョン管理システムの違いは何ですか?
私はCVSを10年以上楽しく使用しており、Gitの方がはるかに優れていると言われています。誰かが2つの違いは何であるのか、そしてなぜ一方が他方より優れているのか説明してくれませんか?
GitとCVSバージョン管理システムの違いは何ですか?
私はCVSを10年以上楽しく使用しており、Gitの方がはるかに優れていると言われています。誰かが2つの違いは何であるのか、そしてなぜ一方が他方より優れているのか説明してくれませんか?
回答:
主な違いは、(他の応答ですでに述べられているように)CVSは(古い)集中型バージョン管理システムであり、Gitは配布されていることです。
ただし、単一の開発者、単一のマシン(単一のアカウント)でバージョン管理を使用する場合でも、GitとCVSの間にはいくつかの違いがあります。
リポジトリを設定しています。Gitは.git
プロジェクトの最上位ディレクトリのディレクトリにリポジトリを保存します。CVSでは、さまざまなプロジェクト(モジュール)のバージョン管理情報を格納する中心的な場所であるCVSROOTを設定する必要があります。ユーザー向けのこの設計の結果は、既存のソースをバージョン管理にインポートするのがGitの "git init && git add。&& git commit"と同じくらい簡単ですが、CVSではより複雑です。
アトミックオペレーション。当初のCVSはファイルごとのRCSバージョン管理システムに関する一連のスクリプトであったため、CVSでのコミット(およびその他の操作)はアトミックではありません。リポジトリの操作が途中で中断された場合、リポジトリは一貫性のない状態のままになる可能性があります。Gitでは、すべての操作がアトミックです。つまり、全体として成功するか、変更せずに失敗します。
チェンジセット。CVSでの変更はファイルごとですが、Gitでの変更(コミット)は常にプロジェクト全体を参照します。これは非常に重要なパラダイムシフトです。この結果の1つは、Gitで元に戻す(元に戻す変更を作成する)または変更全体を元に戻すのが非常に簡単であることです。他の結果として、CVSでは部分的なチェックアウトが簡単ですが、Gitでは現在のところ不可能です。変更がファイルごとにグループ化されているという事実により、CVSのコミットメッセージのGNU Changelogフォーマットが発明されました。Gitユーザーは、さまざまな規則を使用し(一部のGitツールはそれを想定しています)、変更を説明(要約)する1行、空行、変更の詳細説明の順に続きます。
リビジョン/バージョン番号の命名。CVSでの変更はファイルごとであるという事実に関連する別の問題があります。1.4のようなバージョン番号(キーワード拡張で時々見られるように、以下を参照)は、指定されたファイルが変更された時間を反映します。Gitでは、プロジェクトの各バージョン全体(各コミット)に、SHA-1 idで指定された一意の名前があります。通常、最初の7〜8文字でコミットを識別できます(分散バージョン管理システムのバージョンに単純な番号付けスキームを使用することはできません。中央の番号付け権限が必要です)。CVSでは、全体としてプロジェクトの状態を参照するバージョン番号またはシンボル名を使用するには、タグを使用します; プロジェクトの一部のバージョンで「v1.5.6-rc2」のような名前を使用したい場合、Gitでも同じことが言えますが、Gitのタグははるかに使いやすくなっています。
簡単な分岐。私の意見では、CVSのブランチは非常に複雑であり、対処するのが困難です。リポジトリブランチ全体の名前を付けるには、ブランチにタグを付ける必要があります(ファイルごとの処理のために、覚えていれば、場合によっては失敗することもあります)。さらに、CVSにはマージ追跡がないため、マージまたは分岐点を覚えるか、手動でタグ付けし、「cvs update -j」に正しい情報を手動で入力して分岐をマージする必要があります。不必要に使いにくい。Gitでは、ブランチの作成とマージは非常に簡単です。Gitは必要なすべての情報をそれ自体で記憶します(したがって、ブランチのマージは "git merge branchname " と同じくらい簡単です)...分散開発は当然複数のブランチにつながるため、そうする必要がありました。
つまり、トピックブランチを使用できます。つまり、個別の機能ブランチの複数のステップで個別の機能を開発できます。
トラッキングの名前を変更(およびコピー)します。CVSではファイル名の変更はサポートされていません。手動で名前を変更すると、履歴が2つに分割されたり、名前が変更される前にプロジェクトの状態を正しく回復できないという無効な履歴が表示される場合があります。Gitは、コンテンツとファイル名の類似性に基づいて、ヒューリスティックな名前変更検出を使用します(このソリューションは実際にはうまく機能します)。ファイルのコピーの検出を要求することもできます。この意味は:
バイナリファイル。CVSはバイナリファイル(画像など)のサポートを非常に制限しているため、追加時に(または後で「cvs admin」を使用して、またはラッパーを介してファイル名に基づいて自動的に行う)バイナリファイルを明示的にマークする必要があります。行末変換とキーワード拡張によるバイナリファイル。Gitは、CNU diffや他のツールが行うのと同じ方法で、内容に基づいてバイナリファイルを自動的に検出します。gitattributesメカニズムを使用して、この検出をオーバーライドできます。さらに、バイナリファイルは、「safecrlf」のデフォルト(および、行末の変換を要求する必要がありますが、ディストリビューションによってはデフォルトでオンになっている場合があります)のおかげで、回復不能なマングリングに対して安全です。拡張はGitでの厳密な「オプトイン」です。
キーワード拡張。Gitは、CVS(デフォルト)と比較して非常に限られたキーワードセットを提供します。これは2つの事実によるものです。Gitの変更はファイルごとではなくリポジトリごとであり、Gitは他のブランチに切り替えたり、履歴の他のポイントに巻き戻したりしても変更されなかったファイルの変更を回避します。Gitを使用してリビジョン番号を埋め込む場合は、ビルドシステムを使用してこれを行う必要があります。たとえば、LinuxカーネルソースとGitソースのGIT-VERSION-GENスクリプトの例を次に示します。
コミットの修正。Gitのような分散VCSでは、公開の行為はコミットの作成とは別なので、他のユーザーに迷惑をかけることなく、未公開の履歴の一部を変更(編集、書き換え)できます。特に、コミットメッセージのタイプミス(またはその他のエラー)またはコミットのバグに気付いた場合は、単に「git commit --amend」を使用できます。これはCVSでは不可能です(少なくとも、大規模なハッカーなしでは不可能です)。
その他のツール。GitはCVSよりもはるかに多くのツールを提供しています。より重要なものの1つは、「git bisect」であり、バグを引き起こしたコミット(リビジョン)を見つけるために使用できます。コミットが小さく自己完結型の場合、バグの場所を見つけるのはかなり簡単です。
少なくとも1人の他の開発者と共同作業をしている場合は、GitとCVSの間に以下の違いがあることもわかります。
マージ前にコミットする Gitは、CVSのようにmerge-before-commit(またはupdate-then-commit)ではなくcommit-before-mergeを使用します。ファイルの編集中に新しいコミット(新しいリビジョン)を作成する準備をしているときに、他の誰かが同じブランチに新しいコミットを作成し、それがリポジトリにある場合、CVSは、コミットする前に、まず作業ディレクトリを更新して競合を解決するように強制します。これはGitには当てはまりません。最初にコミットし、状態をバージョン管理に保存してから、他の開発者による変更をマージします。他の開発者にマージして競合を解決するよう依頼することもできます。
線形履歴を保持し、マージを回避したい場合は、「git rebase」(および「git pull --rebase」)を介してcommit-merge-recommitワークフローをいつでも使用できます。これは、変更を最上位で再生するという点でCVSに似ています更新された状態の。ただし、常に最初にコミットします。
中央リポジトリは不要Gitでは、変更をコミットする中央の場所を1つにする必要はありません。各開発者は独自のリポジトリー(またはより優れたリポジトリー:開発を行うプライベートなリポジトリーと、準備ができたその部分を公開するパブリックなベアリー・リポジトリー)を持つことができ、他のリポジトリーからプル/フェッチできます。対称的なファッション。一方で、大規模なプロジェクトでは、誰もがそこからプルする(変更を取得する)ための社会的に定義された/指定された中央リポジトリがあるのが一般的です。
最後に、Gitは、多数の開発者とのコラボレーションが必要な場合により多くの可能性を提供します。以下は、プロジェクトの関心のあるさまざまな段階とCVSまたはGitを使用したバージョン管理下のGitでの位置の違いです。
ラーカー。プロジェクトから最新の変更を取得するだけの場合(変更を反映しない)、またはプライベート開発を行う場合(元のプロジェクトに戻さずに)。または、自分のプロジェクトの基礎として外国のプロジェクトを使用している(変更はローカルであり、それらを公開しても意味がありません)。
Gitは、カスタムの効率的なプロトコルによる匿名の認証されていない読み取り専用アクセスをサポートしgit://
ます。または、ファイアウォールブロックDEFAULT_GIT_PORT
(9418)の背後にある場合は、プレーンHTTPを使用できます。
読み取り専用アクセスのCVSの最も一般的なソリューション(私が理解しているように)は、(2401)の'pserver'プロトコルのゲストアカウントでCVS_AUTH_PORT
、通常は「匿名」と呼ばれ、パスワードは空です。資格情報はデフォルトで$HOME/.cvspass
ファイルに保存されるため、一度だけ提供する必要があります。それでも、これは少しバリア(ゲストアカウントの名前を知っているか、CVSサーバーメッセージに注意を払う必要があります)と煩わしさです。
フリンジ開発者(リーフコントリビューター)。OSSでの変更を伝達する1つの方法は、電子メールでパッチを送信することです。これは、(多かれ少なかれ)偶発的な開発者、単一の変更、または単一のバグ修正を送信する場合の最も一般的な解決策です。ところで。パッチの送信は、電子メールだけでなく、レビューボード(パッチレビューシステム)または同様の手段を介して行われます。
Gitはここで、送信者(クライアント)とメンテナー(サーバー)の両方にこの伝播(公開)メカニズムを支援するツールを提供しています。変更をメールで送信したい人のために、現在のアップストリームバージョンの上に自分の変更を再生するための「git rebase」(または「git pull --rebase」)ツールがあるため、変更は現在のバージョンの上にあります(新しい)、およびコミットメッセージ(および作成者)を含む電子メールを作成するための「git format-patch」は、(拡張された)統一されたdiff形式(および簡単に確認できるようにdiffstat)の形式で変更します。メンテナは、 " git am " を使用して、すべての情報(コミットメッセージを含む)を保持するコミットにそのような電子メールを直接変換できます。
CVSはそのようなツールを提供していません。「cvs diff」/「cvs rdiff」を使用して変更を生成し、GNUパッチを使用して変更を適用できますが、私が知る限り、コミットメッセージの適用を自動化する方法はありません。CVSは、クライアント<->サーバー形式で使用するためのものでした...
中尉。プロジェクト(サブシステム)の別の部分のメンテナーである場合、またはプロジェクトの開発がLinuxカーネルの開発で使用される「信頼のネットワーク」ワークフローに従う場合...または、独自のパブリックリポジトリがある場合に、公開したいものが大きすぎてパッチシリーズとしてメールで送信できない場合は、プロジェクトの(メイン)メンテナにプルリクエストを送信できます。
これは分散バージョン管理システムに固有のソリューションであるため、もちろんCVSはそのようなコラボレーション方法をサポートしていません。「git request-pull」と呼ばれるツールさえあります。これは、リポジトリからプルする要求とともに、メンテナーに送信するメールを準備するのに役立ちます。「git bundle」のおかげで、公開リポジトリがなくても、変更のバンドルを電子メールまたはスニーカーネットで送信することにより、このメカニズムを使用できます。GitHubのような一部のGitホスティングサイトは、誰かがプロジェクトで作業している(一部の作業を公開している)ことを通知したり(同じGitホスティングサイトを使用している場合)、一種のプルリクエストをPMしたりするためのサポートを備えています。
メイン開発者、つまり自分の変更を(メイン/正規リポジトリに)直接公開する人。中央リポジトリへの書き込みアクセス権を持つ複数の開発者がワークフローを実行できるだけではないため、このカテゴリは分散バージョン管理システムに広く当てはまります(変更を正規リポジトリにプッシュする単一のメンテナ、一連の代理人/サブシステムメンテナからの変更を許可できます)プル、およびメンテナ/プロジェクトのメーリングリスト、または代理/サブメンテナのいずれかにメールでパッチを送信する幅広いリーフ開発者)。
Git では、変更を公開するためにSSHプロトコル(SSHでラップされたgitプロトコル)を使用するか、「git shell」(セキュリティを支援し、シェルアカウントのアクセスを制限する)またはGitosis(個別のシェルアカウントを必要とせずにアクセスを管理する)などのツールを使用するかを選択できます)、WebDAV を使用するHTTPS、通常のHTTP認証を使用します。
CVSでは、暗号化されていない(プレーンテキストの) カスタムpserverプロトコルを使用するか、リモートシェル(実際にはSSHを使用する必要がある)を使用して変更を公開するかを選択できます。集中型バージョン管理システムでは、変更をコミット(コミットを作成)します。まあ、SSHを使用して「pserver」プロトコルをトンネリングすることもでき、これを自動化するサードパーティのツールがあります...しかし、これはGitosisなどほど簡単ではないと思います。
一般的に、Gitなどの分散バージョン管理システムでは、可能なワークフローの選択肢が大幅に広がります。CVSなどの集中型バージョン管理システムでは、必然的に、リポジトリへのコミットアクセス権を持つ人と持たない人とを区別する必要があります...そしてCVSは、(パッチを介して)人からの貢献を受け入れるのに役立つツールを提供しませんアクセスをコミットします。
バージョン管理に関するセクションの「オープンソースソフトウェアの作成」の Karl Fogelは、パブリックリポジトリに変更を加えることが許可されている領域には、厳格で厳格かつ厳格な管理を提供しない方がよいと述べています。技術的な制限よりも(コードレビューなどの)社会的な制限に頼る方がはるかに優れています。分散バージョン管理システムは、そのIMHOをさらに削減します...
HTH (助けてくれる希望)
GitのWebサイトはおそらくこれを最もよく説明しています。
私のペット機能は、オフライン時にコミットを実行できるようになっています。スピードとは、押したり引いたりする以外のすべてが起こる、まさに燃えるようなスピードです。(そして、これらの操作は非破壊的な設計であるため、中央レポが遅れている場合は、コーヒーを飲みに行くときにプッシュ/プルできます。)もう1つの良い点は、バッテリーが含まれていることです。組み込みgitk
は、十分な履歴ビューアです。git gui
十分なコミットツールです。出力カラー化して、git add -i
、git add -p
、git rebase -i
良い十分な対話型のインターフェイスです。git daemon
そしてgit instaweb
あなたが/したくない場合は、あなたの中央リポジトリとフィドルアドホックコラボレーションのための良い十分ではないことができます。
私は10年以上もcvsを使用していてとても幸せですが、gitも好きですし、時間が経つにつれてそれを好むようになりますが、現在取り組んでいるプロジェクトのほとんどはcvsまたはsvnを使用しています。私が働いている官僚主義を取得するために、ファイアウォールにgitホールを開けることを確信させました。
それ以外の場合よりもcvsをより優れたものにするいくつかのことはcvspsであり、もう1つはAndrew Mortonのパッチスクリプトまたはキルトです。Cvspsを使用すると、コミットの複数のファイルを単一のパッチに再構成できます(したがって、CVSから「チェンジセット」を抽出します)、またはAndrew Mortonのパッチスクリプトを使用すると、合理的な「チェンジセット」をcvsにかなり簡単かつ快適にコミットできます。コミットする前にそれらを分離したまま、同時に複数の事柄に取り組みます。CVSには癖がありますが、私はそれらのほとんどに慣れています。
「x年以上CVSを楽しく使っている」というのは興味深いアイデアです:-)これは、大量のコピーを保持することからの大きなステップですが、...
私はあなたがそれがすべての奇妙なことに慣れているか、分岐やマージをあまり行わないと思います。悪い可能性があります。
組織の人々はCVSの制限に慣れており、それに応じて業務慣行が順応しています。
たとえば、緊急時にブランチを使用するなど、一度に1つのパッケージで複数の開発者が作業することはありません。
基本的な原則は、何かが難しいほど、それを実行する人が少なくなるということです。