Зафіксувати тільки частина файлу в Git

Коли я вношу зміни в файл в Git, як я можу виконати тільки деякі з змін?

Наприклад, як я можу виконати тільки 15 рядків з 30 рядків, які були змінені в файлі?

2394
06 июля '09 в 5:25 2009-07-06 05:25 заданий freddiefujiwara 06 липня '09 о 5:25 2009-07-06 5:25
@ 22 відповідей

Ви можете використовувати git add --patch <filename> (або -p для стислості), і git почне розбивати ваш файл на те, що він вважає розумними "порціями" (частинами файлу). Потім він підкаже вам це питання:

 Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? 

Ось опис кожної опції:

  • y підготувати цей шматок для наступного коммітов
  • n не ставити цей шматок для наступного коммітов
  • q вихід; не ставте цей шматок або будь-який з решти шматків
  • a ставить цей шматок і всі наступні фрагменти в файлі
  • d не ставити цей блок або будь-якої більш пізній фрагмент в файлі
  • g виберіть шматок, щоб перейти до
  • / Пошук блоку, відповідного заданому регулярному виразу
  • j залиш цей шматок невирішеним, дивись наступний невирішене шматок
  • J залиш цей шматок невирішеним, дивись наступний шматок
  • k залишити цей шматок невирішеним, см. Попередній невирішене шматок
  • K залиш цей шматок невирішеним, дивись попередній шматок
  • s розділити поточний шматок на більш дрібні фрагменти
  • e вручну редагувати поточний блок
  • ? довідка по роздруківці

Якщо файл ще не знаходиться в сховищі, ви можете спочатку зробити git add -N <filename> . Після цього ви можете продовжити за допомогою git add -p <filename> .

Після цього ви можете використовувати:

  • git diff --staged щоб переконатися, що ви поставили правильні зміни
  • git reset -p щоб розстебнути помилково додані фрагменти
  • git commit -v для перегляду вашого коммітов під час редагування повідомлення коммітов.

Зверніть увагу, що це сильно відрізняється від команди git format-patch , метою якої є аналіз даних .patch файлах .patch .

Посилання на майбутнє: Git Tools - Інтерактивна постановка

3149
06 июля '09 в 5:36 2009-07-06 05:36 відповідь дан cloudhead 06 липня '09 в 5:36 2009-07-06 5:36

Ви можете використовувати git add --interactive або git add -p <file> , а потім git commit (НЕ git commit -a ); см. інтерактивний режим в git-add manpage або просто дотримуйтесь інструкцій.

Сучасний Git також має git commit --interactivegit commit --patch , який є ярликом для параметра патча в інтерактивній фіксації).

border=0

Якщо ви віддаєте перевагу робити це з графічного інтерфейсу, ви можете використовувати git-gui . Ви можете просто відзначити шматки, які ви хочете включити в фіксацію. Мені особисто легше, ніж використовувати git add -i . Інші Git GUI, такі як QGit або GitX, також можуть мати цю функціональність.

223
06 июля '09 в 14:49 2009-07-06 14:49 відповідь дан Jakub Narębski 06 липня '09 о 14:49 2009-07-06 14:49

git gui надає цю функціональність під виглядом diff. Просто клацніть правою кнопкою миші цікаву для вас лінію, і ви побачите пункт меню "Цей рядок для фіксації".

118
06 июля '09 в 5:41 2009-07-06 05:41 відповідь дан Ionuţ G. Stan 06 липня '09 в 5:41 2009-07-06 5:41

Я вважаю, що git add -e myfile - найпростіший спосіб (по крайней мере, моє перевагу), оскільки він просто відкриває текстовий редактор і дозволяє вам вибрати, який рядок ви хочете виконати, а який рядок у вас немає. Що стосується команд редагування:

доданий контент:

Доданий вміст представлено рядками, які починаються часткою з "+". Ви можете запобігти створенню будь-яких ліній складання, видаливши їх.

віддалений контент:

Віддалене вміст представлено рядками, які починаються часткою з "-". Ви можете запобігти їх видалення шляхом перетворення "-" в "" (пробіл).

зміни вмісту:

Зміни вмісту представлено лініями "-" (видалення старого вмісту), за яким слідують рядки "+" (додавання заміщає вмісту). Ви можете запобігти установку модифікації шляхом перетворення рядків "-" в "" і видалення "+", ліній. Пам'ятайте, що зміна тільки половини пари, швидше за все, призведе до заплутують змін індексу.

Кожна інформація про git add доступна на git --help add

64
25 сент. відповідь дан theFreedomBanana 25 сент. 2015-09-25 23:45 '15 о 23:45 2015-09-25 23:45

Якщо ви використовуєте vim, ви можете спробувати відмінний плагін під назвою fugitive .

Ви можете побачити diff файлу між робочою копією та індексом за допомогою :Gdiff , а потім додати рядки або стовпці в індекс, використовуючи класичні команди vim diff, такі як dp . Збережіть зміни в індексі і скопіюйте за допомогою :Gcommit , і все готово.

