# Re: [PATCH 15/16] checkout: add new options to support narrow checkout

9 messages from 2008-09-15 to 2008-09-17. Participants: Jakub Narebski, Nguyen Thai Ngoc Duy, Johannes Sixt.
Thread: https://gitlist.dev/t/15534

## Jakub Narebski, 2008-09-15 10:40

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <200809151240.54495.jnareb@gmail.com>
URL: https://gitlist.dev/e/200809151240.54495.jnareb%40gmail.com
In-Reply-To: <48cdde2837b2d_12d73fc6eb2c355c27876@app02.zenbe.com.tmail>

```
[I don't see mails I am replying to on GMane interface to git mailing
 list, so threads might be broken. Strange... Perhaps too long lines
 were cause of rejection by anti-SPAM vger filter?]

On Mon, 15 Sep 2008, Duy Nguyen wrote:
> On 09/15/2008 "Jakub Narebski" <jnareb@gmail.com> wrote:

> > > +Narrow works by applying your rules to the index, marking which
> > > +file you need and which file you need not. Modified/Unmerged
> > > +files cannot be marked unneeded. Unnecessary files will be
> > > +removed from working directory.  Note that after this step,
> > > +removed files can still be added to working directory when they
> > > +are needed by any git command. For example, when you have a merge
> > > +conflict, conflicted files will be checked out on working
> > > +directory and will no longer be marked "unneeded".
> > 
> > This paragraph I think need some more love...
> > 
> > So the "checkout rules" are meant to mark which paths are "wanted"
> > or "needed", and we would like to have in the checkout, and which
> > files are "unwanted" or "not needed" ("unneeded"?) and we want to
> > not have them present in working directory; something akin to accept
> > and deny rules, isn't it?
> 
> Yes. But rules will be gone, only the results remain. I don't
> save/reuse rules. 

Ah. I understand. The options are only to select which files to check-out
(which are "wanted"), and which we do not want and mark with "no-checkout"
bit ("unwanted").
 
> > What are the rules, does all files except those marked explicitely
> > as needed are unneeded, or do you have to first mark all files as
> > unneeded?
> > 
> > How would the following table look like:
> > 
> >   working directory  || needed       | not needed    |
> >   ----------------------------------------------------
> >   file is absent     || checkout     | no change     |
> >   file is present    || no change    | removed       |
> >   file is modified   || conflict     | conflict?     |
> 
> Looks better than my description. Though it would be "no change" for
> "file is modified/needed" case. There should be another line for
> unmerged entries.  

Now I am not sure about the line with 'file is modified', because even
in simple full checkout case there are different situations dealing with
checking out of index (and '-f' option), and switching to other branch
(and '-m' option).
 
Doesn't unmerged simply mean ignore "no-checkout" bit?

> > > +
> > > +New files after merges will always be "needed". You can also
> > > +apply rules when switching branches to avoid unwanted new files.
> > 
> > Does it mean that if merge brings some new files, then those
> > files would be "needed" (without "no checkout" bit)?

And as far as I understand the same for simple checkout, and for "2-way
merge" checkout.

> Yes.

Perhaps: new entries appearing in index have "no-checkout" bit unset
(cleared).  Or perhaps in addition, as clarification.

> > What does it mean this sentence about switching branches:
> > how does partial/sparse/narrow checkout rules change when
> > switching to other branch (which, like 'html' and 'todo'
> > branches in git repository, can be completely unrelated)?
> 
> Recall above I say rules are not saved. When you switch branches,
> files that are needed will still be and stay in workdir. New files
> will always appear in workdir ("needed"). If two branches are
> completely unrelated, all files will be new so you get full workdir.   

Thanks. Now I understand: new entries in index are always with
"no-checkout" bit unset, regardless how they got there.
  
> > > +Narrow spec will be used to specify how you want to narrow your
> > > +checkout. It is a list of pathspecs separated by colons. Each
> > > +patchspec specifies what files should be checked out on working
> > > +directory. Pathspec can contain wildcards and is relative to
> > > +current working directory. Usually asterisk (*) does not match
> > > +slashes. If a pathspec is prefixed by a plus sign (+), then
> > > +any asterisk will match anything, even slashes.
> > 
> > First, does this mean that you can specify paths containing colons
> > (':') only using --add-path and --remove-path, or does it mean that
> > you cannot specify paths containg colon ':' (which should be rare)
> > at all as checkout limiter / checkout narrowing rule?
> 
> You cannot do othat explicitly unfortunately. You can work-around using
> wildcard though. 

Couldn't you simply escape ':', i.e. write for example Git\:\:Tag.3pm,
or Eichten_PRD21\:313,1980_erratum.tex, or \:0.log, or perhaps
kmail/jnareb@gmail.com\:@pop.gmail.com\:995, or even something like
Mail/inbox/cur/1194202360.32296.mprnq\:2,S, in the same way like you
can escape other special characters, for example wildcard characters
like '\*' for '*' and '\?' for '?', and of course '\\' for '\'?
 
> > Second, wouldn't it be better to use '**' to match also '/'?
> > Changing meaning of '*' using per-path flag seems a bit bad.
> 
> It would be better. But I don't see any way but duplicating fnmatch()
> implementation and modify it to support '**' so I made a compromise.
> Will make another patch for '**' support and see how bloat the code
> will be.   

Well, the alternative would be to tell in commit message _why_ you
choose that (for implementation reasons), and perhaps give an example.

BTW. does '+' prefixed pathspec means that '?' can match '/', directory
separator?
 
-- 
Jakub Narebski
Poland

```

