# About detached heads

22 messages from 2008-03-14 to 2008-03-15. Participants: Geoff Russell, Jonathan del Strother, Wincent Colaiuta, David Kågedal, Matthieu Moy, Jakub Narebski, Sergei Organov, Adam Piatyszek, Chris Shoemaker, Rafael Garcia-Suarez, Nicolas Pitre, Linus Torvalds, Björn Steinbrink, Sean.
Thread: https://gitlist.dev/t/12686

## Geoff Russell, 2008-03-14 09:46

Subject: About detached heads
Message-ID: <93c3eada0803140246k53408c74m21f9dc277857202d@mail.gmail.com>
URL: https://gitlist.dev/e/93c3eada0803140246k53408c74m21f9dc277857202d%40mail.gmail.com

```
This should be simple! I have a series of commits:

           1---2---3---4---5

I want to go back to 3 but not branch, so I want

           1---2---3---4---5---3

?

         git checkout 3...

gets me the commit on a detached head, but I don't know how to put this back
as the HEAD.

I'm on git 1.5.0.5

Cheers,
Geoff Russell

```

## Jonathan del Strother, 2008-03-14 09:51

Subject: Re: About detached heads
Message-ID: <57518fd10803140251v425a0fa3ud11687a5043806cc@mail.gmail.com>
URL: https://gitlist.dev/e/57518fd10803140251v425a0fa3ud11687a5043806cc%40mail.gmail.com
In-Reply-To: <93c3eada0803140246k53408c74m21f9dc277857202d@mail.gmail.com>

```
On Fri, Mar 14, 2008 at 9:46 AM, Geoff Russell
<geoffrey.russell@gmail.com> wrote:
> This should be simple! I have a series of commits:
>
>            1---2---3---4---5
>
>  I want to go back to 3 but not branch, so I want
>
>            1---2---3---4---5---3
>
>  ?
>
>          git checkout 3...
>
>  gets me the commit on a detached head, but I don't know how to put this back
>  as the HEAD.


Two options.  Either rewrite history, nuking commits 4 & 5 :
  git reset --hard 3

or publicly reverse the changes introduced by 5 & 4 :
  git revert 5
  git revert 4

Jon

```

## Wincent Colaiuta, 2008-03-14 10:15

Subject: Re: About detached heads
Message-ID: <9A4AC53D-BCFA-4BEE-BD53-AA7F29781454@wincent.com>
URL: https://gitlist.dev/e/9A4AC53D-BCFA-4BEE-BD53-AA7F29781454%40wincent.com
In-Reply-To: <93c3eada0803140246k53408c74m21f9dc277857202d@mail.gmail.com>

```
El 14/3/2008, a las 10:46, Geoff Russell escribió:

> This should be simple! I have a series of commits:
>
>           1---2---3---4---5
>
> I want to go back to 3 but not branch, so I want
>
>           1---2---3---4---5---3
>
> ?
>
>         git checkout 3...
>
> gets me the commit on a detached head, but I don't know how to put  
> this back
> as the HEAD.
>
> I'm on git 1.5.0.5

How about?

   git cherry-pick the-sha-1-id-of-commit-3

Wincent

```

## David Kågedal, 2008-03-14 10:39

Subject: Re: About detached heads
Message-ID: <87iqzpfv3l.fsf@lysator.liu.se>
URL: https://gitlist.dev/e/87iqzpfv3l.fsf%40lysator.liu.se
In-Reply-To: <57518fd10803140251v425a0fa3ud11687a5043806cc@mail.gmail.com>

```
"Jonathan del Strother" <maillist@steelskies.com> writes:

> On Fri, Mar 14, 2008 at 9:46 AM, Geoff Russell
> <geoffrey.russell@gmail.com> wrote:
>> This should be simple! I have a series of commits:
>>
>>            1---2---3---4---5
>>
>>  I want to go back to 3 but not branch, so I want
>>
>>            1---2---3---4---5---3
>>
>>  ?
>>
>>          git checkout 3...
>>
>>  gets me the commit on a detached head, but I don't know how to put this back
>>  as the HEAD.
>
>
> Two options.  Either rewrite history, nuking commits 4 & 5 :
>   git reset --hard 3
>
> or publicly reverse the changes introduced by 5 & 4 :
>   git revert 5
>   git revert 4

The revert can be done by resetting to the tree in 3:

  git checkout 3 -- .
  git commit -m "reset to 3"

-- 
David Kågedal

```

