Здесь вам нужно знать, что «структурная ветвь» (сейчас я экспериментирую с этим термином) формируется графом фиксации, а метка git-ветви просто «вставляется» в фиксацию. (или «указывает» на один коммит, если вы предпочитаете эту терминологию).
Похоже, у вас сейчас есть что-то вроде этого:
...--o--o--A--B--C--D--E <-- master
где с A
по E
— пять коммитов, которые представляют собой эту новую экспериментальную функцию, а более ранние o
— другие коммиты. (Обратите внимание, что «время движется вперед» слева направо, т. е. последняя фиксация o
произошла до A
, а A
— до B
и так далее.)
Нарисуем вышеизложенное с изломом на линии, который ее никак не меняет, но освобождает место на рисунке для того, чтобы наклеить на нее вторую метку. Затем наклеим на него вторую этикетку.
...--o--o <-- new-label
\
A--B--C--D--E <-- master
Посмотрите, как, если бы мы могли просто поменять местами эти две метки, мы бы получили именно то, что вы просили: master
указывало бы на последнюю фиксацию непосредственно перед A
, а new-label
указывало бы на фиксацию E
, которая затем "ответвлялась бы от master
".
Мы можем сделать именно это. Есть только одно предостережение: если кто-то еще использует этот репозиторий, либо напрямую, либо (чаще) с помощью операций push
и pull
, другие люди ожидают только, что метки веток будут "двигаться вперед": иметь новые коммиты добавляются с течением времени, а не коммиты, которые "забираются" из-за возвращения "в прошлое".
Если они подобрали ваши новые коммиты (с A
по E
) и действие "переместить метку ветки master
вперед" с последнего коммита o
на E
, а затем вы решили "переместить метка задом наперед", вы должны как-то сказать им: "Эй, ребята, извините, но я должен был вовремя переместить метку назад". Затем им, возможно, придется предпринять дополнительные действия самостоятельно, чтобы оправиться от этого.
Если ни у кого еще нет коммитов, вы в отличной форме. Если у кого-то они могут быть, но они ими не пользуются, или они согласны предпринимать действия, чтобы оправиться от «движения назад», то вы все еще в хорошей форме.
Вот один из кратчайших способов добиться трюка с метками (есть еще несколько не менее коротких способов):
Добавьте новую метку, указывающую на коммит E
:
git checkout master # if you're not already "on branch master"
git checkout -b ExpA
(преимущество этого метода заключается в том, что он оставляет вас «на ветке ExpA
», что, как я полагаю, вам бы хотелось).
Теперь, когда у E
есть вторая метка, принудительно переместите master
назад на пять коммитов:
git branch -f master master~5
(master~5
означает «переместиться на 5 коммитов назад от того места, где сейчас находится master
; вы можете использовать любой другой метод, чтобы назвать желаемый коммит, который является последним узлом o
на рисунках выше; master@{date}
, как в вашем собственном ответе, может помочь, например ).
Только если вы уже push
ed совершаете коммиты с A
по E
в какой-то центральный репозиторий (здесь, я полагаю, он называется origin
) в ветке master
. Обратите внимание, что этот шаг, по крайней мере, немного опасен (иногда более чем слегка, если другие запихнули туда больше коммитов на master
) и не должен выполняться до тех пор, пока все остальные не узнают об этом и не согласятся с этим (и если вы не знаете то, что вы здесь делаете, пусть вместо этого это сделает кто-то другой — тот, кто отвечает за центральное хранилище origin
):
git push -f origin master
Если у других есть ваши коммиты, а вам не разрешено "вернуться в прошлое" с помощью меток, вам нужно вместо этого "откатить" материал; см. другие обсуждения StackOverflow по этому поводу.
person
torek
schedule
24.01.2014
git checkout A
и запустите тест; затем выполнитеgit checkout B
и запустите свой тест и т. д. — Вы можете проверить любой коммит в отдельном HEAD, чтобы запустить свои тесты на версии этого коммита. - person poke   schedule 24.01.2014git bisect master A~
. - person Greg Bacon   schedule 24.01.2014