Git: рекурсивно перемещаются подмодули (вложенные подмодули)
У меня есть следующая структура git
- git-repo a
-- subdirectory 2015
--- git-submodule b
-- git-submodule c
--- git-submodule d
Я хотел бы переместить подмодуль git c в папку 2015.
Я знаю "грязные способы" для этого (включая модификацию .git/config и изменение gitdir в нескольких файлах в файлах .git/modules)
Недавно я прочитал, что git mv должен иметь возможность сделать это, т.е. запустить
git mv c 2015/
Это отлично работает для репозиториев, в которых нет вложенного подмодуля (d в моем случае). Однако, когда я запускаю эту команду в моем каталоге, я получаю ошибки, например
fatal: Not a git repository: d/../../.git/modules/c/modules/d
fatal: 'git status --porcelain' failed in submodule 2015/c
(обратите внимание, что эта ошибка возникает при статусе git после выполнения вышеупомянутого перемещения)
Кто-нибудь знает о чистом методе для этого перемещения (т.е. не требует ручного изменения путей в файлах .git/modules)?
Изменить: (6/10/2015)
Мое текущее лучшее решение, которое не связано с модификациями любого из конфигурационных файлов git (сначала убедитесь, что все изменения d были зафиксированы и помещены куда-то)
rm c/d -rf
git mv c 2015
cd 2015/c
git submodule update
Изменить: (8/10/2015)
Еще менее навязчивое обходное решение
git mv c 2015
rm 2015/c/d/.git
cd 2015/c
git submodule update
Ответы
Ответ 1
Как подтверждено @VonC в fooobar.com/questions/292359/..., это ошибка в git mv.
Существует несколько возможных обходных решений. Самый простой из них не требует сложных модификаций .git файлов (я использовал этот вопрос с тех пор, как задал вопрос). Он работает следующим образом:
git mv c 2015
rm 2015/c/d/.git
cd 2015/c
git submodule update
Он временно удаляет файл .git в подбмодуле d
. Обновление подмодуля git затем снова исправляет этот .git файл.
Для других обходных решений, которые позволяют избежать временного удаления gitdir, см. этот ответ: fooobar.com/questions/292359/...
Ответ 2
Обновление 2017:
Последний Git 2.14.x/2.15 (Q4 2017) документирует ошибку
См. commit c514167 (15 сентября 2017 г.) Heiko Voigt (hvoigt
).
(объединено Junio C Hamano - gitster
- в commit 450b908, 25 Sep 2017)
При использовании git-mv
с подмодулем он обнаружит это и обновит пути для его конфигураций (.gitmodules
, worktree и gitfile).
Это не работает для рекурсивных подмодулей, где пользователь переименовывает корень подмодуль.
Оригинальный ответ 2015
Я только что протестировал его с помощью Git 2.6.0 (в Windows), и перемещение подмодулей с их собственными вложенными подмодулями кажется проблематичным:
C:\Users\vonc\prog\git\tests\submove>git clone --recursive a a1
Cloning into 'a1'...
done.
Submodule '2015/b' (C:/Users/vonc/prog/git/tests/submove/b) registered for path '2015/b'
Submodule 'c' (C:/Users/vonc/prog/git/tests/submove/c) registered for path 'c'
Cloning into '2015/b'...
done.
Submodule path '2015/b': checked out 'dc18955ec7b9ad0c04245968e2474646e4d593b2'
Cloning into 'c'...
done.
Submodule path 'c': checked out 'fb4722eaca17ac171b7a2c8c5a1ac1e697f0ee85'
Submodule 'd' (C:/Users/vonc/prog/git/tests/submove/d) registered for path 'd'
Cloning into 'd'...
done.
Submodule path 'c/d': checked out '73cd7b8ff82519720b2fcca18df5ed00dd618b71'
У меня есть:
a1
c
d
2015
b
Если я попытаюсь переместить субмодуль c
в подпапку 2015:
C:\Users\vonc\prog\git\tests\submove\a1>git mv c 2015/c
C:\Users\vonc\prog\git\tests\submove\a1>git status
fatal: Not a git repository: d/../../.git/modules/c/modules/d
fatal: 'git status --porcelain' failed in submodule 2015/c
Я обнаружил, что мне нужно изменить 2 вещи во вложенном модуле d
:
1/изменить вручную .git/modules/c/modules/d/config
, чтобы ввести правильный путь:
git config -f .git/modules/c/modules/d/config core.worktree ../../../../../2015/c/d
^^^^
2/изменить d
worktree:
git config -f .git/modules/c/modules/d/config core.worktree ../../../../../2015/c/d
Оттуда работает a git status
, но мне нравится (обязательно) добавить git submodule sync --recursive
:
C:\Users\vonc\prog\git\tests\submove\a1>git submodule sync --recursive
Synchronizing submodule url for '2015/b'
Synchronizing submodule url for '2015/c'
Synchronizing submodule url for '2015/c/d'
git status
показывает ожидаемый результат:
C:\Users\vonc\prog\git\tests\submove\a1>git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: .gitmodules
renamed: c -> 2015/c
Я добавляю и фиксирую это изменение:
C:\Users\vonc\prog\git\tests\submove\a1>git add .
C:\Users\vonc\prog\git\tests\submove\a1>git commit -m "move sub c in 2015/c"
[master 8289632] move sub c in 2015/c
2 files changed, 1 insertion(+), 1 deletion(-)
rename c => 2015/c (100%)
C:\Users\vonc\prog\git\tests\submove\a1>gl
* 8289632 - (HEAD -> master) move sub c in 2015/c (3 seconds ago) <VonC>
* 7ebb8e0 - (origin/master, origin/HEAD) a with sub c (38 minutes ago) <VonC>
Теперь я клонировал это репо, чтобы проверить, действительно ли он правильно зарегистрирован:
C:\Users\vonc\prog\git\tests\submove>git clone --recursive a1 a2
Cloning into 'a2'...
done.
Submodule '2015/b' (C:/Users/vonc/prog/git/tests/submove/b) registered for path '2015/b'
Submodule 'c' (C:/Users/vonc/prog/git/tests/submove/c) registered for path '2015/c'
Cloning into '2015/b'...
done.
Submodule path '2015/b': checked out 'dc18955ec7b9ad0c04245968e2474646e4d593b2'
Cloning into '2015/c'...
done.
Submodule path '2015/c': checked out 'fb4722eaca17ac171b7a2c8c5a1ac1e697f0ee85'
Submodule 'd' (C:/Users/vonc/prog/git/tests/submove/d) registered for path 'd'
Cloning into 'd'...
done.
Submodule path '2015/c/d': checked out '73cd7b8ff82519720b2fcca18df5ed00dd618b71'
Как вы можете видеть, c
и c/d
находятся в ожидаемой подпапке 2015/
:
C:\Users\vonc\prog\git\tests\submove>cd a2
C:\Users\vonc\prog\git\tests\submove\a2>dir 2015\c
Directory of C:\Users\vonc\prog\git\tests\submove\a2\2015\c
03/10/2015 18:10 <DIR> .
03/10/2015 18:10 <DIR> ..
03/10/2015 18:10 29 .git
03/10/2015 18:10 40 .gitmodules
03/10/2015 18:10 <DIR> d
2 File(s) 69 bytes
3 Dir(s) 23 656 910 848 bytes free
C:\Users\vonc\prog\git\tests\submove\a2>dir 2015\c\d
Directory of C:\Users\vonc\prog\git\tests\submove\a2\2015\c\d
03/10/2015 18:10 <DIR> .
03/10/2015 18:10 <DIR> ..
03/10/2015 18:10 42 .git
03/10/2015 18:10 3 d.txt
2 File(s) 45 bytes
2 Dir(s) 23 656 910 848 bytes free