46

これらの各 VCS は名前の変更をどのように処理しますか?

git はファイルではなく LOC (コード行) を追跡するため、名前の変更は意味をなさないという矛盾する情報が多数見つかりました。

4

6 に答える 6

43
  • Git は名前の変更をまったく追跡しませんが、ヒューリスティックを使用して、マージなどの際にそれらを再発見します。
  • Mercurial トラックは名前を変更し (元のバージョンと元のファイルが記録されます)、マージ中にその情報を使用します。そのため、名前の変更について hg に明示的に伝えるか、自動検出にhg mv使用する必要があります。hg addremove --similarityマージ中にヒューリスティックを追加するという話もありました。
  • Svn は名前の変更を追跡しますが、マージ中にどれだけ適切に処理されるかはわかりません (実際にテストしたことはありません)。
于 2009-10-08T13:21:27.483 に答える
23

ギット

Gitは、名前変更の追跡を行わないという点で異なります。つまり、SCMコマンドを使用して名前を変更する(または自動検出スクリプトを実行してコミット前に名前を変更する)ことで名前変更について通知する必要がなく、保存されません。リポジトリ内のそのような情報ですが、名前変更の検出を行います。-Mこれは、マージ中と、オプションを介して要求された場合(またはdiff.renamesconfigオプションを使用して構成された場合)のdiffの両方で、ファイル名とファイルの内容の類似性に基づくヒューリスティックアルゴリズムを使用して名前変更を検出することを意味します。

この方法の利点は次のとおりです。

  • 名前の変更を明示的にマーク(または検出)する必要はありません。名前の変更はパッチから取得することも、ファイルマネージャーまたはグラフィカルインターフェイスを介して実行することもできます。
  • 類似性検出アルゴリズムは改善でき、コミット前に名前の変更を検出してマークを付け、この情報をリポジトリに保存する場合のように、コミット時に凍結されません。また、名前変更の検出ミスが履歴に固定されていない場合は、それらのミスに対処するのも簡単です。
  • 重要なのはコンテンツであるというGitの哲学に従います。git blame (および「 gitgui blame」のようなグラフィカルフロントエンド)が、ファイルの境界を越えたコードブロックの移動を追跡する方法を確認してください。これは、ファイルの名前をまったく変更するよりも一般的です。
  • 同じメカニズムが、マージ中の名前変更の処理を担当します。名前変更検出を使用すると、マージが最終的に基づく3つのコミットに対して実行できることを意味し、各名前変更に注意して履歴を注意深く追跡する必要はありません-またはファイルの正規名の非分散概念

pathspecフィルタリングは、名前変更の検出ではうまく機能しないことに注意してください。git log --follow <filename>名前の変更を超えてファイルの履歴を追跡する場合は、「 」を使用します

于 2009-10-09T09:06:06.003 に答える
10

実際には:

Git は名前の変更を自動的に検出します。(ちなみに、あるファイルから別のファイルに関数を移動したときに git が検出できるという主張を聞いたことがあります。しかし、私の最初のテストでは、そうではないことが示されているようです。)

hg mvMercurial では、 、または の--similarityオプションhg addremove、TortoiseHg の「名前の推測」オプション、または VisualHg などの特定のツールを使用して、名前の変更について明示的に伝える必要があります。Mercurial で Git アプローチを使用する場合は、コミット時に名前の変更を検出する拡張機能を作成しましたが、現時点では非常に実験的な段階にあります。

Subversion は名前の変更をまったく処理しません名前の変更は、1 つのファイルが削除され、別のファイルが追加されたものとして記録されます。これは、たとえば、アリスがファイルを変更し、ボブがそのファイルの名前を変更した場合、ツリーの競合が発生することを意味します。これは、本格的な分岐とマージを行っている場合でも、単純にsvn update. 名前の変更の追跡は、来年中に予定されている Subversion 1.8 で計画されています。

于 2010-06-26T07:25:30.600 に答える
6

あなたは正しいことを聞いたことがあります。

Git はファイル自体ではなくファイルの内容を操作するため、名前の変更は技術的に意味がありません。git にとって、名前の変更は、ファイル A が消え、ファイル B が A と同じ内容で表示されたように見えます。しかし、実際には、ファイルが実際にいつ名前変更されたかを把握するのに git はかなり優れています。

試してみてください: ファイルの名前を変更し、'git rm oldname' と 'git add newname' を実行して、変更をステージングするように git に指示します。次に、'git status' を実行して、git が何をしていると考えているかを確認します。ファイルの名前が変更されました。それが後で何を意味するかはわかりませんが。「git show」でコミットを見ると、名前の変更についての言及は見られず、あるパスから削除されて別のパスに追加された一連の行だけが表示されます。

または、「git mv」コマンドを使用してファイルの名前を変更することもできます。git が操作を認識する方法は変わりません。「mv oldname newname」、「git rm oldname」、および「git add newname」を 1 つのステップで効果的に実行するだけです。

Mercurial の概要については、tonfa's answerを参照してください。

一方、SVN は名前の変更を検出できませんが、'svn mv' コマンドで名前を通知する必要があります。ただし、名前変更を「ファーストクラス」の変更として追跡するため、後で変更ログを表示すると、変更が名前変更であったことがわかります。

ただし、この機能に基づいて git または mercurial よりも SVN を選択することはお勧めしません。ツール間には、はるかに大きく重要な違いがあります。最初に、分散バージョン管理システム (git または mercurial) が必要か、集中型バージョン管理システム (svn) が必要かを決定します。

于 2009-10-08T13:20:58.607 に答える
3

ヒューリスティックを使用して名前変更が行われたかどうかを判断することに加えて、まだ言及されていないgitに関するもう1つのこと:

ファイルまたはディレクトリツリー全体の名前が変更、コピー、または移動され、その下にあるものが何も変更されていない場合、ファイルまたはツリーは実際にはリポジトリ内に同じオブジェクトとして保存され、余分なものは必要ありません。スペース。

変更すると、通常どおり、新しいオブジェクトとして保存されます。

hgとsvnについてはよくわかりませんが、チェンジリスト指向のアーキテクチャーは、このシナリオでは動作が異なることを意味していると思います。リポジトリ内の巨大なツリーを移動またはコピーすることを避ける理由が得られる場合を除いて、実際には使用法に影響はありません。

于 2009-10-10T08:10:19.530 に答える
0

git は、ファイルではなくコンテンツを追跡します。Mercurial についてはよくわかりませんが、名前の変更について svn に明示的に通知する必要があります

于 2009-10-08T13:05:29.183 に答える