2015-12-02 2 views
2

Почему git статус и git show не согласны?Почему git status и git show не согласны?

Репозиторий должен находиться в теге. Это то, что git status говорит мне (хеш-начало 609b).

Но мерзавец шоу говорит мне, что во время фиксации с хэш начиная 156f.

В текущей ситуации происходит следующее: чтобы получить кодовую базу в теге.

git clean -f && git reset HEAD --hard && git fetch && \ 
git fetch --tags && git checkout daily-build-492 && git pull 

Почему непоследовательность?

Некоторых диагностики:

$ git status 
HEAD detached from daily-build-492 
nothing to commit, working directory clean 
$ git rev-list -n 1 daily-build-492 
609b538fb0180b170170be09312fecf5a5240b6a 
$ git show 
commit 156f9e6b3fbfe7c16e8d821efd315428610043c2 
Merge: ec154d9 15e8876 
Author: ubuntu <ubuntu> 
Date: Wed Dec 2 14:09:23 2015 +0000 
    Merge branch 'deploy-server' 
$ git describe --tags --exact-match 
fatal: no tag exactly matches '156f9e6b3fbfe7c16e8d821efd315428610043c2' 
$ git log --tags --simplify-by-decoration --pretty="format:%ai %d" |grep 492 
2015-11-23 07:05:18 +0000 (tag: daily-build-492) 
+0

(daily-build-492 == a tag, right?) Вы отделены от HEAD, потому что вы git checkout '. Вы уверены, что не хотите проверять филиал? Если вы проверяете тег, это означает, что индекс git застрял в предыдущем месте, но локальные файлы выгружаются, в зависимости от того, какие файлы выглядят в теге. Другое предположение: если вы хотите стоять на определенном теге, вы должны иметь возможность (предупреждение: деструктивная команда) 'git fetch --all && git reset --hard '). – chelmertz

+0

@chelmertz Да, я хочу именно этот «замороженный» код из тега. (В этом примере работает ежедневная известная сборка на сервере, она не является средой разработчиков.) Но, несмотря на это, интересный вопрос заключается в том, почему разные команды git не согласны. –

+0

@torek @hoppa @chelmertz Я попытался сделать это без git pull. Различная диагностика, которую я упоминаю в ИС, является последовательной. Затем я вручную «git pull» просто посмотрел, что произойдет. Я получаю «Уже обновленный». И тогда диагностика остается неизменной. Таким образом, неясно, что «git pull» «испортил» ситуацию. Вопрос остается открытым. –

ответ

3

Есть два ключа к этому и hoppa has provided both, но позвольте мне посмотреть, могу ли я его немного сократить. (Это сложная задача для меня, так как я склонен писать очень длинные ответы. :-)) В любом случае я постараюсь прикрепить несколько вещей.

Во-первых, позвольте мне добавить, что git pull просто удобство скрипт, который первым запускает git fetch для вас, тогда в зависимости от конфигурации и дополнительные флаги спусков либо git merge или git rebase. (По умолчанию это делается для слияния, что для многих пользователей, как правило, неверно.)

(В вашем вопросе также отсутствует информация. Использование git pull само по себе должно было привести к ошибке. Однако, если вы использовали git pull origin master или аналогичный, вы должны были увидеть некоторый дополнительный вывод из git pull, когда он сделал свой второй шаг. В любом случае мы можем видеть, что ваше окончательное состояние состоит в том, что HEAD указывает на фиксацию слияния, хотя ни один из его родителей не является фиксацией что ваш тег идентифицирует.)

Когда вы указываете его тег, git checkout ставит вас в состояние «отдельно стоящий ГОЛОВА». Это звучит немного страшно, как какая-то французская революция 18-го века, но на самом деле просто означает, что вы больше не в какой-либо отрасли. Git отлично работает в этом состоянии: вы можете совершать новые коммиты, включая слияния; они просто на нет филиалов. Единственный способ их найти - это сырой SHA-1, такой как 156f9e6b3fbfe7c16e8d821efd315428610043c2, или некоторым относительным именем, начиная с HEAD, например HEAD, HEAD~1, HEAD~2 и так далее.

