Смещение только поэтапных изменений в git - возможно ли это?

Есть ли способ, которым я могу зачеркнуть только мои поэтапные изменения? Сценарий, с которым у меня возникают проблемы, - это когда я работал над несколькими ошибками в определенный момент времени и имею несколько неустановленных изменений. Я хотел бы иметь возможность создавать эти файлы по отдельности, создавать мои файлы .patch и спрятать их до тех пор, пока код не будет одобрен. Таким образом, когда он будет одобрен, я могу скрыть всю мою текущую сессию, поп эту ошибку и нажать код.

Неужели я ошибаюсь? Я не понимаю, как git может работать другими способами, чтобы упростить мой процесс?

Ответ 1

Да, это возможно с помощью ДВОЙНОЙ ШТЕЙП, верят или нет,

  1. Подготовьте все свои файлы, которые вам нужно спрятать.
  2. Запустите git stash --keep-index. Эта команда создаст stash с ВСЕМИ вашими изменениями (поэтапно и не поэтапно), но оставит поэтапные изменения в вашем рабочем каталоге (все еще в состоянии стадии).
  3. Запустите git stash -m "good stash"
  4. Теперь ваш "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

Чтобы сделать то же самое...

  1. Поместите только те файлы, над которыми вы хотите работать.
  2. git commit -m 'temp'
  3. git add.
  4. git stash
  5. 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