Як клонуватись у не порожній каталог?


572

У мене є каталог A з файлами, що відповідають каталогу B. У каталозі A можуть бути інші необхідні файли. Каталог B - це git repo.

Я хочу клонувати каталог B у каталог A, але git-clone не дозволить мені, оскільки каталог не порожній.

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

Я не можу клонуватись у порожній каталог, оскільки у мене є файли в каталозі A, які не знаходяться в каталозі B, і я хочу їх зберегти.

Копіювання .git не є варіантом, оскільки я хочу, щоб рефлекси натискали / тягнули, і я не хочу їх встановлювати вручну.

Чи можна це зробити?

Оновлення: Я думаю, що це працює, може хтось бачить якісь проблеми? ->

cd a
git clone --no-hardlinks --no-checkout ../b a.tmp 
mv a.tmp/.git .
rm -rf a.tmp
git unstage # apparently git thinks all the files are deleted if you don't do this

5
можливо, ви могли б змінити прийняту відповідь?
Бастіанський Кваст

Відповіді:


724

Це працювало для мене:

git init
git remote add origin PATH/TO/REPO
git fetch
git reset origin/master  # Required when the versioned files existed in path before "git init" of this repo.
git checkout -t origin/master

ПРИМІТКА: -t встановить для вас гілку вище за течією, якщо це те, що ви хочете, і це зазвичай.


70
Це не працює в не порожній каталозі, коли вхідні файли вже існують (як описано в оригінальному запитанні). Але якщо ви git reset origin/masterпісля цього git fetch, він буде працювати (також зберігаючи будь-які локальні зміни).
Араксія

8
фатально: Не вдається оновити контури та одночасно перейти до 'master' гілки.
Арнольд Роа

7
Ця відповідь не працює для мене. Коли я роблю git checkout ...git, скаржиться, що всі мої файли будуть перезаписані, і я повинен їх перенести спочатку. Коли я вперше `git reset origin / master /` спочатку команда checkout скаржиться, що гілка з ім'ям master вже існує.
Саскія

4
git checkout masterбув достатнім заключним кроком для мене.
yoyo

16
Всі кроки працювали відмінно , але останній отримав мене: fatal: A branch named 'master' already exists. Я думаю, мені це не дуже було потрібно.
Шаді

164

У наступних командах оболонки existing-dirзнаходиться каталог, вміст якого відповідає відстеженим файлам у repo-to-cloneсховищі git.

# Clone just the repository's .git folder (excluding files as they are already in
# `existing-dir`) into an empty temporary directory
git clone --no-checkout repo-to-clone existing-dir/existing-dir.tmp # might want --no-hardlinks for cloning local repo

# Move the .git folder to the directory with the files.
# This makes `existing-dir` a git repo.
mv existing-dir/existing-dir.tmp/.git existing-dir/

# Delete the temporary directory
rmdir existing-dir/existing-dir.tmp
cd existing-dir

# git thinks all files are deleted, this reverts the state of the repo to HEAD.
# WARNING: any local changes to the files will be lost.
git reset --hard HEAD

5
Мені потрібно було це зробити, git reset --hard HEADабо він не відмовиться від видалених файлів.
Димитар

18
git reset HEADдобре працював для мене. git reset --hard HEADзнищує будь-які зміни у ваших файлах, тому якщо вони не точно такі, як файли у сховищі, ви не повинні цього робити.
Тгр

1
git reset HEADце, мабуть, не впливає на мене. git reset --hard HEAD- але це втрачає будь-які зміни, внесені до файлів. Чи є краще рішення?
Джейкоб Дорман

1
@ Відповідь Кейсі - git init / remote add / fetch / checkout - чистіша та простіша і не потребує тимчасових папок.
yoyo

1
@ Відповідь Кейсі не спрацювала для мене, коли в папках вже були файли, які потрібно було залишити, але їх не було в репортажі git. Це корисно для оновлення конфігурації після запуску сценаріїв встановлення, де створюються файли та каталоги, але вам потрібно оновити / додати файли поверх встановлених елементів.
соулстон

