Як вишнево вибрати лише зміни лише для одного файлу, а не для всього комітету


108

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


Відповіді:


137

У вас є різні варіанти залежно від того, чого ви хочете досягти:

Якщо ви хочете, щоб вміст файлу був таким самим, як на цільовій гілці, ви можете використовувати git checkout <branch> -- <filename>. Це, однак, не «вишневе» зміни, що відбулися в одному зафіксуванні, а просто прийме отриманий стан вказаного файлу. Отже, якщо ви додали рядок у коміті, але попередні комісії змінилися більше, і ви хочете лише додати цей рядок без інших змін, то замовлення - це не те, що ви хочете.

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

git diff <branch>^..<branch> -- <filename> | git apply

22

Створіть patch fileі застосуйте його.

git diff branchname -- filename > patchfile
git apply patchfile

Редагувати:

Оскільки вам потрібно взяти зміни з комітки, створіть виправлення таким чином:

git show sha1 -- filename > patchfile

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

Правильно. Відредагував відповідь. Дякую.
Сайлеш

1
-1 git checkoutз назвою файлу - правильний молоток для цього цвяха. Обидва ці варіанти зайво складні.
Рейн Генріхс

7
Для цього конкретного випадку, так. Але в цілому, якщо ви хочете вибрати зміни з комісії, зробленого для певного файлу, checkoutвони не будуть працювати, оскільки це може включати інші небажані попередні зміни, а може не містити змін, внесених у поточній гілці.
Сайлеш

11

Ще одна зручна річ - це отримати патч локально, а потім використовувати:

git checkout {<name_of_branch>, commit's SHA} <path to the file> 

Це не збирання вишні, хоча.


2
Попередження: як говорить @poke у своїй відповіді, це не скопіює зміни; він копіює весь стан файлу. Отже, якщо ви хочете додати зміни файлу комітету у файл, то, перевіривши подібне, ви перезаписуєте нові нові зміни, що не годиться.
Олександр Птах

7

У Git все готово :)

Просто використовуйте git checkout <sha> <path-to-file>


4
Це не вишня, яка перевіряє файл повністю. Мета - зробити певну зміну від зобов'язання. Часто це одне й те саме, але іноді це не так.
AndrewF

6
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension

це працює, якщо ви хочете скопіювати один файл з іншої гілки в поточну робочу гілку


1
Будьте уважні, зміни, зроблені у файлі, який не є у версії з іншої гілки, будуть втрачені.
Патрік Шлютер

З цим погодився. це корисно, якщо вам просто потрібна копія файлу, і ви хочете змінити його на поточній гілці
Ісмаїл Ікбал

1
Можна використовувати глобуси (path / *) та вказати більше одного шляху / файлу
Todd

1

Це те, що ви шукаєте:

git checkout target-branch sha1 path/to/file

sha1 необов’язковий


11
ні, "вибрати зміни у фіксації" - це не "вибрати весь файл"
Abyx,

1

Те, що я схильний робити, - це використовувати git ls-tree

просто роби:

git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'

Це дозволить надрукувати всі назви файлів, які відповідають вашій грепі, та надасть SHA1 ключі файлів у коміті.

Git show також може використовуватися для файлів поза вашою філією. використання >з вашої оболонки для передачі виводу у файл дає результат, який ви шукаєте.


0

Ви можете спробувати зробити це:

git show COMMIT_ID -- path/to/specific-file | git apply

Наприклад:

git show 3feaf20 -- app/views/home/index.html | git apply

-9
git reset HEAD~1

переміщує файли на етап попереднього фіксації

git stash

видаляє з пам'яті

Тепер ваша філія досить чиста (повернена до попередньої комісії)

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