web-dev-qa-db-ja.com

git-worktreeは何に使用しますか?

Githubのgit-worktreeへの投稿 を読みました。彼らは書きます:

ユーザーがfeatureの緊急度の高いバグを報告したときに、masterというブランチのGitリポジトリで作業しているとします。最初に、マスターに対して相対的にチェックアウトされた新しいブランチhotfixでリンクされた作業ツリーを作成します。[…]バグを修正し、修正プログラムをプッシュし、プルリクエストを作成できます。

Featureと呼ばれるブランチで作業していて、masterで緊急性の高いバグが報告された場合、通常、作業中のものを隠して新しいブランチを作成します。完了したら、作業を続行できます。これは非常に単純なモデルで、私は長年そのように働いてきました。

一方、git-worktreeの使用には独自の制限があります。

たとえば、2つのリンクされた作業ツリーで同じブランチを同時にチェックアウトすることはできません。これにより、一方の作業ツリーでコミットされた変更によって他方の作業ツリーが同期しなくなるからです。

すでに解決済みの問題に対して、より複雑なワークフローを選択するのはなぜですか?

git-worktreeについて、事前に行うことができず、このまったく新しい複雑な機能を正当化するものはありますか?

153
awendt

私にとって、git worktreeは長い間最大の改善点です。私はエンタープライズソフトウェア開発に取り組んでいます。そこでは、3年前にリリースしたような古いバージョンを維持しなければならないことは非常に一般的です。もちろん、バージョンごとにブランチがあり、簡単に切り替えてバグを修正できます。ただし、その間にリポジトリを完全に再構築し、システムを構築する可能性があるため、切り替えは高価です。切り替えると、IDEが狂って実行され、プロジェクト設定を調整しようとします。

ワークツリーを使用すると、そのような再構成を回避できます。ワークツリーを使用して、これらの古いブランチを個別のフォルダーにチェックアウトします。ブランチごとに、独立したIDEプロジェクトが作成されました。

もちろん、これはレポを数回複製することで過去に行うことができ、これはこれまでの私のアプローチでした。ただし、それはハードライブのスペースを浪費し、さらに悪いことにリポジトリから同じ変更を数回取得する必要があることも意味していました。

現在、欠落している部分はWindows用の公式git 2.5バージョンだけですが、 windows用の新しいgit がまもなくリリースされることを期待しています:-)

125
Sebi

これにはいくつかの用途があります。

長時間実行するテストスイートがある場合は、数時間を想像して開始すると、テストが完了するまで作業コピーを効果的にブロックします。これらのテスト中にブランチを切り替えると、理解しにくい方法でブランチが破損します。

したがって、git-worktreeを使用すると、そこで作業を行う別のブランチの2つ目のアイデアを開始できます。

また、簡単な調査を行うために他のブランチに切り替えると、IDEは多くのファイルが突然変更されたと判断し、すべての変更をインデックス付けします。バック。

3番目の使用例は、通常のdiffのようなgit-diff以外のツールを使用して、2つのブランチの代わりに2つのディレクトリ間でファイル比較を行うことです。

60

明らかな用途の1つは、異なるバージョンの動作(ソースではない)を同時に比較することです。たとえば、Webサイトの異なるバージョンまたはWebページだけです。

私はこれをローカルで試しました。

  • ディレクトリpage1を作成します。

  • 内部にsrcディレクトリとgit init itディレクトリを作成します。

  • srcで、少しの内容でpage1.htmlを作成し、コミットします。

  • $ git branch ver0

  • $ git worktree add ../V0 ver0

  • src masterで、page1.htmlにさらにテキストを追加してコミットします。

  • $ git branch sty1

  • page1.htmlブランチのsty1を編集し(独特のCSSスタイルを追加)、コミットを追加します。

  • $ git worktree add ../S1 sty1

Webブラウザを使用して、これらの3つのバージョンを同時に開いて表示できるようになりました。

  • ..\page1\src\page1.html //現在のgitが持つものは何でも

  • ..\page1\V0\page1.html //初期バージョン

  • ..\page1\S1\page1.html //実験的なスタイルのバージョン

51
RodMcGuire
  1. ファイルシステムに一度に複数のワークツリーが必要/必要になる正当な理由があります。

    • チェックアウトされたファイルの操作while他の場所で変更を加える必要がある(例:コンパイル/テスト)

    • 通常の差分ツールを介してファイルを差分する

    • マージの競合中、ソース側にあるようにソースコードをナビゲートすることがよくありますwhileファイル内の競合を解決します。

    • 頻繁に切り替える必要がある場合、複数のワークツリーを使用する必要がないという無駄な時間のチェックアウトと再チェックアウトがあります。

    • git stashingを介したブランチ間のメンタルコンテキストスイッチングのメンタルコストは、実際には測定できません。一部の人々は、別のディレクトリからファイルを開くだけでは、スタッシングには精神的なコストがかかることに気付きます。

  2. 一部の人々は「なぜ複数のローカルクローンをしないのか」と尋ねます。 「--local」フラグを使用すると、余分なディスク容量の使用を心配する必要はありません。これ(または同様のアイデア)は、私がこれまでに行ったことです。ローカルクローンよりもリンクされたワークツリーの機能的な利点は次のとおりです。

    1. ローカルクローンを使用すると、追加のワークツリー(ローカルクローン内にある)は単にOriginまたはアップストリームブランチにアクセスできません。クローンの「Origin」は、最初のクローンの「Origin」と同じではありません。

      • git log @{u}..またはgit diff Origin/feature/other-featureを実行すると非常に役立つ場合があり、これらはもはや不可能または困難です。これらのアイデアは、さまざまなワーカローンを介してローカルクローンで技術的に可能ですが、リンクされたワークツリーを使用することで、回避策はすべて改善され、簡単になります。
    2. ワークツリー間で参照を共有できます。他のローカルブランチからの変更を比較または借用する場合は、今すぐできます。

24
Alexander Bird

tl; dr:何らかの理由で2つの作業ツリーを同時にチェックアウトする場合は、git-worktreeを使用すると、すばやく効率的にスペースを節約できます。

別のワークツリーを作成すると、リポジトリのほとんどの部分(つまり.git)が共有されます。つまり、1つの作業ツリーにいるときにブランチを作成したりデータをフェッチしたりすると、他の作業ツリーからもアクセスできます。ブランチfooでテストスイートを実行して、クローンを作成するためにどこかにプッシュする必要がなく、リポジトリをローカルでクローン作成する手間を避けたい場合、git-worktreeを使用すると、ある状態の新しいチェックアウトを作成するのに便利一時的または永続的に別の場所。クローンの場合と同じように、クローンを作成した後に行う必要があるのは、それを削除することだけです。クローンへの参照は、しばらくするとガベージコレクションされます。

9
jsageryd

私はもともと、これらの派手なワークツリーを何に使うことができるのかと思った後、この質問に出くわしました。それ以来、私はそれらをワークフローに統合しましたが、最初の懐疑論にもかかわらず、それらは非常に有用であることがわかりました。

私はかなり大きなコードベースに取り組んでおり、コンパイルにはかなりの時間がかかります。通常、現在作業中の機能ブランチに加えて、現在の開発ブランチと、稼働中のシステムの現在の状態を表すマスターブランチがマシンにあります。

私にとっての最大の利点の1つは、明らかに、ブランチ(つまり、ワークツリー)を切り替えるたびに全体を再コンパイルする必要がないことです。素敵な副作用は、開発ワークツリーに行き、そこで作業を行い、現在の機能ブランチのディレクトリをワークツリーに変更し、最初にプルすることなくリベースできることです。

6
rethab

私はかなり珍しいものを持っています:同じマシンでWindowsとLinuxの開発をしています。 Windowsボックス内にLinuxを実行するVirtualBoxがあります。 VirtualBoxは一部のWindowsディレクトリをマウントし、Linuxマシン内で直接使用します。これにより、Windowsを使用してファイルを管理できますが、Linux内でビルドできます。これはクロスプラットフォームプロジェクトであるため、WindowsとLinuxの両方で同じディレクトリ構造からビルドされます。

問題は、LinuxとWindowsのビルドシステムが同じディレクトリで使用されると互いにクラッシュすることです。同じディレクトリ名を使用するライブラリなどをダウンロードするための複雑なビルド手順がいくつかあります。ビルドシステムのWindowsバージョンはWindows固有のライブラリをダウンロードし、ビルドシステムのLinuxバージョンはLinux固有のライブラリをダウンロードします。

理想的な世界では、WindowsとLinuxがディレクトリ内に共存できるようにビルドシステムが変更されますが、現時点では、問題はワークツリーで対処されています。 「Linux」フォルダーはLinux固有のビルド成果物を生成でき、「Windows」フォルダーはWindows固有のビルド成果物を生成できます。これは理想的なソリューションとは言えませんが、ビルドシステムのバグに対処するのを待つ間、すてきな一時停止になります。

確かに、ワークツリーはこのために設計されていません。 WindowsバージョンとLinuxバージョンを別々のブランチに保持する必要がありますが、同じブランチに配置することを本当に望んでいます。それでも、それは仕事をしており、ワークツリーが日を節約するというやや型破りなケースです。

3
AHelps

私の新しいプロジェクトでは、機能を作成しました。しかし、いくつかの仕様は失敗しました。結果をmasterと比較するために、work-treeリポジトリを作成しました。何がうまくいかなかったかを理解するまで、実行コードで段階的に結果を比較しました。

1
itsnikolay

機械学習の開発にgit worktreeを使用しています。

私は主な機能コードを持っているので、異なる実験のブランチ(異なるアルゴリズムと異なるハイパーパラメーター)を分割したいと思います。 git worktreeを使用すると、さまざまなアルゴリズムに特化したさまざまなバージョンのコードと一緒に dvc を統合できます。すべてのトレーニングジョブを実行した後、最終的なメトリックを評価し、マージして最適なブランチ/モデルをマスターします。

0
Ricardo M S