Как мне открыть файл из другой ветки git?

35

Я хотел бы открыть файл из другой ветки в текущем хранилище git. Я видел этот вопрос SO , но предложения по его объединению с Vim громоздки (передача в Vim, открытие stdin, установка типа файла и т. Д. Вручную). Есть ли более простой способ сохранить подсветку синтаксиса, настройки типов файлов и т. Д.?

Если это поможет:

  • У меня установлен беглый плагин (хотя используется редко).
  • Мне не нужно изменять это.

Файл может быть файлом для текущего открытого буфера или другим.

Мур
источник

Ответы:

49

Вы можете использовать :Gedit/ :Gsplit/ :Gvsplit/ ... с формой{revision}:{filename}

:Gedit branch:/foo/bar.c

Примечание: Если файл является тем же, что и текущий файл , вы можете сократить команду следующим образом: :Gsplit branch:%.

Часто бывает предпочтительнее использовать diff текущего файла, чем просто открыть файл в другой ветке. Вы можете сделать это через :Gdiff {branch}.

Для получения дополнительной помощи см .:

:h fugitive-:Gedit
:h fugitive-revision
:h fugitive-:Gdiff
:h c_%

Вы также можете проверить эпизоды Vimcasts в серии « Беглецы» .

Питер Ринкер
источник
Прекрасный! Любопытно: что произойдет, если я изменю файл, открытый таким образом?
Муру
1
@muru Вы заметите, что буфер открыт в буфере только для чтения (вероятно, обратите внимание [RO]на строку состояния).
Питер Ринкер,
да, это там.
Муру
fugitiveнужен путь от корня хранилища. Ответ уже покрывает это, но я ошибочно предположил, что беглец мог понять, когда мы находимся в определенном подкаталоге репо.
Пасхалис
удивительно .. впервые использую беглеца .. хотя у меня его долго устанавливали :)
alpha_989
14

Это немного шире, чем то, что просил OP, но для людей, не желающих использовать плагины и, возможно, другие системы контроля версий, этот небольшой фрагмент имеет тенденцию работать довольно хорошо:

:new
:r! git show branch:file
:1d

Он создает новое окно и показывает там файл, считывая вывод данной команды в новый буфер. Это, конечно, работает с любой внешней командой, а не только с git.

Пример для bzr (где синтаксис REV может указывать ветку):

:new
:r! bzr cat -r REV file
:1d

Пример для hg (не уверен насчет веток в hg; не используйте его достаточно)

:new
:r! hg cat -r REV file
:1d

Пример для SVN (

:new
:r! svn cat file@REV
:1d

Вы все еще, вероятно, захотите установить тип файла для подсветки синтаксиса, как в сообщениях SO, но, по крайней мере, вам не нужно возиться с трубопроводами.

Открыв его, вы можете сохранить его под новым именем с помощью :w filenameили :saveas filename, поскольку у Vim еще не будет имени файла. Если вы не хотите иметь возможность редактировать его, вы также можете добавить :setlocal readonlyи и / или :setlocal nomodifiable.

Редактировать: Автоматический тип файла

Это немного больше работы, но вы можете попросить Vim угадать тип файла с

:filetype detect

Но, поскольку у Vim еще нет имени, это не всегда работает хорошо (например, я вытащил некоторый C-код, и он догадался filtype=conf.

Мы можем дать ему имя, сохранив его, но мы не хотим перезаписывать возможно существующий файл. Мы также можем просто установить имя файла (Спасибо @PeterRincker!), Но опять же, мы не хотим рисковать коллизиями. Так как маловероятно, что существует файл, который является как отчеством, так и именем файла вместе, мы объединяем их с некоторым произвольным разделителем

:exe "silent file " . "branch" . "-" . "file"
:filetype detect

Где "file"заменяется фактическим именем файла и "branch"именем ветви

Конечно, на данный момент мы почти пишем плагин ;-)

Подводя итог всему этому, вот как специфическая функция git, которую вы можете добавить в свой vimrc:

function! GitFile(branch,file)
    new
    exe "silent r! git show " . a:branch . ":" . a:file
    1d
    exe "silent file " . a:branch . "-" . a:file
    filetype detect
    setlocal readonly     "don't allow saving
    setlocal nomodified   "allow easy quitting without saving
    setlocal nomodifiable "don't allow modification
endfunction

который вы можете заключить в команду или вызвать непосредственно, например call GitFile("whateverBranch","myfile.c"). Вы получите новое окно с буфером с именемwhateverBranch-myfile.c

Джон О'М.
источник
И можно ли заставить его автоматически определять тип файла, синтаксис и т. Д. Этим методом?
Муру
К сожалению, не без дополнительной работы; Я обновил пост
Джон ОМ.
1
Я рекомендую использовать метод плагина из поста @ PeterRinker, если можете. Он должен делать много хороших вещей, которые вы хотели бы. В основном я хотел показать, что не нужно выходить из редактора и не сталкиваться с трудностями, связанными с передачей данных, и я знаю, что есть люди, которые ненавидят использование плагинов.
Джон ОМ.
1
Я просто добавил немного, чтобы можно было определить тип файла. Это больше не то, что вы хотели бы просто набирать на лету, но могло бы работать как простое дополнение к .vimrc. Использование определенного плагина все еще, вероятно, будет работать лучше.
Джон ОМ.
Возможно, вы захотите изучить использование :fileимени файла вместо временного файла. Смотрите:h :file
Питер Ринкер