Яка найкраща практика "git clone" в існуючій папці?


479

У мене є робоча копія проекту, без жодних метаданих контролю джерела. Тепер я хотів би зробити еквівалент git-clone в цій папці та зберегти мої локальні зміни.

git-clone не дозволяє мені клонуватись у існуючу папку. Яка тут найкраща практика?


4
Краще обговорення тут .
cdunn2001

1
@MEM Мені подобається ця відповідь більше, але як працює ... stackoverflow.com/a/5377989/11236
ripper234

2
@ ripper234 - Так. Я був у тій же ситуації, і я просто робив ті кроки, і жодних питань. Все чисто і приємно. Я здогадуюсь, що це питання переваги, суть в тому, що обидва працюють, як ви заявляєте. Ура.
MEM

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

Відповіді:


557

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

Якщо ваш існуючий каталог має назву "код".

git clone https://myrepo.com/git.git temp
mv temp/.git code/.git
rm -rf temp

Це також можна зробити, не роблячи замовлення під час команди клонування; більше інформації можна знайти тут .


25
Зауважте, що це саме пропозиція від @ChrisJohnsen, яку він залишив у коментарях. Я вважав це корисним і хотів зробити це фактичною відповіддю. Кріс, якщо ти закінчиш ставити відповідь, я щасливо видалю цю.
amicitas

2
Дякую! Хоча для цього немає кроку на кшталт "git checkout -." як він думає, всі файли видалені, правда?
mrooney

2
Ні, поки ви використовуєте git cloneв якості першої команди, подальша команда перевірки не потрібна. Якщо ви замість цього використовуєте щось подібне git clone --no-checkoutна цьому першому кроці, то після переміщення каталогу .git необхідно git reset HEADбуде сказати git, що файли не видалено.
amicitas

3
Я додав би це як третій крок: mv temp / .gitignore code / .gitignore
Daniel Aranda

1
@KalpeshSoni, так git дізнається про змінені файли, і зміни можна буде побачити за допомогою звичайних команд git, таких як git status.
amicitas

284

Не клонуйте, замість цього прийміть. У репо:

git init
git remote add origin $url_of_clone_source
git fetch origin
git checkout -b master --track origin/master # origin/master is clone's default

Тоді ви можете скинути дерево, щоб отримати потрібну команду:

git reset origin/master # or whatever commit you think is proper...

і ти, як ти клонований.

Цікаве запитання тут (і те, що не має відповіді): як дізнатись, на якому ґрунті ґрунтувалося ваше оголене дерево, звідси на яку посаду потрібно повернутись.


7
Я не є прихильником цього - за налаштуваннями github "Порада: Помічник даних для роботи з обліковими записами працює лише тоді, коли ви клонуєте URL-адресу сховища HTTPS." Я використовував вірних помічників, і це відправило мене в довгу, досить безрезультатну кролячу нору.
Андрій

5
'git checkout - трек походження / master' також добре працює замість 'git checkout -b master - трек походження / master'. Скидання не потрібно.
felipecrp

1
Я отримував помилку "Git error: Наступні незавершені файли робочого дерева будуть перезаписані під замовлення", тому я додаю цю команду: git clean -d -fx ""
shakaran

1
точно не доцільно в усіх ситуаціях, але це саме те, що мені було потрібно.
Хаїм Елія

1
@AndreasKrey Ваша оригінальна відповідь (яку я пішов в історію редагування, щоб побачити) робить саме те, що потрібно для запитання (і я). Змінена відповідь під час реєстрації без використання -f, що відкидає локальні зміни і саме те, чого я не хочу. Якби я був ти, я би роздумав про те, щоб повернутись до своєї оригінальної відповіді.
Ajean

77

Я зробив наступне, щоб перевірити головну гілку в існуючому каталозі:

git init
git remote add origin [my-repo]
git fetch
git checkout origin/master -ft