## Nguyen Thai Ngoc Duy, 2008-09-15 14:01

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <fcaeb9bf0809150701j1161f87gcedef0013a244610@mail.gmail.com>
URL: https://gitlist.dev/e/fcaeb9bf0809150701j1161f87gcedef0013a244610%40mail.gmail.com
In-Reply-To: <200809151240.54495.jnareb@gmail.com>

```
On 9/15/08, Jakub Narebski <jnareb@gmail.com> wrote:
> [I don't see mails I am replying to on GMane interface to git mailing
>   list, so threads might be broken. Strange... Perhaps too long lines
>   were cause of rejection by anti-SPAM vger filter?]

It was because I used zenbe.com (limited choices at work) to send
mails and did not realize until too late that zenbe.com did not encode
UTF-8 properly in mail headers. It made vger.k.o nervous and refuse to
accept my mails.

>  On Mon, 15 Sep 2008, Duy Nguyen wrote:
>  > On 09/15/2008 "Jakub Narebski" <jnareb@gmail.com> wrote:
>
>
> > > > +Narrow works by applying your rules to the index, marking which
>  > > > +file you need and which file you need not. Modified/Unmerged
>  > > > +files cannot be marked unneeded. Unnecessary files will be
>  > > > +removed from working directory.  Note that after this step,
>  > > > +removed files can still be added to working directory when they
>  > > > +are needed by any git command. For example, when you have a merge
>  > > > +conflict, conflicted files will be checked out on working
>  > > > +directory and will no longer be marked "unneeded".
>  > >
>  > > This paragraph I think need some more love...
>  > >
>  > > So the "checkout rules" are meant to mark which paths are "wanted"
>  > > or "needed", and we would like to have in the checkout, and which
>  > > files are "unwanted" or "not needed" ("unneeded"?) and we want to
>  > > not have them present in working directory; something akin to accept
>  > > and deny rules, isn't it?
>  >
>  > Yes. But rules will be gone, only the results remain. I don't
>  > save/reuse rules.
>
>
> Ah. I understand. The options are only to select which files to check-out
>  (which are "wanted"), and which we do not want and mark with "no-checkout"
>  bit ("unwanted").
>
>
>  > > What are the rules, does all files except those marked explicitely
>  > > as needed are unneeded, or do you have to first mark all files as
>  > > unneeded?
>  > >
>  > > How would the following table look like:
>  > >
>  > >   working directory  || needed       | not needed    |
>  > >   ----------------------------------------------------
>  > >   file is absent     || checkout     | no change     |
>  > >   file is present    || no change    | removed       |
>  > >   file is modified   || conflict     | conflict?     |
>  >
>  > Looks better than my description. Though it would be "no change" for
>  > "file is modified/needed" case. There should be another line for
>  > unmerged entries.
>
>
> Now I am not sure about the line with 'file is modified', because even
>  in simple full checkout case there are different situations dealing with
>  checking out of index (and '-f' option), and switching to other branch
>  (and '-m' option).
>
>  Doesn't unmerged simply mean ignore "no-checkout" bit?

Yes.

>  > > > +Narrow spec will be used to specify how you want to narrow your
>  > > > +checkout. It is a list of pathspecs separated by colons. Each
>  > > > +patchspec specifies what files should be checked out on working
>  > > > +directory. Pathspec can contain wildcards and is relative to
>  > > > +current working directory. Usually asterisk (*) does not match
>  > > > +slashes. If a pathspec is prefixed by a plus sign (+), then
>  > > > +any asterisk will match anything, even slashes.
>  > >
>  > > First, does this mean that you can specify paths containing colons
>  > > (':') only using --add-path and --remove-path, or does it mean that
>  > > you cannot specify paths containg colon ':' (which should be rare)
>  > > at all as checkout limiter / checkout narrowing rule?
>  >
>  > You cannot do othat explicitly unfortunately. You can work-around using
>  > wildcard though.
>
>
> Couldn't you simply escape ':', i.e. write for example Git\:\:Tag.3pm,
>  or Eichten_PRD21\:313,1980_erratum.tex, or \:0.log, or perhaps
>  kmail/jnareb@gmail.com\:@pop.gmail.com\:995, or even something like
>  Mail/inbox/cur/1194202360.32296.mprnq\:2,S, in the same way like you
>  can escape other special characters, for example wildcard characters
>  like '\*' for '*' and '\?' for '?', and of course '\\' for '\'?
>

Sure. Somehow I forgot that.

>  > > Second, wouldn't it be better to use '**' to match also '/'?
>  > > Changing meaning of '*' using per-path flag seems a bit bad.
>  >
>  > It would be better. But I don't see any way but duplicating fnmatch()
>  > implementation and modify it to support '**' so I made a compromise.
>  > Will make another patch for '**' support and see how bloat the code
>  > will be.
>
>
> Well, the alternative would be to tell in commit message _why_ you
>  choose that (for implementation reasons), and perhaps give an example.
>
>  BTW. does '+' prefixed pathspec means that '?' can match '/', directory
>  separator?

No it only affects '*'.

So how about this? Note that document changes that also require code
change like narrow spec escape or '**' do not get in. I will change it
when I update code.

--<--
Narrow checkout
---------------

Normally when you do checkout a branch, your working directory
will be fully populated. In some situations, you just need to
work on certain files, no full checkout is needed. Narrow
checkout is a mode that limits checkout area according to your
needs.

Because narrow checkout uses new index format, it will be
incompatible with git prior to 1.6.0 regarding worktree operations.
Repository-only operations such as clone, push, pull... should not be
affected by narrow checkout. In order to make your working directory
work again with those versions, you can use `git checkout --full` to
return to normal mode (and compatible index format).

In narrow checkout mode, checkout status of every files in your
working directory will be recorded in index. If a file is marked
"no-checkout", it means that file is not needed to be present in
working directory by user or any git command. When a new file is added
to index, it will be marked "checkout" unless narrow spec is applied.
Unmerged files are always "checkout". linkgit:git-update-index[1] can
be used to update "checkout/no-checkout" status in index. When you
checkout new files using "git checkout <file>" they will be
automatically marked "checkout". Other commands such as "git apply"
can also checkout new files if they are needed.

"No-checkout" status is very similar to "assume-unchanged bit"
(see linkgit:git-update-index[1]). The main difference between them
is "assume unchanged" bit just ignores corresponding files in working
directory while narrow checkout goes a bit farther, remove those files
when it is safe to do so.

Narrow spec
-----------

Narrow spec is used to easily specify how do you want to form your
checkout area.  It is a list of pathspecs separated by colons. Each
patchspec specifies what files should or should not be checked out on
working directory. Pathspec can contain wildcards and is relative to
current working directory. Usually asterisk (*) does not match
slashes. If a pathspec is prefixed by a plus sign (+), then any
asterisk will match anything, even slashes.

When you apply new narrow spec to your working directory using either
--path, --add-path or --remove-path, it will update "checkout" status
in index accordingly. Moreover, if a file is marked "no-checkout" and
is present in working directory, it will be removed. If a file is
turned from "no-checkout" to "checkout", then it will be added again
to working directory. Modified and unmerged entries can't bear
"no-checkout" status, if narrow spec applies to them, "git checkout"
will refuse to update working directory.

Narrow spec is not saved by "git checkout". You can form your checkout
area on one go with --path option, or do it incrementally
with --add-path and --remove-path.
--<--

-- 
Duy

```

