150 votes

git add --patch' pour inclure les nouveaux fichiers ?

Quand je cours git add -p Est-ce qu'il y a un moyen pour git de sélectionner les fichiers nouvellement créés en tant que hunks à sélectionner ?

Donc si je crée un nouveau fichier appelé foo.java puis exécuter git add -p, git ne me laissera pas choisir le contenu de ce fichier à ajouter dans l'index.

145voto

CatShoes Points 1390

Quand j'ai essayé git add -p someNewFile.txt sur un nouveau fichier (un fichier non suivi), git afficherait simplement No changes. et s'arrêter. J'ai dû dire à git que j'avais l'intention de suivre le nouveau fichier en premier.

git add -N someNewFile.txt
git add -p

Cependant, comme le fichier n'était pas suivi, il apparaissait comme un gros morceau qui ne pouvait pas être divisé (parce qu'il était tout nouveau !). Il fallait donc que j'édite le gros morceau en petits morceaux. Si vous n'êtes pas familier avec cette méthode, allez voir cette référence pour commencer.

Mise à jour - info sur l'édition de Hunk Je voulais mettre à jour cette information au cas où la référence ci-dessus disparaîtrait. Parce que le nouveau fichier n'est pas tracé, git add -p affichera chaque ligne du fichier comme une nouvelle ligne dans un seul morceau. Il vous demandera ensuite ce que vous voulez faire avec ce hunk, en vous donnant l'invite suivante :

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

En supposant que vous ne voulez pas livrer l'ensemble du hunk (et donc, l'ensemble du fichier ; parce que je ne suis pas sûr de la raison pour laquelle vous voudriez utiliser l'option git add -p dans ce cas ?), vous voudrez spécifier l'option e pour indiquer à git que vous voulez éditer le hunk.

Une fois que vous avez indiqué à git que vous voulez modifier le hunk, il devrait vous placer dans l'éditeur de votre choix pour que vous puissiez effectuer vos modifications. Toutes les lignes doivent être préfixées par un + et git a quelques commentaires explicatifs (préfixés avec un # ) à la fin du fichier. Supprimez simplement toutes les lignes que vous ne souhaitez pas voir figurer dans votre livraison initiale du fichier. Ensuite, enregistrez et quittez l'éditeur.

Explication de Git sur les options hunk de 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

125voto

Ulysse BN Points 2280

Pour inclure tous les nouveaux fichiers, vous pouvez exécuter :

git add -N .
git add -p

Si vous voulez l'utiliser fréquemment, vous pouvez créer un alias dans votre fichier ~/.bashrc :

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

N.B. : Si vous utilisez ceci avec un nouveau fichier vide, git ne sera pas capable de le patcher et de passer au suivant.

10voto

doublejosh Points 974

Il existe également une approche très similaire qui utilise la fonction --cached drapeau...

1) Transformez vos modifications non indexées en indexées, tout comme votre fichier ajouté.

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

2) Regardez le diff (note : vous pouvez inclure à la fois les modifications et les nouveaux fichiers).

git diff --cached

3) Créez le patch.

git diff --cached > my_patch_file.patch

8voto

VonC Points 414372

Catshoes La réponse de la Commission comprend :

Quand j'ai essayé git add -p someNewFile.txt sur un nouveau fichier (un fichier non suivi), git afficherait simplement No changes. et s'arrêterait.
J'ai dû dire à git que j'avais l'intention de suivre le nouveau fichier en premier.

git add -N someNewFile.txt
git add -p

Cela devrait changer prochainement avec Git 2.29 (Q4 2020).

Les versions récentes de " git diff-files " ( homme ) montre une différence entre l'index et l'arbre de travail pour les chemins "intentionnels" comme un patch "nouveau fichier" ;
" git apply --cached " ( homme ) devrait être en mesure de prendre " git diff-files "et devrait agir comme un équivalent de " git add " pour le chemin, mais la commande n'a pas réussi à le faire pour un tel chemin.

Ver commettre 4c025c6 , commettre e3cc41b (08 août 2020), et commettre 7cfde3f (06 août 2020) par Raymond E. Pasco ( juped ) .
(fusionné par Junio C Hamano -- gitster -- en commettre ca81676 17 août 2020)

apply : permettre les patchs "nouveau dossier" sur les entrées i-t-a

Assisté par : Junio C Hamano
Signé par : Raymond E. Pasco

diff-files récemment modifié pour traiter les changements de chemins marqués "intention d'ajouter" dans l'index comme des différences de nouveaux fichiers plutôt que des différences depuis le blob vide.

Cependant, apply refuse d'appliquer les nouvelles différences de fichiers par-dessus les entrées d'index existantes, sauf dans le cas de renommages.
Cela provoque " git add -p " ( homme ) qui utilise apply, échoue lors de la tentative de mise en scène des hunks d'un fichier lorsque l'intention d'ajouter a été enregistrée.