2
Це чудова відповідь і дозволяє уникнути завершення роботи будь-якої файлової системи.
користувач151841

1
Це має бути прийнятою відповіддю, оскільки це не злом.
php_nub_qq

5
Насправді це робить саме те, чого не хочуть ОП (і я) , а це перезаписати локальні зміни.
Ajean

Мій підсумок вказує, що це допомогло мені, але це не найкраща відповідь на питання ОП.
TecBrat

2
Хтось може пояснити, чому -tтут використовується прапор?
jfowkes

38

Я б git cloneу новий каталог і скопіював вміст існуючого каталогу в новий клон.


4
якщо ви це зробите, переконайтесь, що перегляньте відмінності, перш ніж робити дуже ретельно - це абсолютний класичний випадок, коли ви можете випадково повернути зміни, які були внесені у вихідний репо з часу, коли ви отримали свою робочу копію - оскільки недостатньо інформації у робочій копії з’ясуйте, які зміни ви внесли в порівнянні з тим, що це було до того, як ви почали вносити зміни, щоб об'єднатися з іншими змінами, внесеними в репо. Я бачив, як це трапляється знову і знову в цій ситуації, до того моменту, коли я "сильно відлякував" себе і людей, з якими працював, коли-небудь це робив.
Бен Кліффорд

72
git clone wherever tmp && git mv tmp/.git . && rm -rf tmpІншими словами, переміщення .gitdir з тимчасового клону здається простішим, ніж очищення робочого дерева клону та копіювання наявних файлів туди.
Кріс Джонсен

1
@ChrisJohnsen: ти мав би зробити це відповіддю, це, безумовно, найкращий спосіб зробити це імхо
Стефано

2
@ChrisJohnsen git mv tmp/.git .повертається fatal: cannot move directory over file, source=tmp/.git, destination=.gitза мною. Хтось знає, в чому проблема?
Денніс

6
@Dennis, Це помилка: ця команда повинна бути простою mv, а не git mv; хоча це не пояснює, чому у вас вже є .gitфайл (що містить gitdir: some/path/to/a/git-dir"gitfile"; якби його не було, то ви б бачили fatal: Not a git repository (or any of the parent directories): .gitзамість цього).
Кріс Джонсен

34

Використання тимчасової директорії чудово, але це спрацює, якщо ви хочете уникнути цього кроку. З кореня робочого каталогу:

$ rm -fr .git
$ git init
$ git remote add origin your-git-url
$ git fetch
$ git reset --mixed origin/master

20
git reset --hard origin/masterвидалить усі локальні файли.
Муад Деббар

1
щоб додати до того, що вже було зазначено вище, різниця між hardі mixedполягає в тому, що змішані будуть зберігати локальні зміни (тому, якщо пізніше ви спробуєте витягнути це, ви побачите, наприклад, Неможливо потягнути за допомогою ребазування: У вас є незроблені зміни. Будь ласка, введіть або приховайте їх ) , тоді як важко
відкине

Ви неправильно написали дистанційне.
Гленн Дейтон

10
git clone your_repo tmp && mv tmp/.git . && rm -rf tmp && git reset --mixed

7
Використання git reset --hardпризведе до зменшення змін у локальному файлі, зокрема НЕ того, що вимагала ця ОП. --mixedслід використовувати замість цього.
Калеб

4

Для клонування git repo в порожній існуючий каталог виконайте наступне:

cd myfolder
git clone https://myrepo.com/git.git . 

Зауважте .в кінці вашої git cloneкоманди. Це завантажить репо в поточний робочий каталог.


4
fatal: destination path '.' already exists and is not an empty directory.
Роланд Кофлер

Каталог повинен бути порожнім.
okTalk

4
ОП задає питання про те, як клонуватися до існуючого проекту, заявляючи, що Git клон скаржиться. Погана відповідь.
mix3d

Це працює лише під час створення нового каталогу, виконайте вищезазначені команди, не використовуючи "git init"
Bilal Ahmed

