web-dev-qa-db-fra.com

N'ajouter que les modifications d'espaces non blancs

J'ai mon éditeur de texte pour couper automatiquement les espaces blancs de fin lors de l'enregistrement d'un fichier, et je contribue à un projet open source qui présente de graves problèmes de suivi des espaces.

Chaque fois que j'essaie de soumettre un correctif, je dois d'abord ignorer manuellement tous les changements d'espaces, pour ne choisir que les informations pertinentes. Non seulement cela, mais quand je lance git rebase, je rencontre généralement plusieurs problèmes à cause d’eux.

En tant que tel, j'aimerais pouvoir ajouter à l'index uniquement les modifications non d'espacement, d'une manière similaire à celle de git add -p, mais sans devoir choisir toutes les modifications moi-même.

Est-ce que quelqu'un sait comment faire ça?

EDIT: Je ne peux pas changer le fonctionnement du projet et ils ont décidé, après en avoir discuté sur la liste de diffusion, de l'ignorer.

320
Edu Felipe

La solution @Frew n'était pas tout à fait ce dont j'avais besoin, c'est donc l'alias que j'ai créé pour le même problème:

alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'

Ou vous pouvez simplement lancer:

git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -

Mise à jour

Ajout des options -U0 et --unidiff-zero respectivement aux problèmes de correspondance du contexte de la solution de contournement, selon ce commentaire .

Fondamentalement, il applique le patch qui serait appliqué avec add sans changements d’espace. Vous remarquerez qu'après un git addnw your/file, il y aura toujours des modifications non mises en scène, ce sont les espaces blancs restants.

Le paramètre --no-color n'est pas obligatoire, mais comme les couleurs sont définies sur toujours, je dois les utiliser. Quoi qu'il en soit, mieux vaut prévenir que guérir.

365
Colin Hebert

Cela fonctionne pour moi:

Si vous voulez garder une réserve, cela fonctionne

git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

Je n'aime pas les cachettes, mais j'ai = ai rencontré un bogue dans git + cygwin où je perds les modifications, donc pour être sûr que tout cela est bien passé au moins au reflog, j'ai mis en place ce qui suit:

git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

Fondamentalement, nous créons un diff qui n'inclut pas les modifications d'espace, annulons toutes nos modifications, puis appliquons le diff.

36
Frew Schmidt

Créez un fichier de correctif contenant uniquement les modifications réelles (à l'exception des lignes contenant uniquement des modifications d'espaces), puis nettoyez votre espace de travail et appliquez ce fichier de correctif:

git diff> sauvegarde
git diff -w> modifications
git reset --hard
patch <changements

Passez en revue les différences restantes, puis add et commit comme d'habitude.

L'équivalent pour Mercurial est le suivant:

hg diff> sauvegarde
hg diff -w> modifications
hg revert --all
hg import --no-commit modifications

29
Steve Pitchers

Ajoutez ce qui suit à votre .gitconfig:

anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"

Merci à @ réponse de Colin Herbert pour l'inspiration.

Explication de la syntaxe

Le dernier # doit être cité de sorte qu'il ne soit pas traité comme un commentaire à l'intérieur du .gitconfig, mais passe plutôt à travers et est traité comme un commentaire à l'intérieur du Shell - il est inséré entre la fin du git apply et les arguments fournis par l'utilisateur que git place automatiquement à la fin de la ligne de commande. Ces arguments ne sont pas recherchés ici - nous ne voulons pas que git apply les consomme, d'où le caractère de commentaire précédent. Vous voudrez peut-être exécuter cette commande en tant que GIT_TRACE=1 git anw pour le voir en action.

Le -- signale la fin des arguments et permet dans le cas où vous auriez un fichier nommé -w ou quelque chose qui ressemblerait à un passage à git diff.

Les guillemets doubles échappés autour de $@ sont nécessaires pour conserver tous les arguments cités fournis par l'utilisateur. Si le caractère " n'est pas échappé, il sera consommé par l'analyseur .gitconfig et ne parviendra pas au shell.

Remarque: l'analyse .gitconfig d'alias ne reconnaît pas les guillemets simples, mais ses seuls caractères spéciaux sont ", \, \n et ; ( en dehors d'une chaîne "- entre guillemets). C'est pourquoi un " doit toujours être échappé, même s'il a l'air d'être dans une chaîne entre guillemets (ce qui git complètement agnostique).

C'est important, par exemple. si vous avez un alias pratique pour exécuter une commande bash à la racine de l’arbre de travail. La formulation incorrecte est:

sh = !bash -c '"$@"' -

Alors que le bon est:

sh = !bash -c '\"$@\"' -
9
Tom Hale

La réponse la plus votée ne fonctionne pas dans tous les cas, à cause des espaces dans le contexte du correctif selon les utilisateurs dans les commentaires.

J'ai révisé la commande comme suit:

$ git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero

Cela génère un patch sans contexte. Cela ne devrait pas poser de problème, car le correctif est de courte durée.

Alias ​​correspondant, encore une révision de ce qui a déjà été fourni par d'autres utilisateurs:

addw = !sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero' -
9
void.pointer

Que diriez-vous de ce qui suit:

git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`

La commande dans les guillemets arrières récupère les noms des fichiers dont les modifications ne sont pas des espaces.

6
karmakaze

Vous devez d’abord déterminer si les espaces de fin sont intentionnels. De nombreux projets, notamment le noyau Linux, Mozilla, Drupal et Kerberos (pour en nommer quelques-uns de la page Wikipedia sur le style) interdisent les espaces de fin. De la documentation du noyau Linux:

Obtenez un éditeur décent et ne laissez pas d’espace à la fin des lignes.

Dans votre cas, le problème est inversé: les commits précédents (et peut-être les plus actuels) n'ont pas suivi cette ligne directrice.

Je parie que personne ne veut vraiment les derniers espaces, et résoudre le problème pourrait être un changement bienvenu. D'autres utilisateurs pourraient également rencontrer le même problème que vous. Il est également probable que le ou les contributeurs qui ajoutent des espaces finaux ne le sachent pas.

Plutôt que d'essayer de reconfigurer git pour ignorer le problème ou de désactiver les fonctionnalités souhaitables dans votre éditeur, je commencerais par créer un message sur la liste de diffusion du projet expliquant le problème. De nombreux éditeurs (et git lui-même) peuvent être configurés pour gérer les espaces de fin.

0
Kevin Vermeer