Як я можу перемістити весь вміст git на один рівень вгору в ієрархії папок?


82

У мене є сховище git, структура якого виглядає так:

+--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 насправді не обробляє переміщення або перейменування. Я знаю, що, хоча він відображається як новий файл у журналах, все одно можна переглянути історію комітів для цього файлу, використовуючи деякі опції в git log.

З того, що я прочитав, найкращим способом досягти цього було б використання git-filter. Я не дуже добре володію оболонкою або git, тому хтось може сказати мені, що мені потрібно виконати, щоб зробити вищезазначене.


1
Якщо хеші ваших файлів залишаються незмінними, git повинен виявляти файли, переміщені без git mvпереміщення. Ви можете перевірити це після додавання нових файлів за git addдопомогою git status.
Ніндзяканнон

Відповіді:


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, вам просто потрібно зробити те, git mv /path/new/old/* /path/new/.де path/new/oldзараз знаходяться файли, і /path/newде ви хочете, щоб вони були. *Являє самі файли, а не каталог.
Люсі Бейн

Вітаємо Вас @LucyBain та +1 за те, що Ви залишили корисне пояснення іншим.
Sumeet Pareek

52
Я розумію, fatal: bad source, source=webapp/*, destination=*це взагалі не працює; (
Ендрю Савіних,

4
@AndrewSavinykh, як згадував JLRishe в іншій відповіді, здається, це проблема, ізольована від оболонки Windows, але якщо вона працює в Git Bash, вона повинна працювати.
Алек

34

Інший варіант відповіді Sumeet - у каталозі сховища над "webapp" виконайте таку команду:

git mv webapp/* ./ -k

-k - Пропустити дії переміщення або перейменування, що призведе до стану помилки, інакше ви отримуєте:

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

2
Фатальним. Я вперше перемістив ці файли вручну, перш ніж побачив вашу відповідь ;-)
GhostCat

1
А як щодо інших філій? Чи потрібно мені їх також перебазувати? Дякую!
Matifou

1
> А як щодо інших галузей? Мені також доведеться перебазувати їх? - Відповідь: ви вносите ці зміни в конкретну гілку, тому вам потрібно буде виконати подібні зміни для кожної гілки окремо.
Олексій

7

у вікнах ви можете зробити наступне:

Поки ви знаходитесь у дочірній папці

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

У результаті всі об'єкти в дочірній папці будуть у батьківській папці

Зверніть увагу: деякі помилки можуть виникати, якщо у вас є об’єкт у дочірній папці з іменем, рівним дочірній папці


Це єдина відповідь, яка працювала у мене в Win10 ... не використовуючи Powershell. +1
алан,

1
отримав це: fatal: '../' знаходиться поза сховищем
mrapi

7

Я зміг змусити його працювати, просто зробивши це з цільової папки:

git mv webapp/* .

Здається, це не працює в оболонці Windows (не вдається з помилкою Bad source), але це буде працювати в Windows, якщо ви використовуєте оболонку Git Bash, яка розширює *шаблон.


5

Рішення, про яке ви згадали, має спрацювати, оскільки git спочатку відстежує зміни на основі хешу файлів, а потім їх розташування.

Це не спрацює, якщо під час переміщення файлу ви змінюєте вміст файлів.

Нижній регістр, спробуйте, і якщо він не спрацює, ви можете повернути зміни, перш ніж надсилати зміни до головного репо :). Це одна з причин, чому я дуже люблю git.

Редагувати

Я забув згадати, що для того, щоб побачити зміни після перейменування, потрібно скористатися параметром '--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/

Потім створив файл у папці / тесті

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

Сподіваюся, це допоможе!


Привіт! Перевірте оновлену відповідь, я додав приклад, як відстежувати зміни.
Августо

3

Якщо ви використовуєте PowerShell, ви можете запустити цю команду з кореня проекту, і вона розмістить там вміст webapp.

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

1

Так, ви можете просто перемістити файли. Однак вам потрібно сказати git, що старі файли в папці webapp зникли, тобто git повинен оновити свій індекс готових / зафіксованих файлів.

Таким чином, ви можете використовувати, git add -A .щоб git помітив усі зміни, або використовуйте, git mv <files>щоб сказати git зробити сам рух. Дивіться сторінку довідки git mv .

--оновити.

Ви зауважили, що думали: ".. git насправді не обробляє переміщення або перейменування .." - Спочатку я також був розгублений і не до кінця зрозумів, як працює Індекс. З одного боку, люди кажуть, що git робить лише знімки і не відстежує перейменування, але тоді вас вражає, що він не працює, якщо ви оновлюєте файл .gitignoreабо mvфайл тощо. Ця "помилка" викликає плутанину щодо того, як працює індекс.

Моя візуалізація полягає в тому, що область покажчика / постановки - це місце, як стіна розкадрування, де ви розміщуєте копію вашого останнього та найкращого „готового” файлу, включаючи його шлях, (використовуючи git add), і саме ця копія фіксується. Якщо ви не знімете цю копію зі стіни розкадровки (тобто git rm), тоді git продовжить її фіксувати, і плутанина рясніє (див. Багато запитань щодо SO ...). Індекс також використовується git під час merges подібним чином


1

У Windows, використовуючи Bash, працювали:

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

0

Так, git буде відстежувати зміни в минулому вмісті. Він використовує хеші вмісту файлу, тому незалежно від того, де вони знаходяться в структурі каталогів, вони будуть одним і тим же файлом.

Як результат, вам слід зробити переміщення за один коміт, а потім виправити будь-які зміни в наступному коміті. Це дозволить Git визначити переспрямування з максимальною ефективністю і не вплине на обсяг даних, що зберігаються у сховищі (оскільки ви все одно внесете ці зміни).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.