'git add --patch', aby dołączyć nowe pliki?

105

Kiedy uruchamiam git add -p, czy jest sposób, aby git wybierał nowo utworzone pliki jako porcje do wybrania?

Więc jeśli utworzę nowy plik o nazwie foo.java, a następnie uruchomię git add -p, git nie pozwoli mi wybrać zawartości tego pliku do dodania do indeksu.

Alexander Bird
źródło

Odpowiedzi:

78

Aby to zrobić z każdym nowym plikiem, możesz uruchomić:

git add -N .
git add -p

Jeśli chcesz go często używać, możesz utworzyć alias w ~/.bashrc:

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

NB : Jeśli użyjesz tego z pustym nowym plikiem, git nie będzie w stanie go załatać i przejść do następnego.

Ulysse BN
źródło
13
Dla każdego, kto się zastanawia, co git add -Nrobi, po prostu dodaje określone nieśledzone pliki do indeksu, ale bez zawartości.
Odin
112

Kiedy próbowałem git add -p someNewFile.txtna nowym pliku (nieśledzonym pliku), git po prostu wyświetlał No changes.i zatrzymywał się. Musiałem powiedzieć gitowi, że zamierzałem najpierw śledzić nowy plik.

git add -N someNewFile.txt
git add -p

Jednak ponieważ plik nie został prześledzony, pojawiłby się jako jeden gigantyczny kawałek, którego nie można podzielić (ponieważ jest nowy!). Musiałem więc edytować fragment na mniejsze części. Jeśli nie jesteś tego zaznajomiony, sprawdź to odniesienie, aby rozpocząć.

Aktualizacja - informacje o edycji Hunk Chciałem to zaktualizować na wypadek, gdyby powyższe odniesienie zniknęło. Ponieważ nowy plik nie jest śledzony, git add -ppokaże każdy wiersz w pliku jako nowy wiersz w jednym kawałku. Następnie zapyta Cię, co chcesz zrobić z tym kawałkiem, wyświetlając następujący monit:

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

Zakładając, że nie chcesz zatwierdzać całego kawałka (a tym samym całego pliku; ponieważ nie jestem pewien, dlaczego miałbyś chcieć użyć git add -pw tym przypadku?), Będziesz chciał określić opcję, eaby powiedzieć gitowi, że chcesz edytować przystojniak.

Gdy powiesz gitowi, że chcesz edytować fragment, powinien on przenieść Cię do wybranego edytora, abyś mógł wprowadzić zmiany. Wszystkie wiersze powinny być poprzedzone a, +a git ma #na końcu pliku kilka komentarzy wyjaśniających (z prefiksem a ). Po prostu usuń wszystkie wiersze, których nie chcesz, w początkowym zatwierdzeniu pliku. Następnie zapisz i zamknij edytor.

Git's wyjaśnienie opcji hunk gita:

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
CatShoes
źródło
1
Niech ktoś odpowie na to podsumowanie.
Inanc Gumus
5
Podsumowując, git add -N someNewFile.txta następniegit add -p
CatShoes
Wygląda na to, że w nowej wersji gita zachowanie się zmieniło. Nie ma opcji ręcznej edycji bieżącej porcji.
Wolfgang.Grimmer
7

git add -p tak naprawdę polega na dodawaniu zmian do już śledzonych plików.

Polecenie do interaktywnego wybierania plików do dodania to git add -i. Na przykład:

$ 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

(Prawdziwe polecenie ma kolory, których nie mogłem tutaj wyciąć i wkleić, więc jest ładniejsze niż się wydaje)

Właściwie komenda p atch git add -irobi to samo git add -p, więc druga jest podzbiorem pierwszej (chociaż przyznaję, że kocham add -pi nienawidzę add -isiebie!).

Matthieu Moy
źródło
„Przyznaję, że uwielbiam dodawać -p i nienawidzę dodawać -i siebie!” Właśnie dlatego git add then patch to rozwiązanie, które uwielbiam: nadal pozwala na sprawdzanie zawartości nowych plików, które dodajesz (ponieważ porównujesz je z ich pustymi wersjami) i łatanie plików, które edytowałeś!
Ulysse BN
Proszę poprawić mnie, jeśli się mylę, ale nawet tutaj, w trybie interaktywnym, poprawka będzie nadal wyświetlała No changes.nowy plik. OP pytał, jak dodać porcje z nowego pliku, a nie z całego pliku. Uważam, że --intent-to-addjest to nadal wymagane.
Jeff Puckett
add -pSamo nie zadziała, ale ta odpowiedź sugeruje add -i, że tak.
Matthieu Moy
Głosuję za, ponieważ nie wiedziałem o tym git add -i. Jednak możesz zrobić to samo bez interakcji git add -N.
Mad Physicist
5

Jest też bardzo podobne podejście z użyciem --cachedflagi ...

1) Zamień swoje niestacjonarne zmiany w staged, tak jak dodany plik.

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

2) Spójrz na różnicę (uwaga: możesz dołączyć zarówno edycje, jak i nowe pliki).

git diff --cached

3) Utwórz poprawkę.

git diff --cached > my_patch_file.patch
doublejosh
źródło
Niestety to nie spełni tego samego celu. Podoba mi się git add -pto, że nie dodaje wszystkiego, ale pozwól mi wybrać to, co chcę dodać. To rozwiązanie dodałoby wszystko na ślepo.
Alexander Bird
Możesz wybrać, co dodasz! Zaktualizuję odpowiedź.
doublejosh
1
dziękuję: wszystko: to działa dla mnie niesamowicie
macool
1

Odpowiedź Catshoes obejmuje:

Kiedy próbowałem git add -p someNewFile.txtna nowym pliku (nieśledzonym pliku), git po prostu wyświetlał Brak zmian. i stój.
Musiałem powiedzieć gitowi, że zamierzałem najpierw śledzić nowy plik.

git add -N someNewFile.txt
git add -p

To powinno się wkrótce zmienić w Git 2.29 (Q4 2020).

Najnowsze wersje " git diff-files" ( man ) pokazują różnicę między indeksem a drzewem roboczym dla ścieżek "zamierzających dodać" jako łatkę "nowego pliku";
" git apply --cached" ( człowiek ) powinien być w stanie obrać " git diff-files" i powinien działać jako odpowiednik " git add" dla ścieżki, ale polecenie nie zrobiło tego dla takiej ścieżki.

Zobacz commit 4c025c6 , commit e3cc41b (08 sierpnia 2020) i commit 7cfde3f (06 sierpnia 2020) autorstwa Raymonda E. Pasco ( juped) .
(Scalone przez Junio ​​C Hamano - gitster- w zobowiązaniu ca81676 , 17 sierpnia 2020 r.)

apply: zezwól na łatanie "nowych plików" dla wpisów ita

Z pomocą: Junio ​​C Hamano
Podpisał: Raymond E. Pasco

diff-files niedawno zmieniono, aby traktować zmiany w ścieżkach oznaczonych jako „zamiar dodania” w indeksie jako nowe pliki różnicowe zamiast różnic z pustego obiektu BLOB.

Jednak applyodmawia stosowania nowych plików różnicowych na podstawie istniejących wpisów indeksu, z wyjątkiem przypadków zmiany nazw.
Powoduje to, że " git add -p" ( man ) , który używa Apply, kończy się niepowodzeniem podczas próby przygotowania porcji z pliku, gdy intencja dodania została zarejestrowana.

Zmienia to logikę, w check_to_create()której sprawdza, czy wpis już istnieje w indeksie na dwa sposoby:

  • po pierwsze, w ogóle wyszukujemy wpis indeksu, jeśli ok_if_existsjest fałszywy;
  • po drugie, sprawdzamy CE_INTENT_TO_ADDflagę w każdym znalezionym wpisie indeksu i pozwalamy aplikacji na kontynuowanie, jeśli jest ustawiona.
VonC
źródło
jakieś aktualizacje na ten temat? Używam gita w wersji 2.28.0 i nie działa z git add -N + git add -pręczną edycją porcji
The.Wolfgang.Grimmer
1
@ The.Wolfgang.Grimmer Jeszcze nie: 2.29 zostanie wydany za kilka tygodni.
VonC