Git development
 help / color / mirror / Atom feed
* Re: [RFC PATCH v2 2/4] gitignore: read from index if .gitignore is assume-unchanged
From: Johannes Schindelin @ 2009-08-10 16:33 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1249917562-5931-3-git-send-email-pclouds@gmail.com>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2887 bytes --]

Hi,

On Mon, 10 Aug 2009, Nguyễn Thái Ngọc Duy wrote:

> diff --git a/dir.c b/dir.c
> index e05b850..e55344f 100644
> --- a/dir.c
> +++ b/dir.c
> @@ -200,11 +200,36 @@ void add_exclude(const char *string, const char *base,
>  	which->excludes[which->nr++] = x;
>  }
>  
> +static void *read_index_data(const char *path, size_t *size)

How about calling it "read_assume_unchanged_from_index()" instead?  I 
suggest this because it does not read the index from the data if the path 
is not marked assume unchanged...

> @@ -212,27 +237,31 @@ 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);

Should this change not rather be a separate one?

> @@ -241,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)

Could you mention in the commit message why this function does not want to 
check the index (I _guess_ it is because this code path only tries to read 
.git/info/exclude, but it would be better to be sure).

>  		die("cannot use %s as an exclude file", fname);
>  }
>  
> @@ -302,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..88b69bc 100755
> --- a/t/t3001-ls-files-others-exclude.sh
> +++ b/t/t3001-ls-files-others-exclude.sh
> @@ -85,6 +85,26 @@ test_expect_success \
>         >output &&
>       test_cmp expect output'
>  
> +test_expect_success 'setup sparse gitignore' '
> +	git add .gitignore one/.gitignore one/two/.gitignore &&
> +	git update-index --assume-unchanged .gitignore one/.gitignore one/two/.gitignore &&
> +	rm .gitignore one/.gitignore one/two/.gitignore
> +'

You're probably less sloppy than me; I'd have defined a variable like 
this:

	ignores=".gitignore one/.gitignore one/two/.gitignore"

and used it for the three calls, just to make sure that I do not fsck 
anything up there due to fat fingers.

Thanks,
Dscho

^ permalink raw reply

* Re: [Feature Request] git export
From: Tim Visher @ 2009-08-10 16:27 UTC (permalink / raw)
  To: thomas; +Cc: git
In-Reply-To: <200908101822.59940.thomas@koch.ro>

Hey Thomas,

On Mon, Aug 10, 2009 at 12:22 PM, Thomas Koch<thomas@koch.ro> wrote:
> could you please provide a simple solution to save a tree object into an
> arbitrary location?

This has been requested a few times and I have no idea what the
development status of it is.  Most people seem to recommend just
making an alias around git checkout-index.

> I found some hints, that it would be possible by missusing either git
> checkout-index or git-archive, but I think that it shouldn't require that much
> GIT FU to do such a simple thing.

It's not really a misuse, as the [man page
itself](http://www.kernel.org/pub/software/scm/git/docs/git-checkout-index.html)
recommends using checkout-index as a way to export an entire tree.
Until someone decides that it's worth making the porcelain command
(like you perhaps) then I think you can just stick with checkout-index
knowing you're not abusing anything.

-- 

In Christ,

Timmy V.

http://burningones.com/
http://five.sentenc.es/ - Spend less time on e-mail

^ permalink raw reply

* [Feature Request] git export
From: Thomas Koch @ 2009-08-10 16:22 UTC (permalink / raw)
  To: git

could you please provide a simple solution to save a tree object into an 
arbitrary location?
I found some hints, that it would be possible by missusing either git 
checkout-index or git-archive, but I think that it shouldn't require that much 
GIT FU to do such a simple thing.

Thanks,

Thomas Koch, http://www.koch.ro

^ permalink raw reply

* [PATCH 2/2] Correctly mark cover letters' encodings if they are not pure ASCII
From: Johannes Schindelin @ 2009-08-10 16:22 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <cover.1249921206u.git.johannes.schindelin@gmx.de>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 792 bytes --]

If your name is, say, Üwë, you want your cover letters to appear
correctly.  Convince format-patch to mark it as 8-bit.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin-log.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/builtin-log.c b/builtin-log.c
index 3600215..d4a6a7d 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -678,6 +678,10 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
 	log_write_email_headers(rev, head, &subject_start, &extra_headers,
 				&need_8bit_cte);
 
+	for (i = 0; !need_8bit_cte && i < nr; i++)
+		if (has_non_ascii(list[i]->buffer))
+			need_8bit_cte = 1;
+
 	msg = body;
 	pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
 		     encoding);
-- 
1.6.3.2.734.g770e

^ permalink raw reply related

* [PATCH 1/2] Expose the has_non_ascii() function
From: Johannes Schindelin @ 2009-08-10 16:22 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <cover.1249921206u.git.johannes.schindelin@gmx.de>

This function is useful outside of log-tree.c, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 commit.h   |    1 +
 log-tree.c |   12 ------------
 pretty.c   |   12 ++++++++++++
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/commit.h b/commit.h
index 8bfdf0e..d1674d7 100644
--- a/commit.h
+++ b/commit.h
@@ -64,6 +64,7 @@ enum cmit_fmt {
 };
 
 extern int non_ascii(int);
+extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
 extern char *reencode_commit_message(const struct commit *commit,
 				     const char **encoding_p);
diff --git a/log-tree.c b/log-tree.c
index 6f73c17..a3b4c06 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -168,18 +168,6 @@ static unsigned int digits_in_number(unsigned int number)
 	return result;
 }
 
-static int has_non_ascii(const char *s)
-{
-	int ch;
-	if (!s)
-		return 0;
-	while ((ch = *s++) != '\0') {
-		if (non_ascii(ch))
-			return 1;
-	}
-	return 0;
-}
-
 void get_patch_filename(struct commit *commit, int nr, const char *suffix,
 			struct strbuf *buf)
 {
diff --git a/pretty.c b/pretty.c
index 1aa9c3f..ec0affe 100644
--- a/pretty.c
+++ b/pretty.c
@@ -86,6 +86,18 @@ int non_ascii(int ch)
 	return !isascii(ch) || ch == '\033';
 }
 
+int has_non_ascii(const char *s)
+{
+	int ch;
+	if (!s)
+		return 0;
+	while ((ch = *s++) != '\0') {
+		if (non_ascii(ch))
+			return 1;
+	}
+	return 0;
+}
+
 static int is_rfc2047_special(char ch)
 {
 	return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_'));
-- 
1.6.3.2.734.g770e

^ permalink raw reply related

* [PATCH 0/2] Fix cover letters when they contain non-ASCII
From: Johannes Schindelin @ 2009-08-10 16:22 UTC (permalink / raw)
  To: git, gitster

[-- Attachment #1: Type: TEXT/PLAIN, Size: 368 bytes --]

Hi,

I saw this issue with Santi's and Nguyễn's patch series.

Johannes Schindelin (2):
  Expose the has_non_ascii() function
  Correctly mark cover letters' encodings if they are not pure ASCII

 builtin-log.c |    4 ++++
 commit.h      |    1 +
 log-tree.c    |   12 ------------
 pretty.c      |   12 ++++++++++++
 4 files changed, 17 insertions(+), 12 deletions(-)

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] Prevent diff machinery from examining assume-unchanged entries on worktree
From: Johannes Schindelin @ 2009-08-10 16:20 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1249917562-5931-2-git-send-email-pclouds@gmail.com>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2072 bytes --]

Hi,

On Mon, 10 Aug 2009, Nguyễn Thái Ngọc Duy wrote:

> diff --git a/diff-lib.c b/diff-lib.c
> index b7813af..f5787f6 100644
> --- a/diff-lib.c
> +++ b/diff-lib.c
> @@ -337,6 +337,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
>  	struct rev_info *revs = o->unpack_data;
>  	int match_missing, cached;
>  
> +	/* if the entry is not checked out, don't examine work tree */
> +	cached = o->index_only || (idx && (idx->ce_flags & CE_VALID));
>  	/*
>  	 * Backward compatibility wart - "diff-index -m" does
>  	 * not mean "do not ignore merges", but "match_missing".
> @@ -344,7 +346,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)) {

Out of curiosity: why did that line have to move up?

Ciao,
Dscho

> diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh
> new file mode 100755
> index 0000000..d0e46a7
> --- /dev/null
> +++ b/t/t4039-diff-assume-unchanged.sh
> @@ -0,0 +1,31 @@
> +#!/bin/sh
> +
> +test_description='diff with assume-unchanged entries'
> +
> +. ./test-lib.sh
> +
> +# external diff has been tested in t4020-diff-external.sh
> +
> +test_expect_success 'setup' '
> +	echo zero > zero &&
> +	git add zero &&
> +	git commit -m zero &&
> +	echo one > one &&
> +	echo two > two &&
> +	git add one two &&
> +	git commit -m onetwo &&
> +	git update-index --assume-unchanged one &&
> +	echo borked >> one &&
> +	test "$(git ls-files -v one)" = "h one"
> +'

Maybe use test_commit, to make it more readable?

> +
> +test_expect_success 'diff-index does not examine assume-unchanged entries' '
> +	git diff-index HEAD^ -- one | grep -q 5626abf0f72e58d7a153368ba57db4c673c0e171 
> +'
> +
> +# TODO ced_uptodate()

What is this about?

> +test_expect_success 'diff-files does not examine assume-unchanged entries' '
> +	/usr/bin/git diff-files -- one
> +'
> +
> +test_done

Thanks,
Dscho

^ permalink raw reply

* Re: [PATCH] fix potential infinite loop given large unsigned integer
From: Ryan Flynn @ 2009-08-10 16:17 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Erik Faye-Lund, Christian Couder, Junio C Hamano, git
In-Reply-To: <alpine.DEB.1.00.0908101421340.8324@intel-tinevez-2-302>

On Mon, Aug 10, 2009 at 8:24 AM, Johannes
Schindelin<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Mon, 10 Aug 2009, Erik Faye-Lund wrote:
>
>> On Mon, Aug 10, 2009 at 7:24 AM, Christian
>> Couder<chriscool@tuxfamily.org> wrote:
>> >> log10() appears to be C99, but can be emulated on earlier C-versions by
>> >> doing #define log10(x) (log(x) / log(10.0))
>> >
>> > That would mean linking with -lm?
>>
>> I guess so. Are we currently trying to avoid linking to the math-parts
>> of libc?
>
> Yes.
>
> I guess we could fix the overflow thing very easily, though:
>
> static unsigned int digits_of_number(unsigned int number) {
>        unsigned int result;
>        for (result = 1; number; number /= 10, result++)
>                ; /* do nothing */
>        return result;
> }
>
> Ciao,
> Dscho
>
>

whoops, actually yours: digits_of_number(1) -> 2

^ permalink raw reply

