Machen Sie einen Hunk in Magit 2.1.0 rückgängig

24

Ich habe gerade ein Upgrade auf Magit 2.1.0 durchgeführt. (Und auch zu Emacs 25.0.50 und Git 2.3.1.)

Bisher konnte *magit*ich im Puffer:

  1. Wählen Sie ein Stück im Bereich Nicht bereitgestellt aus.
  2. Tippe vund antworte mit Ja, um es umzukehren.

Das war praktisch.

Aber jetzt in magit 2.1.0 gibt es einen Fehler: "Cannot reverse unstaged changes".

Warum?


Als ich einen Hinweis aus der Fehlermeldung nahm, stellte ich fest, dass ich dies immer noch tun kann, wenn auch etwas "rückwärts" mit mehr Schritten:

  1. stage das Stück. (Fühlt sich rückwärts an und rückt näher an den festgelegten Zustand heran.)
  2. Navigieren Sie nach unten und wählen Sie es im Bereich Bereitgestellt aus.
  3. Drücken Sie v, antworten Sie mit Ja.
  4. Allerdings ist das Stück immer noch in uSzene gesetzt , also muss ich das Stück endlich inszenieren .

Ist das ein Fehler oder ist es beabsichtigt und / oder ich bin dicht? Wenn letzteres, können Sie mir helfen, das zu verstehen?


UPDATE: Nach gründlicher RTF-Information sehe ich, dass es zwei Befehle gibt:

  • v magit-reverse Machen Sie die Änderung am Punkt im Arbeitsbaum rückgängig.
  • k magit-discard Entfernen Sie die Änderung am Punkt aus dem Arbeitsbaum.

Es scheint so, als ob k magit-discardes das tut, was ich vvorher gewohnt war . Es funktioniert auf einem nicht bereitgestellten Stück.

Also muss ich praktisch nur mein Muskelgedächtnis trainieren, um es zu nutzen k. Ich könnte das als Selbstantwort posten. Aber ich denke, ich bin immer noch neugierig auf die Gründe, weil ich mir vorstelle, dass das Verständnis mir dabei hilft, magit insgesamt besser zu verstehen.

Greg Hendershott
quelle
Ich bin froh, dass du The Fine Info liest :) Ich bin verwirrt, was du damit meinst, ein Stück umzukehren. Ich habe diesen Begriff noch nie gehört.
PythonNut
kverwirft eine nicht festgeschriebene Änderung auch in früheren Versionen von magit und scheint der geeignete Befehl für das zu sein, was Sie tun. vis for git revert: Erstellen eines neuen Commits, bei dem das Gegenteil eines vorherigen geändert wird. Das Zurücksetzen einer Änderung, die nicht tatsächlich festgeschrieben wurde, ist vermutlich dasselbe wie das Verwerfen, aber das Zurücksetzen hat eine bestimmte Bedeutung als git-Befehl.
Glucas
OK, es sieht so aus, als ob ves an magit-revert-item(die "umgekehrte" Terminologie stammt von dort, @PythonNut) gebunden war und für nicht bereitgestellte Elemente, für die dies verwendet wurde magit-discard-item(wie auch an k) - siehe Zeile 4872 hier . Anscheinend habe ich aus Versehen diese spezielle Bedeutung von gelernt v, die funktioniert, wenn ich gelernt haben sollte, zu verwenden k.
Greg Hendershott
Obwohl ich normalerweise kein großer Fan von Selbstantworten bin, denke ich, dass dies in diesem Fall der gnädigste Weg ist, um daraus zu schließen. :) Unten einen gepostet.
Greg Hendershott

Antworten:

20

Magit implementiert fünf im Handbuch beschriebene " Apply- Varianten" : Stage, Unstage, "Regular Apply", Discard und Reverse. Die ersten drei sollten für die meisten Git-Benutzer ziemlich offensichtlich sein. Die beiden letzteren sind im Git- Porzellan nicht vorhanden (in Magit werden sie mit Git- Installationsbefehlen und Emacs Lisp implementiert ).

Diese beiden Varianten werden folgendermaßen beschrieben:

  • Verwerfen. Entfernen Sie bei einer gestuften Änderung diese aus der Arbeitsstruktur und dem Index. Entfernen Sie eine nicht bereitgestellte Änderung nur aus der Arbeitsstruktur.
  • Umkehren. Machen Sie eine Änderung im Arbeitsbaum rückgängig. Sowohl festgeschriebene als auch bereitgestellte Änderungen können rückgängig gemacht werden. Nicht bereitgestellte Änderungen können nicht rückgängig gemacht werden. Verwerfen Sie sie stattdessen.

Diese beiden Varianten haben sehr unterschiedliche Funktionen, sodass keine dieser Varianten auf die andere Variante zurückgreifen sollte, wenn sie selbst nicht verwendet werden können. Das alte Verhalten beizubehalten (in manchen Kontexten vom umgekehrten zum verworfenen Zustand zurückzukehren) mag kurzfristig bequemer gewesen sein, aber auf lange Sicht hindert es die Benutzer daran, wirklich zu versuchen, zu verstehen, wofür diese beiden Varianten gedacht sind.

Das Wegwerfen ist viel gefährlicher als das Umkehren . Ersteres "wirft nicht festgeschriebene Änderungen weg" (diese Änderungen gehen verloren, sie sind nirgendwo mehr zu finden), während Letzteres tatsächlich "Änderungen schafft", indem es eine ältere Änderung vornimmt und im Arbeitsbaum das Gegenteil tut (die alte Änderung geht nicht verloren). es befindet sich noch in einem Commit oder im Index).

Das Zurückgreifen von "Erstellen" auf "Löschen" ist sehr gefährlich, deshalb macht Magit das nicht mehr.


Beachten Sie auch, dass Sie sich mit den neuen Wip-Modi davor schützen können, Änderungen aufgrund eines versehentlichen Verwerfens zu verlieren.

Tarsius
quelle
3
Vielen Dank, dass Sie sich die Zeit genommen haben, die Gründe zu beantworten und zu erklären.
Greg Hendershott
10

Es sieht aus wie hatte ich zufällig erfuhr , dass v, gebunden magit-revert-item, verwendet haben ein zu tun magit-discard-itemin diesem speziellen Fall von unstaged großen Stücken. Siehe den <=== HERE ===Kommentar, den ich unten schreibe:

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

Quelle: 1.4.2 Code .

Aber jetzt passiert das nicht:

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

Quelle: Meister :


Jedoch kist direkt an gebunden magit-discard-item. Ich hätte das eigentlich lernen sollen. Das hat vor 2.1.0 funktioniert und funktioniert immer noch.

Abschließend wurde magit 2.1.0 erheblich überarbeitet. Es ist unvermeidlich, dass einige seltsame Eckfälle nicht überlebt haben. Und ich würde zustimmen, dass ich nicht überlebt haben muss. Ich werde den Schlüssel neu lernen.

Greg Hendershott
quelle
1
Nette ausführliche Selbstantwort - kann es genauso gut annehmen!
Glucas