Введіть лише частину файлу в Git


2764

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

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


3
пов’язані stackoverflow.com/q/34609924/52074 : якщо вам потрібно розділити лунку на більш дрібні.
Тревор Бойд Сміт

Підсумок: з точки зору можливостей: git gui= git add -e> git add -i -p; з точки зору зручності: git gui> git add -i -p> git add -e. Отже: вибирайте, git guiколи у вас є доступ до X. вибирайте git add -i -pдля простих речей, а коли у вас немає або хочете використовувати X. git add -eдля складних постановок без X.
Penghe Geng

Відповіді:


3687

Ви можете скористатися 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файли.

Довідка на майбутнє: Git Tools - інтерактивна постановка


83
Можливо, буде корисно відзначити, що -p/--patchце ярлик до дії виправлення всередині -i/--interactiveкоманди, яка ініціює корисний інтерактивний режим .
tutuDajuju

5
> Що станеться, якщо цей файл вже інсценований? Він відображатиме лише нестандартні зміни. Те ж саме git diff.
Євген Конков

3
Як я можу редагувати поточну частину вручну? Я не знаю, що робити після введення e.
Хунсу

23
Після натискання кнопки e, Ви можете редагувати шмат вручну шляхом заміни +або -по#
veksen

1
це чудово, але тепер, як я насправді натискаю на це? якщо я git pushце роблю, це вже є актуальним. і якщо я git diffя бачу, скибки я сказав nв. якщо я git diff --stagedдійсно бачу похиту, яку хочу натиснути. Якщо припустити, що я можу підштовхнути команду, як видалити залишки, про які я сказав no?
чови

250

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

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

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


1
Цікаво, що windows.github.com мала підтримку часткових файлових файлів, але, здається, нещодавно відмовилася від цього.
Juri,

1
@Juri Я думаю, що підтримка часткових файлових файлів повертається.
Ela782,

@Juri Ви раді. Я насправді ніколи не помічав, що він там був раніше - я бачив це минулого тижня і думав "о, яка дивовижна нова функція"! :-)
Ela782

1
В даний час windows.github.com перенаправляє на ребрендований робочий стіл GitHub, який є кращим, ніж Git GUI і підтримує часткові зобов’язання ..., але не підтримує підписання комісій. Зітхнути.

147

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


13
для складних патчів це, як правило, найшвидший підхід для мене.
hochl

7
Це дуже ефективний та інтуїтивно зрозумілий спосіб додати зміни до місця постановки тонкозернистим способом. Також можна вибрати кілька рядків, і всі зміни в цьому виділенні будуть додані.
jox

Зауважте, що це не так gitk, але воно входить до програми Git Bash для Windows; у вас має бути запис меню "Пуск" для нього або ви можете запустити його командою git gui. Є також, stage this hunkщо, мабуть, корисніше, ніж stage this line. Можливо, це буде новим, оскільки ця відповідь була створена 10 років тому.
Кріс

82

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

доданий вміст:

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

видалений вміст:

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

змінений вміст:

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

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


7
Це було б корисніше, якби десь було чітке пояснення того, як насправді вибрати ці рядки (тобто фактичні команди для введення). Я не зміг знайти його в документації. Чи можете ви додати посилання?
Олексій

4
Для тих, хто не любить скорочені варіанти, -eє --edit.
Колюня

2
@Alex Довідкові цитати, додані TheFreedomBanana, є з розділу «РЕГІСТРАЦІЯ ПАТЧІВ»git --help add
Randall,

8
Це єдина відповідь (вимагає лише git), яка вирішує проблему додавання / видалення рядків розумним, коли ви не можете зменшити розміри sв інтерактивному режимі виправлення.
cdosborn

3
Може бути корисним зрозуміти, що ця команда ( git add -e) * не змінює вміст файлу на диску. Він просто переміщує частину змін від нестандартних до поетапних (індекс).
Penghe Geng

44

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

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

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


Дякую вам за це посилання. Точно те, що мені потрібно. Особливо :diffget/:diffputу візуальному режимі, де я можу вибрати конкретні лінії, які я хочу скинути / ввести. Отже, переконайтеся ще раз: vim - приголомшливий.
goodniceweb

30

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

введіть тут опис зображення


1
Я погоджуюся, що SourceTree є хорошим інструментом для цієї мети, оскільки він дає вам більш тонкий контроль, ніж те, що можливо за допомогою командного рядка.

18
@cupcake Я б заперечував протилежне, бачачи, що SourceTree, ймовірно, використовує ті виконавчі файли git командного рядка, за своєю суттю завжди можна буде робити ті самі (або більше) дрібнозернисті дії через "командний рядок".
tutuDajuju

2
Незалежно від дрібнозернистого аргументу, я настійно рекомендую SourceTree як інсценувати перегони та окремі лінії дуже просто: i.imgur.com/85bNu4C.png
Mars Robertson,

1
@tutuDajuju У цьому випадку я не впевнений, що це правда. SourceTree має можливість вибирати, які частини слід виконувати по черзі . Вам не доведеться виставляти цілий шматок; Ви можете провести 2 рядки посеред частини. Я поняття навіть не маю, як це досягти. (На даний момент я намагаюся подолати невміння SourceTree встановити окремі рядки для відслідковуваного файлу. Я приземлився тут, шукаючи обхід, лише щоб виявити, що git, мабуть, не пропонує можливості рядкового рядка взагалі. Принаймні не прямолінійно.)
jpmc26

1
@Sun ви можете натиснути на рядок 50 і перемістити + натиснути рядок 100, а потім перейти на етап. Ви можете легко поставити лінію 50-100 в Sourcetree :)
ryan123

26

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

git add -N file
git add -p file

23

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

Подобається це:

$ 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

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


12

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


Я часто подорожую над командою git, бажаючи відкрити редактор, коли я запускаю її з вікна оболонки Mx. Чи магіт перехоплює це божевілля і відкриває для цього лише новий буфер? (будь ласка, жодних підказок background-emacs-daemon; все одно дякую, але життя занадто коротке).
користувач2066657

Ні, наскільки я можу сказати, це не перехоплює. Але не приймайте моє слово, тому що (1) я навряд чи коли-небудь використовую вікно оболонки в Emacs, і (2) я зазвичай використовую emacsclient. Сказавши, що якщо emacsclient є для вас варіантом, ви принаймні перешкоджали відкриттю додаткового вікна з emacs та відкриття буфера "COMMIT_EDITMSG" у моєму існуючому вікні Emacs.
Марк ван Лент


9

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

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


2
Комбінація клавіш у розширеннях Git для "Етап виділених рядків" s- дуже корисна для швидкої постановки фрагментів файлів на коміт.
Alchemistmatt

8

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

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

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


це працює добре, але якщо ви користуєтеся git commit --amend, то, здається, ви не зможете випустити приховування згодом, або є спосіб зробити це?
Марк

7

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

введіть тут опис зображення

Як ви, можливо, вам відомі рядки, які починаються з +доповнення, рядки, які починаються з - -це видалення. Тому:

  • Щоб не ставити додавання, просто видаліть цей рядок.
  • Щоб не проводити видалення, просто замініть -пробіл .

Ось що git add -hговорить про додавання файлів таким чином (виправлення файлів):

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

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

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

Увага: не змінюйте вміст файлу, це не вдале місце для цього. Просто змініть оператори видалених або доданих рядків.


Яка попередня відповідь? Відповіді зберігаються на основі кількості балів, які вони мають. Тож ваша відповідь зараз в іншому місці, ніж це було, коли ви її писали порівняно з іншими відповідями.
KulaGGin

Я вважаю, що відповідь, на яку посилається, є від @theFreedomBanana
K. Symbol

6

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

:GitGutterStageHunk

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

Якщо тільки частина лукавинки повинна бути інсценізована вим-втікачем

:Gdiff

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



4

З TortoiseGit:

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


4

Минуло 10 років, як було задано це питання. І я сподіваюся, що ця відповідь комусь стане у нагоді. Як згадується у відповіді тут , де графічний інтерфейс не є варіантом, розширення крекорд Ендрю Шадури допомагає вивести вікно ncurses, в якому ми можемо вибрати рядки для здійснення.

Налаштуйте розширення наступним чином:

git clone https://github.com/andrewshadura/git-crecord
cd git-crecord
./setup.py install
ln -s $PWD/git-crecord ~/.local/bin/git-crecord

CD на ваш git repo і викликайте його наступним чином:

git crecord

Це призведе до інтерфейсу ncurses, який можна використовувати, як показано нижче. Натискання наступних клавіш у вікні ncurses виконає певні дії:

f       hunk toggle fold (arrow keys can also be used)
space   toggle hunk selection
a       toggle commit or amend
c       confirm and open commit window

Екранна трансляція показує вибіркове використанняПриклад


3

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

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



2

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

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

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

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

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

У сховищі git запустіть:

git meld-index

Ви побачите, що meld (або налаштований git difftool) спливає з:

ЛІВОРУЧ : тимчасові файли каталогу contining скопійовані з вашого робочого дерева

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

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

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


2

Якщо це на 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

1

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

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

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

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

... а потім за допомогою згаданих клавіш (y / n тощо) для вибору рядків, які будуть включені до комітки.


Що це дає вам більше, ніж " git add -p filename.txt" менше помилок? Якщо ви зіпсуєте зміну часткового файлу, скасування додавання краще, ніж скасування комісії.
CTMacUser

Я не знаю чому, але коли я кажу 'n', рядок включається .... і коли я кажу "у" на 2-й лусці, він також включається.
chovy

0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.