## Matthieu Moy, 2008-03-14 10:48

Subject: Re: About detached heads
Message-ID: <vpq1w6dvaxe.fsf@bauges.imag.fr>
URL: https://gitlist.dev/e/vpq1w6dvaxe.fsf%40bauges.imag.fr
In-Reply-To: <9A4AC53D-BCFA-4BEE-BD53-AA7F29781454@wincent.com>

```
Wincent Colaiuta <win@wincent.com> writes:

> El 14/3/2008, a las 10:46, Geoff Russell escribió:
>
>> This should be simple! I have a series of commits:
>>
>>           1---2---3---4---5
>>
>> I want to go back to 3 but not branch, so I want
>>
>>           1---2---3---4---5---3
>
> How about?
>
>   git cherry-pick the-sha-1-id-of-commit-3

Correct me if I'm wrong, but I believe this will try to re-apply
commit 3 (probably a no-op since commit 3 is already in the history,
perhaps tons of conflicts if 4 and 5 touched the same pieces of code).

The OP wants to keep commit 3, and to revert commits 4 and 5. As
mentionned in other messages, either "git revert" 4 and 5, or just
commit a new revision with the same tree as 3 had.

-- 
Matthieu

```

## Jakub Narebski, 2008-03-14 10:52

Subject: Re: About detached heads
Message-ID: <m3lk4ly3vy.fsf@localhost.localdomain>
URL: https://gitlist.dev/e/m3lk4ly3vy.fsf%40localhost.localdomain
In-Reply-To: <93c3eada0803140246k53408c74m21f9dc277857202d@mail.gmail.com>

```
"Geoff Russell" <geoffrey.russell@gmail.com> writes:

> This should be simple! I have a series of commits:
> 
>            1---2---3---4---5
> 
> I want to go back to 3 but not branch, so I want
> 
>            1---2---3---4---5---3
> 
> ?
> 
>          git checkout 3...
> 
> gets me the commit on a detached head, but I don't know how to put this back
> as the HEAD.

Lets check what git does in each of scenarios. Let's assume that
current branch is named 'master'.

At beginning we have:

   1---2---3---4---5    <--- master <--- HEAD

HEAD contents is "ref: refs/heads/master"

1. Now, "git checkout 3...", which is equivalent to "git checkout 3",
detaches HEAD because commit '3' is not a head (is not a branch), so
we have:

   1---2---3---4---5    <--- master
           ^
            \ 
             \-------------- HEAD

HEAD contents is "<sha1 of 3>"


2. If we did "git reset --hard 3" we would rewind the history,
resulting in the following situation:

   1---2---3           <--- master <--- HEAD
            \           
             \-4---5   <... master@{1}, ORIG_HEAD, HEAD@{1}
              
and now commits 4 and 5 are referenced only by reflogs, and by the
(temporary) "last position of HEAD" reference named ORIG_HEAD.


3. Now, if you have published 1..5 history you would not want
(usually) to rewind published branch. If you do the following:

  $ git revert --no-commit 5
  $ git revert 4

you would get the following:

   1---2---3---4---5---(5^-1 4^-1 => 3)  <--- master <--- HEAD

git-revert applies reversal of changes in given commit, in the 
"patch -R" ("patch --reverse") sense. Using '--no-commit' option
allows to squash reverting two commits into one commit. The ordering
of reverting ensures that there are no merge conflicts.


4. Or you can just put the _contents_ of revision 3 into your working
tree, either using plumbing command git-read-tree, or by checking out
or resetting to top tree: "git checkout 3^{tree}", or 
"git checkout 3 -- .", or equivalent git-reset invocation.

This way you would get exactly

   1---2---3---4---5---3   <--- master <--- HEAD

but the relation of 5---3 parentage is unclear: you would have to
explain it in the commit mesage.

HTH
-- 
Jakub Narebski
Poland
ShadeHawk on #git

```

## Wincent Colaiuta, 2008-03-14 11:17