## Jakub Narebski, 2008-09-15 20:05

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <200809152205.15388.jnareb@gmail.com>
URL: https://gitlist.dev/e/200809152205.15388.jnareb%40gmail.com
In-Reply-To: <fcaeb9bf0809150701j1161f87gcedef0013a244610@mail.gmail.com>

```
On Mon, 15 Sep 2008 16:01, Nguyen Thai Ngoc Duy wrote:
> On 9/15/08, Jakub Narebski <jnareb@gmail.com> wrote:
>> [I don't see mails I am replying to on GMane interface to git mailing
>>   list, so threads might be broken. Strange... Perhaps too long lines
>>   were cause of rejection by anti-SPAM vger filter?]
> 
> It was because I used zenbe.com (limited choices at work) to send
> mails and did not realize until too late that zenbe.com did not encode
> UTF-8 properly in mail headers. It made vger.k.o nervous and refuse to
> accept my mails.

Yes, vger anti-SPAM filter is quite "trigger happy"...

>>  On Mon, 15 Sep 2008, Duy Nguyen wrote:
>>> On 09/15/2008 "Jakub Narebski" <jnareb@gmail.com> wrote:

>>>>> +Narrow spec will be used to specify how you want to narrow your
>>>>> +checkout. It is a list of pathspecs separated by colons. Each
>>>>> +patchspec specifies what files should be checked out on working
>>>>> +directory. Pathspec can contain wildcards and is relative to
>>>>> +current working directory. Usually asterisk (*) does not match
>>>>> +slashes. If a pathspec is prefixed by a plus sign (+), then
>>>>> +any asterisk will match anything, even slashes.
>>>>
>>>> First, does this mean that you can specify paths containing colons
>>>> (':') only using --add-path and --remove-path, or does it mean that
>>>> you cannot specify paths containg colon ':' (which should be rare)
>>>> at all as checkout limiter / checkout narrowing rule?
>>>
>>> You cannot do othat explicitly unfortunately. You can work-around using
>>> wildcard though.
>>
>> Couldn't you simply escape ':', i.e. write for example Git\:\:Tag.3pm,
>> or Eichten_PRD21\:313,1980_erratum.tex, or \:0.log, or perhaps
>> kmail/jnareb@gmail.com\:@pop.gmail.com\:995, or even something like
>> Mail/inbox/cur/1194202360.32296.mprnq\:2,S, in the same way like you
>> can escape other special characters, for example wildcard characters
>> like '\*' for '*' and '\?' for '?', and of course '\\' for '\'?
> 
> Sure. Somehow I forgot that.

Well, if it is possible, it should be stated in documentation.
Even if it is obvious.


> [...] how about this? Note that document changes that also require code
> change like narrow spec escape or '**' do not get in. I will change it
> when I update code.

> --<--
> Narrow checkout
> ---------------
> 
> Normally when you do checkout a branch, your working directory
> will be fully populated. In some situations, you just need to
> work on certain files, no full checkout is needed. Narrow
> checkout is a mode that limits checkout area according to your
> needs.

You have decided then on the term 'narrow checkout', and not
'partial checkout' or 'sparse checkout', then?
 
It would be nice if git mailing list came with examples of usage for
this feature.  It was quite frequently requested.  I can think off-hand
about two reasons one might want to use 'narrow checkout':

 1.) when you are not interested in files outside some selected
     set, and you don't want to mess files outside this set, even
     by accident.  For example for end-user documentation writers
     it would be Documentation/* (non-recursive).

 2.) when you work on some large monolithic repository which doesn't
     use submodules, and you have limited and small quota (or disk size).
     Usually repository size is smaller or comparable to checkout size,
     and even if it isn't you can use alternates to reduce size of
     repository (assuming that reference repository is hosted outside
     user quota).


> Because narrow checkout uses new index format, it will be
> incompatible with git prior to 1.6.0 regarding worktree operations.
> Repository-only operations such as clone, push, pull... should not be

s/pull/fetch/. pull affects working repository, and it can affect
narrow checkout unexpectedly by conflicts during merge part of pull.

> affected by narrow checkout. In order to make your working directory
> work again with those versions, you can use `git checkout --full` to
> return to normal mode (and compatible index format).

By the way, you have made "git checkout <file>" get file and mark
it "wanted", i.e. clear/zero "no-checkout" bit.  Wouldn't then
"git checkout ." be shorter equivalent to "git checkout --full"?
I'm not saying that '--full' option should be abandoned...

>
> In narrow checkout mode, checkout status of every files in your
> working directory will be recorded in index. If a file is marked
> "no-checkout", it means that file is not needed to be present in
> working directory by user or any git command. When a new file is added
> to index, it will be marked "checkout" unless narrow spec is applied.
> Unmerged files are always "checkout". linkgit:git-update-index[1] can
> be used to update "checkout/no-checkout" status in index. When you
> checkout new files using "git checkout <file>" they will be
> automatically marked "checkout". Other commands such as "git apply"
> can also checkout new files if they are needed.
> 
> "No-checkout" status is very similar to "assume-unchanged bit"
> (see linkgit:git-update-index[1]). The main difference between them
> is "assume unchanged" bit just ignores corresponding files in working
> directory while narrow checkout goes a bit farther, remove those files
> when it is safe to do so.

Good description (although probably could be improved even further).

>
> Narrow spec
> -----------
> 
> Narrow spec is used to easily specify how do you want to form your
> checkout area.  It is a list of pathspecs separated by colons. Each
> patchspec specifies what files should or should not be checked out on
> working directory. Pathspec can contain wildcards and is relative to
> current working directory. Usually asterisk (*) does not match
> slashes. If a pathspec is prefixed by a plus sign (+), then any
> asterisk will match anything, even slashes.

Here I think you should give some examples, perhaps together with
wildcard escaping, escape (backslash) escaping and colon escaping.

> 
> When you apply new narrow spec to your working directory using either
> --path, --add-path or --remove-path, it will update "checkout" status
> in index accordingly. Moreover, if a file is marked "no-checkout" and
> is present in working directory, it will be removed. If a file is
> turned from "no-checkout" to "checkout", then it will be added again
> to working directory. Modified and unmerged entries can't bear
> "no-checkout" status, if narrow spec applies to them, "git checkout"
> will refuse to update working directory.

Do I understand correctly, that if one uses --path=<colon separated list>
_only_ filenames matching one of patterns specified would be checked out,
--add-path=<path> would additionally checkout given path and mark "wanted",
and  --remove-path=<path> would additionally mark "no-checkout" and remove
path?  

What --add-path starts from, i.e. does

  $ git checkout --add-path=.gitignore

starts from empty set if --add-path is first, or from full set as without
--add-path?

And is <pathspec> matched against full pathname, or like .gitignore
rules, i.e. as full pathname if it has at least one '/' in it?

> 
> Narrow spec is not saved by "git checkout". You can form your checkout
> area on one go with --path option, or do it incrementally
> with --add-path and --remove-path.
> --<--

I would probably say that specification used to select which paths to
check out is not saved anywhere, and used only to mark paths in index
as "no-checkout" or not.  Or somehing like that.


Thank you very much for your continued work on this feature!
-- 
Jakub Narebski
Poland

```

