Сделать потерянную ветку из существующего репозитория?

У меня есть git-репозиторий, на котором я провел некоторое тестирование, и я хотел бы включить его в основной репозиторий.

Я хотел бы добавить это как потерянную ветку, потому что я хочу сохранить ее, но я не хочу раздувать основную ветку с моим тестовым проектом.

Как я могу импортировать git-репозиторий как осиротевший брах? Я хотел бы сохранить свои коммиты.

Отредактируйте, чтобы показать, что это не дубликат: на самом деле мне было все равно, что он будет осиротевшим или что-то в этом роде, я просто хотел объединить два хранилища. Данный ответ правильный и решает мою проблему.

1 ответ

Решение

Я думаю, что вы смотрите на это неправильно. На самом деле, существование этого вопроса подразумевает нечто неправдивое. Я думаю, что вы хотите, правильнее назвать "непересекающиеся подграфы".

Чтобы попасть туда, перенеси меня через это следующее упражнение. Если вы просто хотите получить ответ, прокрутите вниз.:-)

Упражнение: какая ветвь осиротела?

Представьте, что у вас есть хранилище, и в этом хранилище есть две ветви с именем X а также Y (нет master, просто X а также Y). Ветка X указывает на фиксацию a123456 и филиал Y указывает на фиксацию b987654, Эти коммиты, как обычно, указывают на их родителей, но если мы рисуем весь граф коммитов (репозиторий маленький, так что это хорошо вписывается в этот SO-ответ), мы получим:

o--o--o--o    <-- X

o--o--o---o   <-- Y
    \    /
     o--o

Есть два разных корневых коммита. Ветка X указывает на a123456 который является вершиной цепочки с четырьмя коммитами с корнем в a000000, Ветка Y указывает на b987654 который является коммитом кончика слияния структуры с шестью коммитами, основанной на b000000,

Какая ветвь (и), если есть, является сиротской ветвью?

(Это хорошее место, чтобы остановиться и подумать над этим вопросом.)


Если вы выбрали Xпочему вы выбрали именно этот? Если вы выбрали Yпочему вы выбрали именно этот? Если бы вы выбрали оба, я думаю, вы могли бы оправдать этот выбор; но если бы вы не ответили ни на что, я бы назвал это правильным и заметил, что вы теперь согласились с Git.

(Если вы выбрали оба X а также Yкакова ваша причина называть эти "сиротские ветви"? Я думаю, что вы могли бы поспорить за это как правильный ответ и обосновать это, сказав, что ни один из них не связан с master, Если мы тогда добавили ветку с именем master и сделал это указать на любой из четырех коммитов на X, тогда вы бы сказали, что филиал Y осиротевший и X не является. Если вы сделали master указать на любой из шести коммитов на Y, вы бы тогда сказали, что X это сирота и Y больше не осиротел. Вероятно, есть и другие способы решения, в зависимости от того, насколько вы хотите изменить то, как вы определяете "сирота". Но это не то, что означает Git, и на самом деле, есть лучшая терминология, которая не будет противоречить Git и будет служить вам лучше в долгосрочной перспективе.)

Несвязные подграфы

В нашем примере репозитория упражнений выше, ни X ни Y была сиротская ветвь, потому что у обоих есть коммиты на них. В теории графов - репозитории Git построены вокруг теории графов - двух ветвей имен X а также Y указывают на непересекающиеся подграфы общего графа.

Примечание: что Git подразумевает под ветвью сироты

В Git, сиротском филиале, созданном с git checkout --orphan newbranch, является отраслью в особом состоянии, "еще не родиться". Это состояние длится до тех пор, пока в ветви не будут зафиксированы коммиты, после чего ветка больше не будет "сиротской ветвью". Теперь это просто обычная ветка, как и любая другая.

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

Наконец, ответ на то, что я думаю, ваш вопрос на самом деле

Имея два несвязанных репозитория R1 и R2, вы хотите создать объединение репозитория (возможно, новое хранилище R3, возможно, просто изменив одно из двух исходных репозиториев), чей граф фиксации является непересекающимся графом, возникающим из объединения двух графов фиксации в R1 и R2

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

Чтобы построить новый репозиторий R3, сначала создайте пустой репозиторий:

$ mkdir r3 && cd r3 && git init

Теперь извлеките все из R1 в R3. Вы можете сделать это, добавив R1 в качестве именованного удаленного (это почти наверняка так, если вы добавляете R2 в R1, хотя тогда мы сейчас в R1 добавляем R2, а не в R3 добавляем R1). Вы могли бы просто бежать git fetch и дать ему URL-адрес и использовать информацию о ветвях, что он падает в FETCH_HEAD, но давайте пойдем с добавлением обоих как пультов. <url>тут могут быть пути (../../otherrepo.git или же /path/to/otherrepo.git), или же ssh://... или же git://... или же https://..., по-прежнему.

Затем извлеките все из R2 в R3. Мы используем точно такие же шаги, только другое удаленное имя и URL:

$ git remote add r1 <url for r1>
$ git remote add r2 <url for r2>
$ git fetch r1; git fetch r2

К этому моменту вы, по сути, готовы: у вас есть объединение в качестве графа коммитов в вашем новом хранилище. Осталось только сделать имена локальных веток, указывающие на те же коммиты, что и некоторые или все ветки удаленного отслеживания.

Так как мы назвали хранилище R1 r1все его филиалы находятся в refs/remotes/r1/branch-name, Аналогично, так как мы назвали R2 r2все его филиалы находятся в refs/remotes/r2/branch-name, Вы можете ссылаться на них по их сокращенным версиям, r1/whatever а также r2/whatever, Скажем r1 имеет филиалы master а также A а также r2 имеет филиалы master а также B,

Потому что есть только один A, ты можешь сделать:

$ git checkout A

и теперь у вас есть ветка с именем A указывая на тот же коммит r1/A, Кроме того, ваш местный A настроен на отслеживание r1/A: то есть его вверх по течению r1/A,

То же самое относится и к B,

Вы можете создать новый master в r3 но он может указывать только на тот же коммит, что и один из двух других репозиториев, и вы не можете использовать этот ярлык. Допустим, вы хотите r3"s master соответствовать r2/master:

$ git checkout -b master r2/master

создаст его и настроит для отслеживания r2/master,

Если вы не хотите этого вверх по течению --track настройки, создавайте ветки используя --no-track,

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

Другие вопросы по тегам