* Re: [PATCH 05/16] ls-files: add --narrow-checkout option to "will checkout" entries
From: Jakub Narebski @ 2008-09-14 18:55 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1221397685-27715-6-git-send-email-pclouds@gmail.com>
I will comment only on the documentation...
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> Even in narrow checkout mode, "git ls-files --cached" (and --stage)
> will show all entries in index. When those options are used together
> with --narrow-checkout, no-checkout entries will be skipped.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
> index 9f85d60..f74b212 100644
> --- a/Documentation/git-ls-files.txt
> +++ b/Documentation/git-ls-files.txt
> @@ -72,6 +73,11 @@ OPTIONS
> to file/directory conflicts for checkout-index to
> succeed.
>
> +--narrow-checkout::
> + When narrow checkout is being used, this option together with other
> + index-based selection options like --cached or --stage, only narrowed
> + portion will be printed out.
> +
I would rather say, that if git-ls-files is requested to show index
content (by using selection options like --cached or --stage), then
by default it shows all entries, also those marked "no checkout".
With this option git-ls-files would show only files that would get
checked out.
BTW. I think here --narrow-checkout is a good name, even though
I prefer 'partial checkout' or 'sparse checkout', because here it
is about narrowing the list of paths from index shown.
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH 04/16] update-index: add --checkout/--no-checkout to update CE_NO_CHECKOUT bit
From: Jakub Narebski @ 2008-09-14 18:50 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1221397685-27715-5-git-send-email-pclouds@gmail.com>
I will comment only on documentation...
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> --- a/Documentation/git-update-index.txt
> +++ b/Documentation/git-update-index.txt
> @@ -15,6 +15,7 @@ SYNOPSIS
> [--cacheinfo <mode> <object> <file>]\*
> [--chmod=(+|-)x]
> [--assume-unchanged | --no-assume-unchanged]
> + [--checkout | --no-checkout]
> [--ignore-submodules]
> [--really-refresh] [--unresolve] [--again | -g]
> [--info-only] [--index-info]
> @@ -88,6 +89,17 @@ OPTIONS
> sometimes helpful when working with a big project on a
> filesystem that has very slow lstat(2) system call
> (e.g. cifs).
> +--checkout::
> +--no-checkout::
> + When these flags are specified, the object name recorded
> + for the paths are not updated. Instead, these options
> + set and unset the "no-checkout" bit for the paths. This
> + bit is used for marking files for narrow checkout. If
> + a path is marked "no-checkout", then it should not be
> + checked out unless requested by user or needed for a git
> + command to function.
> + See linkgit:git-checkout[1] for more information about
> + narrow checkout.
Low level (porcelain) access to "no checkout" bit/flag, isn't it?
Nice. One caveat: you refer to git-checkout(1), which I think is
updated to include referenced information only later in the series.
Perhaps add "See linkgit:git-checkout[1]..." part only _after_ the
referenced information is in Documentation/git-checkout.txt
> +
> This option can be also used as a coarse file-level mechanism
> to ignore uncommitted changes in tracked files (akin to what
Ooops. It looks like it is continuation line to _previous_ option,
probably --assume-unchanged, which you have interrupted by mistake.
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* Re: CGit and repository list
From: Lars Hjemli @ 2008-09-14 18:01 UTC (permalink / raw)
To: Kristian Høgsberg; +Cc: Petr Baudis, Johan Herland, git, Jakub Narebski
In-Reply-To: <59ad55d30809141022r6973155fh933976d25ef4cf01@mail.gmail.com>
On Sun, Sep 14, 2008 at 7:22 PM, Kristian Høgsberg <krh@bitplanet.net> wrote:
> On Sun, Sep 14, 2008 at 1:14 PM, Kristian Høgsberg <krh@bitplanet.net> wrote:
>> The script we're using on freedesktop.org is something like this:
>>
>> http://people.freedesktop.org/~krh/find-repos.sh
Thanks.
>>
>> which isn't too scary. We run it from a cron script, every ten
>> minutes or so. It's much better than rescanning all the dirs every
>> time somebody requests the repo listing (we have a lot of repos, check
>> cgit.freedesktop.org). We have no need for cgit to to this
>> automatically on every request, and I don't see us using that feature
>> if it gets implemented.
Yeah, I'm not interested in a full rescan for each request either. But
having something similar to your script available as a command line
option for cgit wouldn't hurt.
> A feature that would be useful, though, would be support for listing a
> sub-set of repos... for example, cgit.freedesktop.org/~krh would list
> just my repos and cgit.freedesktop.org/xorg/driver would list all the
> X.org driver repos.
This sounds nice, and shouldn't be very difficult...
> Another idea is a javascript/css frontpage that
> supports folding repos away according to the groups and possibly
> common path elements in the url.
This could also be nice as long as non-javascript clients doesn't suffer ;-)
--
larsh
^ permalink raw reply
* Re: Git at Better SCM Initiative comparison of VCS (long)
From: Jakub Narebski @ 2008-09-14 17:48 UTC (permalink / raw)
To: Dmitry Potapov; +Cc: git, Alexey Mahotkin
In-Reply-To: <20080914144306.GF28210@dpotapov.dyndns.org>
On Sun, 14 Sep 2008, Dmitry Potapov wrote:
>
> I have added Alexey Mahotkin in CC, who is allegedly the author of that
> information about Git that you can read on the better-scm site.
Did you forwarded him my original email, I should I do it?
I'm sorry about that, I should have tried to find original author
of Git entry on Better SCM Initiative comparison table, and CC him.
As excuse I have the fact that while instructions how to add new
SCM to the table are easy to find and quite detailed, this is not
the case for trying to correct information in it, including how to
find original authors.
By the way, perhaps I haven't stressed this like I should, but the
most important thing I wanted to ask git list about, besides insight
in my comments and proposal for changes, was if it is possible
using current hooks infrastructure to restrict changes coming from
some account in such a way as to allow it only if all changes are
restricted to specified directory. In short if "Repository Permissions"
_can_ be implemented on per-directory and/or per-file basis (never
mind the fact that it is better to use social means rather than
technical restrictions, and distributed SCM are good at social solution
of a 'honors system').
> On Sat, Sep 13, 2008 at 07:06:16PM +0200, Jakub Narebski wrote:
> >
> > I have thought about trying yet another time... but Git was already
> > added; see http://better-scm.berlios.de/news/changes-2008-08-07/
>
> Interesting, the site still mentions Git as missing in a few places.
> For instance, when you click on Git in the list of alternatives, you
> get this: http://better-scm.berlios.de/alternatives/git/
> and then when you got to FAQ, you can read this:
>
> | The reason it's not there is that while many people have complained
> | about its absense, no one suitable has volunteered to become its
> | champion and supplied a good enough patch. [...]
Well, I have also noticed that, and I have planned on mentioning this
discrepancy when sending corrections for Git for SCM comparison table
to Shlomi Fish / Better SCM Initiative.
> | In addition to everything that was said here, it seems that the
> | originator and maintainer of the site and comparison is now banned
> | from sending messages to vger.kernel.org, which hosts several
> | Linux-kernel-related mailing-lists, including the git one. This has
> | interfered with some of his Linux-related open-source work, including
> | trying to find a "Better SCM" maintainer for git. This is unfortunate,
> | but changing this situation, is currently beyond his control.
>
> Source: http://better-scm.berlios.de/faq/#git-missing
>
> I am surprised to hear that Shlomi Fish is banned...
Well, anti-SPAM filter at vger.kernel.org is rather heavy handed; it
stopped a few legitimate posts of mine, and even a few patches.
However admins are responsive and reasonable, so I wonder why Shlomi
Fish couldn't solve this issue.
I wonder if it is perhaps a case of strange email headers, or
something...
> > scm> <section id="repos_operations">
> > scm> <title>Repository Operations</title>
> > scm> <section id="atomic_commits">
> > scm> <title>Atomic Commits</title>
> > scm> <expl>
> > scm> Support for atomic commits means that if an
> > scm> operation on the repository is interrupted
> > scm> in the middle, the repository will not be
> > scm> left in an inconsistent state. Are the
> > scm> check-in operations atomic, or can
> > scm> interrupting an operation leave the
> > scm> repository in an intermediate state?
> > scm> </expl>
> >
> > Here I think the explanation of a criterion (feature) is clear enough.
> > I might have added that "interruption" include killing of a process
> > during for example commit, lack of disk space for a full commit, or
> > a network fail during network operation (fetch or push, or equivalent).
>
> My initial reaction was to say that killing a process with -9 is not
> what you expect to see in practice, but a second later, I realized how
> wrong I was. Lack of memory may cause that the process gets killed with
> -9, and it has been observed in practice (at least, in case of Mercurial
> repo): http://norman.walsh.name/2007/08/09/mercurial
Well, kill -9 might be not very common, but interrupting for example
fetch process which looks to take too long, or some operation that you
found shouldn't be run, with ^C is I think more common.
> Another thing that is not clear in the above criterion is what exactly
> "inconsistent state" (or "intermediate state") means. For instance, if
> Git gets killed during commit, you may have to remove .git/index.lock
> manually. AFAIK, Mercury leaves the 'journal' file and you have to
> run "hg recovery". Does it mean that the commit is not atomic?
IMHO "atomic commits" (or rather "atomic operations", see below) is
about commit being either in full, or not done at all. The fact
that SCM might need some manual steps to recover from failure shouldn't
factor in evaluating this criterion.
> Another thing here is that "git commit" is local, so I am not sure
> if this question includes network operations...
Well, I think this session would be better titled "Atomic Operations"
or just "Atomicity". Although I'm not sure if for example in Git
all operations are atomic under all conditions...
But even if we leave it "Atomic Commits", as for centralized SCM
commit includes network operation, to have centralized and distributed
SCM on equal footing, for distributed SCM this in my opinion should
mean both atomic commit, and atomic push. (And that should be stated
explicitly in the description...)
> > scm> <section id="move">
> > scm> <title>Files and Directories Moves or Renames</title>
> > scm> <expl>
> > scm> Does the system support moving a file or directory to
> > scm> a different location while still retaining the history
> > scm> of the file? <b>Note:</b> also see the next section
> > scm> about intelligent merging of renamed paths.
> > scm> </expl>
> >
> > In my opinion this criterion is next to worthess without more in depth
> > clarification of what does it mean to "support" moves or renames; as
> > entries for different systems are written by different people, if it
> > is not clear how to check if some feature is supported, some might
> > write 'no' for some system A, and some other person can write 'yes'
> > for other system B, even if the support is better in system A than in
> > system B (and would be considered enough, i.e. 'yes' answer, by the
> > creator of this criterion).
> >
> > For me the support for renames/moves and copying (see next section)
> > means that:
> >
> > 0.) When examining or going to some point in the history (some old
> > revision/version of a project) the state you get is _exactly_
> > the same as it was at that time, exactly the same as it was
> > recorded (comitted) then.
> >
> > For example tricks with moving *,v files in the CVS repository
> > break this assertion.
>
> IMHO, the above assertion is assumed when we talk about renaming, as
> the system that is not capable of that will not be qualified as an
> SCM. Yet, there is still plenty way to interpret the above criterion.
> Even in CVS, the history of the file does not disappear when you move
> a file. You can just write, this file move was renamed from old-name,
> so anyone can get old history without any problem. Of course, it will
> require some an additional step taken manually. But if the requirement
> is to see all log history with one $scm log command, you can just copy
> old log into log of a newly added file. Of course, you cannot run $scm
> annotate on that file and see who changed what line, but there is no
> such a requirement above.
I have written this obvious requirement (that it is "obvious" can be
seen in the fact that it got number '0' -- zero -- and not '1'; but
perhaps it was too subtle) to exclude CVS "support" for renames by
copying *,v file to new name, as after this operation if you would
checkout old revision you would get extra file, the new name one.
So this 'solution' wouldn't satisfy this requirement.
> So, I agree, it should be better defined.
Nice to be in agreement.
It would be best if there was some automated test for each criterion,
or at least description how to check if SCM fulfils it; not necessary
visible in the table by default.
> > 1.) When examining history of a project as a whole version control
> > system tells you that file was renamed (moved). I would consider
> > having there renaming represented as copy + delete to be only
> > a partial support of this feature.
>
> If files moving is interpreted in the sense of preserving the old history
> then copy + delete fully satisfies that criterion.
>
> However, if you defined support of file movement as ability to see that
> some file when you look at the history of the whole project then
> certainly copy + delete representation would not satisfy it.
Well, I would consider 'copy + delete' as "good enough" solution; not
perfect, but enough for most cases.
> So, perhaps, it should be two separate points:
> - ability to preserve history of rename (with detail clarification
> of what it means)
> - ability to show renames in the project history
That are points '1' and '2' on my list, perhaps stated bit differently:
showing renames in full history / history of project as whole, and
following history of a single file across renames.
> > scm> <s id="git">
> > scm> Renames are supported for most practical
> > scm> purposes. Git even detects renames when a file has been
> > scm> changed afterward the rename. However, due to a peculiar
> > scm> repository structure, renames are not recorded
> > scm> explicitly, and Git has to deduce them (which works well
> > scm> in practice).
> > scm> </s>
[...]
> > Second, we can think about how the above statement could be improved.
> >
>
> <long and detail explanation of how git works>
>
> >
> > ...Now only put the above in a few short sentences to be used in
> > "Better SCM Initiative" comparison table...
>
> Git tracks content rather than file-ids, and therefore it uses heuristics
> for rename detection. This approach has an advantage of being able to
> preserve history for code lines between files, which usually happens much
> more often than file renaming.
I would rather write
Renames are supported for most practical purposes[1]. By design Git
does heuristic <i>rename detection</i> (based on similarity score of
pathnames and file contents), instead of doing rename tracking (which
usually is based on some kind of file-ids). This approach allows for
more generic content tracking of code movement (which usually happens
much often than wholesame file renaming), e.g. in "git blame -C -C".
Footnotes:
[1] "git log --follow <i>filename</i>" works only for very simple
history currently; rename detection gets confused by empty files
and files consisting mainly of boilerplate (e.g. license text).
But this also could be I think improved.
BTW. I wouldn't mention problem with 'new files in renamed directories',
which is IMHO separate issue, and contrary to what Mark Shuttleworth
wrote in "Renaming is the killer app of distributed version control"
(http://www.markshuttleworth.com/archives/123) that part of rename
support is not that important. Especially that I doubt that it was
tested / checked for other SCM in the table.
> > scm> <s id="git">
> > scm> No. As detailed in the <a
> > scm> href="http://git.or.cz/gitwiki/GitFaq#rename-tracking">Git
> > scm> FAQ</a>:
> > scm> "Git has a rename command git mv, but that is just a
> > scm> convenience. The effect is indistinguishable from removing
> > scm> the file and adding another with different name and the
> > scm> same content."
> > scm> </s>
> >
> > This is of course NOT TRUE. If the author bother checking (which
> > would be helped if there was available simple shell script, or simple
> > Perl script, testing 'intelligent_renames' criterion) he/she would
> > notice that git does apply change to renamed file, both if file
> > itself is renamed, and if directory it is in gets renamed.
>
> Sure. But it just demonstrates that the line of reasoning, which was
> clearly based on unstated assumption of how file-id tracking performs
> merge in this situation leads to the wrong conclusion for Git as it is
> the content tracking system, so Git does that differently.
Well, if you are not sure, test it. I did this; admittedly you has
to take care for your test files to have some more content to better
resemble real-life examples for Git contents similarity based rename
detection to work.
Side note: I _think_ that usually if rename detection fails, 3-way
merge would fail too, where by fail I mean the situation where it
is hard to resolve textual conflict, not that there is conflict.
> Perhaps, it would make sense to extend GitFaq to better cover that
> point, because people with other SCM background could easily conclude
> that Git cannot do "intelligent merge" after reading about git-mv.
That is a fact that the section in GitFaq about tracking renames
http://git.or.cz/gitwiki/GitFaq#rename-tracking should be cleaned up
(for example "git annotate" is now just a convenient shortcut to
"git blame -c"; it is no longer alternate implementation), and perhaps
even rewritten. I think that the whole reasoning about rename tracking
vs rename detection, perhaps with famous Linus Torvalds post on that
matter (if I can find it) should be put on separate page, as it will
be I think quite lenghty, while GitFaq should contain only bare-bones
consequences of such decision (and link to details).
> > scm> <section id="changesets">
> > scm> <title>Changesets' Support</title>
> > scm> <expl>
> > scm> Does the repository support changesets? Changesets are a way
> > scm> to group a number of modifications that are relevant to each
> > scm> other in one atomic package, that can be cancelled or
> > scm> propagated as needed.
> > scm> </expl>
> >
> > Here it is not entirely clean what creator of "Better SCM Initiative"
> > comparison table had on mind, what he meant by this. Not all version
> > control systems are changeset based; some are snapshot based. I guess
> > that for snapshot based SCM the above requirement is equivalent to
> > "Whole tree commits".
>
> Yes, it is irrelevant to being changeset or snapshot based.
Errr... what I meant to say that description is clearly inspired by
changeset based SCM, but the criterion is important also for snapshot
based; it is simply not without any doubts that it refers to the
visible UI feature, and not underlying repository design (engine).
> It is whether modification to more than one file can be commited (and
> propogated) atomically. I also suppose that those changes should be
> shown in history as a single change (not many changes too different
> files that took place in the same time and the same commit comment).
>
> However, the whole tree commit is a more strict requirement than
> just being able to commit a group of changes atomically. For example,
> "svn ci" creates a changeset and atomically store all its modification
> on the server. Yet, it is not the whole tree commit, because the result
> tree may differ from the tree that you commiting (files that are not
> modified by changeset may differ).
I think the gist of intent was to have revisions (revision identifiers)
refer to the state of a whole repository (or to changes to the set of
files as a whole: a changeset).
I agree that "whole tree commit" has slightly different semantics than
"supporting changesets".
> > scm> <s id="git">
> > scm> Yes, Changesets are supported,
> > scm> and there's some flexibility in creating them.
> > scm> </s>
> > scm> </compare>
> > scm> </section>
> >
> > [Again, Git part was re-wrapped for better readibility]
> >
> > In my opition, such an _empty_ addition ("there's some flexibility in
> > creating them") is totally unnecessary; it adds no solid information
> > (what does it mean "some flexibility") and should be removed.
>
> Agreed. I suspect the author implied by that Git allows to stage
> and commit separately chunk without commiting the whole file.
> Yet, as it is worded above, it is useless.
Hmmm... now that you stated that possibility I see how this wording can
refer to it. Nevertheless it is irrelevant to the criterion discussed;
also Darcs which also has extra flexibility (chunk selection in
interactive git-add / git-commit were inspired by Darcs feature) doesn't
have any extra wording.
> > scm> <section id="tracking_uncommited_changes">
> > scm> <title>Tracking Uncommited Changes</title>
> > scm> <expl>
> > scm> Does the software have an ability to track the changes in the
> > scm> working copy that were not yet committed to the repository?
> > scm> </expl>
> >
> > This also should be made more clean. Does it mean for example ability
> > to tell which files have changed, or ability to diff working copy to
> > either last comitted changes, or to any revision available in repository?
>
> Also, ability to diff one or more specified files in the working copy to
> some specified revision.
Right.
I'm not sure now if "Tracking Uncommitted Changes" is a good name for
this feature / criterion, but I don't have definite idea for change...
> > scm> <section id="technical_status">
> > scm> <title>Technical Status</title>
> > scm> <section id="documentation">
> > scm> <title>Documentation</title>
> > scm> <expl>
> > scm> How well is the system documented? How easy is it to
> > scm> get started using it?
> > scm> </expl>
> > scm> <compare>
> > scm> <s id="git">
> > scm> Medium. The short help is too terse and obscure.
> > scm> The man pages are extensive, but tend to be confusing.
> > scm> The are many tutorials.
> > scm> </s>
> > scm> </compare>
> > scm> </section>
> >
> > That of course depends on your opinion. I would say "Good", now that
> > there is "Git User's Manual" distributed with Git, and now that there
> > started semi-official "Git Community Book" (http://book.git-scm.com).
>
> Interesting that versioncontrolblog, which, if I am not mistaken, is
> Alexey's site, states for Git Documentation:
>
> | Good. There is extensive documentation for every command, and many
> | tutorials.
>
> http://www.versioncontrolblog.com/comparison/Git/index.html
>
> So, I am not sure were the word "Medium" came from.
Backward compatibility^W^W Old impressions die hard, I would guess...
And the meme that git documentation is not user friendly is hard to
fight.
Thank you very much for your comments.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: CGit and repository list
From: Kristian Høgsberg @ 2008-09-14 17:22 UTC (permalink / raw)
To: Petr Baudis; +Cc: Johan Herland, git, Lars Hjemli, Jakub Narebski
In-Reply-To: <59ad55d30809141014x2160d50dqb8ac20b4c108b4e1@mail.gmail.com>
On Sun, Sep 14, 2008 at 1:14 PM, Kristian Høgsberg <krh@bitplanet.net> wrote:
> The script we're using on freedesktop.org is something like this:
>
> http://people.freedesktop.org/~krh/find-repos.sh
>
> which isn't too scary. We run it from a cron script, every ten
> minutes or so. It's much better than rescanning all the dirs every
> time somebody requests the repo listing (we have a lot of repos, check
> cgit.freedesktop.org). We have no need for cgit to to this
> automatically on every request, and I don't see us using that feature
> if it gets implemented.
A feature that would be useful, though, would be support for listing a
sub-set of repos... for example, cgit.freedesktop.org/~krh would list
just my repos and cgit.freedesktop.org/xorg/driver would list all the
X.org driver repos. Another idea is a javascript/css frontpage that
supports folding repos away according to the groups and possibly
common path elements in the url. For example:
[+] Freedesktop Repositories
[-] User repositories
[+] ~agdf5
[+] ~ahuillet
...
[-] ~krh
~krh/akamaru
~krh/bugzilla
~krh/compiz
[-] ~kyle
etc.
Just throwing out a couple of ideas.
cheers,
Kristian
^ permalink raw reply
* Re: CGit and repository list
From: Kristian Høgsberg @ 2008-09-14 17:14 UTC (permalink / raw)
To: Petr Baudis; +Cc: Johan Herland, git, Lars Hjemli, Jakub Narebski
In-Reply-To: <20080912224817.GF10360@machine.or.cz>
On Fri, Sep 12, 2008 at 6:48 PM, Petr Baudis <pasky@suse.cz> wrote:
> On Fri, Sep 12, 2008 at 06:12:40PM +0200, Johan Herland wrote:
>> On Friday 12 September 2008, Lars Hjemli wrote:
>> > On Fri, Sep 12, 2008 at 4:58 PM, Petr Baudis <pasky@suse.cz> wrote:
>> > > it seems that cgit
>> > > requires all the repositories explicitly listed in the config file.
>> > > Do you plan to remove this limitation in the future?
>> >
>> > Not really, I'd rather add another command (or a commandline option)
>> > to generate an include-file for cgitrc by scanning directory-trees
>> > for git repos. I've CC'd Kristian since I believe he's got such a
>> > script running for freedesktop.org; if so, maybe it could be
>> > included/used as basis for something similar in cgit?
>>
>> Here's a script I wrote for locating repos and generating repo
>> lists/configs for cgit, gitweb and hgwebdir (yes, this handles hg repos
>> as well). It works either as a CGI script (producing a list of detected
>> repos in HTML format), or from the command-line. It's only been tested
>> on an experimental DVCS server at $dayjob, so you might have to change
>> things to make it work in your scenario.
>>
>> If there is interest in this, I can create a public repo and we can keep
>> improving on it.
>
> Thanks. The script was a bit more scary than I thought, but in the end I
> managed to generate something. There are trailing dots in project names,
> but I'm not going to waste time on that anymore - this has long gone
> over the 20 minutes I originally alotted the project anyway; I hope cgit
> will gain a builtin capability for this in the future, since this is
> still quite a pain. Attached is a random patch for your script I had to
> use, FWIW.
The script we're using on freedesktop.org is something like this:
http://people.freedesktop.org/~krh/find-repos.sh
which isn't too scary. We run it from a cron script, every ten
minutes or so. It's much better than rescanning all the dirs every
time somebody requests the repo listing (we have a lot of repos, check
cgit.freedesktop.org). We have no need for cgit to to this
automatically on every request, and I don't see us using that feature
if it gets implemented.
cheers,
Kristian
^ permalink raw reply
* Re: [TOY PATCH] filter-branch: add option --delete-unchanged
From: Felipe Contreras @ 2008-09-14 16:29 UTC (permalink / raw)
To: Thomas Rast; +Cc: git, Jan Wielemaker
In-Reply-To: <1218226224-25273-1-git-send-email-trast@student.ethz.ch>
On Fri, Aug 8, 2008 at 11:10 PM, Thomas Rast <trast@student.ethz.ch> wrote:
> With --delete-unchanged, we nuke refs whose targets did not change
> during rewriting. It is intended to be used along with
> --subdirectory-filter to clean out old refs from before the first
> commit to the filtered subdirectory. (They would otherwise keep the
> old history alive.)
>
> Obviously this is a rather dangerous mode of operation.
>
> Note the "sort -u" is required: Without it, --all includes
> 'origin/master' twice (from 'origin/master' and via 'origin/HEAD'),
> and the second pass concludes it is unchanged and nukes the ref.
This is really useful, why isn't it merged?
Personally I use filter-branch to, duh, filter a branch, so I don't
want the commit objects that are not filtered, nor the refs to them.
--
Felipe Contreras
^ permalink raw reply
* Re: Git at Better SCM Initiative comparison of VCS (long)
From: Alexey Mahotkin @ 2008-09-14 15:09 UTC (permalink / raw)
To: Dmitry Potapov; +Cc: Jakub Narebski, git
In-Reply-To: <20080914144306.GF28210@dpotapov.dyndns.org>
Hi,
I've written the version which is on http://versioncontrolblog.com and
sent it to Mr. Shlomi Fish several months ago. He has extensively
re-written my text, making it more "neutral", and published it on
better-scm. I do not agree with some of the changes he made, but I
did not insist. :)
Occasionally I update my text with the current version at better-scm,
but this has not happened for some time, and it still contains my
original version.
Is there anything I can do to improve the state of things in any way? :)
On Sun, Sep 14, 2008 at 6:43 PM, Dmitry Potapov <dpotapov@gmail.com> wrote:
> Hello Jakub,
>
> I have added Alexey Mahotkin in CC, who is allegedly the author of that
> information about Git that you can read on the better-scm site.
>
> On Sat, Sep 13, 2008 at 07:06:16PM +0200, Jakub Narebski wrote:
>>
>> I have thought about trying yet another time... but Git was already
>> added; see http://better-scm.berlios.de/news/changes-2008-08-07/
>
> Interesting, the site still mentions Git as missing in a few places.
> For instance, when you click on Git in the list of alternatives, you
> get this: http://better-scm.berlios.de/alternatives/git/
> and then when you got to FAQ, you can read this:
>
> | The reason it's not there is that while many people have complained
> | about its absense, no one suitable has volunteered to become its
> | champion and supplied a good enough patch. If you have a substantial
> | amount of git expertise, have good English writing skills, and wish to
> | volunteer, then we'll be happy to hear from you. If not - at least don't
> | complain about it.
> |
> | In addition to everything that was said here, it seems that the
> | originator and maintainer of the site and comparison is now banned
> | from sending messages to vger.kernel.org, which hosts several
> | Linux-kernel-related mailing-lists, including the git one. This has
> | interfered with some of his Linux-related open-source work, including
> | trying to find a "Better SCM" maintainer for git. This is unfortunate,
> | but changing this situation, is currently beyond his control.
>
> Source: http://better-scm.berlios.de/faq/#git-missing
>
> I am surprised to hear that Shlomi Fish is banned...
>
>> scm> <section id="repos_operations">
>> scm> <title>Repository Operations</title>
>> scm> <section id="atomic_commits">
>> scm> <title>Atomic Commits</title>
>> scm> <expl>
>> scm> Support for atomic commits means that if an
>> scm> operation on the repository is interrupted
>> scm> in the middle, the repository will not be
>> scm> left in an inconsistent state. Are the
>> scm> check-in operations atomic, or can
>> scm> interrupting an operation leave the
>> scm> repository in an intermediate state?
>> scm> </expl>
>>
>> Here I think the explanation of a criterion (feature) is clear enough.
>> I might have added that "interruption" include killing of a process
>> during for example commit, lack of disk space for a full commit, or
>> a network fail during network operation (fetch or push, or equivalent).
>
> My initial reaction was to say that killing a process with -9 is not
> what you expect to see in practice, but a second later, I realized how
> wrong I was. Lack of memory may cause that the process gets killed with
> -9, and it has been observed in practice (at least, in case of Mercury
> repo): http://norman.walsh.name/2007/08/09/mercurial
>
> Another thing that is not clear in the above criterion is what exactly
> "inconsistent state" (or "intermediate state") means. For instance, if
> Git gets killed during commit, you may have to remove .git/index.lock
> manually. AFAIK, Mercury leaves the 'journal' file and you have to
> run "hg recovery". Does it mean that the commit is not atomic?
>
> Another thing here is that "git commit" is local, so I am not sure
> if this question includes network operations...
>
>> scm> <section id="move">
>> scm> <title>Files and Directories Moves or Renames</title>
>> scm> <expl>
>> scm> Does the system support moving a file or directory to
>> scm> a different location while still retaining the history
>> scm> of the file? <b>Note:</b> also see the next section
>> scm> about intelligent merging of renamed paths.
>> scm> </expl>
>>
>> In my opinion this criterion is next to worthess without more in depth
>> clarification of what does it mean to "support" moves or renames; as
>> entries for different systems are written by different people, if it
>> is not clear how to check if some feature is supported, some might
>> write 'no' for some system A, and some other person can write 'yes'
>> for other system B, even if the support is better in system A than in
>> system B (and would be considered enough, i.e. 'yes' answer, by the
>> creator of this criterion).
>>
>> For me the support for renames/moves and copying (see next section)
>> means that:
>>
>> 0.) When examining or going to some point in the history (some old
>> revision/version of a project) the state you get is _exactly_
>> the same as it was at that time, exactly the same as it was
>> recorded (comitted) then.
>>
>> For example tricks with moving *,v files in the CVS repository
>> break this assertion.
>
> IMHO, the above assertion is assumed when we talk about renaming, as
> the system that is not capable of that will not be qualified as an
> SCM. Yet, there is still plenty way to interpret the above criterion.
> Even in CVS, the history of the file does not disappear when you move
> a file. You can just write, this file move was renamed from old-name,
> so anyone can get old history without any problem. Of course, it will
> require some an additional step taken manually. But if the requirement
> is to see all log history with one $scm log command, you can just copy
> old log into log of a newly added file. Of course, you cannot run $scm
> annotate on that file and see who changed what line, but there is no
> such a requirement above.
>
> So, I agree, it should be better defined.
>
>>
>> 1.) When examining history of a project as a whole version control
>> system tells you that file was renamed (moved). I would consider
>> having there renaming represented as copy + delete to be only
>> a partial support of this feature.
>
> If files moving is interpreted in the sense of preserving the old history
> then copy + delete fully satisfies that criterion.
>
> However, if you defined support of file movement as ability to see that
> some file when you look at the history of the whole project then
> certainly copy + delete representation would not satisfy it.
>
> So, perhaps, it should be two separate points:
> - ability to preserve history of rename (with detail clarification
> of what it means)
> - ability to show renames in the project history
>
>>
>> scm> <s id="git">
>> scm> Renames are supported for most practical
>> scm> purposes. Git even detects renames when a file has been
>> scm> changed afterward the rename. However, due to a peculiar
>> scm> repository structure, renames are not recorded
>> scm> explicitly, and Git has to deduce them (which works well
>> scm> in practice).
>> scm> </s>
>>
>> First, a correction to above statement. It is not due to "a peculiar
>> repository structure", but due to "a design decision" (perhaps with
>> link to some explanation why it was implemented this way; I planned
>> to make a wiki page about 'rename tracking' vs. 'rename detection'
>> with references to various mailing list messages etc., but to this
>> day it was not created).
>
> Agreed.
>
>>
>>
>> Second, we can think about how the above statement could be improved.
>>
>
> <long and detail explanation of how git works>
>
>>
>> ...Now only put the above in a few short sentences to be used in
>> "Better SCM Initiative" comparison table...
>
> Git tracks content rather than file-ids, and therefore it uses heuristics
> for rename detection. This approach has an advantage of being able to
> preserve history for code lines between files, which usually happens much
> more often than file renaming.
>
>> scm> <s id="git">
>> scm> No. As detailed in the <a
>> scm> href="http://git.or.cz/gitwiki/GitFaq#rename-tracking">Git
>> scm> FAQ</a>:
>> scm> "Git has a rename command git mv, but that is just a
>> scm> convenience. The effect is indistinguishable from removing
>> scm> the file and adding another with different name and the
>> scm> same content."
>> scm> </s>
>>
>> This is of course NOT TRUE. If the author bother checking (which
>> would be helped if there was available simple shell script, or simple
>> Perl script, testing 'intelligent_renames' criterion) he/she would
>> notice that git does apply change to renamed file, both if file
>> itself is renamed, and if directory it is in gets renamed.
>
> Sure. But it just demonstrates that the line of reasoning, which was
> clearly based on unstated assumption of how file-id tracking performs
> merge in this situation leads to the wrong conclusion for Git as it is
> the content tracking system, so Git does that differently.
>
> Perhaps, it would make sense to extend GitFaq to better cover that
> point, because people with other SCM background could easily conclude
> that Git cannot do "intelligent merge" after reading about git-mv.
>
>> scm> <section id="changesets">
>> scm> <title>Changesets' Support</title>
>> scm> <expl>
>> scm> Does the repository support changesets? Changesets are a way
>> scm> to group a number of modifications that are relevant to each
>> scm> other in one atomic package, that can be cancelled or
>> scm> propagated as needed.
>> scm> </expl>
>>
>> Here it is not entirely clean what creator of "Better SCM Initiative"
>> comparison table had on mind, what he meant by this. Not all version
>> control systems are changeset based; some are snapshot based. I guess
>> that for snapshot based SCM the above requirement is equivalent to
>> "Whole tree commits".
>
> Yes, it is irrelevant to being changeset or snapshot based. It is
> whether modification to more than one file can be commited (and
> propogated) atomically. I also suppose that those changes should be
> shown in history as a single change (not many changes too different
> files that took place in the same time and the same commit comment).
>
> However, the whole tree commit is a more strict requirement than
> just being able to commit a group of changes atomically. For example,
> "svn ci" creates a changeset and atomically store all its modification
> on the server. Yet, it is not the whole tree commit, because the result
> tree may differ from the tree that you commiting (files that are not
> modified by changeset may differ).
>
>> scm> <s id="git">
>> scm> Yes, Changesets are supported,
>> scm> and there's some flexibility in creating them.
>> scm> </s>
>> scm> </compare>
>> scm> </section>
>>
>> [Again, Git part was re-wrapped for better readibility]
>>
>> In my opition, such an _empty_ addition ("there's some flexibility in
>> creating them") is totally unnecessary; it adds no solid information
>> (what does it mean "some flexibility") and should be removed.
>
> Agreed. I suspect the author implied by that Git allows to stage
> and commit separately chunk without commiting the whole file.
> Yet, as it is worded above, it is useless.
>
>> scm> <section id="tracking_uncommited_changes">
>> scm> <title>Tracking Uncommited Changes</title>
>> scm> <expl>
>> scm> Does the software have an ability to track the changes in the
>> scm> working copy that were not yet committed to the repository?
>> scm> </expl>
>>
>> This also should be made more clean. Does it mean for example ability
>> to tell which files have changed, or ability to diff working copy to
>> either last comitted changes, or to any revision available in repository?
>
> Also, ability to diff one or more specified files in the working copy to
> some specified revision.
>
>> scm> <section id="technical_status">
>> scm> <title>Technical Status</title>
>> scm> <section id="documentation">
>> scm> <title>Documentation</title>
>> scm> <expl>
>> scm> How well is the system documented? How easy is it to
>> scm> get started using it?
>> scm> </expl>
>> scm> <compare>
>> scm> <s id="git">
>> scm> Medium. The short help is too terse and obscure.
>> scm> The man pages are extensive, but tend to be confusing.
>> scm> The are many tutorials.
>> scm> </s>
>> scm> </compare>
>> scm> </section>
>>
>> That of course depends on your opinion. I would say "Good", now that
>> there is "Git User's Manual" distributed with Git, and now that there
>> started semi-official "Git Community Book" (http://book.git-scm.com).
>
> Interesting that versioncontrolblog, which, if I am not mistaken, is
> Alexey's site, states for Git Documentation:
>
> | Good. There is extensive documentation for every command, and many
> | tutorials.
>
> http://www.versioncontrolblog.com/comparison/Git/index.html
>
> So, I am not sure were the word "Medium" came from.
>
>
> Dmitry
>
--
Алексей Махоткин
http://squadette.ru/
^ permalink raw reply
* Re: Git at Better SCM Initiative comparison of VCS (long)
From: Dmitry Potapov @ 2008-09-14 14:43 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, Alexey Mahotkin
In-Reply-To: <200809131906.18746.jnareb@gmail.com>
Hello Jakub,
I have added Alexey Mahotkin in CC, who is allegedly the author of that
information about Git that you can read on the better-scm site.
On Sat, Sep 13, 2008 at 07:06:16PM +0200, Jakub Narebski wrote:
>
> I have thought about trying yet another time... but Git was already
> added; see http://better-scm.berlios.de/news/changes-2008-08-07/
Interesting, the site still mentions Git as missing in a few places.
For instance, when you click on Git in the list of alternatives, you
get this: http://better-scm.berlios.de/alternatives/git/
and then when you got to FAQ, you can read this:
| The reason it's not there is that while many people have complained
| about its absense, no one suitable has volunteered to become its
| champion and supplied a good enough patch. If you have a substantial
| amount of git expertise, have good English writing skills, and wish to
| volunteer, then we'll be happy to hear from you. If not - at least don't
| complain about it.
|
| In addition to everything that was said here, it seems that the
| originator and maintainer of the site and comparison is now banned
| from sending messages to vger.kernel.org, which hosts several
| Linux-kernel-related mailing-lists, including the git one. This has
| interfered with some of his Linux-related open-source work, including
| trying to find a "Better SCM" maintainer for git. This is unfortunate,
| but changing this situation, is currently beyond his control.
Source: http://better-scm.berlios.de/faq/#git-missing
I am surprised to hear that Shlomi Fish is banned...
> scm> <section id="repos_operations">
> scm> <title>Repository Operations</title>
> scm> <section id="atomic_commits">
> scm> <title>Atomic Commits</title>
> scm> <expl>
> scm> Support for atomic commits means that if an
> scm> operation on the repository is interrupted
> scm> in the middle, the repository will not be
> scm> left in an inconsistent state. Are the
> scm> check-in operations atomic, or can
> scm> interrupting an operation leave the
> scm> repository in an intermediate state?
> scm> </expl>
>
> Here I think the explanation of a criterion (feature) is clear enough.
> I might have added that "interruption" include killing of a process
> during for example commit, lack of disk space for a full commit, or
> a network fail during network operation (fetch or push, or equivalent).
My initial reaction was to say that killing a process with -9 is not
what you expect to see in practice, but a second later, I realized how
wrong I was. Lack of memory may cause that the process gets killed with
-9, and it has been observed in practice (at least, in case of Mercury
repo): http://norman.walsh.name/2007/08/09/mercurial
Another thing that is not clear in the above criterion is what exactly
"inconsistent state" (or "intermediate state") means. For instance, if
Git gets killed during commit, you may have to remove .git/index.lock
manually. AFAIK, Mercury leaves the 'journal' file and you have to
run "hg recovery". Does it mean that the commit is not atomic?
Another thing here is that "git commit" is local, so I am not sure
if this question includes network operations...
> scm> <section id="move">
> scm> <title>Files and Directories Moves or Renames</title>
> scm> <expl>
> scm> Does the system support moving a file or directory to
> scm> a different location while still retaining the history
> scm> of the file? <b>Note:</b> also see the next section
> scm> about intelligent merging of renamed paths.
> scm> </expl>
>
> In my opinion this criterion is next to worthess without more in depth
> clarification of what does it mean to "support" moves or renames; as
> entries for different systems are written by different people, if it
> is not clear how to check if some feature is supported, some might
> write 'no' for some system A, and some other person can write 'yes'
> for other system B, even if the support is better in system A than in
> system B (and would be considered enough, i.e. 'yes' answer, by the
> creator of this criterion).
>
> For me the support for renames/moves and copying (see next section)
> means that:
>
> 0.) When examining or going to some point in the history (some old
> revision/version of a project) the state you get is _exactly_
> the same as it was at that time, exactly the same as it was
> recorded (comitted) then.
>
> For example tricks with moving *,v files in the CVS repository
> break this assertion.
IMHO, the above assertion is assumed when we talk about renaming, as
the system that is not capable of that will not be qualified as an
SCM. Yet, there is still plenty way to interpret the above criterion.
Even in CVS, the history of the file does not disappear when you move
a file. You can just write, this file move was renamed from old-name,
so anyone can get old history without any problem. Of course, it will
require some an additional step taken manually. But if the requirement
is to see all log history with one $scm log command, you can just copy
old log into log of a newly added file. Of course, you cannot run $scm
annotate on that file and see who changed what line, but there is no
such a requirement above.
So, I agree, it should be better defined.
>
> 1.) When examining history of a project as a whole version control
> system tells you that file was renamed (moved). I would consider
> having there renaming represented as copy + delete to be only
> a partial support of this feature.
If files moving is interpreted in the sense of preserving the old history
then copy + delete fully satisfies that criterion.
However, if you defined support of file movement as ability to see that
some file when you look at the history of the whole project then
certainly copy + delete representation would not satisfy it.
So, perhaps, it should be two separate points:
- ability to preserve history of rename (with detail clarification
of what it means)
- ability to show renames in the project history
>
> scm> <s id="git">
> scm> Renames are supported for most practical
> scm> purposes. Git even detects renames when a file has been
> scm> changed afterward the rename. However, due to a peculiar
> scm> repository structure, renames are not recorded
> scm> explicitly, and Git has to deduce them (which works well
> scm> in practice).
> scm> </s>
>
> First, a correction to above statement. It is not due to "a peculiar
> repository structure", but due to "a design decision" (perhaps with
> link to some explanation why it was implemented this way; I planned
> to make a wiki page about 'rename tracking' vs. 'rename detection'
> with references to various mailing list messages etc., but to this
> day it was not created).
Agreed.
>
>
> Second, we can think about how the above statement could be improved.
>
<long and detail explanation of how git works>
>
> ...Now only put the above in a few short sentences to be used in
> "Better SCM Initiative" comparison table...
Git tracks content rather than file-ids, and therefore it uses heuristics
for rename detection. This approach has an advantage of being able to
preserve history for code lines between files, which usually happens much
more often than file renaming.
> scm> <s id="git">
> scm> No. As detailed in the <a
> scm> href="http://git.or.cz/gitwiki/GitFaq#rename-tracking">Git
> scm> FAQ</a>:
> scm> "Git has a rename command git mv, but that is just a
> scm> convenience. The effect is indistinguishable from removing
> scm> the file and adding another with different name and the
> scm> same content."
> scm> </s>
>
> This is of course NOT TRUE. If the author bother checking (which
> would be helped if there was available simple shell script, or simple
> Perl script, testing 'intelligent_renames' criterion) he/she would
> notice that git does apply change to renamed file, both if file
> itself is renamed, and if directory it is in gets renamed.
Sure. But it just demonstrates that the line of reasoning, which was
clearly based on unstated assumption of how file-id tracking performs
merge in this situation leads to the wrong conclusion for Git as it is
the content tracking system, so Git does that differently.
Perhaps, it would make sense to extend GitFaq to better cover that
point, because people with other SCM background could easily conclude
that Git cannot do "intelligent merge" after reading about git-mv.
> scm> <section id="changesets">
> scm> <title>Changesets' Support</title>
> scm> <expl>
> scm> Does the repository support changesets? Changesets are a way
> scm> to group a number of modifications that are relevant to each
> scm> other in one atomic package, that can be cancelled or
> scm> propagated as needed.
> scm> </expl>
>
> Here it is not entirely clean what creator of "Better SCM Initiative"
> comparison table had on mind, what he meant by this. Not all version
> control systems are changeset based; some are snapshot based. I guess
> that for snapshot based SCM the above requirement is equivalent to
> "Whole tree commits".
Yes, it is irrelevant to being changeset or snapshot based. It is
whether modification to more than one file can be commited (and
propogated) atomically. I also suppose that those changes should be
shown in history as a single change (not many changes too different
files that took place in the same time and the same commit comment).
However, the whole tree commit is a more strict requirement than
just being able to commit a group of changes atomically. For example,
"svn ci" creates a changeset and atomically store all its modification
on the server. Yet, it is not the whole tree commit, because the result
tree may differ from the tree that you commiting (files that are not
modified by changeset may differ).
> scm> <s id="git">
> scm> Yes, Changesets are supported,
> scm> and there's some flexibility in creating them.
> scm> </s>
> scm> </compare>
> scm> </section>
>
> [Again, Git part was re-wrapped for better readibility]
>
> In my opition, such an _empty_ addition ("there's some flexibility in
> creating them") is totally unnecessary; it adds no solid information
> (what does it mean "some flexibility") and should be removed.
Agreed. I suspect the author implied by that Git allows to stage
and commit separately chunk without commiting the whole file.
Yet, as it is worded above, it is useless.
> scm> <section id="tracking_uncommited_changes">
> scm> <title>Tracking Uncommited Changes</title>
> scm> <expl>
> scm> Does the software have an ability to track the changes in the
> scm> working copy that were not yet committed to the repository?
> scm> </expl>
>
> This also should be made more clean. Does it mean for example ability
> to tell which files have changed, or ability to diff working copy to
> either last comitted changes, or to any revision available in repository?
Also, ability to diff one or more specified files in the working copy to
some specified revision.
> scm> <section id="technical_status">
> scm> <title>Technical Status</title>
> scm> <section id="documentation">
> scm> <title>Documentation</title>
> scm> <expl>
> scm> How well is the system documented? How easy is it to
> scm> get started using it?
> scm> </expl>
> scm> <compare>
> scm> <s id="git">
> scm> Medium. The short help is too terse and obscure.
> scm> The man pages are extensive, but tend to be confusing.
> scm> The are many tutorials.
> scm> </s>
> scm> </compare>
> scm> </section>
>
> That of course depends on your opinion. I would say "Good", now that
> there is "Git User's Manual" distributed with Git, and now that there
> started semi-official "Git Community Book" (http://book.git-scm.com).
Interesting that versioncontrolblog, which, if I am not mistaken, is
Alexey's site, states for Git Documentation:
| Good. There is extensive documentation for every command, and many
| tutorials.
http://www.versioncontrolblog.com/comparison/Git/index.html
So, I am not sure were the word "Medium" came from.
Dmitry
^ permalink raw reply
* Re: Git User's Survey 2008 partial summary, part 5 - other SCM
From: Jakub Narebski @ 2008-09-14 13:32 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <fcaeb9bf0809140345n11d41430ma9b4096c66776b0c@mail.gmail.com>
On Sun, 14 Sep 2008, Nguyen Thai Ngoc Duy wrote:
> On 9/12/08, Jakub Narebski <jnareb@gmail.com> wrote:
> >
> > 15) Do you miss features in git that you know from other SCMs?
> > If yes, what features are these (and from which SCM)?
> > (Open ended text - Essay)
> >
> > Total respondents 1046 (some/many of them wrote 'no')
> > skipped this question 1249
> >
> > This is just a very quick summary, based on a first few pages of
> > responses, Full analysis is I think best left for after closing the
> > survey, because I think this would be a lot of work...
> >
> > So here is preliminary list, or rather beginning of one:
> > * sparse/partial checkout and clone (e.g. Perforce)
>
> Have not read the survey result, but do you recall what is the most
> used term for sparse/partial checkout? What SCMs do sparse/partial
> checkout? I think it could be usable as it is now in my
> will-be-sent-again series, but I don't really know how people want it
> to from that.
Well, I do not remember, and I think I haven't got original data now,
only the above summary. Besides, I haven't even began analysing data
from question 34. about ideas for features, and I guess we would see
'partial checkou' ide there too.
>From short discussion on #git channel, Abhijit Menon-Sen (crab) said
that they are 'restricted views' in Perforce, but this terminology is
completly alien to Git. Bjorn Steinbrink (doener_) mentioned that
Subversion 1.5 acquired something they call 'sparse directories':
http://blogs.open.collab.net/svn/2007/06/sparse-director.html
(Sidenote: perhaps it would be worth to follow SVN UI for sparse
checkout here?). In short, people on #git agreed that 'partial
checkout' is a good name; I think that 'sparse checkout' better renders
idea that one can checkout _set_ of files and directories, and it is
not only limited to single subdirectory ('subtree checkout' /
'subdirectory checkout') or a single file.
Comparison table on Better SCM Initiative
http://better-scm.berlios.de/comparison/comparison.html
names it "Ability to Work only on One Directory of the Repository" and
uses '"work_on_dir"' id.
HTH
--
Jakub Narebski
Poland
^ permalink raw reply
* [PATCH 16/16] ls-files: add --overlay option
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:08 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-16-git-send-email-pclouds@gmail.com>
Narrow checkout mode introduces an interesting case: some files
are not to be checked out (marked CE_NO_CHECKOUT in index) but still
exist in working directory. Those files will be ignored by Git unless
explicitly specified. In Clearcase, these files are called "eclipsed".
I would call them "overlay" for now. Any better term is welcome.
The same situation happens for "assume unchanged" bit, but I would
expect narrow checkout to be more user-friendly and should notify users
these cases so users will not be confused. On this first step, users
may check by themselves with "git ls-files --overlay", further steps
may make the information visible from "git status".
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-ls-files.txt | 4 ++++
builtin-ls-files.c | 16 +++++++++++++---
t/t2104-update-index-narrow.sh | 4 ++++
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 4f5a37e..9e749ef 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -56,6 +56,9 @@ OPTIONS
--stage::
Show staged contents' object name, mode bits and stage number in the output.
+--overlay::
+ Show files that are marked no-checkout but exist in working directory.
+
--directory::
If a whole directory is classified as "other", show just its
name (with a trailing slash) and not its whole contents.
@@ -122,6 +125,7 @@ OPTIONS
R:: removed/deleted
C:: modified/changed
K:: to be killed
+ !:: overlay files
?:: other
-v::
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f48a157..6e55207 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -20,6 +20,7 @@ static int show_others;
static int show_stage;
static int show_unmerged;
static int show_modified;
+static int show_overlay;
static int show_killed;
static int show_valid_bit;
static int narrow_checkout;
@@ -39,6 +40,7 @@ static const char *tag_removed = "";
static const char *tag_other = "";
static const char *tag_killed = "";
static const char *tag_modified = "";
+static const char *tag_overlay = "";
/*
@@ -256,7 +258,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
}
}
- if (show_deleted | show_modified) {
+ if (show_deleted | show_modified | show_overlay) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
struct stat st;
@@ -265,6 +267,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
continue;
err = lstat(ce->name, &st);
+ if (show_overlay && ce_no_checkout(ce) && !err)
+ show_ce_entry(tag_overlay, ce);
if (show_deleted && err && ce_checkout(ce))
show_ce_entry(tag_removed, ce);
if (show_modified && ce_modified(ce, &st, 0))
@@ -431,7 +435,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
}
static const char ls_files_usage[] =
- "git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
+ "git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified|overlay])* "
"[ --narrow-checkout ] [--narrow-match=<narrow_spec>] "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ] [--exclude-standard] "
@@ -466,6 +470,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
tag_modified = "C ";
tag_other = "? ";
tag_killed = "K ";
+ tag_overlay = "! ";
if (arg[1] == 'v')
show_valid_bit = 1;
continue;
@@ -491,6 +496,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
require_work_tree = 1;
continue;
}
+ if (!strcmp(arg, "--overlay")) {
+ show_overlay = 1;
+ require_work_tree = 1;
+ continue;
+ }
if (!strcmp(arg, "-o") || !strcmp(arg, "--others")) {
show_others = 1;
require_work_tree = 1;
@@ -610,7 +620,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
/* With no flags, we default to showing the cached files */
if (!(show_stage | show_deleted | show_others | show_unmerged |
- show_killed | show_modified))
+ show_killed | show_modified | show_overlay))
show_cached = 1;
if (narrow_checkout && !show_cached && !show_stage)
diff --git a/t/t2104-update-index-narrow.sh b/t/t2104-update-index-narrow.sh
index 1a3acdd..79da418 100755
--- a/t/t2104-update-index-narrow.sh
+++ b/t/t2104-update-index-narrow.sh
@@ -31,6 +31,10 @@ test_expect_success 'ls-files --deleted ignores no-checkout entries' '
touch 1
'
+test_expect_success 'there are overlay entries' '
+ test "$(git ls-files --overlay|grep 1|wc -l)" = 2
+'
+
test_expect_success 'update-index --checkout' '
git update-index --checkout 1 sub/1 &&
test "$(git ls-files)" = "$(git ls-files --narrow-checkout)"'
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 15/16] checkout: add new options to support narrow checkout
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:08 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-15-git-send-email-pclouds@gmail.com>
These options include:
--full: return to full checkout (default)
--path: narrow checkout to some areas according to given spec
--add-path/--remove-path: adjust current narrow checkout
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-checkout.txt | 68 +++++++++++++++++++++++++++++++++-
builtin-checkout.c | 44 ++++++++++++++++++++++
t/t2011-checkout-narrow.sh | 80 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+), 2 deletions(-)
create mode 100755 t/t2011-checkout-narrow.sh
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 82e154d..2ae483b 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -8,8 +8,10 @@ git-checkout - Checkout a branch or paths to the working tree
SYNOPSIS
--------
[verse]
-'git checkout' [-q] [-f] [--track | --no-track] [-b <new_branch> [-l]] [-m] [<branch>]
-'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
+'git checkout' [-q] [-f] [--track | --no-track] [-b <new_branch> [-l]] [-m]
+ [<narrow options>] [<branch>]
+'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>]
+ [<narrow options>] [--] <paths>...
DESCRIPTION
-----------
@@ -34,6 +36,10 @@ used to specify a specific tree-ish (i.e. commit, tag or tree)
to update the index for the given paths before updating the
working tree.
+<narrow options> include --full, --path, --add-path and --remove-path.
+The last three require narrow spec. Please refer to "narrow checkout"
+section to have more information about this mode.
+
The index may contain unmerged entries after a failed merge. By
default, if you try to check out such an entry from the index, the
checkout operation will fail and nothing will be checked out.
@@ -108,6 +114,22 @@ exlicitly give a name with '-b' in such a case.
However, with this option, a three-way merge between the current
branch, your working tree contents, and the new branch
is done, and you will be on the new branch.
+
+--full::
+ Quit narrow checkout mode. Return to full checkout.
+
+--path=<narrow_spec>::
+ Re-apply new narrow spec on current working directory to
+ form new checkout area.
+
+--add-path=<narrow_spec>::
+ Checkout more areas specified by narrow spec to current
+ checkout area.
+
+--remove-path=<narrow_spec>::
+ Narrow checkout area by removing files specified by narrow spec
+ from current checkout area. This operation will fail if there
+ is unmerged or modified files in the removing areas.
+
When a merge conflict happens, the index entries for conflicting
paths are left unmerged, and you need to resolve the conflicts
@@ -171,6 +193,48 @@ the reflog for HEAD where you were, e.g.
$ git log -g -2 HEAD
------------
+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 required. Narrow
+checkout is a mode that limits checkout area according to your
+rules.
+
+Because narrow checkout uses new index format, it will be
+incompatible with git prior to 1.6.0. In order to make your
+working directory work with those versions, you can use `git
+checkout --full` to return to normal mode (and compatible index
+format).
+
+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".
+
+New files after merges will always be "needed". You can also
+apply rules when switching branches to avoid unwanted new files.
+
+Files that are marked "no-checkout" will be treated like entries
+with "assume-unchanged bit" (see linkgit:git-update-index[1]). In
+short, Git will never look for those files in working directory
+no matter whether they exist in working directory.
+
+You can apply your rules at once with --path option, or do it
+incrementally with --add-path and --remove-path.
+
+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.
EXAMPLES
--------
diff --git a/builtin-checkout.c b/builtin-checkout.c
index c7b0aad..b6bc3c5 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -33,6 +33,12 @@ struct checkout_opts {
const char *new_branch;
int new_branch_log;
enum branch_track track;
+
+ const char *prefix;
+ char *new_path;
+ char *add_path;
+ char *remove_path;
+ int no_narrow_checkout;
};
static int post_checkout_hook(struct commit *old, struct commit *new,
@@ -412,6 +418,24 @@ static int merge_working_tree(struct checkout_opts *opts,
tree = parse_tree_indirect(new->commit->object.sha1);
init_tree_desc(&trees[1], tree->buffer, tree->size);
+ topts.narrow_prefix = opts->prefix;
+ if (opts->no_narrow_checkout) {
+ /* leave narrow_spec NULL */
+ topts.new_narrow_path = 1;
+ }
+ else if (opts->new_path) {
+ topts.narrow_spec = opts->new_path;
+ topts.new_narrow_path = 1;
+ }
+ else if (opts->add_path) {
+ topts.narrow_spec = opts->add_path;
+ topts.add_narrow_path = 1;
+ }
+ else if (opts->remove_path) {
+ topts.narrow_spec = opts->remove_path;
+ topts.remove_narrow_path = 1;
+ }
+
ret = unpack_trees(2, trees, &topts);
if (ret == -1) {
/*
@@ -600,6 +624,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN('m', "merge", &opts.merge, "merge"),
OPT_STRING(0, "conflict", &conflict_style, "style",
"conflict style (merge or diff3)"),
+ OPT_BOOLEAN(0, "full", &opts.no_narrow_checkout, "quit sparse checkout"),
+ OPT_STRING(0, "path", &opts.new_path, "prefixes", "apply new narrow checkout path"),
+ OPT_STRING(0, "add-path", &opts.add_path, "prefixes", "add more checkout area"),
+ OPT_STRING(0, "remove-path", &opts.remove_path, "prefixes", "narrow checkout area"),
OPT_END(),
};
int has_dash_dash;
@@ -610,6 +638,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
git_config(git_checkout_config, NULL);
opts.track = BRANCH_TRACK_UNSPECIFIED;
+ opts.prefix = prefix;
argc = parse_options(argc, argv, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
@@ -639,6 +668,18 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (!opts.new_branch && (opts.track != git_branch_track))
die("git checkout: --track and --no-track require -b");
+ if (((opts.no_narrow_checkout ? 1 : 0) +
+ (opts.new_path ? 1 : 0) +
+ (opts.add_path ? 1 : 0) +
+ (opts.remove_path ? 1 : 0)) > 1)
+ die("git checkout: --path, --full, --add-path and --remove-path are incompatible");
+
+ if (opts.new_branch && (opts.add_path || opts.remove_path))
+ die("git checkout: --add-path and --remove-path should only be used on current branch");
+
+ if (opts.new_branch && opts.no_narrow_checkout)
+ die("git checkout: switching branch with --full does not make sense");
+
if (opts.force && opts.merge)
die("git checkout: -f and -m are incompatible");
@@ -732,6 +773,9 @@ no_reference:
if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
die("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index.");
+ if (opts.no_narrow_checkout || opts.new_path || opts.add_path || opts.remove_path)
+ die("git checkout: updating paths is incompatible with setting sparse checkout");
+
return checkout_paths(source_tree, pathspec, &opts);
}
diff --git a/t/t2011-checkout-narrow.sh b/t/t2011-checkout-narrow.sh
new file mode 100755
index 0000000..77b99e1
--- /dev/null
+++ b/t/t2011-checkout-narrow.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+test_description='narrow checkout'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir work1 work2 work3
+ touch one two three
+ touch work1/one work2/two work3/three
+ git add one work1/one
+ git commit -m work1
+ git add two work2/two
+ git commit -m work2
+ git add three work3/three
+ git commit -m work3
+'
+
+test_expect_success '--full on no-narrow checkout' '
+ git checkout --full
+'
+
+test_expect_success '--full and --path incompatible' '
+ test_must_fail git checkout --full --path=work1
+'
+
+test_expect_success 'limit worktree to work1 and work2' '
+ git checkout --path="work1/*:work2/*" &&
+ test -f work1/one &&
+ test -f work2/two &&
+ ! test -f work3/three
+'
+
+test_expect_success 'update worktree to work2 and work3' '
+ git checkout --path="work2/*:work3/*" &&
+ ! test -f work1/one &&
+ test -f work2/two &&
+ test -f work3/three
+'
+
+test_expect_success 'update narrow prefix with modification' '
+ echo modified >> work2/two &&
+ git checkout --path="work1/*:work2/*" &&
+ test -f work1/one &&
+ test -f work2/two &&
+ ! test -f work3/three &&
+ grep -q modified work2/two
+'
+
+test_expect_success 'update narrow should not lose modification' '
+ ! git checkout --path="work1/*:work3/*" &&
+ test -f work1/one &&
+ test -f work2/two &&
+ ! test -f work3/three &&
+ grep -q modified work2/two
+'
+
+test_expect_success 'widen checkout area' '
+ git checkout --add-path="work3/*" &&
+ test -f work1/one &&
+ test -f work2/two &&
+ test -f work3/three
+'
+
+test_expect_success 'narrow checkout area' '
+ git checkout --remove-path="work3/*" &&
+ test -f work1/one &&
+ test -f work2/two &&
+ ! test -f work3/three
+'
+
+test_expect_success 'exit narrow checkout' '
+ git checkout --full &&
+ test -f work1/one &&
+ test -f work2/two &&
+ test -f work3/three &&
+ test one
+'
+
+test_done
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 14/16] clone: support narrow checkout with --path option
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:08 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-14-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-clone.txt | 8 +++++++-
builtin-clone.c | 13 +++++++++++++
t/t5703-clone-narrow.sh | 39 +++++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 1 deletions(-)
create mode 100755 t/t5703-clone-narrow.sh
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 0e14e73..0a7d11d 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -12,7 +12,8 @@ SYNOPSIS
'git clone' [--template=<template_directory>]
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
[-o <name>] [-u <upload-pack>] [--reference <repository>]
- [--depth <depth>] [--] <repository> [<directory>]
+ [--depth <depth>] [--path=<narrow_spec>] [--]
+ <repository> [<directory>]
DESCRIPTION
-----------
@@ -94,6 +95,11 @@ then the cloned repository will become corrupt.
-n::
No checkout of HEAD is performed after the clone is complete.
+--path=<narrow_spec>::
+ A narrow checkout of HEAD is performed after clone is complete
+ with given narrow spec. Please refer to linkgit:git-checkout[1]
+ for more detail on narrow checkout and narrow spec.
+
--bare::
Make a 'bare' GIT repository. That is, instead of
creating `<directory>` and placing the administrative
diff --git a/builtin-clone.c b/builtin-clone.c
index c843529..37d44ca 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -36,6 +36,7 @@ static const char * const builtin_clone_usage[] = {
static int option_quiet, option_no_checkout, option_bare, option_mirror;
static int option_local, option_no_hardlinks, option_shared;
static char *option_template, *option_reference, *option_depth;
+static char *option_narrow_path;
static char *option_origin = NULL;
static char *option_upload_pack = "git-upload-pack";
@@ -43,6 +44,8 @@ static struct option builtin_clone_options[] = {
OPT__QUIET(&option_quiet),
OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
"don't create a checkout"),
+ OPT_STRING(0, "path", &option_narrow_path, "prefixes",
+ "limit checkout to specified paths (narrow checkout)"),
OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"),
OPT_BOOLEAN(0, "mirror", &option_mirror,
@@ -385,10 +388,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_origin)
die("--bare and --origin %s options are incompatible.",
option_origin);
+ if (option_narrow_path)
+ die("--bare and --path options are incompatible.");
option_no_checkout = 1;
use_separate_remote = 0;
}
+ if (option_no_checkout && option_narrow_path)
+ die("--no-checkout and --path options are incompatible.");
+
if (!option_origin)
option_origin = "origin";
@@ -597,6 +605,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
opts.src_index = &the_index;
opts.dst_index = &the_index;
+ if (option_narrow_path) {
+ opts.new_narrow_path = 1;
+ opts.narrow_spec = option_narrow_path;
+ }
+
tree = parse_tree_indirect(remote_head->old_sha1);
parse_tree(tree);
init_tree_desc(&t, tree->buffer, tree->size);
diff --git a/t/t5703-clone-narrow.sh b/t/t5703-clone-narrow.sh
new file mode 100755
index 0000000..3ab9eaf
--- /dev/null
+++ b/t/t5703-clone-narrow.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+test_description='narrow clone'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ rm -fr .git &&
+ test_create_repo src &&
+ (
+ cd src
+ mkdir -p work/sub/dir
+ touch untracked tracked modified added
+ touch work/untracked work/tracked work/modified work/added
+ git add tracked work/tracked
+ git add modified work/modified
+ git commit -m initial
+ )
+
+'
+
+test_expect_success 'narrow clone incompatible with --bare' '
+ rm -fr dst &&
+ test_must_fail git clone --path=work --bare src dst
+'
+
+test_expect_success 'narrow clone incompatible with --no-checkout' '
+ rm -fr dst &&
+ test_must_fail git clone --path=work -n src dst
+'
+
+test_expect_success 'clone with --path' '
+ rm -fr dst &&
+ git clone --path=work src dst &&
+ cd dst &&
+ test -z "$(git ls-files --checkout | grep -v ^work/)"
+'
+
+test_done
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 13/16] ls-files: add --narrow-match=spec option for testing narrow matching
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:08 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-13-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-ls-files.txt | 7 +++++-
builtin-ls-files.c | 14 +++++++++++-
t/t3003-ls-files-narrow-match.sh | 45 ++++++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 2 deletions(-)
create mode 100755 t/t3003-ls-files-narrow-match.sh
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index f74b212..4f5a37e 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -12,7 +12,7 @@ SYNOPSIS
'git ls-files' [-z] [-t] [-v]
(--[cached|deleted|others|ignored|stage|unmerged|killed|modified])\*
(-[c|d|o|i|s|u|k|m])\*
- [--narrow-checkout]
+ [--narrow-checkout] [--narrow-match=<narrow_spec>]
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
@@ -78,6 +78,11 @@ OPTIONS
index-based selection options like --cached or --stage, only narrowed
portion will be printed out.
+--narrow-match=<narrow_spec>::
+ Narrow spec can be applied on ls-files output so that you can test
+ your spec. Can only be used with --cached. See linkgit:git-checkout[1]
+ for more information about narrow spec.
+
-z::
\0 line termination on output.
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 02fa00b..f48a157 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -10,6 +10,8 @@
#include "dir.h"
#include "builtin.h"
#include "tree.h"
+#include "tree-walk.h"
+#include "unpack-trees.h"
static int abbrev;
static int show_deleted;
@@ -29,6 +31,7 @@ static const char **pathspec;
static int error_unmatch;
static char *ps_matched;
static const char *with_tree;
+static const char *narrow_spec;
static const char *tag_cached = "";
static const char *tag_unmerged = "";
@@ -248,6 +251,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
continue;
if (narrow_checkout && ce_no_checkout(ce))
continue;
+ if (narrow_spec && !match_narrow_spec(narrow_spec, ce->name, prefix))
+ continue;
show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
}
}
@@ -427,7 +432,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
static const char ls_files_usage[] =
"git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
- "[ --narrow-checkout ] "
+ "[ --narrow-checkout ] [--narrow-match=<narrow_spec>] "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ] [--exclude-standard] "
"[--full-name] [--abbrev] [--] [<file>]*";
@@ -473,6 +478,10 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
narrow_checkout = 1;
continue;
}
+ if (!prefixcmp(arg, "--narrow-match=")) {
+ narrow_spec = arg+15;
+ continue;
+ }
if (!strcmp(arg, "-d") || !strcmp(arg, "--deleted")) {
show_deleted = 1;
continue;
@@ -607,6 +616,9 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
if (narrow_checkout && !show_cached && !show_stage)
die("ls-files: --narrow-checkout can only be used with either --cached or --stage");
+ if (narrow_spec && !show_cached && !show_stage)
+ die("ls-files: --narrow-match can only be used with either --cached or --stage");
+
read_cache();
if (prefix)
prune_cache(prefix);
diff --git a/t/t3003-ls-files-narrow-match.sh b/t/t3003-ls-files-narrow-match.sh
new file mode 100755
index 0000000..b48fdb2
--- /dev/null
+++ b/t/t3003-ls-files-narrow-match.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+test_description='This test is for narrow spec matching'
+
+. test-lib.sh
+
+test_expect_success 'setup' '
+ touch 1 2 3 &&
+ mkdir -p sub/subsub &&
+ touch sub/1 sub/2 sub/3 &&
+ touch sub/subsub/1 sub/subsub/2 sub/subsub/3 &&
+ git add .
+'
+
+test_expect_success 'exact matches' '
+ test "$(git ls-files --narrow-match=1)" = 1 &&
+ test -z "$(git ls-files --narrow-match=sub)" && # exact match on a directory gives nothing
+ (cd sub &&
+ test "$(git ls-files --full-name --narrow-match=subsub/1)" = sub/subsub/1 &&
+ test "$(git ls-files --narrow-match=subsub/1)" = subsub/1)
+'
+
+test_expect_success 'star matches' '
+ test "$(git ls-files --narrow-match=\*1)" = 1 &&
+ (cd sub &&
+ test "$(git ls-files --full-name --narrow-match=subsub/\*1)" = sub/subsub/1 &&
+ test "$(git ls-files --narrow-match=subsub/\*1)" = subsub/1)
+'
+
+cat >starplus-1.expected <<\EOF
+1
+sub/1
+sub/subsub/1
+EOF
+cat >starplus-2.expected <<\EOF
+sub/1
+sub/subsub/1
+EOF
+test_expect_success 'starplus matches' '
+ git ls-files --narrow-match=+\*1 | cmp starplus-1.expected
+ (cd sub &&
+ git ls-files --full-name --narrow-match=+\*1 | cmp ../starplus-2.expected)
+'
+
+test_done
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 12/16] narrow spec: put '+' before a spec will change semantic of '*'
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:08 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-12-git-send-email-pclouds@gmail.com>
Previously '*' in narrow spec means 'match everything, even slashes'.
With this change, '*' is now 'match everything except slashes' so it is
more like shell wildcard one. Putting '+' before a spec will make
'*' as powerful as before.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
unpack-trees.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index 968cc98..3782de6 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -812,10 +812,15 @@ int match_narrow_spec(const char *spec_, const char *path, const char *prefix)
while (!match) {
char *next_spec = strchr(cur_spec, ':');
+ int flag = 0;
if (next_spec)
*next_spec = '\0';
- if (!fnmatch(cur_spec, path+prefix_len, 0))
+ if (*cur_spec == '+')
+ cur_spec++;
+ else
+ flag = FNM_PATHNAME;
+ if (!fnmatch(cur_spec, path+prefix_len, flag))
match = 1;
if (!next_spec)
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 11/16] unpack_trees(): add support for narrow checkout
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:08 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-11-git-send-email-pclouds@gmail.com>
This patch teaches unpack_trees() to checkout/remove entries
on working directories appropriately when narrow area is
changed. There are three kind of changes:
- new_narrow_path: reset workdir to a new narrow checkout
- add_narrow_path: keep current narrow areas and add more entries
- remove_narrow_path: remove some entries from current narrow areas
A simple "narrow spec" is introduced to specify what entries is in
narrow area. For now it is just a list of prefix separated by colon.
CE_WD_REMOVE is introduced to remove entries from working directories,
but still keep them in index
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 3 ++
unpack-trees.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
unpack-trees.h | 6 +++
3 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index 2b2c90f..1fc0f83 100644
--- a/cache.h
+++ b/cache.h
@@ -167,6 +167,9 @@ struct cache_entry {
#define CE_HASHED (0x100000)
#define CE_UNHASHED (0x200000)
+/* Only remove in work directory, not index */
+#define CE_WD_REMOVE (0x400000)
+
/*
* Extended on-disk flags
*/
diff --git a/unpack-trees.c b/unpack-trees.c
index e59d144..968cc98 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -96,6 +96,15 @@ static int check_updates(struct unpack_trees_options *o)
if (o->update && o->verbose_update) {
for (total = cnt = 0; cnt < index->cache_nr; cnt++) {
struct cache_entry *ce = index->cache[cnt];
+
+ if (ce->ce_flags & CE_WD_REMOVE) {
+ total++;
+ continue;
+ }
+
+ if (ce_no_checkout(ce))
+ continue;
+
if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
total++;
}
@@ -108,6 +117,16 @@ static int check_updates(struct unpack_trees_options *o)
for (i = 0; i < index->cache_nr; i++) {
struct cache_entry *ce = index->cache[i];
+ if (ce->ce_flags & CE_WD_REMOVE) {
+ display_progress(progress, ++cnt);
+ if (o->update)
+ unlink_entry(ce);
+ continue;
+ }
+
+ if (ce_no_checkout(ce))
+ continue;
+
if (ce->ce_flags & CE_REMOVE) {
display_progress(progress, ++cnt);
if (o->update)
@@ -121,6 +140,9 @@ static int check_updates(struct unpack_trees_options *o)
for (i = 0; i < index->cache_nr; i++) {
struct cache_entry *ce = index->cache[i];
+ if (ce_no_checkout(ce))
+ continue;
+
if (ce->ce_flags & CE_UPDATE) {
display_progress(progress, ++cnt);
ce->ce_flags &= ~CE_UPDATE;
@@ -133,6 +155,47 @@ static int check_updates(struct unpack_trees_options *o)
return errs != 0;
}
+static int verify_uptodate(struct cache_entry *ce, struct unpack_trees_options *o);
+static int apply_narrow_checkout(struct unpack_trees_options *o)
+{
+ struct index_state *index = &o->result;
+ int i;
+
+ if (!(o->new_narrow_path | o->add_narrow_path | o->remove_narrow_path))
+ return 0;
+
+ for (i = 0; i < index->cache_nr; i++) {
+ struct cache_entry *ce = index->cache[i];
+ int was_checkout = ce_checkout(ce);
+ int match = match_narrow_spec(o->narrow_spec, ce->name, o->narrow_prefix);
+
+ if (ce_stage(ce))
+ continue;
+
+ if (o->new_narrow_path) {
+ if (match)
+ ce_mark_checkout(ce);
+ else
+ ce_mark_no_checkout(ce);
+ }
+
+ if (o->add_narrow_path && match)
+ ce_mark_checkout(ce);
+
+ if (o->remove_narrow_path && match)
+ ce_mark_no_checkout(ce);
+
+ if (was_checkout && ce_no_checkout(ce)) {
+ if (verify_uptodate(ce, o))
+ return -1;
+ ce->ce_flags |= CE_WD_REMOVE;
+ }
+ if (!was_checkout && ce_checkout(ce))
+ ce->ce_flags |= CE_UPDATE;
+ }
+ return 0;
+}
+
static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o)
{
int ret = o->fn(src, o);
@@ -409,6 +472,9 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
if (o->trivial_merges_only && o->nontrivial_merge)
return unpack_failed(o, "Merge requires file-level merging");
+ if (apply_narrow_checkout(o))
+ return unpack_failed(o, NULL);
+
o->src_index = NULL;
ret = check_updates(o) ? (-2) : 0;
if (o->dst_index)
@@ -677,6 +743,8 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
return -1;
invalidate_ce_path(old, o);
}
+ if (ce_no_checkout(old))
+ update |= CE_NO_CHECKOUT;
}
else {
if (verify_absent(merge, "overwritten", o))
@@ -726,6 +794,38 @@ static void show_stage_entry(FILE *o,
}
#endif
+int match_narrow_spec(const char *spec_, const char *path, const char *prefix)
+{
+ int match = 0;
+ char *spec, *cur_spec;
+ int prefix_len = 0;
+
+ if (!spec_)
+ return 1; /* always match if spec_ is NULL */
+ if (prefix) {
+ if (prefixcmp(path, prefix))
+ return 0;
+ prefix_len = strlen(prefix);
+ }
+
+ spec = cur_spec = xstrdup(spec_);
+
+ while (!match) {
+ char *next_spec = strchr(cur_spec, ':');
+ if (next_spec)
+ *next_spec = '\0';
+
+ if (!fnmatch(cur_spec, path+prefix_len, 0))
+ match = 1;
+
+ if (!next_spec)
+ break;
+ cur_spec = next_spec+1;
+ }
+ free(spec);
+ return match;
+}
+
int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)
{
struct cache_entry *index;
diff --git a/unpack-trees.h b/unpack-trees.h
index 0d26f3d..942a007 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -27,6 +27,9 @@ struct unpack_trees_options {
aggressive:1,
skip_unmerged:1,
initial_checkout:1,
+ new_narrow_path:1,
+ add_narrow_path:2,
+ remove_narrow_path:2,
gently:1;
const char *prefix;
int pos;
@@ -38,6 +41,8 @@ struct unpack_trees_options {
int merge_size;
struct cache_entry *df_conflict_entry;
+ const char *narrow_spec;
+ const char *narrow_prefix;
void *unpack_data;
struct index_state *dst_index;
@@ -48,6 +53,7 @@ struct unpack_trees_options {
extern int unpack_trees(unsigned n, struct tree_desc *t,
struct unpack_trees_options *options);
+int match_narrow_spec(const char *spec_, const char *path, const char *prefix);
int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o);
int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o);
int bind_merge(struct cache_entry **src, struct unpack_trees_options *o);
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 10/16] grep: skip files that have not been checked out
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-10-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-grep.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/builtin-grep.c b/builtin-grep.c
index 3a51662..d5507d7 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -343,6 +343,8 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
continue;
if (!pathspec_matches(paths, ce->name))
continue;
+ if (ce_no_checkout(ce))
+ continue;
name = ce->name;
if (name[0] == '-') {
int len = ce_namelen(ce);
@@ -404,8 +406,11 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
continue;
hit |= grep_sha1(opt, ce->sha1, ce->name, 0);
}
- else
+ else {
+ if (ce_no_checkout(ce))
+ continue;
hit |= grep_file(opt, ce->name);
+ }
if (ce_stage(ce)) {
do {
nr++;
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 09/16] ls-files: apply --deleted on narrow area only
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-9-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-ls-files.c | 2 +-
t/t2104-update-index-narrow.sh | 6 ++++++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 456d41c..02fa00b 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -260,7 +260,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
continue;
err = lstat(ce->name, &st);
- if (show_deleted && err)
+ if (show_deleted && err && ce_checkout(ce))
show_ce_entry(tag_removed, ce);
if (show_modified && ce_modified(ce, &st, 0))
show_ce_entry(tag_modified, ce);
diff --git a/t/t2104-update-index-narrow.sh b/t/t2104-update-index-narrow.sh
index 2683929..1a3acdd 100755
--- a/t/t2104-update-index-narrow.sh
+++ b/t/t2104-update-index-narrow.sh
@@ -25,6 +25,12 @@ test_expect_success 'index is at version 3 after having some no-checkout entries
test "$(test-index-version < .git/index)" = 3
'
+test_expect_success 'ls-files --deleted ignores no-checkout entries' '
+ rm 1 &&
+ test -z "$(git ls-files --deleted)" &&
+ touch 1
+'
+
test_expect_success 'update-index --checkout' '
git update-index --checkout 1 sub/1 &&
test "$(git ls-files)" = "$(git ls-files --narrow-checkout)"'
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 08/16] checkout_entry(): CE_NO_CHECKOUT on checked out entries.
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-8-git-send-email-pclouds@gmail.com>
With this you can just do "git checkout some-files" to
widen your checkout. One caveat though: caller must save
the index.
For all of its callers (unpack_trees(), checkout-index, checkout
and apply), only "git apply" does not write index back.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
entry.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/entry.c b/entry.c
index aa2ee46..305f8d3 100644
--- a/entry.c
+++ b/entry.c
@@ -230,5 +230,6 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
} else if (state->not_new)
return 0;
create_directories(path, state);
+ ce_mark_checkout(ce);
return write_entry(ce, path, state, 0);
}
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 07/16] Prevent diff machinery from examining worktree outside narrow checkout
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-7-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
diff-lib.c | 5 +++--
diff.c | 4 +++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/diff-lib.c b/diff-lib.c
index ae96c64..992280b 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -161,7 +161,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
continue;
}
- if (ce_uptodate(ce))
+ if (ce_uptodate(ce) || ce_no_checkout(ce))
continue;
changed = check_removed(ce, &st);
@@ -348,6 +348,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
struct rev_info *revs = cbdata->revs;
int match_missing, cached;
+ /* if the entry is not checked out, don't examine work tree */
+ cached = o->index_only || (idx && ce_no_checkout(idx));
/*
* Backward compatibility wart - "diff-index -m" does
* not mean "do not ignore merges", but "match_missing".
@@ -355,7 +357,6 @@ static void do_oneway_diff(struct unpack_trees_options *o,
* But with the revision flag parsing, that's found in
* "!revs->ignore_merges".
*/
- cached = o->index_only;
match_missing = !revs->ignore_merges;
if (cached && idx && ce_stage(idx)) {
diff --git a/diff.c b/diff.c
index a2f4850..7a8f520 100644
--- a/diff.c
+++ b/diff.c
@@ -1784,8 +1784,10 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
/*
* If ce matches the file in the work tree, we can reuse it.
+ * For narrow checkout case, ce_uptodate() may be true although
+ * the file may or may not exist in the work tree.
*/
- if (ce_uptodate(ce) ||
+ if ((ce_uptodate(ce) && ce_checkout(ce)) ||
(!lstat(name, &st) && !ce_match_stat(ce, &st, 0)))
return 1;
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 06/16] Add tests for updating no-checkout entries in index
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-6-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
.gitignore | 1 +
Makefile | 2 +-
t/t2104-update-index-narrow.sh | 36 ++++++++++++++++++++++++++++++++++++
test-index-version.c | 14 ++++++++++++++
4 files changed, 52 insertions(+), 1 deletions(-)
create mode 100755 t/t2104-update-index-narrow.sh
create mode 100644 test-index-version.c
diff --git a/.gitignore b/.gitignore
index bbaf9de..0c35577 100644
--- a/.gitignore
+++ b/.gitignore
@@ -147,6 +147,7 @@ test-date
test-delta
test-dump-cache-tree
test-genrandom
+test-index-version
test-match-trees
test-parse-options
test-path-utils
diff --git a/Makefile b/Makefile
index 716161d..7a22bde 100644
--- a/Makefile
+++ b/Makefile
@@ -1323,7 +1323,7 @@ endif
### Testing rules
-TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X
+TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X test-index-version$X
all:: $(TEST_PROGRAMS)
diff --git a/t/t2104-update-index-narrow.sh b/t/t2104-update-index-narrow.sh
new file mode 100755
index 0000000..2683929
--- /dev/null
+++ b/t/t2104-update-index-narrow.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
+#
+
+test_description='git update-index narrow checkout update'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir sub &&
+ touch 1 2 sub/1 sub/2 &&
+ git add 1 2 sub/1 sub/2
+'
+
+test_expect_success 'index is at version 2' '
+ test "$(test-index-version < .git/index)" = 2
+'
+
+test_expect_success 'update-index --no-checkout' '
+ git update-index --no-checkout 1 sub/1 &&
+ test -z "$(git ls-files --narrow-checkout|grep 1)"'
+
+test_expect_success 'index is at version 3 after having some no-checkout entries' '
+ test "$(test-index-version < .git/index)" = 3
+'
+
+test_expect_success 'update-index --checkout' '
+ git update-index --checkout 1 sub/1 &&
+ test "$(git ls-files)" = "$(git ls-files --narrow-checkout)"'
+
+test_expect_success 'index version is back to 2 when there is no no-checkout entry' '
+ test "$(test-index-version < .git/index)" = 2
+'
+
+test_done
diff --git a/test-index-version.c b/test-index-version.c
new file mode 100644
index 0000000..bfaad9e
--- /dev/null
+++ b/test-index-version.c
@@ -0,0 +1,14 @@
+#include "cache.h"
+
+int main(int argc, const char **argv)
+{
+ struct cache_header hdr;
+ int version;
+
+ memset(&hdr,0,sizeof(hdr));
+ if (read(0, &hdr, sizeof(hdr)) != sizeof(hdr))
+ return 0;
+ version = ntohl(hdr.hdr_version);
+ printf("%d\n", version);
+ return 0;
+}
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 05/16] ls-files: add --narrow-checkout option to "will checkout" entries
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-5-git-send-email-pclouds@gmail.com>
Even in narrow checkout mode, "git ls-files --cached" (and --stage)
will show all entries in index. When those options are used together
with --narrow-checkout, no-checkout entries will be skipped.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-ls-files.txt | 6 ++++++
builtin-ls-files.c | 11 +++++++++++
2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 9f85d60..f74b212 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -12,6 +12,7 @@ SYNOPSIS
'git ls-files' [-z] [-t] [-v]
(--[cached|deleted|others|ignored|stage|unmerged|killed|modified])\*
(-[c|d|o|i|s|u|k|m])\*
+ [--narrow-checkout]
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
@@ -72,6 +73,11 @@ OPTIONS
to file/directory conflicts for checkout-index to
succeed.
+--narrow-checkout::
+ When narrow checkout is being used, this option together with other
+ index-based selection options like --cached or --stage, only narrowed
+ portion will be printed out.
+
-z::
\0 line termination on output.
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 068f424..456d41c 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -20,6 +20,7 @@ static int show_unmerged;
static int show_modified;
static int show_killed;
static int show_valid_bit;
+static int narrow_checkout;
static int line_terminator = '\n';
static int prefix_len;
@@ -245,6 +246,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
continue;
if (ce->ce_flags & CE_UPDATE)
continue;
+ if (narrow_checkout && ce_no_checkout(ce))
+ continue;
show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
}
}
@@ -424,6 +427,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
static const char ls_files_usage[] =
"git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
+ "[ --narrow-checkout ] "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ] [--exclude-standard] "
"[--full-name] [--abbrev] [--] [<file>]*";
@@ -465,6 +469,10 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
show_cached = 1;
continue;
}
+ if (!strcmp(arg, "--narrow-checkout")) {
+ narrow_checkout = 1;
+ continue;
+ }
if (!strcmp(arg, "-d") || !strcmp(arg, "--deleted")) {
show_deleted = 1;
continue;
@@ -596,6 +604,9 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
show_killed | show_modified))
show_cached = 1;
+ if (narrow_checkout && !show_cached && !show_stage)
+ die("ls-files: --narrow-checkout can only be used with either --cached or --stage");
+
read_cache();
if (prefix)
prune_cache(prefix);
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 04/16] update-index: add --checkout/--no-checkout to update CE_NO_CHECKOUT bit
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-4-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-update-index.txt | 12 ++++++++++++
builtin-update-index.c | 16 +++++++++++++++-
2 files changed, 27 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 1d9d81a..707c33f 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -15,6 +15,7 @@ SYNOPSIS
[--cacheinfo <mode> <object> <file>]\*
[--chmod=(+|-)x]
[--assume-unchanged | --no-assume-unchanged]
+ [--checkout | --no-checkout]
[--ignore-submodules]
[--really-refresh] [--unresolve] [--again | -g]
[--info-only] [--index-info]
@@ -88,6 +89,17 @@ OPTIONS
sometimes helpful when working with a big project on a
filesystem that has very slow lstat(2) system call
(e.g. cifs).
+--checkout::
+--no-checkout::
+ When these flags are specified, the object name recorded
+ for the paths are not updated. Instead, these options
+ set and unset the "no-checkout" bit for the paths. This
+ bit is used for marking files for narrow checkout. If
+ a path is marked "no-checkout", then it should not be
+ checked out unless requested by user or needed for a git
+ command to function.
+ See linkgit:git-checkout[1] for more information about
+ narrow checkout.
+
This option can be also used as a coarse file-level mechanism
to ignore uncommitted changes in tracked files (akin to what
diff --git a/builtin-update-index.c b/builtin-update-index.c
index f63a34e..6ed883d 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -24,6 +24,7 @@ static int info_only;
static int force_remove;
static int verbose;
static int mark_valid_only;
+static int mark_no_checkout_only;
#define MARK_FLAG 1
#define UNMARK_FLAG 2
@@ -276,6 +277,11 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
die("Unable to mark file %s", path);
goto free_return;
}
+ if (mark_no_checkout_only) {
+ if (mark_ce_flags(p, CE_NO_CHECKOUT, mark_no_checkout_only == MARK_FLAG))
+ die("Unable to mark file %s", path);
+ goto free_return;
+ }
if (force_remove) {
if (remove_file_from_cache(p))
@@ -386,7 +392,7 @@ static void read_index_info(int line_termination)
}
static const char update_index_usage[] =
-"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
+"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--checkout|--no-checkout] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];
@@ -652,6 +658,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
mark_valid_only = UNMARK_FLAG;
continue;
}
+ if (!strcmp(path, "--checkout")) {
+ mark_no_checkout_only = UNMARK_FLAG;
+ continue;
+ }
+ if (!strcmp(path, "--no-checkout")) {
+ mark_no_checkout_only = MARK_FLAG;
+ continue;
+ }
if (!strcmp(path, "--info-only")) {
info_only = 1;
continue;
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 03/16] update-index: refactor mark_valid() in preparation for new options
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-3-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-update-index.c | 24 ++++++++++--------------
1 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index ce83224..f63a34e 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -24,8 +24,8 @@ static int info_only;
static int force_remove;
static int verbose;
static int mark_valid_only;
-#define MARK_VALID 1
-#define UNMARK_VALID 2
+#define MARK_FLAG 1
+#define UNMARK_FLAG 2
static void report(const char *fmt, ...)
{
@@ -40,19 +40,15 @@ static void report(const char *fmt, ...)
va_end(vp);
}
-static int mark_valid(const char *path)
+static int mark_ce_flags(const char *path, int flag, int mark)
{
int namelen = strlen(path);
int pos = cache_name_pos(path, namelen);
if (0 <= pos) {
- switch (mark_valid_only) {
- case MARK_VALID:
- active_cache[pos]->ce_flags |= CE_VALID;
- break;
- case UNMARK_VALID:
- active_cache[pos]->ce_flags &= ~CE_VALID;
- break;
- }
+ if (mark)
+ active_cache[pos]->ce_flags |= flag;
+ else
+ active_cache[pos]->ce_flags &= ~flag;
cache_tree_invalidate_path(active_cache_tree, path);
active_cache_changed = 1;
return 0;
@@ -276,7 +272,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
goto free_return;
}
if (mark_valid_only) {
- if (mark_valid(p))
+ if (mark_ce_flags(p, CE_VALID, mark_valid_only == MARK_FLAG))
die("Unable to mark file %s", path);
goto free_return;
}
@@ -649,11 +645,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
continue;
}
if (!strcmp(path, "--assume-unchanged")) {
- mark_valid_only = MARK_VALID;
+ mark_valid_only = MARK_FLAG;
continue;
}
if (!strcmp(path, "--no-assume-unchanged")) {
- mark_valid_only = UNMARK_VALID;
+ mark_valid_only = UNMARK_FLAG;
continue;
}
if (!strcmp(path, "--info-only")) {
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
* [PATCH 02/16] Introduce CE_NO_CHECKOUT bit
From: Nguyễn Thái Ngọc Duy @ 2008-09-14 13:07 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1221397685-27715-2-git-send-email-pclouds@gmail.com>
This bit is the basis of narrow checkout. If this bit is on, the entry
is outside narrow checkout and therefore should be ignored (similar
to CE_VALID)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 10 +++++++++-
read-cache.c | 6 +++---
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/cache.h b/cache.h
index 1e572e4..2b2c90f 100644
--- a/cache.h
+++ b/cache.h
@@ -170,10 +170,11 @@ struct cache_entry {
/*
* Extended on-disk flags
*/
+#define CE_NO_CHECKOUT 0x40000000
/* CE_EXTENDED2 is for future extension */
#define CE_EXTENDED2 0x80000000
-#define CE_EXTENDED_FLAGS (0)
+#define CE_EXTENDED_FLAGS (CE_NO_CHECKOUT)
/*
* Safeguard to avoid saving wrong flags:
@@ -185,6 +186,9 @@ struct cache_entry {
#error "CE_EXTENDED_FLAGS out of range"
#endif
+/* "Assume unchanged" mask */
+#define CE_VALID_MASK (CE_VALID | CE_NO_CHECKOUT)
+
/*
* Copy the sha1 and stat state of a cache entry from one to
* another. But we never change the name, or the hash state!
@@ -222,6 +226,10 @@ static inline size_t ce_namelen(const struct cache_entry *ce)
ondisk_cache_entry_size(ce_namelen(ce)))
#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
+#define ce_no_checkout(ce) ((ce)->ce_flags & CE_NO_CHECKOUT)
+#define ce_checkout(ce) (!ce_no_checkout(ce))
+#define ce_mark_no_checkout(ce) ((ce)->ce_flags |= CE_NO_CHECKOUT)
+#define ce_mark_checkout(ce) ((ce)->ce_flags &= ~CE_NO_CHECKOUT)
#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
diff --git a/read-cache.c b/read-cache.c
index 667c36b..e965a4c 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -254,7 +254,7 @@ int ie_match_stat(const struct index_state *istate,
* If it's marked as always valid in the index, it's
* valid whatever the checked-out copy says.
*/
- if (!ignore_valid && (ce->ce_flags & CE_VALID))
+ if (!ignore_valid && (ce->ce_flags & CE_VALID_MASK))
return 0;
changed = ce_match_stat_basic(ce, st);
@@ -962,10 +962,10 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
return ce;
/*
- * CE_VALID means the user promised us that the change to
+ * CE_VALID_MASK means the user promised us that the change to
* the work tree does not matter and told us not to worry.
*/
- if (!ignore_valid && (ce->ce_flags & CE_VALID)) {
+ if (!ignore_valid && (ce->ce_flags & CE_VALID_MASK)) {
ce_mark_uptodate(ce);
return ce;
}
--
1.6.0.96.g2fad1.dirty
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox