Git development
 help / color / mirror / Atom feed
* Question: behavior when reverting a commit from a shallow clone
@ 2026-10-03  8:54 Sphinx
  2026-10-03 19:41 ` Carlisle T. Hamlin
  2026-10-05  6:57 ` Patrick Steinhardt
  0 siblings, 2 replies; 10+ messages in thread
From: Sphinx @ 2026-10-03  8:54 UTC (permalink / raw)
  To: git

Hi Git maintainers,

I have been investigating Git's behavior in a particular destructive
scenario and wanted to verify my understanding with the maintainers.

Consider the following repository history:

A -> B

where A contains the repository's files and B is the current HEAD.

The repository is then cloned with:

git clone --depth=1 <repository>

so only B is available locally and its parent A is not present in the
shallow clone.

If an operation is then performed to restore/revert B, I was looking
into the behavior when the resulting working tree/index becomes empty
— effectively causing all tracked files to be removed.

I have gone through the Git documentation and experimented with the
relevant Git commands, including the behavior of shallow repositories,
branch deletion, working-tree changes, resets, restores, and other
destructive operations. Based on my investigation, I have not been
able to find evidence that Git provides a warning or confirmation
specifically when an operation results in all tracked files being
removed or produces an empty tree.

Before drawing any conclusions, I wanted to verify this with the Git developers.

Is the following understanding correct?

An empty tree is a valid Git state, so Git does not generally consider
transitioning from a non-empty tree to an empty tree inherently
erroneous.

Git does not have a general safeguard that warns when an operation
will delete all tracked files.

If there are existing safeguards, warnings, configuration options, or
historical discussions that I may have missed, I would appreciate any
pointers.

The reason I am asking is that I am trying to establish precisely
where Git's safety boundary is in this scenario specifically, whether
Git itself is expected to warn about the resulting empty tree, or
whether detecting an unexpectedly destructive tree change is
considered the responsibility of the tooling performing the operation.

Thanks,
A fellow git user

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-03  8:54 Question: behavior when reverting a commit from a shallow clone Sphinx
@ 2026-10-03 19:41 ` Carlisle T. Hamlin
  2026-10-05  6:57   ` Patrick Steinhardt
  2026-10-05  6:57 ` Patrick Steinhardt
  1 sibling, 1 reply; 10+ messages in thread
From: Carlisle T. Hamlin @ 2026-10-03 19:41 UTC (permalink / raw)
  To: Sphinx, git


[-- Attachment #1.1.1: Type: text/plain, Size: 1539 bytes --]

On 10/3/26 1:54 AM, Sphinx wrote:
> Is the following understanding correct?
> 
> An empty tree is a valid Git state, so Git does not generally consider
> transitioning from a non-empty tree to an empty tree inherently
> erroneous.
> 
> Git does not have a general safeguard that warns when an operation
> will delete all tracked files.
> 
> If there are existing safeguards, warnings, configuration options, or
> historical discussions that I may have missed, I would appreciate any
> pointers.
> 
> The reason I am asking is that I am trying to establish precisely
> where Git's safety boundary is in this scenario specifically, whether
> Git itself is expected to warn about the resulting empty tree, or
> whether detecting an unexpectedly destructive tree change is
> considered the responsibility of the tooling performing the operation.
You know, it seems to me that it should be reasonable for Git to assume 
that someone with the wherewithal to set up and operate a git repository 
(or at the very least operate one that someone else set up) knows enough 
to understand what's going to happen if they obliterate the only commit 
in their tree.

There really is only *so* much holding of the hand I think we should be 
expected to perform before it's not only insulting to the project 
developers, but also to the *user*.

My two cents. I know folk use Git for all sorts of stuff. Just, maybe... 
the sort of person who would be surprised catastrophically by this 
behaviour... well... shouldn't.



[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7951 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 203 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-03 19:41 ` Carlisle T. Hamlin
@ 2026-10-05  6:57   ` Patrick Steinhardt
  2026-10-05 18:10     ` Carlisle T. Hamlin
  0 siblings, 1 reply; 10+ messages in thread
From: Patrick Steinhardt @ 2026-10-05  6:57 UTC (permalink / raw)
  To: Carlisle T. Hamlin; +Cc: Sphinx, git

