폴더 계층 구조에서 모든 git 콘텐츠를 한 수준 위로 이동하려면 어떻게해야합니까?


82

구조가 다음과 같은 자식 저장소가 있습니다.

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

webapp폴더 의 내용을 한 단계 위로 이동하고 싶습니다 . 내 결과 저장소는 다음과 같아야합니다.

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

webapp디렉토리 의 모든 파일을 한 수준 위로 이동 하고 빈 webapp디렉토리를 삭제 한 다음 변경 사항을 커밋하여이를 수행 할 수 있습니까? 이렇게하면 webapp디렉토리 아래에있는 파일의 커밋 기록이 보존 됩니까?

많은 분들에게 매우 간단한 질문이지만 확신하고 싶습니다. 내가 원하는 마지막 것은 새끼 수프입니다.


파일 이동을 시도했지만 git이 실제로 이동이나 이름 바꾸기를 처리하지 않기 때문에 커밋 기록을 잃었습니다. 로그에 새 파일로 표시되지만 .NET의 일부 옵션을 사용하여 파일에 대한 커밋 기록을 볼 수 있다는 것을 알고 있습니다 git log.

내가 읽은 바에 따르면이를 수행하는 가장 좋은 방법은 git-filter. 나는 쉘이나 자식을 잘하지 못하기 때문에 누군가가 앞서 언급 한 것을 실행해야 할 것을 말해 줄 수 있습니다.


1
파일의 해시가 동일하게 유지되면 git은 이동하지 않고 git mv이동 한 파일을 감지해야합니다 . 를 git add사용하여 새 파일을 추가 한 후이를 확인할 수 있습니다 git status.
Ninjakannon

답변:


70

이를 수행하는 올바른 방법은 다음과 같습니다.

git mv repo.git/webapp/* repo.git/.
git rm repo.git/webapp
git add * 
git commit -m "Folders moved out of webapp directory :-)"

5
이것은 나를 위해 작동하지 않습니다. 어떤 디렉토리에서 이것을 실행 했습니까?
wharding28

6
이것은 나를 위해 완벽하게 작동했습니다. 감사합니다! 그냥 명확합니다 - 당신은 자식 디렉토리에 현재 있다면, 당신은 단지해야 할 git mv /path/new/old/* /path/new/.경우 path/new/old파일이 현재있는 곳이며, /path/new당신이 그들을되고 싶은 곳입니다. 은 *파일 자체가 아닌 디렉토리를 나타냅니다.
Lucy Bain

@LucyBain을 환영하고 다른 사람들에게 유용한 설명을 남겨주신 +1.
Sumeet Pareek

52
나는 fatal: bad source, source=webapp/*, destination=*이것이 전혀 작동하지 않습니다. (
Andrew Savinykh

4
@AndrewSavinykh, JLRishe가 다른 답변에서 언급했듯이 이것은 Windows 셸과 관련된 문제로 보이지만 Git Bash에서 실행하는 경우 작동합니다.
Alec

35

Sumeet의 답변의 또 다른 변형- "webapp"위의 저장소 디렉토리에서 다음 명령을 실행합니다.

git mv webapp/* ./ -k

-k- 오류 조건을 유발할 수있는 이동 또는 이름 바꾸기 작업을 건너 뜁니다 . 그렇지 않으면 다음이 발생합니다.

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

2
치명적인. 나는 당신의 대답 ;-)보기 전에 내가 먼저 수동으로 해당 파일을 멀리 이동
GhostCat

1
다른 지점은 어떻습니까? 그것들도 리베이스해야합니까? 감사!
Matifou

1
> 다른 지점은 어떻습니까? 그것들도 리베이스해야합니까? -답변 : 특정 분기에서 이러한 변경을 수행하고 있으므로 각 분기에 대해 개별적으로 유사한 변경을 수행해야합니다.
Alex

7

창에서 다음을 수행 할 수 있습니다.

하위 폴더에있는 동안

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

결과는 하위 폴더의 모든 개체가 상위 폴더에 있습니다.

참고 : 하위 폴더에 이름이 하위 폴더와 같은 개체가 있으면 일부 오류가 발생할 수 있습니다.


이것은 Powershell을 사용하지 않고 Win10에서 나를 위해 일한 유일한 대답입니다. +1
alan

1
이 : 치명적 : '../'저장소 외부에 있음
mrapi

7

대상 폴더에서 간단히 다음과 같이 작동하도록 할 수있었습니다.

git mv webapp/* .

Windows 셸 (오류와 함께 실패에서 작동하지 않는 것 Bad source),하지만 것입니다 당신이 확장 망할 놈의 배쉬 쉘, 사용하는 경우 Windows에서 작동 *와일드 카드를.


5

git이 먼저 파일의 해시를 기반으로 변경 사항을 추적 한 다음 해당 위치를 추적하므로 언급 한 솔루션이 작동합니다.

파일 이동의 일부로 파일 내용을 변경하면 작동하지 않습니다.

하단의 경우 시도해보고 작동하지 않으면 변경 사항을 마스터 저장소에 푸시하기 전에 변경 사항을 되돌릴 수 있습니다. 이것이 내가 정말 자식을 좋아하는 이유 중 하나입니다.

편집하다

이름을 바꾼 후 변경 사항을 보려면 '--follow'매개 변수를 사용해야한다는 점을 잊었습니다. 이 예를 확인하십시오.

먼저 새로운 git repo를 만들었습니다.

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/

그런 다음 폴더 / 테스트에 파일을 생성했습니다.

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

그런 다음 파일을 새 폴더 / 테스트 로 이동했습니다.

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 <xxxx@gmail.com>
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 <xxxx@gmail.com>
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

이게 도움이 되길 바란다!


안녕! 업데이트 된 답변을 확인하십시오. 변경 사항을 추적하는 방법의 예를 추가했습니다.
Augusto

3

PowerShell을 사용하는 경우 프로젝트 루트에서이 명령을 실행할 수 있으며 여기에 webapp의 콘텐츠가 배치됩니다.

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

1

예, 간단히 파일을 이동할 수 있습니다. 그러나 git에게 webapp 폴더의 이전 파일이 사라 졌다고 알려야합니다. 즉, 완료 / 커밋 된 파일의 색인을 업데이트해야합니다.

git add -A .따라서을 사용 하여 git이 모든 변경 사항 git mv <files>을 알리거나을 사용하여 git에게 자체적으로 이동하도록 지시 할 수 있습니다. git mv 매뉴얼 페이지를 참조하십시오 .

--최신 정보.

".. git은 이동이나 이름 변경을 실제로 처리하지 않습니다."라고 생각했습니다.-처음에는 혼란 스러웠고 인덱스가 작동하는 방식을 완전히 이해하지 못했습니다. 한편으로 사람들은 git이 스냅 샷 만 찍고 이름 변경을 추적하지 않는다고 말합니다.하지만 .gitignore이나 mv파일 등 을 업데이트하면 '실패'가 발생합니다.이 '실패'는 방법에 대한 혼란입니다. 색인 작동합니다.

내 시각화는 인덱스 / 스테이징 영역이 스토리 보드 벽과 같은 장소로, 경로를 포함하여 가장 최근의 '완성 된'파일의 복사본을 배치하고 (를 사용하여 git add) 커밋 된 복사본이라는 것입니다. 스토리 보드 벽 (예 :)에서 해당 카피를 가져 오지 않으면 git rmgit이 계속 커밋하고 혼란 스러울 것입니다 (많은 SO 질문 참조 ...). 인덱스는 merges 동안 비슷한 방식으로 git에서도 사용됩니다.


1

Windows에서 Bash를 사용하면 다음이 작동했습니다.

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

0

예, git은 과거 콘텐츠의 변경 사항을 추적합니다. 파일 콘텐츠의 해시를 사용하므로 디렉터리 구조의 위치에 관계없이 동일한 파일이됩니다.

결과적으로 하나의 커밋에서 이동을 수행 한 다음 후속 커밋에서 수정 사항을 수정해야합니다. 이렇게하면 Git이 최대의 효율성으로 리디렉션을 결정할 수 있으며 리포지토리에 저장된 데이터의 양에 영향을주지 않습니다 (어쨌든 변경을 수행 할 것이므로).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.