git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Philip Oakley" <philipoakley@iee.org>
To: "Christoph Michelbach" <michelbach94@gmail.com>
Cc: "Git Mailing List" <git@vger.kernel.org>
Subject: Re: [PATCH] Documentation/git-checkout: make doc. of checkout <tree-ish> clearer
Date: Mon, 17 Apr 2017 21:59:44 +0100	[thread overview]
Message-ID: <5FD0803E166B4D2F9F64D8D21AC23EB3@PhilipOakley> (raw)
In-Reply-To: 1492452173.11708.22.camel@gmail.com

I've added back the list, as it was accidentally dropped.

From: "Christoph Michelbach" <michelbach94@gmail.com>
> On Mon, 2017-04-17 at 17:04 +0100, Philip Oakley wrote:
>> From: "Christoph Michelbach" <michelbach94@gmail.com>
>> >
>> > On Sun, 2017-04-16 at 22:25 +0100, Philip Oakley wrote:
>> > >
>> > > From: "Christoph Michelbach" <michelbach94@gmail.com>
>> > > >
>> > > > It's: git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>...
>> > > The one I quoted is direct from the Synopsis, which does indicate
>> > > there are
>> > > potentially more aspects to resolve, such as the influence of
>> > > using
>> > > the
>> > > [-p|--patch] options.
>> > Oh, you are right. I didn't even notice the one in the synopsis
>> > doesn't
>> > match the one further down. The one in the synopsis is wrong because
>> > after removing the optional parameters, it's the same as the first
>> > one
>> > in the synopsis, yet we expect very different behavior from them.
>> >
>> >
>> > >
>> > > It maybe that the paragraph / sentence that needs adjusting is;
>> > >
>> > > 'git checkout' with <paths> or `--patch` is used to restore
>> > > modified
>> > > or
>> > > deleted paths to their original contents from the index or replace
>> > > paths
>> > > with the contents from a named <tree-ish> (most often a commit-
>> > > ish).
>> > >
>> > > and split it at the "or replace paths" option to pick out your
>> > > specific
>> > > case.
>> > This one is confusing, too: Paths can lead to folders, yet folders
>> > whose
>> > contents have been modified are not restored to their original
>> > contents
>> > when executing that command. Only files are.
>> >
>> > After reading the documentation and having never used the command
>> > before, one would expect
>> >
>> > #!/bin/bash
>> > rm -Rf repo
>> > mkdir repo
>> > cd repo
>> > git init &> /dev/null
>> > mkdir folder
>> > echo a > folder/a
>> > git add -A
>> > git commit -m "Commit 1." &> /dev/null
>> > echo b > folder/b
>> > git add -A
>> > git commit -m "Commit 2." &> /dev/null
>> > echo c > folder/c
>> > git add -A
>> > git commit -m "Commit 3." &> /dev/null
>> > git checkout `git log --pretty=format:%H | tail -1` folder
>> > ls folder
>> >
>> > to print `a`. However, it prints `a b c` because all of the files
>> > inside
>> > `folder` which have been modified or deleted since (here: none) are
>> > reset to their original state after the first commit, but `folder`
>> > itself isn't. Yet, the only path which was passed to the command in
>> > question is `folder`.
>> >
>> > In my opinion, this command needs improved documentation (and the
>> > synopsis needs to be fixed).
>> >
>> I think this example is of a different kind of misunderstanding.
>>
>> We are at commit 3, with a b c in the working directory and index, and
>> then
>> we ask to checkout certain specific files from the first commit 1,
>> which
>> contains the file a. That old file is extracted and replaces the file
>> from
>> commit 3.
>>
>> As the file a is identical there is no change and we still have the
>> original
>> b and c files from commit c.
>>
>> I'd guess that the misunderstanding is that you maybe thought that the
>> whole
>> directory would be reset to it's old state and the files b and c
>> deleted,
>> rather than just the named files present in that old commit being
>> extracted.
>> If we'd created and added a file d just before the checkout, what
>> should
>> have happened to d, and why?
>
> I understand what the command does. It behaves perfectly as I expected
> it to. I did not find this script but wrote it to demonstrate that what
> the documentation says is different from how it behaves after having
> read what the documentation says it should do and noticing that that's
> not how I expected it to work from experience.
>
> What it really does is to copy all files described by the given paths
> from the given tree-ish to the working directory. Or at least that's my
> expectation of what it does.
>
> The documentation, however, says that the given paths are *restored*.
> This is different.

