Смещение только поэтапных изменений в git - возможно ли это?
Есть ли способ, которым я могу зачеркнуть только мои поэтапные изменения? Сценарий, с которым у меня возникают проблемы, - это когда я работал над несколькими ошибками в определенный момент времени и имею несколько неустановленных изменений. Я хотел бы иметь возможность создавать эти файлы по отдельности, создавать мои файлы .patch и спрятать их до тех пор, пока код не будет одобрен. Таким образом, когда он будет одобрен, я могу скрыть всю мою текущую сессию, поп эту ошибку и нажать код.
Неужели я ошибаюсь? Я не понимаю, как git может работать другими способами, чтобы упростить мой процесс?
Ответы
Ответ 1
Да, это возможно с помощью ДВОЙНОЙ ШТЕЙП, верят или нет,
- Подготовьте все свои файлы, которые вам нужно спрятать.
- Запустите
git stash --keep-index
. Эта команда создаст stash с ВСЕМИ вашими изменениями (поэтапно и не поэтапно), но оставит поэтапные изменения в вашем рабочем каталоге (все еще в состоянии стадии).
- Запустите
git stash -m "good stash"
- Теперь ваш
"good stash"
имеет ТОЛЬКО подготовленные файлы.
Теперь, если вам нужны неподготовленные файлы перед копированием, просто примените первый stash (созданный с помощью --keep-index
), и теперь вы можете удалить файлы, которые вы спрятали в "good stash"
.
наслаждаться
Ответ 2
С последним git вы можете использовать --patch
git stash push --patch
И git попросит вас добавить каждое изменение в ваши файлы или нет в stash. Вы просто отвечаете y
или n
Ответ 3
Я создал script, который задерживает только то, что в настоящее время выполняется, и оставляет все остальное. Это потрясающе, когда я начинаю делать слишком много несвязанных изменений. Просто выполните то, что не связано с желаемым фиксацией и типом.
(Спасибо Бартломие за отправную точку)
#!/bin/bash
#Stash everything temporarily. Keep staged files, discard everything else after stashing.
git stash --keep-index
#Stash everything that remains (only the staged files should remain) This is the stash we want to keep, so give it a name.
git stash save "$1"
#Apply the original stash to get us back to where we started.
git stash apply [email protected]{1}
#Create a temporary patch to reverse the originally staged changes and apply it
git stash show -p | git apply -R
#Delete the temporary stash
git stash drop [email protected]{1}
Ответ 4
Почему вы не совершаете изменения для определенной ошибки и не создаете патч из этого коммита и своего предшественника?
# hackhackhack, fix two unrelated bugs
git add -p # add hunks of first bug
git commit -m 'fix bug #123' # create commit #1
git add -p # add hunks of second bug
git commit -m 'fix bug #321' # create commit #2
Затем, чтобы создать соответствующие патчи, используйте git format-patch
:
git format-patch HEAD^^
Это создаст два файла: 0001-fix-bug-123.patch
и 0002-fix-bug-321.patch
Или вы можете создавать отдельные ветки для каждой ошибки, поэтому вы можете объединять или переустанавливать исправления ошибок отдельно или даже удалять их, если они не работают.
Ответ 5
В этом сценарии я предпочитаю создавать новые ветки для каждой проблемы. Я использую префикс temp/, поэтому я знаю, что могу удалить эти ветки позже.
git checkout -b temp/bug1
Поместите файлы, которые исправляют ошибку 1, и зафиксируйте их.
git checkout -b temp/bug2
Затем вы можете выбрать коммиты из соответствующих веток по мере необходимости и отправить запрос на извлечение.
Ответ 6
Чтобы сделать то же самое...
- Поместите только те файлы, над которыми вы хотите работать.
-
git commit -m 'temp'
-
git add.
-
git stash
-
git reset HEAD~1
Boom. Файлы, которые вы не хотите, спрятаны. Все файлы, которые вы хотите, готовы для вас.
Ответ 7
Нужно ли сразу работать над несколькими ошибками? И "сразу", я имею в виду "одновременное редактирование файлов для нескольких ошибок". Потому что, если вам это абсолютно не нужно, я буду работать только с одной ошибкой за раз в вашей среде. Таким образом, вы можете использовать локальные ветки и rebase, которые я нахожу намного проще, чем управление сложным stash/stage.
Скажем, мастер находится на фиксации B. Теперь работаем над ошибкой # 1.
git checkout -b bug1
Теперь вы находитесь на ветке bug1. Внесите некоторые изменения, зафиксируйте, дождитесь проверки кода. Это локально, поэтому вы не влияете ни на кого другого, и должно быть достаточно легко сделать патч из git diffs.
A-B < master
\
C < bug1
Теперь вы работаете над bug2. Вернитесь к мастеру с помощью git checkout master
. Создайте новую ветвь, git checkout -b bug2
. Внесите изменения, зафиксируйте, дождитесь проверки кода.
D < bug2
/
A-B < master
\
C < bug1
Предположим, что кто-то еще совершает E и F на хозяине, пока вы ждете обзора.
D < bug2
/
A-B-E-F < master
\
C < bug1
Когда ваш код одобрен, вы можете переустановить его на мастер с помощью следующих шагов:
git checkout bug1
git rebase master
git checkout master
git merge bug1
Это приведет к следующему:
D < bug2
/
A-B-E-F-C' < master, bug1
Затем вы можете нажать, удалить локальную ветку bug1 и выйти. Одна ошибка за раз в вашей рабочей области, но с использованием локальных ветвей ваш репозиторий может обрабатывать несколько ошибок. И это позволяет избежать сложного танцевального/стафф-танца.
Отвечайте на вопрос ctote в комментариях:
Хорошо, вы можете вернуться к stashing для каждой ошибки и работать только с одной ошибкой за раз. По крайней мере, это избавит вас от промежуточной проблемы. Но, попробовав это, я лично считаю это неприятным. Штампы немного беспорядочны в графике журнала git. И что еще более важно, если вы что-то вникнете, вы не можете вернуться. Если у вас грязный рабочий каталог, и вы всплываете, вы не можете "отменить" этот поп. Гораздо труднее испортить уже существующие коммиты.
So git rebase -i
.
Когда вы переставляете одну ветку на другую, вы можете сделать это в интерактивном режиме (флаг -i). Когда вы это сделаете, у вас есть возможность выбрать, что вы хотите делать с каждой фиксацией. Pro git - это потрясающая книга, которая также находится в режиме онлайн в формате HTML, и имеет приятный раздел о перезагрузке и раздаче:
http://git-scm.com/book/ch6-4.html
Я украду их пример дословно для удобства. Предположите, что у вас есть следующая история фиксации, и вы хотите переустановить и вырезать bug1 на master:
F < bug2
/
A-B-G-H < master
\
C-D-E < bug1
Здесь, что вы увидите при вводе git rebase -i master bug1
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Чтобы выкопать все фиксации ветки вниз в одну фиксацию, сохраните первую фиксацию как "выбрать" и замените все последующие записи "pick" на "squash" или просто "s". Вы также получите возможность изменить сообщение фиксации.
pick f7f3f6d changed my name a bit
s 310154e updated README formatting and added blame
s a5f4a0d added cat-file
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
Так что да, раздавливание - это немного боль, но я бы по-прежнему рекомендовал его при сильном использовании приступов.
Ответ 8
git stash --keep-index
- хорошее решение... за исключением того, что оно не работало правильно на удаленных путях, которые были исправлены в Git 2.23 (Q3 2019)
См. коммит b932f6a (16 июля 2019 г.) автора Томаса Гаммерера (tgummerer
).
(Merged by Junio C Hamano -- [TG42] -- in commit f8aee85, 25 Jul 2019)
stash
: исправлена обработка удаленных файлов с помощью --keep-index
git stash push --keep-index
должен сохранять все изменения, которые имеют был добавлен в индекс, как в индексе, так и на диске.
В настоящее время это ведет себя неправильно при удалении файла из индекса.
Вместо сохранения его на диске ** - keep-index в настоящее время восстанавливает файл. **
Исправьте это поведение, используя "git checkout
" в режиме без наложения, который может верно восстановить индекс и рабочее дерево.
Это также упрощает код.
Обратите внимание, что это будет перезаписывать неотслеживаемые файлы, если неотслеживаемый файл имеет то же имя, что и файл, который был удален в индексе.
Ответ 9
Из ваших комментариев к Mike Monkiewicz ответ я предлагаю использовать более простую модель: используйте регулярные ветки развития, но используйте параметр squash для слияния, чтобы получить отдельную фиксацию в основной ветке:
git checkout -b bug1 # create the development branch
* hack hack hack * # do some work
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
git checkout master # go back to the master branch
git merge --squash bug1 # merge the work back
git commit # commit the merge (don't forget
# to change the default commit message)
git branch -D bug1 # remove the development branch
Преимущество этой процедуры заключается в том, что вы можете использовать обычный рабочий процесс git.
Ответ 10
Слишком сложно. Я скорее создаю ветку и совершаю поэтапные изменения там.
Примечание. Возврат к исходной ветке (при условии, что мы можем продолжить работу с не поставленными файлами) может быть сложным, если только файлы частично исполняются. (Мое решение состоит в том, чтобы зафиксировать их и вишневый выбор в корневой ветке.)
Ответ 11
Чтобы удалить случайное изменение, особенно удаление нескольких файлов, выполните следующие действия:
git add <stuff to keep> && git stash --keep-index && git stash drop
другими словами, спрятать дерьмо и выбросить его вместе с stashом.
Протестировано в git версии 2.17.1