* Re: [PATCH] fix potential infinite loop given large unsigned integer
From: Ryan Flynn @ 2009-08-10 16:14 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Erik Faye-Lund, Christian Couder, Junio C Hamano, git
In-Reply-To: <alpine.DEB.1.00.0908101421340.8324@intel-tinevez-2-302>

On Mon, Aug 10, 2009 at 8:24 AM, Johannes
Schindelin<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Mon, 10 Aug 2009, Erik Faye-Lund wrote:
>
>> On Mon, Aug 10, 2009 at 7:24 AM, Christian
>> Couder<chriscool@tuxfamily.org> wrote:
>> >> log10() appears to be C99, but can be emulated on earlier C-versions by
>> >> doing #define log10(x) (log(x) / log(10.0))
>> >
>> > That would mean linking with -lm?
>>
>> I guess so. Are we currently trying to avoid linking to the math-parts
>> of libc?
>
> Yes.
>
> I guess we could fix the overflow thing very easily, though:
>
> static unsigned int digits_of_number(unsigned int number) {
>        unsigned int result;
>        for (result = 1; number; number /= 10, result++)
>                ; /* do nothing */
>        return result;
> }
>
> Ciao,
> Dscho
>
>

that is equivalent to the original patch, yes.

^ permalink raw reply

* [PATCH (resend) 3/3] Check return value of ftruncate call in http.c
From: Tay Ray Chuan @ 2009-08-10 16:05 UTC (permalink / raw)
  To: git, gitster; +Cc: Jeff Lasslett
In-Reply-To: <20090810235955.1a659e6c.rctay89@gmail.com>

From: Jeff Lasslett <jeff.lasslett@gmail.com>

In new_http_object_request(), check ftruncate() call return value and
handle possible errors.

Signed-off-by: Jeff Lasslett <jeff.lasslett@gmail.com>
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
---

 Jeff, I took out all the url-specific cleanups and expanded their
 scope (see earlier patches). You can safely focus on ftruncate() and
 do an abort there. :)

 http.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/http.c b/http.c
index 98f9707..14d5357 100644
--- a/http.c
+++ b/http.c
@@ -1187,7 +1187,11 @@ struct http_object_request *new_http_object_request(const char *base_url,
 		if (prev_posn>0) {
 			prev_posn = 0;
 			lseek(freq->localfile, 0, SEEK_SET);
-			ftruncate(freq->localfile, 0);
+			if (ftruncate(freq->localfile, 0) < 0) {
+				error("Couldn't truncate temporary file %s for %s: %s",
+					  freq->tmpfile, freq->filename, strerror(errno));
+				goto abort;
+			}
 		}
 	}

--
1.6.3.1

^ permalink raw reply related

* [PATCH (resend) 2/3] http.c: replace usage of temporary variable for urls
From: Tay Ray Chuan @ 2009-08-10 15:59 UTC (permalink / raw)
  To: git, gitster; +Cc: Jeff Lasslett
In-Reply-To: <20090810235548.110c43a6.rctay89@gmail.com>

Use preq->url in new_http_pack_request and freq->url in
new_http_object_request when calling curl_setopt(CURLOPT_URL), instead
of using an intermediate variable, 'url'.

Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
---
 http.c |   15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/http.c b/http.c
index cfe32f5..98f9707 100644
--- a/http.c
+++ b/http.c
@@ -1004,7 +1004,6 @@ int finish_http_pack_request(struct http_pack_request *preq)
 struct http_pack_request *new_http_pack_request(
 	struct packed_git *target, const char *base_url)
 {
-	char *url;
 	char *filename;
 	long prev_posn = 0;
 	char range[RANGE_HEADER_SIZE];
@@ -1018,8 +1017,7 @@ struct http_pack_request *new_http_pack_request(
 	end_url_with_slash(&buf, base_url);
 	strbuf_addf(&buf, "objects/pack/pack-%s.pack",
 		sha1_to_hex(target->sha1));
-	url = strbuf_detach(&buf, NULL);
-	preq->url = xstrdup(url);
+	preq->url = strbuf_detach(&buf, NULL);

 	filename = sha1_pack_name(target->sha1);
 	snprintf(preq->filename, sizeof(preq->filename), "%s", filename);
@@ -1035,7 +1033,7 @@ struct http_pack_request *new_http_pack_request(
 	preq->slot->local = preq->packfile;
 	curl_easy_setopt(preq->slot->curl, CURLOPT_FILE, preq->packfile);
 	curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
-	curl_easy_setopt(preq->slot->curl, CURLOPT_URL, url);
+	curl_easy_setopt(preq->slot->curl, CURLOPT_URL, preq->url);
 	curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER,
 		no_pragma_header);

@@ -1059,6 +1057,7 @@ struct http_pack_request *new_http_pack_request(

 abort:
 	free(filename);
+	free(preq->url);
 	free(preq);
 	return NULL;
 }
@@ -1099,7 +1098,6 @@ struct http_object_request *new_http_object_request(const char *base_url,
 	char *hex = sha1_to_hex(sha1);
 	char *filename;
 	char prevfile[PATH_MAX];
-	char *url;
 	int prevlocal;
 	unsigned char prev_buf[PREV_BUF_SIZE];
 	ssize_t prev_read = 0;
@@ -1153,8 +1151,7 @@ struct http_object_request *new_http_object_request(const char *base_url,

 	git_SHA1_Init(&freq->c);

-	url = get_remote_object_url(base_url, hex, 0);
-	freq->url = xstrdup(url);
+	freq->url = get_remote_object_url(base_url, hex, 0);

 	/*
 	 * If a previous temp file is present, process what was already
@@ -1199,7 +1196,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
 	curl_easy_setopt(freq->slot->curl, CURLOPT_FILE, freq);
 	curl_easy_setopt(freq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);
 	curl_easy_setopt(freq->slot->curl, CURLOPT_ERRORBUFFER, freq->errorstr);
-	curl_easy_setopt(freq->slot->curl, CURLOPT_URL, url);
+	curl_easy_setopt(freq->slot->curl, CURLOPT_URL, freq->url);
 	curl_easy_setopt(freq->slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);

 	/*
@@ -1219,9 +1216,9 @@ struct http_object_request *new_http_object_request(const char *base_url,

 	return freq;

-	free(url);
 abort:
 	free(filename);
+	free(freq->url);
 	free(freq);
 	return NULL;
 }
--
1.6.3.1

^ permalink raw reply related

* Re: give a hint/solution for "It looks like git-am is in progress.  Cannot rebase."
From: John Tapsell @ 2009-08-10 15:59 UTC (permalink / raw)
  To: Lucian Adrian Grijincu; +Cc: git
In-Reply-To: <acf3f2e60908100734l6388d9a8k90ed835304a69918@mail.gmail.com>

2009/8/10 Lucian Adrian Grijincu <lucian.grijincu@gmail.com>:
> Hi,
>
> I ran git-am instead of git-apply on my repo. The git-am complained
> about the input data, I completely ignored it because I never use
> git-am (except on typos + tab-completions like today).
>
> Later, after a few commits I wanted to rebase (interactively) my tree
> to merge a few commits.
>  $ git rebase -i HEAD~4
>  It looks like git-am is in progress. Cannot rebase.
>
> Ok, the message is nice, it tells me it can't do something, but I'm
> stupid enough not to know how to proceed.
> I see that this message is the same in HEAD (master and next).
>
> It would be nice if git would output one or two hints. For example:
> * run "git cancel-a-git-am-in-progress" to cancel a git-am in progress
> * run "git commit-the-git-am-in-progress" to commit the git-am in progress

+1

git am --help  suggests  --abort      btw.  That would be the most
obvious guess :-)



> Of course, the commands need to be replaced with some valid git
> commands, but I don't know which those commands are :)
>
> The message is generated in git-rebase.sh by this code:
>  test -f "$GIT_DIR"/rebase-apply/applying &&
>  die 'It looks like git-am is in progress. Cannot rebase.'
>
> For now I think I'll `rm -rf .git/rebase-apply` (and hopefully not
> break anything).
>
> --
>  .
> ..: Lucian
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH (resend) 1/3] http.c: free preq when aborting
From: Tay Ray Chuan @ 2009-08-10 15:55 UTC (permalink / raw)
  To: git, gitster; +Cc: Jeff Lasslett
In-Reply-To: <be6fef0d0908100847h7e9b53a2ofdf318e9958be3b2@mail.gmail.com>

Free preq in new_http_pack_request when aborting. preq was allocated
before jumping to the 'abort' label so this is safe.

Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
---
 http.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/http.c b/http.c
index a2720d5..cfe32f5 100644
--- a/http.c
+++ b/http.c
@@ -1059,6 +1059,7 @@ struct http_pack_request *new_http_pack_request(

 abort:
 	free(filename);
+	free(preq);
 	return NULL;
 }

--
1.6.3.1

^ permalink raw reply related

* Re: [EGIT PATCH] Provide a more JavaBeans-style 'getName' accessor for the id Signed-off-by: Alex Blewitt <alex.blewitt@gmail.com>
From: Shawn O. Pearce @ 2009-08-10 15:52 UTC (permalink / raw)
  To: Alex Blewitt; +Cc: robin.rosenberg, git
In-Reply-To: <1241909854-11498-1-git-send-email-alex.blewitt@gmail.com>

Alex Blewitt <alex.blewitt@gmail.com> wrote:
> ---
>  .../src/org/spearce/jgit/lib/AnyObjectId.java      |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
> 
> diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java
> index acb3cb5..015042a 100644
> --- a/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java
> +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java
> @@ -448,6 +448,12 @@ public final String name() {
>  	}
>  
>  	/**
> +	 * @return string form of the SHA-1, in lower case hexadecimal.
> +	 */
> +	public final String getName() {
> +		return name();
> +	}

Obviously you didn't compile test this in JGit:

./org/spearce/jgit/revwalk/RevTag.java:206: getName() in
org.spearce.jgit.revwalk.RevTag cannot override getName() in
org.spearce.jgit.lib.AnyObjectId; overridden method is final

:-(

-- 
Shawn.

^ permalink raw reply

* [PATCH 1/3] http.c: free preq when aborting
From: Tay Ray Chuan @ 2009-08-10 15:51 UTC (permalink / raw)
  To: git; +Cc: Jeff Lasslett

Free preq in new_http_pack_request when aborting. preq was allocated
before jumping to the 'abort' label so this is safe.

Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
---
 http.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/http.c b/http.c
index a2720d5..cfe32f5 100644
--- a/http.c
+++ b/http.c
@@ -1059,6 +1059,7 @@ struct http_pack_request *new_http_pack_request(

 abort:
 	free(filename);
+	free(preq);
 	return NULL;
 }

--
1.6.3.1

^ permalink raw reply related

* Re: [PATCH] Check return value of ftruncate call in http.c. Remove  possible mem leak
From: Tay Ray Chuan @ 2009-08-10 15:47 UTC (permalink / raw)
  To: Jeff Lasslett; +Cc: git, gitster
In-Reply-To: <1249911747-28490-1-git-send-email-jeff.lasslett@gmail.com>

Hi,

On Mon, Aug 10, 2009 at 9:42 PM, Jeff Lasslett<jeff.lasslett@gmail.com> wrote:
> @@ -1216,10 +1220,12 @@ struct http_object_request *new_http_object_request(const char *base_url,
>                                 CURLOPT_HTTPHEADER, range_header);
>        }
>
> +       free(url);
>        return freq;
>
> -       free(url);

Freeing after the return didn't make sense. Thanks for spotting this.

On a side note, you could simply do away with the 'url' variable,
since you're going to pass freq->url to curl_setopt.

-- 
Cheers,
Ray Chuan

^ permalink raw reply

* Re: [PATCH] git gui: remove warning when deleting correctly merged remote branch
From: Shawn O. Pearce @ 2009-08-10 15:47 UTC (permalink / raw)
  To: Heiko Voigt; +Cc: git
In-Reply-To: <20090615211956.GB8065@macbook.lan>

Heiko Voigt <hvoigt@hvoigt.net> wrote:
> If the user wants to delete a remote branch and selects the correct
> "merged into" we should not warn that "Recovering deleted branches is
> difficult". For local branches we do the same already.
> 
> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
> ---
>  git-gui/lib/remote_branch_delete.tcl |   16 +++++++++-------
>  1 files changed, 9 insertions(+), 7 deletions(-)

Thanks, applied.
 
-- 
Shawn.

^ permalink raw reply

* Re: git-gui translation pushed
From: Shawn O. Pearce @ 2009-08-10 15:44 UTC (permalink / raw)
  To: Jimmy Angelakos; +Cc: git
In-Reply-To: <1245870671.5526.14.camel@blob>

Jimmy Angelakos <vyruss@hellug.gr> wrote:
> I have pushed a Greek translation for git-gui on repo.or.cz's
> git-gui-i18n (mob branch).

Thanks, I have cherry-picked this through to master.  The charset
was set wrong in the files, it was "CHARSET", which isn't a valid
charset.  I modified to UTF-8 before applying.  I suspect something
is up with your PO editor.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] Limited git-gui to displaying 5000 new files
From: Shawn O. Pearce @ 2009-08-10 15:38 UTC (permalink / raw)
  To: Dan Zwell; +Cc: Git Mailing List, raa.lkml
In-Reply-To: <4A4A77A6.1020905@lawrence.edu>

Dan Zwell <dzwell@gmail.com> wrote:
> When there is a large number of new or modified files,
> "display_all_files" takes a long time, and git-gui appears to
> hang. Limit the display to 5000 files, by default. This number
> is configurable as gui.maxfilesdisplayed.
>
> Show a warning if the list of files is truncated.

> @@ -1713,7 +1717,18 @@ proc display_all_files {} {
> 	set file_lists($ui_index) [list]
> 	set file_lists($ui_workdir) [list]
>
> -	foreach path [lsort [array names file_states]] {
> +	set to_display [lsort [array names file_states]]
> +	set display_limit $default_config(gui.maxfilesdisplayed)

This should use [get_config gui.maxfilesdisplayed] so that the
user can actually set this property in a configuration file and
have git-gui honor it.  Reading from $default_config means you are
only looking at the hardcoded value you set in git-gui.sh.

> +	if {[llength $to_display] > $display_limit} {
> +		if {![info exists files_warning] || !$files_warning} {

Wouldn't it be easier to just set files_warning to 0 at the start
of the script, so that you don't need to do this info exists test?

> +			set warning "Displaying only $display_limit of "
> +			append warning "[llength $to_display] files."
> +			info_popup [mc $warning]

This needs to be in the translated strings.

-- 
Shawn.

^ permalink raw reply

* Re: [RFC/PATCH RESEND v2] git-gui: display summary when showing diff of a submodule
From: Shawn O. Pearce @ 2009-08-10 15:33 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: git, gitster, Heiko Voigt
In-Reply-To: <4A65FBAF.9020603@web.de>

Jens Lehmann <Jens.Lehmann@web.de> wrote:
> As it is hard to say what changed in a submodule by looking at the hashes,
> let's show the colored submodule summary instead.
> 
> Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
> ---
> 
> I got only one response two weeks ago, so here is a resend.

Thanks for the resend, got lost in my inbox.  Applied.
 
-- 
Shawn.

^ permalink raw reply

* Re: Droppable Git Gui in Mac OS X
From: Shawn O. Pearce @ 2009-08-10 15:26 UTC (permalink / raw)
  To: Tobia Conforto; +Cc: git
In-Reply-To: <loom.20090807T090458-788@post.gmane.org>

Tobia Conforto <tobia.conforto@gmail.com> wrote:
> I noticed that Git Gui cannot be launched on an existing repository by
> simply dragging the repository folder onto Git Gui's icon in the dock,
> but this is a standard UI feature in OS X.
> 
> Here is a fix "Git Gui.app" (which MacPorts installs in
> /opt/local/share/git-gui/lib) to enable this feature.

Interesting.

Two comments:

1) Commit message?  What should we record in the project history
   for this change?

2) Signed-off-by line?  Please see git.git's SUBMITTING_PATCHES
   file for details of what this means, and why it is necessary:

   http://repo.or.cz/w/alt-git.git?a=blob;f=Documentation/SubmittingPatches;hb=HEAD

 
> --- Git Gui.app/Contents/Info.plist
> +++ Git Gui.app/Contents/Info.plist
> @@ -24,5 +24,16 @@
>  	<string>GITg</string>
>  	<key>CFBundleVersion</key>
>  	<string>0.12.0</string>
> +	<key>CFBundleDocumentTypes</key>
> +	<array>
> +		<dict>
> +			<key>CFBundleTypeOSTypes</key>
> +			<array>
> +				<string>fold</string>
> +			</array>
> +			<key>CFBundleTypeRole</key>
> +			<string>Viewer</string>
> +		</dict>
> +	</array>
>  </dict>
>  </plist>
> --- Git Gui.app/Contents/Resources/Scripts/AppMain.tcl
> +++ Git Gui.app/Contents/Resources/Scripts/AppMain.tcl
> @@ -19,4 +19,9 @@
> 
>  unset gitexecdir gitguilib
>  set argv [lrange $argv 1 end]
> -source $AppMain_source
> +
> +proc ::tk::mac::OpenDocument {args} {
> +	cd [lindex $args 0]
> +}
> +
> +after 1 { source $AppMain_source }
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Shawn.

^ permalink raw reply

* Re: [JGIT] Request For Help/Directions
From: Shawn O. Pearce @ 2009-08-10 15:23 UTC (permalink / raw)
  To: Douglas Campos; +Cc: Git Mailing List
In-Reply-To: <ed88cb980907312015q5eb89bf3k73b6664c4f3cbcfd@mail.gmail.com>

Douglas Campos <douglas@theros.info> wrote:
> I'm interested in helping with the implementation, can someone gimme
> little directions?
> 
> I was thinking on implement "git checkout <file>" functionality.
> 
> Any tips?
> 
> PS: I'm reading the testcases & code to find directions, but got
> struck at some deprecated types (GitIndex -> DirCache).

Sorry for the late reply, things tend to get lost in my inbox.

GitIndex vs. DirCache... that's an ugly issue at the momement in the
code base.  I really want to move to DirCache because it tends to
be quicker at reading and writing the index out, plus it honors the
'TREE' extension, at least some of the time.  But its API is said
to be harder to work with, and I can't disagree with that, using the
DirCacheBuilder vs. DirCacheEditor to make updates is horribly ugly.

FWIW, DirCacheBuilder is really meant to be used inside of a
TreeWalk, alongside other iterators, like a FileTreeIterator.

In theory, you should be able to create a 3 way TreeWalk between:

 1) DirCacheBuilderIterator
 2) FileTreeIterator
 3) CanonicalTreeParser

where 1 represents the current state of the .git/index file,
2 represents the current state of the working directory, and 3
represents the tree you are performing the checkout from.

IIRC you could attach a TreeFilter.ANY_DIFF to this TreeWalk and
only have it stop where there are differences between the 3 trees.
Though with a FileTreeIterator ANY_DIFF is probably a bad idea,
as the SHA-1 isn't readily available in a FileTreeIterator and
that is one of the things ANY_DIFF relies upon.  Instead you'd
need to write your own TreeFilter to check stat data between 1-2,
and SHA-1 data between 2-3.

At a difference point, you then need to apply the basic 3-way merge
logic to determine if you should checkout the file in 3 to 1 and 2,
or if you should abort because the file in 2 (the working tree)
differs and needs to be merged.

A really good reason for using the TreeWalk is it has a subclass
called NameConflictTreeWalk that knows how to heal around
directory/file conflicts (aka D/F conflicts) and reports both D/F
paths under a single entry, so that the merge alogrithm can attempt
to deal with D->F or F->D type changes.

But a good chunk of this is pie-in-the-sky.  I've built these APIs
with this in mind... but haven't gotten as far as actually putting
the implementation into practice.

-- 
Shawn.

^ permalink raw reply

* [RFC PATCH v2 4/4] read-tree: add --no-sparse to turn off sparse hook
From: Nguyễn Thái Ngọc Duy @ 2009-08-10 15:19 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1249917562-5931-4-git-send-email-pclouds@gmail.com>


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin-read-tree.c         |    4 +++-
 t/t1009-read-tree-sparse.sh |    6 ++++++
 unpack-trees.c              |    6 ++++--
 unpack-trees.h              |    1 +
 4 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 9c2d634..4c1061e 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] [--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", &opts.no_sparse_hook,
+			    "do not run sparse hook", 1),
 		OPT_END()
 	};
 
