Зафиксировать только часть файла в Git
Когда я делаю изменения в файле в Git, как я могу зафиксировать только некоторые изменения?
Например, как я могу зафиксировать только 15 строк из 30 строк, которые были изменены в файле?
29 ответов
Ты можешь использовать git add --patch <filename>
(или же -p
для краткости), и git начнет разбивать ваш файл на то, что он считает разумными "кусочками" (частями файла). Затем он подскажет вам этот вопрос:
Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?
Вот описание каждой опции:
- у подготовить этот кусок для следующего коммита
- n не ставить этот кусок для следующего коммита
- q выход; не ставьте этот кусок или любой из оставшихся кусков
- сцена этот кусок и все последующие фрагменты в файле
- не ставить этот кусок или любой другой более поздний фрагмент в файле
- г выберите лом, чтобы перейти к
- / искать кусок, соответствующий заданному регулярному выражению
- j оставить этот кусок нерешенным, увидеть следующий нерешенный кусок
- J оставить этот кусок нерешенным, увидеть следующий кусок
- k оставить этот кусок нерешенным, см. предыдущий нерешенный кусок
- K оставить этот кусок нерешенным, см. Предыдущий кусок
- разделить текущий кусок на более мелкие фрагменты
- e вручную редактировать текущий блок
- ? распечатать справку
Если файл еще не находится в хранилище, вы можете сначала сделать git add -N <filename>
, После этого вы можете продолжить git add -p <filename>
,
После этого вы можете использовать:
git diff --staged
чтобы убедиться, что вы поставили правильные измененияgit reset -p
расшатать ошибочно добавленные кускиgit commit -v
чтобы просмотреть ваш коммит во время редактирования сообщения о коммите.
Обратите внимание, что это сильно отличается от git format-patch
команда, целью которой является анализ данных фиксации в .patch
файлы.
Ссылка на будущее: Git Tools - Интерактивная постановка
Ты можешь использовать git add --interactive
или же git add -p <file>
, а потом git commit
(не git commit -a
); см. Интерактивный режим на странице руководства git-add или просто следуйте инструкциям.
Modern Git также имеет git commit --interactive
(а также git commit --patch
, который является ярлыком для опции исправления в интерактивном коммите).
Если вы предпочитаете делать это из GUI, вы можете использовать git-gui. Вы можете просто пометить чанки, которые хотите включить в коммит. Я лично нахожу это проще, чем использовать git add -i
, Другие графические интерфейсы git, такие как QGit или GitX, также могут иметь эту функцию.
git gui предоставляет эту функциональность в представлении diff. Просто щелкните правой кнопкой мыши на строке (строках), которая вас интересует, и вы должны увидеть пункт меню "подготовить эту строку для фиксации".
Я полагаю, что git add -e myfile
это самый простой способ (по крайней мере, мои предпочтения), поскольку он просто открывает текстовый редактор и позволяет вам выбрать, какую строку вы хотите поставить, а какую - нет. По поводу команд редактирования:
добавленный контент:
Добавленный контент представлен строками, начинающимися с "+". Вы можете предотвратить размещение любых добавочных строк, удалив их.
удаленный контент:
Удаленный контент представлен строками, начинающимися с "-". Вы можете предотвратить постановку их удаления, преобразовав "-" в " " (пробел).
измененный контент:
Модифицированный контент представлен строками "-" (удаление старого контента), за которыми следуют строчки "+" (добавление контента замены). Вы можете предотвратить внесение изменений, преобразовав строки "-" в "" и удалив строки "+". Помните, что изменение только половины пары может привести к непонятным изменениям в индексе.
Каждая деталь о git add
доступны на git --help add
Если вы используете VSCode, то вам повезло. Выберите диапазон, который вы хотите подготовить, затем используйте
Git: Stage Selected Ranges
поставить их и зафиксировать, если хотите.
Я записал гифку, чтобы продемонстрировать, что имел в виду:
Если вы используете vim, вы можете попробовать отличный плагин под названием fugitive.
Вы можете увидеть различие файла между рабочей копией и индексом с помощью :Gdiff
, а затем добавьте строки или фрагменты в индекс, используя классические команды vim diff, такие как dp
, Сохраните изменения в индексе и подтвердите :Gcommit
, и вы сделали.
Стоит отметить, что использовать git add --patch
для нового файла необходимо сначала добавить файл в индекс с помощью git add --intent-to-add
:
git add -N file
git add -p file
Я настоятельно рекомендую использовать SourceTree от Atlassian. (Это бесплатно.) Это делает это тривиальным. Вы можете быстро и легко создавать отдельные фрагменты кода или отдельные строки кода.
Когда у меня будет много изменений, и в итоге я создам несколько коммитов из изменений, я хочу временно сохранить свою начальную точку, прежде чем ставить вещи.
Как это:
$ git stash -u
Saved working directory and index state WIP on master: 47a1413 ...
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 1st commit"
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 2nd commit"
$ git stash pop
Ответ Whymarrh - то, что я обычно делаю, за исключением того, что иногда происходит много изменений, и я могу сказать, что могу ошибиться при постановке вещей, и я хочу зафиксированное состояние, к которому я могу прибегнуть для второго прохода.
Intellij IDEA (и, я думаю, все остальные продукты серии) имеет встроенную поддержку частичных коммитов начиная с v2018.1
Добавляя предыдущий ответ, если вы предпочитаете использовать командную строку, введите git add -e myfile
дает вам возможность выбирать построчно то, что вы хотите зафиксировать, потому что эта команда откроет редактор с различиями, например так:
Как вы знаете, строки, начинающиеся с +
это дополнения, строки, которые начинаются с -
Это удаления. Так:
- Чтобы не ставить дополнение, просто удалите эту строку.
- Чтобы не удалять, просто замените
-
с пространством,
Это то, что git add -h
говорит о добавлении файлов таким образом (исправление файлов):
добавленный контент Добавленный контент представлен строками, начинающимися с "+". Вы можете предотвратить размещение любых добавочных строк, удалив их.
удаленный контент: удаленный контент представлен строками, начинающимися с "-". Вы можете предотвратить постановку их удаления, преобразовав "-" в "" (пробел).
Модифицированный контент: Модифицированный контент представлен линиями "-" (удаление старого контента), за которыми следуют строки "+" (добавление контента замены). Вы можете предотвратить внесение изменений, преобразовав строки "-" в "" и удалив строки "+". Помните, что изменение только половины пары может привести к непонятным изменениям в индексе.
Внимание: не изменяйте содержимое файла, это не самое подходящее место для этого. Просто поменяйте операторы удаленных или добавленных строк.
Если вы используете emacs, взгляните на Magit, который предоставляет интерфейс git для emacs. Он поддерживает постановку фрагментов (частей файлов) довольно хорошо.
Для тех, кто использует Git Extensions:
В окне "Фиксация" выберите файл, который вы хотите частично зафиксировать, затем выделите текст, который вы хотите зафиксировать, на правой панели, затем щелкните правой кнопкой мыши выделенную область и выберите "Поместить выделенные строки" в контекстном меню.
Во-первых, мы можем посмотреть, в чем заключаются изменения.
git diff <file>
Если он отображается в разных частях, мы можем использовать
git add -p <file>
путем принятия или отклонения изменений (y или n).
Если нет, мы все равно можем сделать это с помощью VS Code.
Прошло 10 лет с тех пор, как этот вопрос был задан. И я надеюсь, что этот ответ будет кому-то полезен. Как уже упоминалось в ответе, где GUI не является опцией, расширение crecord Эндрю Шадуры помогает открыть окно ncurses, в котором мы можем выбрать строки для фиксации.
Настройте расширение следующим образом:
git clone https://github.com/andrewshadura/git-crecord
cd git-crecord
./setup.py install
ln -s $PWD/git-crecord ~/.local/bin/git-crecord
Перейдите к вашему git-репо и вызовите его следующим образом:
git crecord
Это вызовет интерфейс ncurses, который можно использовать, как показано ниже. Нажатие следующих клавиш в окне ncurses выполнит определенные действия:
f hunk toggle fold (arrow keys can also be used)
space toggle hunk selection
a toggle commit or amend
c confirm and open commit window
Скриншот, показывающий пример использования
Так же, как и в ответе jdsumsion, вы можете также спрятать свою текущую работу, но затем использовать difftool, как meld, чтобы извлечь выбранные изменения из тайника. Таким образом, вы даже можете легко редактировать фрагменты вручную, что немного затруднит git add -p
:
$ git stash -u
$ git difftool -d -t meld stash
$ git commit -a -m "some message"
$ git stash pop
Использование метода stash дает вам возможность проверить, работает ли ваш код, до того, как вы его подтвердите.
Плагин vim-gitgutter может ставить фрагменты, не выходя из редактора vim с помощью
:GitGutterStageHunk
Помимо этого, он предоставляет другие интересные функции, такие как столбец различий, как в некоторых современных средах разработки.
Если только часть ломоть должна быть организована vim-беглец
:Gdiff
позволяет визуальный выбор диапазона :'<,'>diffput
или же :'<,'>diffget
поставить / отменить отдельные изменения строки.
С TortoiseGit:
щелкните правой кнопкой мыши на файле и используйте
Context Menu → Restore after commit
, Это создаст копию файла как есть. Затем вы можете отредактировать файл, например, в TortoiseGitMerge и отменить все изменения, которые вы не хотите фиксировать. После сохранения этих изменений вы можете зафиксировать файл.
Опробовал git add -p filename.x
, но на Mac я обнаружил, что gitx ( http://gitx.frim.nl/ или https://github.com/pieter/gitx) гораздо проще зафиксировать именно те строки, которые я хотел.
Для пользователей Atom пакет github включает в себя интерактивную постановку в стиле git gui
, Для ярлыков см. Документацию пакета.
Использование Atom позволяет работать с темой с темным фоном (по умолчанию git gui
имеет белый фон).
Из комментариев к этому ответу 2018 года :
Жаль, что в Visual Studio нет такой возможности.
Около 10 лет назад альтернативная система управления версиями Mercurial поддерживала эту функцию внутри Visual Studio. Я действительно скучаю по нему, так как я использую Git.
Сейчас (август 2022 г.) поддерживается:
Git Line-staging выпущен!
Мы рады объявить о выпуске поддержки Line-staging в Visual Studio 2022.
Построчная постановка, также известная как интерактивная постановка , позволяет разделить измененные строки кода между разными коммитами.
Line-staging также можно использовать для проверки ваших изменений перед их фиксацией. Отметьте измененные строки или разделы кода как проверенные, поместив их на промежуточную подготовку, и зафиксируйте поэтапные изменения, когда закончите.Начните использовать Line-staging, обновив Visual Studio 2022 до версии 17.3 или более поздней.
Прочтите нашу документацию по линейному размещению , чтобы узнать больше о том, как использовать и настраивать эту функцию.
Я хочу добавить lazygit в список инструментов. Это приятный интерфейс командной строки (т.е. работает через ssh, даже если перенаправление X запрещено). Он имеет обширные функциональные возможности (например, выбор строк для фиксации, интерактивное перемещение), полезную окраску и относительно прост в использовании. Можно установить разными способами (go, conda, менеджер пакетов, ...). По-прежнему активно развивается / поддерживается.
Если это на Windows
Платформа, на мой взгляд git gui
это лучший инструмент для stage
/commit
несколько строк из unstaged
файл
1. Гуд мудрый:
- Выберите файл из
unstagged Changes
раздел - Правый клик на фрагмент кода, который нужно поставить
- Выбрать
Stage Hunk for commit
2. Линия мудрая:
- Выберите файл из
unstagged Changes
раздел - Выберите линию / линии для постановки
- Выбрать
Stage Lines for commit
3. Если вы хотите создать полный файл, кроме пары строк:
- Выберите файл из
unstagged Changes
раздел - Нажмите
Ctrl+T (Stage file to commit)
- Выбранный файл теперь перемещается в
Staged Changes
Раздел - Выберите линию / линии для постановки
- Выбрать
UnStage Lines for commit
Как показывает один ответ выше, вы можете использовать
git add --patch filename.txt
или краткая форма
git add -p filename.txt
... но для файлов, уже находящихся в вашем репозитории, в s гораздо лучше использовать флаг --patch непосредственно для команды commit (если вы используете достаточно свежую версию git):
git commit --patch filename.txt
... или, опять же, краткая форма
git commit -p filename.txt
... и затем использовать упомянутые ключи (y/n и т. д.) для выбора строк, которые будут включены в коммит.
git-meld-index - цитирование с сайта:
git-meld-index запускает meld - или любой другой git difftool (kdiff3, diffuse и т. д.) - чтобы вы могли в интерактивном режиме вносить изменения в индекс git (также известный как область подготовки git).
Это похоже на функциональность git add -p и git add --interactive. В некоторых случаях meld легче / быстрее использовать, чем git add -p. Это потому, что соединение позволяет вам, например,:
- увидеть больше контекста
- см. внутристрочные различия
- отредактируйте вручную и увидите "живые" обновления diff (обновляются после каждого нажатия клавиши)
- перейти к изменению, не произнося 'n', к каждому изменению, которое вы хотите пропустить
использование
В репозитории git запустите:
git meld-index
Вы увидите meld (или ваш сконфигурированный git difftool) с:
ВЛЕВО: временные файлы, содержащие каталоги, скопированные из вашего рабочего дерева
ВПРАВО: временный каталог с содержимым индекса. Сюда также входят файлы, которых еще нет в индексе, но которые изменены или не отслежены в рабочей копии - в этом случае вы увидите содержимое файла из HEAD.
Отредактируйте указатель (с правой стороны), пока не будете счастливы Не забудьте сохранить при необходимости.
Когда вы закончите, закройте meld, и git-meld-index обновит индекс, чтобы он соответствовал содержимому временного каталога с правой стороны от только что отредактированного meld.
git-cola - это отличный графический интерфейс, который также имеет встроенную функцию. Просто выберите линии для сцены и нажмите S. Если выбор не сделан, весь блок ставится.
Вы можете использовать Eclipse IDE, каждый измененный локальный файл можно сравнить с поэтапной областью, и в этом параллельном представлении различий вы можете выбрать, какой блок копировать из локальной в поэтапную область, или, наоборот, откатить локальное изменение с постановочная площадь.
Но есть еще кое-что :), все графические клиенты git тоже делают эту постановку фрагментов (git add -p), но ни один из тех, кого я знаю, не может этого сделать: редактировать напрямую в постановочной области, чтобы несколько изменений в той же строке или том же фрагменте могли быть более оштрафованы up (или даже записывать / удалять / обновлять материал, который никогда не существует локально), например «git add -e», работающий на уровне исправления, но без риска нарушить содержимое исправления. Более того, поскольку он работает с обычным текстовым редактором в представлении diff, у вас есть цвет синтаксиса, который поможет, и вы можете выполнять операции замены текста (изменять все типы отступов, переименовывать локальные переменные во многих местах, ...), чтобы начать отдельную фиксацию некоторых переформатируйте / рефакторинг перед фиксацией вашего «реального» изменения, но без встраивания всех изменений файлов в одну фиксацию.
Конечно, Eclipse больше ориентирован на Java, но благодаря мощному промежуточному редактору git его можно использовать и для других языков. Существует бесплатный продукт на основе Eclipse, ориентированный только на операцию git под названием GitEye: https://www.collab.net/downloads/giteye, но, похоже, не поддерживается, поэтому лучше использовать базовый дистрибутив Eclipse, например: https://www.eclipse.org / загрузки / пакеты / выпуск / 2020-12 / г / eclipse-ide-java-developers
Среди всех этих инструментов я больше всего люблю Fork (хотя и не бесплатный)!
По сравнению с другими, он очень гладкий и элегантный в использовании, нажмите кнопку рядом с мышью, чтобы выполнить постановку кусков или строк.
Другой вариант — GitKraken, веселый, но более сложный и мощный!