Создайте git patch из изменений в текущем рабочем каталоге


881

Скажем, у меня есть незафиксированные изменения в моем рабочем каталоге. Как я могу сделать патч из тех, кто не создает коммит?


29
Принятый ответ, вероятно, следует изменить, учитывая, что второй ответ почти в четыре раза более популярен.
Тим Огилви

5
@TimOgilvy согласился. ОП должен это сделать. Второй ответ гораздо более популярен и дает больше информации
Джон Деметриу

1
Думаю, стоит упомянуть, что вам нужен патч от незафиксированных изменений в названии.
2i3r

Ответы:


401

git diffдля неустановленных изменений. git diff --cachedдля поэтапных изменений.


12
да, git diff - это противоположность git apply
Спайк Гроним

33
git format-patchтакже включает в себя двоичные различия и некоторую мета-информацию. На самом деле это было бы лучшим выбором для создания патча, но на самом деле это работает только для проверенных источников / изменений, верно?
Eric

20
Иногда может быть полезно создать патч относительно текущего каталога. Чтобы достичь этого, используйтеgit diff --relative
ejboy

30
git diff> a.patch для записи в файл
qasimzee

139
Кратко граничит с сарказмом, ответ ниже является более полезным.
Air

1866

Если вы еще не зафиксировали изменения, то:

git diff > mypatch.patch

Но иногда случается, что часть того, что вы делаете, - это новые файлы, которые не отслеживаются и не будут в вашем git diffвыводе. Итак, один из способов сделать патч состоит в том, чтобы подготовить все для нового коммита ( git addкаждого файла или просто git add .), но не делать коммит, а затем:

git diff --cached > mypatch.patch

Добавьте опцию 'binary', если вы хотите добавить двоичные файлы в патч (например, mp3-файлы):

git diff --cached --binary > mypatch.patch

Позже вы можете применить патч:

git apply mypatch.patch

Примечание: вы также можете использовать --stagedкак синоним --cached.


128
Большое спасибо за пример. В отличие от принятого ответа вы показываете команды, как это сделать, а не просто говорите. Очень полезно и работал безупречно для меня :)
Нуала

4
Я сделал именно это и получил «роковой: нераспознанный ввод» после выполнения git apply. Есть идеи, что может вызвать это и как это исправить?
Виталий

6
@Vitaly: ваш патч читается, если вы открываете его в текстовом редакторе? он должен быть чистым без каких-либо странных символов, например, если установлена ​​настройка color.diff, в вашем патче будет несколько «цветных символов», которые могут привести к сбою «git apply», в этом случае попробуйте git diff --no-color. В противном случае это выглядит как проблема кодирования.
Джарбалло

3
Относительно «новых файлов, которые не отслеживаются»: «git diff» и «git diff --cached» работают, только если сначала был вызван «git add <file>». (Я новичок в Git и удивляюсь, почему я каждый раз получаю пустой патч)
Аноним

5
Это довольно легко
Джон Хант

86

git diffи git applyбудет работать для текстовых файлов, но не будет работать для двоичных файлов.

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

git format-patch <options...>

После того, как вы сделали патч, запустите эту команду:

git reset --mixed <SHA of commit *before* your working-changes commit(s)>

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

На принимающей стороне вы можете использовать тот же прием, чтобы применить изменения к рабочей копии, не имея истории фиксации. Просто примените патч (ы), и git reset --mixed <SHA of commit *before* the patches>.

Обратите внимание, что вам, возможно, придется хорошо синхронизироваться, чтобы эта опция работала. Я видел некоторые ошибки при применении патчей, когда человек, производящий их, не выпал столько изменений, сколько я. Возможно, есть способы заставить его работать, но я не стал вдаваться в подробности.


Вот как создать те же патчи в Tortoise Git (я не рекомендую использовать этот инструмент):

  1. Зафиксируйте свои рабочие изменения
  2. Щелкните правой кнопкой мыши по корневому каталогу филиала и выберите Tortoise Git->Create Patch Serial
    1. Выберите тот диапазон, который имеет смысл ( Since: FETCH_HEADбудет работать, если вы хорошо синхронизированы)
    2. Создать патч
  3. Щелкните правой кнопкой мыши по корневому каталогу филиала и выберите Tortise Git->Show Log
  4. Щелкните правой кнопкой мыши на коммите перед вашим временным коммитом и выберитеreset "<branch>" to this...
  5. Выберите Mixedопцию

И как их применять:

  1. Щелкните правой кнопкой мыши по корневому каталогу филиала и выберите Tortoise Git->Apply Patch Serial
  2. Выберите правильный патч (ы) и примените их
  3. Щелкните правой кнопкой мыши по корневому каталогу филиала и выберите Tortise Git->Show Log
  4. Щелкните правой кнопкой мыши на коммите до коммитов патча и выберитеreset "<branch>" to this...
  5. Выберите Mixedопцию

5
Технически это требует создания коммита, которого ОП попросил избежать, но он временный, и ответ полезен независимо.
davenpcj

33

Чтобы создать патч с измененными и новыми файлами (поэтапно), вы можете запустить:

git diff HEAD > file_name.patch

Спасибо, в моем случае этот ответ работает, но git diff --cached > mypatch.patchне работает.
майнинг

У меня вопрос: может file_name.patchли patchкоманда использоваться? Совместимы ли они друг с другом?
Ракшит Рави

git diff + git diff --cached / staged == git diff HEAD (показать все изменения с момента последнего коммита)
символ K.

20

Мне нравиться:

git format-patch HEAD~<N>

где <N>число последних коммитов для сохранения как патчей.

Детали как использовать команду находятся в DOC

UPD
Здесь вы можете найти способ их применения.

UPD Для тех, кто не понял идею format-patch
добавления псевдонима:

git config --global alias.make-patch '!bash -c "cd ${GIT_PREFIX};git add .;git commit -m ''uncommited''; git format-patch HEAD~1; git reset HEAD~1"'

Затем в любом каталоге вашего репозитория проекта запустите:

git make-patch

Эта команда создаст 0001-uncommited.patchв вашем текущем каталоге. Патч будет содержать все изменения и неотслеживаемые файлы, которые видны следующей команде:

git status .

@jcarballo: я обновил ответ. Не стесняйтесь оставлять мне любые ваши уведомления.
Евгений Коньков

2
Существует более простой способ, чем создание коммита и его фиксация. git diff - кэшированный --binary
Гаурав Агарвал

9

Если вы хотите сделать двоичный файл, --binaryукажите вариант при запуске git diff.


0

Мы могли бы также указать файлы, чтобы включить только файлы с относительными изменениями, особенно когда они охватывают несколько каталогов, например

git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.