web-dev-qa-db-ja.com

--sync =のような.gitignore&.hgignore&svn:ignoreによるrsync exclude

Rsyncには、「CVSと同じ方法でファイルを無視する」ための気の利いたオプション--cvs-excludeが含まれていますが、CVSは長年廃止されています。最新のバージョン管理システム(Git、Mercurial、Subversion)で無視されるファイルも除外する方法はありますか?

たとえば、GitHubから多数のMavenプロジェクトをチェックアウトしています。通常、少なくともtargetをリストする.gitignore、デフォルトのMavenビルドディレクトリ(トップレベルまたはサブモジュールに存在する場合があります)が含まれます。これらのディレクトリの内容は完全に使い捨てであり、ソースコードよりもはるかに大きくなる可能性があるため、バックアップにrsyncを使用する場合は除外します。

もちろん、明示的に--exclude=target/することもできますが、それは偶然targetという名前で、無視されるはずのない無関係なディレクトリを誤って抑制します。

そして、ディスク上の.gitignore.hgignore、またはsvn:ignoreプロパティで言及されているすべてのファイル名とパターンの絶対パスの完全なリストを提供することもできますが、これは巨大なリストです何らかのスクリプトで作成する必要があります。

RsyncにはCVS以外のVCSチェックアウトのサポートが組み込まれていないため、無視パターンを入力するための良いトリックはありますか?または、特定のファイル/ディレクトリを含めるかどうかをユーザースクリプトに問い合わせることができる、何らかのコールバックシステムですか?

更新:LordJavacが示唆する--filter=':- .gitignore'は、少なくとも私が見つけた例では、--filter=:CがCVSに対して行うように、Gitに対しても同様に機能するようです。構文は完全一致です。 --filter=':- .hgignore'は、Mercurialではあまり機能しません。例えば.hgignore(Git ^target$に相当するMercurialのような行を含む/target/は、rsyncによって正規表現として認識されません。また、Subversionでは何も機能しないようです。この場合、1.6以前の作業コピーでは.svn/dir-prop-baseを解析し、1.7以降の作業コピーではがっかりして手を放さなければなりません。

97
Jesse Glick

Luksanが述べたように、--filterrsyncに切り替えることでこれを行うことができます。 --filter=':- .gitignore'( ".gitignore"の前にスペースがあります)でこれを達成しました。これはrsync.gitignoreファイルとディレクトリマージを行い、gitのルールごとに除外するよう指示します。グローバル無視ファイルがある場合は、追加することもできます。使いやすくするために、フィルターを含むrsyncのエイリアスを作成しました。

102
LordJavac

git ls-filesを使用して、リポジトリの.gitignoreファイルによって除外されるファイルのリストを作成できます。 https://git-scm.com/docs/git-ls-files

オプション:

  • --exclude-standardすべての.gitignoreファイルを検討します。
  • -oステージングされていない変更を無視しないでください。
  • -i無視されたファイルのみを出力します。
  • --directoryディレクトリ全体が無視される場合にのみディレクトリパスを出力します。

私が無視するために残した唯一のものは.gitでした。

rsync -azP --exclude=.git --exclude=`git -C <SRC> ls-files --exclude-standard -oi --directory` <SRC> <DEST>
9
Jared Deckard

2018ソリューション 確認済み

rsync -ah --delete 
    --include .git --exclude-from="$(git -C SRC ls-files \
        --exclude-standard -oi --directory >.git/ignores.tmp && \
        echo .git/ignores.tmp')" \
    SRC DST 

詳細:--excludeの代わりに--exclude-fromが必須です。これは、除外リストが引数として解析されない可能性が高いためです。 Exclude fromにはファイルが必要であり、パイプでは機能しません。

現在のソリューションでは、除外ファイルを.gitフォルダー内に保存して、git statusに影響を与えないようにします。必要な場合は、/ tmpを使用してください。

5
sorin

rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination
それは私のために働いた。
もっと多くの--exclude-fromパラメータも。

5
ericn

Mercurialを使用する場合

hg status -i | sed 's/^I //' > /tmp/tmpfile.txt

。hgignore制限のためにMercurialの制御下にないファイルのリストを収集してから実行する

rsync -avm --exclude-from=/tmp/tmpfile.txt --delete source_dir/ target_dir/

無視されたファイルを除くすべてのファイルをrsyncします。注意:hg status -iは除外されたファイルのみをリストするため、空のディレクトリを同期から除外するrsyncのフラグ-mダース

3
ffeast

これを試して:

rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>

「.gitignore」のファイルを除くすべてのファイルをリモートディレクトリにコピーし、現在のディレクトリにないファイルを削除できます。

2
Shawn Wang

非常に大きな.gitignoreファイルと「純粋なrsync」ソリューションのどれも私のために働いた。これを書きました rsync wrapper script.gitignoreルール(include !スタイルの例外と.gitignoreファイルがサブディレクトリにあります)、私にとっては魅力的な働きをしました。

1
cobbzilla

ファイルパターンの標準リストに加えて、rsyncのマニュアルページごと:

$ HOME/.cvsignoreにリストされているファイルはリストに追加され、CVSIGNORE環境変数にリストされているすべてのファイル

したがって、私の$ HOME/.cvsignoreファイルは次のようになります。

.git/
.sass-cache/

.gitと Sass によって生成されたファイルを除外します。

0
Doug Harris

Rsync(1)のMERGE-FILES FILTER RULESセクションを確認してください。

ディレクトリ構造を走査するときに.gitignoreファイルを含むrsync --filterルールを作成できるようです。

0
luksan

除外フィルターを作成する代わりに、git ls-files rsyncする各ファイルを選択するには:

#!/usr/bin/env bash

if [[ ! $# -eq 2 ]] ; then
    echo "Usage: $(basename $0) <local source> <rsync destination>"
    exit 1
fi

cd $1
versioned=$(git ls-files --exclude-standard)
rsync --verbose --links --times --relative --protect-args ${versioned} $2

これはgit ls-filesは、改行で区切られたパスを返します。ファイル名にスペースを含むバージョン管理されたファイルがある場合、おそらく動作しません。

0
user7033996

代替案:

git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...

git ls-files -zi --exclude-per-directory=".gitignore" |...

(rsyncは.gitignoreを部分的にしか理解しません)

0
druid62