## Nguyen Thai Ngoc Duy, 2008-09-16 12:21

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <fcaeb9bf0809160521o24fd26e4l40f1798228d51712@mail.gmail.com>
URL: https://gitlist.dev/e/fcaeb9bf0809160521o24fd26e4l40f1798228d51712%40mail.gmail.com
In-Reply-To: <200809152205.15388.jnareb@gmail.com>

```
On 9/16/08, Jakub Narebski <jnareb@gmail.com> wrote:
>  >> Couldn't you simply escape ':', i.e. write for example Git\:\:Tag.3pm,
>  >> or Eichten_PRD21\:313,1980_erratum.tex, or \:0.log, or perhaps
>  >> kmail/jnareb@gmail.com\:@pop.gmail.com\:995, or even something like
>  >> Mail/inbox/cur/1194202360.32296.mprnq\:2,S, in the same way like you
>  >> can escape other special characters, for example wildcard characters
>  >> like '\*' for '*' and '\?' for '?', and of course '\\' for '\'?
>  >
>  > Sure. Somehow I forgot that.
>
>
> Well, if it is possible, it should be stated in documentation.
>  Even if it is obvious.

I mean it should be possible, but not yet implemented. Next time
document will be updated when '\' escape is implemented.

>  > --<--
>  > Narrow checkout
>  > ---------------
>  >
>  > Normally when you do checkout a branch, your working directory
>  > will be fully populated. In some situations, you just need to
>  > work on certain files, no full checkout is needed. Narrow
>  > checkout is a mode that limits checkout area according to your
>  > needs.
>
>
> You have decided then on the term 'narrow checkout', and not
>  'partial checkout' or 'sparse checkout', then?

Not yet. I tend to prefer partial/sparse checkout. Probably should
have a look at how other SCMs do and what term they use. If Git's
functionality is so different, a different term might notice people
about that.

>  > Because narrow checkout uses new index format, it will be
>  > incompatible with git prior to 1.6.0 regarding worktree operations.
>  > Repository-only operations such as clone, push, pull... should not be
>
>
> s/pull/fetch/. pull affects working repository, and it can affect
>  narrow checkout unexpectedly by conflicts during merge part of pull.

Bad writing. I mean pull/fetch from a narrow-checkout-ed repository to
another fully populated one. Will fix.

>
>  > affected by narrow checkout. In order to make your working directory
>  > work again with those versions, you can use `git checkout --full` to
>  > return to normal mode (and compatible index format).
>
>
> By the way, you have made "git checkout <file>" get file and mark
>  it "wanted", i.e. clear/zero "no-checkout" bit.  Wouldn't then
>  "git checkout ." be shorter equivalent to "git checkout --full"?
>  I'm not saying that '--full' option should be abandoned...

It is not equivalent. "git checkout ." will happily overwrite any
modified files in your working directory.

>
>  >
>  > In narrow checkout mode, checkout status of every files in your
>  > working directory will be recorded in index. If a file is marked
>  > "no-checkout", it means that file is not needed to be present in
>  > working directory by user or any git command. When a new file is added
>  > to index, it will be marked "checkout" unless narrow spec is applied.
>  > Unmerged files are always "checkout". linkgit:git-update-index[1] can
>  > be used to update "checkout/no-checkout" status in index. When you
>  > checkout new files using "git checkout <file>" they will be
>  > automatically marked "checkout". Other commands such as "git apply"
>  > can also checkout new files if they are needed.
>  >
>  > "No-checkout" status is very similar to "assume-unchanged bit"
>  > (see linkgit:git-update-index[1]). The main difference between them
>  > is "assume unchanged" bit just ignores corresponding files in working
>  > directory while narrow checkout goes a bit farther, remove those files
>  > when it is safe to do so.
>
>
> Good description (although probably could be improved even further).

Contributions are welcome   ;)

>
>  >
>  > When you apply new narrow spec to your working directory using either
>  > --path, --add-path or --remove-path, it will update "checkout" status
>  > in index accordingly. Moreover, if a file is marked "no-checkout" and
>  > is present in working directory, it will be removed. If a file is
>  > turned from "no-checkout" to "checkout", then it will be added again
>  > to working directory. Modified and unmerged entries can't bear
>  > "no-checkout" status, if narrow spec applies to them, "git checkout"
>  > will refuse to update working directory.
>
>
> Do I understand correctly, that if one uses --path=<colon separated list>
>  _only_ filenames matching one of patterns specified would be checked out,
>  --add-path=<path> would additionally checkout given path and mark "wanted",
>  and  --remove-path=<path> would additionally mark "no-checkout" and remove
>  path?

--add-path/--remove-path also use narrow spec, which could be more
than one pattern.

>  What --add-path starts from, i.e. does
>
>   $ git checkout --add-path=.gitignore
>
>  starts from empty set if --add-path is first, or from full set as without
>  --add-path?

I'm not sure I understand this.

>  And is <pathspec> matched against full pathname, or like .gitignore
>  rules, i.e. as full pathname if it has at least one '/' in it?

like shell wildcard, full pathname must match. On my way back home, I
thought I should have removed mention of "pathspec", which behaves a
little bit different.

Also those specs are relative to working directory though, so if you
are in b/c and want to match d, you only need to type --add-path=d
instead of --add-path=b/c/d. Will add this to doc.

>
>  >
>  > Narrow spec is not saved by "git checkout". You can form your checkout
>  > area on one go with --path option, or do it incrementally
>  > with --add-path and --remove-path.
>  > --<--
>
>
> I would probably say that specification used to select which paths to
>  check out is not saved anywhere, and used only to mark paths in index
>  as "no-checkout" or not.  Or somehing like that.
>

Thanks (as for other parts of your comments stripped by me)

-- 
Duy

```

