Переміщення сховища git на один рівень ієрархії


79

Запитання для початківців Git:

У мене є невеликий приватний веб-проект, який виконується локально за версією msysgit. Зовнішнього сховища немає, оскільки це лише для мене, тому я в основному можу робити все, що хочу.

Я налаштував це в каталозі проекту, тобто у "webroot".

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

Отже, структура тепер така:

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

Я хотів би включити цей новий каталог до сховища git, щоб я також міняв версії файлів, що там зберігаються, але, звичайно, я не можу використовувати "git add ../assets". Я також не схильний створювати новий проект git у project_directory, оскільки це втратить усі мої попередні коміти.

То як я можу перенести сховище з "webroot" в "project_directory", зберігаючи свої коміти, а потім мати можливість включати "активи"?


не зовсім те, про що ви просите, але ви можете створити гілку та додати до неї активи.
містер Л,

Відповіді:


78

Отже, ви хочете, щоб ваш репозиторій 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"

2
Гаразд, мабуть, я не дав достатньо інформації. Сховище вже є всередині / projectdir / webroot /, оскільки саме тут воно було створено спочатку. Оскільки каталог активів відбувся, я віддав би перевагу, якби сховище діяло так, ніби воно було створене в / projectdir /, що, на жаль, не було. git mv не дозволить мені переміщати файли за межі сховища.
Сорсі

@Sorcy: Я вважаю, що розумію, що ти хочеш зробити. Я оновив свою відповідь, щоб пояснити її.
Тім Хеніган

Дякую, саме це рішення я шукав. :)
Сорсі

2
Я виявив, що це рішення вимагає mv webroot/.* .також для переміщення файлів репо та .gitignore.
Катріель

git mv * webrootне буде працювати, оскільки узагальнювач bash * також буде замінено webroot, що робить команду be git mv webroot webroot. Git не зможе цього зробити. Іншою папкою, з якою вона мала проблеми, була .git. Тому мені довелося використовувати спеціальну змінну bash env, GLOBIGNORE=webroot:.gitщоб * не замінювався цими двома каталогами. Завдяки цьому мені не довелося робити десятки ручних git mv - у моєму каталозі багато папок і файлів. Мені довелося лише перемістити папку .git вручну.
Кошмар

18

Ви також можете просто перемістити свій .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 повинен бути абсолютним.


Ось порядок, який працював у мене. Поки я перебуваю в папці, куди хочу перенести файл .git: mv .git / ../
anevaude

Я зробив це в подібній ситуації, і мені довелося повторно додавати до репо файли, які вже були додані, коли вони були в попередньому розташуванні. Отже, по суті, я думаю, що я втратив історію git для цих файлів.
aneccodeal

11

Припускаю, ви мали намір переписати історію, щоб вона містила всі файли у всіх версіях, як ніби вони завжди знаходились у підкаталозі webroot /, а не в кореневій

Відповідь має відповідна сторінка фільтра гілки git, ось вдосконалена версія, яка переписує всі існуючі посилання (гілки) та теги:

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 / *) і перепакувати репо, щоб втратити застарілі об’єкти дерева.


2
Чи можете ви пояснити, як позбутися оригінальних посилань та перепакувати репо? Це просто ГХ чи щось інше?
NateS

4

Ваші коміти не прив'язані локально до папки "webroot", вони зберігаються в репозиторії git.

Ви можете просто видалити каталог webroot для повторного оформлення сховища в новому розташуванні "/ каталог проекту", додати каталог активів і зробити коміт.

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

0

Наступна команда перепише вашу історію 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'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.