Создайте репозиторий подмодулей из папки и сохраните историю фиксации git
У меня есть веб-приложение, которое исследует другие веб-приложения особым образом. Он содержит некоторые веб-демонстрации в demos
папка и один из демо теперь должны иметь свой собственный репозиторий. Я хотел бы создать отдельный репозиторий для этого демонстрационного приложения и сделать его подпакет субмодуль из основного репозитория без потери истории фиксации.
можно ли сохранить историю фиксации из файлов в репозитории папка и создайте из нее репозиторий и используйте его как субмодуль вместо?
3 ответов
Подробное Решение
см. примечание в конце этого ответа (последний абзац) для быстрой альтернативы подмодулям git с использованием npm;)
в следующем ответе вы узнаете, как извлечь папку из репозитория и сделать из нее репозиторий git, а затем включить ее в качестве субмодуль вместо папки.
вдохновение из статьи Герг "Байера"перемещение файлов из одного репозитория Git в Другой, Сохраняющий Историю
в начале, у нас есть что-то вроде этого:
<git repository A>
someFolders
someFiles
someLib <-- we want this to be a new repo and a git submodule!
some files
в шагах ниже, я буду ссылаться на это someLib
as <directory 1>
.
в конце концов, у нас будет что-то вроде этого:
<git repository A>
someFolders
someFiles
@submodule --> <git repository B>
<git repository B>
someFolders
someFiles
создайте новый репозиторий git из папки в другом репозитории
Шаг 1
получите свежую копию репозитория для разделения.
git clone <git repository A url>
cd <git repository A directory>
шаг 2
текущая папка будет новым репозиторием, поэтому удалите текущий пульт.
git remote rm origin
Шаг 3
извлеките историю нужной папки и зафиксируйте ее
git filter-branch --subdirectory-filter <directory 1> -- --all
теперь у вас должен быть репозиторий git с файлами из directory 1
в корне вашего РЕПО со всей связанной историей фиксации.
Шаг 4
создайте свой онлайн-репозиторий и нажмите новый репозиторий!
git remote add origin <git repository B url>
git push
вы можете необходимо установить upstream
ветка для вашего первого толчка
git push --set-upstream origin master
очистить <git repository A>
(необязательный, см. замечания)
мы хотим удалить следы (файлы и историю фиксации)<git repository B>
С <git repository A>
таким образом, история для этой папки существует только один раз.
это основано на удаление конфиденциальных данных из github.
заходим в новую папку и
git clone <git repository A url>
cd <git repository A directory>
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <directory 1> -r' --prune-empty --tag-name-filter cat -- --all
заменить <directory 1>
на папку, которую вы хотите удалить. -r
будет сделать это рекурсивно внутри указанного каталога :). Теперь нажмите на origin/master
С --force
git push origin master --force
этап босса (см. Примечание ниже)
создать субмодуль С <git repository B>
на <git repository A>
git submodule add <git repository B url>
git submodule update
git commit
проверьте, все ли работало так, как ожидалось и push
git push origin master
Примечание
сделав все это, я понял, что в моем случае более уместно использовать npm управлять своими вместо этого зависимости. Мы можем указать URL-адреса и версии git, см. пакета.JSON git urls как зависимости.
если вы делаете это таким образом, репозиторий, который вы хотите использовать в качестве требования должны быть модуль npm поэтому он должен содержать или вы получите эту ошибку: Error: ENOENT, open 'tmp.tgz-unpack/package.json'
.
tldr (альтернативное решение)
вы можете найти его проще использовать npm и управление зависимостями с помощью git URL-адреса:
- переместить папку в новый репозиторий
- run
npm init
внутри оба хранилища - run
npm install --save git://github.com/user/project.git#commit-ish
где вы хотите установить ваш зависимостей
решение @GabLeRoux раздавливает ветви и связанные коммиты.
простой способ клонирования и сохранения всех этих дополнительных ветвей и коммитов:
1-Убедитесь, что у вас есть этот псевдоним git
git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'
2-клонируйте пульт, потяните все ветви, измените пульт, отфильтруйте каталог, нажмите
git clone git@github.com:user/existing-repo.git new-repo
cd new-repo
git clone-branches
git remote rm origin
git remote add origin git@github.com:user/new-repo.git
git remote -v
git filter-branch --subdirectory-filter my_directory/ -- --all
git push --all
git push --tags
GabLeRoux работает хорошо, за исключением, если вы используете git lfs
и имеет большие файлы в каталог, который вы хотите отключить. В этом случае после шага 3 все большие файлы останутся указателей файлов, а не реальные файлы. Я думаю, это, вероятно, из-за .gitattributes
файл удаляется в процессе ветви фильтра.
понимая это, я нахожу следующее решение работает для меня:
cp .gitattributes .git/info/attributes
копирование .gitattributes
который git lfs использует для отслеживания больших файлов в .git/
каталог, чтобы избежать удаления.
когда фильтр-ветвь сделана, не забудьте положить обратно .gitattributes
Если вы все еще хотите использовать Git LFS для нового репозитория:
mv .git/info/attributes .gitattributes
git add .gitattributes
git commit -m 'added back .gitattributes'