## Jakub Narebski, 2008-09-17 09:07

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <200809171107.35826.jnareb@gmail.com>
URL: https://gitlist.dev/e/200809171107.35826.jnareb%40gmail.com
In-Reply-To: <fcaeb9bf0809160521o24fd26e4l40f1798228d51712@mail.gmail.com>

```
On Tue, 16 Sep 2008, Nguyen Thai Ngoc Duy wrote:
> On 9/16/08, Jakub Narebski <jnareb@gmail.com> wrote:

>>>> Couldn't you simply escape ':', i.e. write for example Git\:\:Tag.3pm,
>>>> or Eichten_PRD21\:313,1980_erratum.tex, or \:0.log, or perhaps
>>>> kmail/jnareb@gmail.com\:@pop.gmail.com\:995, or even something like
>>>> Mail/inbox/cur/1194202360.32296.mprnq\:2,S, in the same way like you
>>>> can escape other special characters, for example wildcard characters
>>>> like '\*' for '*' and '\?' for '?', and of course '\\' for '\'?
>>>
>>> Sure. Somehow I forgot that.
>>
>> Well, if it is possible, it should be stated in documentation.
>>  Even if it is obvious.
> 
> I mean it should be possible, but not yet implemented. Next time
> document will be updated when '\' escape is implemented.

I was thinking about explicitly stating this limitation (that ':' in
paths are not permitted/can be not escaped), or put it in "Bugs" aka
"Known Limitations" ;-) (sub)section.

>>> --<--
>>> Narrow checkout
>>> ---------------
>>>
>>> Normally when you do checkout a branch, your working directory
>>> will be fully populated. In some situations, you just need to
>>> work on certain files, no full checkout is needed. Narrow
>>> checkout is a mode that limits checkout area according to your
>>> needs.
>>
>> You have decided then on the term 'narrow checkout', and not
>>  'partial checkout' or 'sparse checkout', then?
> 
> Not yet. I tend to prefer partial/sparse checkout. Probably should
> have a look at how other SCMs do and what term they use. If Git's
> functionality is so different, a different term might notice people
> about that.

Perhaps whip up a survey? Just kidding (or not).

>>> Because narrow checkout uses new index format, it will be
>>> incompatible with git prior to 1.6.0 regarding worktree operations.
>>> Repository-only operations such as clone, push, pull... should not be
>>
>> s/pull/fetch/. pull affects working repository, and it can affect
>>  narrow checkout unexpectedly by conflicts during merge part of pull.
> 
> Bad writing. I mean pull/fetch from a narrow-checkout-ed repository to
> another fully populated one. Will fix.

Well, I though that you were referring to operations done _inside_
given repository, not on repository from outside. So I would say
something like repository-only operations (operations which do
not affect index and/or working area) such as fetch and pull, and
by definition all remote operations such as fetching from repository,
or cloning this repository... but this also isn't IMHO best way to
say it.

>>> affected by narrow checkout. In order to make your working directory
>>> work again with those versions, you can use `git checkout --full` to
>>> return to normal mode (and compatible index format).
>>
>>
>> By the way, you have made "git checkout <file>" get file and mark
>>  it "wanted", i.e. clear/zero "no-checkout" bit.  Wouldn't then
>>  "git checkout ." be shorter equivalent to "git checkout --full"?
>>  I'm not saying that '--full' option should be abandoned...
> 
> It is not equivalent. "git checkout ." will happily overwrite any
> modified files in your working directory.

True, I fortgot about this. Sorry, my mistake.
 
>>> When you apply new narrow spec to your working directory using either
>>> --path, --add-path or --remove-path, it will update "checkout" status
>>> in index accordingly. Moreover, if a file is marked "no-checkout" and
>>> is present in working directory, it will be removed. If a file is
>>> turned from "no-checkout" to "checkout", then it will be added again
>>> to working directory. Modified and unmerged entries can't bear
>>> "no-checkout" status, if narrow spec applies to them, "git checkout"
>>> will refuse to update working directory.
>>
>>
>> Do I understand correctly, that if one uses --path=<colon separated list>
>>  _only_ filenames matching one of patterns specified would be checked out,
>>  --add-path=<path> would additionally checkout given path and mark "wanted",
>>  and  --remove-path=<path> would additionally mark "no-checkout" and remove
>>  path?
> 
> --add-path/--remove-path also use narrow spec, which could be more
> than one pattern.

What is the difference then between --add-path and --path? The fact
that --add-path can be incremental, and --path starts always from
an empty set?
 
>>  What --add-path starts from, i.e. does
>>
>>   $ git checkout --add-path=.gitignore
>>
>>  starts from empty set if --add-path is first, or from full set as without
>>  --add-path?
> 
> I'm not sure I understand this.

Well, what I wanted to ask is if --remove-path starts from fully
checked out repository, for example if

  $ git checkout --remove-path=some_large_file

would checkout all files _except_ 'some_large_file'.

>>  And is <pathspec> matched against full pathname, or like .gitignore
>>  rules, i.e. as full pathname if it has at least one '/' in it?
> 
> like shell wildcard, full pathname must match. On my way back home, I
> thought I should have removed mention of "pathspec", which behaves a
> little bit different.
> 
> Also those specs are relative to working directory though, so if you
> are in b/c and want to match d, you only need to type --add-path=d
> instead of --add-path=b/c/d. Will add this to doc.

I would have thought that you follow the same rules (perhaps with
exception of !path excluding rule) like for gitignore and gitattributes.

-- 
Jakub Narebski
Poland

```