Дуже хороші вступні відеоролики тут (див. Частину 2 ).

42
23 февр. відповідь дан François 23 февр. 2012-02-23 13:37 '12 о 13:37 2012-02-23 13:37

Я настійно рекомендую використовувати SourceTree від Atlassian. (Це безкоштовно.) Це робить це тривіальним. Ви можете швидко і легко створювати окремі шматки коду або окремі рядки коду.

2019

29
12 авг. відповідь дан user486646 12 Серпня. 2014-08-12 16:32 '14 о 16:32 2014-08-12 16:32

Варто зазначити, що для використання git add --patch для нового файлу вам потрібно спочатку додати файл в індекс за допомогою git add --intent-to-add :

 git add -N file git add -p file 
22
05 дек. відповідь дан user1338062 05 дек. 2014-12-05 20:29 '14 о 20:29 2014-12-05 20:29

Коли у мене буде багато змін і в підсумку створять кілька коммітов з змін, я хочу тимчасово зберегти свою початкову точку, перш ніж створювати речі.

Ось так:

 $ git stash -u Saved working directory and index state WIP on master: 47a1413 ... $ git checkout -p stash ... step through patch hunks $ git commit -m "message for 1st commit" $ git checkout -p stash ... step through patch hunks $ git commit -m "message for 2nd commit" $ git stash pop master $ git stash -u Saved working directory and index state WIP on master: 47a1413 ... $ git checkout -p stash ... step through patch hunks $ git commit -m "message for 1st commit" $ git checkout -p stash ... step through patch hunks $ git commit -m "message for 2nd commit" $ git stash pop 

Відповідь Whymarh - це те, що я зазвичай роблю, за винятком того, що іноді відбувається безліч змін, і я можу сказати, що можу зробити помилку під час постановки речей, і я хочу, щоб якийсь стан я міг відступити на другий прохід .

19
07 июня '13 в 1:14 2013-06-07 01:14 відповідь дан jdsumsion 07 червня '13 в 1:14 2013-06-07 1:14

Якщо ви використовуєте emacs, подивіться Magit , який надає інтерфейс git для emacs. Він добре підтримує проміжних фрагментів (частини файлів).

12
08 июля '09 в 10:00 2009-07-08 10:00 відповідь дан Mark van Lent 08 липня '09 о 10:00 2009-07-08 10:00

Як і у випадку з jdsumsion, ви також можете заховати свою поточну роботу, але потім використовуйте difffool, наприклад meld, щоб витягнути вибрані зміни зі схованки. Таким чином, ви можете навіть вручну відредагувати шматки, що трохи боляче, коли в git add -p :

 $ git stash -u $ git difftool -d -t meld stash $ git commit -a -m "some message" $ git stash pop 

Використання методу stash дає вам можливість протестувати, якщо ваш код все ще працює, перш ніж виконати його.

8
07 авг. відповідь дан derhoch 07 Серпня. 2013-08-07 16:25 '13 о 16:25 2013-08-07 16:25

Intellij IDEA (і я вважаю, що всі інші продукти серії) побудували підтримку часткових коммітов, оскільки v2018.1

2019

Для тих, хто використовує Git Розширення:

У вікні "Копіювати" виберіть файл, який ви хочете частково здійснити, і виділіть необхідний текст, який ви хочете зафіксувати, в правій панелі, потім клацніть правою кнопкою миші на виділеному фрагменті і виберіть "Сформувати вибрані рядки» у відповідному меню.

7
27 июля '15 в 12:52 2015-07-27 12:52 відповідь дан srgstm 27 липня '15 о 12:52 2015-07-27 12:52

vim-gitgutter плагін може створювати ханки, не виходячи з редактора vim, використовуючи

 :GitGutterStageHunk 

Крім цього, він надає інші цікаві функції, такі як стовпець з різним знаком, як в деяких сучасних IDE

Якщо тільки частина hunk повинна бути поставлена vim-fugitive

 :Gdiff 

дозволяє вибирати діапазон видимого діапазону, потім :'<,'>diffput або :'<,'>diffget для зміни / зміни окремих рядків.

6
09 янв. відповідь дан c0ffeeartc 09 Січня. 2015-01-09 20:11 '15 о 20:11 2015-01-09 20:11

