Inverser un morceau dans Magit 2.1.0

24

Je viens de passer à magit 2.1.0. (Et aussi pour emacs 25.0.50 et git 2.3.1.)

Auparavant, dans le *magit*tampon, je pouvais:

  1. Sélectionnez un morceau dans la zone Unstaged.
  2. Tapez vet répondez oui pour l'inverser.

C'était pratique.

Mais maintenant , en magit 2.1.0 donne une erreur: "Cannot reverse unstaged changes".

Pourquoi?


En prenant un indice du message d'erreur, j'ai découvert que je pouvais toujours le faire, quoique d'une manière quelque peu "à l'envers" avec plus d'étapes:

  1. stage du morceau. (Sensation en arrière; le rapprocher de l'état engagé.)
  2. Naviguez vers le bas et sélectionnez-le dans la zone Mise en scène.
  3. Appuyez sur v, répondez oui.
  4. Cependant, le morceau est toujours mis en scène, donc finalement je dois umonter le morceau.

Est-ce un bug, ou est-ce intentionnel et / ou je suis dense? Si ce dernier, pouvez-vous m'aider à comprendre?


MISE À JOUR: Après bien RTFinfo-ing, je vois qu'il y a deux commandes:

  • v magit-reverse Inversez le changement au point de l'arborescence de travail.
  • k magit-discard Supprimez la modification au point de l'arborescence de travail.

Il semble que cela k magit-discardfasse ce que j'avais l'habitude de vfaire auparavant. Cela fonctionne sur un morceau non mis en scène.

Donc, pratiquement, j'ai juste besoin de recycler ma mémoire musculaire pour l'utiliser k. Je pourrais poster cela comme une auto-réponse. Mais je suppose que je suis toujours curieux de savoir pourquoi, car j'imagine que le comprendre m'aidera à mieux comprendre le magit dans son ensemble.

Greg Hendershott
la source
Heureux que vous lisiez The Fine Info :) Je ne comprends pas ce que vous entendez par "inverser" un morceau. Je n'ai jamais entendu ce terme auparavant.
PythonNut
ksupprime également les modifications non validées dans les versions antérieures de magit et semble être la commande appropriée à ce que vous faites. vest pour git revert: créer un nouveau commit qui fait le changement inverse d'un précédent. J'imagine que le fait d'annuler un changement qui n'a pas réellement été validé équivaut à l'annuler, mais 'revert' a une signification spécifique en tant que commande git.
glucas
OK, il semble que vc'était lié à magit-revert-item(la terminologie "inverse" vient de là, @PythonNut) et pour les éléments non mis en scène, cela faisait magit-discard-item(comme aussi lié à k) - voir la ligne 4872 ici . Apparemment, j'ai accidentellement appris ce sens spécial de v, qui a fonctionné, alors que j'aurais dû apprendre à l'utiliser k.
Greg Hendershott
Bien que je ne sois généralement pas un grand fan des réponses spontanées, je pense que dans ce cas, c'est la façon la plus miséricordieuse de conclure cela. :) Posté un ci-dessous.
Greg Hendershott

Réponses:

20

Magit implémente cinq "variantes d'application" décrites dans le manuel : stage, unstage, "regular apply", discard et reverse. Les trois premiers devraient être assez évidents pour la plupart des utilisateurs de Git. Les deux derniers n'existent pas dans la porcelaine Git (dans Magit, ils sont implémentés en utilisant les commandes de plomberie Git et Emacs Lisp).

Ces deux variantes sont décrites comme ceci:

  • Jeter. Lors d'une modification par étapes, supprimez-la de l'arborescence de travail et de l'index. En cas de modification non progressive, supprimez-la uniquement de l'arborescence de travail.
  • Sens inverse. Inverse un changement dans l'arbre de travail. Les changements engagés et échelonnés peuvent être inversés. Les modifications non planifiées ne peuvent pas être annulées. Jetez-les à la place.

Ces deux variantes font des choses très différentes, donc aucune de ces variantes ne devrait retomber sur l'autre variante dans les cas où elle-même ne peut pas être utilisée. Garder l'ancien comportement (revenir de l'inverse au rejet dans certains contextes) aurait peut-être été plus pratique à court terme, mais à long terme, cela empêche les utilisateurs d'essayer vraiment de comprendre à quoi servent ces deux variantes.

Le rejet est beaucoup plus dangereux que l' inverse . Le premier "supprime les modifications non validées" (ces modifications sont perdues, elles ne sont plus nulle part), tandis que la seconde "crée des modifications", en prenant une modification plus ancienne et en faisant le contraire dans le worktree (l'ancienne modification n'est pas perdue, il est toujours dans un commit ou l'index).

Revenir de la "création" à la "suppression" est très dangereux, donc Magit ne le fait plus.


Notez également qu'en utilisant les nouveaux modes d'essuyage, vous pouvez vous protéger contre la perte de modifications en raison d'une suppression accidentelle.

tarse
la source
3
Merci beaucoup d'avoir pris le temps de répondre et d'expliquer la justification.
Greg Hendershott
10

Il semble que j'aie accidentellement appris que v, lié à magit-revert-item, je faisais un magit-discard-itemdans ce cas particulier de mecs non mis en scène. Voir le <=== HERE ===commentaire que j'ai mis ci-dessous:

(defun magit-revert-item ()
  "Revert the item at point.
The change introduced by the item is reversed in the current
working tree."
  (interactive)
  (magit-section-action revert (info)
    ([* unstaged] (magit-discard-item))  ;; <=== HERE ===
    (commit (when (or (not magit-revert-item-confirm)
                      (yes-or-no-p "Revert this commit? "))
              (magit-revert-commit info)))
    (diff   (when (or (not magit-revert-item-confirm)
                      (yes-or-no-p "Revert this diff? "))
              (magit-apply-diff-item it "--reverse")))
    (hunk   (when (or (not magit-revert-item-confirm)
                      (yes-or-no-p "Revert this hunk? "))
              (magit-apply-hunk-item it "--reverse")))))

Source: code 1.4.2 .

Mais maintenant cela ne se produit pas:

(defun magit-reverse (&rest args)
  "Reverse the change at point in the working tree."
  (interactive (and current-prefix-arg (list "--3way")))
  (--when-let (magit-current-section)
    (pcase (list (magit-diff-type) (magit-diff-scope))
      (`(untracked ,_) (user-error "Cannot reverse untracked changes"))
      (`(unstaged  ,_) (user-error "Cannot reverse unstaged changes"))
      (`(,_      list) (magit-reverse-files (magit-section-children it) args))
      (`(,_     files) (magit-reverse-files (magit-region-sections) args))
      (`(,_      file) (magit-reverse-files (list it) args))
      (_               (magit-reverse-apply it args)))))

Source: maître :


Cependant kest lié directement à magit-discard-item. J'aurais dû apprendre à l'utiliser en premier lieu. Cela fonctionnait avant 2.1.0 et fonctionne toujours.

En conclusion, magit 2.1.0 a été considérablement repensé. Il est inévitable que certains cas de coin étranges n'aient pas survécu. Et, je suis d'accord, pas besoin d'avoir survécu. Je réapprends la clé.

Greg Hendershott
la source
1
Belle auto-réponse détaillée - peut aussi bien l'accepter!
glucas