web-dev-qa-db-ja.com

すべてのgitコンテンツをフォルダー階層で1レベル上に移動するにはどうすればよいですか?

次のような構造のgitリポジトリがあります。

+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+webapp
|
+---------+manage.py
+---------+modules
+---------+templates
+---------+static
+---------+...
+---------+...

webappフォルダーの内容を1レベル上に移動したいと思います。結果のレポは次のようになります。

+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+manage.py
+----+modules
+----+templates
+----+static
+----+...
+----+...

webappディレクトリのすべてのファイルを1レベル上に移動し、空のwebappディレクトリを削除してから変更をコミットするだけで、これを実行できますか?これにより、webappディレクトリ下のファイルのコミット履歴が保持されますか?

あなたの多くにとって非常に簡単な質問ですが、私は確信したいと思います。最後に欲しいのはgitスープです。


ファイルを移動しようとしましたが、gitは実際に移動や名前変更を処理しないため、コミット履歴を失いました。ログには新しいファイルとして表示されますが、git logのいくつかのオプションを使用してファイルのコミット履歴を表示することは可能です。

私が読んだことから、これを達成する最良の方法はgit-filterを使用することです。私はShellやgitがあまり得意ではないので、誰かが前述のことを実行するために何を実行する必要があるかを教えてくれます。

55

これを実行しただけで、実際には非常に簡単です。これを行う正しい方法は-

git mv repo.git/webapp/* repo.git/.

その後

git rm repo.git/webapp

続いて

git add * 
git commit -m "Folders moved out of webapp directory :-)"
52
Sumeet Pareek

Sumeetの答えの別の変形-「webapp」の上のリポジトリディレクトリで、次のコマンドを実行します。

git mv webapp/* ./ -k

-k-バージョン管理下にないファイルが含まれます。それ以外の場合は次のようになります:

fatal: not under version control, source=webapp/somefile, destination=somefile
22
Alex

Gitは最初にファイルのハッシュに基づいて変更を追跡し、次にそれらの場所に基づいて変更を追跡するため、前述のソリューションが機能するはずです。

ファイルの移動の一環として、ファイルの内容を変更した場合、これは機能しません。

ボトムケース、それを試してみて、それが機能しない場合は、マスターリポジトリに変更をプッシュする前に、変更を元に戻すことができます:)。これがgitが本当に好きな理由の1つです。

編集

名前変更後の変更を確認するには、「-follow」パラメーターを使用する必要があることを忘れていました。この例を確認してください

最初に、新しいgitリポジトリを作成しました

94:workspace augusto$ mkdir gittest
94:workspace augusto$ cd gittest/
94:gittest augusto$ git init
Initialized empty Git repository in /Volumes/Data/dev/workspace/gittest/.git/

次に、folder/testにファイルを作成しました

94:gittest augusto$ mkdir folder
94:gittest augusto$ vi folder/test
94:gittest augusto$ git add folder/test
94:gittest augusto$ git commit -am "added file"
[master (root-commit) 7128f82] added file
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 folder/test

次に、ファイルをnewfolder/testに移動しました

94:gittest augusto$ mkdir newfolder
94:gittest augusto$ mv folder/test newfolder/
94:gittest augusto$ git add newfolder/test 
94:gittest augusto$ git commit -am "moved/renamed file"
[master 4da41f5] moved/renamed file
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename {folder => newfolder}/test (100%)

そしてgit log --follow newfolder/testは完全な履歴を表示します(パスなどの詳細情報を表示するためにパラメーター-pを追加しました)。

94:gittest augusto$ git log --follow -p newfolder/test 
commit 4da41f5868ab12146e11820d9813e5a2ac29a591
Author: Augusto Rodriguez <[email protected]>
Date:   Sat Aug 20 18:20:37 2011 +0100

    moved/renamed file

diff --git a/folder/test b/newfolder/test
similarity index 100%
rename from folder/test
rename to newfolder/test

commit 7128f8232be45fd76616f88d7e164a840e1917d5
Author: Augusto Rodriguez <[email protected]>
Date:   Sat Aug 20 18:19:58 2011 +0100

    added file

diff --git a/folder/test b/folder/test
new file mode 100644
index 0000000..3b2aed8
--- /dev/null
+++ b/folder/test
@@ -0,0 +1 @@
+this is a new file

これがお役に立てば幸いです!

4
Augusto

windowsでは、以下を実行できます。

子フォルダーにいる間

for /f %f in ('dir /b') do git mv %f ../

結果は、子フォルダー内のすべてのオブジェクトが親フォルダーになります

注:名前が子フォルダーに等しい子フォルダーにオブジェクトがある場合、いくつかのエラーが発生する可能性があります

2
Ammaroff

PowerShellを使用している場合は、プロジェクトルートからこのコマンドを実行すると、webappのコンテンツがそこに配置されます。

Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
1
Nick

はい、単にファイルを移動できます。ただし、webappフォルダー内の古いファイルがなくなったことをgitに伝える必要があります。つまり、gitは終了/コミット済みファイルのインデックスを更新する必要があります。

したがって、git add -A .を使用してgitにすべての変更を通知させるか、git mv <files>を使用してgitに移動自体を行わせることができます。 git mv manページを参照

- 更新。

「.. gitは実際には移動や名前の変更を処理しません。」と思ったことに注意しました-私も最初は混乱し、インデックスの仕組みを完全に理解していませんでした。一方で、gitはスナップショットのみを取得し、名前の変更を追跡しないと言いますが、.gitignoreまたはmvファイルなどを更新すると、「失敗」でヒットします。失敗」は、インデックスの動作howについての混乱です。

私の視覚化は、インデックス/ステージング領域がストーリーボードの壁のような場所であり、そのパスを含む最新の最高の「完成した」ファイルのコピーを配置することです(git addを使用)。コミットされたコピー。そのコピーをストーリーボードの壁(つまりgit rm)から削除しない場合、gitはそれをコミットし続け、混乱がたくさんあります(多くのSO質問を参照してください... )。インデックスは、同様の方法でmerges中にgitでも使用されます

1
Philip Oakley

目的のフォルダーからこれを行うだけで、それを動作させることができました:

git mv webapp/* .

これはWindowsシェルでは機能しないようです(エラーBad sourceで失敗します)が、使用するとWindowsでwill動作します*ワイルドカードを展開するGit Bashシェル。

1
JLRishe

はい、gitは過去のコンテンツの変更を追跡します。ファイルのコンテンツのハッシュを使用するため、ディレクトリ構造のどこに配置されていても、同じファイルになります。

そのため、1回のコミットで移動を行い、その後のコミットで編集を修正する必要があります。これにより、Gitはリダイレクションを最大の効率で決定でき、リポジトリに保存されているデータの量に違いは生じません(とにかくこれらの変更を行うため)。

0
AlBlue

Windowsでは、Bashを使用して、以下が機能しました。

git mv /c/REPO_FOLDER/X_FOLDER/Y_FOLDER/Z_FOLDER/* /c/REPO_FOLDER/X_FOLDER/Y_FOLDER
0
BCool