Re: [BUG] "git checkout BRANCH -- FILE" deletes staged commits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Nov 19, 2019 at 06:10:01PM +0100, Tasnad Kernetzky wrote:
> Hi,

Hello,

> I suppose I found a bug in git version 2.24.0. Please consider the small
> shell script to reproduce.
*snip*
> # checkout copies over contents from B -> I guess the bug is here,
> changes are not detected
> git checkout B -- tst
> git status
> echo '-> this seems to be wrong, change is not detected'
> 
> # if we now go to B and back to master, we loose staged changes
> echo '*** tst should contain [master, B]: ***'
> cat tst
> echo '-------------'
> git checkout B
> echo '*** tst should contain [master, B]: ***'
> cat tst
> echo '-------------'
> git checkout master
> echo '*** tst should contain [master, B]: ***'
> cat tst
> echo '-------------'
> echo '-> wrong / staged changes lost!?'

I don't think this is a bug at all.

This form of checkout is basically a way to "revert" or "restore"
a file to match whichever tree-ish you select:

    git checkout ... -- file...

It is not a merge. It is overwriting whatever version of the file
you have, and staging those changes. There's no point warning you
that your file is different because you're giving git strict
instructions to overwrite the file. You shouldn't be doing that
unless you already know what the file's state is and you know you
don't want it. If in doubt stash, commit, or copy the file
first.

When you do `git checkout B -- tst` you are basically saying to
checkout the file tst as it exists at the tip of branch B and
stage it for commit.

When you switch back to branch B the state of the tst file is the
same as it exists in the branch B. There is no conflict here so
it succeeds, and once it does you no longer have any changes made
to tst because the version in your index and working tree matches
the version in the HEAD commit.

git status at this point would report nothing (assuming no other
files are modified).

When you switch back to master it happily overwrites tst to match
the version committed to the head of master because the version
you had on B is already committed (and is easily recovered from B
if desired). There's no conflict there and no reason to fail or
refuse.

This is normal behavior. Check the documentation and if you think
it's unclear you can make suggestions to improve it or better yet
submit a patch that does just that for review.

I haven't really been paying much attention to the development of
git, but I recall efforts were being made to split the various
behaviors of git-checkout into separate commands to help improve
the interface because some people struggle with it. Sounds like
these take the form of git-switch to change branches and
git-restore to restore files to some other version. It sounds
like git-restore will still work the same way in this regard
though so I don't think that changes anything.

Regards,



-- 
Brandon McCaig <bamccaig@xxxxxxxxx> <bambams@xxxxxxxxxxxxxxxx>
Castopulence Software <https://www.castopulence.org/>
Blog <http://www.bambams.ca/>
perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }.
q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.};
tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux