Как я могу переместить все содержимое git на один уровень вверх в иерархии папок? - PullRequest
54 голосов
/ 20 августа 2011

У меня есть 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. Я не очень хорошо разбираюсь в shell или git, поэтому кто-то может сказать мне, что мне нужно выполнить, чтобы сделать вышеупомянутое.

Ответы [ 8 ]

51 голосов
/ 19 октября 2013

Только что сделал это, и это довольно просто на самом деле. Правильный способ сделать это -

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

, а затем

git rm repo.git/webapp

с последующим

git add * 
git commit -m "Folders moved out of webapp directory :-)"
22 голосов
/ 05 февраля 2014

Другой вариант ответа Sumeet - в директории хранилища над «webapp» выполните следующую команду:

git mv webapp/* ./ -k

-k - включает файлы, которые еще не контролируются версиями, в противном случае вы получите:

fatal: not under version control, source=webapp/somefile, destination=somefile
4 голосов
/ 20 августа 2011

Решение, которое вы упомянули, должно работать, так как git отслеживает изменения сначала на основе хеша файлов, а затем их местоположения.

Это не будет работать, если в процессе перемещения файла вы меняете содержимоефайлы.

В нижнем случае, попробуйте, и если это не сработает, вы можете отменить изменения, прежде чем отправлять изменения в мастер репо :).Это одна из причин, почему мне действительно нравится git.

Edit

Я забыл упомянуть, что для просмотра изменений после переименования необходимо использовать параметр --folfol.Проверьте этот пример

Сначала я создал новый репозиторий 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 <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

Надеюсь, это поможет!

2 голосов
/ 09 марта 2014

в Windows вы можете сделать следующее:

Пока вы находитесь в дочерней папке

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

В результате все объекты в дочерней папке будут вродительская папка

Обратите внимание: некоторые ошибки могут возникать при наличии объекта в дочерней папке с именем, равным дочерней папке

1 голос
/ 24 апреля 2019

Если вы используете PowerShell, вы можете запустить эту команду из корня вашего проекта, и он поместит туда содержимое веб-приложения.

Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
1 голос
/ 18 декабря 2017

Мне удалось заставить его работать, просто выполнив это из папки назначения:

git mv webapp/* .

Кажется, это не работает в оболочке Windows (происходит ошибка с ошибкой Bad source)но будет работать в Windows, если вы используете оболочку Git Bash, которая расширяет подстановочный знак *.

1 голос
/ 21 августа 2011

Да, вы можете просто переместить файлы. Однако вам нужно сообщить git, что старые файлы в папке webapp исчезли, то есть git необходимо обновить индекс готовых / подтвержденных файлов.

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

-. * Обновление 1009 *

Вы заметили, что вы подумали: «... git на самом деле не обрабатывает движение или переименование ...» - сначала я также был сбит с толку и не совсем понял, как работает Индекс. С одной стороны, люди говорят, что git только делает снимки и не отслеживает переименования, но затем вы получаете «неудачу», если обновляете .gitignore, или mv файл и т. Д. Этот «сбой» - путаница о как работает Индекс.

Моя визуализация заключается в том, что область Index / Staging - это место, похожее на стену раскадровки, где вы размещаете копию своего последнего и самого лучшего «готового» файла, включая его путь (используя git add), и это та копия, которая совершена. Если вы не возьмете эту копию со стены раскадровки (т.е. git rm), то git продолжит ее фиксировать, и возникнет путаница (см. Много SO вопросов ...). Индекс также используется git в течение merge с аналогичным образом

0 голосов
/ 20 августа 2011

Да, git будет отслеживать изменения в прошлом контенте.Он использует хеши содержимого файла, поэтому независимо от того, где они находятся в структуре каталогов, они будут одним и тем же файлом.

В результате вы должны выполнить перемещение за один коммит, а затем исправить всередактирует в последующем коммите.Это позволит Git определять перенаправление с максимальной эффективностью и не будет иметь никакого значения для объема данных, хранящихся в хранилище (поскольку вы все равно внесете эти изменения).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...