次のような構造の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があまり得意ではないので、誰かが前述のことを実行するために何を実行する必要があるかを教えてくれます。
これを実行しただけで、実際には非常に簡単です。これを行う正しい方法は-
git mv repo.git/webapp/* repo.git/.
その後
git rm repo.git/webapp
続いて
git add *
git commit -m "Folders moved out of webapp directory :-)"
Sumeetの答えの別の変形-「webapp」の上のリポジトリディレクトリで、次のコマンドを実行します。
git mv webapp/* ./ -k
-k-バージョン管理下にないファイルが含まれます。それ以外の場合は次のようになります:
fatal: not under version control, source=webapp/somefile, destination=somefile
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
これがお役に立てば幸いです!
windowsでは、以下を実行できます。
子フォルダーにいる間
for /f %f in ('dir /b') do git mv %f ../
結果は、子フォルダー内のすべてのオブジェクトが親フォルダーになります
注:名前が子フォルダーに等しい子フォルダーにオブジェクトがある場合、いくつかのエラーが発生する可能性があります
PowerShellを使用している場合は、プロジェクトルートからこのコマンドを実行すると、webappのコンテンツがそこに配置されます。
Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
はい、単にファイルを移動できます。ただし、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質問を参照してください... )。インデックスは、同様の方法でmerge
s中にgitでも使用されます
目的のフォルダーからこれを行うだけで、それを動作させることができました:
git mv webapp/* .
これはWindowsシェルでは機能しないようです(エラーBad source
で失敗します)が、使用するとWindowsでwill動作します*
ワイルドカードを展開するGit Bashシェル。
はい、gitは過去のコンテンツの変更を追跡します。ファイルのコンテンツのハッシュを使用するため、ディレクトリ構造のどこに配置されていても、同じファイルになります。
そのため、1回のコミットで移動を行い、その後のコミットで編集を修正する必要があります。これにより、Gitはリダイレクションを最大の効率で決定でき、リポジトリに保存されているデータの量に違いは生じません(とにかくこれらの変更を行うため)。
Windowsでは、Bashを使用して、以下が機能しました。
git mv /c/REPO_FOLDER/X_FOLDER/Y_FOLDER/Z_FOLDER/* /c/REPO_FOLDER/X_FOLDER/Y_FOLDER