Принудительная проверка файла после конфликта из тайника

Я сделал git stash save затем git pullgit stash pop и теперь у меня возникают конфликты, и я хочу сбросить один файл, чтобы он был таким же, как в pull, чтобы удалить изменения из stash (у меня есть другие изменения в других файлах, которые я хочу сохранить).

Я пробовал:

git checkout -f inst/app/server.R

но получил предупреждение:

warning: path 'inst/app/server.R' is unmerged

и файл не изменился, у меня все еще есть маркеры конфликта внутри. Как я могу извлечь этот файл из последнего коммита?

1 ответ

Решение

TL;DR: Звучит так, как ты хочешь git checkout --ours inst/app/server.R,

Вы находитесь в середине конфликтующего слияния, поэтому существует два "последнего коммита". Одним из них является ваш HEAD (текущий) коммит. Обратите внимание, что ваш текущий коммит тот, на котором вы были, когда выполняли команду, если только ваша команда git rebase, в этом случае вещи меняются местами: см. Каково точное значение "наших" и "их" в git? Поскольку вы говорите, что последняя команда, которая потерпела неудачу с конфликтом слияния, была git stash apply, 1 ваш текущий коммит тот, который вы сделали после git pull побежал успешно git merge для вас 2 и другой коммит - это один из нескольких коммитов в вашем текущем git stash шкатулка под именем stash@{0} (иначе stash).

(В любом конфликтующем слиянии участвует третий коммит, который является базой слияния. Возможно, он менее актуален для тайников, что немного странно, но стоит упомянуть. Обратите внимание, что если вы установите merge.conflictStyle в diff3 в вашей конфигурации Git вы получите версию слиянием с дополнительным набором маркеров конфликта, |||||||, между <<<<<<< а также >>>>>>> разделы, показывающие вам "наши" и "их" версии. Я люблю держать diff3 установить, так как он показывает мне, что было до того, как я и они оба изменили файл противоречивым образом.)

Когда ты бежишь git checkout без указания конкретного коммита или использования --ours или же --theirs вариант, Git пытается получить версию из индекса. (Помните, что индекс, также называемый промежуточной областью, а иногда и кешем, - это место, где вы строите следующий сделанный вами коммит.) Но конфликтующее объединение оставляет три версии каждого конфликтующего файла в индексе. Git не знает, какой из них получить, поэтому терпит неудачу с этой ошибкой. С помощью --ours говорит git checkout скопировать "нашу" (т. е. HEAD) версию файла из индекса в рабочее дерево; с помощью --theirs говорит git checkout скопировать "другую" (т. е. MERGE_HEAD) версию файла. 3

Когда вы извлекаете одну из этих версий из индекса, это оставляет две другие версии в индексе, т. Е. Оставляет файл в состоянии неразрешенного слияния. Внимательно проверьте содержимое, чтобы убедиться, что у вас правильная версия, затем git add файл для разрешения конфликта. Это уничтожит три отдельные версии индекса, поместив версию рабочего дерева в "разрешенный" индексный слот (нулевой слот).

Если вам нужно заново создать конфликт слияния, вы можете использовать git checkout -m -- path (-- требуется только если pathнапоминает вариант, но это хорошая привычка, чтобы попасть в). Это работает до тех пор, пока вы не запустите git commit завершить неудачное слияние.

Когда все решено так, как вы хотите, используйте git commit закончить слияние.


1 Вы сказали git stash pop, но git stash pop это просто ярлык, означающий "Run git stash apply а затем, если и только если это удастся, запустить git stash drop Msgstr "Поскольку шаг применения не удался, вам нужно будет запустить git stash drop вручную, как только вы убедитесь, что тайник был применен правильно и зафиксирован.

2 Я рекомендую избегать git pull, Все, что он делает, это запускает две другие команды Git для вас: git fetch то либо git merge или же git rebase в зависимости от того, что вы говорите Git заранее. Лучше запускать две команды по отдельности, чтобы:

  • вы знаете, что терпит неудачу, когда кто-то терпит неудачу; а также
  • Вы можете выбрать слияние или перебазирование после проверки того, что git fetch неправдоподобным.

Там нет ничего принципиально неправильно с использованием git pull просто помни, что это действительно git fetch && git something, и вы должны решить "что-то" часть заранее. Если вы не выберете один, Git выберет git merge, что, вероятно, является неправильным значением по умолчанию, но это то, что Git впервые сделал еще в 2005 году, и поэтому не может быть изменен.:-)

3 нет --base вариант, но вы можете использовать gitrevisions синтаксис для доступа к нему из индекса: git checkout -- :1:path, Вы можете использовать этот же синтаксис, чтобы получить на --ours версия, которая является индексной записью № 2, и --theirs версия, которая № 3, но это легче запомнить --ours а также --theirs тем не мение.

"Наша" версия иногда называется локальной версией, а "их" версия иногда называется удаленной, но я ненавижу эти имена. В частности, "пульт" слишком легко спутать с такими пультами, как origin и названия веток удаленного отслеживания, такие как origin/master,

Другие вопросы по тегам