Подтвердить что ты не робот

Несколько промежуточных площадок

Могу ли я иметь несколько промежуточных областей или добиться аналогичного эффекта с помощью git?

Мой типичный рабочий поток идет по строкам:

  • работа, работа, работа
  • Теперь у меня есть идея о чем-то полезном, допустим commit git add -p, y, y
  • но сначала эти меньшие изменения стиля: git reset HEAD .
  • git add -p, n, n, y, q, git commit -m "style changes"
  • git add -p.. зафиксировать фактическую вещь

Иногда у меня есть 20 небольших коммитов, чтобы сделать из огромной кучи изменений. Это спасло бы меня несколько часов в день, если бы я мог пробежать патчи типа git add -p, а затем "отправить" каждый патч в свою собственную зону постановки и совершить каждую область отдельно.

4b9b3361

Ответ 1

На самом деле вы можете иметь несколько разных промежуточных областей (в буквальном смысле, несколько индексных файлов) в git. Чтобы достичь желаемого эффекта, вам все равно придется написать свой собственный вариант git add -p, поэтому я буду делать набросок, как бы это сделать.

Индексный файл по умолчанию - тот, который использует git, если вы не указываете его в какой-либо другой индексный файл - находится в .git/index (или, более корректно в оболочке, $GIT_DIR/.index где $GIT_DIR взят из среды или если не установлен там, из git rev-parse --git-dir).

Однако если вы установите переменную среды GIT_INDEX_FILE, git будет использовать этот файл вместо индекса. Таким образом, вы можете начать процесс "разброса изменений на четыре ветки", выполнив что-то вроде этого:

GIT_DIR=${GIT_DIR:-$(git rev-parse --git-dir)} || exit 1
index_tmp_dir=$(mktemp -d) || exit 1
trap "rm -rf $index_tmp_dir" 0 1 2 3 15 # clean up on exit

# make four copies of initial staging area
for f in i1 i2 i3 i4; do
    cp $GIT_DIR/index $index_tmp_dir/$f
done

# THIS IS THE HARD PART:
# Now, using 'git diff-files -p' or similar, get patches
# (diff hunks).
# Whenever you're ready to stage one, pick an index for it,
# then use:
GIT_INDEX_FILE=$index_tmp_dir/$which git apply --cached < diffhunk

# Once done, commit each index file separately with some
# variation on:
for f in i1 i2 i3 i4; do
    GIT_INDEX_FILE=$index_tmp_dir/$which git commit
done

Для части с надписью "трудная часть" лучше всего скопировать perl-скрипт git add-interactive, находящийся в $(git --exec-path)/git-add--interactive, а затем изменить его так, чтобы он подходил, Чтобы снять ограничение "ровно четыре коммита", сделайте так, чтобы это измененное интерактивное добавление динамически создавало новый индексный файл (путем копирования оригинала или, возможно, создания "пустого" индекса, равного HEAD или как угодно; см. git read-tree как Что ж).

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