Subject: Re: About detached heads
Message-ID: <E1DAC955-38CC-495B-9DCA-B25847EFF6C4@wincent.com>
URL: https://gitlist.dev/e/E1DAC955-38CC-495B-9DCA-B25847EFF6C4%40wincent.com
In-Reply-To: <vpq1w6dvaxe.fsf@bauges.imag.fr>

```
El 14/3/2008, a las 11:48, Matthieu Moy escribió:

> Wincent Colaiuta <win@wincent.com> writes:
>
>> El 14/3/2008, a las 10:46, Geoff Russell escribió:
>>
>>> This should be simple! I have a series of commits:
>>>
>>>          1---2---3---4---5
>>>
>>> I want to go back to 3 but not branch, so I want
>>>
>>>          1---2---3---4---5---3
>>
>> How about?
>>
>>  git cherry-pick the-sha-1-id-of-commit-3
>
> Correct me if I'm wrong, but I believe this will try to re-apply
> commit 3 (probably a no-op since commit 3 is already in the history,
> perhaps tons of conflicts if 4 and 5 touched the same pieces of code).

I thought the OP was saying that 4 and 5 somehow undid the effect of 3  
and he wanted to reapply it. But he probably meant what you said, he  
just wants to reset back to 3.

Wincent

```

## Sergei Organov, 2008-03-14 12:16

Subject: Re: About detached heads
Message-ID: <87lk4lo60k.fsf@osv.gnss.ru>
URL: https://gitlist.dev/e/87lk4lo60k.fsf%40osv.gnss.ru
In-Reply-To: <m3lk4ly3vy.fsf@localhost.localdomain>

```
Jakub Narebski <jnareb@gmail.com> writes:

[...]

> 3. Now, if you have published 1..5 history you would not want
> (usually) to rewind published branch. If you do the following:
>
>   $ git revert --no-commit 5

the working tree in now dirty...

>   $ git revert 4

and this one fails with dirty tree :(

Probably:

$ git revert -n 5 && git revert -n 4 && git commit -a


BTW, why git-revert doesn't take a range? Is there some fundamental
problem with it?

-- Sergei.

```

## Adam Piatyszek, 2008-03-14 12:28

Subject: Re: About detached heads
Message-ID: <47DA6F89.3080609@users.sourceforge.net>
URL: https://gitlist.dev/e/47DA6F89.3080609%40users.sourceforge.net
In-Reply-To: <m3lk4ly3vy.fsf@localhost.localdomain>

```
* Jakub Narebski [14 III 2008 11:52]:
 > Lets check what git does in each of scenarios. Let's assume that
 > current branch is named 'master'.
 >
 > At beginning we have:
 >
 >    1---2---3---4---5    <--- master <--- HEAD
 >
 > HEAD contents is "ref: refs/heads/master"
 >
 > 1. Now, "git checkout 3...", which is equivalent to "git checkout 3",
 > detaches HEAD because commit '3' is not a head (is not a branch), so
 > we have:
 >
 >    1---2---3---4---5    <--- master
 >            ^
 >             \
 >              \-------------- HEAD
 >
 > HEAD contents is "<sha1 of 3>"
 >
 >
 > 2. If we did "git reset --hard 3" we would rewind the history,
 > resulting in the following situation:
 >
 >    1---2---3           <--- master <--- HEAD
 >             \
 >              \-4---5   <... master@{1}, ORIG_HEAD, HEAD@{1}
 >
 > and now commits 4 and 5 are referenced only by reflogs, and by the
 > (temporary) "last position of HEAD" reference named ORIG_HEAD.
 >
 >
 > 3. Now, if you have published 1..5 history you would not want
 > (usually) to rewind published branch. If you do the following:
 >
 >   $ git revert --no-commit 5
 >   $ git revert 4
 >
 > you would get the following:
 >
 >    1---2---3---4---5---(5^-1 4^-1 => 3)  <--- master <--- HEAD
 >
 > git-revert applies reversal of changes in given commit, in the
 > "patch -R" ("patch --reverse") sense. Using '--no-commit' option
 > allows to squash reverting two commits into one commit. The ordering
 > of reverting ensures that there are no merge conflicts.
 >
 >
 > 4. Or you can just put the _contents_ of revision 3 into your working
 > tree, either using plumbing command git-read-tree, or by checking out
 > or resetting to top tree: "git checkout 3^{tree}", or
 > "git checkout 3 -- .", or equivalent git-reset invocation.
 >
 > This way you would get exactly
 >
 >    1---2---3---4---5---3   <--- master <--- HEAD
 >
 > but the relation of 5---3 parentage is unclear: you would have to
 > explain it in the commit mesage.

I suggest one should add the above nice explanation to FAQ or some wiki 
material.

BR,
/Adam

-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.

```

