GITとCVSの違い 質問する

GITとCVSの違い 質問する

Git と CVS バージョン管理システムの違いは何ですか?

私は 10 年以上 CVS を快適に使用してきましたが、今では Git の方がはるかに優れていると言われています。この 2 つの違いと、一方が他方よりも優れている理由を説明していただけますか?

ベストアンサー1

主な違いは、(他の回答でも既に述べられているように)CVS は(古い)集中型バージョン管理システムであるのに対し、Git は分散型であるということです。

しかし、単一の開発者、単一のマシン (単一のアカウント) でバージョン管理を使用する場合でも、Git と CVS にはいくつかの違いがあります。

  • リポジトリの設定Gitはリポジトリを.gitプロジェクトのトップディレクトリに保存します。CVSでは、さまざまなプロジェクト(モジュール)のバージョン管理情報を保存する中心的な場所であるCVSROOTを設定する必要があります。この設計の結果、ユーザーにとって、既存のソースをバージョン管理にインポートすることは、Gitでは「git init && git add . && git commit」と同じくらい簡単ですが、より複雑CVS で。

  • アトミック操作当初の CVS はファイルごとの RCS バージョン管理システムに関する一連のスクリプトであったため、コミット (およびその他の操作) は CVS ではアトミックではありません。リポジトリの操作が途中で中断されると、リポジトリが不整合な状態のままになる可能性があります。Git では、すべての操作がアトミックです。つまり、操作全体が成功するか、変更なしで失敗するかのどちらかです。

  • 変更セットCVSの変更はファイルごとに行われますが、Gitの変更(コミット)は常にプロジェクト全体を参照します。これは非常に重要です。パラダイムシフトその結果、Gitでは元に戻す(元に戻す変更を作成する)または元に戻すのが非常に簡単になります。全体 change; other consequence is that in CVS is easy to do partial checkouts, while it is currently next to impossible in Git. The fact that changes are per-file, grouped together led to invention of GNU Changelog format for commit messages in CVS; Git users use (and some Git tools expect) different convention, with single line describing (summarizing) change, followed by empty line, followed by more detailed description of changes.

  • Naming revisions / version numbers. There is another issue connected with the fact that in CVS changes are per files: version numbers (as you can see sometimes in keyword expansion, see below) like 1.4 reflects how many time given file has been changed. In Git each version of a project as a whole (each commit) has its unique name given by SHA-1 id; usually first 7-8 characters are enough to identify a commit (you can't use simple numbering scheme for versions in distributed version control system -- that requires central numbering authority). In CVS to have version number or symbolic name referring to state of project as a whole you use tags; the same is true in Git if you want to use name like 'v1.5.6-rc2' for some version of a project... but tags in Git are much easier to use.

  • Easy branching. Branches in CVS are in my opinion overly complicated, and hard to deal with. You have to tag branches to have a name for a whole repository branch (and even that can fail in some cases, if I remember correctly, because of per-file handling). Add to that the fact that CVS doesn't have merge tracking, so you have to either remember, or manually tag merges and branching points, and manually supply correct info for "cvs update -j" to merge branches, and it makes for branching to be unnecessary hard to use. In Git creating and merging branches is very easy; Git remembers all required info by itself (so merging a branch is as easy as "git merge branchname")... it had to, because distributed development naturally leads to multiple branches.

This means that you are able to use topic branches, i.e. develop a separate feature in multiple steps in separate feature branch.

  • Rename (and copy) tracking. File renames are not supported in CVS, and manual renaming might break history in two, or lead to invalid history where you cannot correctly recover the state of a project before rename. Git uses heuristic rename detection, based on similarity of contents and filename (This solution works well in practice). You can also request detecting of copying of files. This means that:

  • when examining specified commit you would get information that some file was renamed,

  • merging correctly takes renames into account (for example if the file was renamed only in one branch)

  • "git blame", the (better) equivalent of "cvs annotate", a tool to show line-wise history of a file contents, can follow code movement also across renames

  • Binary filesCVS はバイナリ ファイル (画像など) のサポートが非常に限定的であるため、バイナリ ファイルが改行コードやキーワード拡張によってマングリングされるのを防ぐため、追加時に (または後で "cvs admin" を使用するか、ラッパーを使用してファイル名に基づいて自動的に行う) バイナリ ファイルを明示的にマークする必要があります。Git は、CNU diff や他のツールと同じように、内容に基づいてバイナリ ファイルを自動的に検出します。この検出は、gitattributes メカニズムを使用してオーバーライドできます。さらに、バイナリ ファイルは、デフォルトで 'safecrlf' が有効になっているため (また、ディストリビューションによってはデフォルトで有効になっている場合もありますが、改行コードを要求する必要があるため)、回復不能なマングリングに対して安全であり、(限定的な) キーワード拡張は Git では厳密に 'オプトイン' です。

  • キーワード拡張Git は、CVS (デフォルト) と比較して、非常に限られたキーワード セットを提供します。これは、Git での変更はファイルごとではなくリポジトリごとに行われること、および Git では他のブランチに切り替えたり履歴の他のポイントに巻き戻したりするときに変更されなかったファイルの変更が回避されるという 2 つの事実によるものです。Git を使用してリビジョン番号を埋め込む場合は、ビルド システムを使用してこれを行う必要があります。たとえば、Linux カーネル ソースと Git ソースの GIT-VERSION-GEN スクリプトの例を次に示します。

  • コミットの修正Gitのような分散VCSでは、出版コミットの作成とは別に、他のユーザーに迷惑をかけずに、履歴の未公開部分を変更 (編集、書き換え) できます。特に、コミット メッセージにタイプミス (またはその他のエラー) があったり、コミットにバグがあったりする場合は、単に「git commit --amend」を使用できます。これは、CVS では (少なくとも高度なハッキングなしでは) 不可能です。

  • その他のツールGitはCVSよりも多くのツールを提供しています。最も重要なものの1つは「git バイセクト「」は、バグを引き起こしたコミット(リビジョン)を見つけるために使用できます。コミットが小さく自己完結的であれば、バグがどこにあるかを見つけるのはかなり簡単なはずです。


少なくとも 1 人の他の開発者と共同作業している場合は、Git と CVS の間に次のような違いがあることに気付くでしょう。

  • マージ前にコミットするGitはマージ前のコミットCVSのように、コミット前のマージ(または更新してからコミット)。ファイルを編集して新しいコミット (新しいリビジョン) を作成する準備をしているときに、他の誰かが同じブランチで新しいコミットを作成し、それがリポジトリにある場合、CVS ではコミットする前に、まず作業ディレクトリを更新して競合を解決するように強制されます。これは Git には当てはまりません。最初にコミットして、バージョン管理に状態を保存し、次に他の開発者の変更をマージします。他の開発者にマージと競合の解決を依頼することもできます。

線形履歴を保持し、マージを避けたい場合は、常にコミット-マージ-再コミット「git rebase」(および「git pull --rebase」) によるワークフロー。更新された状態の上に変更を再生するという点で CVS に似ています。ただし、常に最初にコミットします。

  • 中央リポジトリは不要 With Git there is no need to have single central place where you commit your changes. Each developer can have its own repository (or better repositories: private one in which he/she does development, and public bare one where she/he publishes that part which is ready), and they can pull/fetch from each other repositories, in symmetric fashion. On the other hand it is common for larger project to have socially defined/nominated central repository from which everyone pull from (get changes from).

Finally Git offers many more possibilities when collaboration with large number of developers is needed. Below there are differences between CVS in Git for different stages of interest and position in a project (under version control using CVS or Git):

  • lurker. If you are interested only in getting latest changes from a project, (no propagation of your changes), or doing private development (without contributing back to original projects); or you use foreign projects as a basis of your own project (changes are local and doesn't it make sense to publish them).

Git supports here anonymous unauthenticated read-only access via custom efficient git://protocol, or if you are behind firewall blocking DEFAULT_GIT_PORT (9418) you can use plain HTTP.

For CVS most common solution (as I understand it) for read-only access is guest account for 'pserver' protocol on CVS_AUTH_PORT (2401), usually called "anonymous" and with empty password. Credentials are stored by default in $HOME/.cvspass file, so you have to provide it only once; still, this is a bit of barrier (you have to know name of guest account, or pay attention to CVS server messages) and annoyance.

  • fringe developer (leaf contributor). One way of propagating your changes in OSS is sending patches via email. This is most common solution if you are (more or less) accidental developer, sending single change, or single bugfix. BTW. sending patches might be via review board (patch review system) or similar means, not only via email.

Git offers here tools which help in this propagation (publishing) mechanism both for sender (client), and for maintainer (server). For people who want send their changes via email there is "git rebase" (or "git pull --rebase") tool to replay your own changes on top of current upstream version, so your changes are on top of current version (are fresh), and "git format-patch" to create email with commit message (and authorship), change in the form of (extended) unified diff format (plus diffstat for easier review). Maintainer can turn such email directly into commit preserving all information (including commit message) using "git am".

CVS offer no such tools: you can use "cvs diff" / "cvs rdiff" to generate changes, and use GNU patch to apply changes, but as far as I know there is no way to automate applying commit message. CVS was meant to be used in client <-> server fashion...

  • lieutenantプロジェクトの別の部分(サブシステム)のメンテナーである場合、またはプロジェクトの開発がLinuxカーネルの開発で使用されている「信頼のネットワーク」ワークフローに従っている場合、または独自のパブリックリポジトリがあり、公開したい変更が電子メールで送信するには大きすぎる場合など、パッチシリーズ、送信することができますプルリクエストプロジェクトの(メイン)メンテナーへ。

これは、分散したバージョン管理システムなので、当然CVSはそのようなコラボレーション方法をサポートしていません。リポジトリからプルするためのリクエストをメンテナーに送信するメールを準備するのに役立つ「git request-pull」というツールもあります。「git bundle」のおかげで、パブリックリポジトリがなくても、メールやスニーカーネットで変更のバンドルを送信することでこのメカニズムを使用できます。次のようなGitホスティングサイトのいくつかは、GitHub誰かがあなたのプロジェクトで作業している(何らかの作業を公開した)ことを通知する機能(その人が同じ Git ホスティング サイトを使用している場合)と、ある種のプル リクエストを PM で送信する機能をサポートします。

  • メイン開発者つまり、直接公開する彼/彼女の変更(メイン/正規リポジトリへの)を分散型バージョン管理システムで管理する場合には、このカテゴリはより広くなります。中央リポジトリへの書き込み権限を持つ複数の開発者がいることは、ワークフローとして可能であるだけでなく(単一のメンテナーがプッシュ標準リポジトリへの変更、そのリポジトリから変更内容を引き出す一群の副官/サブシステム メンテナー、そして、メンテナー/プロジェクト メーリング リストまたは副官/サブメンテナーのいずれかにメールでパッチを送信する幅広いリーフ開発者)。

Gitでは、SSHプロトコル(SSHでラップされたgitプロトコル)を使用して変更を公開し、「git shell」(セキュリティの向上、シェルアカウントのアクセス制限)などのツールを使用するか、ギトーシス(別のシェルアカウントを必要とせずにアクセスを管理するため)、および翻訳WebDAV と通常の HTTP 認証を使用します。

CVSではカスタム暗号化されていない(プレーンテキスト) 電源サーバープロトコル、または使用リモートシェル(実際にはパスワード)を使用して変更を公開します。集中化されたバージョン コントロール システムとは、変更をコミットする (コミットを作成する) ことを意味します。また、SSH を使用して 'pserver' プロトコルをトンネリングすることもできますし、これを自動化するサードパーティ ツールもあります... ただし、これは Gitosis のように簡単ではないと思います。

一般的に、Git などの分散型バージョン管理システムでは、ワークフローの選択肢がはるかに広くなります。CVS などの集中型バージョン管理システムでは、必然的に、リポジトリへのコミット アクセス権を持つユーザーと持たないユーザーを区別する必要があります。また、CVS では、コミット アクセス権を持たないユーザーからの貢献 (パッチ経由) を受け入れるためのツールは提供されていません。

カール・フォーゲルオープンソースソフトウェアの制作バージョン管理に関するセクションでは、パブリック リポジトリに変更を加えることが許可されている領域に対して、厳格すぎる、硬直した、厳密な管理を提供しない方がよいと述べられています。これには、技術的な制限よりも、社会的制限 (コード レビューなど) に頼る方がはるかに優れています。分散バージョン管理システムは、私見では、それをさらに軽減します...

おすすめ記事