Нет необходимости делать что-либо вообще, но если вы хотите что-то сделать, я бы порекомендовал что-то другое.
Фон
В 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 совершает. Если вы переместите название ветви «назад» (к более старому коммиту), другие люди могут запутаться этим и попытаться настаивать на том, чтобы вы снова переместили имя вперед.