3

Дуже багато відповідей, щоб зробити це так, як попросила ОП. Але варто зазначити, що робити це навпаки куди простіше:

git clone repo-url tmp/
cp -R working/ tmp/

Тепер у вас є бажаний цільовий стан - свіжий клон + локальні зміни.


2

До цього існує два підходи. Де це можливо, я б почав із чистої папки для нового каталогу git, а потім скопіював би вашу версію речей. Це може виглядати приблизно як *:

mv $dir $dir.orig
git clone $url $dir
rsync -av --delete --exclude '.git' $dir.orig/ $dir/
rm -rf $dir.orig

На даний момент у вас повинна бути досить чиста робоча копія з попередньою робочою папкою як поточна робоча директорія, тому будь-які зміни, включаючи видалення файлів, з’являться на радарі, якщо ви запустите git status.

З іншого боку, якщо ви дійсно повинні це робити навпаки, ви можете отримати той самий результат приблизно таким чином:

cd $dir
git clone --no-checkout $url tempdir
mv tempdir/.git .
rmdir tempdir
git reset --mixed HEAD

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

* Обидва приклади передбачають, що ви починаєте з оболонки в батьківському каталозі свого проекту.


2

Це найкращий з усіх методів, які я натрапив

Клоніруйте лише папку .git у сховищі (виключаючи файли, оскільки вони вже є existing-dir) у порожній тимчасовий каталог

  1. git clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp // можливо, захочеться --no-hardlinks для клонування місцевого репо

Перемістіть папку .git до каталогу з файлами. Це робить existing-dirgit repo.

  1. mv existing-dir/existing-dir.tmp/.git existing-dir/

Видаліть тимчасовий каталог

  1. rmdir existing-dir/existing-dir.tmp

  2. cd existing-dir

Git вважає, що всі файли видалені, це повертає стан репо до HEAD.

УВАГА: будь-які локальні зміни файлів будуть втрачені.

  1. git reset --mixed HEAD

1
Сильний скидання здається небажаним у 99% випадків, коли вам потрібно буде це зробити.
Стефан

0

Якщо ви використовуєте принаймні git 1.7.7 (що вчив cloneцю --configопцію), щоб перетворити поточний каталог у робочу копію:

git clone example.com/my.git ./.git --mirror --config core.bare=false

Це працює:

  • Клонування сховища в новій .gitпапці
  • --mirror робить новий клон в папку з метаданими як .git потрібно
  • --config core.bare=falsecountermands неявне bare=trueз --mirrorопції, тим самим дозволяючи сховище мати відповідний робочий каталог і діяти як звичайний клон

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


1
Зауважте, що ця методика призведе до [core]розділу локальної конфігурації, що включає обидва bare = true та bare = false . Більш проблематичним є те, що він буде мати неправильні значення для originвіддаленого пристрою, [remote "origin"]включаючи розділ mirror = trueі специфікацію для отримання, яка не працюватиме належним чином з робочою копією. Після виправлення цих проблем нормальне клонування та переміщення нової робочої копії .gitбудуть ефективнішими.
Араксія

0

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

Перевага цього методу полягає в тому, що ви не пропустите нічого в початковому сховищі, включаючи README або .gitignore.

Ви також можете скористатися командою нижче для завершення кроків:

$ git clone https://github.com/your_repo.git && mv existing_folder/* your_repo

0

Це можна зробити, ввівши наступні командні рядки рекурсивно:

mkdir temp_dir   //  Create new temporary dicetory named temp_dir
git clone https://www...........git temp_dir // Clone your git repo inside it
mv temp_dir/* existing_dir // Move the recently cloned repo content from the temp_dir to your existing_dir
rm -rf temp_dir // Remove the created temporary directory

0

Просто використовуйте. в кінці git cloneкоманди (перебуваючи в тому каталозі), як це:

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