git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: How to revert to a specific commit?

From
Chris Torek <chris.torek@gmail.com>
Date
Dec 2, 2024, 12:39 UTC
Message-ID
<CAPx1Gve_dCRux9_cF7NTspomS4K=Hp_y74d94S-Hm0amuovUqQ@mail.gmail.com>
In-Reply-To
<CAFePT4zytyuLB0TgyJ+mbrNvz=Xt1x+gJv4e-2j07YK7Cg1bzw@mail.gmail.com>
On Mon, Dec 2, 2024 at 4:15 AM tao lv <thebookofunknowable@gmail.com> wrote:
> I want to revert the code to a specific commit. ...
OK, first some background:
 * A commit _is_ a full snapshot of every file, as of the state
   it had at the time you (or whoever) made that particular
   commit. Hence, if you want the particular files from a
   particular commit, you simply check out that (historical)
   commit.
Now:
Show 5 quoted lines
> I don't want to revert each individual commit; I just want to restore
> the code to this specific commit while retaining all the current
> history commits.
>
> How can I achieve this? Is there a better way than using the revert function?
Yes.
The mechanics of:
    git checkout <hash-ID-or-other-commit-specifier>
are twofold, and mean the same thing as:
    git switch --detach <same-hash-ID-etc>
That is, you are asking Git to:
 1) switch to the saved snapshot, and
 2) "detach HEAD".

Step 2 is your problem here because the jargon phrase "detach HEAD" means "stop being on any branch at all, just go to some historical commit". But you seem to want to subsequently make a *new* commit that contains the *old snapshot*, as if you had removed all the work you (or anyone else) had done since that point in time and put all the files back the way they were in the historical commit, *while remaining on your branch*, so that you are now ready to commit all the old versions of the files.

Note that this new commit, if and when you make it, simply sits atop the history (and / but, since every commit is a full snapshot of all files, it undoes all the *work* done since the restored commit -- though, since all commits are also *permanent*, that undone work can be redone trivially as well).

So, at this point, you have several options for achieving this goal, provided I have recapitulated your goal correctly. The most obvious, I think, is:

    git checkout [--detach] <hash>   # or git switch --detach <hash>
    git reset --soft <branch-name>

The checkout-or-switch does what it does, including detaching HEAD, and then the `git reset --soft` tells Git that it should re-attach `HEAD` to the given branch name, but not alter *either* the index / staging-area, *or* the working tree, leaving the historical versions of all files as "ready to commit".

=====
A different, and more direct, option is to use:
    git restore --no-overlay -S -W <hash>

The `git checkout` command can be used in place of this `git restore`, because `git checkout` itself is (in my opinion) overly complicated and stuffed full of modes, so that it has a mode in which it *doesn't* affect `HEAD`. Understanding this requires keeping in mind the way I described `git checkout` has having a step-1-then-step-2, even though the two-step `git checkout` actually very carefully *combines* the two steps (to avoid making any changes should the second step be about to fail for some reason). I find that describing checkout as two separate steps, and literally using an additional `git reset --soft` step, more explainable (Git is complicated! Nobody learns all of it, it is always changing over time! Those new to it find it very mysterious, and this is part of why).

Chris

(PS: the fact that you need `--no-overlay` with the single-step methods is another one of those picky little details that make Git tricky.)

Previous: tao lvNext: Junio C Hamano
Message 2 of 5 in “How to revert to a specific commit?”
  1. tao lvDec 2, 2024
  2. Chris TorekDec 2, 2024
  3. Junio C HamanoDec 3, 2024
  4. Chris TorekDec 3, 2024
  5. Matěj CeplDec 2, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.