Яка найкраща практика "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.