空のディレクトリをGitリポジトリに追加するにはどうすればよいですか?


4267

空のディレクトリ(ファイルを含まない)をGitリポジトリに追加するにはどうすればよいですか?


16
便利ではありませんが、空の(本当に空の)ディレクトリをリポジトリにハッキングする方法がありますcheckoutただし、現在のバージョンのGit には対応していません。
tiwo

335
@tiwo役に立たないという意見は1つありません。ディレクトリ階層はプロジェクトの一部であるため、バージョン管理する必要があります。
JBentley 2013年

114
私の場合、tmpファイル自体ではなく、tmpファイル用のディレクトリ構造を追加したいと思います。これを行うことで、テスターは正しい構造になります(そうでない場合、エラーがあります)が、tmpデータでコミットを詰まらせません。そう、それは私にとって便利です!
アダムマーシャル

45
@AdamMarshallチェックアウトでは無視されるため、ハッキングは役に立たないとティウォが言っていたと思います。Tmp dirsは、VCSの便利な機能のように聞こえます。
Quantum7 2013

31
tmpファイルを作成する手順でtmpディレクトリも作成しないのはなぜですか?
RyPeck 2013

回答:


4128

(リポジトリ内で)ディレクトリを(ほとんど)空のままにする別の方法.gitignoreは、次の4行を含むディレクトリ内にファイルを作成することです。

# Ignore everything in this directory
*
# Except this file
!.gitignore

次に、m104のソリューションで行う必要がある方法で正しい順序を取得する必要はありません。

これにより、gitステータスを実行したときに、そのディレクトリ内のファイルが「追跡されていない」ものとして表示されないという利点もあります。

作る@GreenAsJadeのコメント永続:

この解決策は質問が要求したことを正確に実行することは注目に値しますが、おそらくこの質問を見ている多くの人々が探していたものではないでしょう。このソリューションは、ディレクトリが空のままであることを保証します。「ここにファイルをチェックインしたくない」と書いてある。「ここにチェックインするファイルはまだありませんが、ここにディレクトリが必要です。後でファイルが来る可能性があります」とは対照的です。


25
@JohnMeeが提案したREADMEソリューションは、これと一緒に使用する必要があると思います。.gitignoreファイルはバージョン管理の対象外となるものの説明を提供し、READMEファイルはディレクトリの目的を説明します。これらはどちらも非常に重要な情報です。
pedromanoel 2013年

18
@pedromanoel (コメントとして)ファイルREADME内に配置するドキュメントを書き.gitignoreます。
CarlosCampderrós2013

69
1つの違いを見つけます:1.)空のフォルダー、2 .. .gitignoreファイルが入っているフォルダー。;-)
PeterPerháč2014

6
これは、キャッシュフォルダーに最適です。
2014年

10
残念ながら、これは空でないディレクトリをもたらし、単一の隠しファイルを持っています。
pedorro 2014

1091

できません。Git FAQを参照してください

現在、gitインデックス(ステージング領域)の設計では、ファイルのリストのみを許可しており、空のディレクトリを許可するように変更を行うのに十分な能力を持つ人は、この状況を修正するのに十分注意していません。

ディレクトリは、その中にファイルを追加すると自動的に追加されます。つまり、ディレクトリをリポジトリに追加する必要はなく、単独で追跡されることもありません。

git add <dir>」と言うと、そこにファイルが追加されます。

チェックアウトに存在するディレクトリが本当に必要な場合は、その中にファイルを作成する必要があります。.gitignoreはこの目的に適しています。空のままにするか、ディレクトリに表示される予定のファイルの名前を入力できます。


67
以下の答えははるかに優れています。低レベルのソフトウェアをgitで許可していないという事実は、空のディレクトリが必要なときに実際にGitを使用する方法ほど重要ではありません。2行の.gitignoreを追加することは私には受け入れられるようです。
アマラ2011

1
ファイルを新しいディレクトリに移動したい場合git mv、gitは新しいディレクトリがバージョン管理されていないと文句を言うので、彼らはそれを実行できません
lulalala

16
このよくある質問については、インターネット上で「不可能、不可能など」を読むことができます。.gitignoreトリックは、頻繁な答えである、を満たす多くのニーズ。しかし、可能です gitのトラックを作るために、本当に空のディレクトリを私の答えを参照
ofavre

2
考えれば考えるほど、「空の文字列のSHAハッシュ」のような感じがしますが、それが存在する場合、そのオブジェクトが木かブロブ。
Emil Lundberg 2013

21
.gitkeepこの目的のために呼び出された空のファイルを使用する多くのリポジトリを見てきました。
スキマ

759

.gitkeepディレクトリに空のファイルを作成し、それを追加します。


58
代わりに作成を促す回答を追加しました.keep
Acumenus 2014年

206
.gitkeepはGitで規定されておらず、人々がその意味を2番目に推測するようになり、その結果、Google検索につながり、ここで彼らを導きます。.git接頭辞規則は、Gitの自体が使用するファイルやディレクトリのために確保されなければなりません。
t-mart

10
@ t-mart「.gitプレフィックス規約は予約する必要があります...」なぜですか?gitはこの予約を要求しますか?
限定的な贖罪2014

9
この場合、READMEまたはABOUTファイルは同じかそれ以上です。URLの前に私たち全員が行っていたように、次の人にメモを残します。
デイブ

5
空のディレクトリでコードをテストする必要がある単体テストを記述している場合は機能しません...
thebjorn

437

リポジトリにREADMEファイルを置く理由を説明したREADMEファイルを、いつでも空にすることができます。


39
+1、良い提案です。空のディレクトリは、将来使用する予定がない限り意味がありません。したがって、その中にREADMEファイルを作成し、このディレクトリの目的、および今後そこに配置するファイルを記述します。これで2つの問題が解決されます。
saeedgnu 2011

63
@iliusナンセンス。空のディレクトリを含むディレクトリ構造は、多くの状況で非常に望ましい場合があります(モデルディレクトリが必要だが、モデルの作成にまだ慣れていないMVCアプリ、または後で共有ビューを追加する予定の共有ビューディレクトリなど)。 )。さらに、これらのそれぞれにREADMEを置くことは、それらが何のためにあるのかが明らかであり、それぞれにREADMEを入れるのを忘れがちなので、やり過ぎです。また、他のファイルを追加するときは、READMEを必ず削除してください。基本的に、gitは必ず空のディレクトリを許可する必要があります。
Jez

20
@ジェズ:同意しない。ポイントは、gitがソースコードを制御(およびインデックス付け)するように設計されているということです。重要なことに、コミットのIDはコンテンツのハッシュです。つまり、コンテンツが必要です。ツリーのすべての部分にREADMEは必要ありません。リーフノードだけが必要です。コードを配置する予定の場所があり、コードがない場合、そして「モデルの場所」>> READMEをエコーする時間さえ取らない場合、あなたが持っているのはコミットではないアイデアです。gitには関係ありません。「実行中のアプリにXYZ空のディレクトリを持たせたい」と言うのはランタイムの問題であり、ソースの問題ではありません。インストーラーで処理してください。
Joe Atzberger 2013年

6
@JoeAtzbergerこれは欠けている機能であり、意図的な制限ではありません。Git FAQから:現在、Gitインデックス(ステージング領域)の設計ではファイルのリストのみが許可されており、空のディレクトリを許可するように変更を行うのに十分な能力のある人は誰も
jbo5112 2013年

7
@ jbo5112はい、あなたが言及する「特別なコード」は私が述べた「インストーラー」です。Webアプリケーションのインストールでは、データベースの作成、ローカル構成、依存関係のプル、その他100の操作を処理する必要がありますが、空のディレクトリが2つ以上ありますか?gradle、passenger、chef、プリミティブMakefileなどを試してください。ディレクトリを作成することと、アプリをインストールするその他の(はるかに複雑で危険な可能性がある)作業との間にセキュリティ上の違いはありません。そして、dep、config、DBなどがなく、インストーラもない場合は、READMEを使用してください。両方を行う必要のあるケースはありません。
Joe Atzberger 2013年

349
touch .keep

Linuxでは、これはという名前の空のファイルを作成します.keep。価値があるので、この名前はGitに依存し.gitkeepませんが、Gitに固有です。第二に、別のユーザーが指摘したように、.gitGit自体が使用するファイルとディレクトリのために接頭辞規則を予約する必要があります。

または、別の回答に記載されているように、ディレクトリには代わりに説明READMEまたはREADME.mdファイルを含めることができます。

もちろん、これにはファイルの存在によってアプリケーションが壊れないことが必要です。


1
これは最初のベアディレクトリには適していますが、ファイルでいっぱいになり始めたらどうなるでしょうか。その後、Gitはそれらに気づき、追跡されていないファイルとしてそれらを要求します。ここで選択された回答ははるかにエレガントに機能し、ディレクトリを保持できるようにしますが、内容は無視しても安全です。
JakeGould 2014

14
空のディレクトリを追加することに関する質問と主な一般的な懸念です。後で常駐ファイルがある場合は、その.keepファイルを削除するか、単に無視します。代わりに、ディレクトリ内のファイルを無視する場合は、まったく別の問題です。
Acumenus 2014

3
git clean -nd | sed s/'^Would remove '// | xargs -I{} touch "{}.keep"追跡されていないすべての空のディレクトリでこれを行うことが提案されました。
Acumenus 2014年

1
このソリューションが気に入らない場合、このファイルの機能を推測するのは困難です。また、開発環境でファイル(ログやイメージなど)を生成している場合、これはそれらのファイルがバージョン管理されて本番環境に移行しないようにするものではないため、不快です。
danielrvt 2016年

1
Windowsは名前のないファイルは好きではなく、これを実現するには特別な魔法が必要です(別名bashのようなターミナルアプリまたは同等のもの)。
EntangledLoops

303

なぜバージョン管理された空のフォルダが必要なのでしょうか

まず最初に:

空のディレクトリをGitバージョン管理システムのツリーの一部にすることはできません

それは単に追跡されません。ただし、次の例のように、空のディレクトリの「バージョン管理」が意味を持つシナリオがあります。

  • 事前定義されたフォルダ構造を足場にして、リポジトリのすべてのユーザー/寄稿者が利用できるようにします。または、用フォルダの作成、上記の専門場合と一時ファイルのような、cache/またはlogs/私たちは、フォルダが、提供したいディレクトリ、.gitignoreその内容を
  • 上記に関連して、一部のプロジェクトは一部のフォルダーなしでは機能しません(これは、多くの場合、設計が不十分なプロジェクトのヒントですが、現実のシナリオで頻繁に発生し、おそらく、アクセス許可の問題が発生する可能性があります)。

いくつかの推奨される回避策

多くのユーザーからの提案:

  1. READMEディレクトリを空にしないために、コンテンツを含むファイルまたは別のファイルを配置する、または
  2. 作成.gitignore「逆の論理」の一種で、ファイルを最後に、アプローチ#1の同じ目的を果たしている、(すなわち、すべてのファイルを含めます)。