diff --git a/t/t1009-read-tree-sparse.sh b/t/t1009-read-tree-sparse.sh
index b613a89..18115b1 100755
--- a/t/t1009-read-tree-sparse.sh
+++ b/t/t1009-read-tree-sparse.sh
@@ -39,4 +39,10 @@ test_expect_success 're-add one' '
 	test -f one
 '
 
+test_expect_success 'read-tree --no-sparse' '
+	make_hook "git update-index --assume-unchanged one"
+	git read-tree -u -m --no-sparse HEAD &&
+	test -f one
+'
+
 test_done
diff --git a/unpack-trees.c b/unpack-trees.c
index f407bf5..d087112 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -530,8 +530,10 @@ 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 (run_sparse_hook(o))
-		return unpack_failed(o, NULL);
+	if (!o->no_sparse_hook) {
+		if (run_sparse_hook(o))
+			return unpack_failed(o, NULL);
+	}
 
 	o->src_index = NULL;
 	ret = check_updates(o) ? (-2) : 0;
diff --git a/unpack-trees.h b/unpack-trees.h
index ad21823..81eb2ef 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -30,6 +30,7 @@ struct unpack_trees_options {
 		     skip_unmerged,
 		     initial_checkout,
 		     diff_index_cached,
+		     no_sparse_hook,
 		     gently;
 	const char *prefix;
 	int pos;
-- 
1.6.3.GIT

^ permalink raw reply related

* [RFC PATCH v2 3/4] unpack_trees(): add support for sparse checkout
From: Nguyễn Thái Ngọc Duy @ 2009-08-10 15:19 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1249917562-5931-3-git-send-email-pclouds@gmail.com>

This patch teaches unpack_trees() to checkout/remove entries on
working directories appropriately when sparse checkout area is
changed. Hook "sparse" is needed to help determine which entry will be
checked out, which will not be.

When the hook is run, it is prepared with a pseudo index. The hook then
can use "git update-index --[no-]assume-unchanged" to manipulate the index.
It should not do anything else on the index. Assume unchanged information
from the index will be used to shape working directory.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h                     |    3 +
 t/t1009-read-tree-sparse.sh |   42 ++++++++++++
 unpack-trees.c              |  152 +++++++++++++++++++++++++++++++++++++++++--
 unpack-trees.h              |    2 +
 4 files changed, 193 insertions(+), 6 deletions(-)
 create mode 100755 t/t1009-read-tree-sparse.sh

diff --git a/cache.h b/cache.h
index 1a2a3c9..dfad54a 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/t/t1009-read-tree-sparse.sh b/t/t1009-read-tree-sparse.sh
new file mode 100755
index 0000000..b613a89
--- /dev/null
+++ b/t/t1009-read-tree-sparse.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+test_description='sparse hook tests'
+
+. ./test-lib.sh
+
+make_hook() {
+	echo "#!/bin/sh" > .git/hooks/sparse &&
+	echo "$1" >> .git/hooks/sparse &&
+	chmod u+x .git/hooks/sparse
+}
+
+test_expect_success setup '
+	echo one > one &&
+	echo two > two &&
+	git add one two &&
+	git commit -m onetwo &&
+	echo three > three &&
+	git add three &&
+	git commit -m three
+'
+
+mkdir .git/hooks
+
+test_expect_success 'failed hook' '
+	make_hook "exit 1" &&
+	test_must_fail git read-tree -u -m HEAD
+'
+
+test_expect_success 'remove one' '
+	make_hook "git update-index --assume-unchanged one"
+	git read-tree -u -m HEAD &&
+	test ! -f one
+'
+
+test_expect_success 're-add one' '
+	make_hook "git update-index --no-assume-unchanged one" &&
+	git read-tree -u -m HEAD &&
+	test -f one
+'
+
+test_done
diff --git a/unpack-trees.c b/unpack-trees.c
index 720f7a1..f407bf5 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -8,6 +8,7 @@
 #include "progress.h"
 #include "refs.h"
 #include "attr.h"
+#include "run-command.h"
 
 /*
  * Error messages expected by scripts out of plumbing commands such as
@@ -32,6 +33,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 */
+	"Orphaned working tree file '%s' would be %s by sparse checkout update.",
 };
 
 #define ERRORMSG(o,fld) \
