web-dev-qa-db-fra.com

Cachez les modifications apportées à des fichiers spécifiques

J'ai un grand projet git que j'ai stupidement importé dans Eclipse et exécuté un formatage automatique. Désormais, chaque fichier du projet s'affiche comme modifié. Plutôt que de valider mes fichiers formatés, je préférerais revenir sur tous les fichiers que je n'ai été formatés que sans autres modifications. Par exemple:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)

#     modified: dir/file1.cpp
#     modified: dir/file1.h
#     modified: dir/file2.cpp
#     modified: dir/file2.h
#     modified: dir/file3.cpp
#     modified: dir/file3.h
#     modified: dir/file4.cpp
#     modified: dir/file4.h

Je le sais file2.cpp, file2.h, et file3.cpp ont été modifiés avec du contenu (c'est-à-dire, pas seulement mis en forme). Je veux cacher les modifications apportées à ces trois fichiers, puis extraire une ancienne révision, afin de pouvoir réappliquer les modifications apportées à ces fichiers après. Je préfère éviter quelque chose comme:

$ cp file2.cpp ~/tmp
$ git checkout blahblahblah
$ cp ~/tmp/file2.cpp .

S'il existe un moyen évident de le faire qui n'implique pas de dissimulation, faites-le moi savoir. tout ce qui fait le travail.

41
ewok

Vous pouvez add les fichiers avec les modifications que vous souhaitez conserver, puis stash le reste des fichiers et effacer la cachette:

git add file2.cpp file2.h file3.cpp
git stash --keep-index

À ce stade, vous avez caché vos modifications indésirables. Si vous souhaitez vous en débarrasser définitivement, exécutez:

git stash drop

Maintenant vous avez file2.cpp, file2.h, et file3.cpp mis en scène pour la validation. Si vous souhaitez ensuite cacher ces fichiers (et ne pas les valider):

git reset
git stash

Vous serez maintenant à votre commit précédent, avec seulement ces trois fichiers cachés.

Mise à jour:

Git 2.13 et versions ultérieures incluent un moyen plus direct de cacher des fichiers spécifiques avec git stash Push, comme VonC l'explique dans sa réponse .

34
redhotvengeance

Je le sais file2.cpp, file2.h, et file3.cpp ont été modifiés avec du contenu (c'est-à-dire, pas seulement mis en forme).
Je veux cacher les modifications apportées à ces trois fichiers, puis extraire une ancienne révision, afin de pouvoir réappliquer les modifications apportées à ces fichiers après.

Avec Git 2.13 (Q2 2017), git stash aura officiellement un moyen de cacher les modifications de fichiers spécifiques avec

git stash Push [--] [<pathspec>...]

Voir commit 9e1409 , commit 1ada502 , commit df6bba (28 février 2017), et commit 9ca6326 , commit 6f5ccd4 , commit f5727e2 (19 février 2017) par Thomas Gummerer (tgummerer) .
(Fusionné par Junio ​​C Hamano - gitster - in commit 44c3f09 , 10 mars 2017)

Comme maintenant documenté :

Pour faire rapidement un instantané, vous pouvez omettre "Push".
Dans ce mode, les arguments sans option ne sont pas autorisés à empêcher une sous-commande mal orthographiée de créer une cachette indésirable.
Les deux exceptions à cette règle sont stash -p qui fait office d'alias pour stash Push -p et pathspecs, qui sont autorisés après un double tiret -- pour la désambiguïsation.

Lorsque pathspec est donné à 'git stash Push ', la nouvelle cachette enregistre les états modifiés uniquement pour les fichiers qui correspondent à la pathspec .
Les entrées d'index et les fichiers d'arborescence de travail sont ensuite restaurés à l'état dans HEAD uniquement pour ces fichiers, laissant les fichiers qui ne correspondent pas à la spécification de chemin intacts.

Notez, comme indiqué par medmunds dans les commentaires , que git stash utiliserait des chemins par rapport au dossier racine du dépôt git .

43
VonC

Une option intéressante utilise le mode de stockage interactif.

git stash --patch

Il fonctionne principalement comme le mode d'ajout interactif: vous allez être présenté avec une série de différences montrant les changements que vous avez dans votre arborescence de travail et vous devez choisir les fichiers (ou seulement certaines parties d'un fichier!) Que vous souhaitez cacher , le reste sera laissé intact.

De man git-stash:

Avec --patch, vous pouvez sélectionner interactivement des morceaux dans le diff entre HEAD et l'arborescence de travail à cacher. L'entrée de la réserve est construite de telle sorte que son état d'index est le même que l'état d'index de votre référentiel et son arbre de travail contient uniquement les modifications que vous avez sélectionnées de manière interactive. Les modifications sélectionnées sont ensuite annulées à partir de votre arbre de travail. Consultez la section "Mode interactif" de git-add (1) pour savoir comment utiliser le mode --patch.

Dans votre cas, vous pourrez voir les morceaux de mise en forme uniquement et les cacher individuellement, sans perdre vos modifications significatives.

14
Diego V

Vous pouvez également utiliser git stash -p. De cette façon, vous pouvez sélectionner quels morceaux doivent être ajoutés à la stash, des fichiers entiers peuvent également être sélectionnés.

Vous serez invité avec quelques actions pour chaque morceau:

y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash 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
6
Kashan

C'est une bonne utilisation pour git diff et git apply OMI:

git diff file2.cpp file2.h file3.cpp > ../my-changes.patch
git checkout ...
git apply ../my-changes.patch

Après diff, vous pouvez inspecter le fichier correctif pour vous assurer que toutes vos modifications sont là.

Notez que vous devrez peut-être utiliser le --reject option à appliquer, au cas où le patch ne s'appliquerait pas proprement. Voir également la page de manuel pour appliquer .

3
robinst