Odwróć przystojniak w Magit 2.1.0

24

Właśnie zaktualizowałem do wersji 2.1.0. (A także emacs 25.0.50 i git 2.3.1.)

Wcześniej w *magit*buforze mogłem:

  1. Wybierz przystojniak w obszarze Nieustawiony.
  2. Wpisz vi odpowiedz „tak”, aby to odwrócić.

To było przydatne.

Ale teraz w MAGIT 2.1.0 daje błąd: "Cannot reverse unstaged changes".

Czemu?


Biorąc podpowiedź z komunikatu o błędzie, odkryłem, że wciąż mogę to zrobić, choć w nieco „wsteczny” sposób, wykonując więcej kroków:

  1. stage przystojniak. (Czuje się do tyłu; przybliżając go do stanu popełnionego.)
  2. Przewiń w dół i wybierz go w obszarze etapowym.
  3. Naciśnij v, odpowiedz tak.
  4. Jednak przystojniak jest wciąż wystawiany, więc w końcu muszę go uzaatakować.

Czy to błąd, czy jest to celowe i / lub jestem gęsty? Jeśli to drugie, czy możesz mi pomóc zrozumieć?


AKTUALIZACJA: Po dokładnym poinformowaniu RTF widzę, że istnieją dwie komendy:

  • v magit-reverse Odwróć zmianę w punkcie drzewa roboczego.
  • k magit-discard Usuń zmianę w punkcie z drzewa roboczego.

Wygląda na to, że k magit-discardrobi to, do czego byłem przyzwyczajony vwcześniej. Działa na przystojniaku.

Więc praktycznie muszę po prostu ponownie wyćwiczyć pamięć mięśni, aby móc z niej korzystać k. Mógłbym to opublikować jako odpowiedź własną. Ale wydaje mi się, że wciąż jestem ciekawy uzasadnienia, ponieważ wyobrażam sobie, że zrozumienie pomoże mi lepiej zrozumieć magit.

Greg Hendershott
źródło
Cieszę się, że czytasz dokładne informacje :) Nie rozumiem, co masz na myśli, mówiąc „odwrócenie” przystojniaka. Nigdy wcześniej nie słyszałem tego terminu.
PythonNut
kodrzuca również niezatwierdzone zmiany we wcześniejszych wersjach magit i wydaje się właściwym poleceniem do tego, co robisz. vjest dla git revert: utworzenie nowego zatwierdzenia, które spowoduje odwrotną zmianę w stosunku do poprzedniego. Wydaje mi się, że cofnięcie zmiany, która nie została jeszcze zatwierdzona, jest równoznaczne z jej odrzuceniem, ale „przywracanie” ma określone znaczenie jako polecenie git.
glucas
OK, wygląda na to, że vbył związany magit-revert-item(terminologia „odwrotna” pochodzi stąd, @PythonNut), a dla elementów niestacjonarnych robił to magit-discard-item(jak również jest to związane k) - patrz wiersz 4872 tutaj . Najwyraźniej przypadkowo nauczyłem się tego specjalnego znaczenia v, które zadziałało, kiedy powinienem był nauczyć się używać k.
Greg Hendershott,
Chociaż zazwyczaj nie jestem wielkim fanem odpowiedzi na pytania, myślę, że w tym przypadku jest to najbardziej miłosierny sposób na zakończenie tego. :) Wysłałem jeden poniżej.
Greg Hendershott,

Odpowiedzi:

20

Magit implementuje pięć „wariantów zastosowania” opisanych w instrukcji : etap, wycofanie, „regularne stosowanie”, odrzucenie i odwrócenie. Pierwsze trzy powinny być dość oczywiste dla większości użytkowników Git. Dwa ostatnie nie istnieją w porcelanie Git (w Magit są realizowane za pomocą poleceń hydraulicznych Git i Emacsa Lispa).

Te dwa warianty są opisane w następujący sposób:

  • Odrzucać. Po zmianie etapowej usuń ją z działającego drzewa i indeksu. W przypadku zmiany nieetapowej usuń ją tylko z drzewa roboczego.
  • Rewers. Odwróć zmianę w działającym drzewie. Zarówno zatwierdzone, jak i etapowe zmiany można cofnąć. Nieustawionych zmian nie można cofnąć. Zamiast tego wyrzuć je.

Te dwa warianty robią bardzo różne rzeczy, więc żaden z tych wariantów nie powinien wracać do drugiego wariantu w przypadkach, gdy sam nie może być użyty. Zachowanie starego zachowania (polegającego na cofaniu się z odwrotności do odrzucania w niektórych kontekstach) może być wygodniejsze na krótką metę, ale na dłuższą metę uniemożliwia użytkownikom zrozumienie, do czego służą te dwa warianty.

Odrzucanie jest znacznie bardziej niebezpieczne niż odwracanie . Pierwsze „odrzuca niezaangażowane zmiany” (zmiany te są utracone, nigdzie już ich nie ma), podczas gdy drugie „dokonuje zmian”, przyjmując starszą zmianę i robiąc coś przeciwnego w drzewie roboczym (stara zmiana nie zostaje utracona, nadal znajduje się w zatwierdzeniu lub indeksie).

Powrót od „tworzenia” do „usuwania” jest bardzo niebezpieczny, więc Magit już tego nie robi.


Pamiętaj również, że korzystając z nowych trybów czyszczenia , możesz zabezpieczyć się przed utratą zmian spowodowanych przypadkowym odrzuceniem.

Tarsjusz
źródło
3
Dziękuję bardzo za poświęcenie czasu na odpowiedź i wyjaśnienie uzasadnienia.
Greg Hendershott,
10

Wygląda jakbym przypadkowo dowiedziałem się, że vzobowiązany do magit-revert-item, nie używane do zrobić magit-discard-itemw tym szczególnym przypadku Unstaged porcji. Zobacz <=== HERE ===komentarz, który umieściłem poniżej:

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

Źródło: kod 1.4.2 .

Ale teraz tak się nie dzieje:

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

Źródło: master :


kJest jednak bezpośrednio związany z magit-discard-item. Powinienem był nauczyć się tego używać. To działało przed 2.1.0 i nadal działa.

Podsumowując, magit 2.1.0 został znacznie przeprojektowany. Jest nieuniknione, że niektóre dziwne przypadki narożne mogły nie przetrwać. I zgodziłbym się, że nie muszę przeżyć. Ponownie nauczę się klucza.

Greg Hendershott
źródło
1
Ładna szczegółowa odpowiedź na pytanie - równie dobrze może to zaakceptować!
glucas