Cela change la logique dans check_to_create() qui vérifie si une entrée existe déjà dans un index de deux manières :

  • d'abord, nous ne recherchons une entrée d'index que si ok_if_exists est fausse ;
  • ensuite, nous vérifions la CE_INTENT_TO_ADD sur toutes les entrées d'index que nous trouvons et autorisons l'application à se poursuivre s'il est activé.

Et :

Avec Git 2.29 (Q4 2020), " add -p "permet désormais de modifier des chemins qui n'ont été ajoutés qu'en intention.

Ver commettre 75a009d (09 Sep 2020) par Phillip Wood ( phillipwood ) .
(fusionné par Junio C Hamano -- gitster -- en commit 458205f , 22 septembre 2020)

add -p : correction de l'édition des chemins en intention d'ajouter

Signé par : Phillip Wood
Rapporté par : Thomas Sullivan
Rapporté par : Yuchen Ying

Une façon populaire de mettre partiellement à disposition un nouveau fichier est d'exécuter git add -N <path> ( homme ) et ensuite utiliser l'édition du hunk de git add -p ( homme ) pour sélectionner la partie du fichier que l'utilisateur souhaite mettre en scène.

Depuis 85953a3187 (" diff-files --raw : show correct post-image of intent-to-add files ", 2020-07-01, Git v2.28.0-rc0 -- fusionner répertorié dans lot n° 7 ) cela a cessé de fonctionner car les chemins d'accès en intention d'ajouter sont maintenant affichés comme de nouveaux fichiers plutôt que comme des changements à un blob vide et git apply ( homme ) a refusé d'appliquer un correctif de création pour un chemin qui était marqué comme intentionnel. 7cfde3fa0f ("apply : allow "new file" patches on i-t-a entries", 2020-08-06) a corrigé le problème avec apply mais il n'était toujours pas possible d'éditer correctement le morceau ajouté.

2c8bd8471a (" checkout -p : traiter les nouveaux fichiers correctement", 2020-05-27, Git v2.28.0-rc0 -- fusionner répertorié dans lot n° 2 ) avait précédemment modifié add -p pour gérer les nouveaux fichiers mais il n'implémentait pas correctement l'édition de patchs.
La version perl interdisait simplement l'édition et la version C ouvrait l'éditeur avec le diff complet plutôt que juste le hunk, ce qui signifiait que l'utilisateur devait éditer l'en-tête du hunk manuellement pour que cela fonctionne.

La cause première du problème est que les fichiers ajoutés stockent l'en-tête de diff avec les données du hunk au lieu de séparer les deux comme nous le faisons pour les autres modifications. En modifiant les fichiers ajoutés pour qu'ils stockent l'en-tête de diff séparément, on résout le problème d'édition au prix de devoir traiter les ajouts vides de manière spéciale, car ils ne sont plus associés à des hunks, mais uniquement à l'en-tête de diff.

Les modifications déplacent une partie du code existant dans une conditionnelle en changeant l'indentation, elles sont mieux visualisées avec --color-moved-ws=allow-indentation-change (o --ignore-space-change fonctionne bien pour avoir une vue d'ensemble des changements)


Un peu plus de clarté est ajoutée avec Git 2.32 (Q2 2021) :

Ver commettre 7a14acd (27 avr. 2021) par Peter Oliver ( mavit ) .
(fusionné par Junio C Hamano -- gitster -- en commettre e60e9cc , 07 mai 2021)

doc : point sur l'attribut diff dans la documentation sur le format du patch

Signé par : Peter Oliver

À partir de la documentation sur la génération de texte de correctif avec les commandes liées à diff, consultez la documentation sur l'attribut diff.

Cet attribut influence la façon dont les correctifs sont générés, mais cela n'était pas mentionné auparavant, par exemple dans le document git-diff ( homme ) page de manuel.

diff-generate-patch inclut désormais dans son page de manuel :

  1. Les en-têtes de hunk mentionnent le nom de la fonction à laquelle le hunk s'applique. Voir "Définir un en-tête de hunk personnalisé" dans gitattributes pour plus de détails sur la façon de l'adapter à ce programme. langues spécifiques.

7voto

Matthieu Moy Points 5947

git add -p consiste en fait à ajouter des modifications à des fichiers déjà suivis.

La commande pour sélectionner interactivement les fichiers à ajouter est la suivante git add -i . Par exemple :

$ 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

(La vraie commande a des couleurs que je ne pourrais pas copier-coller ici, donc c'est plus joli qu'il n'y paraît)

En fait, le p atch commandement de git add -i fait la même chose que git add -p donc la seconde est un sous-ensemble de la première (même si j'admets que j'adore les add -p et la haine add -i moi-même !).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X