Przejdź do głównej zawartości

Checkpointy w Cursorze to automatyczne migawki plików zmienianych przez agenta Cursora, które pozwalają cofnąć z poziomu czatu jedną turę agenta. Checkpoint przywraca wyłącznie pliki: nie odwróci wykonanego polecenia i nie jest commitem. Bezpieczny wzorzec łączy checkpointy z Gitem: commit przed każdym zadaniem agenta i osobna gałąź dla każdego eksperymentu, dzięki czemu wszystko, co warto zachować, trzyma Git.

Ta strona jest dla programistów, którzy pozwalają agentowi Cursora na zmiany w wielu plikach naraz. Prosisz agenta o refaktoryzację logowania. Przepisuje sześć plików, a przy okazji „porządkuje” pulę połączeń z bazą, o której w ogóle nie wspominałeś. Kilka razy naciskasz cofnij, ale zmiany przeplatają się między plikami, więc w końcu uruchamiasz git checkout . i tracisz także zmiany w logowaniu, na których ci zależało. Każdego z tych kroków da się uniknąć.

  • Pięciokrokową rutynę, dzięki której każdą turę agenta wyrzucasz bez żalu.
  • Tabelę decyzyjną, która dobiera właściwe cofnięcie: checkpoint, git restore, git reset albo usunięcie gałęzi.
  • Jedno polecenie sprawdzające zakres, a do tego przebieg bramek jakości: razem mówią, czy zachować turę, bez czytania całego diffa.
  • Trzy prompty do skopiowania: zadanie z zakresem, prośbę o plan przed zmianami i ponowienie części pracy po przywróceniu.
  • Schemat nazywania gałęzi, który omija błąd cannot lock ref, na jaki trafia klasyczna rada o „mikrogałęziach”.

Co dokumentuje Cursor, a na czym opiera się ta strona

Dział zatytułowany „Co dokumentuje Cursor, a na czym opiera się ta strona”

Checkpointy Cursora są przechowywane lokalnie, osobno od Gita, a przywrócenie checkpointu cofa wyłącznie pliki (przegląd agenta w dokumentacji Cursora, sprawdzone 2026-10-12). Dokumentacji Cursora nie dało się otworzyć 26 września 2026, więc reszta tej strony opiera się na Gicie, który zweryfikujesz lokalnie, i zakłada jak najmniej o wnętrzu checkpointów.

FunkcjaCo dokumentuje CursorOstatnie sprawdzenieCo zakłada ta strona
CheckpointyStrona Checkpoints w dokumentacji czatu agenta opisuje automatyczne migawki zmian agenta: „Checkpoints are stored locally and separate from Git” oraz „Restoring a checkpoint reverts files only”2026-10-12Checkpoint potrafi przywrócić pliki zmienione przez agenta w danej turze. Nic ponad to, ani o czasie życia, ani o innym zasięgu
Worktree„Worktrees let Agent work in isolated Git checkouts.”28 sierpnia 2026Worktree to zwykłe worktree Gita z własną gałęzią
/rewind w Cursor CLINa liście poleceń slash CLI, bez definicji28 sierpnia 2026Nic. Ta strona dotyczy edytora

Szczegóły mogą się zmieniać między wydaniami Cursora, więc raz, na swojej wersji, wykonaj krótki test zasięgu z następnej sekcji. Pokaże ci dokładnie, czego dotyka przywrócenie.

Traktuj checkpoint jako szybkie cofnięcie kilku ostatnich tur agenta w bieżącym czacie. Wszystko, co chcesz zachować, traktuj jako commit. Z samej natury checkpointu, niezależnie od wersji Cursora, wynikają dwa ograniczenia:

  • Przywraca pliki, nie świat. Jeśli agent uruchomił migrację bazy, zainstalował pakiet, usunął wolumen Dockera albo wypchnął gałąź, przywrócenie plików niczego z tego nie odwróci.
  • Przywraca migawkę, nie twoją intencję. Jeśli po turze agenta ręcznie zmieniłeś plik, przywrócenie checkpointu sprzed tej tury cofa plik do migawki. Twoja ręczna zmiana znika razem z nim, chyba że wcześniej ją zacommitowałeś.

Żeby sprawdzić, jak działa twoja wersja, raz wykonaj ten test na gałęzi roboczej:

  1. Utwórz gałąź do wyrzucenia: git switch -c scratch/checkpoint-test.
  2. Poproś agenta: „Add a comment line to README.md, create tmp-checkpoint-test.txt containing hello, then run echo ran >> tmp-command-log.txt in the terminal.”
  3. Ręcznie dopisz w README.md drugą, własną linię.
  4. Przywróć w czacie checkpoint sprzed tej tury agenta.
  5. Uruchom git status --short i cat README.md. Zanotuj, które z trzech plików wróciły, zniknęły albo zachowały zmiany i czy przetrwała twoja ręczna linia.
  6. Posprzątaj: git switch - i git branch -D scratch/checkpoint-test, a potem usuń pozostałe pliki testowe.

Niezależnie od wyniku poniższa rutyna od niego nie zależy: warstwą, której ufasz, jest Git.

Ustaw rutynę checkpointów i gałęzi dla każdego zadania agenta

Dział zatytułowany „Ustaw rutynę checkpointów i gałęzi dla każdego zadania agenta”

Checkpoint obejmuje jedną turę, Git całą resztę. Poniższa rutyna dodaje kilka sekund na zadanie i sprawia, że każdą turę można wyrzucić.

  1. Zacznij od czystego stanu. Uruchom git status --short. Jeśli coś wypisze, zacommituj to albo odłóż (git stash push -m "before agent"), żeby jedynymi zmianami w drzewie roboczym były zmiany agenta.

  2. Jedna gałąź na zadanie. Uruchom git switch -c agent/login-refactor. Skoro jedno zadanie to jedna gałąź, usunięcie gałęzi zawsze cofa wszystko.

  3. Daj agentowi zakres i sprawdzenie. Wymień katalogi, których wolno mu dotykać, i polecenie, które udowadnia, że zmiana działa. Użyj poniższego promptu z zakresem. Przy ryzykownych zmianach najpierw poproś o plan; tryby agenta w Cursorze wyjaśniają, kiedy lepiej zacząć od trybu Plan.

  4. Sprawdź turę, zanim ją zachowasz. Uruchom sprawdzenie zakresu i bramki jakości (następna sekcja). Jeśli tura nie przejdzie, przywróć jej checkpoint albo odrzuć plik Gitem i zleć poprawkę.

  5. Commituj każdą zieloną turę. git add -A && git commit -m "agent: extract session token validation". Każdy commit to punkt przywracania, który przetrwa restart, nowy czat i zmianę narzędzia. Jeśli zespół woli jeden commit na zmianę, spłaszcz historię przy otwieraniu pull requesta.

Zachować czy odrzucić turę agenta, nie czytając każdej linii

Dział zatytułowany „Zachować czy odrzucić turę agenta, nie czytając każdej linii”

O zachowaniu tury decydujesz na podstawie dowodów, a nie lektury całego diffa. Trzy sprawdzenia, w tej kolejności, szybko dają odpowiedź.

1. Czy agent trzymał się zakresu? To polecenie wypisuje każdy zmieniony lub nowy plik spoza dozwolonych ścieżek, a gdy takich nie ma, wypisuje scope OK. Uruchamiasz je w terminalu w katalogu głównym repozytorium:

Okno terminala
{ git diff --name-only HEAD; git ls-files --others --exclude-standard; } \
| grep -v -E '^(src/auth/|tests/auth/)' || echo "scope OK"

Każdy wypisany plik to zmiana, o którą nie prosiłeś. Odrzuć ją poleceniem git restore --source=HEAD -- src/db/pool.ts (plik śledzony) albo usuń plik (nowy), a potem powiedz agentowi dlaczego.

2. Czy bramki przechodzą na drzewie roboczym? Uruchom te same polecenia co CI, zamiast wierzyć podsumowaniu agenta: npm run typecheck && npm run lint && npm test. „Wszystkie testy przechodzą” od agenta to deklaracja; kod wyjścia to dowód.

3. Czy nowy test dowodzi zachowania? Test, który przechodzi na starym kodzie, niczego nie dowodzi. Odłóż pliki implementacji, zostaw test i go uruchom:

Okno terminala
git stash push -u -- src/auth/ # odłóż implementację, zostaw tests/auth/
npm test -- tests/auth # tu nowy test MUSI nie przejść
git stash pop # przywróć implementację
npm test -- tests/auth # a tu MUSI przejść

Sprawdź, że test pada na asercji o zachowaniu, a nie na brakującym imporcie. Przy czystym refaktoringu nie ma nowego zachowania do udowodnienia; dowodem jest to, że istniejące testy przechodzą przed zmianą i po niej. Przebieg „nie przechodzi, potem przechodzi” stosuj, gdy tura dodaje zachowanie, na przykład w zadaniu z ograniczaniem liczby żądań.

Jeśli test przechodzi w obu przebiegach, poproś agenta o test, który bez zmiany nie przechodzi. Oczekiwane zachowanie zapisz najpierw jako kryteria akceptacji i użyj pętli test-first w Cursorze.

Dopiero wtedy czytaj diff, i tylko tam, gdzie sprawdzenia nic nie mówią: publiczne interfejsy, kod istotny dla bezpieczeństwa i wszystko, czego testy nie wykonują. Pull request niesie wynik sprawdzenia zakresu, wyjście bramek i przebieg „nie przechodzi, potem przechodzi” jako swój pakiet dowodów. Zmianę zatwierdzasz ty jako właściciel gałęzi, CI ponownie uruchamia bramki, a recenzent postępuje według procesu code review w Cursorze przyjętego w twoim zespole.

Wybierz najmniejsze cofnięcie, które usuwa złą zmianę i zostawia dobrą.

SytuacjaUżyjPolecenie lub czynność
Ostatnia tura agenta jest zła, a od tego czasu nic nie commitowałeśPrzywrócenie checkpointuPrzywróć w czacie checkpoint sprzed tej tury
Jeden lub dwa pliki są poza zakresem, reszta jest dobraGit, po plikugit restore --source=HEAD -- PATH dla plików śledzonych; nowe pliki usuń
Część pliku jest dobra, część nieGit, po fragmenciegit restore -p -- PATH i y przy każdym fragmencie do odrzucenia
Zła jest tura, którą już zacommitowałeśGit, nowy commitgit revert COMMIT zachowuje historię
Złe są ostatnie commity na gałęzi agentaGit, przesunięcie gałęzigit reset --hard COMMIT, tylko na gałęzi, której nikt poza tobą nie używa
Całe podejście jest złeUsunięcie gałęzigit switch main && git branch -D agent/login-refactor
Agent uruchomił migrację albo zmienił usługęŻadne z powyższychWycofaj migrację (polecenie down/rollback narzędzia migracji) albo odtwórz lokalną bazę; zobacz awarie poniżej

PATH to ścieżka pliku, a COMMIT to hash commita z git log --oneline. Jeśli cofniesz się za daleko, git reflog pokaże każdą pozycję gałęzi, a git reset --hard HEAD@{1} przesunie ją z powrotem.

Gdy nie wiesz, który projekt rozwiązania jest właściwy, daj każdej próbie osobną gałąź, zamiast cofać się tam i z powrotem w jednym czacie.

Gałęzie eksperymentów nazywaj obok gałęzi funkcji, a nie pod nią. Git przechowuje feature/payments jako plik, więc nie utworzy katalogu o tej samej nazwie. git switch -c feature/payments/stripe kończy się błędem fatal: cannot lock ref ... 'refs/heads/feature/payments' exists. Użyj osobnego prefiksu:

Okno terminala
git switch -c feature/payments # gałąź, którą scalisz
git switch -c try/payments-queue # próba A, od feature/payments
# ...agent pracuje, bramki przechodzą, commitujesz...
git switch feature/payments
git switch -c try/payments-outbox # próba B, z tego samego punktu wyjścia
# ...porównujesz i zostawiasz zwycięzcę:
git switch feature/payments
git merge --squash try/payments-outbox && git commit -m "payments: outbox-based retries"
git branch -D try/payments-queue try/payments-outbox

git branch -D jest potrzebne po scaleniu z --squash, bo Git nie uznaje spłaszczonej gałęzi za scaloną.

Żeby prowadzić próbę B, gdy próba A jest wciąż otwarta, utwórz ją w worktree Gita zamiast przez git switch -c. Worktree to drugi checkout we własnym katalogu; otwórz ten katalog w drugim oknie Cursora:

Okno terminala
git worktree add -b try/payments-outbox ../myapp-outbox feature/payments
# otwórz ../myapp-outbox w nowym oknie Cursora i tam uruchom agenta
git worktree remove ../myapp-outbox # gdy skończysz

Nowe worktree nie ma zainstalowanych zależności ani nieśledzonych plików, takich jak .env.local. Zanim agent zacznie, uruchom tam swój skrypt przygotowania środowiska. Cursor potrafi też sam tworzyć worktree dla swoich agentów; uruchamianie kilku agentów naraz i porównywanie tego samego zadania w kilku próbach opisuje strona Okno Agents i Projects w Cursorze.

Oceniaj próby na tych samych dowodach: tych samych testach, sprawdzeniu zakresu i rozmiarze diffa (git diff --stat feature/payments..try/payments-outbox). Gdy obie przechodzą, wybierz mniejszy diff.

Opcja przywrócenia zniknęła. Zacząłeś nowy czat albo czat z checkpointem nie jest już dostępny. Wyjście: git status i git diff pokazują dokładnie, co się zmieniło od ostatniego commita. Odrzuć to przez git restore . dla plików śledzonych i git clean -n (najpierw podgląd bez usuwania, potem git clean -f) dla nowych plików. Właśnie dlatego krok 5 rutyny commituje każdą zieloną turę.

Przywrócenie skasowało twoje własne zmiany. Po turze agenta ręcznie zmieniłeś plik, a potem przywróciłeś checkpoint sprzed tej tury. Wyjście: jeśli wcześniej zrobiłeś commit albo stash, git stash pop lub git checkout COMMIT -- PATH przywróci twoją zmianę. W przeciwnym razie napisz ją ponownie i odtąd commituj ręczne zmiany przed każdym przywróceniem.

Kod wrócił, a baza nie. Agent uruchomił migrację albo skrypt seedujący, a przywrócenie plików zostawiło schemat w nowym stanie. Wyjście: uruchom polecenie cofnięcia migracji w swoim narzędziu albo odtwórz lokalną bazę od zera. Zapobieganie: jedna jednorazowa lokalna baza na gałąź i wymóg zatwierdzania poleceń ze skutkami ubocznymi; zobacz uprawnienia i sandboxing agentów.

fatal: cannot lock ref przy tworzeniu gałęzi. Gałąź feature/payments blokuje każdą gałąź feature/payments/.... Wyjście: użyj osobnego prefiksu na tym samym poziomie, np. try/payments-queue.

fatal: 'try/payments-outbox' is already used by worktree. Git pozwala, by gałąź była pobrana (checked out) naraz tylko w jednym worktree. Wyjście: otwórz istniejące worktree (git worktree list pokaże, gdzie jest) albo utwórz odłączoną kopię: git worktree add --detach ../verify try/payments-outbox.

Agent wciąż zmienia pliki, które już zacommitowałeś. Długie czaty ciągną za sobą wcześniejsze plany, więc agent „ulepsza” pracę, którą już przyjąłeś. Wyjście: nowy czat na każde zadanie, ponownie podany zakres i dopisek w prompcie „Do not modify files that git diff HEAD does not list unless I ask”. Resztę wyłapie sprawdzenie zakresu.

Reset poszedł za daleko. Wyjście: git reflog pokazuje commit sprzed resetu; git reset --hard HEAD@{1} wraca do niego.

Ta strona dotyczy Cursora. Claude Code ma własne checkpointy, dostępne przez /rewind albo dwukrotne Esc przy pustym polu promptu; zobacz odzyskiwanie po błędach w Claude Code. Codex opiera się na Gicie (funkcja undo ma status removed w codex features list, codex-cli 0.157.1), a codex --worktree uruchamia sesję w nowym, zarządzanym worktree Gita (codex-cli 0.157.1); zobacz worktree w Codeksie. Rutyna gałęzi i trzy sprawdzenia z tej strony działają w obu bez zmian.