Почему тайник представлен как 2 коммита?

При сохранении некоторых изменений Git создает два отдельных коммита: «WIP в ветке» и «индекс в ветке»:

$ git log --graph --all 

*   commit 98aac13303ca086580c1ec9ccba5fe26c2a8ef3c
|\  Merge: 7d99786 82c5c76
| | Author: Tieme <[email protected]>
| | Date:   Wed Nov 19 09:58:35 2014 +0100
| |
| |     WIP on development: 7d99786 Last real commit
| |
| * commit 82c5c763357c401135675a39bfabf9b7f6805815
|/  Author: Tieme <[email protected]>
|   Date:   Wed Nov 19 09:58:35 2014 +0100
|
|       index on development: 7d99786 Last real commit
|
|
| * commit 7d9978637a0e1ef92f2432189bdebf2317f0b2f0
| Author: Tieme <[email protected]>
| Date:   Tue Nov 18 17:32:33 2014 +0100
|
|     Last real commit
|

Я просмотрел документацию для этого, но это не проясняет:

Тайник представлен как коммит, дерево которого записывает состояние рабочего каталога, а его первый родитель — это коммит в HEAD при создании тайника. Дерево второго родителя записывает состояние индекса при создании тайника и становится дочерним элементом фиксации HEAD. Граф родословной выглядит следующим образом:

         .----W
        /    /
  -----H----I

где H — фиксация HEAD, I — фиксация, записывающая состояние индекса, а W — фиксация, записывающая состояние рабочего дерева.

Почему для файлов, которые я изменил, создается 2 коммита, а не только один?


person Tieme    schedule 19.11.2014    source источник
comment
Это может быть три коммита. См. stackoverflow.com/questions/20409853/git-stash-and-apply и stackoverflow.com/questions/20586009 /   -  person torek    schedule 19.11.2014
comment
Связанный: stackoverflow.com/questions/26021591/   -  person jub0bs    schedule 19.11.2014
comment
но это не делает его яснее Ну, это делает, но вы должны читать очень внимательно :-) На самом деле я пришел сюда, потому что у меня был тот же вопрос, и чтение этой цитаты прояснило его для меня.   -  person lmat - Reinstate Monica    schedule 20.04.2016


Ответы (1)


Краткий ответ

git stash различает изменения, которые есть в вашем индексе, и изменения, которые есть в рабочем дереве, и создает коммиты для них обоих.

Длинный ответ

Небольшая предыстория

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

Добавление в индекс только ограниченного числа файлов или с помощью git add --patch даже добавление одной измененной строки в файл приведет к тому, что ваш индекс будет находиться в другом состоянии, чем рабочее дерево.
Это хорошо, поскольку позволяет создавать коммиты, которые фокусируются на одной конкретной задаче/функции.

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

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

Что именно происходит?

Теперь утверждение с самого начала должно иметь больше смысла. Один «тайник» содержит все изменения, внесенные вами в ваше рабочее дерево (файлы, с которыми вы непосредственно работаете), а другой содержит изменения, которые вы добавили в свой индекс.

По умолчанию git stash pop или git stash apply пытается восстановить только изменения, внесенные в ваше рабочее дерево, и игнорирует изменения, внесенные в индекс. Можно указать git stash также попытаться восстановить ваш индекс, используя флаг --index (git stash (pop|apply) --index).

person Sascha Wolf    schedule 19.11.2014
comment
Да, это объясняет, спасибо! Флаг --index также удобен. - person Tieme; 19.11.2014