Іноді задача дуже маленька, а після push у pull request раптом з’являється значно більший diff.
Саме так сталося в мене нещодавно. Я змінювала відступи для одного елемента на сторінці. Потрібна зміна була невеликою, але під час перегляду diff я побачила сторонні пробіли, перенесення рядків і форматування, які взагалі не стосувалися задачі.
Повністю повернути файли до production я не могла, тому що в тих самих файлах уже знаходилась потрібна зміна.
Отже задача була іншою: прибрати тільки випадкові зміни форматування і залишити функціональну зміну.
Для цього мені дуже допоміг git restore -p.
Спочатку я ще раз перевірила diff
git diff origin/master -- \ resources/assets/css/styles/page.scss \ resources/views/front/model/page/show.blade.phpПеред будь-яким відновленням я ще раз подивилася, що саме відрізняється від базової гілки.
У diff були змішані два типи змін:
- моя потрібна зміна;
- стороннє форматування та пробіли.
Саме тому звичайне повне відновлення файлів тут не підходило. Воно прибрало б не лише зайве, а й саму задачу.
Чому повне відновлення файлу тут небезпечне
Якби файл містив лише випадкову зміну, його можна було б просто повернути до стану базової гілки.
Але тут один файл одночасно містив і правильну зміну, і випадкове форматування.
Тому мені потрібен був не вибір між "залишити файл" і "повернути файл", а можливість приймати рішення для кожного окремого фрагмента diff.
Вибіркове відновлення через git restore -p
git restore -p \ --source=origin/master \ -- \ resources/assets/css/styles/page.scss \ resources/views/front/model/page/show.blade.phpОпція -p означає patch.
Git не відновлює весь файл одразу. Він показує зміни окремими фрагментами - hunks - і для кожного запитує, що робити.
Discard this hunk from worktree [y,n,q,a,d,s,e,?]?Найважливіше - не переплутати y та n
y - так, повернути цей фрагмент до версії з origin/production поточна локальна зміна в цьому фрагменті зникне n - ні, не повертати цей фрагмент поточна зміна залишитьсяЯк я вирішувала, що залишити
Коли Git показував фрагмент, у якому були лише випадкові пробіли, перенесення рядків або інше форматування, я відповідала y.
Це означало: повернути саме цей фрагмент до origin/production.
Коли ж Git доходив до справжньої зміни задачі, я відповідала n, щоб залишити її в робочому файлі.
&--withdrawn-gap lot__rate--withdrawn-gapУ моєму випадку ці назви допомагали швидко впізнати потрібну зміну серед інших фрагментів.
Тобто логіка була дуже проста:
- бачу лише випадкове форматування -
y; - бачу зміну, заради якої створена задача -
n.
У цьому й була головна перевага git restore -p: я працювала не з файлом цілком, а з окремими частинами його diff.
Після відновлення я знову перевірила diff
git diff git diff -w git diff --check git status -sbПісля проходження всіх фрагментів я не покладалася лише на пам’ять про відповіді y та n. Я ще раз подивилася результат.
Звичайний git diff показує весь поточний diff.
git diff -w ігнорує зміни пробілів. У такому сценарії це особливо корисно: я могла перевірити, що після очищення залишилася саме функціональна зміна.
git diff --check додатково перевіряє типові проблеми з пробілами, а git status -sb дає короткий стан гілки та файлів.
Що змінюється, якщо код уже був запушений
У моєму випадку зайве форматування стало помітним уже після push.
git restore -p не переписує старий commit у віддаленому репозиторії. Команда лише змінює мої поточні робочі файли.
Після очищення я перевірила результат, додала виправлені файли до нового commit і запушила його.
git add \ resources/assets/css/styles/page.scss \ resources/views/front/model/page/show.blade.php git commit -m "Restore unrelated whitespace" git pushУ результаті pull request отримав ще один commit, який прибирав випадкові зміни, але не торкався самої задачі.
Якщо пізніше потрібно привести історію до одного чистого commit, це вже окрема операція. Для мене на цьому етапі важливішим було спочатку отримати правильний і зрозумілий diff.
Чому я не повертала все вручну
Звичайно, я могла відкрити кожен файл і вручну повертати пробіли та перенесення рядків.
Але коли один файл містить одночасно потрібну зміну, випадкове форматування і кілька незалежних фрагментів, ручне редагування створює ще один ризик: випадково зачепити правильний код.
git restore -p вже має всю потрібну інформацію. Git показує конкретний фрагмент різниці, а я лише вирішую, повернути його до базової версії чи залишити.
Команда, яку я хочу запам’ятати
git restore -p \ --source=origin/production \ -- \ path/to/filey - повернути цей фрагмент до версії з sourcen - залишити мою поточну змінуКоли в одному файлі змішані потрібні й випадкові зміни, мені не обов’язково вибирати між брудним diff і повним відкатом. Я можу повернути тільки конкретні фрагменти.
Це маленька Git-команда, але вона вирішила дуже конкретну проблему.
Потрібна зміна вже була зроблена й запушена. Повний restore знищив би її разом із зайвим форматуванням. Ручне повернення пробілів було б повільнішим і менш надійним.
git restore -p дозволив пройти diff по частинах і для кожної окремо вирішити: це повернути чи це залишити.
У результаті я прибрала тільки те, що випадково потрапило в pull request, і зберегла саме ту зміну, заради якої створювалася задача.



