Як неглибоко клонувати конкретний коміт із глибиною 1?


83

Чи можна дрібно клонувати певний коміт у сховищі, тобто з глибиною 1? Щось на зразок

git clone http://myrepo.git 728a4d --depth 1

отримати стан сховища, як це є при фіксації з SHA 728a4d...?

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


Відповіді:


81

Починаючи з Git 2.5.0 (який повинен бути доступний як на клієнтській, так і на стороні сервера), ви можете встановити uploadpack.allowReachableSHA1InWant=trueна стороні сервера, щоб дозволити отримання конкретних SHA1:

git init
git remote add origin <url>
git fetch --depth 1 origin <sha1>
git checkout FETCH_HEAD

Зауважте, що я не знайшов синтаксису, з яким це можна було б зробити git cloneбезпосередньо.


3
Це не працює принаймні з github. Я не зміг зробити вибірку для github.com/Seldaek/monolog/commit/… . git fetch --depth 1 origin d6be96bc...шоуfatal: Couldn't find remote ref d6be96bc...
Кірбі

9
Правильно, GitHub лише ввімкнув allowTipSHA1InWant, але allowReachableSHA1InWantні allowAnySHA1InWant.
schuberth

Я отримав помилку кажучиerror: pathspec 'FETCH_HEAD' did not match any file(s) known to git
rocketspacer

2
Погравши з цим, я виявив, що це працювало лише на дуже сучасній версії git-клієнта. Навіть git 2.17 у мене не працював. Я відновив git у 2.24, і це спрацювало.
Еял,

1
Працював у мене з 2.27.0.windows.1 на github.com/dotnet/aspnetcore @ 62c098bc170f50feca15916e81cb7f321ffc52ff
JJS

25

ПРИМІТКА: Мій приклад не допомагає клонувати за допомогою хешу коміту, але допоможе клонувати тег і мати полегшений репозиторій.

Якщо вам потрібно мати лише один коміт у вашому "клоні", і ви збираєтеся використовувати хеш коміту, коротка відповідь - НІ .

Я використовую цю конструкцію команди (перевірена на v2.13.2.windows.1 ) для тегів:

git clone --depth 1 git@github.com:VENDOR/REPO.git --branch 1.23.0 --single-branch

Повний приклад:

$ git clone --depth 1 git@github.com:Seldaek/monolog.git --branch 1.23.0 --single-branch
Cloning into 'monolog'...
remote: Counting objects: 201, done.
remote: Compressing objects: 100% (188/188), done.
remote: Total 201 (delta 42), reused 32 (delta 5), pack-reused 0
Receiving objects: 100% (201/201), 190.30 KiB | 0 bytes/s, done.
Resolving deltas: 100% (42/42), done.
Note: checking out 'fd8c787753b3a2ad11bc60c063cff1358a32a3b4'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

$ cd monolog

.gitрозмір папки ( 267 тис. проти 2,6 млн. при використанні повного clone):

$ du -h --max-depth=0 .git
267K    .git

Я хотів би позначити, --branchможе взяти тег / гілку.

https://git-scm.com/docs/git-clone#git-clone---branchltnamegt

--branch також може взяти теги та від'єднати HEAD при цьому фіксації в отриманому сховищі.

UPD

У двох словах, це може зайняти "реф". Детальніше ви можете прочитати тут: Що означає повідомлення про помилку git "Сервер не дозволяє запит на нерекламований об'єкт"?

Крім того, немає таких фокусів, як:

git fetch --depth 1 origin <COMMIT_HASH>

Дякую @BenjiWiebe за те, що вказав мені на мою помилку.


2
За це мільйон голосів. Занадто багато людей стверджують, що це неможливо.
жартує

3
--branchніяк НЕ підтримує коммітов тільки імена гілок ... це не вирішує його взагалі. Як це неправда.
виходьте з життя

1
Кірбі Я намагаюся зробити це зараз, і це не працює для фіксацій , а @abourget говорить. Можливо, це працює для тегів та гілок, але я намагаюся робити це за допомогою хешів комітів, але це не працює.
BenjiWiebe 13.03.18

@BenjiWiebe, я зрозумів, хлопці. Так, схоже, GIT не може визначити конкретний коміт. : - / Копаю глибше.
Кірбі

@BenjiWiebe, отже, на жаль, немає можливості використовувати хеш коміту. Просто двічі перевірили.
Кірбі

6

Негайна відповідь така: Ви не можете.
Чому? детальне пояснення можна знайти тут: Чому немає варіанту коміту Git Clone?

Що ще ти можеш зробити?

Як клонувати сховище до певного коміту? (повний клон)

# Create empty repository to store your content
git clone <url>
git reset <sha-1> --hard

Більше інформації:

Як клонувати одну гілку?

git clone <url> --branch <branch_name> --single-branch <folder_name>

Як клонувати лише останні коміти з даної гілки?

git clone <url> --depth=1 --branch <branch_name> --single-branch <folder_name>

Як неглибоко клонувати конкретний коміт із глибиною 1?

Як прокоментував @sschuberth: --depthмає на увазі --single-branch.

Замість клонування використовуйте команду fetch:

# fetch a commit (or branch or tag) of interest
# In this case you will have the full history of this commit
git fetch origin <sha1>

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

Вибачте, пропустив, я якось зрозумів, що йому потрібен останній коміт. Оновлення відповіді. Дякую
CodeWizard

--depthмається на увазі --single-branch, тож у такому випадку ви можете його відмовитись.
schuberth

Чи git fetchнасправді приймає SHA1 для refspec?
Phil Frost

ні. його просто "завантажують" дані, що відповідають назві гілки
CodeWizard

5

Спробуйте використовувати whileв bash:

git clone --depth=1 $url
i=1; while ! git show $sha1; do git fetch --depth=$((i+=1)); done

Це досить повільно, оскільки воно отримує кожен коміт окремо; ви могли б збільшити приріст (для отримання комітів партіями та покращення продуктивності в мережі), але це все-таки грубий підхід.


Чому голоси проти? ... Мені насправді потрібно було це зробити, і моє рішення це зробило!
Корін

а якщо ви хочете взяти зобов’язання, зроблене роками тому, або воно вже не існує?
Daan Bakker

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