## Nguyen Thai Ngoc Duy, 2008-09-17 13:49

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <fcaeb9bf0809170649w418f4af5x3055c04994c694dc@mail.gmail.com>
URL: https://gitlist.dev/e/fcaeb9bf0809170649w418f4af5x3055c04994c694dc%40mail.gmail.com
In-Reply-To: <200809171107.35826.jnareb@gmail.com>

```
On 9/17/08, Jakub Narebski <jnareb@gmail.com> wrote:
>  >> You have decided then on the term 'narrow checkout', and not
>  >>  'partial checkout' or 'sparse checkout', then?
>  >
>  > Not yet. I tend to prefer partial/sparse checkout. Probably should
>  > have a look at how other SCMs do and what term they use. If Git's
>  > functionality is so different, a different term might notice people
>  > about that.
>
>
> Perhaps whip up a survey? Just kidding (or not).

Well I've been asking about the name on this list long enough. I'm
going with 'sparse checkout' as svn' sparse directories does not look
too different from git's.

>  >>> When you apply new narrow spec to your working directory using either
>  >>> --path, --add-path or --remove-path, it will update "checkout" status
>  >>> in index accordingly. Moreover, if a file is marked "no-checkout" and
>  >>> is present in working directory, it will be removed. If a file is
>  >>> turned from "no-checkout" to "checkout", then it will be added again
>  >>> to working directory. Modified and unmerged entries can't bear
>  >>> "no-checkout" status, if narrow spec applies to them, "git checkout"
>  >>> will refuse to update working directory.
>  >>
>  >>
>  >> Do I understand correctly, that if one uses --path=<colon separated list>
>  >>  _only_ filenames matching one of patterns specified would be checked out,
>  >>  --add-path=<path> would additionally checkout given path and mark "wanted",
>  >>  and  --remove-path=<path> would additionally mark "no-checkout" and remove
>  >>  path?
>  >
>  > --add-path/--remove-path also use narrow spec, which could be more
>  > than one pattern.
>
>
> What is the difference then between --add-path and --path? The fact
>  that --add-path can be incremental, and --path starts always from
>  an empty set?

--path clears out all no-checkout bits and set again based on the
given spec. --add-path adds more checkout entries based on the given
spec, think of widening checkout area. --remove-path does narrow the
checkout area. They are like '=', '+=' and '-=' operators
respectively.

>
>  >>  What --add-path starts from, i.e. does
>  >>
>  >>   $ git checkout --add-path=.gitignore
>  >>
>  >>  starts from empty set if --add-path is first, or from full set as without
>  >>  --add-path?
>  >
>  > I'm not sure I understand this.
>
>
> Well, what I wanted to ask is if --remove-path starts from fully
>  checked out repository, for example if
>
>   $ git checkout --remove-path=some_large_file
>
>  would checkout all files _except_ 'some_large_file'.

No, there is no negative spec. Like I said above, --remove-path is to
remove some files based on the given spec.

>
>  >>  And is <pathspec> matched against full pathname, or like .gitignore
>  >>  rules, i.e. as full pathname if it has at least one '/' in it?
>  >
>  > like shell wildcard, full pathname must match. On my way back home, I
>  > thought I should have removed mention of "pathspec", which behaves a
>  > little bit different.
>  >
>  > Also those specs are relative to working directory though, so if you
>  > are in b/c and want to match d, you only need to type --add-path=d
>  > instead of --add-path=b/c/d. Will add this to doc.
>
>
> I would have thought that you follow the same rules (perhaps with
>  exception of !path excluding rule) like for gitignore and gitattributes.
>

Um.. never thought of gitignores/gitattributes rules before. It's a
good idea all narrowspec/gitignore/gitattributes using the same rules.
Thanks.
-- 
Duy

```

## Johannes Sixt, 2008-09-17 16:32

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <48D13128.3000509@viscovery.net>
URL: https://gitlist.dev/e/48D13128.3000509%40viscovery.net
In-Reply-To: <fcaeb9bf0809170649w418f4af5x3055c04994c694dc@mail.gmail.com>

```
Nguyen Thai Ngoc Duy schrieb:
> Well I've been asking about the name on this list long enough. I'm
> going with 'sparse checkout' as svn' sparse directories does not look
> too different from git's.

FWIW, /me likes 'sparse checkout'.

> --path clears out all no-checkout bits and set again based on the
> given spec. --add-path adds more checkout entries based on the given
> spec, think of widening checkout area. --remove-path does narrow the
> checkout area. They are like '=', '+=' and '-=' operators
> respectively.

The still un-answered question was: In a full checkout, i.e. in a
repository where the narrow/sparse checkout feature has never been used so
far, is

   $ git checkout --add-path=foo

a no-op, or is it equivalent to

   $ git checkout --path=foo

Or stated differently: In the sequence

   $ git checkout --full
   $ git checkout --add-path=foo

is the second statement redundant?

-- Hannes

```

## Nguyen Thai Ngoc Duy, 2008-09-17 16:43

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <fcaeb9bf0809170943k43e5b4adre80856d2b78cac99@mail.gmail.com>
URL: https://gitlist.dev/e/fcaeb9bf0809170943k43e5b4adre80856d2b78cac99%40mail.gmail.com
In-Reply-To: <48D13128.3000509@viscovery.net>

```
On 9/17/08, Johannes Sixt <j.sixt@viscovery.net> wrote:
> The still un-answered question was: In a full checkout, i.e. in a
>  repository where the narrow/sparse checkout feature has never been used so
>  far, is
>
>    $ git checkout --add-path=foo
>
>  a no-op, or is it equivalent to
>
>    $ git checkout --path=foo

no-op.
-- 
Duy

```

## Jakub Narebski, 2008-09-17 21:31

Subject: Re: [PATCH 15/16] checkout: add new options to support narrow checkout
Message-ID: <200809172331.31972.jnareb@gmail.com>
URL: https://gitlist.dev/e/200809172331.31972.jnareb%40gmail.com
In-Reply-To: <fcaeb9bf0809170649w418f4af5x3055c04994c694dc@mail.gmail.com>

```
On Wed, 17 Sep 2008, Nguyen Thai Ngoc Duy wrote:
> On 9/17/08, Jakub Narebski <jnareb@gmail.com> wrote:

>>
>> Well, what I wanted to ask is if --remove-path starts from fully
>>  checked out repository, for example if
>>
>>   $ git checkout --remove-path=some_large_file
>>
>>  would checkout all files _except_ 'some_large_file'.
> 
> No, there is no negative spec. Like I said above, --remove-path is to
> remove some files based on the given spec.

So "git checkout --path/--add-path/--remove-path" is porcelain
interface to use (git-update-index is plumbing)?
 
>>>>  And is <pathspec> matched against full pathname, or like .gitignore
>>>>  rules, i.e. as full pathname if it has at least one '/' in it?
>>>
>>> like shell wildcard, full pathname must match. On my way back home, I
>>> thought I should have removed mention of "pathspec", which behaves a
>>> little bit different.
>>>
>>> Also those specs are relative to working directory though, so if you
>>> are in b/c and want to match d, you only need to type --add-path=d
>>> instead of --add-path=b/c/d. Will add this to doc.
>>
>> I would have thought that you follow the same rules (perhaps with
>>  exception of !path excluding rule) like for gitignore and gitattributes.
> 
> Um.. never thought of gitignores/gitattributes rules before. It's a
> good idea all narrowspec/gitignore/gitattributes using the same rules.

Perhaps you would be able to even reuse some of implementation?...

-- 
Jakub Narebski
Poland

```
