Ответ 1
Просто сделал это, и на самом деле это довольно просто. Правильный способ сделать это -
git mv repo.git/webapp/* repo.git/.
а затем
git rm repo.git/webapp
а затем
git add *
git commit -m "Folders moved out of webapp directory :-)"
У меня есть репозиторий 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 не справляется с переходом или переименованием. Я знаю, что, хотя он отображается как новый файл в журналах, все еще можно просмотреть историю фиксации файла, используя некоторые параметры в git log
.
Из того, что я прочитал, лучший способ добиться этого - использовать git-filter
. Я не очень хорошо разбираюсь в оболочке или 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 отслеживает изменения на основе хэша файлов сначала, а затем их местоположение.
Это не работает, если в процессе перемещения файла вы изменяете содержимое файлов.
В нижнем регистре, попробуйте, и если это не сработает, вы можете вернуть изменения, прежде чем нажимать изменения на master repo:). Это одна из причин, почему мне очень нравится 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 <[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
Надеюсь, это поможет!
в окнах вы можете сделать следующее:
Пока вы находитесь в дочерней папке
for /f %f in ('dir /b') do git mv %f ../
В результате все объекты в дочерней папке будут находиться в родительской папке
Обратите внимание: некоторые ошибки могут возникнуть, если у вас есть объект в дочерней папке с именем, равным дочерней папке
Да, вы можете просто переместить файлы. Однако вам нужно сообщить git, что старые файлы в папке webapp ушли, то есть git необходимо обновить свой индекс готовых/преданных файлов.
Таким образом, вы можете использовать git add -A .
, чтобы сделать git уведомление обо всех изменениях, или использовать git mv <files>
, чтобы сообщить git, чтобы сделать сам ход. См. страницу git mv man.
-. Обновление
Вы заметили, что считаете, что ".. git не справляется с переходом или переименованием". - Сначала я тоже смутился и не полностью понял способ работы индекса. С одной стороны, люди говорят, что git принимает только моментальные снимки и не отслеживает переименования, но затем вы получаете удар с ним "сбой", если вы обновляете файл .gitignore
или mv
и т.д. Этот "отказ" путаница в отношении того, как работает индекс.
Моя визуализация заключается в том, что область Index/Staging - это место, такое как стена раскадровки, где вы размещаете копию вашего последнего и самого большого "готового" файла, включая его путь, (используя git add
), и это это копия, которая совершена. Если вы не берете эту копию со стены раскадровки (т.е. git rm
), то git будет продолжать ее совершать, а путаница изобилует (см. Много вопросов SO...). Индекс также используется git во время merge
аналогичным образом
Мне удалось заставить его работать, просто сделав это из папки назначения:
git mv webapp/* .
Кажется, что это не работает в оболочке Windows (с ошибкой Bad source
), но будет работать в Windows, если вы используете оболочку Git Bash, которая расширяет подстановочный шаблон *
.
Если вы используете PowerShell, вы можете запустить эту команду из корня вашего проекта, и она поместит туда содержимое веб-приложения.
Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
Да, git будет отслеживать изменения в прошлом контенте. Он использует хеши содержимого файла, поэтому независимо от того, где они находятся в структуре каталогов, они будут тем же самым файлом.
В результате вы должны сделать ход в одном коммите, а затем исправить любые изменения в последующей фиксации. Это позволит git определять перенаправление с максимальной эффективностью и не будет иметь никакого значения для объема данных, хранящихся в репозитории (так как вы все равно будете делать эти изменения).
В Windows, используя Bash, сработало следующее:
git mv /c/REPO_FOLDER/X_FOLDER/Y_FOLDER/Z_FOLDER/* /c/REPO_FOLDER/X_FOLDER/Y_FOLDER