## Chris Shoemaker, 2008-03-14 13:42

Subject: Re: About detached heads
Message-ID: <20080314134205.GA19674@pe.Belkin>
URL: https://gitlist.dev/e/20080314134205.GA19674%40pe.Belkin
In-Reply-To: <m3lk4ly3vy.fsf@localhost.localdomain>

```
On Fri, Mar 14, 2008 at 03:52:14AM -0700, Jakub Narebski wrote:
> "Geoff Russell" <geoffrey.russell@gmail.com> writes:
> 
> > This should be simple! I have a series of commits:
> > 
> >            1---2---3---4---5
> > 
> > I want to go back to 3 but not branch, so I want
> > 
> >            1---2---3---4---5---3
> > 
> > ?
> > 
> >          git checkout 3...
> > 
> > gets me the commit on a detached head, but I don't know how to put this back
> > as the HEAD.
> 
> Lets check what git does in each of scenarios. Let's assume that
> current branch is named 'master'.
> 
> At beginning we have:
> 
>    1---2---3---4---5    <--- master <--- HEAD
> 
> HEAD contents is "ref: refs/heads/master"
> 
> 1. Now, "git checkout 3...", which is equivalent to "git checkout 3",
> detaches HEAD because commit '3' is not a head (is not a branch), so
> we have:
> 
>    1---2---3---4---5    <--- master
>            ^
>             \ 
>              \-------------- HEAD
> 
> HEAD contents is "<sha1 of 3>"
> 
> 
> 2. If we did "git reset --hard 3" we would rewind the history,
> resulting in the following situation:
> 
>    1---2---3           <--- master <--- HEAD
>             \           
>              \-4---5   <... master@{1}, ORIG_HEAD, HEAD@{1}
>               
> and now commits 4 and 5 are referenced only by reflogs, and by the
> (temporary) "last position of HEAD" reference named ORIG_HEAD.
> 
> 
> 3. Now, if you have published 1..5 history you would not want
> (usually) to rewind published branch. If you do the following:
> 
>   $ git revert --no-commit 5
>   $ git revert 4
> 
> you would get the following:
> 
>    1---2---3---4---5---(5^-1 4^-1 => 3)  <--- master <--- HEAD
> 
> git-revert applies reversal of changes in given commit, in the 
> "patch -R" ("patch --reverse") sense. Using '--no-commit' option
> allows to squash reverting two commits into one commit. The ordering
> of reverting ensures that there are no merge conflicts.
> 
> 
> 4. Or you can just put the _contents_ of revision 3 into your working
> tree, either using plumbing command git-read-tree, or by checking out
> or resetting to top tree: "git checkout 3^{tree}", or 
> "git checkout 3 -- .", or equivalent git-reset invocation.
> 
> This way you would get exactly
> 
>    1---2---3---4---5---3   <--- master <--- HEAD
> 
> but the relation of 5---3 parentage is unclear: you would have to
> explain it in the commit mesage.

[Great explanation.  Let me offer one minor clarification:]

 This way you would get exactly:
 
    1---2---3---4---5---3'   <--- master <--- HEAD
 
 While the 3' commit has the same contents as 3, it is a new, distinct
 commit with its own history.  Its commit message should explain why
 you want to go from 5 back to the contents of 3.

-chris

```

## Rafael Garcia-Suarez, 2008-03-14 14:53

Subject: Re: About detached heads
Message-ID: <b77c1dce0803140753w21515021u4541796d6e6934b@mail.gmail.com>
URL: https://gitlist.dev/e/b77c1dce0803140753w21515021u4541796d6e6934b%40mail.gmail.com
In-Reply-To: <20080314134205.GA19674@pe.Belkin>