一方で、両方のソリューションが確実に動作し、私はバージョン管理Gitリポジトリに意味のあるアプローチでそれら矛盾を見つけます。

  • プロジェクトに本当に必要ないかもしれない偽のファイルやREADMEを置く必要があるのはなぜですか?
  • なぜ.gitignore物事をするのに使うのか(それが可能であるにもかかわらず、それが意図していること(ファイルを除外すること)とは正反対のファイルを保持すること)ですか?

.gitkeepアプローチ

を使用 .gitkeepバージョン管理システムにフォルダが存在するように強制するために呼び出される空のファイルをます。

それはそれほど大きな違いではないように見えるかもしれませんが:

  • あなたが持っているファイルを使用します フォルダーを保持する単一の目的します。あなたが置きたくない情報はそこには入れません。

    たとえば、フォルダを保持するための言い訳としてではなく、有用な情報が含まれているREADMEも使用する必要があります。

    懸念の分離は常に良いことであり、 .gitignore不要なファイルを無視をます。

  • 名前を付けると.gitkeep、ファイル名自体から(そして他の開発者にとっても)非常に明確かつ簡単になりますにとっても、共有プロジェクトおよびGitリポジトリの主要な目的の1つに適しています)から、このファイルは

    • コードに関係のないファイル(先頭のドットと名前のため)
    • 明らかにGitに関連するファイル
    • その目的(keep)は明確に述べられており、一貫しており、無視するという意味で意味的に反対している

可決

LaravelAngular-CLI.gitkeepなどの非常に重要なフレームワークで採用されているアプローチを見てきました。


8
あなたは一つの見落としを見逃しました-フォルダーを空のままにする理由は何ですか(例/ logs、/ tmp、/ uploads)?はい-フォルダを空のままにします。:)したがって、フォルダを空のままにしたい場合は、その中のファイルを無視する必要があります。
ローマの

14
@RomanAllenstein:必ずしもそうではありません。特定の構造を持つリポジトリを作成し、後で入力することができます。それらのファイルは作成されるとすぐにリポジトリに追加され、.gitignoreファイルの削除や編集を開始するのは面倒です(そして、おそらく追跡されていないことに気づいていないので危険です:gitはそれらを無視しています)
blueFast 2015

45
@ベナム:私は反対票を投じますが、SOメタに関する私の調査は、すべての読者(およびすべてのスキルレベル)に役立つ十分な詳細と明快さを提供する限り、詳細な回答に対する懸念を示していません。それでも私はどんな批判に対しても非常にオープンです。理由を公に宣言してくれてありがとう、私はそれを非常に積極的に受け止めます。
クラニオ

4
答えを編集.gitkeepして、他のgit接頭辞のないファイル名に置き換えると、私の賛成票が得られますが、これが最良で最も有益な答えだと思います。理由:これは単なるプレースホルダーですが、「。git *」はgitの規定ファイル用に予約する必要があると思います。私が最初にそれを目にしたのは、たとえば ".gitkeep"ファイルは自動的に無視される(すばらしい機能です)と思いますが、そうではありません。
ジョニー

5
なぜ「空の」フォルダをgitに追加したいのかを理解するのが難しいのはなぜでしょうか。どこかから始めなければなりませんよね?したがって、通常はプロジェクトのフォルダ構造から開始し、悲しいことに-プロジェクトの最初はまだ何もありません。プロジェクトリポジトリが完了すると、チームワーカーはSAME構造のクローンを作成して作業を開始できます。
BitTickler 2018年

127

他の回答で説明されているように、Gitはステージング領域で空のディレクトリを表すことができません。(Git FAQを参照してください。)ただし、目的のために、.gitignoreファイルのみが含まれているディレクトリが十分に空である場合、次の.gitignore方法でのみ空のディレクトリにファイルを作成できます。

find . -type d -empty -exec touch {}/.gitignore \;

21
あなたは.gitディレクトリを無視することもできます。 find . -name .git -prune -o -type d -empty -exec touch {}/.gitignore \;
ステファン

3
ほとんどの状況でのより単純なバリエーションはfind * -type d -empty -exec touch {}/.gitignore \;
akhan

2
OS Xは、ほとんどすべてのディレクトリに.DS_Storeファイルを作成するため、これはそこで機能しません。私が見つけた唯一の(危険!)回避策は、最初にすべての.DS_Storeファイルを削除してfind . -name .DS_Store -exec rm {} \;から、この回答から優先バリアントを使用することでした。正しいフォルダでのみ実行してください!
zerweck 2015

1
コマンドラインからWindowsでこれを行う方法を誰かが知っていますか?RubyとPythonでいくつかのソリューションを見てきましたが、それが管理できるのであれば、必要最低限​​のソリューションが欲しいです。
Mig82 2017年

1
@akhanに何かを追加し.gitignoreても-emptyfindコマンドのフラグには影響しません。私のコメントは.DS_Store、ディレクトリツリー内のファイルを削除することですので、-emptyフラグを適用できます。
ゼルヴェック2017

68

アンディ・レスターは正しいですが、あなたのディレクトリは単に空である必要があり、そうでない場合、空の空、空を置くことができます.gitignore、回避策として、そこにファイルを。

余談ですが、これは実装の問題であり、基本的なGitストレージ設計の問題ではありません。Gitメーリングリストで何度も言及されているように、これが実装されていない理由は、誰もパッチを提出するのに十分な配慮がなされていないことであり、実行できなかった、または実行できないことではありません。


4
それはまさに私が言ったことです。どちらの段落も、私が投稿したFAQのスニペットで対処されています。
アンディレスター

1
余談はおもしろくて知っておくと便利だと思います-修正することができますが、ほとんどの場合、このような簡単な回避策があるときにすぐに期待しないでください。
wnoise 2008

