Почему я не могу оттолкнуться от мелкого клона?

В опции git clone --depth указано

--depth <depth> 
Create a shallow clone with a history truncated to the specified number of revisions. 
A shallow repository has a number of limitations 
(you cannot clone or fetch from it, nor push from nor into it),
 but is adequate if you are only interested in the recent history of a large project with a long history,
 and would want to send in fixes as patches. 

Почему мелкие клоны имеют это ограничение? Почему это патч только рабочий процесс?

Для некоторых рабочих процессов проекта мне нужно передать только последнюю фиксацию из одной ветки в кодер, а затем предоставить им возможность push их (ускоренную перемотку) событий на главный сервер. Это частично для безопасности, защиты IP и размера репо, а частично для уменьшения путаницы, которую большое репо принесет наивному кодеру. Есть ли git рабочий процесс, который позволяет это?


Обновление: на основании ответа Карла Билефельда ответ git checkout --orphan должен быть правильным ответом. Но по-прежнему нужно "клонировать" эту ветку только новому пользователю и иметь возможность эффективно ее продвигать.

На странице пользователя указано:

git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>] --orphan

Создайте новую сиротскую ветвь с именем <new_branch>, начиная с <start_point> и переключитесь на него. Первая фиксация сделана на этом новом у ветки не будет родителей, и это станет корнем новой истории полностью отключен от всех других ветвей и совершает.

Индекс и рабочее дерево настроены так, как если бы вы ранее запустите git checkout <start_point>. Это позволяет вам начать новый история, которая записывает набор путей, похожих на <start_point> на легко запустить git commit -a, чтобы сделать фиксацию root.

Это может быть полезно, когда вы хотите опубликовать дерево из фиксации не подвергая его полной истории. Вы можете сделать это, чтобы опубликовать ветку с открытым исходным кодом проекта, текущее дерево которого "чистый", но чья полная история содержит проприетарные или иные обремененные биты кода.

Если вы хотите запустить отключенную историю, которая записывает набор путей, которые полностью отличаются от тех, что относятся к <start_point>, то вы должны очистить индекс и рабочее дерево сразу после создания сиротская ветвь, запустив git rm -rf . с верхнего уровня рабочее дерево. После этого вы будете готовы подготовить свои новые файлы, заполняя рабочее дерево, копируя их из другого места, извлечение tarball и т.д.

Интересна ссылка VonC на комментарии Junio. Я думаю, что руководство должно обеспечить руководство в этом случае и разрешить правильную команду [например. clone <branch> --options], чтобы извлечь только соответствующую часть репо. Очевидно, что вероятность успеха push возрастает за счет наличия нескольких связанных коммитов и SHA1 в нижней части истории, которые блокируют соответствие репо.


Обновление git 1.9.0: примечания к выпуску 14 Фев '14.

"Извлечение из мелко-клонированного хранилища было запрещено, прежде всего потому, что вовлеченные кодеки не были тщательно проверены и мы не потрудились поддерживать такое использование. Эта попытка освобождения разрешить передачу объекта из мелко-клонированного репозитория в более контролируемый способ (т.е. приемник становится мелким хранилищем с усеченной историей).

Это хорошая новость для мелких клониров. Далее - Узкие клоны, возможно.

Ответ 1

Как Юнио С. Хамано (главный Git сопровождающий) ставит его:

Не правило более или менее похоже:

Если ваша мелкая история репозитория не продлевается достаточно долго, а другой репозиторий раздвоен до вашей усеченной истории, вы не сможете вычислить общего предка, и вы не можете вытолкнуть его.

Обновление 2014: см. Является ли Git clone --depth 1 (мелкий клон) более полезным, чем это делает?": это ограничение будет отменено с помощью Git 1.9!

Обновление 2015: с Git 2.5+ вы даже сможете извлечь одно commit. См. "Вытяните конкретную фиксацию из удаленного репозитория Git


Оригинальный ответ (август 2011):

Собственно, подумайте об этом, он намного сильнее, чем "невозможно вычислить общий".

История может выглядеть так:

          R---R---R
         /
  --R---R---X---X---S---S---S

где S - это фиксации, которые у вас есть в вашем мелком репозитории, а R - это коммиты, которые существуют в репозитории, который получает ваш push. Поскольку ваша история неглубока, ни один репозиторий не имеет "X", которые являются коммитами, которые должны существовать, чтобы сохранить историю репозитория получателей; получатель не является мелким для начала, и мы не хотим делать его мелким.

Если вы клонировали мелко некоторое время назад, работали без общения с другой стороной, пока другая сторона прогрессировала, И, если прогресс другой стороны включал перемотку и восстановление истории, вы увидите аналогичная топология.
Самый левый 'S' на приведенном выше рисунке, возможно, был концом ветки, когда вы клонировали с глубиной 1, и с тех пор удаленный конец мог отбросить три верхних конца и перестроить свою историю, которая ведет к самой правой " R.
В таком случае нажатие на удаленный HEAD завершится с ошибкой.


Таким образом, он может работать в некоторых случаях, но он не поддерживается:

Если я должен что-то сказать об этом...

  • Я думаю, что "не поддерживается" - это лаконичный способ дать достаточно хорошую информацию, но он будет работать только для умных людей.

  • Не все умны; попробуйте сами, посмотрите, что операция, похоже, работает для их ограниченного количества испытаний, и в заключение она будет работать большую часть времени.
    И они поздравляют свой собственный разум, говоря "большую часть времени", а не "всегда".
    И они расстраиваются, когда видят, что они не работают, хотя они были предупреждены.


Подробнее о процессе обновления мелкого клонирования см. "Как обновить Git мелкий клон?".

Ответ 2

Есть ли рабочий процесс git, который позволяет это?

Да, он отправляет исправления в виде патчей. git format-patch специально разработан для этого. Он назвал рабочий процесс "привратник", если вы хотите, чтобы Google больше деталей. Трудно поверить организации, связанной с "безопасностью и защитой IP", поскольку ваша компания уже не использует нечто подобное, когда один человек или небольшая группа отвечает за проверку "ненадежных" изменений до того, как они превратятся в реальную сборку.


Основываясь на вашем комментарии, я теперь лучше понимаю ваши требования. Я бы рекомендовал создать сиротский филиал (см. git checkout -orphan), от того, что вы хотите, чтобы ваши разработчики начали. Клонировать только эту ветку в другой репозиторий, доступный для этих разработчиков, и позволить им клонировать, нажимать и тянуть нормально из этого репо.

Затем, когда вам нужно реинтегрировать свои изменения в официальный защищенный репозиторий, просто потяните их ветку, сделайте копию ее с помощью git branch, чтобы вы не перезаписывали свою оригинальную сироту (в случае, если вы хотите повторить этот процесс позже), затем переустановите копию на свою исходную точку ветвления и слейте или как обычно. История будет выглядеть так, как будто они работали непосредственно из вашего защищенного репо.

Это немного сложнее, чем обычно, но цена за дополнительную изоляцию.