Получив в «отдельностоящий HEAD» состояние, проверяя тег, то вы сделали по крайней мере, еще совершить один (на самом деле, по крайней мере, еще два на основе git show продукции). Эти новые коммиты, как всегда, с отдельной головкой, вообще не имеют ветви. Последний был слиянием, предположительно с git merge второй половины git pull.

Теперь git status показывает вам, где ваша голова: отдельно, не в тег, но из тега. Это означает, что вы были правы на ярлыке (в отдельном состоянии HEAD) раньше. Если бы вы запустить git status прямо тогда, вы бы видели это:

$ git status 
HEAD detached at daily-build-492 

Сделав несколько новых фиксации (s) вы пошли в «сцепки с» вместо «отторгнуты в».

С другой стороны, команда git show, так как hoppa already noted, показывает объект. Объект по умолчанию, который будет отображаться, если вы его не называете, - это любой объект HEAD.В этом случае HEAD называет коммит слиянием, поэтому отображает его идентификатор, идентификаторы его родителей (Merge: ec154d9 15e8876), автора и дату, сообщение фиксации (которое выглядит как git pull, поставляет на его этап git merge) и комбинированный diff (пустой в этом случае).

Любопытно, что ни один из родителей не соответствует явному идентификатору помеченного фиксации, 609b538fb0180b170170be09312fecf5a5240b6a. (Я говорю «очевидный» здесь, потому что вы использовали git rev-list -n 1, а не git rev-parse daily-build-492^{commit}, и, возможно, маловероятно, что после сортировки коммитов, которые будут перечислены, те, на которые указывает фактический тег, находятся дальше в выводе rev-list.) И, как я уже отмечал ранее, git pull без дополнительных аргументов должен просто дать вам сообщение об ошибке.

(я думаю, что я потерпел неудачу в «короткий» :-), но, возможно, по крайней мере, это помогает выяснить, как вы попали в это состояние.)


Или действительно любой совершить идентификатор, а не краткое название ветки. Например, git checkout refs/heads/master получает то же самое совершает как git checkout master, но оставляет вас в состоянии «отдельно стоящего HEAD». (Если это то, что вы хотите, вы можете также использовать git checkout --detach master, который я считаю более очевидным.)

Если вы git checkout что-то еще, так что HEAD теперь ссылается на какой-либо другой фиксации, вы остались только raw SHA-1, или же с некоторыми модификаторами. Например, 156f9e6~1 относится к первому родителю фиксации 156f9e6, а 156f9e6~2 относится к первому родительскому объекту и т. Д.

+0

Благодарим вас за подробный ответ. Когда я пытаюсь сломать эту длинную строку и «git pull» отдельно от остальных, я получаю сообщение «Вы сейчас не находитесь в ветке. Укажите, с какой веткой вы хотите объединиться. Подробнее см. Git-pull (1). git pull '. Таким образом, это, вероятно, происходит тихо, как эта длинная строка выполнена. Я уверен, что не редактировал код или не делал 'git commit'. Это сервер, а не среда dev. Таким образом, возможно, «git pull» виноват в том, что он «испортил» среду чистых тегов. Но git pull, ничего не делает, как упоминалось, поэтому непонятно, почему. –

+0

Как вы говорите, несколько любопытная вещь все еще несоответствие. Я полагаю, что это все еще остается без ответа. –

+0

Пожалуйста, смотрите мой комментарий под OP. –

4

Я думаю, что вы путаете две проблем сразу. Прежде всего, это факт, что вы находитесь в состоянии ОДН. Daily-build-492 - это тег, и вы не можете вносить изменения в тег. Если вы проверить тег, находясь в мастера (например) мерзавца будет первым дать вам такое сообщение:

