Как я могу ввести промежуточную ветку? - PullRequest
0 голосов
/ 11 января 2019

После изменения основной ветки моего репозитория, которую я клонировал из общедоступного репозитория, я создал несколько ветвей функций, происходящих из моей модифицированной основной ветки.

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

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

В то же время я хочу сохранить ветки своих функций, которые я уже отправил в удаленный репозиторий. (Я уже выдвинул свою модифицированную главную ветку тоже.)

Какие шаги необходимы для достижения этой цели?

enter image description here

1 Ответ

0 голосов
/ 11 января 2019

Нет необходимости делать что-либо вообще, но если вы хотите что-то сделать, я бы порекомендовал что-то другое.

Фон

В Git ответвления names имеют очень небольшое значение для самого Git. Что имеет значение совершает . (Имена значимы для людей , конечно.)

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

Вы начали с клона с некоторой серией коммитов, заканчивая коммитом, который мы назовем H вместо использования его фактического хэша:

...--F--G--H   <-- master (HEAD), origin/master

Затем вы добавили несколько новых коммитов на свой master. Каждый из них получил новый большой уродливый хэш-идентификатор, который мы заменим следующей буквой:

...--F--G--H   <-- origin/master
            \
             I   <-- master (HEAD)

Создание нового коммита говорит Git: переместите текущую ветку , т. Е. Ту, к которой прикреплен HEAD, чтобы указать на этот новый коммит, который указывает на его предыдущий коммит. Так что теперь master имена фиксируют I, а не фиксируют H. Коммит I запоминает хэш для H, хотя. Если вы сделали еще два коммита, картина стала:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master (HEAD)

Именно в этот момент вы создали свои ветви объектов - поэтому давайте нарисуем это:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master (HEAD), feature1, feature2

Затем вы выбрали одну из тех ветвей feature, для которых нужно создавать новые коммиты, прикрепив к ней HEAD. Давайте выберем feature1:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master, feature1 (HEAD), feature2

Далее вы создали коммит или два:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master, feature2
                    \
                     L--M   <-- feature1 (HEAD)

Возможно, затем вы выбрали feature2 в качестве текущей ветви (через git checkout feature2) и создали еще один коммит:

...--F--G--H   <-- origin/master
            \
             I--J--K   <-- master
                   |\
                   | L--M   <-- feature1
                   |
                    `--N   <-- feature2 (HEAD)

То, что вы просите сейчас сделать по любой необъяснимой причине, - это заставить вас master снова подтвердить H. Вы можете сделать это без каких-либо последствий для вашего собственного хранилища, сказав Git: Move master, чтобы он указывал на коммит H. Эффект:

...--F--G--H   <-- master, origin/master
            \
             I--J--K
                   |\
                   | L--M   <-- feature1
                   |
                    `--N   <-- feature2

Коммиты I до K теперь можно найти по:

  • начиная с конца feature1 и работая в обратном направлении: M, L, K, J, I, H, ...
  • начиная с конца feature2 и обратно: N, K, J, I, H, ...

Если вы хотите запомнить, как отличительное имя, идентификатор хеша коммита K, чтобы вы могли запускать новые функции оттуда, вам нужно только создать new имя, указывающее на коммит K. Это новое имя может быть именем ветви или именем тега , в зависимости от того, что вы предпочитаете.

Ваша цель

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

Коммит, на который изначально указывал ваш master, все еще находится в вашем хранилище. Это коммит H. Конечно, реальные хеш-идентификаторы коммитов большие и некрасивые - на самом деле это не H, это какая-то запоминающаяся длинная строка шестнадцатеричных цифр, которую невозможно запомнить. К сожалению:

В то же время я хочу сохранить свои ветви функций, которые я уже отправил в удаленный репозиторий. (Я уже выдвинул свою модифицированную главную ветку тоже.)

Когда вы запустили git push origin master, вы сказали своему Git отправлять коммиты K и более ранние, если и когда необходимо, в origin - другое хранилище Git - и затем попросить Git, управляющего origin, установить его мастер указывает на K. Когда он принял этот запрос, ваш Git обновил свой собственный origin/master, чтобы запомнить хэш-идентификатор K вместо запоминания хэш-идентификатора H. Итак, на данный момент у вас есть что-то вроде этого:

...--F--G--H
            \
             I--J--K   <-- master, origin/master
                   |\
                   | L--M   <-- feature1
                   |
                    `--N   <-- feature2

Есливы точно помните , сколько совершает обратный отсчет от K, вы можете найти H таким образом. Но если вы сделали все это недавно - в течение последних трех месяцев, - тогда ваш собственный Git все еще помнит, куда origin/master обычно указывал, три месяца или меньше назад . Так что вы можете просто запустить:

git reflog origin/master

чтобы увидеть, какие коммиты origin/master использовались для идентификации с течением времени. Добавьте --date=relative, чтобы получить информацию о дате, и вы можете найти записи журналов, которые хранятся намного дольше, чем всего за три месяца. Git может быть довольно небрежным в отношении их очистки, и 90-дневный срок действия - это просто предел: когда Git энергично очищает старые reflogs, он выбрасывает вещи старше 90 дней (по умолчанию или 30 дней для некоторых менее полезные случаи, которые здесь не применимы).

$ git reflog --date=relative origin/master
3c31a20 (HEAD -> master, origin/master) refs/remotes/origin/master@{51 minutes ago}: update by push
cf68824 refs/remotes/origin/master@{3 months ago}: update by push
...
ce4f7f9 refs/remotes/origin/master@{1 year, 2 months ago}: update by push

Чтобы найти H в вашем хранилище, попробуйте команду git reflog.

Найдя H, вы можете просто прикрепить к нему новое имя:

git branch aha <hash-ID>

, который будет производить:

...--F--G--H   <-- aha
            \
             I--J--K   <-- master, origin/master
                   |\
                   | L--M   <-- feature1
                   |
                    `--N   <-- feature2

Теперь вы можете поменять aha и master, если хотите, или делать что-нибудь еще, с этими различными именами ветвей. Просто помните, что если кто-то еще использует клоны вашего хранилища или вашего хранилища origin, то эти другие люди могут ожидать, что имена ветвей получат только new совершает. Если вы переместите название ветви «назад» (к более старому коммиту), другие люди могут запутаться этим и попытаться настаивать на том, чтобы вы снова переместили имя вперед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...