Як скопіювати версію одного файлу з однієї гілки git в іншу?


944

У мене дві гілки, які повністю злиті разом.

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

То який найпростіший спосіб в git зробити це?


3
Зверніть увагу, що у прийнятій відповіді перше рішення стадіює зміни, а друге - не. stackoverflow.com/a/56045704/151841
user151841

Відповіді:


1673

Запустіть це з гілки, де ви хочете, щоб файл закінчився:

git checkout otherbranch myfile.txt

Загальні формули:

git checkout <commit_hash> <relative_path_to_file_or_dir>
git checkout <remote_name>/<branch_name> <file_or_dir>

Деякі нотатки (з коментарів):

  • Використовуючи хеш фіксації, ви можете витягувати файли з будь-якої комісії
  • Це працює для файлів та каталогів
  • перезаписує файл myfile.txtіmydir
  • Підстановочні картки не працюють, але відносні шляхи є
  • Можна вказати кілька шляхів

альтернатива:

git show commit_id:path/to/file > path/to/file

13
Так, було б. Але це був намір питання.
Ikke

37
Можливо, очевидно, але вам потрібно використовувати повне ім'я файлу ... Замітні картки не працюють!
Кріс Харт

6
хоча .. це також приємний спосіб: git show commit_id: path / to / file> path / to / file
milushov

14
remote: git checkout origin / otherbranch myfile.txt
Роман Ррн Нестеров

6
Використання символів підказки справді спрацьовує, потрібно просто обернути їх, ''щоб вони не трактувались оболонкою.
Wiktor Czajkowski

82

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

git show TREEISH:path/to/file >path/to/local/file

18
Метою "git show" є виведення даних у термінал у читаному форматі, який не гарантується точно відповідати вмісту файлу. Те саме, що краще скопіювати слово-документ у цілому, а не намагатися скопіювати та вставити його вміст в інший документ.
Gonen

Я просто хотів переглянути його, щоб я міг порівняти вміст із поточною гілкою (перевірити якийсь фрагмент коду). Я хотів би використовувати vim з цим, хоча ... для підсвічування синтаксису тощо
isaaclw

3
Щоб порівняти вміст перед тим, як зробити замовлення, git diff <other branch> <path to file>добре працює.
Рандалл

2
@Gonen: На версію git 2.21.0 на сторінці керівництва "git show" написано: "Для звичайних крапель він показує звичайний вміст". Я не впевнений, чи означає це, що ми завжди добрі. Мені дуже подобається отримати зображення таким чином ...
hibbelig

52

Як щодо використання команди оформлення замовлення:

  git diff --stat "$branch"
  git checkout --merge "$branch" "$file"
  git diff --stat "$branch"

8
Примітка злиття (2-а команда) не може працювати, якщо файл не існує в обох гілках
simpleuser

Гм. У мене немає дифстату. Це специфічна версія різного інструменту, тому що я ніколи про нього не чув (і чи варто переходити на нього?): D
dudewad

git diffпідтримує --statаргумент, який в основному робить те саме, що і діфстат.
hlovdal

Мені довелося перевірити обидві гілки на місцях, щоб зробити це на роботі.
UnitasBrooks

18

1) Переконайтеся, що ви знаходитесь у відділенні, де вам потрібна копія файлу. наприклад: я хочу, щоб файл підрозділу в master був таким, що вам потрібно замовити або повинен бути в mastergit checkout master

2) Тепер оформити окремий файл, який ви хочете, від підрозділу до головного,

git checkout sub_branch file_path/my_file.ext

тут sub_branchозначає, що у вас є цей файл, а потім ім'я файлу, яке потрібно скопіювати.


Дуже зручно і добре пояснено.
АБК

15

Після відповіді madlep ви також можете просто скопіювати один каталог з іншої гілки за допомогою крапки каталогу.

git checkout other-branch app/**

Щодо питання ОП, якщо ви там змінили лише один файл, це буде добре працювати ^ _ ^


1
Зауважте, що обидві гілки потрібно спочатку правильно витягнути або використати origin/other-branchдля посилання на гілку репо. Основи, але мене покусало. (відповідь чудова - редагування не потрібно)
akauppi

8

Я б використовував git restore(доступно з git 2.23)

git restore --source otherbranch path/to/myfile.txt


Чому це краще, ніж інші варіанти?

git checkout otherbranch -- path/to/myfile.txt- Він копіює файл у робочий каталог, але також у область інсценізації (аналогічний ефект, як якщо б ви копіювали цей файл вручну та виконувались git addна ньому). git restoreне торкається області постановки (якщо не вказано це за --stagedопцією).

git show otherbranch:path/to/myfile.txt > path/to/myfile.txtвикористовує стандартне перенаправлення оболонки. Якщо ви використовуєте Powershell, то може виникнути проблема із вкладенням тексту або ви можете отримати зламаний файл, якщо він є двійковим . Зі git restoreзміною файлів все виконується gitвиконуваним файлом.

Ще одна перевага полягає в тому, що ви можете відновити всю папку за допомогою:

git restore --source otherbranch path/to

або з, git restore --overlay --source otherbranch path/toякщо ви хочете уникати видалення файлів. Наприклад, якщо файлів менше, otherbranchніж у поточному робочому каталозі (і ці файли відслідковуються ), без --overlayможливості git restoreбуде видалено їх. Але це добре поведінка за замовчуванням, ви, швидше за все, хочете, щоб стан каталогів був таким самим, як у otherbranch, а не "те саме, але з додатковими файлами в моєму поточному відділенні"


Гарна відповідь. Чи є git restoreспосіб скопіювати файл із вихідної гілки в новий файл на цільовій гілці? За допомогою git show я можу це зробити з перенаправленням оболонки ( git show otherbranch:path/to/file1.txt > path/to/file2.txt), але я хочу уникати перенаправлення оболонок з причин, про які ви згадали.
АдміралАдама

1
@AdmiralAdama не дуже. І я думаю, що немає великого шансу потрапити в це git restore(але хто знає;)). Це питання перенаправлення - це проблема Powershell, не впевнений, чи є якась інша оболонка, яка має з цим проблему. Зазвичай я повертаюся до "git bash" або навіть "cmd", де мені потрібно використовувати команди " git showз перенаправленням". Або використовуйте графічний інтерфейс, наприклад GitExtensions, де ви можете переглядати дерево файлів фіксації та натиснути «Зберегти як» у будь-якому файлі.
Маріуш Павельський

А, бачу. Я не використовую Powershell, тому, можливо, для мене перенаправлення оболонки є np. Дякую за інформацію.
АдміралАдама

3

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

Git копіює файл з іншої гілки, не встановлюючи його

Поетапні зміни (наприклад git add filename):

$ git checkout directory/somefile.php feature-B

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   directory/somefile.php

Завершені зміни (не інсценовані чи вчинені):

$ git show feature-B:directory/somefile.php > directory/somefile.php

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   directory/somefile.php

no changes added to commit (use "git add" and/or "git commit -a")

Я отримую "особливість-B не файл", ім'я гілки спочатку спочатку, про це -> "> каталог / somefile.php" може це змінити кодування файлу?
Тіаго Олівейра де Фрейтас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.