@@ -78,7 +85,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 +99,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)
@@ -118,6 +132,106 @@ 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 run_sparse_hook(struct unpack_trees_options *o)
+{
+	struct index_state *index = &o->result;
+	struct index_state sparse_index = *index;
+	struct cache_entry *ce, *sparse_ce;
+	char sparse_index_file[PATH_MAX];
+	char sparse_index_env[PATH_MAX];
+	const char *argv[2], *env[2];
+	struct child_process cp;
+	int fd, i, j;
+
+	if (access(git_path("hooks/sparse"), X_OK) < 0)
+		return 0;
+
+	strcpy(sparse_index_file, git_path("sparse"));
+	fd = open(sparse_index_file, O_WRONLY | O_CREAT, 0600);
+	if (fd < 0) {
+		error("Unable to open %s for writing", sparse_index_file);
+		return -1;
+	}
+	/* FIXME: write_index may change something */
+	if (write_index(&sparse_index, fd)) {
+		error("Unable to write index to %s", sparse_index_file);
+		close(fd);
+		return -1;
+	}
+	close(fd);
+
+	memset(&cp, 0, sizeof(cp));
+	argv[0] = git_path("hooks/sparse");
+	argv[1] = NULL;
+	cp.argv = argv;
+	cp.no_stdin = 1;
+	cp.stdout_to_stderr = 1;
+	snprintf(sparse_index_env, sizeof(sparse_index_env), "GIT_INDEX_FILE=%s", sparse_index_file);
+	env[0] = sparse_index_env;
+	env[1] = NULL;
+	cp.env = env;
+	if (run_command(&cp)) {
+		error("Failed to run hook 'sparse'");
+		unlink(sparse_index_file);
+		return -1;
+	}
+
+	discard_index(&sparse_index);
+	read_index_from(&sparse_index, sparse_index_file);
+	unlink(sparse_index_file);
+
+	ce = index->cache[0];
+	sparse_ce = sparse_index.cache[0];
+	for (i = j = 0; i < index->cache_nr; i++, ce++) {
+		int was_checkout = !(ce->ce_flags & CE_VALID);
+
+		if (ce_stage(ce))
+			continue;
+
+		/*
+		 * We only care about files getting into the checkout area
+		 * If merge strategies want to remove some, go ahead
+		 */
+		if (ce->ce_flags & CE_REMOVE)
+			continue;
+
+		while (j < sparse_index.cache_nr &&
+		       cache_name_compare(sparse_ce->name, sparse_ce->ce_flags, ce->name, ce->ce_flags) < 0) {
+			sparse_ce++;
+			j++;
+		}
+		if (j < sparse_index.cache_nr &&
+		    !cache_name_compare(sparse_ce->name, sparse_ce->ce_flags, ce->name, ce->ce_flags))
+			ce->ce_flags = (ce->ce_flags & ~CE_VALID) | (sparse_ce->ce_flags & CE_VALID);
+
+		/* Update worktree, add/remove entries if needed */
+
+		if (was_checkout && ce->ce_flags & CE_VALID) {
+			/*
+			 * 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_checkout && !(ce->ce_flags & CE_VALID)) {
+			if (verify_absent_sparse(ce, "overwritten", o))
+				return -1;
+			ce->ce_flags |= CE_UPDATE;
+		}
+
+		/* merge strategies may set CE_UPDATE outside checkout area */
+		if (ce->ce_flags & CE_VALID)
+			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);
@@ -416,6 +530,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 (run_sparse_hook(o))
+		return unpack_failed(o, NULL);
+
 	o->src_index = NULL;
 	ret = check_updates(o) ? (-2) : 0;
 	if (o->dst_index)
@@ -445,8 +562,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_generic(struct cache_entry *ce,
+				   struct unpack_trees_options *o,
+				   const char *error_msg)
 {
 	struct stat st;
 
@@ -471,7 +589,18 @@ 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_generic(ce, o, ERRORMSG(o, not_uptodate_file));
+}
+static int verify_uptodate_sparse(struct cache_entry *ce,
+				  struct unpack_trees_options *o)
+{
+	return verify_uptodate_generic(ce, o, ERRORMSG(o, sparse_not_uptodate_file));
 }
 
 static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o)
@@ -579,8 +708,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_generic(struct cache_entry *ce, const char *action,
+				 struct unpack_trees_options *o,
+				 const char *error_msg)
 {
 	struct stat st;
 
@@ -660,6 +790,16 @@ 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_generic(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_generic(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 d19df44..ad21823 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -14,6 +14,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.3.GIT

^ permalink raw reply related

* [RFC PATCH v2 2/4] gitignore: read from index if .gitignore is assume-unchanged
From: Nguyễn Thái Ngọc Duy @ 2009-08-10 15:19 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1249917562-5931-2-git-send-email-pclouds@gmail.com>

In sparse checkout mode (aka CE_VALID or assume-unchanged) some files
may be missing from working directory. If some of those files are
.gitignore, it will affect how git excludes files.

Because those files are by definition "assume unchanged" we can
instead read them from index. This adds index as a prerequisite for
directory listing. 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.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/technical/api-directory-listing.txt |    3 +
 builtin-clean.c                                   |    5 +-
 builtin-ls-files.c                                |    4 +-
 dir.c                                             |   70 ++++++++++++++-------
 t/t3001-ls-files-others-exclude.sh                |   20 ++++++
 t/t7300-clean.sh                                  |   19 ++++++
 6 files changed, 96 insertions(+), 25 deletions(-)

diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt
index 5bbd18f..7d0e282 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
 ----------------
 
+* Ensure the_index is populated as it may have CE_VALID entries that
+  affect directory listing.
+
 * 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..d917472 100644
--- a/builtin-clean.c
+++ b/builtin-clean.c
@@ -71,8 +71,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 	dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
 
-	if (!ignored)
+	if (!ignored) {
+		if (read_cache() < 0)
+			die("index file corrupt");
 		setup_standard_excludes(&dir);
+	}
 
 	pathspec = get_pathspec(prefix, argv);
 	read_cache();
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f473220..d1a23c4 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -481,6 +481,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) {
@@ -508,7 +511,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 e05b850..e55344f 100644
--- a/dir.c
+++ b/dir.c
@@ -200,11 +200,36 @@ void add_exclude(const char *string, const char *base,
 	which->excludes[which->nr++] = x;
 }
 
+static void *read_index_data(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;
+	/* only applies to CE_VALID entries */
+	if (!(istate->cache[pos]->ce_flags & CE_VALID))
+		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,27 +237,31 @@ 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_index_data(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;
-	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);
@@ -241,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);
 }
 
@@ -302,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..88b69bc 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -85,6 +85,26 @@ test_expect_success \
        >output &&
      test_cmp expect output'
 
+test_expect_success 'setup sparse gitignore' '
+	git add .gitignore one/.gitignore one/two/.gitignore &&
+	git update-index --assume-unchanged .gitignore one/.gitignore one/two/.gitignore &&
+	rm .gitignore one/.gitignore one/two/.gitignore
+'
+
+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 .gitignore one/.gitignore one/two/.gitignore &&
+	rm .git/index
+'
+
 cat > excludes-file <<\EOF
 *.[1-8]
 e*
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 929d5d4..4886d5f 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 assume-unchanged .gitignore' '
+	git update-index --assume-unchanged .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-assume-unchanged .gitignore &&
+	git checkout .gitignore
+'
+
 test_expect_success 'git clean' '
 
 	mkdir -p build docs &&
-- 
1.6.3.GIT

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox