Перемещение репозитория git на один уровень иерархии выше

Git начинающий вопрос:

У меня есть небольшой частный веб-проект с локальной версией msysgit. Там нет внешнего репозитория, так как он только для меня, так что я могу делать все, что захочу.

Я установил это в каталоге проекта, то есть в «webroot».

Теперь нужно было создать второй каталог, размещенный параллельно webroot. Назовем это активами.

Таким образом, структура теперь выглядит следующим образом:

\ project directory
----\webroot
----\assets

Я хотел бы включить этот новый каталог в репозиторий git, чтобы я также мог изменять версии файлов, хранящихся там, но, конечно, я не могу использовать «git add ../assets». Я также не склонен создавать новый проект git в каталоге_проектов, так как это приведет к потере всех моих предыдущих коммитов.

Итак, как мне переместить репозиторий из «webroot» в «project_directory», сохранив при этом мои коммиты, а затем имея возможность включать «активы»?


person Sorcy    schedule 23.03.2011    source источник
comment
не совсем то, что вы просите, но вы можете создать ветку и добавить в нее активы.   -  person Mr. L    schedule 23.03.2011


Ответы (5)


Итак, вы хотите, чтобы ваш репозиторий git выглядел так:

<projectdir>
    /.git
    /webroot
    /assets

Для этого необходимо переместить существующие файлы в репозитории в новый подкаталог webroot.

cd <git repo root>
mkdir webroot
git mv <all your files> webroot
git commit --all -m "moved all existing files to new 'webroot' directory"

Затем в вашей локальной файловой системе вы хотите переместить свой клон на один каталог выше, чем сейчас:

cd <projectdir>
mv webroot/* .
rmdir webroot

Затем вы хотите добавить каталог assets (и файлы) в репозиторий git:

git add assets
git commit -m "added assets to the repo"
person Tim Henigan    schedule 23.03.2011
comment
Хорошо, видимо, я дал недостаточно информации. Репозиторий уже НАХОДИТСЯ внутри /projectdir/webroot/, так как именно здесь он был изначально создан. Поскольку каталог активов был реализован, я бы предпочел, чтобы репозиторий действовал так, как будто он был создан в /projectdir/, чего, увы, не было. git mv не позволит мне перемещать файлы за пределы репозитория. - person Sorcy; 26.03.2011
comment
@Sorcy: кажется, я понимаю, что вы хотите сделать. Я обновил свой ответ, чтобы уточнить его. - person Tim Henigan; 26.03.2011
comment
Спасибо, это именно то решение, которое я искал. :) - person Sorcy; 26.03.2011
comment
Я обнаружил, что это решение также требует mv webroot/.* . для перемещения файлов репо и .gitignore. - person katriel; 16.07.2015
comment
git mv * webroot не будет работать, потому что подстановочный знак bash * также будет заменен на webroot, что сделает команду git mv webroot webroot. Git потерпит неудачу в этом. Другой папкой, с которой у него были проблемы, была .git. Поэтому мне пришлось использовать специальную переменную bash env GLOBIGNORE=webroot:.git, чтобы * не заменялся этими двумя каталогами. Благодаря этому мне не пришлось делать десятки ручных git mv — в моей директории очень много папок и файлов. Мне нужно было только вручную переместить папку .git. - person Koshmaar; 25.07.2016
comment
Почему rmdir? Разве webroot не содержит все файлы, которые вы хотели отслеживать? - person Juan De la Cruz; 27.07.2018
comment
Это самый правильный и простой способ, если файлов не слишком много. Но вместо mv webroot/* .; rmdir webroot используйте mv webroot tmp; mv tmp/.git tmp/* .; rmdir tmp. - person Curt; 05.01.2021

Вы также можете просто переместить каталог .git на один уровень вверх и обновить свое рабочее дерево.

cd projectdir
mv ./webroot/.git ./.git
git config core.worktree /absolute-path-to-project-dir
git add assets
git commit -m 'adding assets folder'

Не положительно, но я уверен, что путь к core.worktree должен быть абсолютным.

person braitsch    schedule 27.10.2011
comment
Вот порядок, который сработал для меня. Пока я нахожусь в папке, куда хочу переместить файл .git: mv .git / ../ - person anevaude; 21.02.2015
comment
Я сделал это в похожей ситуации, и мне пришлось повторно добавить в репозиторий файлы, которые уже были добавлены, когда они находились в предыдущем месте. По сути, я думаю, что потерял историю git для этих файлов. - person aneccodeal; 12.11.2020

Я предполагаю, что вы хотели переписать историю, чтобы она содержала все файлы во всех ревизиях, как если бы они всегда находились в подкаталоге webroot/, а не в корне

На справочной странице git filter-branch есть ответ, здесь улучшенная версия, которая перезаписывает все существующие ссылки (ветки) и теги:

time git filter-branch --index-filter 'git ls-files -s |
         sed "s-\t\"*-&webroot/-" |
         GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && 
     mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' --tag-name-filter cat -- --all

Мы позаботились о том, чтобы сделать эту операцию только для индекса, чтобы процесс выполнялся быстро даже для больших репозиториев. Не забудьте (когда удовлетворены) избавиться от исходных ссылок (.git/refs/original/*) и переупаковать репозиторий, чтобы избавиться от устаревших объектов дерева.

person sehe    schedule 26.03.2011
comment
Можете ли вы объяснить, как избавиться от исходных ссылок и переупаковать репо? Это просто GC или что-то еще? - person NateS; 19.11.2016
comment
Это именно то, что я хочу. Спасибо! Для людей, которые запутались, эта операция должна быть выполнена ПОСЛЕ завершения того, что предложил Тим Хениган. - person Youwei Liang; 21.04.2021

Ваши коммиты не привязаны локально к папке «webroot», они хранятся в репозитории git.

Вы можете просто удалить каталог webroot, перепроверить репозиторий в новом месте "/ каталог проекта", добавить каталог ресурсов и зафиксировать.

rm -Rf webroot
git clone path-to-repo
git add assets 
git commit -m "Added assets directory"
git push
person Nick    schedule 23.03.2011

Следующая команда перепишет вашу историю Git. Это будет выглядеть так, как если бы содержимое все время находилось в webroot. Обычно переписывание истории вызывает затруднения, если с репозиторием работают несколько человек. Поскольку вы работаете над ним один, все должно быть в порядке.

git filter-branch --index-filter '
    git read-tree --prefix="webroot/" $GIT_COMMIT && \
    git ls-files \
      | sed "s/\/.*//" \
      | sort \
      | uniq \
      | grep -v "^webroot" \
      | xargs -L1 git rm -r --cached > /dev/null'
person Lars Schneider    schedule 10.02.2018