You are in 'detached HEAD' state. You can look around, make experimental 
changes and commit them, and you can discard any commits you make in this 
state without impacting any branches by performing another checkout. 

If you want to create a new branch to retain commits you create, you may 
do so (now or later) by using -b with the checkout command again. Example: 

    git checkout -b new_branch_name 

Это в основном то, что вы, вероятно, сделал, когда выполняется git checkout daily-build-492. Если вы мерзавец статус теперь вы получите сообщение, которое по этим линиям:

$ git status 
HEAD detached at daily-build-492 

После этого вы каскадный (с & &) командой тягового который получает изменения в с пульта дистанционного управления, который связан. Я думаю, что, так как это бы добавить изменения в тег и так, что не разрешено, вы автоматически отсоединяются от ежедневного сборки-492 в дальнейшем подвешенном :) Уведомление будет теперь:

$ git status 
HEAD detached from daily-build-492 
nothing to commit, working directory clean 

Как вы можете см. это именно то, что ваш git статус на самом деле говорит вам после ваших первоначальных команд.

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

Git показать

мерзавец шоу делает что-то другое. Git show отображает информацию об объекте. Объектом в git может быть много вещей; фиксация, тег, дерево и т. д. Если вы не дадите git show, поведение хэша объекта, похоже, должно показать git последнее коммит. Это фиксация, которую вы вытащили после проверки тега. Один из коммитов, который привел вас в отдельный режим HEAD для начала.

Простое воспроизводство вашего вопроса

git init test.git 
cd test.git 
touch A 
git add A 
git commit -m "A, jay" 
touch B 
git add B 
git commit -m "B, jay" 
git tag TAG-1 
git checkout TAG-1 //Now you will get the notice about git detached HEAD etc 
git status // result below 
//HEAD detached at TAG-1 
//nothing to commit, working directory clean 
touch C 
git add C 
git commit -m "C, shoopdawhoop" // a warning like below is outputted,but it works 
//[detached HEAD eda8080] C 
// 1 file changed, 0 insertions(+), 0 deletions(-) 
// create mode 100644 C 
git status // output below again 
// HEAD detached from TAG-1 
// nothing to commit, working directory clean 
git show // will now tell us about commit C the last one we added. 
// commit eda808088594ae7b05ae1b57ffd95f7f810a9091 
// Author: [email protected] <[email protected]> 

Этот небольшой набор команд в основном имитирует то, что я думаю, что вы сделали.Может быть, & & конкатенация команд с отключенным выходом, возможно, это не так, но вы не публиковали. Мораль этой истории заключается в том, что вы пытались сделать то, что git не позволяет.

Как вы можете видеть в примере, это объясняет, почему ваш git describe --tags не привести ни к чему, так как вы даете ему хэш фиксации C (не очень, но она аналогична фиксации C в моем примере.)

Ваш git rev-list действительно дает вам то, что вы ожидаете, так как вы специально задаете ему последний коммит в daily-build-492.

+0

Спасибо, @hoppa за ответ и реконструкцию. Однако я не редактировал код в этом репозитории или вообще не совершал, так как он был в теге. Это на сервере, а не на ветке dev. Что касается '&& git pull' после проверки тега, вы упомянули, что« Мое предположение заключается в том, что, поскольку это добавит изменения в тег, и поскольку это не разрешено, вы автоматически отсоединяетесь от daily-build-492 в дальнейшая неопределенность ". Но кажется, что 'git pull' даже не работает, когда вы делаете это на теге, так что все еще не объясняет несоответствие между' git show' и 'git status', как в примере, который я дал. –

+0

Если я делаю «git pull» после проверки ветки, я получаю: 'Вы не в настоящее время находитесь на ветке. Укажите, с какими филиалом вы хотите объединиться. Подробнее см. Git-pull (1). git pull ' Так что это не то, что вызвало несоответствие. –

+0

Пожалуйста, смотрите мой комментарий под OP. –

Смежные вопросы