On Sat, Oct 03, 2026 at 12:41:47PM -0700, Carlisle T. Hamlin wrote:
> On 10/3/26 1:54 AM, Sphinx wrote:
> > Is the following understanding correct?
> > 
> > An empty tree is a valid Git state, so Git does not generally consider
> > transitioning from a non-empty tree to an empty tree inherently
> > erroneous.
> > 
> > Git does not have a general safeguard that warns when an operation
> > will delete all tracked files.
> > 
> > If there are existing safeguards, warnings, configuration options, or
> > historical discussions that I may have missed, I would appreciate any
> > pointers.
> > 
> > The reason I am asking is that I am trying to establish precisely
> > where Git's safety boundary is in this scenario specifically, whether
> > Git itself is expected to warn about the resulting empty tree, or
> > whether detecting an unexpectedly destructive tree change is
> > considered the responsibility of the tooling performing the operation.
> You know, it seems to me that it should be reasonable for Git to assume that
> someone with the wherewithal to set up and operate a git repository (or at
> the very least operate one that someone else set up) knows enough to
> understand what's going to happen if they obliterate the only commit in
> their tree.
> 
> There really is only *so* much holding of the hand I think we should be
> expected to perform before it's not only insulting to the project
> developers, but also to the *user*.
> 
> My two cents. I know folk use Git for all sorts of stuff. Just, maybe... the
> sort of person who would be surprised catastrophically by this behaviour...
> well... shouldn't.

There really is no need to be this adversarial to a simple question like
from the author. We want to be a welcoming community, and replies like
this are the exact opposite and will drive people away.

Thanks!

Patrick

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-03  8:54 Question: behavior when reverting a commit from a shallow clone Sphinx
  2026-10-03 19:41 ` Carlisle T. Hamlin
@ 2026-10-05  6:57 ` Patrick Steinhardt
  2026-10-05 10:41   ` Matt Hunter
  2026-10-06 15:54   ` Junio C Hamano
  1 sibling, 2 replies; 10+ messages in thread
From: Patrick Steinhardt @ 2026-10-05  6:57 UTC (permalink / raw)
  To: Sphinx; +Cc: git

On Sat, Oct 03, 2026 at 02:24:42PM +0530, Sphinx wrote:
> Hi Git maintainers,
> 
> I have been investigating Git's behavior in a particular destructive
> scenario and wanted to verify my understanding with the maintainers.
> 
> Consider the following repository history:
> 
> A -> B
> 
> where A contains the repository's files and B is the current HEAD.
> 
> The repository is then cloned with:
> 
> git clone --depth=1 <repository>
> 
> so only B is available locally and its parent A is not present in the
> shallow clone.
> 
> If an operation is then performed to restore/revert B, I was looking
> into the behavior when the resulting working tree/index becomes empty
> — effectively causing all tracked files to be removed.

Yeah, this can indeed be surprising behaviour. The reason for it is that
in a shallow clone, we rewrite the boundary commit (so in your case B)
so that it doesn't have any parents anymore. It thus looks like just
another root commit that has added all files in a single go. And the
consequence of that is that reverting it will then delete everything.

Now arguably, Git could be improved here. We just recently had a similar
discussion around maybe forbidding to "git commit --amend" such a
shallow commit. Your scenario is a second one where Git should probably
at least warn about what's happening.

Arguably we should even completely refuse editing such a shallow commit
by default. I would guess that in 99% of all the cases where a user does
it it's unintended. And for the 1% where it's actually intended we could
give users a way to override this safeguard.

> I have gone through the Git documentation and experimented with the
> relevant Git commands, including the behavior of shallow repositories,
> branch deletion, working-tree changes, resets, restores, and other
> destructive operations. Based on my investigation, I have not been
> able to find evidence that Git provides a warning or confirmation
> specifically when an operation results in all tracked files being
> removed or produces an empty tree.
> 
> Before drawing any conclusions, I wanted to verify this with the Git developers.
> 
> Is the following understanding correct?
> 
> An empty tree is a valid Git state, so Git does not generally consider
> transitioning from a non-empty tree to an empty tree inherently
> erroneous.

Mostly correct. A small correction though: Git considers the empty
_root_ tree to be a valid state so that you can create a commit that
contains no files at all. We never write an empty sub-tree though, so
you cannot add an empty directory.

> Git does not have a general safeguard that warns when an operation
> will delete all tracked files.

We try hard to not lose a user's data, so especially untracked data is
something we're careful about. But anything that's committed already is
fair game, as it's trivial to restore.

> If there are existing safeguards, warnings, configuration options, or
> historical discussions that I may have missed, I would appreciate any
> pointers.

There are none for the above use case, to the best of my knowledge.

> The reason I am asking is that I am trying to establish precisely
> where Git's safety boundary is in this scenario specifically, whether
> Git itself is expected to warn about the resulting empty tree, or
> whether detecting an unexpectedly destructive tree change is
> considered the responsibility of the tooling performing the operation.

I wouldn't warn about an empty tree in general. But editing a commit
that is a shallow boundary is something that I'd agree Git should warn
about, if not even refuse by default.

Patrick

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-05  6:57 ` Patrick Steinhardt
@ 2026-10-05 10:41   ` Matt Hunter
  2026-10-05 16:38     ` Junio C Hamano
  2026-10-06 15:54   ` Junio C Hamano
  1 sibling, 1 reply; 10+ messages in thread
From: Matt Hunter @ 2026-10-05 10:41 UTC (permalink / raw)
  To: Patrick Steinhardt, Sphinx; +Cc: git

On Mon Oct 5, 2026 at 2:57 AM EDT, Patrick Steinhardt wrote:
> On Sat, Oct 03, 2026 at 02:24:42PM +0530, Sphinx wrote:
>> 
>> If an operation is then performed to restore/revert B, I was looking
>> into the behavior when the resulting working tree/index becomes empty
>> — effectively causing all tracked files to be removed.
>
> Yeah, this can indeed be surprising behaviour. The reason for it is that
> in a shallow clone, we rewrite the boundary commit (so in your case B)
> so that it doesn't have any parents anymore. It thus looks like just
> another root commit that has added all files in a single go. And the
> consequence of that is that reverting it will then delete everything.

Separate question from the sidelines:  As a non shallow clone user, this
makes me wonder if/how these boundary commits might be munged to
preserve original commit ids in the clone?  eg: so a fast-forward
pull still works for future content

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-05 10:41   ` Matt Hunter
@ 2026-10-05 16:38     ` Junio C Hamano
       [not found]       ` <CALfz8QzymKxvzYGWLwdtzERDm1apa8ebZEVyLne18hpTaB=D0g@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Junio C Hamano @ 2026-10-05 16:38 UTC (permalink / raw)
  To: Matt Hunter; +Cc: Patrick Steinhardt, Sphinx, git

"Matt Hunter" <m@lfurio.us> writes:

> On Mon Oct 5, 2026 at 2:57 AM EDT, Patrick Steinhardt wrote:
>> On Sat, Oct 03, 2026 at 02:24:42PM +0530, Sphinx wrote:
>>> 
>>> If an operation is then performed to restore/revert B, I was looking
>>> into the behavior when the resulting working tree/index becomes empty
>>> — effectively causing all tracked files to be removed.
>>
>> Yeah, this can indeed be surprising behaviour. The reason for it is that
>> in a shallow clone, we rewrite the boundary commit (so in your case B)
>> so that it doesn't have any parents anymore. It thus looks like just
>> another root commit that has added all files in a single go. And the
>> consequence of that is that reverting it will then delete everything.
>
> Separate question from the sidelines:  As a non shallow clone user, this
> makes me wonder if/how these boundary commits might be munged to
> preserve original commit ids in the clone?  eg: so a fast-forward
> pull still works for future content

Something similar to "graft" (and now "replace") is done under the
hood, to stop history traversal machinery seeing the true parents
of these boundary commits.  As the commit object itself (specifically
its "parent " lines in the header part) is not modified in any way,
this does not affect object names.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
       [not found]       ` <CALfz8QzymKxvzYGWLwdtzERDm1apa8ebZEVyLne18hpTaB=D0g@mail.gmail.com>
