У меня есть изменения в моей области подготовки, а другие еще не подготовлены (некоторые файлы имеют изменения как в области подготовки, так и за ее пределами). Я хочу инвертировать содержимое промежуточной области и изменения, которые не промежуточны. Существует ли для этого ярлык без выполнения более сложных действий, таких как локальные коммиты, сравнения или тайники [и т. д.]? Спасибо.
Git инвертирует промежуточную область
Ответы (4)
Вот как я это делаю:
- Зафиксировать индекс во временную фиксацию
- Зафиксируйте оставшуюся часть во вторичной временной фиксации
- Переключение порядка коммитов с помощью интерактивной перебазировки
- Смешанный сброс
- Мягкий сброс
Его можно напечатать вручную довольно быстро, особенно если вы используете Vim для сообщений фиксации:
git commit -m tmp1
git add . # optionally with `git add -u` if there are deletions
git commit -m tmp2
git rebase -i HEAD~2 # swap the order of the commits; `ddp:wq` in vi
git reset HEAD~1
git reset HEAD~1 --soft
Вероятно, есть несколько способов сделать это, но я думаю, что я бы выбрал этот подход — в настоящее время для этого нет заранее созданного ярлыка, но вы можете довольно легко написать свой собственный скрипт, чтобы следовать этому процессу:
Сгенерируйте патч для вещей, которые в данный момент находятся в вашем рабочем каталоге, но еще не в вашем индексе (вещи, для которых вы
git add
еще не сделали)git diff-files -p > /tmp/unstaged.patch
Создайте патч для того, что вы уже добавили в индекс, по сравнению с вашим текущим
HEAD
git diff-index --cached -p HEAD > /tmp/staged.patch
Сбросьте свой индекс и рабочий каталог на свой
HEAD
git reset --hard HEAD
Примените свой неустановленный патч как к вашему рабочему каталогу, так и к вашему индексу, в результате чего эти изменения будут поэтапными.
git apply --index /tmp/unstaged.patch
Примените поэтапный патч только к своему рабочему каталогу.
git apply /tmp/staged.patch
В зависимости от точного характера ваших изменений шаги 4 и/или 5 могут привести к некоторым конфликтам слияния, которые вам нужно разрешить вручную, но я не уверен, что есть чистый способ полностью избежать такой возможности.
Возможно, вы могли бы использовать git stash
для выполнения шагов 1 и 4 вместо приведенных выше команд, но я не уверен, что это действительно принесет вам пользу…
Кроме того, вы можете сначала просмотреть справочные страницы для команд git diff-*
и git apply
, чтобы узнать, есть ли другие параметры, которые могут иметь смысл для вас.
Основываясь на ответе gtd и возможности скрипта, инвертирующего коммиты, это то, что я сейчас использую:
[alias]
swaplast = !git tag _invert && git reset --hard HEAD~2 && git cherry-pick _invert _invert~1 && git tag -d _invert
invertindex = !git commit -m tmp1 && git add -A && git commit -m tmp2 && git swaplast && git reset HEAD~1 && git reset HEAD~1 --soft
Опубликовано в моем блоге здесь: http://blog.ericwoodruff.me/2013/12/inverting-git-index.html
swaplast
меняет местами последний и предпоследний коммит. Внимание: он отбрасывает незафиксированные изменения без предварительного уведомления. invertindex
меняет местами поэтапные и неустановленные изменения, включая неотслеживаемые файлы.
- person Melebius; 20.11.2014
git cherry-pick --abort
, прежде чем вы сможете снова запустить git invertindex
.
- person u01jmg3; 18.07.2016
--continue
) в случае конфликтов. Исходные псевдонимы просто прерываются и оставляют пользователя в затруднительном положении.
- person Ingo Karkat; 17.07.2019
Это то, что я использую для решения этой проблемы.
Сначала git reset
, который удалит все файлы из «промежуточных» в «файлы, не подготовленные для фиксации». Файлы, которые находятся как в «промежуточных», так и в «файлах, не подготовленных для фиксации», сохранят ваши самые последние изменения, которые в настоящее время находятся в ваших «файлах, не подготовленных для фиксации».
тогда
git add /path/to/file
конкретные файлы, которые нужно добавить в промежуточную версию
Не совсем короткий путь, но он выполняет свою работу
И наоборот, после того, как вы git reset
, вы можете git checkout /path/to/file
для файлов, которые в настоящее время «не подготовлены для фиксации», которые вы не хотите добавлять в подготовку. Это удалит определенные файлы из «не подготовленных к фиксации»
затем запустите git add .
, который добавит все файлы из «не подготовленных для фиксации» в «постановочные» - в зависимости от того, что проще для вашей ситуации.