[解決済み】Gitで複数の作業ディレクトリを作成できますか?
質問
これがGitでサポートされているものなのかどうかはわかりませんが、理論的にはうまくいくはずだと思います。
私のワークフローでは、複数のブランチにあるファイルを同時に編集することがよくあります。言い換えれば、あるブランチでいくつかのファイルを開きながら、別のブランチで別のファイルの内容を編集したいことがよくあります。
私の典型的な解決策は、チェックアウトを2つ作ることですが、その間にブランチや参照先を共有できないのが残念です。私が望むのは、同じ.gitフォルダで管理された2つの作業ディレクトリを持つことだけです。
ローカルな git clone ソリューション(デフォルトでは共有オブジェクトをハードリンクし、--shared オプションでは元のレポと別のオブジェクトストアをセットアップします)は知っていますが、これらのソリューションはディスクスペースの使用量を削減するだけで、特に --shared の場合は危険と隣り合わせのようです。
1つの.gitフォルダを使用し、それにバックアップされた2つの作業ディレクトリを持つ方法はありますか?それとも、Gitは常に一つの作業ディレクトリだけをチェックアウトするようにハードコーディングされているのでしょうか?
解決方法は?
Git 2.5では、2015年7月以降、以下のような置き換えが提案されています。
contrib/workdir/git-new-workdir
:
ギットワークツリー
参照
コミット 68a2e6a
によって
ジュニオ・C・ハマノ(
gitster
)
.
は リリースノート :
の代替となるものです。
contrib/workdir/git-new-workdir
シンボリックリンクに依存せず、オブジェクトと参照の共有を、借り手と借り手がお互いを認識することによって、より安全にするものです。
参照 コミット 799767cc9 (Git 2.5rc2)
つまり、以下のことが可能になったということです。
を行う。
git worktree add <path> [<branch>]
<ブロッククオート作成
<path>
をチェックアウトし<branch>
をその中に入れる。新しい作業ディレクトリ は現在のリポジトリにリンクされ、作業用の HEAD、index などのディレクトリ固有のファイルです。 そのためgit worktree
セクションが追加されます。git リポジトリは複数の作業ツリーをサポートすることができます。 これにより、一度に複数のブランチをチェックアウトすることができます。
とはgit worktree add
で、新しい作業ツリーがリポジトリに関連付けられます。この新しい作業木を、"で用意したメイン作業木"に対して、"リンク作業木"と呼びます。
git init
または "。git clone
" .
リポジトリは、(ベアリポジトリでない場合)1つのメイン作業ツリーと、0個以上のリンクされた作業ツリーを持ちます。
の詳細です。
<ブロッククオート
リンクされた各作業ツリーには、リポジトリのプライベートサブディレクトリである
$GIT_DIR/worktrees
ディレクトリに格納されます。
プライベートサブディレクトリの名前は、通常、リンクされた作業ツリーのパスのベースとなる名前に、ユニークにするために数字を付加することもあります。
例えば
$GIT_DIR=/path/main/.git
というコマンドは
git worktree add /path/other/test-next next
を作成します。
-
のリンクされた作業ツリーは
/path/other/test-next
と -
も作成されます。
$GIT_DIR/worktrees/test-next
ディレクトリ(または$GIT_DIR/worktrees/test-next1
もしtest-next
が既に取られている場合)。
リンクされた作業ツリー内。
-
$GIT_DIR
はこのプライベートディレクトリを指すように設定されています (例えば/path/main/.git/worktrees/test-next
の例では) と -
$GIT_COMMON_DIR
は、メインの作業ツリーの$GIT_DIR
(例/path/main/.git
).
これらの設定は
.git
ファイルは、リンクされた作業ツリーのトップディレクトリにあります。
リンクされたワーキング・ツリーを使い終わったら、単純にそれを削除することができます。
リポジトリ内の作業ツリーの管理ファイルは、最終的には自動的に削除されます(
gc.pruneworktreesexpire
で
git config
) を実行することもできます。
git worktree prune
を、メインあるいはリンクされた作業ツリーで
古くなった管理用ファイルを一掃する。
警告:まだ
git worktree
"BUGS"
の部分をご覧ください。
に対応した。
サブモジュール
が不完全である
.
スーパープロジェクトに複数のチェックアウトを行うことは推奨されません。
注意:git 2.7rc1(2015年11月)では、以下のことができるようになりました。
リスト
ワークツリー
参照
コミットbb9c03b
,
コミット 92718b7
,
コミット 5193490
,
コミット 1ceb7f9
,
コミット 1ceb7f9
,
コミット 5193490
,
コミット 1ceb7f9
,
コミット 1ceb7f9
(2015年10月08日)をご参照ください。
コミット 92718b7
,
コミット 5193490
,
コミット 1ceb7f9
,
コミット 1ceb7f9
(2015年10月08日)をご参照ください。
コミット 5193490
,
コミット 1ceb7f9
(2015年10月08日)をご参照ください。
コミット 1ceb7f9
(2015年10月8日)、および
コミット ac6c561
(2015年10月02日)によるものです。
マイケル・ラパッツォ(
rappazzo
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット a46dcfb
, 2015年10月26日)
worktree
: 追加 '
list
' コマンド
'
git worktree list
ワークツリーのリストを繰り返し、出力します。 ワークツリーの詳細(ワークツリーへのパス、現在の チェックアウトされたリビジョンとブランチ、そして作業ツリーが裸であるかどうか。$ git worktree リスト /path/to/bare-source(ベアソース) /path/to/linked-worktree abcd1234 [master] (マスター) /path/to/other-linked-worktree 1234abc (デタッチドHEAD)
また、ポーセリンフォーマットのオプションも用意されています。
ポーセリンフォーマットは、1つの属性につき1行です。
- 属性は、ラベルと値をスペース1つで区切って記載します。
- ブール値属性('bare' や 'detached' など)はラベルとしてのみ表示され、値が真の場合にのみ存在します。
- 空白行は、ワークツリーの終端を示します。
例えば
$ git worktree list --porcelain
worktree /path/to/bare-source
bare
worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master
worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached
注意:ワークツリーフォルダをMOVEする場合、次のことが必要です。
手動で
を更新します。
gitdir
ファイルを作成します。
参照
コミット618244e
(2016年1月22日)、および
コミットd4cddd6
(2016年1月18日)による
Nguyễn Thái Ngọc Duy (
pclouds
)
.
ヘルプドバイ
エリック・サンシャイン (
sunshineco
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミットd0a1cbc
, 2016年2月10日)
新しいドキュメント を git 2.8 (2016年3月) に収録予定です。
リンクされた作業ツリーを移動する場合、'
gitdir
' ファイル をエントリーのディレクトリに配置します。
例えば、リンクされた作業ツリーを/newpath/test-next
とその.git
ファイルが指すのは/path/main/.git/worktrees/test-next
を更新してください。/path/main/.git/worktrees/test-next/gitdir
を参照するように/newpath/test-next
の代わりに
ブランチの削除には注意が必要:git 2.9(2016年6月)以前は、使用中のブランチを削除する際に 別の 作業ツリー
いつ"
git worktree
"機能が使用されている場合、"git branch -d
を許可します。 他のワークツリーでチェックアウトされているブランチを削除する。
参照
コミットf292244
(2016年3月29日)によるものです。
山口和樹さん(
rhenium
)
.
ヘルプドバイ
エリック・サンシャイン (
sunshineco
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット 4fca4e3
, 2016年4月13日)
branch -d
: 現在チェックアウトされているブランチの削除を拒否する
<ブロッククオート
現在の作業ツリーでブランチがチェックアウトされている場合、ブランチの削除は
ブランチは禁止されています。
しかし、そのブランチが他のワーキングツリーからのみチェックアウトされている場合、誤って削除が成功してしまいます。
使用方法
find_shared_symref()
のみならず、そのブランチが使用中であるかどうかをチェックするために
現在の作業ツリーのHEADと比較する。
同様に、git 2.9(2016年6月)以前は、他のワークツリーでチェックアウトしたブランチの名前を変更しても、当該他のワークツリーのシンボリックHEADは調整されませんでした。
参照
コミット 18eb3a9
(2016/04/08)、および
コミット 70999e9
,
コミット 2233066
(2016年3月27日)によるものです。
山口和樹さん(
rhenium
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット741a694
, 2016年4月18日)
branch -m
: ワークツリーごとの HEAD をすべて更新します。
<ブロッククオート
ブランチ名を変更する場合、現在は現在の作業ツリーのHEADのみ を指すすべての作業木のHEADを更新しなければなりません。 旧ブランチ
これは現在の動作で、/path/to/wtのHEADは更新されません。
% git worktree list
/path/to 2c3c5f2 [master]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m master master2
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m oldname newname
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 0000000 [oldname]
このパッチは、関連するすべてのワークツリーのHEADを更新することで、この問題を修正します。 ブランチの名前を変更する際に
ロック機構はgit 2.10(2016年第3四半期)で正式にサポートされています
参照
コミット 080739b
,
コミット 6d30862
,
コミット 58142c0
,
コミット 346ef53
,
コミット 346ef53
,
コミット 58142c0
,
コミット 346ef53
,
コミット 346ef53
(2016年6月13日)、および
コミット 984ad9e
,
コミット6835314
(2016年06月03日)によるものです。
Nguyễn Thái Ngọc Duy (
pclouds
)
.
サジェストバイ
エリック・サンシャイン (
sunshineco
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット 2c608e0
, 2016年7月28日)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
リンクされた作業ツリーがポータブルデバイスまたはネットワーク共有に保存されている場合 常にマウントされていない場合、その管理ファイルから を発行することで、刈り込みが行われます。
git worktree lock
コマンドを実行し、オプションで を指定します。--reason
を使用して、作業ツリーがロックされている理由を説明します。
<worktree>
: 作業木のパスの最後のパス成分が作業木間でユニークであれば、それを使って作業木を識別することができる。
例えば、"にしかワーキングツリーがない場合。/abc/def/ghi
"と"/abc/def/ggg
"の後に、"ghi
"または"def/ghi
"であれば、以前のワーキングツリーを指すのに十分です。
Git 2.13 (2017年第2四半期) 追加の
lock
オプション
で
コミット 507e6e9
(2017年4月12日)による
Nguyễn Thái Ngọc Duy (
pclouds
)
.
サジェストバイ
デビッド・テイラー (
dt
)
.
ヘルプドバイ
ジェフ・キング (
peff
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット e311597
, 2017年4月26日)
ワークツリーを作成後、すぐにロックできるようにしました。
これは、".NETと".NETの間の競合を防ぐのに役立ちます。
git worktree add; git worktree lock
と
"
git worktree prune
"です。
そこで
git worktree add' --lock
は、次のものと同等です。
git worktree lock
の後に
git worktree add
しかし、レースコンディションはありません。
Git 2.17+(2018年第2四半期)より追加されました。
git worktree move
/
git worktree remove
:
この回答を見る
.
Git 2.19(2018年第3四半期)"を追加しました。
--quiet
"オプションで、"
git worktree add
を減らすことができます。
を冗長にします。
参照
コミット 371979c
(2018年8月15日)によるものです。
エリア・ピント (
devzero2000
)
.
Helped-by: Martin Ågren [email protected]。
Duy Nguyen (
pclouds
)
および
エリック・サンシャイン (
sunshineco
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット a988ce9
, 2018年8月27日)
worktree
: 追加
--quiet
オプション
を追加します。
--quiet
というオプションをgit worktree
のように、他のgit
コマンドを使用します。
'add
を除く他のすべてのコマンドは、この影響を受けるので、'は唯一のコマンドです。list
は、現在デフォルトでサイレントになっています。
なお、"
git worktree add
以前は、quot;利用可能な名前をstatで検索していました。
そして
mkdir
"、これはレースが起こりやすい。
この現象は、Git 2.22 (2019 年第 2 四半期) で、次のように修正されました。
mkdir
に反応し
EEXIST
をループさせる。
参照
コミット 7af01f2
(2019年2月20日)によるものです。
ミハエル・スチャネク (
hramrach
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット20fe798
, 2019年04月09日)
worktree
: 修正
worktree add
レース
<ブロッククオート
Gitは、利用可能なワークツリー名を見つけるためにstatループを実行し
を実行します。
mkdir
という名前になります。
に変えてください。
mkdir
ループを使用することで、worktree add が同じフリーネームを見つけ、最初にディレクトリを作成することを回避できます。
Git 2.22(2019年第2四半期)では、Gitリポジトリに作業ツリーが保護されているかどうかを判別するロジックが修正されました"。
git branch -D
現在チェックされているブランチが削除されないよう
を誤って出力してしまう。
このロジックの実装は、最近のサブモジュールの主流である、変わった名前のリポジトリに対して壊れていました。
参照
コミット f3534c9
(2019年4月19日)によるものです。
ジョナサン・タン (
jhowtan
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット ec2642a
, 2019年05月08日)
worktree
: アップデート
is_bare
ヒューリスティック
<ブロッククオート
いつ"
git branch -D <name>
を実行すると、Git は通常、最初にその
ブランチは現在チェックアウトされています。
しかし、そのリポジトリのGitディレクトリが"にない場合、このチェックは行われません。
<repo>/.git
これは、そのリポジトリがサブモジュールで、その Git ディレクトリが " に格納されている場合です。
super/.git/modules/<repo>
"などです。
この結果、チェックアウトされているにもかかわらず、ブランチが削除されてしまいます。
これは
get_main_worktree()
で
worktree.c
セット
is_bare
の
ワークツリーのレポは、ワークツリーの
のパスが " で終わっていない場合。
/.git
それ以外の場合は、裸ではありません。
これは
is_bare
のコードが導入されました。
92718b7
("
worktree
: add details to worktree struct", 2015-10-08, Git v2.7.0-rc0) に続く。
pre-core.bare
ヒューリスティックに
このパッチは2つのことを行います。
-
教える
get_main_worktree()
を使用するis_bare_repository()
で紹介した 7d1864c ("Introduce is_bare_repository() and core.bare configuration variable", 2007-01-07, Git v1.5.0-rc1) で更新され、さらに e90fdc3 ("Clean up work-tree handling", 2007-08-01, Git v1.5.3-rc4) があります。
これにより、"git branch -D <name>
"の問題は前述したとおりです。
しかし... -
もし、リポジトリに
core.bare=1
が、"git
"コマンドは、そのセカンダリワークツリーの1つから実行されています。is_bare_repository()
は false を返します(利用可能なワークツリーがあるため、問題ありません)。
また、メインワークツリーが裸である場合に、それを裸でないものとして扱うと、例えば、メインワークツリーのHEADによって参照されるセカンダリワークツリーからのブランチを、そのメインワークツリーが裸であっても削除できないといった問題が発生する。
それを避けるために
core.bare
を設定する際に
is_bare
.
もし
core.bare=1
を使用し、それ以外の場合は
is_bare_repository()
.
Git 2.29 (2020年第4四半期) で、"
worktree
" API は、ワークツリーのパスのより良い決定を提供します。
参照
コミット 918d8ff
,
コミット 1c4854e
,
コミット246756f
,
コミット 62573a5
(2020年7月31日)による
エリック・サンシャイン (
sunshineco
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット 197253e
, 2020年8月10日)
worktree
不要なパスを削除する。
サインオフバイ:エリック・サンシャイン
<ブロッククオート
の内容は
.git/worktrees/<id>/gitdir
は " という形式のパスでなければなりません。
/path/to/worktree/.git
"です。
これ以外の内容は、"が破損していることを示しています。
gitdir
"ファイルです。
ワークツリー自体のパスを決定するには、単に"を取り除くだけです。
/.git
というように、ワークツリーのパスが最初から決まっているのです。
しかし
5193490442
("
worktree
: ワークツリーの詳細を取得する関数を追加", 2015-10-08, Git v2.7.0-rc0 --。
マージ
に記載されている
一括7位
)は、不思議な方法でパス操作を拡張しました。
もし、"を剥がすことができない場合。
/.git
の代わりに、現在の作業ディレクトリをリンク先のワークツリーのパスとして報告します。
if (!strbuf_strip_suffix(&worktree_path, "/.git")) {
strbuf_reset(&worktree_path);
strbuf_add_absolute_path(&worktree_path, ".");
strbuf_strip_suffix(&worktree_path, "/.");
}
この論理は明らかにインチキであり、一般的に正しい行動であるはずがない。このロジックは 5193490442 を、それが望ましいとされるケースを説明するための説明もテストもない。
このロジックは、不正な"に何とか対処するために導入された可能性があります。
gitdir
を返すようにしました。
一部
のような意味のある値を返しますが、現在の作業ディレクトリを返すことは役に立ちません。実際、これは非常に誤解を招きやすいものです(ただし、カレントディレクトリが " のワークツリーであるという特殊なケースは例外です)。
gitdir
のエントリが破損しています)。
さらに、破損した値を偽ってそのまま隠すよりも、ユーザーに報告した方が、問題の診断に役立つ可能性があるため、より有用です。
したがって、このインチキパスマンギングをやめて、単に"をストリッピングするという元の動作にロジックを戻してください。
/.git
"です。
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] リモートのGitブランチをチェックアウトするには?
-
[解決済み] Git リポジトリを以前のコミットに戻すにはどうすればよいですか?
-
[解決済み] 現在のGit作業ツリーからローカル(未追跡)ファイルを削除する方法
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み] Git で最新のコミットを新しいブランチに移動する
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Git Push Error: リポジトリデータベースにオブジェクトを追加する権限が不足しています。
-
[解決済み] LFはgitでCRLFに置き換えられます - それは何ですか、そしてそれは重要ですか?[重複]。
-
[解決済み] GitHubです。パーミッションが拒否されました (公開鍵)。
-
[解決済み] Gitのフォルダ構造で変更・追加されたファイルのみをエクスポートする機能
-
[解決済み] gitのルートディレクトリを1つのコマンドで取得する方法はありますか?
-
[解決済み] Git ですべてのリモートブランチをクローンする方法
-
[解決済み] GitのHEAD、作業ツリー、インデックスの違いは何ですか?
-
[解決済み] 実行中のnode.jsアプリケーションからプロジェクトルートを決定する
-
[解決済み】Bareリポジトリと非Bareリポジトリの -実用的な- 違いは何ですか?
-
[解決済み】gitが2つのブランチで同時に動作する件