```
On 14/03/2008, Chris Shoemaker wrote:
>   This way you would get exactly:
>
>     1---2---3---4---5---3'   <--- master <--- HEAD
>
>
>  While the 3' commit has the same contents as 3, it is a new, distinct
>   commit with its own history.  Its commit message should explain why
>   you want to go from 5 back to the contents of 3.

Just a small question -- does that mean that 3 and 3' share the same
tree object ?

```

## Nicolas Pitre, 2008-03-14 15:19

Subject: Re: About detached heads
Message-ID: <alpine.LFD.1.00.0803141117040.2947@xanadu.home>
URL: https://gitlist.dev/e/alpine.LFD.1.00.0803141117040.2947%40xanadu.home
In-Reply-To: <b77c1dce0803140753w21515021u4541796d6e6934b@mail.gmail.com>

```
On Fri, 14 Mar 2008, Rafael Garcia-Suarez wrote:

> On 14/03/2008, Chris Shoemaker wrote:
> >   This way you would get exactly:
> >
> >     1---2---3---4---5---3'   <--- master <--- HEAD
> >
> >
> >  While the 3' commit has the same contents as 3, it is a new, distinct
> >   commit with its own history.  Its commit message should explain why
> >   you want to go from 5 back to the contents of 3.
> 
> Just a small question -- does that mean that 3 and 3' share the same
> tree object ?

Yes.  However, they don't share the same parent in the commit object, so 
even if the commit text was the same and the time stamps were forced to 
be the same, the commit 3' won't have the same SHA1.


Nicolas

```

## Jakub Narebski, 2008-03-14 15:21

Subject: Re: About detached heads
Message-ID: <200803141621.48321.jnareb@gmail.com>
URL: https://gitlist.dev/e/200803141621.48321.jnareb%40gmail.com
In-Reply-To: <b77c1dce0803140753w21515021u4541796d6e6934b@mail.gmail.com>

```
On Fri, 14 Mar 2008, Rafael Garcia-Suarez wrote:
> On 14/03/2008, Chris Shoemaker wrote:
>>
>>   This way you would get exactly:
>>
>>     1---2---3---4---5---3'   <--- master <--- HEAD
>>
>>
>>  While the 3' commit has the same contents as 3, it is a new, distinct
>>   commit with its own history.  Its commit message should explain why
>>   you want to go from 5 back to the contents of 3.
> 
> Just a small question -- does that mean that 3 and 3' share the same
> tree object ?

Yes it does. 

Commit object has link to a tree object in the form
of its sha1 id, and repository's object store is content addressed,
or to be more exact sha-1 id of contents addressed.

-- 
Jakub Narebski
Poland

```

## Linus Torvalds, 2008-03-14 17:53

Subject: Re: About detached heads
Message-ID: <alpine.LFD.1.00.0803141041080.3557@woody.linux-foundation.org>
URL: https://gitlist.dev/e/alpine.LFD.1.00.0803141041080.3557%40woody.linux-foundation.org
In-Reply-To: <93c3eada0803140246k53408c74m21f9dc277857202d@mail.gmail.com>

```


On Fri, 14 Mar 2008, Geoff Russell wrote:
>
> This should be simple! I have a series of commits:
> 
>            1---2---3---4---5
> 
> I want to go back to 3 but not branch, so I want
> 
>            1---2---3---4---5---3

This is actually an uncommonly easy operation for core git, but it's a 
very unusual thing to want to do in general, so I don't think there is any 
high-level command to do it directly. But it's really easy to do with 
a single so-called "plumbing" command, namely "git read-tree".

So the "core git" way to do it is to literally just do

	git read-tree -u -m 3
	git commit

(or use "--reset" instead of "-m" if you want to do it even in the 
presense unmerged entries).

What the above does is to literally just read the tree state at "3", and 
make it the new index: the "-u" means that we also want to update the 
working tree to that state, and the "-m" means that we will merge in the 
old index stat information.

The commit then will then create the actual new commit: it will have the 
exact same tree as your commit '3', but it will be a new commit (so call 
it 3').

Of course, people have already pointed out that another easy way to do it 
is to just revert 5 and 4. That may be the more high-level way to do it, 
but the git-read-tree approach actually has the advantage that it will 
work even across merges etc, and it will be very unambiguous: we want 
*exactly* the state at commit 3 back, nothing else.

			Linus

```

