'git add --patch' для включения новых файлов?

105

Когда я бегу git add -p, есть ли способ для git выбрать недавно созданные файлы в качестве фрагментов для выбора?

Поэтому, если я создам новый файл с именем foo.java, а затем запустите git add -p, git не позволит мне выбрать содержимое этого файла для добавления в индекс.

Александр Берд
источник

Ответы:

78

Чтобы сделать это с каждым новым файлом, вы можете запустить:

git add -N .
git add -p

Если вы хотите использовать его часто, вы можете создать псевдоним в своем ~/.bashrc:

alias gapan='git add --intent-to-add . && git add --patch'

NB : если вы используете это с пустым новым файлом, git не сможет исправить его и перейти к следующему.

Ulysse BN
источник
13
Для тех, кому интересно, что git add -Nделает, он просто добавляет указанные неотслеживаемые файлы в индекс, но без содержимого.
Odin
112

Когда я пробовал git add -p someNewFile.txtновый файл (неотслеживаемый файл), git просто выводил No changes.и останавливался. Мне пришлось сказать git, что я намереваюсь сначала отследить новый файл.

git add -N someNewFile.txt
git add -p

Однако, поскольку файл не отслеживался, он отображался как один гигантский кусок, который нельзя было разделить (потому что он все новый!). Итак, мне нужно было отредактировать кусок на более мелкие части. Если вы не знакомы с этим, ознакомьтесь с этой ссылкой, чтобы начать работу.

Обновление - информация о редактировании фрагмента. Я хотел обновить это на случай, если указанная выше ссылка исчезнет. Поскольку новый файл не отслеживается, git add -pкаждая строка в файле будет отображаться как новая строка в одном фрагменте. Затем он спросит вас, что вы хотите сделать с этим фрагментом, предоставив вам следующую подсказку:

Stage this hunk [y,n,q,a,d,/,e,?]?

Предполагая, что вы не хотите фиксировать весь кусок (и, следовательно, весь файл; потому что я не уверен, почему вы хотите использовать git add -pв этом случае?), Вы захотите указать параметр, eчтобы сообщить git, что вы хотите отредактировать ломоть.

Как только вы сообщите git, что хотите отредактировать кусок, он должен перетащить вас в выбранный вами редактор, чтобы вы могли внести свои изменения. Все строки должны иметь префикс a, +а #в конце файла git есть пояснительные комментарии (с префиксом a ). Просто удалите все строки, которые вам не нужны при первоначальной фиксации файла. Затем сохраните и выйдите из редактора.

Объяснение Git опций фрагментов git:

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
КошкаОбувь
источник
1
Пожалуйста, ответьте на это вкратце.
Inanc Gumus
5
В итоге, git add -N someNewFile.txtдалееgit add -p
CatShoes 08
Похоже, что в новой версии git поведение изменилось. У него нет возможности вручную редактировать текущий кусок.
Вольфганг Гриммер
7

git add -p действительно о добавлении изменений в уже отслеживаемые файлы.

Команда для интерактивного выбора файлов для добавления - git add -i. Например:

$ git add -i

*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
What now> a
  1: another-new.java
  2: new.java
Add untracked>> 2
  1: another-new.java
* 2: new.java
Add untracked>> 
added one path

*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
What now> q
Bye.
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   new.java

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        another-new.java

(Настоящая команда имеет цвета, которые я не мог вырезать и вставить здесь, так что это лучше, чем кажется)

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

Матье Мой
источник
"Признаюсь, я люблю add -p и ненавижу add -i!" Вот почему мне нравится git add then patch: он по-прежнему позволяет вам проверять содержимое новых файлов, которые вы добавляете (поскольку вы сравниваете их с их пустыми версиями), и исправлять файлы, которые вы редактировали!
Ulysse BN
Пожалуйста, поправьте меня, если я ошибаюсь, но даже здесь, в интерактивном режиме, патч все равно будет выводиться No changes.в новом файле. OP спрашивал, как добавить фрагменты из нового файла, а не всего файла. Я считаю, что --intent-to-addздесь все еще требуется.
Джефф Пакетт
add -pсам по себе не сработает, но этот ответ предполагает add -i, что это так.
Matthieu Moy
Я голосую за, потому что не знал о git add -i. Однако вы можете делать то же самое не интерактивно с git add -N.
Mad Physicist
5

Также есть очень похожий подход с использованием --cachedфлага ...

1) Превратите ваши неустановленные изменения в поэтапные, как и ваш добавленный файл.

git add edited-file.txt
git add new-file.txt
git add directory-of-changes/

2) Посмотрите на разницу (примечание: вы можете включать как правки, так и новые файлы).

git diff --cached

3) Создайте патч.

git diff --cached > my_patch_file.patch
даблджош
источник
К сожалению, это не приведет к той же цели. Что мне нравится, так git add -pэто то, что он не добавляет все, но позвольте мне выбрать то, что я хочу добавить. Это решение слепо добавляло бы все.
Александр Берд
Вы можете выбрать, что добавить! Обновлю ответ.
doublejosh
1
спасибо: allthethings: у меня это работает потрясающе
macool
1

Ответ Catshoes включает:

Когда я пробовал git add -p someNewFile.txtновый файл (неотслеживаемый файл), git просто выводил Без изменений. и остановись.
Мне пришлось сказать git, что я намереваюсь сначала отследить новый файл.

git add -N someNewFile.txt
git add -p

Это должно скоро измениться с выходом Git 2.29 (4 квартал 2020 г.).

Последние версии « git diff-files» ( man ) показывают разницу между индексом и рабочим деревом для путей «с намерением добавить» как патч «новый файл»;
" git apply --cached" ( man ) должен иметь возможность принимать " git diff-files" и действовать как эквивалент " git add" для пути, но команда не смогла этого сделать для такого пути.

См. Коммит 4c025c6 , коммит e3cc41b (8 августа 2020 г.) и коммит 7cfde3f (6 августа 2020 г.) Раймонда Э. Паско ( juped) .
(Объединено Junio ​​C Hamano - gitster- в коммите ca81676 , 17 августа 2020 г.)

apply: разрешить патчи "новый файл" в записях ita

Помощник: Джунио С. Хамано.
Подпись: Раймонд Э. Паско.

diff-files недавно изменено, чтобы рассматривать изменения в путях, помеченных как «намерение добавить» в индексе, как изменения в новом файле, а не в отличие от пустого большого двоичного объекта.

Однако applyотказывается применять новые различия файлов поверх существующих записей индекса, за исключением случая переименований.
Это приводит к сбою " git add -p" ( man ) , использующего apply, при попытке подготовить фрагменты из файла, когда было записано намерение добавить.

Это изменяет логику, в check_to_create()которой проверяется, существует ли запись в индексе двумя способами:

  • во-первых, мы ищем индексную запись, только если ok_if_existsона ложна;
  • во-вторых, мы проверяем наличие CE_INTENT_TO_ADDфлага на всех найденных нами элементах указателя и разрешаем продолжить применение, если он установлен.
VonC
источник
какие-нибудь обновления по этому поводу? Я использую git версии 2.28.0, и он не работает с git add -N + git add -pручным редактированием
ханков
1
@ The.Wolfgang.Grimmer Еще нет: 2.29 выйдет через несколько недель.
VonC