I don't see that difference in the phrase *restored*, compared to your 'copy 
all files described by the given paths'. Could you explain a little more?

>
> To answer your question: Nothing should happen to the file `d`. I stated
> what I genuinely believe to be true above: "What it really does is to
> copy all files described by the given paths from the given tree-ish to
> the working directory." If we take this and apply it, we see that `d` is
> not touched because there is nothing in the given tree-ish that could
> override it because `d` is not in the index.
>
> If we, however, take the existing documentation and apply it, `d` is
> removed if and only if a path leading to `d` (like `d` if `d` is in the
> root of the repo or `folder` or `folder/d` if it is in the folder
> `folder`) is passed as an argument.
>
>
>> Comming back to the mental model issue with the implicit staging of
>> checked
>> out paths, I suspect this is a because we have both a snapshot and a
>> diff
>> based mental model. Normally the distinction is natural. We have the
>> snapshot from the last commit (or branch checkout) in the index, and
>> then we
>> have the two steps for additional changes we personally made, and then
>> added
>> added, that determine the diff(s).
>>
>> However in this (git checkout <treeish> -- <paths>) case we don't get
>> that
>> two step option. There is IIUC no 'git copyout <treeish> -- <paths>'
>> which
>> simply copies older files into the current worktree without adding it
>> to the
>> index/staging area.
>
> Well, technically we can `git reset` to that point, then `git checkout-
> index` where the index is already up-to-date with the state of the
> working tree we want regarding the files we care about, and then `git
> reset` back, but I don't think there is a single command for that,
> either.
>
>
>> The confounding of the, both optional, [--patch] and [<paths>] in the
>> same
>> description doesn't make it any easier. Splitting their synopses and
>> descriptions may be the way forward.
>>
>> I also haven't used the --patch option directly so there may be more
>> issues
>> beneath the surface.
>
> Yeah, definitely. There should be 2 separate entries for this.
>
> I think someone thought it was a good idea to make `<pathspec>...`
> optional in the synopsis because `git checkout` behaves in that special
> way if a patch *or* paths are given. But then, of course, with both `-
> p|--patch` and `<pathspec>...` optional, the command is the same as the
> first variation, just with optional parameters -- but the documentation
> (correctly) says those variations should behave very differently from
> each other.
>
> I don't see how this can be avoided without having 2 separate entries
> for those cases.

true.

--
Philip 


  parent reply	other threads:[~2017-04-17 20:59 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-15 20:17 [PATCH] Documentation/git-checkout: make doc. of checkout <tree-ish> clearer Christoph Michelbach
2017-04-15 23:28 ` Philip Oakley
2017-04-16 13:01   ` Christoph Michelbach
2017-04-16 18:03     ` Philip Oakley
2017-04-16 18:51       ` Christoph Michelbach
2017-04-16 21:25         ` Philip Oakley
2017-04-16 22:06           ` Christoph Michelbach
2017-04-17 16:04             ` Philip Oakley
     [not found]               ` <1492452173.11708.22.camel@gmail.com>
2017-04-17 20:59                 ` Philip Oakley [this message]
2017-04-18  0:31                   ` Junio C Hamano
2017-04-18 12:26                     ` Christoph Michelbach
2017-04-19  1:40                       ` Junio C Hamano
2017-04-22 17:12                         ` Christoph Michelbach
2017-04-24  1:55                           ` Junio C Hamano
2017-04-24 12:24                             ` Christoph Michelbach
2017-04-24 12:46                             ` Christoph Michelbach
2017-04-25  1:35                               ` Junio C Hamano
2017-04-25  9:11                                 ` Christoph Michelbach
2017-04-19  7:32                     ` Philip Oakley
2017-04-18 11:50                   ` Christoph Michelbach
2017-04-18  0:26               ` Junio C Hamano
2017-04-18 12:02                 ` Christoph Michelbach
2017-04-19  8:14                 ` Philip Oakley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5FD0803E166B4D2F9F64D8D21AC23EB3@PhilipOakley \
    --to=philipoakley@iee.org \
    --cc=git@vger.kernel.org \
    --cc=michelbach94@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).