## Björn Steinbrink, 2008-03-14 18:37

Subject: Re: About detached heads
Message-ID: <20080314183731.GA2994@atjola.homenet>
URL: https://gitlist.dev/e/20080314183731.GA2994%40atjola.homenet
In-Reply-To: <alpine.LFD.1.00.0803141041080.3557@woody.linux-foundation.org>

```
On 2008.03.14 10:53:25 -0700, Linus Torvalds wrote:
> 
> 
> On Fri, 14 Mar 2008, Geoff Russell wrote:
> >
> > This should be simple! I have a series of commits:
> > 
> >            1---2---3---4---5
> > 
> > I want to go back to 3 but not branch, so I want
> > 
> >            1---2---3---4---5---3
> 
> This is actually an uncommonly easy operation for core git, but it's a 
> very unusual thing to want to do in general, so I don't think there is any 
> high-level command to do it directly. But it's really easy to do with 
> a single so-called "plumbing" command, namely "git read-tree".
> 
> So the "core git" way to do it is to literally just do
> 
> 	git read-tree -u -m 3
> 	git commit
> 
> (or use "--reset" instead of "-m" if you want to do it even in the 
> presense unmerged entries).
> 
> What the above does is to literally just read the tree state at "3", and 
> make it the new index: the "-u" means that we also want to update the 
> working tree to that state, and the "-m" means that we will merge in the 
> old index stat information.
> 
> The commit then will then create the actual new commit: it will have the 
> exact same tree as your commit '3', but it will be a new commit (so call 
> it 3').
> 
> Of course, people have already pointed out that another easy way to do it 
> is to just revert 5 and 4. That may be the more high-level way to do it, 
> but the git-read-tree approach actually has the advantage that it will 
> work even across merges etc, and it will be very unambiguous: we want 
> *exactly* the state at commit 3 back, nothing else.

Hm, that's just squashing revert commit. Squashing can be done via:
git reset --soft HEAD~5    # Or wherever your squashed commit should start
git commit -m "Squashed from HEAD~5 onwards"

Now the "revert" version of that:
git reset --hard HEAD~5      # Go back to the state that we want
git reset --soft ORIG_HEAD   # Move HEAD back, but keep the index as is
git commit -m "Back at the state of HEAD~5"

AFAICT that should have the same advantages as using read-tree, but
doesn't feel so low-level :-)

Björn

```

## Linus Torvalds, 2008-03-14 18:51

Subject: Re: About detached heads
Message-ID: <alpine.LFD.1.00.0803141150070.3557@woody.linux-foundation.org>
URL: https://gitlist.dev/e/alpine.LFD.1.00.0803141150070.3557%40woody.linux-foundation.org
In-Reply-To: <20080314183731.GA2994@atjola.homenet>

```


On Fri, 14 Mar 2008, Bj?rn Steinbrink wrote:
> 
> Hm, that's just squashing revert commit. Squashing can be done via:
> git reset --soft HEAD~5    # Or wherever your squashed commit should start
> git commit -m "Squashed from HEAD~5 onwards"
> 
> Now the "revert" version of that:
> git reset --hard HEAD~5      # Go back to the state that we want
> git reset --soft ORIG_HEAD   # Move HEAD back, but keep the index as is
> git commit -m "Back at the state of HEAD~5"
> 
> AFAICT that should have the same advantages as using read-tree, but
> doesn't feel so low-level :-)

Umm. The low-level one is a *lot* easier to understand than your 
"high-level" one, wouldn't you say?

And when the low-level plumbing commands are easier, are they not then 
better porcelain?

		Linus

```

## Jakub Narebski, 2008-03-14 19:11

Subject: Re: About detached heads
Message-ID: <m34pb9xgrp.fsf@localhost.localdomain>
URL: https://gitlist.dev/e/m34pb9xgrp.fsf%40localhost.localdomain
In-Reply-To: <alpine.LFD.1.00.0803141150070.3557@woody.linux-foundation.org>

```
Linus Torvalds <torvalds@linux-foundation.org> writes:

> On Fri, 14 Mar 2008, Bjorn Steinbrink wrote:
>> On 2008.03.14 10:53:25 -0700, Linus Torvalds wrote:
>>> 
>>> So the "core git" way to do it is to literally just do
>>> 
>>> 	git read-tree -u -m 3
>>> 	git commit
>>> 
>>> (or use "--reset" instead of "-m" if you want to do it even in the 
>>> presense unmerged entries).
>>> 
>> 
>> Hm, that's just squashing revert commit. Squashing can be done via:
>> git reset --soft HEAD~5    # Or wherever your squashed commit should start
>> git commit -m "Squashed from HEAD~5 onwards"
>> 
>> Now the "revert" version of that:
>> git reset --hard HEAD~5      # Go back to the state that we want
>> git reset --soft ORIG_HEAD   # Move HEAD back, but keep the index as is
>> git commit -m "Back at the state of HEAD~5"
>> 
>> AFAICT that should have the same advantages as using read-tree, but
>> doesn't feel so low-level :-)
> 
> Umm. The low-level one is a *lot* easier to understand than your 
> "high-level" one, wouldn't you say?
> 
> And when the low-level plumbing commands are easier, are they not then 
> better porcelain?

AFAIK the porcelain equivalent to plumbing

  git read-tree -u -m 3

is just

  git checkout 3 -- .

-- 
Jakub Narebski
Poland
ShadeHawk on #git

```

## Sean, 2008-03-14 19:17

Subject: Re: About detached heads
Message-ID: <BAYC1-PASMTP1563DCF0556F09CFE67BE8AE0A0@CEZ.ICE>
URL: https://gitlist.dev/e/BAYC1-PASMTP1563DCF0556F09CFE67BE8AE0A0%40CEZ.ICE
In-Reply-To: <m34pb9xgrp.fsf@localhost.localdomain>

```
On Fri, 14 Mar 2008 12:11:33 -0700 (PDT)
Jakub Narebski <jnareb@gmail.com> wrote:

> AFAIK the porcelain equivalent to plumbing
> 
>   git read-tree -u -m 3
> 
> is just
> 
>   git checkout 3 -- .

Hi Jakub,

   git checkout .   won't remove paths, so you could end up with extra
state that didn't exist in the earlier commit.

Sean

```

## Geoff Russell, 2008-03-14 23:43

Subject: Re: About detached heads
Message-ID: <93c3eada0803141643r2f2c4c56l9e59f2ee7b67a8ca@mail.gmail.com>
URL: https://gitlist.dev/e/93c3eada0803141643r2f2c4c56l9e59f2ee7b67a8ca%40mail.gmail.com
In-Reply-To: <BAYC1-PASMTP1563DCF0556F09CFE67BE8AE0A0@CEZ.ICE>

```
I thought my question was trivial, but judging by the number of answers, clearly
not!

I understand "git read-tree -u -m 3 ; git commit" and it does exactly
what I want.

The context where I want to use this is for users who update files,
can understand
"take me back to the state I was in at 4pm yesterday before I mucked up
my data" but who don't want to know about merging, branching, topics, etc, etc,
But of course having taken them back to the 4pm commit, they then realise that
they really need the 6pm commit or perhaps the 3pm commit. So anything which
just throws away commits would be risky.

The "git read-tree -u -m 3; git commit" allows me to present a simple
straight line
view of the data, which is perfect for the people I'm dealing with.

Many thanks to you all,

Cheers,
Geoff Russell

```

## Jakub Narebski, 2008-03-15 00:03

Subject: Re: About detached heads
Message-ID: <m3zlt0x39k.fsf@localhost.localdomain>
URL: https://gitlist.dev/e/m3zlt0x39k.fsf%40localhost.localdomain
In-Reply-To: <93c3eada0803141643r2f2c4c56l9e59f2ee7b67a8ca@mail.gmail.com>

```
"Geoff Russell" <geoffrey.russell@gmail.com> writes:

> I thought my question was trivial, but judging by the number of
> answers, clearly not!
> 
> I understand "git read-tree -u -m 3 ; git commit" and it does exactly
> what I want.
> 
> The context where I want to use this is for users who update files,
> can understand "take me back to the state I was in at 4pm yesterday
> before I mucked up my data" but who don't want to know about
> merging, branching, topics, etc, etc, But of course having taken
> them back to the 4pm commit, they then realise that they really need
> the 6pm commit or perhaps the 3pm commit. So anything which just
> throws away commits would be risky.

Thanks to the reflog even if they go the "git reset --hard 3" route,
the commits would be protected for gc.reflogExpireUnreachable period,
which defaults to 30 days, by reflog. After this period they could be
garbage-collected.

> The "git read-tree -u -m 3; git commit" allows me to present a
> simple straight line view of the data, which is perfect for the
> people I'm dealing with.

Simple, straight line with _rewinds_, i.e. not so simple history.

Unless you can expect users to find errors later than 30 days, or you
have pushed non-rewritable branch already, then "git reset --hard 3"
is IMHO a beter solution than "git read-file -u -m 3 && git commit -a".

-- 
Jakub Narebski
Poland
ShadeHawk on #git

```

## Nicolas Pitre, 2008-03-15 00:38

Subject: Re: About detached heads
Message-ID: <alpine.LFD.1.00.0803142025080.2947@xanadu.home>
URL: https://gitlist.dev/e/alpine.LFD.1.00.0803142025080.2947%40xanadu.home
In-Reply-To: <93c3eada0803141643r2f2c4c56l9e59f2ee7b67a8ca@mail.gmail.com>

```
On Sat, 15 Mar 2008, Geoff Russell wrote:

> The context where I want to use this is for users who update files,
> can understand
> "take me back to the state I was in at 4pm yesterday before I mucked up
> my data" but who don't want to know about merging, branching, topics, etc, etc,
> But of course having taken them back to the 4pm commit, they then realise that
> they really need the 6pm commit or perhaps the 3pm commit. So anything which
> just throws away commits would be risky.

The reflog can help you there as well.  You can simply do:

	git reset --hard HEAD@{yesterday.at.4pm}

and it'll magically bring you back to the state you were yesterday at 
4pm.  You need the 6pm state instead?  No problem: just ask for 
yesterday.at.6pm then.

And before doing the 'reset --hard', you might want to do a simple 
'checkout' beforehand so you can be sure it actually corresponds to what 
you want:

	git checkout HEAD@{yesterday.at.4pm}
	[compile, test, whatever]
	git checkout HEAD@{yesterday.at.6pm}
	[compile, test, whatever]

and when OK with it, then:

	# return to your master branch (or any other branch)
	git checkout master
	# then reset it to the desired state
	git reset --hard HEAD@{yesterday.at.6pm}


Nicolas

```

## Geoff Russell, 2008-03-15 02:03

Subject: Re: About detached heads
Message-ID: <93c3eada0803141903p30184defk979247129a1cc6db@mail.gmail.com>
URL: https://gitlist.dev/e/93c3eada0803141903p30184defk979247129a1cc6db%40mail.gmail.com
In-Reply-To: <alpine.LFD.1.00.0803142025080.2947@xanadu.home>

```
On 3/15/08, Nicolas Pitre <nico@cam.org> wrote:
> ...
>
>         git reset --hard HEAD@{yesterday.at.4pm}
>
>  and it'll magically bring you back to the state you were yesterday at
>  4pm.  You need the 6pm state instead?  No problem: just ask for
>  yesterday.at.6pm then.
>
>  And before doing the 'reset --hard', you might want to do a simple
>  'checkout' beforehand so you can be sure it actually corresponds to what
>  you want:
>
>         git checkout HEAD@{yesterday.at.4pm}
>         [compile, test, whatever]
>         git checkout HEAD@{yesterday.at.6pm}
>         [compile, test, whatever]
>
>  and when OK with it, then:
>
>         # return to your master branch (or any other branch)
>         git checkout master
>         # then reset it to the desired state
>         git reset --hard HEAD@{yesterday.at.6pm}
>
>
>
>  Nicolas

More useful advice ... many thanks.

Cheers,
Geoff.

```
