Ответ 1
Хорошо, из комментариев, то, что нужно, - это прикрытие всех изменений, которые еще не были добавлены (исключено во время git add -p
или просто еще не добавлено).
Причина этого заключается в том, чтобы применить некоторые тесты/потенциальные хитрости к поэтапному состоянию, прежде чем совершать его.
Это прямая git stash -k
, все как обычно, задержите индексированное состояние и соответствующую рабочую строку, т.е. Очистите от worktree все, что я не собираюсь совершать.
Так:
git stash -k
git clang-format
git commit
и в хранилище теперь есть четыре интересных моментальных снимка: исходное содержимое aka stash base, индекс моментальных снимков, снимок рабочей строки и текущий индекс (, commit и worktree), который является снимком индекса при 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 в состояние с сохранением с изменениями от базы stash (которая обычно удивительно похожа на текущую базу) на текущее состояние. Вы хотите, чтобы спрятанная рабочая нагрузка изменилась в вашей рабочей группе, но только те, которые вы еще не добавили, поскольку те, что вы добавили, все еще здесь, теперь они немного отличаются.
Таким образом, вишня -p ick - -n
, no commit, -m2
, mainline для изменений - ее второй родитель, то есть все различия, которые вы сделали, но не добавленные при сшивании.
Пример может помочь,
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
'd изменение 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
.
Изменения, которые вы хотите вернуть, - это разница между вашим спрятанным индексом и вашей спрятанной рабочей линией, что кошелек фиксирует различия со вторым родителем. Следовательно, это вишня -p ick.
Альтернативные способы написания вишни -p включают
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
чтобы делать то, что вы хотите.
отредактируйте: как дополнительный fillip, предположите, что вы пошли дальше и сделали еще какую-то работу, прежде чем вспоминать ваши сдержанные изменения в worktree, вишня -p ick будет правильно обновлять рабочую строку и индекс, но сброс будет отменять любые изменения, которые вы уже добавили в новый индекс. Теперь вы находитесь на основной территории,
( index='git write-tree' &&
git cherry-pick -nm2 stash &&
git read-tree $index &&
git stash drop
)
как я реализую это по-настоящему.