Проверка старого фиксации и поддержание головы на главной ветке?

В настоящее время для перехода на другой git commit (на той же ветке... на самом деле, на главной ветке!), я выполняю команду

git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

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

Ответ 1

В большинстве случаев, когда я делаю это, я проверяю временную ветку:

git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Затем, после того как я закончил, я просто удалю ветку

Ответ 2

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

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

git checkout -b newbranch ea3d5ed

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

Пусть начинается с 3 коммитов на master, A, B и C. master является текущей ветвью, поэтому HEAD указывает на master, что указывает на фиксацию C.

A  B  C
*--*--* <-- master <-- HEAD

Теперь, если мы зафиксируем, git создаст коммит, который имеет C как родительский (поскольку это текущая фиксация, указанная с HEAD через master), и обновит master, чтобы указать на это новый фиксация. Все наши фиксации теперь находятся в master, а HEAD указывает на новый фиксацию через master.

A  B  C  D
*--*--*--* <-- master <-- HEAD

Теперь позвольте проверить B, предоставив нам отдельный HEAD.

A  B  C  D
*--*--*--* <-- master
   ^
    \-- HEAD

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

A  B  C  D
*--*--*--* <-- master
    \
     * <-- HEAD
     E

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

A  B  C  D
*--*--*--* <-- master <-- HEAD
    \
     *
     E

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

Итак, вместо того, чтобы проверять голую ревизию и получать отдельную голову, если вы чувствуете, что собираетесь делать больше коммитов, вы должны использовать git checkout -b branch B, чтобы создать ветку и проверить ее. Теперь ваши коммиты не будут потеряны, так как они будут включены в ветку, к которой вы можете легко обратиться, и затем слить.

A  B  C  D
*--*--*--* <-- master
   ^
    \-- branch <-- HEAD

Если вы забудете сделать это и создайте фиксацию с ветки, нет необходимости беспокоиться. Вы можете создать ветвь, относящуюся к редакции главы, с помощью git checkout -b branch. Если вы уже вернулись к ветке master и понимаете, что вы забыли неудачную фиксацию, вы можете найти ее с помощью git reflog, который покажет вам историю того, что зафиксировал HEAD за последние несколько дней. Все, что еще в reflog не будет собираться мусором, и, как правило, ссылки хранятся в reflog не менее 30 дней.

Ответ 3

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

git co <previous-commit-id>

после этой команды вы будете на ветке с именем "(без ветки)".

Подтвердите это с помощью

git br

После того, как вы сыграли с этим ранее совершенным кодом, вы можете переключиться на ветку, на которой вы были на

git co <the-branch-you-were-on>

"(без ветвления)" будет автоматически удалено. Таким образом, вам не нужно создавать временную ветвь.

Ответ 4

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

Вот краткое объяснение. Многословность ниже, мы надеемся, поможет понять, как HEAD и master различны:

Обычно все выглядит так:

C ← refs/heads/master ← HEAD 
↓
B
↓
A

То есть: "Родитель C - это B, а родительский элемент B - A. Мастер ветки указывает на C, и я в настоящее время проверил содержимое мастера. Кроме того, когда я совершаю, мастер обновляется".

Некоторые предположения являются неявными в этом, которые необходимы для глубокого понимания графа фиксации. А именно, фиксации относятся только к их родителям, а содержимое ветки - это те коммиты (и только те коммиты), которые могут быть достигнуты, следуя родительским ссылкам. (Немодифицированное) содержимое рабочего дерева и индекс должны соответствовать фиксации, названной HEAD, либо косвенно ( "символическая" ), либо непосредственно ( "отсоединенная" ).

Таким образом, если вы хотите проверить старый фиксатор, HEAD должен быть обновлен, чтобы указать на требуемую фиксацию. git-checkout делает только это:

C ← refs/heads/master 
↓
B ← HEAD
↓
A

Теперь ты оставил свой филиал позади тебя, так как ты смотришь на что-то старое. Совершенно нормально, так как совет "отдельно взятой головы" расскажет вам спокойно (внимание мое):

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

С другой стороны, при перезагрузке вашего ветки также появляется HEAD, где он должен быть, это будет иметь совершенно другой эффект!

C
↓
B ← refs/heads/master ← HEAD
↓
A

Конец C станет мусором, поскольку вы заявили, что не хотите, чтобы он был частью основной ветки.

Короче говоря, все, что вам нужно сделать, это понять, что означает git под "HEAD" - его, где вы находитесь, а не где какая-либо данная ветка. И если вы находитесь не так, как там, где есть ветка, нет выбора, кроме как использовать отдельную головку.

(Возможно, загляните в GitHub, gitk или gitweb, чтобы просмотреть историю фиксации, если свернуть с вашего ума, HEAD продолжает раздражать вас.)

Ответ 5

Вопрос немного расплывчатый, но если вы хотите просто изменить файлы в рабочем дереве, вы можете просто сделать это:

git checkout [commit|branch] -- .

Затем вы можете выполнить изменения и создать новую фиксацию, если хотите. Иногда это довольно полезно.

Ответ 6

Думаю, я понимаю ваши вопросы. Вот что я нашел для его решения. и нет никакого GUI-решения, вы можете использовать команду только для ее решения, и это очень просто.

Шаг 1: создайте тег старого коммита, который вы хотите вернуться.

как тег v2.0

Шаг 2: git checkout v2.0

вот он, теперь ваш HEAD указывает на 'v2.0' commit, но мастер все еще указывает на последнюю фиксацию.

C:\Program Files\Git\doc\git\html\git-checkout.html Этот документ может помочь вам

или введите git help < выезд >