Спробував git add -p filename.x , але на Mac я виявив, що gitx ( http://gitx.frim.nl/ або https://github.com/pieter/gitx ) набагато простіше зробити точно лінії, які я хотів .

5
16 авг. відповідь дан jasongregori 16 Серпня. 2011-08-16 02:43 '11 в 2:43 2011-08-16 2:43

З TortoiseGit:

клацніть правою кнопкою миші файл і використовуйте Context Menu → Restore after commit . Це створить копію файлу, як є. Потім ви можете відредагувати файл, наприклад. в TortoiseGitMerge і відмініть всі зміни, які ви не хочете робити. Після збереження цих змін ви можете зафіксувати файл.

4
06 апр. відповідь дан Fr0sT 06 Квітня. 2015-04-06 19:16 '15 о 19:16 2015-04-06 19:16

git-meld-index - цитування з веб-сайту:

git -meld-index запускає meld - або будь-який інший git diffftool (kdiff3, diffuse і т.д.) - щоб ви могли інтерактивно змінювати зміни індексу git (також відомого як git).

Це схоже на функціональність git add -p і git add --interactive. У деяких випадках meld легше / швидше використовувати, ніж git add -p. Це тому, що meld дозволяє вам, наприклад ,:

  • см. більше контексту
  • см. Внутрішньо лінійні відмінності
  • відредагуйте вручну і подивіться 'live' diff updates (оновлюється після кожного натискання клавіші)
  • перейдіть до зміни, що не вказуючи "n" на кожну зміну, яке ви хочете пропустити.

Використання

У репозиторії git запустіть:

 git meld-index 

Ви побачите, що meld (або налаштований git diffftool) з'являється за допомогою

LEFT: файли тимчасового каталогу, скопійовані з робочого дерева

ВПРАВО: тимчасовий каталог з вмістом індексу. Це також включає файли, які ще не знаходяться в індексі, але змінені або не перевірені в робочій копії - в цьому випадку ви побачите вміст файлу з HEAD.

Відредагуйте індекс (праворуч) до тих пір, поки він не стане щасливим. Не забудьте зберегти при необхідності.

Коли ви закінчите, закрийте meld і git -meld-index оновить індекс, щоб він відповідав вмісту тимчасового каталогу в правій частині команди meld, яку ви тільки що відредагували.

2
04 июля '15 в 23:26 2015-07-04 23:26 відповідь дан Croad > 04 липня '15 о 23:26 2015-07-04 23:26
2
13 июля '09 в 0:52 2009-07-13 00:52 відповідь дан zut 13 липня '09 в 0:52 2009-07-13 00:52

Додаючи попередній відповідь, якщо ви віддаєте перевагу використовувати командний рядок, введіть git add -e myfile дає вам вибір, щоб вибрати рядок за рядком, яку ви б хотіли записати, бо ця команда відкриє редактор з відмінностями, наприклад:

2019

24 авг. відповідь дан Beto Aveiga 24 Серпня. 2018-08-24 18:24 '18 о 18:24 2018-08-24 18:24

Для користувачів Atom пакет github включає інтерактивну постановку в стилі git gui . Для ярликів см. Документацію до упаковки.

Використання Atom дозволяє працювати з темою з темним тлом (за замовчуванням git gui має білий фон).

1
10 апр. відповідь дан Ioannis Filippidis 10 Квітня. 2018-04-10 05:31 '18 в 5:31 2018-04-10 5:31

Як один відповідь вище показує, ви можете використовувати git add --patch filename.txt

або коротка форма git add -p filename.txt

... але для файлів, які вже перебувають в ваше сховище, є набагато краще використовувати прапор -patch для команди commit (якщо ви використовуєте досить недавню версію git): git commit --patch filename.txt

... або, знову ж таки, коротка форма git commit -p filename.txt

... і потім використовуючи зазначені ключі (y / n і т.д.), для вибору рядків, які повинні бути включені в фіксацію.

1
30 июня '14 в 11:34 2014-06-30 11:34 відповідь дан Samuel Lampa 30 червня '14 о 11:34 2014-06-30 11:34

git-cola - відмінний графічний інтерфейс, а також вбудована функція. Просто виберіть лінії для сцени і натисніть S. Якщо вибір не проводиться, виконується повний шматок.

0
27 авг. відповідь дан AndiDog 27 Серпня. 2015-08-27 14:28 '15 о 14:28 2015-08-27 14:28

Якщо на платформі Windows , на мій погляд, git gui - кращий інструмент для stage / commit кількох рядків з unstaged файлу

1. Хенк мудрий:

  • Виберіть файл з розділу unstagged Changes
  • Клацніть правою кнопкою миші код коду, який необхідно виконати.
  • Виберіть Stage Hunk for commit

2. Рядок:

  • Виберіть файл з розділу unstagged Changes
  • Виберіть рядок / рядки, які будуть організовані
  • Виберіть Stage Lines for commit

3. Якщо ви хочете створити повний файл, крім пари рядків:

  • Виберіть файл з розділу unstagged Changes
  • Натисніть Ctrl+T (Stage file to commit)
  • Обраний файл тепер переміщається в Staged Changes Розділ
  • Виберіть рядок / рядки, які будуть організовані
  • Виберіть UnStage Lines for commit
0
28 мая '15 в 15:52 2015-05-28 15:52 відповідь дан Anvesh Yalamarthy 28 травня '15 о 15:52 2015-05-28 15:52

Інші питання по мітках або Задайте питання