Invertire un pezzo in Magit 2.1.0


24

Ho appena aggiornato a Magit 2.1.0. (E anche per emacs 25.0.50 e git 2.3.1.)

In precedenza, nel *magit*buffer ho potuto:

  1. Seleziona un hunk nell'area Unstaged.
  2. Digita ve rispondi sì per invertirlo.

Questo è stato utile.

Ma ora in magit 2.1.0 dà un errore: "Cannot reverse unstaged changes".

Perché?


Prendendo un suggerimento dal messaggio di errore, ho scoperto che posso ancora farlo, anche se in modo un po '"arretrato" con più passaggi:

  1. sstuzzicare il pezzo. (Si sente all'indietro; avvicinandolo allo stato impegnato.)
  2. Nav down e selezionarlo nell'area Staged.
  3. Premi v, rispondi si.
  4. Comunque il pezzo è ancora in scena, quindi finalmente devo mettere in uscena il pezzo.

È un bug o è intenzionale e / o sto diventando denso? Se quest'ultimo, mi puoi aiutare a capire?


AGGIORNAMENTO: Dopo aver accuratamente RTFinfo-ing, vedo che ci sono due comandi:

  • v magit-reverse Invertire la modifica nel punto dell'albero di lavoro.
  • k magit-discard Rimuovere la modifica nel punto dall'albero di lavoro.

Sembra che k magit-discardfaccia quello che ero abituato a vfare prima. Funziona su un pezzo non messo in scena.

Quindi praticamente ho solo bisogno di riqualificare la mia memoria muscolare da usare k. Potrei postarlo come risposta automatica. Ma immagino di essere ancora curioso della logica, perché immagino che comprenderlo mi aiuterà a capire meglio Magit nel complesso.


Sono contento che stai leggendo The Fine Info :) Sono confuso sul significato di "invertire" un pezzo. Non ho mai sentito quel termine prima.
PythonNut

kignora anche un cambiamento non confermato nelle versioni precedenti di magit e sembra il comando appropriato per quello che stai facendo. vè per git revert: creare un nuovo commit che apporta la modifica opposta di una precedente. Immagino che annullare una modifica che non sia stata effettivamente commessa equivale a scartarla, ma "ripristinare" ha un significato specifico come comando git.
Glucas,

OK, sembra che vfosse legato a magit-revert-item(la terminologia "inversa" viene da lì, @PythonNut) e per gli elementi non messi in scena questo era usato per magit-discard-item(come anche associato k) - vedere la riga 4872 qui . Apparentemente ho imparato per caso quel significato speciale di v, che ha funzionato, quando avrei dovuto imparare ad usare k.
Greg Hendershott,

Anche se di solito non sono un grande fan di auto-risposte, penso che in questo caso sia il modo più misericordioso per concludere questo. :) Inserito uno qui sotto.
Greg Hendershott,

Risposte:


20

Magit implementa cinque "varianti di applicazione" descritte nel manuale : fase, non scena, "applicazione regolare", scarto e retro. I primi tre dovrebbero essere abbastanza ovvi per la maggior parte degli utenti Git. Gli ultimi due non esistono nella porcellana Git (in Magit sono implementati usando i comandi idraulici Git e Emacs Lisp).

Queste due varianti sono descritte in questo modo:

  • Scartare. In caso di modifica graduale, rimuoverlo dall'albero di lavoro e dall'indice. Su una modifica non messa in scena, rimuoverla solo dall'albero di lavoro.
  • Inverso. Invertire una modifica nell'albero di lavoro. È possibile invertire sia le modifiche impegnate che quelle in fasi. Le modifiche non messe in scena non possono essere annullate. Scartali invece.

Queste due varianti fanno cose molto diverse, quindi nessuna di queste varianti dovrebbe ricadere sull'altra variante nei casi in cui non può essere utilizzata. Mantenere il vecchio comportamento (dal ricadere dal retro allo scarto in alcuni contesti) potrebbe essere stato più conveniente a breve termine, ma a lungo termine impedisce agli utenti di provare davvero a capire a cosa servono queste due varianti.

Scartare è molto più pericoloso del contrario . Il primo "elimina i cambiamenti non confermati" (questi cambiamenti vengono persi, non sono più da nessuna parte), mentre il secondo in realtà "crea cambiamenti", prendendo un cambiamento più vecchio e facendo l'opposto nel campo di lavoro (il vecchio cambiamento non viene perso, è ancora in un commit o nell'indice).

Ripiegare dalla "creazione" alla "cancellazione" è molto pericoloso, quindi Magit non lo fa più.


Inoltre, utilizzando le nuove modalità di pulizia è possibile proteggersi dalla perdita di modifiche a causa di uno scarto accidentale.


3
Grazie mille per aver dedicato del tempo per rispondere e spiegare la logica.
Greg Hendershott,

10

Sembra che avessi saputo per caso che v, legato magit-revert-item, in un magit-discard-itemcaso speciale di hunk non messi in scena era solito fare una cosa . Vedi il <=== HERE ===commento che ho inserito di seguito:

(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")))))

Fonte: 1.4.2 codice .

Ma ora non succede:

(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)))))

Fonte: master :


Tuttavia kè legato direttamente a magit-discard-item. Avrei dovuto imparare ad usarlo in primo luogo. Funzionava prima della 2.1.0 e funziona ancora.

In conclusione, magit 2.1.0 è stato ridisegnato in modo significativo. È inevitabile che alcuni strani casi angolari non siano sopravvissuti. E, sarei d'accordo, non è necessario che sia sopravvissuto. Imparerò di nuovo la chiave.


1
Bella auto risposta dettagliata - può anche accettarla!
Glucas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.