104

Невелика зміна однієї з відповідей, яка працювала для мене:

git init
git remote add origin PATH/TO/REPO
git pull origin master

почати працювати над головним відділенням відразу


1
довелося скинути HEAD --важко очистити брудний існуючий каталог, не видаляючи невідповідні файли, вказані в gitignore
Рей Фосс

1
Це те, що насправді працювало на мене, на відміну від відповіді @ cmcginty.
certainlyakey

4
Це не зовсім еквівалентно git-клону - того, чого не вистачає, є висхідна інформація для ведучої гілки. Це можна виправити, додавши git branch --set-upstream-to=origin/master master.
Славен Резіч

Ця версія працювала для мене, просто довелося зробити скидання git --hard HEAD
Frédéric Klee

29

Попередження - це може потенційно перезаписати файли.

git init     
git remote add origin PATH/TO/REPO     
git fetch     
git checkout -t origin/master -f

Змінено з відповіді @ cmcginty - без того, якщо для мене це не вийшло


Напевно вам потрібно перевірити всі файли після цього git checkout .?
Кріс Стричинський

25

Ось що я закінчив робити, коли в мене була така ж проблема (принаймні, я думаю, що це та сама проблема). Я зайшов у каталог А і побігgit init .

Оскільки я не хотів, щоб за файлами в каталозі A супроводжувався git, я відредагував .gitignore і додав до нього наявні файли. Після цього я побіг git remote add origin '<url>' && git pull origin masterта воюла, Б "клонували" в А без жодної гикавки.


2
Ця техніка не працює в не порожній каталозі, коли вхідні файли вже існують (як описано в оригінальному запитанні).
Араксія

11

Я використовував це кілька моментів тому, вимагає найменш потенційно руйнівних команд:

cd existing-dir
git clone --bare repo-to-clone .git
git config --unset core.bare
git remote rm origin
git remote add origin repo-to-clone
git reset

І вуаля!


10

Ще один простий рецепт, здається, добре працює для мене:

git clone --bare $URL .git
git config core.bare false

Головний мій варіант використання для перевірки в каталозі з існуючими файлами - це керування моїми точковими файлами Unix за допомогою Git. У новому обліковому записі домашній каталог вже матиме в ньому деякі файли, можливо, навіть ті, які я хочу отримати від Git.


1
Голі сховища налаштовані дещо інакше, і хоча це працює, я б не рекомендував це. :)
ThorSummoner

1
Чи можете ви бути більш конкретними? Чим відрізняється?
Кен Вільямс

1
Лише дві відмінності: 1.) .git/configФайл вказує, що репост оголений. 2.) Файли, які зазвичай зберігаються .git, зберігаються в корені (який ви назвали .git)
може

4
Це саме ті зміни , які клонування .gitі встановлення core.bareв falseдбатиме, так що я все ще відчуваю себе добре про цей метод.
Кен Вільямс

10

Це працювало для мене:

cd existing_folder
git init
git remote add origin path_to_your_repo.git
git add .
git commit
git push -u origin master

6

У мене була аналогічна проблема з новим веб-каталогом Apache (обліковий запис, створений за допомогою WHM), який я планував використовувати в якості інтерактивного веб-сервера. Мені потрібно було спочатку клонувати свій новий проект з базою коду і періодично розгортати зміни, витягуючи з сховища.

Проблема полягала в тому, що в обліковому записі вже були такі файли веб-сервера, як:

.bash_history
.bash_logout
.bash_profile
.bashrc
.contactemail
.cpanel/
...

... що я не хотів ні видаляти, ні призначати своє сховище. Мені знадобилися вони, щоб просто залишитися там без нагляду та без нагляду.

Що я зробив:

Я зайшов у свою веб-папку (существующую папку):

cd /home/existing_folder

і потім:

git init
git remote add origin PATH/TO/REPO
git pull origin master
git status

Він відображав (як і очікувалося) список багатьох нестадійних файлів - тих, які вже існували спочатку з мого веб-акаунта cPanel.

Потім, завдяки цій статті , я просто додав список цих файлів до:

**.git/info/exclude**

Цей файл, майже як і .gitignoreфайл, дозволяє ігнорувати файли від постановки. Після цього мені не було чого робити в каталозі .git / каталог - він працює як особистий, .gitignoreякий ніхто більше не може побачити.

Тепер перевірка git statusповернень:

On branch master
nothing to commit, working tree clean

Тепер я можу розгорнути зміни на цьому веб-сервері, просто витягнувши з мого сховища git. Сподіваємось, це допомагає деяким веб-розробникам легко створити сервер для встановлення.



4

Можливо, я неправильно зрозумів ваше запитання, але чи не було б простіше, якщо ви копіюєте / переміщуєте файли з A в git repo B і додаєте потрібні з git add ?

ОНОВЛЕННЯ: Від git doc:

Клонування в існуючий каталог дозволено лише в тому випадку, якщо каталог порожній.

ДЖЕРЕЛ: http://git-scm.com/docs/git-clone


2
Ні, власник і файли можуть бути довільними. Це для ситуації з декількома розробниками. Всі ми маємо існуючі каталоги, і лише один наразі має замовлення на git. У всіх нас є однакові підмножини файлів, тому ми хочемо, щоб інші розробники могли клонуватись, зберігаючи свої файли. І це повинно бути максимально елегантно і зручно.
Дейл Лісник

Чесно кажучи, я не бачу сенсу розвиватися в такому стані. Не можете використовувати гілки та операції злиття? Або мають підрепозиторії із зовнішніми залежностями? Чому ви хочете покластися на один "git checkout"?
Роберто Алої

5
"Один порядок перевірки" - це не суть усього випробування. Просто так воно є, і нам потрібен спосіб рухатися вперед. Я оновив оригінальне запитання з рішенням, яке, здається, працює. Я вдячний за відгуки.
Дейл Форестер

3
Для цього є багато законних випадків - у мене є складне дерево папок, яке має бути встановлено до того, як джерелом мого проекту може бути налаштування, і це дерево папок містить ліцензовані роботи, які неможливо зберігати на GitHub, наприклад.
BrainSlugs83

3

Я шукав щось подібне, і ось що я придумав:

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

  1. Перейдіть до веб-дерева та запустіть git init
  2. Перейдіть до місця призначення сховища та запустіть: git clone --bare /path/to/web/repo
  3. Відредагуйте конфігураційний файл у моєму віддаленому репо і видаліть [remote "origin"]розділ.
  4. Додайте [remote "origin"]розділ до .git / config у веб-дереві, вказуючи на нове віддалене репо.

Мені цей рецепт дуже подобається.
длан

git clone --bareТут зайві і обхідні. Чому б не просто git remote add origin <URL>в першу чергу?
Араксія

3

це робота для мене ,, але вам слід об'єднати віддалені файли сховища з локальними файлами:

git init
git remote add origin url-to-git
git branch --set-upstream-to=origin/master master
git fetch
git status

1

Мені сподобалась відповідь Дейла , і я також додав

git clone --depth 2 --no-checkout repo-to-clone existing-dir/existing-dir.tmp
git branch dev_new214
git checkout dev_new214
git add .
git commit
git checkout dev
git merge dev_new214

Невелика глибина дозволила уникнути безлічі зайвих ранніх дев. Нова гілка дала нам гарну візуальну історію, що з цього сервера був поміщений новий код. Це, на мій погляд, ідеальне використання гілок. Дякую за прекрасне розуміння всіх людей, які розмістили тут.


0

У мене виникли ті самі проблеми, коли я намагався клонуватися до c / code

Але ця папка містить цілу купу проектів.

Я створив нову папку в c / code / newproject і відобразив свій клон до цієї папки.

git для робочого столу тоді запитав у мого користувача, а потім клонував штрафу.

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