申し訳ありませんが、最後の段落は読みませんでした。最初の段落は読みましたが、なぜその情報を繰り返したのかわかりません。
アリストテレスパガルツィス

2
もちろん、この追加の回答は事実を指摘するのに役立ちます。
マイケル・ジョンソン

私はここに、ディレクトリが存在せずデフォルトで空である場合にビルドが落ちるケースを見ましたが、空である必要はありません。.gitignoreの作成は正しいことを行います。
ジョシュア

33

Ruby on Railsが作成途中のフォルダログインします。

mkdir log && touch log/.gitkeep && git add log/.gitkeep

これで、ログディレクトリがツリーに含まれます。デプロイ時に非常に便利なので、ログディレクトリを作成するルーチンを作成する必要はありません。

ログファイルは、

echo log/dev.log >> .gitignore

しかし、あなたはおそらくそれを知っていました。


23
Ruby on Railsとどう関係しているのですか?
Quolonelの質問2015


30

Gitは空のディレクトリを追跡しません。詳細については、Git FAQを参照してください。推奨される回避策は.gitignore、空のディレクトリにファイルを配置することです。その解決策は好きではありません。.gitignore Unixの慣例によって「隠されいる」。また、ディレクトリが空である理由も説明されていません。

READMEファイルを空のディレクトリに配置して、ディレクトリが空である理由とGitで追跡する必要がある理由を説明することをお勧めします。READMEファイルを配置すると、Gitに関する限り、ディレクトリは空ではなくなります。

本当の質問は、なぜgitに空のディレクトリが必要なのですか?通常、コンパイル/実行する前に空のディレクトリを作成できる、ある種のビルドスクリプトがあります。そうでない場合は、1つ作成します。これは、gitに空のディレクトリを配置するよりもはるかに優れたソリューションです。

したがって、gitに空のディレクトリが必要な理由がいくつかあります。その理由をREADMEファイルに入れてください。そうすれば、他の開発者(そして将来あなたも)は、空のディレクトリが存在する必要がある理由を知っています。空のディレクトリを必要とする問題が解決されたら、空のディレクトリを削除できることもわかります。


空のディレクトリをすべて一覧表示するには、次のコマンドを使用します。

find -name .git -prune -o -type d -empty -print

すべての空のディレクトリにプレースホルダーのREADMEを作成するには:

find -name .git -prune -o -type d -empty -exec sh -c \
  "echo this directory needs to be empty because reasons > {}/README.emptydir" \;

READMEファイルを除くディレクトリ内のすべてを無視するには、次の行をに入れます.gitignore

path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir

または、すべての READMEファイルを無視しないように除外することもできます。

path/to/emptydir/*
path/to/otheremptydir/*
!README.emptydir

作成後にすべてのREADMEをリストするには:

find -name README.emptydir

28

警告:この調整は、実際には機能していません。ご不便おかけしてすみません。

以下の元の投稿:

Gitの内部で遊んでいるときに解決策を見つけました!

  1. リポジトリにいるとします。
  2. 空のディレクトリを作成します。

    $ mkdir path/to/empty-folder
    
  3. 配管コマンドと空のツリーSHA-1を使用して、インデックスに追加します。

    $ git update-index --index-info
    040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904    path/to/empty-folder
    

    コマンドを入力してから、2行目を入力します。押しEnterた後、Ctrl+ Dあなたの入力を終了します。注:形式はモード [スペース] タイプ [スペース] SHA-1ハッシュ[タブ]パスです(タブは重要です。回答のフォーマットでは保持されません)。

  4. それでおしまい!空のフォルダがインデックスにあります。あなたがしなければならないすべてはコミットです。

このソリューションは短く、明らかにうまく機能します(編集を参照してください!)が、覚えるのはそれほど簡単ではありません...

空のツリーSHA-1を見つけるには、新しい空のGitリポジトリをその中に作成し、空のツリーSHA-1を出力するcdを発行git write-treeします。

編集:

このソリューションを見つけてからずっと使っています。どこにもモジュールが定義されていないことを除いて、サブモジュールの作成とまったく同じように機能するようです。これにより、発行時にエラーが発生しgit submodule init|updateます。問題はgit update-index040000 treeパーツをに書き換えること160000 commitです。

さらに、そのパスの下に置かれたファイルは、他のリポジトリに属していると見なされるため、Gitによって認識されることはありません。これは簡単に見落とされる可能性があるため、厄介です!

ただし、リポジトリでGitサブモジュールをまだ使用していない(そして使用しない)場合、「空の」フォルダーは空のままになるか、Gitがその存在を認識してその内容を無視するようにしたい場合は、この微調整。サブモジュールを通常の方法で使用するには、この微調整よりも多くの手順が必要です。


空のフォルダーをインデックスに入れてコミットした後git svn dcommit、希望の結果でそれを行うことは可能ですか?
限定的な贖罪2014

2
この微調整が他のツールで機能することはほとんどありません。警告と編集で述べたように、かなり制限された場合を除いて、私はそれを使用しないようにします。
ofavre

1
そしてもちろん、これがgit内部をいじることが禁忌である理由です。
ケーシー

@abhisekpそれはどのようにして可能ですか?
PyRulez

1
@PyRulezよく、ソフトウェアの世界では、不可能はありません。:D実際には、私は答えに従いました。
abhisekp

21

tmpという名前の空のディレクトリが必要だとします。

$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp

言い換えると、Gitにそれ(および空のディレクトリ内の他のすべて)を無視するように指示する前に、.gitignoreファイルをインデックスに追加する必要があります。


11
2つのこと:タッチする代わりに、単に「エコー '*'> tmp / .gitignore」とすることができ、「git commit -m」は、ファイルをインデックスに追加した後に行われた変更をコミットしません。
ChristofferHammarström、2010年

6
あなただけ行う場合はecho bla > file、あなたが得ることはありませんfile: File existsので>、それはすでにあります場合は、ファイルを上書きするか、それが存在しない場合は新規に作成されます。
psyrendust 2014

3
/bin/sh文化的仮定!*「ここ」がcshあり、変数noclobberが設定されている場合、実際に取得されfile: File existsます。誰かが「私はこれを手に入れました」と言った場合、彼らがバカだと思い込まず、「いいえ、あなたはしません」と答えます。* c2.com/cgi/wiki?AmericanCulturalAssumption
2015年

1
@clacke誰かが他の全員とは異なるシェルを使用することを決定した場合、問題が発生している場合は明示的にそのことを述べる必要があります。国籍とは異なり、誰でもシェルを自由に選択できます。
SeldomNeedy 2016年

2
@SeldomNeedy多分彼らは彼らが他の人とは異なるシェルを使用していることさえ知らないので彼らは助けを探しています。
2016年

20

空のディレクトリの追加は、そのディレクトリが存在することを期待するスクリプトがあるため(おそらく生成されたバイナリのターゲットであるため)、抵抗が最も少ないパスのように思われます。別のアプローチは、スクリプト変更して、必要に応じてディレクトリを作成することです

mkdir --parents .generated/bin ## create a folder for storing generated binaries
mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed

この例では、ディレクトリへの(壊れた)シンボリックリンクをチェックインして、「。generated」プレフィックスなしでアクセスできるようにします(ただし、これはオプションです)。

ln -sf .generated/bin bin
git add bin

ソースツリーをクリーンアップしたいときは、次のことができます:

rm -rf .generated ## this should be in a "clean" script or in a makefile

ほぼ空のフォルダーをチェックインするという推奨されるアプローチをとる場合、「。gitignore」ファイルを削除せずにコンテンツを削除するという複雑さはわずかです。

ルートの.gitignoreに以下を追加することで、生成されたすべてのファイルを無視できます。

.generated

1
注:私が提案したシンボリックリンク.generatedは、最初はディレクトリが存在しないため、クリーンチェックアウトでは「壊れています」。ビルドを行っても壊れることはありません。
nobar 2012年

2
これは非常に良い考えである場合もありますが、他の場合(たとえば、models /やviews /などのフォルダーを含む空のスケルトンがあるプロジェクトを配布する場合など)は、ユーザーがこれらのディレクトリを手元に置いておくとよいでしょう。手動でドキュメントを読む必要があるよりも、リポジトリを複製した後に何らかのインストールスクリプトを実行することを期待するのは少し難しいかもしれません。この回答と@ john-meeのREADME回答を組み合わせると、すべてではないにしてもほとんどのケースをカバーできると思います。
moopet 2014年

14

私も空のディレクトリの問題に直面しています。プレースホルダーファイルを使用する場合の問題は、それらを作成し、不要になった場合は削除する必要があることです(後でサブディレクトリやファイルが追加されたためです)。大きなソースツリーを使用すると、これらのプレースホルダーファイルを管理するのが面倒でエラーになる可能性があります。腹痛。

そのため、このようなプレースホルダーファイルの作成/削除を自動的に管理できるオープンソースツールを作成することにしました。.NETプラットフォーム用に作成され、Mono(Linuxの場合は.NET)とWindowsで動作します。

ちょうど見てくださいhttp : //code.google.com/p/markemptydirs


14

@ Artur79と@mjsの回答が気に入ったので、両方を組み合わせて使用​​し、プロジェクトの標準にしました。

find . -type d -empty -exec touch {}/.gitkeep \;

ただし、MacまたはLinuxで作業している開発者はごくわずかです。Windowsでは多くの作業が行われ、そこで同じことを達成するための同等のシンプルなワンライナーを見つけることができませんでした。他の理由でCygwinをインストールできる幸運な人もいましたが、これだけのためにCygwinを処方するのはやり過ぎに思えました。

より良いソリューションのために編集する

ですから、ほとんどの開発者はすでにAntをインストールしているので、私が最初に考えたのは、Antビルドファイルをまとめて、これをプラットフォームとは独立して実現することでした。これはまだ見つかりますここにあります

ただし、後でこれを小さなユーティリティコマンドにした方がよいと思ったので、Pythonを使用して再作成し、ここのPyPIに公開しました。次のコマンドを実行するだけでインストールできます。

pip3 install gitkeep2

.gitkeepファイルを再帰的に作成および削除できるほか、ピアにメッセージを追加して、これらのディレクトリが重要である理由を理解することもできます。この最後のビットはボーナスです。.gitkeepファイルが自己文書化できればいいと思いました。

$ gitkeep --help
Usage: gitkeep [OPTIONS] PATH

  Add a .gitkeep file to a directory in order to push them into a Git repo
  even if they're empty.

  Read more about why this is necessary at: https://git.wiki.kernel.org/inde
  x.php/Git_FAQ#Can_I_add_empty_directories.3F

Options:
  -r, --recursive     Add or remove the .gitkeep files recursively for all
                      sub-directories in the specified path.
  -l, --let-go        Remove the .gitkeep files from the specified path.
  -e, --empty         Create empty .gitkeep files. This will ignore any
                      message provided
  -m, --message TEXT  A message to be included in the .gitkeep file, ideally
                      used to explain why it's important to push the specified
                      directory to source control even if it's empty.
  -v, --verbose       Print out everything.
  --help              Show this message and exit.

お役に立てば幸いです。


13

できませんし、残念ながらできません。これは、Linus Torvald自身が行った決定です。彼は私たちにとって何が良いのかを知っています。

私が一度読んだどこかに暴言があります。

私はRe:空のディレクトリを見つけました..、しかし別のディレクトリがあるかもしれません。

あなたは回避策と一緒に生きなければなりません...残念ながら。


1
あなたがこれを悪い議論の例として投稿したのは知っていますが、リンクを追跡することに対する実際の根拠のある議論であるため、リンクに感謝します。;-)
2015年

1
Linus Torvaldは、参照されているスレッドの次の投稿で、ディレクトリトラッキングを追加する必要があると予想しているため、この回答は一貫していないようです:markmail.org/message/libip4vpvvxhyqbl。実際、彼は「[空のディレクトリを追跡するためのサポートを追加する]パッチを歓迎します」
Patrick M

パトリック、彼はそこでも「イディオティック」という言葉を使っています。彼の言葉遣いはこのスレッドの人々をここで扱っているのではないかと思うので、彼が自分でGitに「馬鹿げたこと」を実装することはないと思います。
user2334883 2017

10

.gitignoreファイルを追加するときに、Gitに無視させたいコンテンツをいくらか入れようとする場合は、アスタリスクだけの1行を*追加して、無視したコンテンツを誤って追加しないようにすることができます。 。


9

Gitにディレクトリを追跡させる方法はないので、唯一の解決策は、Gitに追跡させたいディレクトリ内にプレースホルダーファイルを追加することです。

ファイルには名前を付けて、好きなものを含めることができますが、ほとんどの人は空のファイル名を使用します.gitkeep(ただし、VCSに依存しない.keep)。

接頭辞付き .ていると、隠しファイルとしてマークされます。

別のアイデアはREADME、ディレクトリが何のために使用されるかを説明するファイルを追加することです。


8

前述のとおり、空のディレクトリを追加することはできませんが、空の.gitignoreファイルをすべてのディレクトリに追加する1つのライナーがあります。

ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'

簡単にアクセスできるように、これをRakefileに貼り付けました。


6
私はむしろ使いたいfind . -type d -empty -print0 | xargs --null bash -c 'for a; do { echo "*"; echo "!.gitignore"; } >>"$a/.gitignore"; done' --
Tino

8

Jamie Flournoyの解は素晴らしい働きをします。これは、を維持するための少し拡張されたバージョン.htaccessです。

# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess

このソリューションを使用すると、空のフォルダをコミットできます。たとえば/log/tmpまたは/cacheフォルダは空のままになります。


2
彼はファイルではなく空のディレクトリを保持したいと考えています。
gvsrepins 2014

2
そして、私はそれが.htaccessも保持することを述べました。例:ソフトウェアに、ウェブ経由でアクセスできないログファイル用のディレクトリ(oxid eshopなど)がある場合、そのディレクトリには.htaccessがあります。上記の.gitignoreをフォルダーに配置すると、.htaccessはコミットされず、フォルダーはWeb経由でアクセス可能になります。
ローマ

バージョン管理下にある.htaccessファイルがある場合は、それを含むディレクトリがすでにバージョン管理下にあります。したがって、問題はすでに解決されています-.gitignoreファイルは無関係になります。
ポンカドゥードル2017年

1
@Wallacoloo正しい質問に関連して、それでもファイルは便利ですが、.htaccessでファイルを保護するようなアップロードディレクトリに使用します。Romansの説明とは逆に、.htaccessファイルは、ignore-ruleによって除外されるため、コミットされます。[古いスレッド、知っています]
デビッド

7

私は常に、目的のフォルダー構造を確認する機能を構築し、プロジェクト内で構築しています。空のフォルダがプロキシによってGitに保持されるため、これはこの問題を回避します。

function check_page_custom_folder_structure () {
    if (!is_dir(TEMPLATEPATH."/page-customs"))
        mkdir(TEMPLATEPATH."/page-customs");    
    if (!is_dir(TEMPLATEPATH."/page-customs/css"))
        mkdir(TEMPLATEPATH."/page-customs/css");
    if (!is_dir(TEMPLATEPATH."/page-customs/js"))
        mkdir(TEMPLATEPATH."/page-customs/js");
}

これはPHPにありますが、ほとんどの言語が同じ機能をサポートしていると思います。フォルダーの作成はアプリケーションによって処理されるため、フォルダーは常にそこにあります。


2
私たち全員が同じページにいるので、私はもうこれをしません。時間の無駄です。.gitkeep大会は、はるかに良い習慣です。
軽度のファズ2014年

これがどのように時間の無駄になるのか、私にはわかりません。TEMPLATEPATHが明らかに動的である場合、.gitkeepソリューションを使用できません。また、動的でないフォルダー構造であっても、ディレクトリをチェックする非常に優れたソリューションを削除する代わりに、いくつかのものを追加する必要があります。グローバル.gitignore内のディレクトリをマークする方法を追加することは、私にとっては完璧でしょう。#keep / path / to / dirのようなもの
Jochen Schultz

7

これはハックですが、機能するのはおかしいです(Git 2.2.1)。@Tekaが提案したものに似ていますが、覚えやすいです:

  • サブモジュールを任意のリポジトリに追加します(git submodule add path_to_repo
  • これにより、フォルダとファイルが追加されます.submodules。変更をコミットします。
  • .submodulesファイルを削除し、変更をコミットします。

これで、コミットがチェックアウトされたときに作成されるディレクトリができました。興味深いのは、このファイルのツリーオブジェクトのコンテンツを見ると、次のようになることです。

致命的:無効なオブジェクト名b64338b90b4209263b50244d18278c0999867193

Gitの将来のバージョンでは動作しなくなる可能性があるため、私はそれを使用することをお勧めしません。リポジトリが壊れたままになる可能性があります。


これは実際に機能しますが、IntelliJの一体を混乱させると思います...:|
rogerdpack '06 / 06/18

これに基づいて、これらの欠点のないより良いソリューションを作成しました:stackoverflow.com/a/58543445/277882
ntninja

7

多くの人がすでにこの質問に答えています。ここにPowerShellバージョンを追加するだけです。

ディレクトリ内のすべての空のフォルダを見つけます

空の.gitkeepファイルをそこに追加します

Get-ChildItem 'Path to your Folder' -Recurse -Directory | Where-Object {[System.IO.Directory]::GetFileSystemEntries($_.FullName).Count -eq 0} | ForEach-Object { New-Item ($_.FullName + "\.gitkeep") -ItemType file}

Nice.‌‌(͡☉͜ʖ͡☉)Fi
FiringSquadWitness

6

複数のセマンティックディレクトリに多くの一時データを格納するフォルダーを追加する場合、1つのアプローチは、ルート.gitignoreに次のようなものを追加することです...

/app/data/**/*.* !/app/data/**/*.md

次に*.md、各ディレクトリで説明的なREADME.mdファイル(または、空のファイルでも構いません)を各ディレクトリにコミットして、すべてのディレクトリがリポジトリの一部であることを確認できますが、ファイル(拡張子付き)は無視されます。制限:.はディレクトリ名に使用できません!

これらのすべてのディレクトリをxml / imagesファイルなどで埋め、さらにディレクトリを追加することができます。 /app/data/、アプリのストレージニーズが発展するにつれて、時間の経過とともにます(README.mdファイルは、各ストレージディレクトリの目的の説明を書き込むために役立ちます)丁度)。

新しいディレクトリごとに新しいディレクトリを.gitignore作成することで、さらに変更したり分散化したりする必要はありません.gitignore。おそらく最も賢い解決策ではありませんが、簡潔なgitignore-wiseであり、常に私のために機能します。素敵でシンプル!;)

ここに画像の説明を入力してください


6

これを行う簡単な方法は、.gitkeep(現在のところ)空のままにしたいディレクトリにファイルを追加することです。

詳細については、このSOFの回答を参照してください。これは、.gitignoreファイルを追加するという競合する規則(多くの回答で説明されている)が混乱する理由を説明している理由も説明しています。


4

ほつれにもう1つのオプションを追加します。

git関連するすべての目的で、そこにディレクトリを追加する場合はgit、空のままにして、その内容を追跡.gitignoreしないでください。ここで何度も提案されているように、うまくいくでしょう。

前述のとおり、形式は次のとおりです。

*
!.gitignore

コマンドラインでこれを行う方法が必要な場合は、追加したいディレクトリで次のコマンドを実行できます。

$ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore

私自身、これを行うために使用するシェルスクリプトがあります。スクリプトに任意の名前を付け、インクルードパスのどこかに追加するか、直接参照します。

#!/bin/bash

dir=''

if [ "$1" != "" ]; then
    dir="$1/"
fi

echo "*" > $dir.gitignore && \
echo '!.gitignore' >> $dir.gitignore && \
git add $dir.gitignore

これにより、追加したいディレクトリ内から実行するか、最初で唯一のパラメータとしてディレクトリを参照できます。

$ ignore_dir ./some/directory

あなたがいることを空のフォルダを追跡したい場合(@GreenAsJadeによってコメントに応答して)別のオプションは、MAYは将来的に追跡されたファイルが含まれていますが、今のところは空になりますが、あなたはOMMITできる*から.gitignore、ファイル、およびチェックすることをインチ基本的に、ファイルが言っているすべては「私を無視しないでください」、それ以外の場合、ディレクトリは空で追跡されます。

あなたの.gitignoreファイルは、次のようになります。

!.gitignore

これで確認できます。後でファイルを追跡できる空のまだ追跡されているディレクトリがあります。

ファイルの1行を維持することをお勧めする理由は、.gitignore目的を与えるためです。そうでなければ、誰かがそれを削除しようと考えるかもしれません。行の上にコメントを付けると役立つ場合があります。


4

「実際の」空の既存のディレクトリが必要な、不適切に作成されたライブラリまたはソフトウェアに対処する必要がある場合があります。シンプルを置く.gitignoreか、.keepそれらを破るとバグが発生する可能性があります。以下はこれらの場合に役立つかもしれませんが、保証はありません...

まず、必要なディレクトリを作成します。

mkdir empty

次に、このディレクトリに壊れたシンボリックリンクを追加します(ただし、上記の使用例以外の場合は、説明README付きでを使用してください)。

ln -s .this.directory empty/.keep

このディレクトリ内のファイルを無視するには、ルートに追加できます.gitignore

echo "/empty" >> .gitignore

無視されたファイルを追加するには、パラメーターを使用してそれを強制します。

git add -f empty/.keep

コミット後、インデックスに壊れたシンボリックリンクがあり、gitがディレクトリを作成します。壊れたリンクは通常のファイルではなく、通常のファイルをポイントしないため、いくつかの利点があります。つまり、意図ではなく意味によって、「(ファイルを含まない)」という質問の部分にさえ当てはまると思います。

find empty -type f

このディレクトリにはファイルが存在しないため、このコマンドは空の結果を表示します。そのため、ディレクトリ内のすべてのファイルを取得するほとんどのアプリケーションは、少なくとも「ファイルが存在する」または「読み取り可能」である場合、通常このリンクは表示されません。一部のスクリプトでもファイルが見つかりません。

$ php -r "var_export(glob('empty/.*'));"
array (
  0 => 'empty/.',
  1 => 'empty/..',
)

しかし、私はこのソリューションを特別な状況でのみ使用することを強くお勧めしますREADME。空のディレクトリに書かれた良いものは通常より良いソリューションです。(これがWindowsファイルシステムで機能するかどうかはわかりません...)


4

読み込み@ofavreをさんと@スタニスラフ・bashkyrtsev GITのディレクトリを作成するために、壊れたGITサブモジュールの参照を使用しての答えを、私は誰も全体のことを正気と安全を作るためのアイデアを、まだこの簡単な修正を示唆していないことに驚いています:

偽のサブモジュールをGITにハッキングするのではなく、空の実際のサブモジュールを追加するだけです。

入力:https : //gitlab.com/empty-repo/empty.git

コミットが1つだけのGITリポジトリ:

commit e84d7b81f0033399e325b8037ed2b801a5c994e0
Author: Nobody <none>
Date: Thu Jan 1 00:00:00 1970 +0000

メッセージなし、コミットされたファイルなし。

使用法

空のディレクトリをGITリポジトリに追加するには:

git submodule add https://gitlab.com/empty-repo/empty.git path/to/dir

既存の空のディレクトリをすべてサブモジュールに変換するには:

find . -type d -empty -delete -exec git submodule add -f https://gitlab.com/empty-repo/empty.git \{\} \;

Gitはサブモジュール参照を作成するときに最新のコミットハッシュを保存するため、私(またはGitLab)がこれを使用して悪意のあるファイルを挿入することを心配する必要はありません。残念ながら、チェックアウト時にどのコミットIDを使用するかを強制する方法が見つからなかったため、参照コミットIDがe84d7b81f0033399e325b8037ed2b801a5c994e0使用していることを手動で確認する必要がありますgit submodule status、リポジトリを追加後れていること。

まだ、ネイティブのソリューションが、我々は、おそらく誰かが手を得ることなく持つことができる最高の本当に本当に GITのコードベースで汚いです。

付録:このコミットを再作成する

あなたは(空のディレクトリで)を使用してこの正確なコミットを再作成できるはずです:

# Initialize new GIT repository
git init

# Set author data (don't set it as part of the `git commit` command or your default data will be stored as “commit author”)
git config --local user.name "Nobody"
git config --local user.email "none"

# Set both the commit and the author date to the start of the Unix epoch (this cannot be done using `git commit` directly)
export GIT_AUTHOR_DATE="Thu Jan 1 00:00:00 1970 +0000"
export GIT_COMMITTER_DATE="Thu Jan 1 00:00:00 1970 +0000"

# Add root commit
git commit --allow-empty --allow-empty-message --no-edit

再現可能なGITコミットの作成は驚くほど難しい…


3

できません。これは、Gitメンテナーによる意図的な設計決定です。基本的に、Gitのようなソースコード管理システムの目的はソースコードを管理することであり、空のディレクトリはソースコードではありません。Gitはコンテンツトラッカーとも呼ばれ、空のディレクトリはコンテンツではないため(実際にはまったく逆です)、追跡されません。


60
私はこの見方に異議を唱えています。構造はコンテンツであり、名前付けるとすべてがコンテンツに貢献します。
ThomasH 2011

20
空のファイルはソースコードでもコンテンツでもありません。名前だけです。しかし、Gitは空のファイルを喜んで追跡します。空のディレクトリの追跡をGitに拒否させるのは、意図的な設計上の決定ではなかったと思います。空のディレクトリを追跡することは、99%の時間は単に必要とされない機能であるため、適切に機能させるために必要な追加の作業を行う必要はありませんでした。誰かがその機能を実装するほどひどく欲しければ、Gitはそれを行うことができます。Gitのメンテナが正しく行われた場合、そのようなパッチに反対することはないでしょう。
Dan Molding、

1
ここの@TobyAllenは、更新されたFAQリンクです。トップの回答は、より正確な指示を含むFAQによって推奨されるものでもあります。
Daniel Da Cunha

3
これは、意図的な制限ではなく、欠けている機能(および優先度が低い)です。Git FAQから:現在、Gitインデックス(ステージング領域)の設計ではファイルのリストのみが許可されており、空のディレクトリを許可するように変更を行うのに十分な能力のある人は誰も
jbo5112 2013年

本当に同意しないでください。空のフォルダーを追跡する理由はさまざまです。たとえば、私のプロジェクト用に非常に軽量なPHP MVCフレームワークを開発しています。モデルやビューなどを配置するための特定のフォルダーがあります。フレームワークに基づいて新しいサイトを作成すると、デフォルトではモデルまたはビューがないため、これらのフォルダーは空ですが、フォルダーが存在する必要があります。動かない!
Gladen 2013年

2

このコードをcreate_readme.phpとして保存し、GitプロジェクトのルートディレクトリからPHPコードを実行できます。

> php create_readme.php

空のすべてのディレクトリにREADMEファイルが追加されるため、これらのディレクトリはインデックスに追加されます。

<?php
    $path = realpath('.');
    $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),       RecursiveIteratorIterator::SELF_FIRST);
    foreach($objects as $name => $object){
        if ( is_dir($name) && ! is_empty_folder($name) ){
            echo "$name\n" ;
            exec("touch ".$name."/"."README");
        }
    }

    function is_empty_folder($folder) {
        $files = opendir($folder);
        while ($file = readdir($files)) {
            if ($file != '.' && $file != '..')
                return true; // Not empty
            }
        }
?>

次に行う

git commit -m "message"
git push
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.