Створіть git-патч із змін у поточному робочому каталозі


878

Скажіть, я змінив зміни у своєму робочому каталозі. Як я можу зробити виправлення з тих, не створюючи комітку?


29
Прийняту відповідь, ймовірно, слід змінити, враховуючи, що друга відповідь є майже в чотири рази популярнішою.
Тім Огілві

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

1
Я думаю, що варто згадати, що вам потрібен також виправлення від невмілих змін у назві.
2i3r

Відповіді:


401

git diffдля нестандартних змін. git diff --cachedдля поетапних змін.


12
yup, git diff - це зворотне застосування git
Спайк Гронім

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

20
Іноді може бути корисно створити виправлення відносно поточного каталогу. Щоб досягти цього, використовуйтеgit diff --relative
ejboy

30
git diff> a.patch, щоб записати його у файл
qasimzee

139
Терза, що межує з саркастичним, відповідь нижче корисніша.
Повітря

1864

Якщо ви ще не внесли зміни, то:

git diff > mypatch.patch

Але іноді трапляється, що частина того, що ви робите, - це нові файли, які не відслідковуються і не будуть у вашому git diffвиході. Отже, один із способів зробити виправлення - це встановити все для нової фіксації ( git addкожного файлу чи просто git add .), але не виконувати комісію, а потім:

git diff --cached > mypatch.patch

Додайте опцію "двійкові", якщо ви хочете додати біткові файли до патчу (наприклад, mp3-файли):

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

Пізніше ви можете застосувати виправлення:

git apply mypatch.patch

Примітка. Ви також можете використовувати --stagedяк синонім --cached.


127
Дуже дякую за приклад. На відміну від прийнятої відповіді, ви показуєте команди, як це зробити, а не просто говорити. Дуже корисно і працювало бездоганно для мене :)
nuala

4
Я зробив саме це і отримав "фатальне: невпізнане введення" після виконання git застосувати. Будь-яка ідея, що може спричинити це і як це виправити?
Віталій

6
@Vitaly: чи читається ваш патч, якщо відкрити його за допомогою текстового редактора? він повинен бути чистим, не маючи сторонніх символів, наприклад, якщо встановлено налаштування color.diff, ваш патч матиме деякі кольорові символи, які можуть призвести до відмови "git apply", у цьому випадку спробуйте git diff --no-color. Інакше це виглядає як проблема кодування.
jcarballo

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команда? Чи сумісні вони між собою?
Rakshith Ravi

git diff + git diff - кешировано / інсценовано == 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 --cached --binary
Gaurav Agarwal

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.