All of lore.kernel.org
 help / color / mirror / Atom feed
* git -C has unexpected behaviour
@ 2016-11-04 14:28 Felix Nairz
  2016-11-04 16:10 ` Stefan Beller
  2016-11-04 16:36 ` Johannes Schindelin
  0 siblings, 2 replies; 5+ messages in thread
From: Felix Nairz @ 2016-11-04 14:28 UTC (permalink / raw)
  To: git

Hi guys,

I ran into some really weird git behaviour today.

My git --version is: git version 2.8.1.windows.1

We have a git repository with a submodule called TestData. The data in
there is modified and reset as part of our unit tests.

The submodule is a sub-folder of the git repository called TestData.
So the relative path from the git repository to the submodule is
.\TestData

If I delete the entire TestData folder and run
git -C .\TestData reset --hard

I will get the following error:
git : fatal: Cannot change to '.\TestData': No such file or directory
This is as expected.


Now, to the unexpected part, which I think is a bug:

If the TestData folder is there, but empty (I deleted all the files),
then running

git -C .\TestData reset --hard

will NOT throw me an error but run

git reset --hard

on the git repository (not the submodule in the sub-directory!),
without warning, or error. This is easy to reproduce by having an
empty .\TestData folder, and just changing any file in your git
repository before running

git -C .\TestData reset --hard

and seeing the local file changes gone.

Because of this we have had losses of uncommitted changes a few times
now (loosing a few days of work, and getting a bit paranoid), but
could never find the root cause for this until today, where I found
out that it happens when the TestData directory is empty.

Thank for looking into this, and I am looking forward to hear your
opinions about this.

Best Regards, Felix Nairz

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

* Re: git -C has unexpected behaviour
  2016-11-04 14:28 git -C has unexpected behaviour Felix Nairz
@ 2016-11-04 16:10 ` Stefan Beller
  2016-11-04 16:36 ` Johannes Schindelin
  1 sibling, 0 replies; 5+ messages in thread
From: Stefan Beller @ 2016-11-04 16:10 UTC (permalink / raw)
  To: Felix Nairz; +Cc: git

On Fri, Nov 4, 2016 at 7:28 AM, Felix Nairz <felix.nairz@gmail.com> wrote:
> Hi guys,
>
> I ran into some really weird git behaviour today.
>
> My git --version is: git version 2.8.1.windows.1
>
> We have a git repository with a submodule called TestData. The data in
> there is modified and reset as part of our unit tests.
>
> The submodule is a sub-folder of the git repository called TestData.
> So the relative path from the git repository to the submodule is
> .\TestData
>
> If I delete the entire TestData folder and run
> git -C .\TestData reset --hard
>
> I will get the following error:
> git : fatal: Cannot change to '.\TestData': No such file or directory
> This is as expected.
>
>
> Now, to the unexpected part, which I think is a bug:
>
> If the TestData folder is there, but empty (I deleted all the files),

And "all the files" includes the ".git" file, which git uses to find out if
it is in a git repository. So it keeps walking up until it finds a .git
file/directory, which is the parent project.

Once a git directory is found, the main function of git initializes some
data structures, e.g. the "path prefix" inside the repository which would be
" .\TestData" in your case. then the actual command is found and run.

So what it is doing is:
"Suppose you are in the TestData directory of the parent project and then
run the command ..."

My gut reaction was to propose to check if any GITLINK (submodule)
is a prefix of said "path prefix" and then rather initialize and operate on
the submodule.

However I do not think this is a good idea:
* Git wants to be fast and checking if we are in any submodule
slows down the common case.
* Historically commands in un-initialized or deinitialized submodules
behave as if in the parent project. I think if we'd fix this issue, other
people would complain as their workflow is harmed.

>
> Because of this we have had losses of uncommitted changes a few times
> now (loosing a few days of work, and getting a bit paranoid),

* commit early, commit often such that the losses are less than a few days.
* do not remove the submodule directory as a whole thing
  (make sure the .git file is there and not wiped)
* instead use "git -C TestData clean -dffx && git -C TestData reset --hard"
   https://git-scm.com/docs/git-clean


> could never find the root cause for this until today, where I found
> out that it happens when the TestData directory is empty.

I am undecided if it is a bug or a feature. Fixing this as a bug
would be a performance penalty. Not fixing it may incur data losses.
I dunno.

>
> Thank for looking into this, and I am looking forward to hear your
> opinions about this.
>
> Best Regards, Felix Nairz

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

