Git: Добавить часть (измененного) файла в индекс * по номерам строк * - PullRequest
7 голосов
/ 06 мая 2010

Существует ли команда git для добавления различий в диапазоне номеров строк к индексу?

Я хочу иметь возможность выбирать строки в моем редакторе и запускать макрос, чтобы добавить любые изменения в выборке в индекс.

Ответы [ 4 ]

17 голосов
/ 07 мая 2010

Если вы можете убедить своего редактора написать версию файла, который вы хотите подготовить, вы можете использовать команды git уровня слесарного дела, чтобы добавить его в индекс под правильным именем. Вам нужно обойти «git add», который всегда будет связывать путь X в рабочем дереве с путем X в индексе (насколько я знаю).

Когда у вас есть содержимое, которое вы хотите записать во временный файл $ tempfile, запустите git hash-object -w $tempfile - это запишет объект в .git / objects и выведет идентификатор blob. Затем передайте этот идентификатор BLOB-объекта в индекс, используя git update-index --cacheinfo 100644 $blobid $path, чтобы связать путь $ path с этим объектом.

Вот пример, в котором происходит изменение сценария с именем «post_load» в моем репозитории без перезаписи самого файла (также демонстрируется, что вы можете обойтись без временного файла):

git update-index --cacheinfo 100755 $(perl -lne 'print unless (/^#/)' post_load \
                                      | git hash-object -w --stdin) post_load

Вы не упоминаете, из какого редактора вы планируете делать это, поэтому сложно посоветовать вам, как интегрировать это. Как я уже упоминал, вам нужно как-то представить git вместе с файлом так, как вы хотите, чтобы он был подготовлен (помните, что git не имеет дело с сохранением изменений). Если вы можете написать макрос, чтобы просто сохранить файл как «$ file.tmp», тогда используйте что-то подобное выше git update-index --cacheinfo $the_mode $(git hash-object -w $file.tmp) $file (получение $ the_mode оставлено в качестве упражнения: p), удалите $ file.tmp и отмените буфер редактора возвращается к $ file, который будет делать то, что вы просите.

Например, следующий скрипт принимает три аргумента: M N path. Он обновит содержимое индекса для файла по «пути», так что строки от M до N (включительно) будут заменены содержимым из stdin:

#!/bin/sh

start_line=$1
end_line=$2
path=$3

mode=$(git ls-files -s $path | awk '{print $1}')
blob_id=$(
    (
        head -n $(expr $start_line - 1) $path
        cat
        tail -n +$(expr $end_line + 1) $path
        ) | git hash-object -w --stdin
    )
exec git update-index --cacheinfo $mode $blob_id $path

например echo "HELLO WORLD" | ./stage-part 8 10 post_load заменит три строки из 8-10 просто "HELLO WORLD".

3 голосов
/ 06 мая 2010

Самый простой способ сделать это в настоящее время - git add в интерактивном режиме:

git add -i path/to/file

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

2 голосов
/ 18 марта 2016

По моему опыту, git-cola отлично справляется с этой задачей. Хотелось бы, чтобы он поддерживал интеграцию с Atom ...

0 голосов
/ 07 мая 2010

Ближайший готовый инструмент, который делает что-то подобное, это git gui citool. Он не работает напрямую в вашем редакторе (не все редакторы имеют полезные представления различий, и я подозреваю, что большинству людей, вероятно, не важно точно помнить, какие строки они изменили с момента последнего коммита, поэтому представление различий очень полезно), но кажется как будто это близко к тому, что вы хотите.

git gui citool позволяет просматривать поэтапные и нематериальные изменения в представлениях, которые эквивалентны git diff --cached и git diff соответственно.

При просмотре неотмеченных изменений в контекстном меню (щелчок правой кнопкой мыши) есть параметры для размещения выбранных строк (или строки, по которой щелкают, если выбора нет), и параметр для создания целого блока. Аналогично, при просмотре поэтапных изменений в контекстном меню есть параметры для удаления строк или фрагмента.

Чтобы получить больше контекста, вы можете использовать пункт меню «Показать больше контекста» (или «Показать меньше контекста», если хотите уменьшить блоки).

После того, как вы подготовили новый контент, вы также можете составить сообщение о коммите и сделать коммит из GUI.

Я полагаю, что некоторые люди используют git gui в таком рабочем процессе:

  1. Используйте интерфейс командной строки для добавления новых отслеживаемых файлов и удаления старых файлов (различные параметры для git add).
  2. Редактирование отслеживаемых файлов в вашем любимом редакторе / окружении.
  3. В git gui выберите «Повторное сканирование», просмотрите изменения, внесите некоторые изменения в стадию и, в конце концов, подтвердите их.
  4. [повтор]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...