Ладно, из комментариев нам нужен тайник всех изменений, которые еще не были добавлены (независимо от того, были ли они исключены во время git add -p
или просто еще не добавлены).
Причина этого заключается в том, чтобы применить некоторые тесты / потенциальные настройки к промежуточному состоянию до его фиксации.
Это просто git stash -k
, спрятать все как обычно, но сохранить индексируемое состояние и соответствующее рабочее дерево, то есть очистить от рабочего дерева все, что я не собираюсь фиксировать.
Итак:
git stash -k
git clang-format
git commit
и в репозитории теперь есть четыре интересных снимка: исходное содержимое, также называемое базой хранения, индекс моментального снимка, рабочее дерево моментального снимка и текущий индекс (, коммит и рабочее дерево), который является моментальным снимком индекса в stash^2
с чистками применяется. Обратите внимание, что все три из новых снимков, также известные как коммиты, имеют в качестве родительской базы тайник.
Теперь вы хотите, чтобы ваше рабочее дерево изменилось обратно, но очевидно, что изменения от базового к сохраненному индексу и рабочему дереву не совпадают с изменениями в текущем индексе и рабочем дереве (и новом коммите, все они совпадают), поэтому, когда git переходит к выдвиньте тайник, в котором будут обнаружены конфликты: изменения из сохраненной базы в сохраненный индекс не соответствуют изменениям из базовой базы в текущий индекс.
Если бы Git предложил то, что вы хотите напрямую, «спрятать все изменения рабочего дерева , за исключением изменений в индексе», вы могли бы использовать это, и тогда у всплывающего окна не было бы никаких проблем, прямо git stash pop
сделает это. К счастью, если Git хорош во всем, он объединяет, объединяет, разделяет и объединяет все различия.
git cherry-pick -nm2 stash
# cherry-pick updated the index, too. maybe git reset here to unstage that stuff.
git stash drop
Stash pop - это слияние изменений из базы stash в состояние stashed с изменениями из базы stash (которая обычно очень похожа на текущую базу) в текущее состояние. Вы хотите, чтобы спрятанное рабочее дерево изменилось в вашем рабочем дереве, но только те, которые вы еще не добавили, поскольку те, к которым вы добавили , добавили , все еще здесь, они просто немного изменились.
Таким образом, вишневый пик - -n
, без фиксации, -m2
, основной строкой изменений является его второй родительский элемент, т. Е. Все различия, которые вы внесли, но не добавили при копировании.
Пример может помочь,
cd `mktemp -d`
git init
printf >file %s\\n 1 2 3 4 5
git add .;git commit -m1
printf >file %s\\n 1 2a 3 4 5
git add .
printf >file %s\\n 1 2a 3 4a 5
теперь вы фактически git add -p
изменили 2a, а изменение 4a только в вашем рабочем дереве.
$ git stash -k
$ cat file
1
2a
3
4
5
$ sed -i '2s,^,_,' file # indent the 2a line
$ git commit -am2
Теперь начальный коммит :/1
равен 1 2 3 4 5
, ваш текущий коммит, индекс и рабочее дерево все 1 _2a 3 4 5
, ваш спрятанный индекс 1 2a 3 4 5
и ваш спрятанный рабочий дерев 1 2a 3 4a 5
.
Изменения, которые вы хотите вернуть, - это разница между вашим сохраненным индексом и вашим скрытым рабочим деревом, это отличие фиксации stash от его второго родителя. Отсюда и эта вишня.
Альтернативные способы написания вишни включают
git cherry-pick -nm1 -Xours stash
, который применяет все спрятанные изменения рабочего дерева, но принимает локальную версию в случае конфликта (в основном это поиск и выбрасывание конфликтующих различий вместо того, чтобы просто избегать их, как -m2
делает) и
git diff stash^2..stash|git apply -3
Облегчить все это для себя - это территория скриптинга, самый простой способ поговорить о настройке - это как псевдоним git,
git config --global alias.poptree '!git cherry-pick -nm2 stash; git reset; git stash pop'
и теперь у вас есть команда git poptree
, чтобы делать то, что вы хотите.
edit: предположим, что вы продвинулись вперед и проделали еще некоторую работу, прежде чем запоминать изменения в своем спрятанном рабочем дереве, cherry-pick будет корректно обновлять рабочее дерево и индекс, но при сбросе будут отменены все изменения, которые вы уже добавили. к новому индексу. Теперь вы находитесь на территории основного командования,
( index=`git write-tree` &&
git cherry-pick -nm2 stash &&
git read-tree $index &&
git stash drop
)
это то, как я бы реализовал это по-настоящему.