4

注:(すでに行われた議論から)GITは実際にはこのユースケースには適していないように見えますが、私はこの質問を賞金に開放して、より明確な答えを促しました。 GITの経験が豊富です。元の質問は以下のとおりです。

独立したファイルのコレクションが大量にあるという状況があります。独立しているということは、各ファイルがその周囲のファイルの存在、不在、または特定の状態に依存しないことを意味します。良い例えは、画像のディレクトリです。このワークフローでは、各画像を個別に作成、編集、削除でき、画像に対して行われた作業は、ディレクトリ内の他の画像とは関係ありません。

この独立性は偶発的なものであるだけでなく、ワークフローにとって重要であることに注意してください。

これらの各ファイルは、ワークフローのようなGITの恩恵を受けます。各ファイルへの変更を追跡し、各ファイルを独立したブランチで作業し、完了したら変更をマージできると便利です(したがって、類推のために、これらがSVGイメージであると想像してください。画像を描くアーティストとテキストコンテンツを翻訳する翻訳者を配置し、GITを使用する他のプロジェクトのファイルにアクセスします。

私の経験から、GITは、すべて特定の状態にあるファイルのコレクションがある場合に最適です。たとえば、「Production Release 1.2」の状態に達した後にGITリポジトリをコミットすると、すべてのファイルはそのコミット時に「ProductionRelease1.2」の状態を共有します。

しかし、GITワークフローを適用する方法がわかりません。また、各ファイルがその周囲のファイルの状態を共有できない場合、または適用することが実際的であるかどうかもわかりません。各ファイルを独自のGITリポジトリに配置することもできますが、それは実用的ではないようです。

だから、私の質問は次のとおりです。

  1. GITは関連ファイルのコレクションでのみ機能するという私の印象は正しいですか?
  2. そうでない場合、ファイルごとにGITのクローン/ブランチ/マージ機能を使用するためのプロセスは何でしょうか?

アップデート

iberbeuへの応答:バージョンがXYであると見なされるのではなく、GITコミットが、リポジトリ内のすべてのファイルが同じバージョンまたはコミットポイント(ただし、バージョンを定義する)を持っていると想定していると見なされるということです。この場合、GITリポジトリ内のファイルは完全に独立しているわけではありません。

ここでの問題は、すべての独立したファイルを含む単一のリポジトリを取得し、それを独自のローカルリポジトリに複製して、ブランチでの作業を開始する場合です。この時点では、すべてのファイルがブランチに属していると見なされますが、ワークフローの観点からは、1つのファイルのみで作業しています。ただし、これらの独立したファイルはすべて「乗り物に沿って」おり、実際に編集したい単一のファイルに関連付けられたリビジョン履歴を引き継いでいます。

したがって、Joeは「JoeWorkingonImage1」というレポコールのブランチを作成する可能性があります。彼のブランチには、彼が作業したい画像1と、彼が興味を持っていない他の10,000枚の画像があります。

Janeは、「Jane workingonImage987」と呼ばれる同じリポジトリのブランチを作成する場合があります。彼女のブランチには、彼女が作業したいImage 987と、彼女が興味を持っていない10,000の他の画像があります。

ジョーとジェーンがブランチ内の他の画像の編集を開始しようとしない限り、これは問題ありません。しかし、そうすると、独立したエンティティとして編集され、他の画像から分離して編集されている各画像の概念モデルが失われます。

したがって、ジョーが画像1のみを編集するはずだったブランチで画像2を編集し、それらの変更をリポジトリにマージした場合、画像2の明示的な改訂履歴が画像1と一緒に編集されます。ただし、画像1と2は完全に独立している。画像1と一緒に編集されたため、画像2の概念はありません。

つまり、これが問題の核心です。GITは、リビジョンが他のファイルと相関しない分離されたエンティティとして制御するファイルの概念をサポートしていますか?または、これはすべてのファイルの個別のgitリポジトリでのみ達成できますか?

更新2

サブモジュールは、何千ものGITリポジトリの代わりになる可能性があるようです。

4

7 に答える 7

3

私は本当に問題を見ていません。コード(この場合はファイル)をバージョン管理する方法としてリポジトリを見ると思います。それは正しいですが、常にXY形式のバージョンをコミットすることを意味するわけではないため、このアイデアはエラーにつながる可能性があります

つまり、リポジトリは、フォルダのコンテンツのさまざまな状態を持つタイムラインとして表示できます。ファイルが相互に関連しているかどうかは関係ありません。

gitを使用すると、常に古いバージョンの単一ファイルを取得できます。リポジトリの完全な状態に戻る必要はありません。

したがって、あなたの場合、複数の独立したファイルを持つ1つのリポジトリと、それぞれ1つのファイルを持つ複数のリポジトリの間にまったく違いはありません。実際には大きな違いがあります。最初のオプションは手頃な価格で、2番目のオプションは処理できません。

実際、通常のプロジェクトには完全に独立したファイルがありますが、それらはすべて同じリポジトリに属しています。

于 2013-03-03T21:59:35.093 に答える
2

他の人が言っているように、gitは多くの単一ファイルリポジトリに使用できますが、(ご指摘のとおり)一連のファイルを管理するために作成されています。

何千もの単一ファイルリポジトリを管理するには、Gitslaveツールが役立つ場合があります。このツールを使用すると、多数のリポジトリを作成し、それらをすべて1つにまとめて管理できます。リポジトリを取得したら、もちろんそれぞれを独立して操作できますが、Gitslaveを使用すると、プッシュ/プルやコミットなどのグループ操作を簡単に行うことができます。

これは、サブモジュールの操作が難しい場合があるため、多くのgitサブモジュールがあるのでIMHOのより良いソリューションです。

ホームページから:

Gitslaveは、関連するリポジトリのグループ(スーパープロジェクトリポジトリと多数のスレーブリポジトリ)を作成します。これらはすべて同時に開発され、すべてのgit操作が通常動作する必要があります。したがって、分岐すると、プロジェクト内の各リポジトリが順番に分岐します。同様に、コミット、プッシュ、プル、マージ、タグ付け、チェックアウト、ステータス、ログなどを行う場合。各gitコマンドは、スーパープロジェクトとすべてのスレーブリポジトリで順番に実行されます。

[...]

Gitslaveはリポジトリを引き継ぎません。gitsクローンリポジトリの内部とプライベートのgitクローンリポジトリの外部の両方で、レガシーgitコマンドを引き続き使用できます。

于 2013-03-07T09:40:44.020 に答える
2

Gitは、単一ファイルのリポジトリを作成することに問題はありません。

ファイルごとにリポジトリを作成する必要がなく、ディレクトリ内のすべてのファイルを同時に表示する必要がない場合は、空のリポジトリから始めて、これらのファイルごとにブランチを作成できます。これらの独立したブランチ間でマージを行わない場合、それらは独立したままになります。特定のファイルのブランチから新しいブランチを作成し、変更をマージして戻すことができます。

于 2013-03-03T21:17:58.533 に答える
2

私はCVSを使用しており、各ファイルはリポジトリ内の他のすべてのファイルから独立しています。

ボーナスとして、これにより、一部のファイルに対して「cvs update」を実行し、他のファイルはそのままにしておくことができます。

これは、ローカルワークスペースでファイルを変更したり、別のワークスペースからの変更をチェックインしたりする場合に便利です。マージする必要があるかもしれないファイルを処理することを気にせずに、リポジトリ内でのみ変更されたファイルと同期したいことがよくあります。

これにより、私がcvs-update-safeと呼ぶスクリプトが作成されました。このスクリプトは、安全に更新できるファイルをすばやく簡単に更新し、他のファイルは後で手動で処理できるようにしておきます。

私はどんな複雑さでもCVSの大ファンではありませんが(私はgitが好きです)、どこにでもあるという利点があり、リポジトリの一部だけを更新できるという利点があります。

#!/usr/bin/python

# $Id: cvs-update-safe,v 1.1 2007-11-02 19:47:02 falk Exp $

usage = """Like cvs update, but only updates files which will update cleanly.

Usage:  cvs-update-safe [files...]
"""

import sys
import os
import string
import commands

def main():
  cmd = 'cvs -n update ' + string.join(sys.argv[1:], ' ')
  output = commands.getoutput(cmd).split('\n')
  olist = []
  for line in output:
    line = line.split()
    if line[0] is 'U' and len(line) is 2:
      olist.append(line[1])
  if olist:
    cmd = 'cvs update ' + string.join(olist, ' ')
    os.system(cmd)
  else:
    print 'Nothing to update'



if __name__ == "__main__":
  sys.exit(main())
于 2013-03-09T02:41:33.843 に答える
0

単一のリポジトリでは、一度に1つのファイルのみをコミットすることを選択して、各ファイルに異なるコミットメッセージを与えることができます。ただし、リポジトリのクローンを作成すると、リポジトリ全体がダウンロードされることになります。Gitは分散バージョン管理システムであり、これはその副作用です。

各ファイルに独自のgitリポジトリを与え、サブモジュールを使用して他のgitリポジトリにインポートすることができます。管理するのがやや面倒であることがわかりますが、dvcsを使用することの長所は、コンピューター上のリポジトリーの履歴を常に持っていることです。

考慮すべきもう1つのことは、ジョブに間違ったツールを使用している可能性があることです。SVNは一元化されたバージョン管理システムであり、リポジトリ全体のクローンを作成する代わりに、単一のファイルをチェックアウト(スパースチェックアウト)することができます。git-svnなどのツールを使用して、既存のGitリポジトリにブリッジできます。

いずれにせよ、それは楽しいプロセスではありません。ファイルごとに個別のgitリポジトリを用意するのが最も簡単かもしれません。

于 2013-03-06T21:32:57.073 に答える
0

単一のリポジトリを使用し、gitフックを使用して1つの粒度を適用できます。

クライアント側のpre-commitフックは、コミットが単一のファイルに変更されたことを確認し、オプションで、prepare-commit-msgフックは、コミットメッセージの前にファイルの名前を自動的に付けます。

サーバー側の事前受信フックは、上記を強制する可能性があります。

最終的に多数の独立したブランチを持つという信号ノイズの問題が依然として発生します。

于 2013-03-06T00:53:31.073 に答える
0

あなたは間違った質問からこの議論を始めたと思います。

段落:

これらの各ファイル[...]は、GITを使用する他のプロジェクトのファイルにアクセスします。

(特に:GITを使用する他のプロジェクトからのファイルにアクセスする)は、他のプロジェクトからアクセスされるリポジトリのコレクションだけが必要であることを示唆しています。

最善の解決策はサブモジュールを使用することだと思います。

「ファイル」ごとに新しいリポジトリを設定します。それらを「one-file-repo」と呼びます。

「one-file-repo」リポジトリを使用するプロジェクトでは、サブモジュールを定義します。

「one-file-repo」リポジトリに単一のファイルが含まれているという事実は重要ではありません。

「one-file-repo」内の作業は分離されていますが、必ずしも単一のファイルに制限されているわけではありません。

于 2013-03-06T08:19:16.230 に答える