Пропустить прошедшую (полную) область подготовки и зафиксировать файл или патч напрямую? - PullRequest
0 голосов
/ 23 января 2019

Представьте себе такой сценарий: вы работаете над функцией, которая требует касания большого количества файлов, и у вас есть много вещей, поставленных и много вещей, которые не поставлены (например, отладочный код, временные комментарии, которые вы должны запомнить сами) делать / отменять определенные вещи и не забывать добавлять биты, которые вы еще не успели добавить), и тогда вы увидите простое однострочное изменение, которое вы должны внести, но которое принадлежит его собственному коммиту.

Есть ли способ просто совершить это, не вытаскивая все из области подготовки, которую вы тщательно добавили, не пряча (и рискуя потерять тщательный выбор того, что ставить, а что нет) и просто передайте эту одну строку ?

Я понимаю, что возиться с несколькими областями подготовки , вероятно, сделало бы это возможным, но я надеюсь, что есть более простое решение, чем это. Некоторый переключатель, который позволяет мне пропустить область подготовки, был бы более удобен, чем перебирать с GIT_INDEX_FILE, чтобы иметь 2 из них.

Моим идеальным решением было бы что-то вроде этого:

git commit --skip-stage --patch ./app/models/whatever.rb

Если это невозможно , тогда я просто прятаю и использую --index, когда высовываю его обратно, и надеюсь, что я случайно не сделал что-то между копчением и выталкиванием, что нарушает возможность чистого восстановления индекс.

Потому что я знаю, что кто-то спросит: «Если вы знаете о --index с git stash pop, почему вы задаете этот вопрос? Потому что речь идет не только о том, что я могу сделать с Git, но и о решении практическая проблема. То, что существует одно решение проблемы, не означает, что это лучшее решение, или что следует прекратить искать альтернативы. Это относится ко всей жизни, а не только к Git.

1 Ответ

0 голосов
/ 23 января 2019

Имеются флаги -a, git commit -a, а также флаги --only и --include (которые можно сократить до -o и -i), которые позволяют выполнять:

git commit --only file1 file2

или:

git commit --include file3

но они работают на , создавая новый временный индекс, как я обрисовал в своем ответе на связанный вопрос.

Что этоделать это немного волшебно, и может или не может быть то, что вы хотите.В частности, временные индексные файлы, которые они создают, включают .git/index.lock, который является внутренним временным новым индексом Git, который, в случае успешной фиксации, станет (обычный) индекс после.Это имеет очень сильные (и несколько странные) последствия.Давайте посмотрим на каждый режим работы.Вариант --only приближается к тому, что вы хотите, и может иногда быть тем, что вы хотите, но иногда может уничтожить что-то ценное.

git commit --only file1 file2

Это начинаетсясделав новый временный индекс, скопированный из HEAD.В этот новый временный индекс Git копирует file1 и file2 из рабочего дерева, как бы git add file1 file2.Так что теперь этот временный индекс соответствует HEAD за исключением двух именованных файлов.

Git также создает .git/index.lock путем копирования содержимого текущего индекса, то есть промежуточных файлов.В это временный индекс, Git копирует file1 и file2, как и раньше.Так что этот временный индекс, который отличается от первого, содержит все ваши подготовленные файлы, за исключением того, что file1 и file2 перезаписаны из рабочего дерева.

Теперь Git делаетновый коммит, использующий временный индекс first - тот, который в основном соответствует HEAD, за исключением двух файлов.Если эта фиксация выполнена успешно, Git обновляет текущую ветку как обычно, затем удаляет этот первый временный индекс, а также разблокирует и обновляет реальный / обычный индекс, переименовывая временный индекс second , .git/index.lock, в .git/index,Таким образом, теперь нормальный индекс такой же, каким он был до , за исключением , в котором file1 и file2 были заменены, как если бы он был git add file1 file2.

Если вы тщательно подготовили другая версия file1 и / или file2, которые (конечно) не находятся в вашем рабочем дереве прямо сейчас - потому что версии рабочего дерева - это те, с которыми вы фиксируете --only - эта специальная версия исчезла , уничтожена с помощью шага git add.Если нет, то это, вероятно, то, что вы хотели!

git commit --include file3

Здесь, давайте предположим, что вы git add ed file1 ранее - возможно, немного другая версия из file1 чем сейчас в вашем рабочем дереве, так что file1 в вещественном / регулярном индексе отличается от file1 в HEAD.

Git начинается с создания нового временногоиндекс с именем .git/index.lock, скопированный из реального / регулярного индекса.Затем Git копирует file3 в этот временный индекс, как если бы git add file3.

Теперь Git делает новый коммит, используя временный индекс .git/index.lock.Если эта фиксация выполнена успешно, Git обновляет текущую ветку как обычно, а затем переименовывает временный индекс с .git/index.lock до .git/index.Так что теперь у реального / обычного индекса все еще есть file1, который вы добавили ранее (который, возможно, не соответствует file1 в рабочем дереве, но отличается от file1 старого коммита), плюс file3 выдобавлено через git commit --include.

(Этот режим никогда не разрушает тщательно подготовленные файлы, но также не выполняет то, что вы описываете в своем вопросе.)

...