web-dev-qa-db-ja.com

コミット履歴とともにファイルとディレクトリをサブディレクトリに移動します

コミット履歴とともにディレクトリとファイルをサブディレクトリに移動するにはどうすればよいですか?

例えば:

  • ソースディレクトリ構造:[project]/x/[files & sub-dirs]

  • ターゲットディレクトリ構造:[project]/x/p/q/[files & sub-dirs]

64
rst.ptl

bmarguliescomment に追加するための完全なシーケンスは次のとおりです。

mkdir -p x/p/q      # make sure the parent directories exist first
git mv x/* x/p/q    # move folder, with history preserved
git commit -m "changed the foldername x into x/p/q"

最初に試して、動きのプレビューを確認します。

git mv -n x/* x/p/q

Wolfgangコメント

Bashを使用している場合、次のような拡張グロブを使用することにより、フォルダーをそれ自体に移動しようとする問題を回避できます( the shopt built-in ):

shopt -s extglob; git mv !(folder) folder

Captain Man レポート コメント内 やらなければならないこと:

mkdir temp 
git mv x/* temp
mkdir -p x/p/q
git mv temp x/p/q
rmdir temp;

状況:

WindowsでCygwinを使用しています。
shopt -s extglobの例を間違えたので、自分のやり方は必要ないかもしれないことに気付きましたが、通常はbashの代わりにzshを使用し、shopt -s extglobコマンドはありませんでした(確かに代替)、このアプローチはシェル全体で機能するはずです(シェルのmkdirおよびrmdirが特に異質な場合は、それをサブブします)


別の方法として、 spanky に言及 コメント内-kgit mvオプション

エラー状態につながる移動アクションまたは名前変更アクションをスキップします。

git mv -k * target/

これにより、「can not move directory into itself」エラーが回避されます。

63
VonC

これは古い質問であることがわかりますが、私は git book の例の1つから派生した問題に対する現在の解決策で答える必要があります。非効率的な--tree-filterを使用する代わりに、--index-filterを使用してインデックス上でファイルを直接移動します。

git filter-branch -f --index-filter 'PATHS=`git ls-files -s | sed "s/^<old_location>/<new_location>/"`;GIT_INDEX_FILE=$GIT_INDEX_FILE.new; echo -n "$PATHS" | git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- --all

これは、1つの特別なケースでコミット履歴内のファイルの名前を一括変更するために同じ例を使用した本の例の1つを特化したものです。サブディレクトリ内のファイルを移動する場合:パスで/文字をエスケープするときは、\を使用して、sedコマンドが期待どおりに動作するようにしてください。

例:

Project Directory
                 |-a
                 |  |-a1.txt
                 |  |-b
                 |  |  |-b1.txt

bディレクトリをプロジェクトルートに移動するには:

git filter-branch -f --index-filter 'PATHS=`git ls-files -s | sed "s/a\/b\//b\//"`;GIT_INDEX_FILE=$GIT_INDEX_FILE.new; echo -n "$PATHS" | git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- --all

結果:

Project Directory
                 |-a
                 |  |-a1.txt
                 |
                 |-b
                 |  |-b1.txt
9
peroyhav

Git mvコマンドが最も簡単な方法です。ただし、少なくとも私のLinuxボックスでは、-kフラグを指定して、フォルダーをそれ自体に移動できないというエラーが返されないようにする必要がありました。を使用してアクションを実行できました...

mkdir subdirectory
git mv -k ./* ./subdirectory
# check to make sure everything moved (see below)
git commit

警告として、これはallの移動をスキップし、エラー状態になります。そのため、移動後、コミット前にすべてが正常に動作したことを確認する必要があるでしょう。

6
Jeremy Hutchins