git@vger.kernel.org mailing list mirror (one of many)
 help / Atom feed
* What exactly is a "initial checkout"
@ 2018-11-06 12:38 Christian Halstrick
  2018-11-06 21:18 ` Jeff King
  2018-11-07  0:07 ` Junio C Hamano
  0 siblings, 2 replies; 5+ messages in thread
From: Christian Halstrick @ 2018-11-06 12:38 UTC (permalink / raw)
  To: Git; +Cc: rene.scheibe

I am trying to teach JGit [1] to behave like native git regarding some
corner cases during "git checkout". I am reading the "git read-tree"
documentation and I am not sure about the case [2]. Git should behave
differently during a normal checkout than when you are doing a
"initial checkout". I can imagine that the first checkout you do after
you have cloned a repo is a initial checkout but: What exactly defines
a "initial checkout"? It can't be an empty or non-existing index
because native git behaves like in a non-initial-checkout even if the
index is empty (see example below).

Here are some commands explaining my case. Git is facing an empty
index, HEAD and MERGE (the commit you checkout) have the some content
for path 'p'  and still git is neither updating index nor workingtree
file during checkout.

git init
mkdir p
echo initial >p/a
git add p/a
git commit -m initial
touch p2
git add p2
git commit -m followup
git rm -r p p2
echo "important data" >p
git checkout HEAD~ # successful checkout leaving p dirty
cat p # prints "important data", so 'p' is not updated during the checkout
git ls-files -sv  # empty -> index is empty

[1] https://www.eclipse.org/jgit/
[2] https://github.com/git/git/blob/master/Documentation/git-read-tree.txt#L187

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

* Re: What exactly is a "initial checkout"
  2018-11-06 12:38 What exactly is a "initial checkout" Christian Halstrick
@ 2018-11-06 21:18 ` Jeff King
  2018-11-07  0:07 ` Junio C Hamano
  1 sibling, 0 replies; 5+ messages in thread
From: Jeff King @ 2018-11-06 21:18 UTC (permalink / raw)
  To: Christian Halstrick; +Cc: Git, rene.scheibe

On Tue, Nov 06, 2018 at 01:38:45PM +0100, Christian Halstrick wrote:

> I am trying to teach JGit [1] to behave like native git regarding some
> corner cases during "git checkout". I am reading the "git read-tree"
> documentation and I am not sure about the case [2]. Git should behave
> differently during a normal checkout than when you are doing a
> "initial checkout". I can imagine that the first checkout you do after
> you have cloned a repo is a initial checkout but: What exactly defines
> a "initial checkout"? It can't be an empty or non-existing index
> because native git behaves like in a non-initial-checkout even if the
> index is empty (see example below).
> 
> Here are some commands explaining my case. Git is facing an empty
> index, HEAD and MERGE (the commit you checkout) have the some content
> for path 'p'  and still git is neither updating index nor workingtree
> file during checkout.

Without looking at the code, I'd assume that an empty HEAD is different
than "there is no HEAD at all". I.e., what we call an "unborn branch"
elsewhere.

So perhaps try:

  git init
  git fetch ../some/other/repo HEAD:tmp
  git checkout tmp

where you'd truly have no HEAD.

Though peeking at the code, it looks like we set the unpack_trees
initial_checkout flag based on is_cache_unborn(), which looks for a
totally missing index file (not just an empty one). That would trigger
in the above case, too, though, because of course we have no index there
either.

-Peff

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

* Re: What exactly is a "initial checkout"
  2018-11-06 12:38 What exactly is a "initial checkout" Christian Halstrick
  2018-11-06 21:18 ` Jeff King
@ 2018-11-07  0:07 ` Junio C Hamano
  2018-11-07  8:50   ` Christian Halstrick
  1 sibling, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2018-11-07  0:07 UTC (permalink / raw)
  To: Christian Halstrick; +Cc: Git, rene.scheibe

Christian Halstrick <christian.halstrick@gmail.com> writes:

> I am trying to teach JGit [1] to behave like native git regarding some
> corner cases during "git checkout". I am reading the "git read-tree"
> documentation and I am not sure about the case [2]. Git should behave
> differently during a normal checkout than when you are doing a
> "initial checkout".

When you are starting from commit H and checking out a different
commit M, and when a path in the index does not match what is
recorded in commit H, usually Git tries to keep the state of the
path you have in your index as a "local change", as long as the data
recorded for the path is the same between H and M.  A path in the
index that matches what is recorded in commit H and with different
data recorded for it in commit M gets M's version in the index and
the working file is updated to match (but it requires that either
the working tree file is missing, or the working tree version
matches what is in the original index, to avoid data loss).

But imagine you have just cloned and are trying to finish that
process.  What Git has done so far would include creating an empty
repository, populating the object database and pointing branches at
various commits.  HEAD now points at the branch (usually 'master'),
the index file does not exist (you haven't checked out anything),
and we want to populate the index and the working tree files to
match what is recorded in HEAD.  We do so by starting from commit
HEAD and checking out commit HEAD.

This situation presents conflicting goals to the above "keep the
local change" rule.  To the rule, this situation looks as if you
removed each and every path from the index (as the index hasn't been
populated yet---in fact, the index file does not even exist yet in
this state), but the data recorded for each path are the same
between commit H and commit M (as H==M==HEAD in this case), so "keep
the local change" rule would leave the index and the working tree
empty X-<.

That is rescued by the "initial checkout behaves differently and
forces the index and the working tree match what is recorded in
commit M" exception.  It probably should be obvious to the readers
by now that the absense of .git/index is used as the clue for this
exception to kick in from the above use case.

And that is exactly the condition that is checked by
read-cache.c::is_index_unborn().


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

* Re: What exactly is a "initial checkout"
  2018-11-07  0:07 ` Junio C Hamano
@ 2018-11-07  8:50   ` Christian Halstrick
  2018-11-07 23:33     ` Philip Oakley
  0 siblings, 1 reply; 5+ messages in thread
From: Christian Halstrick @ 2018-11-07  8:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git, rene.scheibe

Ok, I know understand the problems which are solved by this
special behaviour of a "initial checkout". And also important I understand
when exactly I should do a "initial checkout" - when the index file does
not exist. I'll share my new knowledge with JGit :-)

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

* Re: What exactly is a "initial checkout"
  2018-11-07  8:50   ` Christian Halstrick
@ 2018-11-07 23:33     ` Philip Oakley
  0 siblings, 0 replies; 5+ messages in thread
From: Philip Oakley @ 2018-11-07 23:33 UTC (permalink / raw)
  To: Christian Halstrick, Junio C Hamano; +Cc: Git, rene.scheibe

On 07/11/2018 08:50, Christian Halstrick wrote:
> Ok, I know understand the problems which are solved by this
> special behaviour of a "initial checkout". And also important I understand
> when exactly I should do a "initial checkout" - when the index file does
> not exist. I'll share my new knowledge with JGit :-)
> 
Given that the initial query was about the lack of documentation for the 
term "initial checkout", do you have any suggestion of how it might best 
be incorporated into the documentation to assist future reader?
-- 
Philip

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

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-06 12:38 What exactly is a "initial checkout" Christian Halstrick
2018-11-06 21:18 ` Jeff King
2018-11-07  0:07 ` Junio C Hamano
2018-11-07  8:50   ` Christian Halstrick
2018-11-07 23:33     ` Philip Oakley

git@vger.kernel.org mailing list mirror (one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/
       or Tor2web: https://www.tor2web.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox