* Re: [PATCH 2/2] Add gitk-git Hungarian translation
From: Junio C Hamano @ 2009-12-14 2:46 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Laszlo Papp, Laszlo Papp, git
In-Reply-To: <20091213230305.GA8135@brick.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> writes:
> In any case, your patch has problems: I applied it and then ran
> make to update the message catalogs, and I got these errors:
>
> Generating catalog po/hu.msg
> msgfmt --statistics --tcl po/hu.po -l hu -d po/
> po/hu.po:41: end-of-line within string
> po/hu.po:41:4: syntax error
> po/hu.po:42: end-of-line within string
> po/hu.po:666: end-of-line within string
> po/hu.po:666:10: syntax error
> po/hu.po:667: end-of-line within string
> msgfmt: found 6 fatal errors
> make: *** [po/hu.msg] Error 1
>
> so I reverted it.
Syntactically there seem to be only two line-wrapping caused by MUA on the
originating side that caused this. Munging the problematic lines seems to
fix the above.
Now, I don't read _any_ Hungarian, so it could very well be that my fix-up
is wrong and there shouldn't be any SP between two words in 'fájlon belül'
and 'még nincsenek'; if we hear from some Hungarian capable readers that the
fix-up below makes sense, perhaps squashing it in would be the easiest way
to move forward?
diff --git b/gitk-git/po/hu.po a/gitk-git/po/hu.po
index d281e3c..cbaa93d 100755
--- b/gitk-git/po/hu.po
+++ a/gitk-git/po/hu.po
@@ -37,8 +37,7 @@ msgid ""
"No files selected: --merge specified but no unmerged files are within file "
"limit."
msgstr ""
-"Nincsen fájl kiválasztva: --merge megadva, de nincsenek unmerged fájlok a fájlon
-belül "
+"Nincsen fájl kiválasztva: --merge megadva, de nincsenek unmerged fájlok a fájlon belül "
"limit."
#: gitk:361 gitk:508
@@ -662,8 +661,7 @@ msgstr "Nem előd"
#: gitk:4842
msgid "Local changes checked in to index but not committed"
-msgstr "Lokális változtatások, melyek be vannak téve az indexbe, de még
-nincsenek commitolva"
+msgstr "Lokális változtatások, melyek be vannak téve az indexbe, de még nincsenek commitolva"
#: gitk:4878
msgid "Local uncommitted changes, not checked in to index"
^ permalink raw reply related
* Re: [PATCH 2/2] Add gitk-git Hungarian translation
From: Paul Mackerras @ 2009-12-14 3:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Laszlo Papp, Laszlo Papp, git
In-Reply-To: <7vskbejmrw.fsf@alter.siamese.dyndns.org>
On Sun, Dec 13, 2009 at 06:46:11PM -0800, Junio C Hamano wrote:
> Paul Mackerras <paulus@samba.org> writes:
>
> > In any case, your patch has problems: I applied it and then ran
> > make to update the message catalogs, and I got these errors:
> >
> > Generating catalog po/hu.msg
> > msgfmt --statistics --tcl po/hu.po -l hu -d po/
> > po/hu.po:41: end-of-line within string
> > po/hu.po:41:4: syntax error
> > po/hu.po:42: end-of-line within string
> > po/hu.po:666: end-of-line within string
> > po/hu.po:666:10: syntax error
> > po/hu.po:667: end-of-line within string
> > msgfmt: found 6 fatal errors
> > make: *** [po/hu.msg] Error 1
> >
> > so I reverted it.
>
> Syntactically there seem to be only two line-wrapping caused by MUA on the
> originating side that caused this. Munging the problematic lines seems to
> fix the above.
It didn't look to me as though it was just MUA line-wrapping, since
there was a '+' at the start of the line following the one that didn't
have a closing quote. Also, git am didn't complain about it, which it
would have done if it had been MUA line-wrapping.
> Now, I don't read _any_ Hungarian, so it could very well be that my fix-up
> is wrong and there shouldn't be any SP between two words in 'fájlon belül'
> and 'még nincsenek'; if we hear from some Hungarian capable readers that the
> fix-up below makes sense, perhaps squashing it in would be the easiest way
> to move forward?
I also don't read any Hungarian, which is why I didn't want to try to
fix up problems that were more than just MUA line-wrapping. As you
say, if a Hungarian speaker can verify that your fix is correct, we
could fix up the original patch. A clean re-post with a suitable
subject would be nicer, though.
Paul.
^ permalink raw reply
* Re: [PATCH 2/2] Add gitk-git Hungarian translation
From: Junio C Hamano @ 2009-12-14 4:43 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Junio C Hamano, Laszlo Papp, Laszlo Papp, git
In-Reply-To: <20091214032816.GB24152@drongo>
Paul Mackerras <paulus@samba.org> writes:
> I also don't read any Hungarian, which is why I didn't want to try to
> fix up problems that were more than just MUA line-wrapping. As you
> say, if a Hungarian speaker can verify that your fix is correct, we
> could fix up the original patch. A clean re-post with a suitable
> subject would be nicer, though.
You are right on all counts (the breakage was inside the editor of the
author before the commit was made, the "fix-up" is more than just a MUA
breakage, and a clean re-post with a proper title would be nicer).
Thanks.
^ permalink raw reply
* Re: git --version wrong
From: B Smith-Mannschott @ 2009-12-14 6:17 UTC (permalink / raw)
To: oshybrid; +Cc: git
In-Reply-To: <26770625.post@talk.nabble.com>
On Sun, Dec 13, 2009 at 23:51, oshybrid <oshybrid@gmail.com> wrote:
>
> After i Instal 1.6.5.5 my "git --version" still shows 1.6.0.5
>
How, exactly, did you install it?
What's the output when you type "which git" at the command line?
// Ben
^ permalink raw reply
* How can I get full filenames from Git difftool (for Microsoft Word “Compare Documents” feature)?
From: Doug Ireton @ 2009-12-14 6:25 UTC (permalink / raw)
To: git
In-Reply-To: <b507cb050912132222x7e1daa9cw73b13f3db0ee22c6@mail.gmail.com>
I am using the latest version of Git (1.6.6) on a Mac. My wife wants
to use Git to manage her fiction writing as long as she can still use
Microsoft Word 2008 (Mac). Instead of pushing her into saving
everything as plain text, I would like to use Git Difftool to pass the
files to Word and use Word's Compare Documents feature. She wouldn't
be able to use Git Diff since Word docs are binary files but she could
still use Git Difftool.
I have written an Applescript which takes two filenames in this
format: /Users/foo/Documents/my_novel.docx and opens Word to do the
file comparison. However, Git Difftool seems to only pass the bare
filenames (e.g. my_novel.docx) as parameters.
Is there anyway to get the full filenames from Git Difftool?
Thanks,
Doug Ireton
^ permalink raw reply
* Re: How can I get full filenames from Git difftool (for Microsoft Word “Compare Documents” feature)?
From: Matthieu Moy @ 2009-12-14 7:55 UTC (permalink / raw)
To: Doug Ireton; +Cc: git
In-Reply-To: <b507cb050912132225j1bdc39c2v42a3bf6bddf1cb1a@mail.gmail.com>
Doug Ireton <dougireton@gmail.com> writes:
> I am using the latest version of Git (1.6.6) on a Mac. My wife wants
> to use Git to manage her fiction writing as long as she can still use
> Microsoft Word 2008 (Mac). Instead of pushing her into saving
> everything as plain text, I would like to use Git Difftool to pass the
> files to Word and use Word's Compare Documents feature. She wouldn't
> be able to use Git Diff since Word docs are binary files but she could
> still use Git Difftool.
If you're interested in diff-ing the _text_ itself, you can use the
textconv filter of Git, together with antiword (or catdoc, which does
the same thing, but I think antiword works better).
See this:
http://git.or.cz/gitwiki/GitTips#HowtousegittotrackOpenDocument.28OpenOffice.2CKoffice.29files.3F
and adapt by replacing "OpenOffice" with MS Word, and odt2txt with
antiword.
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: [BUG] Bad msysgit/egit interaction over dotfiles
From: Yann Dirson @ 2009-12-10 8:35 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: kusmabite, Ferry Huberts, GIT ml
In-Reply-To: <4B200EF5.2060606@gmail.com>
On Wed, Dec 09, 2009 at 09:56:21PM +0100, Marius Storm-Olsen wrote:
> Yann Dirson said the following on 08.12.2009 15:37:
> >On Tue, Dec 08, 2009 at 03:23:55PM +0100, Erik Faye-Lund wrote:
> >>You can follow the discussion here:
> >>http://code.google.com/p/msysgit/issues/detail?id=288
> >>
> >>I believe the reason is something like "because someone suggested
> >>it, and no one disagreed". Do you have a good argument why it
> >>shouldn't be the default (other than "it's a change", because
> >>changing it back now would also be a change)?
> >
> >Depending on the opinion of the Eclipse guys on this issue about
> >"writing to hidden files only says 'could not write'", which
> >arguably could be seen as a bug on their side, we can see changing
> >this behaviour back to the default on the msysgit side as either a
> >(possibly temporary) workaround for a known eclipse bug, or as
> >getting again interoperable with egit.
>
> Dot-files on unix are considered hidden. It's the only way files are
> hidden there. Not so on Windows. Dot-files are just like any normal
> file, and you need to mark a file hidden.
>
> So, the logic of egit, that *actually* hidden files should not be
> written to, but dot-files should, seems to me to be a bug in egit.
> There should be no reason why egit shouldn't be able to write to any
> file, pending permissions. I'd say file a bug report with egit.
Actually it is not egit who is unable to write to the file, but
eclipse itself, and I do tend to think it is a bug in eclipse. But
now, even if we can convince the eclipse guys that it is a bug, it
will be some time before a new release with this bug fixed gets
published.
So IMHO it would makes sense, for the sake of usability, to not
activate the "hide dotfiles" feature by default. It is easier for
someone seeing unwanted dotfiles to find the switch to hide them, than
for someone getting a "could not write" message from eclipse to
understand that there is a seemingly-unrelate switch for msysgit to
avoid this situation.
But maybe the situation is not so clear. That "hide dotfiles" was
implemented so that ".git" at first, and then ".git*" files do not
clutter the view of the project. But then, if a git repo has other
dotfiles, those are really *part of* the versionned stuff, so I do not
see why those should be hidden at all. After all, the .project,
.classpath, and other eclipse project files have that name on windows
too, and it will indeed *confuse* people to get them hidden.
So should we have 2 classes of dotfiles, those "private to git", and
the others, one class being hidden while the others are not ? I am
not sure at all this would be a good idea either. Or maybe we should
only get .git hidden - after all, that one is the only real metadata
not part of the versionned stuff itself ?
Maybe we should add some sort of "core.hidedotfiles = dotgitonly"
setting, and make that the default ? That one does not appear to
cause any problems to jgit, and eclipse itself has not business with
it, so it would IMHO make sense.
Opinions ?
^ permalink raw reply
* Re: [BUG] Bad msysgit/egit interaction over dotfiles
From: Erik Faye-Lund @ 2009-12-14 9:13 UTC (permalink / raw)
To: Yann Dirson; +Cc: Marius Storm-Olsen, Ferry Huberts, GIT ml
In-Reply-To: <20091210083514.GA5971@linagora.com>
On Thu, Dec 10, 2009 at 9:35 AM, Yann Dirson <ydirson@linagora.com> wrote:
> On Wed, Dec 09, 2009 at 09:56:21PM +0100, Marius Storm-Olsen wrote:
>> Yann Dirson said the following on 08.12.2009 15:37:
>> >On Tue, Dec 08, 2009 at 03:23:55PM +0100, Erik Faye-Lund wrote:
>> >>You can follow the discussion here:
>> >>http://code.google.com/p/msysgit/issues/detail?id=288
>> >>
>> >>I believe the reason is something like "because someone suggested
>> >>it, and no one disagreed". Do you have a good argument why it
>> >>shouldn't be the default (other than "it's a change", because
>> >>changing it back now would also be a change)?
>> >
>> >Depending on the opinion of the Eclipse guys on this issue about
>> >"writing to hidden files only says 'could not write'", which
>> >arguably could be seen as a bug on their side, we can see changing
>> >this behaviour back to the default on the msysgit side as either a
>> >(possibly temporary) workaround for a known eclipse bug, or as
>> >getting again interoperable with egit.
>>
>> Dot-files on unix are considered hidden. It's the only way files are
>> hidden there. Not so on Windows. Dot-files are just like any normal
>> file, and you need to mark a file hidden.
>>
>> So, the logic of egit, that *actually* hidden files should not be
>> written to, but dot-files should, seems to me to be a bug in egit.
>> There should be no reason why egit shouldn't be able to write to any
>> file, pending permissions. I'd say file a bug report with egit.
>
> Actually it is not egit who is unable to write to the file, but
> eclipse itself, and I do tend to think it is a bug in eclipse. But
> now, even if we can convince the eclipse guys that it is a bug, it
> will be some time before a new release with this bug fixed gets
> published.
>
> So IMHO it would makes sense, for the sake of usability, to not
> activate the "hide dotfiles" feature by default. It is easier for
> someone seeing unwanted dotfiles to find the switch to hide them, than
> for someone getting a "could not write" message from eclipse to
> understand that there is a seemingly-unrelate switch for msysgit to
> avoid this situation.
>
Actually, I think it makes much more sense to put a note of the issue
in the release-notes. I don't want people to lose features because
Eclipse, an IDE I don't even use, is broken. Since Eclipse is the
culprit here, I think it's the Eclipse that should "take the hit", not
the rest of us.
This of course assumes that hidden dotfiles is a feature that people
want, which is what I assumed was the reason why it was added in the
first place. Personally I don't care about this feature, since I have
the "show hidden files"-feature turned on.
> But maybe the situation is not so clear. That "hide dotfiles" was
> implemented so that ".git" at first, and then ".git*" files do not
> clutter the view of the project. But then, if a git repo has other
> dotfiles, those are really *part of* the versionned stuff, so I do not
> see why those should be hidden at all. After all, the .project,
> .classpath, and other eclipse project files have that name on windows
> too, and it will indeed *confuse* people to get them hidden.
>
> So should we have 2 classes of dotfiles, those "private to git", and
> the others, one class being hidden while the others are not ? I am
> not sure at all this would be a good idea either. Or maybe we should
> only get .git hidden - after all, that one is the only real metadata
> not part of the versionned stuff itself ?
>
> Maybe we should add some sort of "core.hidedotfiles = dotgitonly"
> setting, and make that the default ? That one does not appear to
> cause any problems to jgit, and eclipse itself has not business with
> it, so it would IMHO make sense.
>
> Opinions ?
>
IF we were to go down this path, perhaps it would be even better to
use some sort of file-pattern or even squeeze this into gitattributes?
I guess something like ".* +hidden" should emulate the unix behaviour
(given that we add a hidden attribute). I don't think we have a global
gitattributes file though, so it'd have to be added to each repo where
the effect is desired, I guess.
--
Erik "kusma" Faye-Lund
^ permalink raw reply
* [PATCH 00/23] nd/sparse reroll
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy
Compared to the current series in pu, patch "Teach Git to respect
skip-worktree (reading part)" has been broken up into smaller patches.
builtin-commit.c is also fixed to make the two failed test cases in
t7011 now pass. Skip-worktree bit no longer relies on
CE_MATCH_IGNORE_VALID flag, which means
"git update-index --really-refresh" respects skip-worktree bit too.
The rest is unchanged.
Nguyễn Thái Ngọc Duy (23):
update-index: refactor mark_valid() in preparation for new options
Add test-index-version
Introduce "skip-worktree" bit in index, teach Git to get/set this bit
update-index: ignore update request if it's skip-worktree
Teach ls-files and update-index to respect skip-worktree bit
Teach diff machinery to respect skip-worktree bit
Teach grep to respect skip-worktree bit
Teach commit to respect skip-worktree bit
Teach Git to respect skip-worktree bit (writing part)
Avoid writing to buffer in add_excludes_from_file_1()
Read .gitignore from index if it is skip-worktree
unpack-trees(): carry skip-worktree bit over in merged_entry()
excluded_1(): support exclude files in index
dir.c: export excluded_1() and add_excludes_from_file_1()
Introduce "sparse checkout"
unpack-trees(): add CE_WT_REMOVE to remove on worktree alone
unpack-trees.c: generalize verify_* functions
unpack-trees(): "enable" sparse checkout and load
$GIT_DIR/info/sparse-checkout
unpack_trees(): apply $GIT_DIR/info/sparse-checkout to the final
index
unpack-trees(): ignore worktree check outside checkout area
read-tree: add --no-sparse-checkout to disable sparse checkout
support
Add tests for sparse checkout
sparse checkout: inhibit empty worktree
.gitignore | 1 +
Documentation/config.txt | 4 +
Documentation/git-ls-files.txt | 1 +
Documentation/git-read-tree.txt | 52 ++++++-
Documentation/git-update-index.txt | 29 ++++
Documentation/technical/api-directory-listing.txt | 3 +
Makefile | 1 +
builtin-apply.c | 2 +-
builtin-clean.c | 4 +-
builtin-commit.c | 11 +-
builtin-grep.c | 2 +-
builtin-ls-files.c | 11 +-
builtin-read-tree.c | 4 +-
builtin-update-index.c | 78 ++++++----
cache.h | 10 +-
config.c | 5 +
diff-lib.c | 5 +-
diff.c | 2 +-
dir.c | 100 ++++++++----
dir.h | 4 +
entry.c | 2 +-
environment.c | 1 +
read-cache.c | 17 ++-
t/t1011-read-tree-sparse-checkout.sh | 150 +++++++++++++++++
t/t2104-update-index-skip-worktree.sh | 57 +++++++
t/t3001-ls-files-others-exclude.sh | 22 +++
t/t7011-skip-worktree-reading.sh | 158 ++++++++++++++++++
t/t7012-skip-worktree-writing.sh | 139 ++++++++++++++++
t/t7300-clean.sh | 19 +++
test-index-version.c | 14 ++
unpack-trees.c | 181 +++++++++++++++++++--
unpack-trees.h | 6 +
32 files changed, 994 insertions(+), 101 deletions(-)
create mode 100755 t/t1011-read-tree-sparse-checkout.sh
create mode 100755 t/t2104-update-index-skip-worktree.sh
create mode 100755 t/t7011-skip-worktree-reading.sh
create mode 100755 t/t7012-skip-worktree-writing.sh
create mode 100644 test-index-version.c
^ permalink raw reply
* [PATCH 05/23] Teach ls-files and update-index to respect skip-worktree bit
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-ls-files.c | 2 +
builtin-update-index.c | 38 +++++++-----
t/t7011-skip-worktree-reading.sh | 114 ++++++++++++++++++++++++++++++++++++++
3 files changed, 138 insertions(+), 16 deletions(-)
create mode 100755 t/t7011-skip-worktree-reading.sh
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index c1afbad..ad7e447 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -194,6 +194,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
continue;
if (ce->ce_flags & CE_UPDATE)
continue;
+ if (ce_skip_worktree(ce))
+ continue;
err = lstat(ce->name, &st);
if (show_deleted && err)
show_ce_entry(tag_removed, ce);
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 5e97d09..97b9ea6 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -172,29 +172,29 @@ static int process_directory(const char *path, int len, struct stat *st)
return error("%s: is a directory - add files inside instead", path);
}
-/*
- * Process a regular file
- */
-static int process_file(const char *path, int len, struct stat *st)
-{
- int pos = cache_name_pos(path, len);
- struct cache_entry *ce = pos < 0 ? NULL : active_cache[pos];
-
- if (ce && S_ISGITLINK(ce->ce_mode))
- return error("%s is already a gitlink, not replacing", path);
-
- return add_one_path(ce, path, len, st);
-}
-
static int process_path(const char *path)
{
- int len;
+ int pos, len;
struct stat st;
+ struct cache_entry *ce;
len = strlen(path);
if (has_symlink_leading_path(path, len))
return error("'%s' is beyond a symbolic link", path);
+ pos = cache_name_pos(path, len);
+ ce = pos < 0 ? NULL : active_cache[pos];
+ if (ce && ce_skip_worktree(ce)) {
+ /*
+ * working directory version is assumed "good"
+ * so updating it does not make sense.
+ * On the other hand, removing it from index should work
+ */
+ if (allow_remove && remove_file_from_cache(path))
+ return error("%s: cannot remove from the index", path);
+ return 0;
+ }
+
/*
* First things first: get the stat information, to decide
* what to do about the pathname!
@@ -205,7 +205,13 @@ static int process_path(const char *path)
if (S_ISDIR(st.st_mode))
return process_directory(path, len, &st);
- return process_file(path, len, &st);
+ /*
+ * Process a regular file
+ */
+ if (ce && S_ISGITLINK(ce->ce_mode))
+ return error("%s is already a gitlink, not replacing", path);
+
+ return add_one_path(ce, path, len, &st);
}
static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh
new file mode 100755
index 0000000..ede3ee1
--- /dev/null
+++ b/t/t7011-skip-worktree-reading.sh
@@ -0,0 +1,114 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
+#
+
+test_description='skip-worktree bit test'
+
+. ./test-lib.sh
+
+cat >expect.full <<EOF
+H 1
+H 2
+H init.t
+H sub/1
+H sub/2
+EOF
+
+cat >expect.skip <<EOF
+S 1
+H 2
+H init.t
+S sub/1
+H sub/2
+EOF
+
+NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+ZERO_SHA1=0000000000000000000000000000000000000000
+setup_absent() {
+ test -f 1 && rm 1
+ git update-index --remove 1 &&
+ git update-index --add --cacheinfo 100644 $NULL_SHA1 1 &&
+ git update-index --skip-worktree 1
+}
+
+test_absent() {
+ echo "100644 $NULL_SHA1 0 1" > expected &&
+ git ls-files --stage 1 > result &&
+ test_cmp expected result &&
+ test ! -f 1
+}
+
+setup_dirty() {
+ git update-index --force-remove 1 &&
+ echo dirty > 1 &&
+ git update-index --add --cacheinfo 100644 $NULL_SHA1 1 &&
+ git update-index --skip-worktree 1
+}
+
+test_dirty() {
+ echo "100644 $NULL_SHA1 0 1" > expected &&
+ git ls-files --stage 1 > result &&
+ test_cmp expected result &&
+ echo dirty > expected
+ test_cmp expected 1
+}
+
+test_expect_success 'setup' '
+ test_commit init &&
+ mkdir sub &&
+ touch ./1 ./2 sub/1 sub/2 &&
+ git add 1 2 sub/1 sub/2 &&
+ git update-index --skip-worktree 1 sub/1 &&
+ git ls-files -t > result &&
+ test_cmp expect.skip result
+'
+
+test_expect_success 'update-index' '
+ setup_absent &&
+ git update-index 1 &&
+ test_absent
+'
+
+test_expect_success 'update-index' '
+ setup_dirty &&
+ git update-index 1 &&
+ test_dirty
+'
+
+test_expect_success 'update-index --remove' '
+ setup_absent &&
+ git update-index --remove 1 &&
+ test -z "$(git ls-files 1)" &&
+ test ! -f 1
+'
+
+test_expect_success 'update-index --remove' '
+ setup_dirty &&
+ git update-index --remove 1 &&
+ test -z "$(git ls-files 1)" &&
+ echo dirty > expected &&
+ test_cmp expected 1
+'
+
+test_expect_success 'ls-files --delete' '
+ setup_absent &&
+ test -z "$(git ls-files -d)"
+'
+
+test_expect_success 'ls-files --delete' '
+ setup_dirty &&
+ test -z "$(git ls-files -d)"
+'
+
+test_expect_success 'ls-files --modified' '
+ setup_absent &&
+ test -z "$(git ls-files -m)"
+'
+
+test_expect_success 'ls-files --modified' '
+ setup_dirty &&
+ test -z "$(git ls-files -m)"
+'
+
+test_done
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 09/23] Teach Git to respect skip-worktree bit (writing part)
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
This part is mainly to remove CE_VALID shortcuts (and as a
consequence, ce_uptodate() shortcuts as it may be turned on by
CE_VALID) in writing code path if skip-worktree is used. Various tests
are added to avoid future breakages.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
t/t7012-skip-worktree-writing.sh | 139 ++++++++++++++++++++++++++++++++++++++
unpack-trees.c | 4 +-
2 files changed, 141 insertions(+), 2 deletions(-)
create mode 100755 t/t7012-skip-worktree-writing.sh
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
new file mode 100755
index 0000000..c75efe4
--- /dev/null
+++ b/t/t7012-skip-worktree-writing.sh
@@ -0,0 +1,139 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
+#
+
+test_description='test worktree writing operations when skip-worktree is used'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit init &&
+ echo modified >> init.t &&
+ touch added &&
+ git add init.t added &&
+ git commit -m "modified and added" &&
+ git tag top
+'
+
+test_expect_success 'read-tree updates worktree, absent case' '
+ git checkout -f top &&
+ git update-index --skip-worktree init.t &&
+ rm init.t &&
+ git read-tree -m -u HEAD^ &&
+ echo init > expected &&
+ test_cmp expected init.t
+'
+
+test_expect_success 'read-tree updates worktree, dirty case' '
+ git checkout -f top &&
+ git update-index --skip-worktree init.t &&
+ echo dirty >> init.t &&
+ test_must_fail git read-tree -m -u HEAD^ &&
+ grep -q dirty init.t &&
+ test "$(git ls-files -t init.t)" = "S init.t" &&
+ git update-index --no-skip-worktree init.t
+'
+
+test_expect_success 'read-tree removes worktree, absent case' '
+ git checkout -f top &&
+ git update-index --skip-worktree added &&
+ rm added &&
+ git read-tree -m -u HEAD^ &&
+ test ! -f added
+'
+
+test_expect_success 'read-tree removes worktree, dirty case' '
+ git checkout -f top &&
+ git update-index --skip-worktree added &&
+ echo dirty >> added &&
+ test_must_fail git read-tree -m -u HEAD^ &&
+ grep -q dirty added &&
+ test "$(git ls-files -t added)" = "S added" &&
+ git update-index --no-skip-worktree added
+'
+
+NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+ZERO_SHA0=0000000000000000000000000000000000000000
+setup_absent() {
+ test -f 1 && rm 1
+ git update-index --remove 1 &&
+ git update-index --add --cacheinfo 100644 $NULL_SHA1 1 &&
+ git update-index --skip-worktree 1
+}
+
+test_absent() {
+ echo "100644 $NULL_SHA1 0 1" > expected &&
+ git ls-files --stage 1 > result &&
+ test_cmp expected result &&
+ test ! -f 1
+}
+
+setup_dirty() {
+ git update-index --force-remove 1 &&
+ echo dirty > 1 &&
+ git update-index --add --cacheinfo 100644 $NULL_SHA1 1 &&
+ git update-index --skip-worktree 1
+}
+
+test_dirty() {
+ echo "100644 $NULL_SHA1 0 1" > expected &&
+ git ls-files --stage 1 > result &&
+ test_cmp expected result &&
+ echo dirty > expected
+ test_cmp expected 1
+}
+
+cat >expected <<EOF
+S 1
+H 2
+H init.t
+S sub/1
+H sub/2
+EOF
+
+test_expect_success 'index setup' '
+ git checkout -f init &&
+ mkdir sub &&
+ touch ./1 ./2 sub/1 sub/2 &&
+ git add 1 2 sub/1 sub/2 &&
+ git update-index --skip-worktree 1 sub/1 &&
+ git ls-files -t > result &&
+ test_cmp expected result
+'
+
+test_expect_success 'git-add ignores worktree content' '
+ setup_absent &&
+ git add 1 &&
+ test_absent
+'
+
+test_expect_success 'git-add ignores worktree content' '
+ setup_dirty &&
+ git add 1 &&
+ test_dirty
+'
+
+test_expect_success 'git-rm fails if worktree is dirty' '
+ setup_dirty &&
+ test_must_fail git rm 1 &&
+ test_dirty
+'
+
+cat >expected <<EOF
+Would remove expected
+Would remove result
+EOF
+test_expect_success 'git-clean, absent case' '
+ setup_absent &&
+ git clean -n > result &&
+ test_cmp expected result
+'
+
+test_expect_success 'git-clean, dirty case' '
+ setup_dirty &&
+ git clean -n > result &&
+ test_cmp expected result
+'
+
+test_done
diff --git a/unpack-trees.c b/unpack-trees.c
index 4870da9..1ab3c89 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -450,7 +450,7 @@ static int verify_uptodate(struct cache_entry *ce,
{
struct stat st;
- if (o->index_only || o->reset || ce_uptodate(ce))
+ if (o->index_only || (!ce_skip_worktree(ce) && (o->reset || ce_uptodate(ce))))
return 0;
if (!lstat(ce->name, &st)) {
@@ -1004,7 +1004,7 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
if (old && same(old, a)) {
int update = 0;
- if (o->reset && !ce_uptodate(old)) {
+ if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) {
struct stat st;
if (lstat(old->name, &st) ||
ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE))
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 10/23] Avoid writing to buffer in add_excludes_from_file_1()
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
In the next patch, the buffer that is being used within
add_excludes_from_file_1() comes from another function and does not
have extra space to put \n at the end.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
dir.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/dir.c b/dir.c
index e05b850..1170d64 100644
--- a/dir.c
+++ b/dir.c
@@ -229,10 +229,9 @@ static int add_excludes_from_file_1(const char *fname,
if (buf_p)
*buf_p = buf;
- buf[size++] = '\n';
entry = buf;
- for (i = 0; i < size; i++) {
- if (buf[i] == '\n') {
+ for (i = 0; i <= size; i++) {
+ if (i == size || buf[i] == '\n') {
if (entry != buf + i && entry[0] != '#') {
buf[i - (i && buf[i-1] == '\r')] = 0;
add_exclude(entry, base, baselen, which);
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 12/23] unpack-trees(): carry skip-worktree bit over in merged_entry()
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
In this code path, we would remove "old" and replace it with "merge".
"old" may have skip-worktree bit, so re-add it to "merge".
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
unpack-trees.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index 1ab3c89..ac59fbe 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -680,6 +680,8 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
} else {
if (verify_uptodate(old, o))
return -1;
+ if (ce_skip_worktree(old))
+ update |= CE_SKIP_WORKTREE;
invalidate_ce_path(old, o);
}
}
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 11/23] Read .gitignore from index if it is skip-worktree
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
This adds index as a prerequisite for directory listing (with
exclude). At the moment directory listing is used by "git clean",
"git add", "git ls-files" and "git status"/"git commit" and
unpack_trees()-related commands. These commands have been
checked/modified to populate index before doing directory listing.
add_excludes_from_file() does not enable this feature, because it
is used to read .git/info/exclude and some explicit files specified
by "git ls-files".
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/technical/api-directory-listing.txt | 3 +
builtin-clean.c | 4 +-
builtin-ls-files.c | 4 +-
dir.c | 65 ++++++++++++++------
t/t3001-ls-files-others-exclude.sh | 22 +++++++
t/t7300-clean.sh | 19 ++++++
6 files changed, 95 insertions(+), 22 deletions(-)
diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt
index 5bbd18f..add6f43 100644
--- a/Documentation/technical/api-directory-listing.txt
+++ b/Documentation/technical/api-directory-listing.txt
@@ -58,6 +58,9 @@ The result of the enumeration is left in these fields::
Calling sequence
----------------
+Note: index may be looked at for .gitignore files that are CE_SKIP_WORKTREE
+marked. If you to exclude files, make sure you have loaded index first.
+
* Prepare `struct dir_struct dir` and clear it with `memset(&dir, 0,
sizeof(dir))`.
diff --git a/builtin-clean.c b/builtin-clean.c
index 2d8c735..e424b77 100644
--- a/builtin-clean.c
+++ b/builtin-clean.c
@@ -71,11 +71,13 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
+ if (read_cache() < 0)
+ die("index file corrupt");
+
if (!ignored)
setup_standard_excludes(&dir);
pathspec = get_pathspec(prefix, argv);
- read_cache();
fill_directory(&dir, pathspec);
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index ad7e447..2e47242 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -485,6 +485,9 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
prefix_offset = strlen(prefix);
git_config(git_default_config, NULL);
+ if (read_cache() < 0)
+ die("index file corrupt");
+
argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
ls_files_usage, 0);
if (show_tag || show_valid_bit) {
@@ -513,7 +516,6 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
pathspec = get_pathspec(prefix, argv);
/* be nice with submodule paths ending in a slash */
- read_cache();
if (pathspec)
strip_trailing_slash_from_submodules();
diff --git a/dir.c b/dir.c
index 1170d64..e8e5b79 100644
--- a/dir.c
+++ b/dir.c
@@ -200,11 +200,35 @@ void add_exclude(const char *string, const char *base,
which->excludes[which->nr++] = x;
}
+static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
+{
+ int pos, len;
+ unsigned long sz;
+ enum object_type type;
+ void *data;
+ struct index_state *istate = &the_index;
+
+ len = strlen(path);
+ pos = index_name_pos(istate, path, len);
+ if (pos < 0)
+ return NULL;
+ if (!ce_skip_worktree(istate->cache[pos]))
+ return NULL;
+ data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
+ if (!data || type != OBJ_BLOB) {
+ free(data);
+ return NULL;
+ }
+ *size = xsize_t(sz);
+ return data;
+}
+
static int add_excludes_from_file_1(const char *fname,
const char *base,
int baselen,
char **buf_p,
- struct exclude_list *which)
+ struct exclude_list *which,
+ int check_index)
{
struct stat st;
int fd, i;
@@ -212,20 +236,26 @@ static int add_excludes_from_file_1(const char *fname,
char *buf, *entry;
fd = open(fname, O_RDONLY);
- if (fd < 0 || fstat(fd, &st) < 0)
- goto err;
- size = xsize_t(st.st_size);
- if (size == 0) {
- close(fd);
- return 0;
+ if (fd < 0 || fstat(fd, &st) < 0) {
+ if (0 <= fd)
+ close(fd);
+ if (!check_index ||
+ (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL)
+ return -1;
}
- buf = xmalloc(size+1);
- if (read_in_full(fd, buf, size) != size)
- {
- free(buf);
- goto err;
+ else {
+ size = xsize_t(st.st_size);
+ if (size == 0) {
+ close(fd);
+ return 0;
+ }
+ buf = xmalloc(size);
+ if (read_in_full(fd, buf, size) != size) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
}
- close(fd);
if (buf_p)
*buf_p = buf;
@@ -240,17 +270,12 @@ static int add_excludes_from_file_1(const char *fname,
}
}
return 0;
-
- err:
- if (0 <= fd)
- close(fd);
- return -1;
}
void add_excludes_from_file(struct dir_struct *dir, const char *fname)
{
if (add_excludes_from_file_1(fname, "", 0, NULL,
- &dir->exclude_list[EXC_FILE]) < 0)
+ &dir->exclude_list[EXC_FILE], 0) < 0)
die("cannot use %s as an exclude file", fname);
}
@@ -301,7 +326,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
add_excludes_from_file_1(dir->basebuf,
dir->basebuf, stk->baselen,
- &stk->filebuf, el);
+ &stk->filebuf, el, 1);
dir->exclude_stack = stk;
current = stk->baselen;
}
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index c65bca8..132c476 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -64,6 +64,8 @@ two/*.4
echo '!*.2
!*.8' >one/two/.gitignore
+allignores='.gitignore one/.gitignore one/two/.gitignore'
+
test_expect_success \
'git ls-files --others with various exclude options.' \
'git ls-files --others \
@@ -85,6 +87,26 @@ test_expect_success \
>output &&
test_cmp expect output'
+test_expect_success 'setup skip-worktree gitignore' '
+ git add $allignores &&
+ git update-index --skip-worktree $allignores &&
+ rm $allignores
+'
+
+test_expect_success \
+ 'git ls-files --others with various exclude options.' \
+ 'git ls-files --others \
+ --exclude=\*.6 \
+ --exclude-per-directory=.gitignore \
+ --exclude-from=.git/ignore \
+ >output &&
+ test_cmp expect output'
+
+test_expect_success 'restore gitignore' '
+ git checkout $allignores &&
+ rm .git/index
+'
+
cat > excludes-file <<\EOF
*.[1-8]
e*
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 929d5d4..8073d02 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -22,6 +22,25 @@ test_expect_success 'setup' '
'
+test_expect_success 'git clean with skip-worktree .gitignore' '
+ git update-index --skip-worktree .gitignore &&
+ rm .gitignore &&
+ mkdir -p build docs &&
+ touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
+ git clean &&
+ test -f Makefile &&
+ test -f README &&
+ test -f src/part1.c &&
+ test -f src/part2.c &&
+ test ! -f a.out &&
+ test ! -f src/part3.c &&
+ test -f docs/manual.txt &&
+ test -f obj.o &&
+ test -f build/lib.so &&
+ git update-index --no-skip-worktree .gitignore &&
+ git checkout .gitignore
+'
+
test_expect_success 'git clean' '
mkdir -p build docs &&
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 08/23] Teach commit to respect skip-worktree bit
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
There is nothing much to do when the index is committed as-is. But
when partial commit is used, the index will be reset to HEAD. This
leads to loss of skip-worktree bits in the original index. Those bits
are kept (for committed paths only) so git-commit will know which
paths to ignore later on.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-commit.c | 11 +++++++++--
t/t7011-skip-worktree-reading.sh | 12 ++++++++++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/builtin-commit.c b/builtin-commit.c
index 4bcce06..9fe5c25 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -152,7 +152,7 @@ static int commit_index_files(void)
static int list_paths(struct string_list *list, const char *with_tree,
const char *prefix, const char **pattern)
{
- int i;
+ static int i;
char *m;
for (i = 0; pattern[i]; i++)
@@ -164,11 +164,15 @@ static int list_paths(struct string_list *list, const char *with_tree,
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
+ struct string_list_item *item;
+
if (ce->ce_flags & CE_UPDATE)
continue;
if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
continue;
- string_list_insert(ce->name, list);
+ item = string_list_insert(ce->name, list);
+ if (ce_skip_worktree(ce))
+ item->util = &i; /* better a valid pointer than a fake one */
}
return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
@@ -181,6 +185,9 @@ static void add_remove_files(struct string_list *list)
struct stat st;
struct string_list_item *p = &(list->items[i]);
+ if (p->util)
+ continue;
+
if (!lstat(p->string, &st)) {
if (add_to_cache(p->string, &st, 0))
die("updating files failed");
diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh
index 2ec677a..5cf2cb8 100755
--- a/t/t7011-skip-worktree-reading.sh
+++ b/t/t7011-skip-worktree-reading.sh
@@ -143,4 +143,16 @@ test_expect_success 'diff-files does not examine skip-worktree dirty entries' '
test -z "$(git diff-files -- one)"
'
+test_expect_success 'commit on skip-worktree absent entries' '
+ git reset &&
+ setup_absent &&
+ test_must_fail git commit -m null 1
+'
+
+test_expect_success 'commit on skip-worktree dirty entries' '
+ git reset &&
+ setup_dirty &&
+ test_must_fail git commit -m null 1
+'
+
test_done
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 07/23] Teach grep to respect skip-worktree bit
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-grep.c | 2 +-
t/t7011-skip-worktree-reading.sh | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/builtin-grep.c b/builtin-grep.c
index ad0e0a5..813fe97 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -517,7 +517,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached,
* are identical, even if worktree file has been modified, so use
* cache version instead
*/
- if (cached || (ce->ce_flags & CE_VALID)) {
+ if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) {
if (ce_stage(ce))
continue;
hit |= grep_sha1(opt, ce->sha1, ce->name, 0);
diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh
index 5db93d0..2ec677a 100755
--- a/t/t7011-skip-worktree-reading.sh
+++ b/t/t7011-skip-worktree-reading.sh
@@ -111,6 +111,15 @@ test_expect_success 'ls-files --modified' '
test -z "$(git ls-files -m)"
'
+test_expect_success 'grep with skip-worktree file' '
+ git update-index --no-skip-worktree 1 &&
+ echo test > 1 &&
+ git update-index 1 &&
+ git update-index --skip-worktree 1 &&
+ rm 1 &&
+ test "$(git grep --no-ext-grep test)" = "1:test"
+'
+
echo ":000000 100644 $ZERO_SHA1 $NULL_SHA1 A 1" > expected
test_expect_success 'diff-index does not examine skip-worktree absent entries' '
setup_absent &&
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 13/23] excluded_1(): support exclude files in index
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Index does not really have "directories", attempts to match "foo/"
against index will fail unless someone tries to reconstruct directories
from a list of file.
Observing that dtype in this function can never be NULL (otherwise
it would segfault), dtype NULL will be used to say "hey.. you are
matching against index" and behave properly.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
dir.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/dir.c b/dir.c
index e8e5b79..7735cea 100644
--- a/dir.c
+++ b/dir.c
@@ -349,6 +349,12 @@ static int excluded_1(const char *pathname,
int to_exclude = x->to_exclude;
if (x->flags & EXC_FLAG_MUSTBEDIR) {
+ if (!dtype) {
+ if (!prefixcmp(pathname, exclude))
+ return to_exclude;
+ else
+ continue;
+ }
if (*dtype == DT_UNKNOWN)
*dtype = get_dtype(NULL, pathname, pathlen);
if (*dtype != DT_DIR)
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 15/23] Introduce "sparse checkout"
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
With skip-worktree bit, you can manually set it to unwanted files,
then remove them: you would have the so-called sparse checkout. The
disadvantages are:
- Porcelain tools are not aware of this. Everytime you do an
operation that may update working directory, skip-worktree may be
cleared out. You have to set them again.
- You still have to remove skip-worktree'd files manually, which is
boring and ineffective.
These will be addressed in the following patches. This patch gives an
idea what is "sparse checkout" in Documentation/git-read-tree.txt.
This file is chosen instead of git-checkout.txt because it is quite
technical and user-unfriendly. I'd expect git-checkout.txt to have
something when Porcelain support is done.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/git-read-tree.txt | 44 +++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 4a932b0..8b39716 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -360,6 +360,50 @@ middle of doing, and when your working tree is ready (i.e. you
have finished your work-in-progress), attempt the merge again.
+Sparse checkout
+---------------
+
+"Sparse checkout" allows to sparsely populate working directory.
+It uses skip-worktree bit (see linkgit:git-update-index[1]) to tell
+Git whether a file on working directory is worth looking at.
+
+"git read-tree" and other merge-based commands ("git merge", "git
+checkout"...) can help maintaining skip-worktree bitmap and working
+directory update. `$GIT_DIR/info/sparse-checkout` is used to
+define the skip-worktree reference bitmap. When "git read-tree" needs
+to update working directory, it will reset skip-worktree bit in index
+based on this file, which uses the same syntax as .gitignore files.
+If an entry matches a pattern in this file, skip-worktree will be
+set on that entry. Otherwise, skip-worktree will be unset.
+
+Then it compares the new skip-worktree value with the previous one. If
+skip-worktree turns from unset to set, it will add the corresponding
+file back. If it turns from set to unset, that file will be removed.
+
+While `$GIT_DIR/info/sparse-checkout` is usually used to specify what
+files are in. You can also specify what files are _not_ in, using
+negate patterns. For example, to remove file "unwanted":
+
+----------------
+*
+!unwanted
+----------------
+
+Another tricky thing is fully repopulating working directory when you
+no longer want sparse checkout. You cannot just disable "sparse
+checkout" because skip-worktree are still in the index and you working
+directory is still sparsely populated. You should re-populate working
+directory with the `$GIT_DIR/info/sparse-checkout` file content as
+follows:
+
+----------------
+*
+----------------
+
+Then you can disable sparse checkout. Sparse checkout support in "git
+read-tree" and similar commands is disabled by default.
+
+
SEE ALSO
--------
linkgit:git-write-tree[1]; linkgit:git-ls-files[1];
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 16/23] unpack-trees(): add CE_WT_REMOVE to remove on worktree alone
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
CE_REMOVE now removes both worktree and index versions. Sparse
checkout must be able to remove worktree version while keep the
index intact when checkout area is narrowed.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
cache.h | 3 +++
unpack-trees.c | 9 ++++++++-
2 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/cache.h b/cache.h
index f040f24..3a37469 100644
--- a/cache.h
+++ b/cache.h
@@ -177,6 +177,9 @@ struct cache_entry {
#define CE_HASHED (0x100000)
#define CE_UNHASHED (0x200000)
+/* Only remove in work directory, not index */
+#define CE_WT_REMOVE (0x400000)
+
/*
* Extended on-disk flags
*/
diff --git a/unpack-trees.c b/unpack-trees.c
index ac59fbe..eb1a818 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -78,7 +78,7 @@ 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_UPDATE | CE_REMOVE))
+ if (ce->ce_flags & (CE_UPDATE | CE_REMOVE | CE_WT_REMOVE))
total++;
}
@@ -92,6 +92,13 @@ 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_WT_REMOVE) {
+ display_progress(progress, ++cnt);
+ if (o->update)
+ unlink_entry(ce);
+ continue;
+ }
+
if (ce->ce_flags & CE_REMOVE) {
display_progress(progress, ++cnt);
if (o->update)
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 14/23] dir.c: export excluded_1() and add_excludes_from_file_1()
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
These functions are used to handle .gitignore. They are now exported
so that sparse checkout can reuse.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
dir.c | 32 ++++++++++++++++----------------
dir.h | 4 ++++
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/dir.c b/dir.c
index 7735cea..6b1c478 100644
--- a/dir.c
+++ b/dir.c
@@ -223,12 +223,12 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
return data;
}
-static int add_excludes_from_file_1(const char *fname,
- const char *base,
- int baselen,
- char **buf_p,
- struct exclude_list *which,
- int check_index)
+int add_excludes_from_file_to_list(const char *fname,
+ const char *base,
+ int baselen,
+ char **buf_p,
+ struct exclude_list *which,
+ int check_index)
{
struct stat st;
int fd, i;
@@ -274,8 +274,8 @@ static int add_excludes_from_file_1(const char *fname,
void add_excludes_from_file(struct dir_struct *dir, const char *fname)
{
- if (add_excludes_from_file_1(fname, "", 0, NULL,
- &dir->exclude_list[EXC_FILE], 0) < 0)
+ if (add_excludes_from_file_to_list(fname, "", 0, NULL,
+ &dir->exclude_list[EXC_FILE], 0) < 0)
die("cannot use %s as an exclude file", fname);
}
@@ -324,9 +324,9 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
memcpy(dir->basebuf + current, base + current,
stk->baselen - current);
strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
- add_excludes_from_file_1(dir->basebuf,
- dir->basebuf, stk->baselen,
- &stk->filebuf, el, 1);
+ add_excludes_from_file_to_list(dir->basebuf,
+ dir->basebuf, stk->baselen,
+ &stk->filebuf, el, 1);
dir->exclude_stack = stk;
current = stk->baselen;
}
@@ -336,9 +336,9 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
/* Scan the list and let the last match determine the fate.
* Return 1 for exclude, 0 for include and -1 for undecided.
*/
-static int excluded_1(const char *pathname,
- int pathlen, const char *basename, int *dtype,
- struct exclude_list *el)
+int excluded_from_list(const char *pathname,
+ int pathlen, const char *basename, int *dtype,
+ struct exclude_list *el)
{
int i;
@@ -412,8 +412,8 @@ int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
prep_exclude(dir, pathname, basename-pathname);
for (st = EXC_CMDL; st <= EXC_FILE; st++) {
- switch (excluded_1(pathname, pathlen, basename,
- dtype_p, &dir->exclude_list[st])) {
+ switch (excluded_from_list(pathname, pathlen, basename,
+ dtype_p, &dir->exclude_list[st])) {
case 0:
return 0;
case 1:
diff --git a/dir.h b/dir.h
index a631446..472e11e 100644
--- a/dir.h
+++ b/dir.h
@@ -69,7 +69,11 @@ extern int match_pathspec(const char **pathspec, const char *name, int namelen,
extern int fill_directory(struct dir_struct *dir, const char **pathspec);
extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec);
+extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,
+ int *dtype, struct exclude_list *el);
extern int excluded(struct dir_struct *, const char *, int *);
+extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
+ char **buf_p, struct exclude_list *which, int check_index);
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *which);
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 18/23] unpack-trees(): "enable" sparse checkout and load $GIT_DIR/info/sparse-checkout
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:31 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
This patch introduces core.sparseCheckout, which will control whether
sparse checkout support is enabled in unpack_trees()
It also loads sparse-checkout file that will be used in the next patch.
I split it out so the next patch will be shorter, easier to read.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/config.txt | 4 ++++
Documentation/git-read-tree.txt | 4 +++-
cache.h | 1 +
config.c | 5 +++++
environment.c | 1 +
unpack-trees.c | 36 ++++++++++++++++++++++++++++++------
unpack-trees.h | 4 ++++
7 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7791c32..5825c91 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -439,6 +439,10 @@ On some file system/operating system combinations, this is unreliable.
Set this config setting to 'rename' there; However, This will remove the
check that makes sure that existing object files will not get overwritten.
+core.sparseCheckout::
+ Enable "sparse checkout" feature. See section "Sparse checkout" in
+ linkgit:git-read-tree[1] for more information.
+
add.ignore-errors::
Tells 'git-add' to continue adding files when some files cannot be
added due to indexing errors. Equivalent to the '--ignore-errors'
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 8b39716..fc3f08b 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -401,7 +401,9 @@ follows:
----------------
Then you can disable sparse checkout. Sparse checkout support in "git
-read-tree" and similar commands is disabled by default.
+read-tree" and similar commands is disabled by default. You need to
+turn `core.sparseCheckout` on in order to have sparse checkout
+support.
SEE ALSO
diff --git a/cache.h b/cache.h
index 3a37469..f51b285 100644
--- a/cache.h
+++ b/cache.h
@@ -528,6 +528,7 @@ extern size_t delta_base_cache_limit;
extern int auto_crlf;
extern int fsync_object_files;
extern int core_preload_index;
+extern int core_apply_sparse_checkout;
enum safe_crlf {
SAFE_CRLF_FALSE = 0,
diff --git a/config.c b/config.c
index e87edea..abd762e 100644
--- a/config.c
+++ b/config.c
@@ -503,6 +503,11 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.sparsecheckout")) {
+ core_apply_sparse_checkout = git_config_bool(var, value);
+ return 0;
+ }
+
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
diff --git a/environment.c b/environment.c
index 8f5eaa7..020422c 100644
--- a/environment.c
+++ b/environment.c
@@ -48,6 +48,7 @@ enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
#endif
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
int grafts_replace_parents = 1;
+int core_apply_sparse_checkout;
/* Parallel index stat data preload? */
int core_preload_index = 0;
diff --git a/unpack-trees.c b/unpack-trees.c
index 5467265..56f1a30 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -378,6 +378,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
{
int ret;
static struct cache_entry *dfc;
+ struct exclude_list el;
if (len > MAX_UNPACK_TREES)
die("unpack_trees takes at most %d trees", MAX_UNPACK_TREES);
@@ -387,6 +388,16 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
state.quiet = 1;
state.refresh_cache = 1;
+ memset(&el, 0, sizeof(el));
+ if (!core_apply_sparse_checkout || !o->update)
+ o->skip_sparse_checkout = 1;
+ if (!o->skip_sparse_checkout) {
+ if (add_excludes_from_file_to_list(git_path("info/sparse-checkout"), "", 0, NULL, &el, 0) < 0)
+ o->skip_sparse_checkout = 1;
+ else
+ o->el = ⪙
+ }
+
memset(&o->result, 0, sizeof(o->result));
o->result.initialized = 1;
if (o->src_index) {
@@ -407,26 +418,39 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
info.fn = unpack_callback;
info.data = o;
- if (traverse_trees(len, t, &info) < 0)
- return unpack_failed(o, NULL);
+ if (traverse_trees(len, t, &info) < 0) {
+ ret = unpack_failed(o, NULL);
+ goto done;
+ }
}
/* Any left-over entries in the index? */
if (o->merge) {
while (o->pos < o->src_index->cache_nr) {
struct cache_entry *ce = o->src_index->cache[o->pos];
- if (unpack_index_entry(ce, o) < 0)
- return unpack_failed(o, NULL);
+ if (unpack_index_entry(ce, o) < 0) {
+ ret = unpack_failed(o, NULL);
+ goto done;
+ }
}
}
- if (o->trivial_merges_only && o->nontrivial_merge)
- return unpack_failed(o, "Merge requires file-level merging");
+ if (o->trivial_merges_only && o->nontrivial_merge) {
+ ret = unpack_failed(o, "Merge requires file-level merging");
+ goto done;
+ }
o->src_index = NULL;
ret = check_updates(o) ? (-2) : 0;
if (o->dst_index)
*o->dst_index = o->result;
+
+done:
+ for (i = 0;i < el.nr;i++)
+ free(el.excludes[i]);
+ if (el.excludes)
+ free(el.excludes);
+
return ret;
}
diff --git a/unpack-trees.h b/unpack-trees.h
index d19df44..5c9e98a 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -4,6 +4,7 @@
#define MAX_UNPACK_TREES 8
struct unpack_trees_options;
+struct exclude_list;
typedef int (*merge_fn_t)(struct cache_entry **src,
struct unpack_trees_options *options);
@@ -28,6 +29,7 @@ struct unpack_trees_options {
skip_unmerged,
initial_checkout,
diff_index_cached,
+ skip_sparse_checkout,
gently;
const char *prefix;
int pos;
@@ -44,6 +46,8 @@ struct unpack_trees_options {
struct index_state *dst_index;
struct index_state *src_index;
struct index_state result;
+
+ struct exclude_list *el; /* for internal use */
};
extern int unpack_trees(unsigned n, struct tree_desc *t,
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 19/23] unpack_trees(): apply $GIT_DIR/info/sparse-checkout to the final index
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:31 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
unpack-trees.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
unpack-trees.h | 2 +
2 files changed, 83 insertions(+), 1 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index 56f1a30..6288385 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -32,6 +32,12 @@ static struct unpack_trees_error_msgs unpack_plumbing_errors = {
/* bind_overlap */
"Entry '%s' overlaps with '%s'. Cannot bind.",
+
+ /* sparse_not_uptodate_file */
+ "Entry '%s' not uptodate. Cannot update sparse checkout.",
+
+ /* would_lose_orphaned */
+ "Working tree file '%s' would be %s by sparse checkout update.",
};
#define ERRORMSG(o,fld) \
@@ -125,6 +131,57 @@ static int check_updates(struct unpack_trees_options *o)
return errs != 0;
}
+static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
+static int verify_absent_sparse(struct cache_entry *ce, const char *action, struct unpack_trees_options *o);
+
+static int will_have_skip_worktree(const struct cache_entry *ce, struct unpack_trees_options *o)
+{
+ const char *basename;
+
+ if (ce_stage(ce))
+ return 0;
+
+ basename = strrchr(ce->name, '/');
+ basename = basename ? basename+1 : ce->name;
+ return excluded_from_list(ce->name, ce_namelen(ce), basename, NULL, o->el) <= 0;
+}
+
+static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o)
+{
+ int was_skip_worktree = ce_skip_worktree(ce);
+
+ if (will_have_skip_worktree(ce, o))
+ ce->ce_flags |= CE_SKIP_WORKTREE;
+ else
+ ce->ce_flags &= ~CE_SKIP_WORKTREE;
+
+ /*
+ * We only care about files getting into the checkout area
+ * If merge strategies want to remove some, go ahead, this
+ * flag will be removed eventually in unpack_trees() if it's
+ * outside checkout area.
+ */
+ if (ce->ce_flags & CE_REMOVE)
+ return 0;
+
+ if (!was_skip_worktree && ce_skip_worktree(ce)) {
+ /*
+ * If CE_UPDATE is set, verify_uptodate() must be called already
+ * also stat info may have lost after merged_entry() so calling
+ * verify_uptodate() again may fail
+ */
+ if (!(ce->ce_flags & CE_UPDATE) && verify_uptodate_sparse(ce, o))
+ return -1;
+ ce->ce_flags |= CE_WT_REMOVE;
+ }
+ if (was_skip_worktree && !ce_skip_worktree(ce)) {
+ if (verify_absent_sparse(ce, "overwritten", o))
+ return -1;
+ 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);
@@ -376,7 +433,7 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
*/
int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
{
- int ret;
+ int i, ret;
static struct cache_entry *dfc;
struct exclude_list el;
@@ -440,6 +497,17 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
goto done;
}
+ if (!o->skip_sparse_checkout) {
+ for (i = 0;i < o->result.cache_nr;i++) {
+ struct cache_entry *ce = o->result.cache[i];
+
+ if (apply_sparse_checkout(ce, o)) {
+ ret = -1;
+ goto done;
+ }
+ }
+ }
+
o->src_index = NULL;
ret = check_updates(o) ? (-2) : 0;
if (o->dst_index)
@@ -512,6 +580,12 @@ static int verify_uptodate(struct cache_entry *ce,
return verify_uptodate_1(ce, o, ERRORMSG(o, not_uptodate_file));
}
+static int verify_uptodate_sparse(struct cache_entry *ce,
+ struct unpack_trees_options *o)
+{
+ return verify_uptodate_1(ce, o, ERRORMSG(o, sparse_not_uptodate_file));
+}
+
static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o)
{
if (ce)
@@ -705,6 +779,12 @@ static int verify_absent(struct cache_entry *ce, const char *action,
return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_untracked));
}
+static int verify_absent_sparse(struct cache_entry *ce, const char *action,
+ struct unpack_trees_options *o)
+{
+ return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_orphaned));
+}
+
static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
struct unpack_trees_options *o)
{
diff --git a/unpack-trees.h b/unpack-trees.h
index 5c9e98a..95ff36c 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -15,6 +15,8 @@ struct unpack_trees_error_msgs {
const char *not_uptodate_dir;
const char *would_lose_untracked;
const char *bind_overlap;
+ const char *sparse_not_uptodate_file;
+ const char *would_lose_orphaned;
};
struct unpack_trees_options {
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 03/23] Introduce "skip-worktree" bit in index, teach Git to get/set this bit
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:30 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Detail about this bit is in Documentation/git-update-index.txt.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/git-ls-files.txt | 1 +
Documentation/git-update-index.txt | 29 +++++++++++++++++
builtin-ls-files.c | 5 ++-
builtin-update-index.c | 16 +++++++++-
cache.h | 4 ++-
t/t2104-update-index-skip-worktree.sh | 57 +++++++++++++++++++++++++++++++++
6 files changed, 109 insertions(+), 3 deletions(-)
create mode 100755 t/t2104-update-index-skip-worktree.sh
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 021066e..6f9d880 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -107,6 +107,7 @@ OPTIONS
Identify the file status with the following tags (followed by
a space) at the start of each line:
H:: cached
+ S:: skip-worktree
M:: unmerged
R:: removed/deleted
C:: modified/changed
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 25e0bbe..a10f355 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]
+ [--skip-worktree | --no-skip-worktree]
[--ignore-submodules]
[--really-refresh] [--unresolve] [--again | -g]
[--info-only] [--index-info]
@@ -99,6 +100,13 @@ in the index e.g. when merging in a commit;
thus, in case the assumed-untracked file is changed upstream,
you will need to handle the situation manually.
+--skip-worktree::
+--no-skip-worktree::
+ When one of these flags is specified, the object name recorded
+ for the paths are not updated. Instead, these options
+ set and unset the "skip-worktree" bit for the paths. See
+ section "Skip-worktree bit" below for more information.
+
-g::
--again::
Runs 'git-update-index' itself on the paths whose index
@@ -304,6 +312,27 @@ M foo.c
<9> now it checks with lstat(2) and finds it has been changed.
+Skip-worktree bit
+-----------------
+
+Skip-worktree bit can be defined in one (long) sentence: When reading
+an entry, if it is marked as skip-worktree, then Git pretends its
+working directory version is up to date and read the index version
+instead.
+
+To elaborate, "reading" means checking for file existence, reading
+file attributes or file content. The working directory version may be
+present or absent. If present, its content may match against the index
+version or not. Writing is not affected by this bit, content safety
+is still first priority. Note that Git _can_ update working directory
+file, that is marked skip-worktree, if it is safe to do so (i.e.
+working directory version matches index version)
+
+Although this bit looks similar to assume-unchanged bit, its goal is
+different from assume-unchanged bit's. Skip-worktree also takes
+precedence over assume-unchanged bit when both are set.
+
+
Configuration
-------------
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f473220..c1afbad 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -37,6 +37,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_skip_worktree = "";
static void show_dir_entry(const char *tag, struct dir_entry *ent)
{
@@ -178,7 +179,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
continue;
if (ce->ce_flags & CE_UPDATE)
continue;
- show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
+ show_ce_entry(ce_stage(ce) ? tag_unmerged :
+ (ce_skip_worktree(ce) ? tag_skip_worktree : tag_cached), ce);
}
}
if (show_deleted | show_modified) {
@@ -490,6 +492,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
tag_modified = "C ";
tag_other = "? ";
tag_killed = "K ";
+ tag_skip_worktree = "S ";
}
if (show_modified || show_others || show_deleted || (dir.flags & DIR_SHOW_IGNORED) || show_killed)
require_work_tree = 1;
diff --git a/builtin-update-index.c b/builtin-update-index.c
index f1b6c8e..5e97d09 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_skip_worktree_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_skip_worktree_only) {
+ if (mark_ce_flags(p, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG))
+ die("Unable to mark file %s", path);
+ goto free_return;
+ }
if (force_remove) {
if (remove_file_from_cache(p))
@@ -384,7 +390,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] [--skip-worktree|--no-skip-worktree] [--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];
@@ -650,6 +656,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
mark_valid_only = UNMARK_FLAG;
continue;
}
+ if (!strcmp(path, "--no-skip-worktree")) {
+ mark_skip_worktree_only = UNMARK_FLAG;
+ continue;
+ }
+ if (!strcmp(path, "--skip-worktree")) {
+ mark_skip_worktree_only = MARK_FLAG;
+ continue;
+ }
if (!strcmp(path, "--info-only")) {
info_only = 1;
continue;
diff --git a/cache.h b/cache.h
index 9222774..f266246 100644
--- a/cache.h
+++ b/cache.h
@@ -181,10 +181,11 @@ struct cache_entry {
* Extended on-disk flags
*/
#define CE_INTENT_TO_ADD 0x20000000
+#define CE_SKIP_WORKTREE 0x40000000
/* CE_EXTENDED2 is for future extension */
#define CE_EXTENDED2 0x80000000
-#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD)
+#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD | CE_SKIP_WORKTREE)
/*
* Safeguard to avoid saving wrong flags:
@@ -233,6 +234,7 @@ 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_skip_worktree(ce) ((ce)->ce_flags & CE_SKIP_WORKTREE)
#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
diff --git a/t/t2104-update-index-skip-worktree.sh b/t/t2104-update-index-skip-worktree.sh
new file mode 100755
index 0000000..1d0879b
--- /dev/null
+++ b/t/t2104-update-index-skip-worktree.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
+#
+
+test_description='skip-worktree bit test'
+
+. ./test-lib.sh
+
+cat >expect.full <<EOF
+H 1
+H 2
+H sub/1
+H sub/2
+EOF
+
+cat >expect.skip <<EOF
+S 1
+H 2
+S sub/1
+H sub/2
+EOF
+
+test_expect_success 'setup' '
+ mkdir sub &&
+ touch ./1 ./2 sub/1 sub/2 &&
+ git add 1 2 sub/1 sub/2 &&
+ git ls-files -t | test_cmp expect.full -
+'
+
+test_expect_success 'index is at version 2' '
+ test "$(test-index-version < .git/index)" = 2
+'
+
+test_expect_success 'update-index --skip-worktree' '
+ git update-index --skip-worktree 1 sub/1 &&
+ git ls-files -t | test_cmp expect.skip -
+'
+
+test_expect_success 'index is at version 3 after having some skip-worktree entries' '
+ test "$(test-index-version < .git/index)" = 3
+'
+
+test_expect_success 'ls-files -t' '
+ git ls-files -t | test_cmp expect.skip -
+'
+
+test_expect_success 'update-index --no-skip-worktree' '
+ git update-index --no-skip-worktree 1 sub/1 &&
+ git ls-files -t | test_cmp expect.full -
+'
+
+test_expect_success 'index version is back to 2 when there is no skip-worktree entry' '
+ test "$(test-index-version < .git/index)" = 2
+'
+
+test_done
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 17/23] unpack-trees.c: generalize verify_* functions
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:31 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
unpack-trees.c | 23 ++++++++++++++++++-----
1 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index eb1a818..5467265 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -452,8 +452,9 @@ static int same(struct cache_entry *a, struct cache_entry *b)
* When a CE gets turned into an unmerged entry, we
* want it to be up-to-date
*/
-static int verify_uptodate(struct cache_entry *ce,
- struct unpack_trees_options *o)
+static int verify_uptodate_1(struct cache_entry *ce,
+ struct unpack_trees_options *o,
+ const char *error_msg)
{
struct stat st;
@@ -478,7 +479,13 @@ static int verify_uptodate(struct cache_entry *ce,
if (errno == ENOENT)
return 0;
return o->gently ? -1 :
- error(ERRORMSG(o, not_uptodate_file), ce->name);
+ error(error_msg, ce->name);
+}
+
+static int verify_uptodate(struct cache_entry *ce,
+ struct unpack_trees_options *o)
+{
+ return verify_uptodate_1(ce, o, ERRORMSG(o, not_uptodate_file));
}
static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o)
@@ -586,8 +593,9 @@ static int icase_exists(struct unpack_trees_options *o, struct cache_entry *dst,
* We do not want to remove or overwrite a working tree file that
* is not tracked, unless it is ignored.
*/
-static int verify_absent(struct cache_entry *ce, const char *action,
- struct unpack_trees_options *o)
+static int verify_absent_1(struct cache_entry *ce, const char *action,
+ struct unpack_trees_options *o,
+ const char *error_msg)
{
struct stat st;
@@ -667,6 +675,11 @@ static int verify_absent(struct cache_entry *ce, const char *action,
}
return 0;
}
+static int verify_absent(struct cache_entry *ce, const char *action,
+ struct unpack_trees_options *o)
+{
+ return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_untracked));
+}
static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
struct unpack_trees_options *o)
--
1.6.5.2.216.g9c1ec
^ permalink raw reply related
* [PATCH 21/23] read-tree: add --no-sparse-checkout to disable sparse checkout support
From: Nguyễn Thái Ngọc Duy @ 2009-12-14 10:31 UTC (permalink / raw)
To: Junio C Hamano, git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <1260786666-8405-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/git-read-tree.txt | 6 +++++-
builtin-read-tree.c | 4 +++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index fc3f08b..ea7b0b2 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
'git read-tree' [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>]
[-u [--exclude-per-directory=<gitignore>] | -i]]
- [--index-output=<file>]
+ [--index-output=<file>] [--no-sparse-checkout]
<tree-ish1> [<tree-ish2> [<tree-ish3>]]
@@ -110,6 +110,10 @@ OPTIONS
directories the index file and index output file are
located in.
+--no-sparse-checkout::
+ Disable sparse checkout support even if `core.sparseCheckout`
+ is true.
+
<tree-ish#>::
The id of the tree object(s) to be read/merged.
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 9c2d634..f5acb1a 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -31,7 +31,7 @@ static int list_tree(unsigned char *sha1)
}
static const char * const read_tree_usage[] = {
- "git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]]",
+ "git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]]",
NULL
};
@@ -98,6 +98,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
PARSE_OPT_NONEG, exclude_per_directory_cb },
OPT_SET_INT('i', NULL, &opts.index_only,
"don't check the working tree after merging", 1),
+ OPT_SET_INT(0, "no-sparse-checkout", &opts.skip_sparse_checkout,
+ "skip applying sparse checkout filter", 1),
OPT_END()
};
--
1.6.5.2.216.g9c1ec
^ 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