Gitリポジトリに保存されていないファイルのリスト

Gitリポジトリに保存されていないファイルのリスト

特定のディレクトリ内のどのファイルがGitで管理されていないかを知りたいです。私がこれを行う理由は、バックアップにGitを使用し、最終的にすべてのファイルをGitに保存したいからです。

これを行うことができるUnixツールは何ですか?find合理的に効率的な方法でこれを行う方法はありますか?

例:

RFC関連のコンテンツを保存するフォルダがあります。

.
├── TheFile
└── tests
    ├── 4180
    │   └── data
    │       ├── bad
    │       └── good
    │           └── linebreaks.csv
    ├── get-rfc.sh
    ├── .git <contents omited>
    ├── LICENSE
    ├── README
    └── rfc4180.txt

私は私を出力するコマンドを探しています。

TheFile

答え1

find the_starting_dir \( -type d -exec test -d '{}'/.git \; -prune \) -o -print

最も移植性の高い find 呼び出しではありませんが、GNU find で動作します。

検索はディレクトリツリーに移動します。この用語は-prunetrue を返しますが、findサブツリーの追加処理を停止します。したがって、左側には-o「これがディレクトリであり、サブディレクトリがtestあると言えばと言い、trueを返す.gitpruneツリーでこれが完了したのです」と言います。右側には「別の方法で印刷」と表示されています。

目次を印刷したくない場合は、に-print変更します\( ! -type d -print \)。ただし、目次が空であることを示す表示は表示されません。

-print次に変更してリストを取得できます-ls-printf マニュアルを見るその他など

答え2

なぜgitを使用しないのかわかりません...

git status --untracked-files

[編集する]

要求を理解する限り、ディレクトリツリーがあります。このツリーには複数のgitリポジトリがありますが、ツリー全体をカバーするリポジトリはありません。この例は、testサブディレクトリにあるgitリポジトリを示しています。したがって、提案されたコマンドはgit error fatal:Not in a gitリポジトリではなく、必要に応じてTheFileを受け取ります。

find . -name .git  -exec echo  $(realpath '{}') \; |\
sed 's/\(.*\)\(.git\)/git --git-dir=\1\2 --work-tree=\1 status --untracked-files/g' | bash  

答え3

あなたのリクエストには具体的なケースがたくさんあります。

  1. 実際には、gitが管理しているディレクトリの外部にあるファイルです。
    • あなたのTheFile状況に適しています。
  2. いくつかのタグを含むGitによって管理されるディレクトリのファイル.git.git必ずしもディレクトリではありません。実際のGIT_DIRへのパスを持つファイルでもかまいません。次のようにこれらのファイルをさらに分割できます。
    1. 既知のファイルはGitインデックスに存在するファイルです。
    2. 無視されたファイル、次のパターンに一致するファイルgitignore(5):
      • .gitignore
      • $HOME/.config/git/ignore
      • $GIT_DIR/info/exclude
    3. $GIT_DIRファイルは物理ディレクトリにありますが、いいえ買戻契約の一部。
      • .git/hooksおそらく
      • 悪意のあるコードかもしれません

したがって、最も信頼できるケースは、指定されたデフォルトディレクトリに対して2つのリストを作成して$D比較することです(事前に並べ替えて重複エントリを削除する必要があります)。

上記の2.3のサブリストを生成する信頼できる方法が思い出せないので、公開質問として残しておきます(以前に感覚を失ったことがあるのでこれについて知りたいです)。

上記の2.1に従って既知のファイルを一覧表示するシェルスクリプト:

for g in $(find $D -name .git) ; do
  echo $g 
  p=${g%/.git} g2=`readlink -f $g` ;
  ( cd $p && GIT_DIR=$g2 \
  git ls-files --exclude-standard --full-name ) \
  | sed "s,^,${p}/,g" ; 
done > list-2.1

上記の2.2に従って無視されたファイルを一覧表示するシェルスクリプト:

for g in $(find $D -name .git) ; do
  p=${g%/.git} g2=`readlink -f $g` ;
  ( cd $p && GIT_DIR=$g2 \
  git ls-files \
  --others -i --exclude-standard ) \
  | sed "s,^,${p}/,g" ; 
done > list-2.2

上記の2.3に従ってファイルを一覧表示するシェルスクリプト:

TODO > list-2.3

リストを処理してB側にないコンテンツを見つけるシェルスクリプト:

comm -23 <(find $D ! -type d |sort) <(sort 2.1 2.2 2.3 | uniq)

答え4

find <root_dir> -type d -name ".git"

これはあなたが望むものですか?

また、次のことを行うことができます

find <root_dir> -type d -name ".git" -print0 | xargs -0 -r dirname

その部分なしでディレクトリ名のみを出力します。これを防ぎ、/.git各フォルダ名の末尾にdirnameプラス出力を使用するだけです。find/../

find <root_dir> -type d -name ".git" -print0 | xargs -0 -r printf "%s/../"

編集する

パラメーターを否定-nameし、-maxdepth値を使用できます。たとえば、cカーネルツリーで名前が(大文字または小文字)で始まらないすべてのディレクトリを簡単に一覧表示できます。

find linux-4.8.2/ -type d ! -iname "c*" -maxdepth 1

私はまだあなたが何を言っているのかよく理解していません。

私はこれの正反対であるGitリポジトリにないすべてのファイルを見つけるためのコマンドを探しています。

ルートディレクトリと同じファイルシステムの同じディレクトリにあるファイルがリポジトリ.gitの一部ではない可能性があるため、これは文字通り名前を付けたディレクトリと同じディレクトリ(またはサブディレクトリ)にファイルがあることを意味します。.gitまた。git概念があることを覚えておいてください。分割火通常、ディスクに見えるのはgitリポジトリではないかもしれません。

見てhttps://libgit2.github.com/これは、多くのバインディング、多くのドキュメント、例、およびメソッドを含むgit用の公式Cライブラリです。

関連情報