У меня есть две ветви, которые полностью объединены.
Однако после того, как слияние выполнено, я понимаю, что один файл был испорчен слиянием (кто-то другой выполнил автоматическое форматирование, угадай), и было бы проще перейти на новую версию в другой ветке, и затем повторно вставьте мое изменение одной строки после его переноса в мою ветку.
Так какой же самый простой способ сделать это в git?
Запустите это из ветки, в которой вы хотите, чтобы файл закончился:
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
Но не перезапишет ли это все ваши изменения в мастере?
Да, было бы. Но это было целью вопроса.
Вероятно, очевидно, но вам нужно использовать полное имя файла ... Подстановочные знаки не работают!
Есть ли такой удобный способ «скопировать» файл из определенного коммита (не из ветки, как показано в этом ответе)?
хотя .. это тоже хороший способ: git show commit_id: path / to / file> path / to / file
@Chris Hart Подстановочные знаки не работают, но относительные пути работают. Полное имя файла не всегда необходимо :)
удаленный: git checkout origin / otherbranch myfile.txt
@ user1448031 по запросу, я полагаю, вы имеете в виду, что файл существует в удаленной ветке? git checkout <remote_name>/<branch_name> <file>
должен работать (git checkout upstream/foo myfile.txt
должен «вытащить» myfile.txt из исходного репозитория разветвленного репо в ваш локальный в текущей ветке).
Есть ли способ сказать git не обрабатывать файлы, показанные таким образом? Я просто хочу, чтобы он обновлял мою рабочую копию, а не индекс.
Для будущих недосыпающих людей не забудьте полный путь к файлу: git checkout otherbranch path/to/myfile.txt
.
Это решение отлично подходит для зафиксированных файлов, но есть ли способ скопировать рабочий файл в новую ветку? Конечно, дилемма состоит в том, что вы вынуждены фиксировать или хранить файл, прежде чем сможете переключать ветки. Иногда я нахожусь в процессе написания кода и вижу выгоду от помещения текущей рабочей версии этого файла в другую ветку.
@jefflab, согласно быстрому тесту с v2.3.3, достаточно указать только относительный путь. Более того, предполагая, что каталог такой же, необходимо указать как минимум только имя файла.
Должен ли я после выполнения проверки явно отключить HEAD
, чтобы я мог повторно добавить и зафиксировать для включения в свое собственное сообщение фиксации?
Использование подстановочных знаков действительно работает, вам просто нужно обернуть их ''
, чтобы они не интерпретировались оболочкой.
Вы сэкономили день!
Это замечательно, но, похоже, не работает для удаленных файлов. Например, предположим, что у вас есть ветки a
и b
с идентичными папками foo/
(и идентичным содержимым папки): если вы удалите файл из папки foo/
в ветке a
, а затем checkout a foo/
в ветке b
(в которой есть тот же файл), никаких изменений не произойдет. применено: файл останется на месте в ветке b
.
Если между обеими ветвями есть промежутки, создаст ли это действие конфликты позже, если вы объединитесь?
Как насчет использования команды проверки:
git diff --stat "$branch"
git checkout --merge "$branch" "$file"
git diff --stat "$branch"
примечание слияние (2-я команда) не может работать, если файл не существует в обеих ветвях
Хм. У меня нет diffstat. Это конкретная версия инструмента сравнения, потому что я никогда о нем не слышал (и должен ли я переключиться на него?): D
git diff
поддерживает аргумент --stat
, который в основном делает то же самое, что и diffstat.
Мне пришлось проверить обе ветки локально, чтобы это работало.
Я пришел к этому вопросу при аналогичном поиске. В моем случае я хотел извлечь файл из другой ветки в текущий рабочий каталог, который отличался от исходного местоположения файла. Отвечать:
git show TREEISH:path/to/file > path/to/local/file
Цель «git show» - выводить данные на терминал в удобочитаемом формате, который не гарантирует точное соответствие содержимому файла. Так же, как лучше скопировать текстовый документ целиком, а не пытаться скопировать и вставить его содержимое в другой документ.
Я просто хотел просмотреть его, чтобы сравнить содержимое с текущей веткой (проверьте какой-нибудь фрагмент кода). Я бы хотел использовать vim с этим ... для подсветки синтаксиса и т. д.
git diff <other branch> <path to file>
подходит для сравнения содержимого перед оформлением заказа.
@Gonen: Начиная с версии git 2.21.0, на странице руководства "git show" написано: "Для простых BLOB-объектов отображается простое содержимое". Я не уверен, означает ли это, что мы всегда в порядке Я немного опасаюсь получать изображение таким образом ...
Следуя ответу madlep, вы также можете просто скопировать один каталог из другой ветки с каталогом blob.
git checkout other-branch app/**
Что касается вопроса оператора, если вы изменили только один файл, это будет работать нормально ^ _ ^
Обратите внимание, что сначала необходимо правильно вытащить обе ветви или использовать origin/other-branch
для ссылки на ветку репо. Основы, но укусил меня. (ответ отличный - редактирования не требуется)
1) Убедитесь, что вы находитесь в ветке, где вам нужна копия файла.
например: я хочу, чтобы файл вспомогательной ветки был в главном, поэтому вам нужно оформить заказ или он должен быть в главном git checkout master
2) Теперь проверьте только конкретный файл, который вы хотите из подчиненной ветки в мастер,
git checkout sub_branch file_path/my_file.ext
здесь sub_branch
означает, где у вас есть этот файл, за которым следует имя файла, которое вам нужно скопировать.
Очень удобно и хорошо объяснено.
Обратите внимание, что в принятом ответе первый параметр этапы весь файл из другой ветки (например, был выполнен 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")
Я получаю "feature-B не файл", имя ветки идет первым, об этом -> "> directory / somefile.php" может ли это изменить кодировку файла?
Я бы использовал 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
», а не «таким же, как в otherbranch
, но с дополнительными файлами из моей текущей ветки»
Хороший ответ. Есть ли способ git restore
скопировать файл из исходной ветки в файл новый в целевой ветке? С помощью git show я могу сделать это с помощью перенаправления оболочки (git show otherbranch:path/to/file1.txt > path/to/file2.txt
), но я хочу избежать перенаправления оболочки по причинам, которые вы упомянули.
@AdmiralAdama не совсем. И думаю, что в git restore
нет больших шансов получить его (но кто знает;)). Эти проблемы с перенаправлением в основном являются проблемой Powershell, не уверен, есть ли проблема с какой-либо другой оболочкой. Обычно я возвращаюсь к «git bash» или даже к «cmd», где мне нужно использовать команды «git show
с перенаправлением». Или используйте графический интерфейс, например GitExtensions, где вы можете просмотреть дерево файлов фиксации и нажать «Сохранить как» для любого файла.
Ах я вижу. Я не использую Powershell, поэтому, возможно, перенаправление оболочки для меня np. Спасибо за информацию.
Обратите внимание, что в принятом ответе первое решение вносит изменения, а второе - нет. stackoverflow.com/a/56045704/151841