* Re: git -C has unexpected behaviour
  2016-11-04 14:28 git -C has unexpected behaviour Felix Nairz
  2016-11-04 16:10 ` Stefan Beller
@ 2016-11-04 16:36 ` Johannes Schindelin
  2016-11-07  7:26   ` Felix Nairz
  1 sibling, 1 reply; 5+ messages in thread
From: Johannes Schindelin @ 2016-11-04 16:36 UTC (permalink / raw)
  To: Felix Nairz; +Cc: git

Hi Felix,

On Fri, 4 Nov 2016, Felix Nairz wrote:

> Now, to the unexpected part, which I think is a bug:
> 
> If the TestData folder is there, but empty (I deleted all the files),
> then running
> 
> git -C .\TestData reset --hard
> 
> will NOT throw me an error but run
> 
> git reset --hard
> 
> on the git repository (not the submodule in the sub-directory!),
> without warning, or error.

I *think* that this is actually intended. Please note that -C is *not* a
synonym of --git-dir. It is more of a synonym of

	cd .\TestData
	git reset --hard

In other words, you probably expected -C to specify the top-level
directory of a worktree, and you expected Git to error out when it is not.
Instead, Git will treat -C as a directory *from where to start*; It *can*
be a subdirectory of the top-level directory of the worktree.

Please note that

	git --git-dir=.\TestData\.git reset --hard

will not work, though, as it mistakes the current directory for the
top-level directory of the worktree. What you want to do is probably

	git -C .\TestData --git-dir=.git reset --hard

This will tell Git to change the current working directory to the
top-level of your intended worktree, *and* state that the repository needs
to be in .git (which can be a file containing "gitdir: <real-git-dir>",
which is the default in submodules).

If the repository is *not* found, this command will exit with a failure.

Ciao,
Johannes

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

* Re: git -C has unexpected behaviour
  2016-11-04 16:36 ` Johannes Schindelin
@ 2016-11-07  7:26   ` Felix Nairz
  2016-11-07 16:54     ` Johannes Schindelin
  0 siblings, 1 reply; 5+ messages in thread
From: Felix Nairz @ 2016-11-07  7:26 UTC (permalink / raw)
  To: Johannes Schindelin, sbeller; +Cc: git

Hi guys,

thanks for the answer and the clarification.

From what you are saying I can see that this expects as designed. It's
confusing in the submodule case, but I get you don't want to add extra
rules which slow down performance and mess with other people at the
same time.

I will look into the git-dir solution, this seems to be exactly what I need.

Thanks, Felix

On Fri, Nov 4, 2016 at 5:36 PM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi Felix,
>
> On Fri, 4 Nov 2016, Felix Nairz wrote:
>
>> Now, to the unexpected part, which I think is a bug:
>>
>> If the TestData folder is there, but empty (I deleted all the files),
>> then running
>>
>> git -C .\TestData reset --hard
>>
>> will NOT throw me an error but run
>>
>> git reset --hard
>>
>> on the git repository (not the submodule in the sub-directory!),
>> without warning, or error.
>
> I *think* that this is actually intended. Please note that -C is *not* a
> synonym of --git-dir. It is more of a synonym of
>
>         cd .\TestData
>         git reset --hard
>
> In other words, you probably expected -C to specify the top-level
> directory of a worktree, and you expected Git to error out when it is not.
> Instead, Git will treat -C as a directory *from where to start*; It *can*
> be a subdirectory of the top-level directory of the worktree.
>
> Please note that
>
>         git --git-dir=.\TestData\.git reset --hard
>
> will not work, though, as it mistakes the current directory for the
> top-level directory of the worktree. What you want to do is probably
>
>         git -C .\TestData --git-dir=.git reset --hard
>
> This will tell Git to change the current working directory to the
> top-level of your intended worktree, *and* state that the repository needs
> to be in .git (which can be a file containing "gitdir: <real-git-dir>",
> which is the default in submodules).
>
> If the repository is *not* found, this command will exit with a failure.
>
> Ciao,
> Johannes

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

* Re: git -C has unexpected behaviour
  2016-11-07  7:26   ` Felix Nairz
@ 2016-11-07 16:54     ` Johannes Schindelin
  0 siblings, 0 replies; 5+ messages in thread
From: Johannes Schindelin @ 2016-11-07 16:54 UTC (permalink / raw)
  To: Felix Nairz; +Cc: sbeller, git

Hi Felix,

On Mon, 7 Nov 2016, Felix Nairz wrote:

> From what you are saying I can see that this expects as designed. It's
> confusing in the submodule case, but I get you don't want to add extra
> rules which slow down performance and mess with other people at the
> same time.

The "messing with other people" is the key point. There are most likely
other users than just me who use the fact that `git -C sub/directory/ ...`
works in a subdirectory of a checkout.

Ciao,
Johannes

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

end of thread, other threads:[~2016-11-07 16:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-04 14:28 git -C has unexpected behaviour Felix Nairz
2016-11-04 16:10 ` Stefan Beller
2016-11-04 16:36 ` Johannes Schindelin
2016-11-07  7:26   ` Felix Nairz
2016-11-07 16:54     ` Johannes Schindelin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.