@ 2026-10-05 17:35         ` Sphinx
  0 siblings, 0 replies; 10+ messages in thread
From: Sphinx @ 2026-10-05 17:35 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: git

Thanks, Patrick. That makes it much clearer.

I was initially thinking of the empty tree as the potentially unsafe
part, but from your explanation, it's clear that the empty tree itself
isn't really the problem it's the shallow boundary that makes this
behavior surprising.

The absence of a safeguard specifically for editing a shallow boundary
commit, and the possibility of warning or refusing such operations by
default, is exactly what I was trying to understand.

Thanks again for taking the time to explain it.


On Mon, Oct 5, 2026 at 10:44 PM Sphinx <sphinx9692@gmail.com> wrote:
>
> Thanks, Patrick. That makes it much clearer.
>
> I was initially thinking of the empty tree as the potentially unsafe part, but from your explanation, it's clear that the empty tree itself isn't really the problem it's the shallow boundary that makes this behavior surprising.
>
> The absence of a safeguard specifically for editing a shallow boundary commit, and the possibility of warning or refusing such operations by default, is exactly what I was trying to understand.
>
> Thanks again for taking the time to explain it.
>
>
> On Mon, 5 Oct, 2026, 10:08 pm Junio C Hamano, <gitster@pobox.com> wrote:
>>
>> "Matt Hunter" <m@lfurio.us> writes:
>>
>> > On Mon Oct 5, 2026 at 2:57 AM EDT, Patrick Steinhardt wrote:
>> >> On Sat, Oct 03, 2026 at 02:24:42PM +0530, Sphinx wrote:
>> >>>
>> >>> If an operation is then performed to restore/revert B, I was looking
>> >>> into the behavior when the resulting working tree/index becomes empty
>> >>> — effectively causing all tracked files to be removed.
>> >>
>> >> Yeah, this can indeed be surprising behaviour. The reason for it is that
>> >> in a shallow clone, we rewrite the boundary commit (so in your case B)
>> >> so that it doesn't have any parents anymore. It thus looks like just
>> >> another root commit that has added all files in a single go. And the
>> >> consequence of that is that reverting it will then delete everything.
>> >
>> > Separate question from the sidelines:  As a non shallow clone user, this
>> > makes me wonder if/how these boundary commits might be munged to
>> > preserve original commit ids in the clone?  eg: so a fast-forward
>> > pull still works for future content
>>
>> Something similar to "graft" (and now "replace") is done under the
>> hood, to stop history traversal machinery seeing the true parents
>> of these boundary commits.  As the commit object itself (specifically
>> its "parent " lines in the header part) is not modified in any way,
>> this does not affect object names.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-05  6:57   ` Patrick Steinhardt
@ 2026-10-05 18:10     ` Carlisle T. Hamlin
  0 siblings, 0 replies; 10+ messages in thread
From: Carlisle T. Hamlin @ 2026-10-05 18:10 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: Sphinx, git


[-- Attachment #1.1.1: Type: text/plain, Size: 1248 bytes --]

On 10/4/26 11:57 PM, Patrick Steinhardt wrote:
>> You know, it seems to me that it should be reasonable for Git to assume that
>> someone with the wherewithal to set up and operate a git repository (or at
>> the very least operate one that someone else set up) knows enough to
>> understand what's going to happen if they obliterate the only commit in
>> their tree.
>>
>> There really is only *so* much holding of the hand I think we should be
>> expected to perform before it's not only insulting to the project
>> developers, but also to the *user*.
>>
>> My two cents. I know folk use Git for all sorts of stuff. Just, maybe... the
>> sort of person who would be surprised catastrophically by this behaviour...
>> well... shouldn't.
> 
> There really is no need to be this adversarial to a simple question like
> from the author. We want to be a welcoming community, and replies like
> this are the exact opposite and will drive people away.

My apologies; I didn't realize I was coming across as adversarial.

Also, I stand corrected - other replies to this question indicate that 
we *are, indeed* prepared to perform this level of hand holding. I 
fundamentally misunderstood the project's stance in this regard.



[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7951 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 203 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-05  6:57 ` Patrick Steinhardt
  2026-10-05 10:41   ` Matt Hunter
@ 2026-10-06 15:54   ` Junio C Hamano
  2026-10-09 17:34     ` Sphinx
  1 sibling, 1 reply; 10+ messages in thread
From: Junio C Hamano @ 2026-10-06 15:54 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: Sphinx, git

Patrick Steinhardt <ps@pks.im> writes:

> Yeah, this can indeed be surprising behaviour. The reason for it is that
> in a shallow clone, we rewrite the boundary commit (so in your case B)
> so that it doesn't have any parents anymore. It thus looks like just
> another root commit that has added all files in a single go. And the
> consequence of that is that reverting it will then delete everything.
>
> Now arguably, Git could be improved here. We just recently had a similar
> discussion around maybe forbidding to "git commit --amend" such a
> shallow commit. Your scenario is a second one where Git should probably
> at least warn about what's happening.
>
> Arguably we should even completely refuse editing such a shallow commit
> by default. I would guess that in 99% of all the cases where a user does
> it it's unintended. And for the 1% where it's actually intended we could
> give users a way to override this safeguard.

Yeah, I think that line of thinking is going in the right direction.

It is not surprising that these non-core features (read: as opposed
to really core features that were already considered mature even
back in Git 1.5.3) that had many years to mature still has rough
edges even today around corners that practicaly nobody has touched,
and we should not be afraid to round them further.

> I wouldn't warn about an empty tree in general. But editing a commit
> that is a shallow boundary is something that I'd agree Git should warn
> about, if not even refuse by default.

Yes.  Committing an empty tree, whether at the beginning of a
project or in the middle of a project after you fed up with too many
bugs in your early attempts and want to start clean, is a perfectly
normal, if wasteful, thing to do.

Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Question: behavior when reverting a commit from a shallow clone
  2026-10-06 15:54   ` Junio C Hamano
@ 2026-10-09 17:34     ` Sphinx
  0 siblings, 0 replies; 10+ messages in thread
From: Sphinx @ 2026-10-09 17:34 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Patrick Steinhardt, git

Thank you both. I wanted to follow up with a slightly more concrete
framing of what a safeguard could look like, in case it is useful as
a starting point.

Git already tracks shallow boundary commits in .git/shallow, so
detection is possible at the point where a destructive operation is
about to be applied to one. A minimal version of this safeguard
could look like:

  - Before executing git revert (and maybe git commit --amend)
    on a commit OID, check whether that OID appears in .git/shallow.
  - If it does, refuse by default with a message explaining that the
    commit is a shallow boundary and suggesting either
    --allow-shallow-boundary to proceed or git fetch --unshallow
    to restore full history before retrying.

Refusing rather than just warning seems appropriate given that, as
Patrick noted, the overwhelming majority of such operations are
unintentional.

I am happy to attempt a patch for git revert as a starting point
if this direction seems worth pursuing. Let me know if there are
constraints or prior discussions I should be aware of before doing so.

Thanks


On Tue, Oct 6, 2026 at 9:24 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Patrick Steinhardt <ps@pks.im> writes:
>
> > Yeah, this can indeed be surprising behaviour. The reason for it is that
> > in a shallow clone, we rewrite the boundary commit (so in your case B)
> > so that it doesn't have any parents anymore. It thus looks like just
> > another root commit that has added all files in a single go. And the
> > consequence of that is that reverting it will then delete everything.
> >
> > Now arguably, Git could be improved here. We just recently had a similar
> > discussion around maybe forbidding to "git commit --amend" such a
> > shallow commit. Your scenario is a second one where Git should probably
> > at least warn about what's happening.
> >
> > Arguably we should even completely refuse editing such a shallow commit
> > by default. I would guess that in 99% of all the cases where a user does
> > it it's unintended. And for the 1% where it's actually intended we could
> > give users a way to override this safeguard.
>
> Yeah, I think that line of thinking is going in the right direction.
>
> It is not surprising that these non-core features (read: as opposed
> to really core features that were already considered mature even
> back in Git 1.5.3) that had many years to mature still has rough
> edges even today around corners that practicaly nobody has touched,
> and we should not be afraid to round them further.
>
> > I wouldn't warn about an empty tree in general. But editing a commit
> > that is a shallow boundary is something that I'd agree Git should warn
> > about, if not even refuse by default.
>
> Yes.  Committing an empty tree, whether at the beginning of a
> project or in the middle of a project after you fed up with too many
> bugs in your early attempts and want to start clean, is a perfectly
> normal, if wasteful, thing to do.
>
> Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-10-09 17:34 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-03  8:54 Question: behavior when reverting a commit from a shallow clone Sphinx
2026-10-03 19:41 ` Carlisle T. Hamlin
2026-10-05  6:57   ` Patrick Steinhardt
2026-10-05 18:10     ` Carlisle T. Hamlin
2026-10-05  6:57 ` Patrick Steinhardt
2026-10-05 10:41   ` Matt Hunter
2026-10-05 16:38     ` Junio C Hamano
     [not found]       ` <CALfz8QzymKxvzYGWLwdtzERDm1apa8ebZEVyLne18hpTaB=D0g@mail.gmail.com>
2026-10-05 17:35         ` Sphinx
2026-10-06 15:54   ` Junio C Hamano
2026-10-09 17:34     ` Sphinx

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox