Git development
 help / color / mirror / Atom feed
* Re: [PATCH 5/5] git-add: add ignored files when asked explicitly.
From: Nicolas Pitre @ 2006-12-25 19:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7vslf3khsc.fsf@assigned-by-dhcp.cox.net>

On Mon, 25 Dec 2006, Junio C Hamano wrote:

> An alternative is to use the mechanism I added here to _detect_
> the attempt to add an ignored file with explicitly spelled out
> pathspec, and issue an info message that says something like:
> 
> 	Path 'xyzzy/filfre.o' is not being ignored by one of
> 	your .gitignore files.  If you really want to add it,
> 	please add this entry to .gitignore file:
> 
>         !/xyzzy/filfre.o

What about this instead:

	Path 'xyzzy/filfre.o' should be ignored according to one of
	your .gitignore files.  If you really want to add it, you must
	use the -f flag.


Nicolas

^ permalink raw reply

* [PATCH] git-add: warn when adding an ignored file with an explicit request.
From: Junio C Hamano @ 2006-12-25 18:39 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <7vslf3khsc.fsf@assigned-by-dhcp.cox.net>

We allow otherwise ignored paths to be added to the index by
spelling its path out on the command line, but we would warn the
user about them when we do so.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * This is on top of what I sent out last night.

 builtin-add.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/builtin-add.c b/builtin-add.c
index 822075a..c54c694 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -37,6 +37,9 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
 			free(entry);
 			continue;
 		}
+		if (entry->ignored_entry)
+			fprintf(stderr, "warning: '%s' is an ignored path.\n",
+				entry->name);
 		*dst++ = entry;
 	}
 	dir->nr = dst - dir->entries;
-- 
1.4.4.3.g71b5

^ permalink raw reply related

* Re: [RFC] git reflog show
From: Junio C Hamano @ 2006-12-25 18:07 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Shawn Pearce
In-Reply-To: <Pine.LNX.4.63.0612251449140.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Also I highly doubt visualization based on parents information rewritten 
>> to match the reflog order is of _any_ use.  By rewriting the parenthood, 
>> you are losing the topology and your visualization is no better than 
>> what "tac .git/logs/$ref" would give.
>
> Okay, but if they are _not_ rewritten, we can reuse the log machinery to 
> show the revisions in "upstream..master@{2.hours.ago}", but in the order 
> they came into the local repository.

Shawn's code was about showing where the tip of the branch was,
and I think you are talking about something entirely different,
which I would address later.

A sensible way to reuse existing code to implement Shawn's one
is to add the revisions to rev.pending, and iterate over that
array like "git show" does.  This does not need to touch the
existing revision walking code at all.  The most valuable parts
of the revision walking code are about ancestry traversal and
history simplification with pathspec, neither of which makes
much sense to use when "walking" reflog.  Reflog walking might
want to use the filtering by commit_match() but then it is only
the matter of renaming the function to a bit more specific name
and exporting it.

You can largely reuse the display side of the code that way, and
I think you should be able to hook into the code without making
it too specific to the reflog (perhaps using object->util and/or
a callback) if you need to give extra information (e.g. comments
and commit information from the log).

But it _also_ makes sense to use reflog when the primary thing
we are interested in seeing is not how the tip jumped around,
but seeing how the branch acquired commits, which I think is
what you are suggesting.  What we would want to have is a sort
order different from the existing topo or date, which is "reflog
order".  While I think it makes sense, a naive implementation
would be somewhat expensive.  Instead of sorting topologically
at the end of prepare_revision_walk (you would need to limit the
list if you do this), for each commit, you binary search the
reflog entries to find the earliest one that is the ancestor of
the commit, and use the reflog entry's timestamp as the age of
the commit (it's the first time the branch saw that commit), and
sort commits using that.

^ permalink raw reply

* Re: [PATCH 5/5] git-add: add ignored files when asked explicitly.
From: Junio C Hamano @ 2006-12-25 17:27 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0612251443230.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Mon, 25 Dec 2006, Junio C Hamano wrote:
>
>>     $ git add foo.o
>>     $ git add '*.o'
>
> Most people do
>
> 	$ git add *.o
>
> instead, where bash expands the expression. Maybe this new behaviour 
> should be hidden between a "-f" option?

When would anybody do "git add *.o"?

A more plausible situation is that you have '*.o' in .gitignore
because you do not want to keep track of object files generated
from your source, but your project needs to keep track of one
third-party object file that you do not have the source to, and
helping that situation is what this patch is about.

An alternative is to use the mechanism I added here to _detect_
the attempt to add an ignored file with explicitly spelled out
pathspec, and issue an info message that says something like:

	Path 'xyzzy/filfre.o' is not being ignored by one of
	your .gitignore files.  If you really want to add it,
	please add this entry to .gitignore file:

        !/xyzzy/filfre.o

One advantage of this is that it would help guiding the user in
the right direction, giving a reusable piece of knowledge,
without changing the behaviour of the command (what is refused
is refused).  But I can already see people's complaints: if the
tool knows how to fix that situation why forces the user to do
so?

Although the reason why the alternative does not do so is "The
user earlier said *.o files are uninteresting but came back with
a conflicting request to add xyzzy/filfre.o, which could be a
mistake.  We ask for a confirmation", which is very sensible,
another alternative would be to add the path anyway and issue an
warning, like this:

	$ ls xyzzy
        filfre.c	filfre.o
	$ git add xyzzy/filfre.?
	added ignored path xyzzy/filfre.o

^ permalink raw reply

* cgit vs. gitweb
From: Lars Hjemli @ 2006-12-25 17:21 UTC (permalink / raw)
  To: Git Mailing List

[-- Attachment #1: Type: text/plain, Size: 1593 bytes --]

Hi

I wanted to compare cgit against gitweb to see the effect of using
libgit and internal caching. So I ran the attached scripts against
http://hjemli.net/git/ and http://hjemli.net/cgi-bin/gitweb.cgi as a
very simplistic benchmark.

The scripts forks a number of similar child processes (specified by
$1) and then uses curl(1) to request the first log page of three
repositories $2 times. This is an attempt to simulate concurrent
requests for different pages/repositories (I chose the log-pages since
they're pretty similar in cgit and gitweb, both showing info for 100
commits).

The numbers are the average of three runs, executed from another box
on my subnet. To avoid a roundtrip to my ISP, the pages are accessed
by a local hostname.

So, here's the results, as measured by time(1):

fork count|cached uncached gitweb.cgi
---- -----+------ -------- ----------
   0    10|  0.28     0.46      15.33
   1    10|  0.56     0.77      29.72
  10    10|  2.77     4.22     166.40

fork: number of child processes
count: number of loop iterations, each requesting 3 different log-pages
cached: results for cgit with caching enabled
uncached: results for cgit with caching disabled
gitweb.cgi: results for gitweb

If ((fork+1) * count * 3) is taken as a rough estimate of the total
number of page requests, then requests/second looks like this:

 req| cached uncached gitweb.cgi
----+------- -------- ----------
  30| 107.14    65.22       1.96
  60| 107.14    77.92       2.01
 330| 119.13    78.20       1.98


-- 
larsh

ps: server is an AMD Athlon XP2600, running at ~2Ghz with 512MB ram

[-- Attachment #2: cgit.sh --]
[-- Type: application/x-sh, Size: 375 bytes --]

[-- Attachment #3: gitweb.sh --]
[-- Type: application/x-sh, Size: 427 bytes --]

^ permalink raw reply

* Re: [RFC] git reflog show
From: Johannes Schindelin @ 2006-12-25 14:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Shawn Pearce
In-Reply-To: <7v1wmpq83g.fsf@assigned-by-dhcp.cox.net>

Hi,

On Sun, 24 Dec 2006, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > Yes, but if we have to read the reflog anyway to determine the logical 
> > (local) parent, we can just as well read the message, and display it, 
> > too.
> >
> > What it buys us is that we do not duplicate efforts here, and we can 
> > easily visualize the reflog in gitk, too.
> 
> I do not think you can sanely rewrite parenthood.

Well, I did not mean to change the parents in the commit object. Rather, 
let the revision walker determine the parent differently for reflogs.

> Also I highly doubt visualization based on parents information rewritten 
> to match the reflog order is of _any_ use.  By rewriting the parenthood, 
> you are losing the topology and your visualization is no better than 
> what "tac .git/logs/$ref" would give.

Okay, but if they are _not_ rewritten, we can reuse the log machinery to 
show the revisions in "upstream..master@{2.hours.ago}", but in the order 
they came into the local repository.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 5/5] git-add: add ignored files when asked explicitly.
From: Johannes Schindelin @ 2006-12-25 13:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqlskz2u.fsf@assigned-by-dhcp.cox.net>

Hi,

On Mon, 25 Dec 2006, Junio C Hamano wrote:

>     $ git add foo.o
>     $ git add '*.o'

Most people do

	$ git add *.o

instead, where bash expands the expression. Maybe this new behaviour 
should be hidden between a "-f" option?

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/5] git-rm: update to saner semantics
From: Johannes Schindelin @ 2006-12-25 13:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vac1cmdrv.fsf@assigned-by-dhcp.cox.net>

Hi,

On Mon, 25 Dec 2006, Junio C Hamano wrote:

> +	 *	rm F; git fm F

Minor nit: s/fm/rm/.

Ciao,
Dscho

^ permalink raw reply

* [PATCH 5/5] git-add: add ignored files when asked explicitly.
From: Junio C Hamano @ 2006-12-25 11:13 UTC (permalink / raw)
  To: git

One thing many people found confusing about git-add was that a
file whose name matches an ignored pattern could not be added to
the index.  With this, such a file can be added by explicitly
spelling its name to git-add.

Fileglobs and recursive behaviour do not add ignored files to
the index.  That is, if a pattern '*.o' is in .gitignore, and
two files foo.o, bar/baz.o are in the working tree:

    $ git add foo.o
    $ git add '*.o'
    $ git add bar

Only the first form adds foo.o to the index.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 Documentation/git-add.txt |   11 ++++++++---
 builtin-add.c             |   11 ++++++++++-
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index d86c0e7..a8ed459 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -25,8 +25,9 @@ the commit.
 The 'git status' command can be used to obtain a summary of what is included
 for the next commit.
 
-This command only adds non-ignored files, to add ignored files use
-"git update-index --add".
+This command can be used to add ignored files, but they have to be
+explicitly and exactly specified from the command line.  File globbing
+and recursive behaviour do not add ignored files.
 
 Please see gitlink:git-commit[1] for alternative ways to add content to a
 commit.
@@ -35,7 +36,11 @@ commit.
 OPTIONS
 -------
 <file>...::
-	Files to add content from.
+	Files to add content from.  Fileglobs (e.g. `*.c`) can
+	be given to add all matching files.  Also a
+	leading directory name (e.g. `dir` to add `dir/file1`
+	and `dir/file2`) can be given to add all files in the
+	directory, recursively.
 
 -n::
         Don't actually add the file(s), just show if they exist.
diff --git a/builtin-add.c b/builtin-add.c
index f306f82..389c106 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -25,7 +25,14 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
 	i = dir->nr;
 	while (--i >= 0) {
 		struct dir_entry *entry = *src++;
-		if (!match_pathspec(pathspec, entry->name, entry->len, prefix, seen)) {
+		int how = match_pathspec(pathspec, entry->name, entry->len,
+					 prefix, seen);
+		/*
+		 * ignored entries can be added with exact match,
+		 * but not with glob nor recursive.
+		 */
+		if (!how ||
+		    (entry->ignored_entry && how != MATCHED_EXACTLY)) {
 			free(entry);
 			continue;
 		}
@@ -54,6 +61,8 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec)
 
 	/* Set up the default git porcelain excludes */
 	memset(dir, 0, sizeof(*dir));
+	if (pathspec)
+		dir->show_both = 1;
 	dir->exclude_per_dir = ".gitignore";
 	path = git_path("info/exclude");
 	if (!access(path, R_OK))
-- 
1.4.4.3.g50da

^ permalink raw reply related

* [PATCH 4/5] read_directory: show_both option.
From: Junio C Hamano @ 2006-12-25 11:11 UTC (permalink / raw)
  To: git

This teaches the internal read_directory() routine to return
both interesting and ignored pathnames.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 dir.c |   19 ++++++++++++-------
 dir.h |    6 ++++--
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/dir.c b/dir.c
index 8477472..dd188a8 100644
--- a/dir.c
+++ b/dir.c
@@ -260,7 +260,8 @@ int excluded(struct dir_struct *dir, const char *pathname)
 	return 0;
 }
 
-static void add_name(struct dir_struct *dir, const char *pathname, int len)
+static void add_name(struct dir_struct *dir, const char *pathname, int len,
+		     int ignored_entry)
 {
 	struct dir_entry *ent;
 
@@ -273,6 +274,7 @@ static void add_name(struct dir_struct *dir, const char *pathname, int len)
 		dir->entries = xrealloc(dir->entries, alloc*sizeof(ent));
 	}
 	ent = xmalloc(sizeof(*ent) + len + 1);
+	ent->ignored_entry = ignored_entry;
 	ent->len = len;
 	memcpy(ent->name, pathname, len);
 	ent->name[len] = 0;
@@ -314,6 +316,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
 
 		while ((de = readdir(fdir)) != NULL) {
 			int len;
+			int ignored_entry;
 
 			if ((de->d_name[0] == '.') &&
 			    (de->d_name[1] == 0 ||
@@ -322,11 +325,12 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
 				continue;
 			len = strlen(de->d_name);
 			memcpy(fullname + baselen, de->d_name, len+1);
-			if (excluded(dir, fullname) != dir->show_ignored) {
-				if (!dir->show_ignored || DTYPE(de) != DT_DIR) {
-					continue;
-				}
-			}
+			ignored_entry = excluded(dir, fullname);
+
+			if (!dir->show_both &&
+			    (ignored_entry != dir->show_ignored) &&
+			    (!dir->show_ignored || DTYPE(de) != DT_DIR))
+				continue;
 
 			switch (DTYPE(de)) {
 			struct stat st;
@@ -364,7 +368,8 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
 			if (check_only)
 				goto exit_early;
 			else
-				add_name(dir, fullname, baselen + len);
+				add_name(dir, fullname, baselen + len,
+					 ignored_entry);
 		}
 exit_early:
 		closedir(fdir);
diff --git a/dir.h b/dir.h
index c919727..08c6345 100644
--- a/dir.h
+++ b/dir.h
@@ -13,7 +13,8 @@
 
 
 struct dir_entry {
-	int len;
+	unsigned ignored_entry : 1;
+	unsigned int len : 15;
 	char name[FLEX_ARRAY]; /* more */
 };
 
@@ -29,7 +30,8 @@ struct exclude_list {
 
 struct dir_struct {
 	int nr, alloc;
-	unsigned int show_ignored:1,
+	unsigned int show_both: 1,
+		     show_ignored:1,
 		     show_other_directories:1,
 		     hide_empty_directories:1;
 	struct dir_entry **entries;
-- 
1.4.4.3.g50da

^ permalink raw reply related

* [PATCH 3/5] t3600: update the test for updated git rm
From: Junio C Hamano @ 2006-12-25 11:11 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 t/t3600-rm.sh |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 201d164..e31cf93 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -43,19 +43,19 @@ test_expect_success \
 
 test_expect_success \
     'Test that git-rm foo succeeds' \
-    'git-rm foo'
+    'git-rm --cached foo'
 
 test_expect_success \
     'Post-check that foo exists but is not in index after git-rm foo' \
     '[ -f foo ] && ! git-ls-files --error-unmatch foo'
 
 test_expect_success \
-    'Pre-check that bar exists and is in index before "git-rm -f bar"' \
+    'Pre-check that bar exists and is in index before "git-rm bar"' \
     '[ -f bar ] && git-ls-files --error-unmatch bar'
 
 test_expect_success \
-    'Test that "git-rm -f bar" succeeds' \
-    'git-rm -f bar'
+    'Test that "git-rm bar" succeeds' \
+    'git-rm bar'
 
 test_expect_success \
     'Post-check that bar does not exist and is not in index after "git-rm -f bar"' \
@@ -84,4 +84,74 @@ test_expect_success \
     'When the rm in "git-rm -f" fails, it should not remove the file from the index' \
     'git-ls-files --error-unmatch baz'
 
+# Now, failure cases.
+test_expect_success 'Re-add foo and baz' '
+	git add foo baz &&
+	git ls-files --error-unmatch foo baz
+'
+
+test_expect_success 'Modify foo -- rm should refuse' '
+	echo >>foo &&
+	! git rm foo baz &&
+	test -f foo &&
+	test -f baz &&
+	git ls-files --error-unmatch foo baz
+'
+
+test_expect_success 'Modified foo -- rm -f should work' '
+	git rm -f foo baz &&
+	test ! -f foo &&
+	test ! -f baz &&
+	! git ls-files --error-unmatch foo &&
+	! git ls-files --error-unmatch bar
+'
+
+test_expect_success 'Re-add foo and baz for HEAD tests' '
+	echo frotz >foo &&
+	git checkout HEAD -- baz &&
+	git add foo baz &&
+	git ls-files --error-unmatch foo baz
+'
+
+test_expect_success 'foo is different in index from HEAD -- rm should refuse' '
+	! git rm foo baz &&
+	test -f foo &&
+	test -f baz &&
+	git ls-files --error-unmatch foo baz
+'
+
+test_expect_success 'but with -f it should work.' '
+	git rm -f foo baz &&
+	test ! -f foo &&
+	test ! -f baz &&
+	! git ls-files --error-unmatch foo
+	! git ls-files --error-unmatch baz
+'
+
+test_expect_success 'Recursive test setup' '
+	mkdir -p frotz &&
+	echo qfwfq >frotz/nitfol &&
+	git add frotz &&
+	git commit -m "subdir test"
+'
+
+test_expect_success 'Recursive without -r fails' '
+	! git rm frotz &&
+	test -d frotz &&
+	test -f frotz/nitfol
+'
+
+test_expect_success 'Recursive with -r but dirty' '
+	echo qfwfq >>frotz/nitfol
+	! git rm -r frotz &&
+	test -d frotz &&
+	test -f frotz/nitfol
+'
+
+test_expect_success 'Recursive with -r -f' '
+	git rm -f -r frotz &&
+	! test -f frotz/nitfol &&
+	! test -d frotz
+'
+
 test_done
-- 
1.4.4.3.g50da

^ permalink raw reply related

* [PATCH 2/5] git-rm: update to saner semantics
From: Junio C Hamano @ 2006-12-25 11:11 UTC (permalink / raw)
  To: git

This updates the "git rm" command with saner semantics suggested
on the list earlier with:

	Message-ID: <Pine.LNX.4.64.0612020919400.3476@woody.osdl.org>
	Message-ID: <Pine.LNX.4.64.0612040737120.3476@woody.osdl.org>

The command still validates that the given paths all talk about
sensible paths to avoid mistakes (e.g. "git rm fiel" when file
"fiel" does not exist would error out -- user meant to remove
"file"), and it has further safety checks described next.  The
biggest difference is that the paths are removed from both index
and from the working tree (if you have an exotic need to remove
paths only from the index, you can use the --cached option).

The command refuses to remove if the copy on the working tree
does not match the index, or if the index and the HEAD does not
match.  You can defeat this check with -f option.

This safety check has two exceptions: if the working tree file
does not exist to begin with, that technically does not match
the index but it is allowed.  This is to allow this CVS style
command sequence:

	rm <path> && git rm <path>

Also if the index is unmerged at the <path>, you can use "git rm
<path>" to declare that the result of the merge loses that path,
and the above safety check does not trigger; requiring the file
to match the index in this case forces the user to do "git
update-index file && git rm file", which is just crazy.

To recursively remove all contents from a directory, you need to
pass -r option, not just the directory name as the <path>.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 builtin-rm.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 103 insertions(+), 20 deletions(-)

diff --git a/builtin-rm.c b/builtin-rm.c
index 33d04bd..5b078c4 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -7,9 +7,10 @@
 #include "builtin.h"
 #include "dir.h"
 #include "cache-tree.h"
+#include "tree-walk.h"
 
 static const char builtin_rm_usage[] =
-"git-rm [-n] [-v] [-f] <filepattern>...";
+"git-rm [-n] [-f] [--cached] <filepattern>...";
 
 static struct {
 	int nr, alloc;
@@ -41,12 +42,75 @@ static int remove_file(const char *name)
 	return ret;
 }
 
+static int check_local_mod(unsigned char *head)
+{
+	/* items in list are already sorted in the cache order,
+	 * so we could do this a lot more efficiently by using
+	 * tree_desc based traversal if we wanted to, but I am
+	 * lazy, and who cares if removal of files is a tad
+	 * slower than the theoretical maximum speed?
+	 */
+	int i, no_head;
+	int errs = 0;
+
+	no_head = is_null_sha1(head);
+	for (i = 0; i < list.nr; i++) {
+		struct stat st;
+		int pos;
+		struct cache_entry *ce;
+		const char *name = list.name[i];
+		unsigned char sha1[20];
+		unsigned mode;
+
+		pos = cache_name_pos(name, strlen(name));
+		if (pos < 0)
+			continue; /* removing unmerged entry */
+		ce = active_cache[pos];
+
+		if (lstat(ce->name, &st) < 0) {
+			if (errno != ENOENT)
+				fprintf(stderr, "warning: '%s': %s",
+					ce->name, strerror(errno));
+			/* It already vanished from the working tree */
+			continue;
+		}
+		else if (S_ISDIR(st.st_mode)) {
+			/* if a file was removed and it is now a
+			 * directory, that is the same as ENOENT as
+			 * far as git is concerned; we do not track
+			 * directories.
+			 */
+			continue;
+		}
+		if (ce_match_stat(ce, &st, 0))
+			errs = error("'%s' has local modifications "
+				     "(hint: try -f)", ce->name);
+		if (no_head)
+			continue;
+		/*
+		 * It is Ok to remove a newly added path, as long as
+		 * it is cache-clean.
+		 */
+		if (get_tree_entry(head, name, sha1, &mode))
+			continue;
+		/*
+		 * Otherwise make sure the version from the HEAD
+		 * matches the index.
+		 */
+		if (ce->ce_mode != create_ce_mode(mode) ||
+		    hashcmp(ce->sha1, sha1))
+			errs = error("'%s' has changes staged in the index "
+				     "(hint: try -f)", name);
+	}
+	return errs;
+}
+
 static struct lock_file lock_file;
 
 int cmd_rm(int argc, const char **argv, const char *prefix)
 {
 	int i, newfd;
-	int verbose = 0, show_only = 0, force = 0;
+	int show_only = 0, force = 0, index_only = 0, recursive = 0;
 	const char **pathspec;
 	char *seen;
 
@@ -62,23 +126,20 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 
 		if (*arg != '-')
 			break;
-		if (!strcmp(arg, "--")) {
+		else if (!strcmp(arg, "--")) {
 			i++;
 			break;
 		}
-		if (!strcmp(arg, "-n")) {
+		else if (!strcmp(arg, "-n"))
 			show_only = 1;
-			continue;
-		}
-		if (!strcmp(arg, "-v")) {
-			verbose = 1;
-			continue;
-		}
-		if (!strcmp(arg, "-f")) {
+		else if (!strcmp(arg, "--cached"))
+			index_only = 1;
+		else if (!strcmp(arg, "-f"))
 			force = 1;
-			continue;
-		}
-		usage(builtin_rm_usage);
+		else if (!strcmp(arg, "-r"))
+			recursive = 1;
+		else
+			usage(builtin_rm_usage);
 	}
 	if (argc <= i)
 		usage(builtin_rm_usage);
@@ -99,14 +160,36 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 	if (pathspec) {
 		const char *match;
 		for (i = 0; (match = pathspec[i]) != NULL ; i++) {
-			if (*match && !seen[i])
-				die("pathspec '%s' did not match any files", match);
+			if (!seen[i])
+				die("pathspec '%s' did not match any files",
+				    match);
+			if (!recursive && seen[i] == MATCHED_RECURSIVELY)
+				die("not removing '%s' recursively without -r",
+				    *match ? match : ".");
 		}
 	}
 
 	/*
+	 * If not forced, the file, the index and the HEAD (if exists)
+	 * must match; but the file can already been removed, since
+	 * this sequence is a natural "novice" way:
+	 *
+	 *	rm F; git fm F
+	 *
+	 * Further, if HEAD commit exists, "diff-index --cached" must
+	 * report no changes unless forced.
+	 */
+	if (!force) {
+		unsigned char sha1[20];
+		if (get_sha1("HEAD", sha1))
+			hashclr(sha1);
+		if (check_local_mod(sha1))
+			exit(1);
+	}
+
+	/*
 	 * First remove the names from the index: we won't commit
-	 * the index unless all of them succeed
+	 * the index unless all of them succeed.
 	 */
 	for (i = 0; i < list.nr; i++) {
 		const char *path = list.name[i];
@@ -121,14 +204,14 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 		return 0;
 
 	/*
-	 * Then, if we used "-f", remove the filenames from the
-	 * workspace. If we fail to remove the first one, we
+	 * Then, unless we used "--cache", remove the filenames from
+	 * the workspace. If we fail to remove the first one, we
 	 * abort the "git rm" (but once we've successfully removed
 	 * any file at all, we'll go ahead and commit to it all:
 	 * by then we've already committed ourselves and can't fail
 	 * in the middle)
 	 */
-	if (force) {
+	if (!index_only) {
 		int removed = 0;
 		for (i = 0; i < list.nr; i++) {
 			const char *path = list.name[i];
-- 
1.4.4.3.g50da

^ permalink raw reply related

* [PATCH 1/5] match_pathspec() -- return how well the spec matched
From: Junio C Hamano @ 2006-12-25 11:09 UTC (permalink / raw)
  To: git

This updates the return value from match_pathspec() so that the
caller can tell cases between exact match, leading pathname
match (i.e. file "foo/bar" matches a pathspec "foo"), or
filename glob match.  This can be used to prevent "rm dir" from
removing "dir/file" without explicitly asking for recursive
behaviour with -r flag, for example.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 dir.c |   51 +++++++++++++++++++++++++++++++++++----------------
 dir.h |    4 ++++
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/dir.c b/dir.c
index 16401d8..8477472 100644
--- a/dir.c
+++ b/dir.c
@@ -40,6 +40,18 @@ int common_prefix(const char **pathspec)
 	return prefix;
 }
 
+/*
+ * Does 'match' matches the given name?
+ * A match is found if
+ *
+ * (1) the 'match' string is leading directory of 'name', or
+ * (2) the 'match' string is a wildcard and matches 'name', or
+ * (3) the 'match' string is exactly the same as 'name'.
+ *
+ * and the return value tells which case it was.
+ *
+ * It returns 0 when there is no match.
+ */
 static int match_one(const char *match, const char *name, int namelen)
 {
 	int matchlen;
@@ -47,27 +59,30 @@ static int match_one(const char *match, const char *name, int namelen)
 	/* If the match was just the prefix, we matched */
 	matchlen = strlen(match);
 	if (!matchlen)
-		return 1;
+		return MATCHED_RECURSIVELY;
 
 	/*
 	 * If we don't match the matchstring exactly,
 	 * we need to match by fnmatch
 	 */
 	if (strncmp(match, name, matchlen))
-		return !fnmatch(match, name, 0);
+		return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
 
-	/*
-	 * If we did match the string exactly, we still
-	 * need to make sure that it happened on a path
-	 * component boundary (ie either the last character
-	 * of the match was '/', or the next character of
-	 * the name was '/' or the terminating NUL.
-	 */
-	return	match[matchlen-1] == '/' ||
-		name[matchlen] == '/' ||
-		!name[matchlen];
+	if (!name[matchlen])
+		return MATCHED_EXACTLY;
+	if (match[matchlen-1] == '/' || name[matchlen] == '/')
+		return MATCHED_RECURSIVELY;
+	return 0;
 }
 
+/*
+ * Given a name and a list of pathspecs, see if the name matches
+ * any of the pathspecs.  The caller is also interested in seeing
+ * all pathspec matches some names it calls this function with
+ * (otherwise the user could have mistyped the unmatched pathspec),
+ * and a mark is left in seen[] array for pathspec element that
+ * actually matched anything.
+ */
 int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen)
 {
 	int retval;
@@ -77,12 +92,16 @@ int match_pathspec(const char **pathspec, const char *name, int namelen, int pre
 	namelen -= prefix;
 
 	for (retval = 0; (match = *pathspec++) != NULL; seen++) {
-		if (retval & *seen)
+		int how;
+		if (retval && *seen == MATCHED_EXACTLY)
 			continue;
 		match += prefix;
-		if (match_one(match, name, namelen)) {
-			retval = 1;
-			*seen = 1;
+		how = match_one(match, name, namelen);
+		if (how) {
+			if (retval < how)
+				retval = how;
+			if (*seen < how)
+				*seen = how;
 		}
 	}
 	return retval;
diff --git a/dir.h b/dir.h
index 550551a..c919727 100644
--- a/dir.h
+++ b/dir.h
@@ -40,6 +40,10 @@ struct dir_struct {
 };
 
 extern int common_prefix(const char **pathspec);
+
+#define MATCHED_RECURSIVELY 1
+#define MATCHED_FNMATCH 2
+#define MATCHED_EXACTLY 3
 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
 
 extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen);
-- 
1.4.4.3.g50da

^ permalink raw reply related

* [PATCH 0/5] git-add/git-rm updates
From: Junio C Hamano @ 2006-12-25 11:09 UTC (permalink / raw)
  To: git

This series futzes with a pair of functions in dir.c machinery
and enhances git-add and git-rm command.

[PATCH 1/5] match_pathspec() -- return how well the spec matched

The function match_pathspec() takes the pathspec given from the
command line and tells if a given name matches it.  This
enhances its return value so that the command can tell how well
the name matches.  Earlier, the caller could not tell if matched
pathspec was exactly the same as the name, was a fileglob that
matched the name, or was a leading directory.

[PATCH 2/5] git-rm: update to saner semantics
[PATCH 3/5] t3600: update the test for updated git rm

This updates git-rm to saner semantics Linus suggested on the
list earlier, and updates the tests.  When a path is removed, it
is removed both from the working tree and from the index.  As a
safety measure, the path is required to be cache-clean, and also
must match the HEAD (unless it is before the initial commit on
the branch).

[PATCH 4/5] read_directory: show_both option.

The function read_directory() is the workhorse to traverse
working tree while taking '.gitignore' into account.  This
updates the function to allow callers that are interested in
both ignored and non-ignored paths to get both paths so that it
can do its own filtering on the result.

[PATCH 5/5] git-add: add ignored files when asked explicitly.

One thing many people found confusing about git-add was that a
file whose name matches an ignored pattern could not be added.
This is an RFC fix for the problem.

^ permalink raw reply

* Re: [PATCH] commit encoding: store it in commit header rather than mucking with NUL
From: Junio C Hamano @ 2006-12-25  7:27 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0612250134040.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>>  - I was not sure if the "assume the whole commit->buffer is in
>>    the local encoding and recode it into UTF-8" is correct.
>
> For the purpose of showing it, there is no point in using two different 
> encodings. I am not aware of any terminal (and do not own such a terminal 
> anyway) which can display text with parts encoded differently from the 
> rest.

That's not what I meant.  Because the definition of the contents
of the commit has been (and will be --- the unpublished topic
was about suggesting stronger convention across Porcelains) just
the set of fixed headers plus binary blob, the use of different
encodings is entirely up to the users.

I was afraid that there might be something we did (or we did not
do) that encouraged people to have their names (via environment
variables, or perhaps user.name) always in UTF-8 while recording
the log messages in the legacy encoding, and if that kind of use
is already done in the wild, we would end up having to not
reencode the header field but reencode the body.

But I do not think we ever encouraged encoding names in UTF-8 or
anything else (we did encourage use of UTF-8 in the commit log),
so I think we are Ok.
 

^ permalink raw reply

* Re: [PATCH 1/2] libgit.a: add some UTF-8 handling functions
From: Alexander Litvinov @ 2006-12-25  4:03 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Nicolas Pitre, Uwe Kleine-König, git
In-Reply-To: <Pine.LNX.4.63.0612222319230.19693@wbgn013.biozentrum.uni-wuerzburg.de>

> > > To me, characters are the symbols occupying one "column" each. Bytes
> > > are the 8-bit thingies that you usually use to encode the characters.

You can check man 3 wcwidth:
wcwidth - determine columns needed for a wide character

We possible could convert utf-8 encoded string into wchar_t[] and use that 
function.

^ permalink raw reply

* Re: [PATCH] commit encoding: store it in commit header rather than mucking with NUL
From: Johannes Schindelin @ 2006-12-25  0:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3b74q1c9.fsf@assigned-by-dhcp.cox.net>

Hi,

On Sun, 24 Dec 2006, Junio C Hamano wrote:

> Thanks for paying a very close attention to what is in 'pu'.

You're welcome ;-)

>  - I did not want to break existing git implementations, but
>    hadn't audited the commit header parsers to see if they do
>    not get upset when they see unrecognized header fields in
>    commit objects.

I did not really audit it, but am quite sure that only parse_commit() 
really walks the buffer, and even this function just ignores what comes 
after committer. But if I read the code correctly, then the mandatory 
headers ("tree parent* author committer") have to come first, in that 
order.

>  - I was not sure if the "assume the whole commit->buffer is in
>    the local encoding and recode it into UTF-8" is correct.

For the purpose of showing it, there is no point in using two different 
encodings. I am not aware of any terminal (and do not own such a terminal 
anyway) which can display text with parts encoded differently from the 
rest.

>  - Existing Porcelains such as gitk know i18n.commitencoding is
>    a hint to them by the core, and expect the core to give them
>    output in the local encoding.  With the change, the core
>    feeds UTF-8 to the caller, unless the Porcelain gets the log
>    with plumbing "cat-file".  This means they either have to
>    lose code to do their own recoding (which is probably a good
>    thing in the long run), or we would need to have a flag for
>    them to tell the core not to do the conversion.  But a new
>    flag to ask for older behaviour is always a wrong way of
>    transitioning across backward incompatibility.
> 
>    I think the output conversion from the log should be more
>    explicitly asked for it, than just a mere configuration
>    variable that cannot be overriden by gitk and friends.

Probably a new flag "--encoding" to log, which sets git_commit_encoding. 
And the function you introduced should probably not blindly convert to 
UTF-8, but to the current git_commit_encoding.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] commit encoding: store it in commit header rather than mucking with NUL
From: Junio C Hamano @ 2006-12-25  0:13 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, junkio
In-Reply-To: <Pine.LNX.4.63.0612241643440.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Thanks for paying a very close attention to what is in 'pu'.
The series was a work in progress not yet ready for publication,
which I merged by mistake because I was way too sleepy.

There are three reasons (and a half -- it was not even compile
tested) that I did not mean to merge it yet.

 - I did not want to break existing git implementations, but
   hadn't audited the commit header parsers to see if they do
   not get upset when they see unrecognized header fields in
   commit objects.  The 'trailer' was just a quick hack to have
   something working for me to test the output conversion code.
   I've looked at the code since then and I think it is Ok to
   add new ones after author/name fields like you did.

   If we _were_ to do this, I think it is preferable to make it
   a header, not a trailer like I did.

 - I was not sure if the "assume the whole commit->buffer is in
   the local encoding and recode it into UTF-8" is correct.  The
   message body ought to be in i18n.commitencoding from the
   repository the commit comes from, which is now recorded in
   the trailer (or the header as in your patch), but what I was
   unsure about was the encoding in which author and committer
   names are recorded.  I think they are set either by the
   environment variables or user.name to be consistent with
   i18n.commitencoding in the repository the commit is made, so
   it is Ok after all.

 - Existing Porcelains such as gitk know i18n.commitencoding is
   a hint to them by the core, and expect the core to give them
   output in the local encoding.  With the change, the core
   feeds UTF-8 to the caller, unless the Porcelain gets the log
   with plumbing "cat-file".  This means they either have to
   lose code to do their own recoding (which is probably a good
   thing in the long run), or we would need to have a flag for
   them to tell the core not to do the conversion.  But a new
   flag to ask for older behaviour is always a wrong way of
   transitioning across backward incompatibility.

   I think the output conversion from the log should be more
   explicitly asked for it, than just a mere configuration
   variable that cannot be overriden by gitk and friends.

^ permalink raw reply

* Re: [RFC] git reflog show
From: Junio C Hamano @ 2006-12-24 21:47 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Shawn Pearce
In-Reply-To: <Pine.LNX.4.63.0612241333280.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Yes, but if we have to read the reflog anyway to determine the logical 
> (local) parent, we can just as well read the message, and display it, too.
>
> What it buys us is that we do not duplicate efforts here, and we can 
> easily visualize the reflog in gitk, too.

I do not think you can sanely rewrite parenthood.

Think about this sequence

	$ git init-db; edit foo; git add foo
	$ git commit -m 'first'
	$ edit foo; git add foo
        $ git commit -m 'second'
        $ git reset --hard HEAD@{1}

At this point, the commits on the reflog are:

        $ git show-branch --reflog=3 HEAD
        ! [HEAD@{0}] first
         ! [HEAD@{1}] second
          ! [HEAD@{2}] first
        ---
         +  [HEAD@{1}] second
        +++ [HEAD@{0}] first

We are currently at the first commit, and its "rewritten" parent
should point at the second commit (i.e. pretend HEAD@{1} is the
parent of HEAD@{0}).  The "rewritten" parent of the second commit
should be HEAD@{2}, but that is actually the same first commit
which is HEAD@{0}.

Also I highly doubt visualization based on parents information
rewritten to match the reflog order is of _any_ use.  By
rewriting the parenthood, you are losing the topology and your
visualization is no better than what "tac .git/logs/$ref" would
give.

I do agree that reusing the message formattng and display code
from the usual log machinery is desirable.  I think you can hook
that information somewhere in object->util (or a callback
mechanism) and teach log display machinery to use it as a
generic mechanism.  That might make the existing code to insert
"Subject: " for --pretty=format simpler, but I haven't looked.

^ permalink raw reply

* Re: Separating "add path to index" from "update content in index"
From: Daniel Barkalow @ 2006-12-24 21:38 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Carl Worth, Junio C Hamano, Peter Baumann, git
In-Reply-To: <Pine.LNX.4.64.0612221709380.18171@xanadu.home>

On Sat, 23 Dec 2006, Nicolas Pitre wrote:

> On Fri, 22 Dec 2006, Carl Worth wrote:
> 
> > On Fri, 22 Dec 2006 00:06:32 -0500 (EST), Nicolas Pitre wrote:
> > > On Thu, 21 Dec 2006, Carl Worth wrote:
> > >
> > > > So, I think what I really want here is a complete separation in the
> > > > interface between adding a path to the index and updating content into
> > > > the index.
> > >
> > > Strangely enough I think this separation is unnecessary and redundent.
> > 
> > One argument I would make in favor of the separation is that the two
> > operations are conceptually distinct from the user point-of-view. But
> > that's really hard to nail down since all users have different points
> > of view and different conceptual models,
> 
> ... and if we want to break the CVS model and give people a better 
> chance of ever grasping the git index concept I think they should not be 
> different.

I don't think the misunderstanding (if there is one) of the git index 
model is due to CVS. If I'm using a staging area for wrapping Christmas 
presents, I may assign space to items I haven't got yet: this is where I 
put the tape so I can reach it, this is where the roll of wrapping paper 
goes, here is where the wrapping paper will be spread out, but I can't 
spread out the wrapping paper until I have the present (it just rolls back 
up), so there's nothing in the spot allocated to actual wrapping. Git 
reminds me of people who have to put a trash can in their parking spaces 
when their cars aren't there to keep them from being deallocated simply 
because they're empty.

The allocation of empty space before anything is put in it is a 
fundamental operation available in the general concept of a staging 
area. Someone coming from an index-based version-control system that 
doesn't lack this feature would expect to have a possible status:

# Changed but not updated:
#   (use git-update-index to mark for commit)
#
#       new file: new-test-file
#

(And note that it can't be CVS-damage, because "Changed but not updated" 
isn't supported by CVS. This is a way in which git sort of has CVS-damage, 
because the "new file" operation goes straight to "Updated but not checked 
in", unlike everything else.)

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: confusion over the new branch and merge config
From: Nicolas Pitre @ 2006-12-24 20:49 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7vbqlvrldk.fsf@assigned-by-dhcp.cox.net>

On Sat, 23 Dec 2006, Junio C Hamano wrote:

> If you (or other people) use branch.*.merge, with its value set
> to remote name _and_ local name, and actually verify that either
> form works without confusion, please report back and I'll apply.

This is nice, thanks.

What would be nice as well is to be able to provide only the _name_ of 
the tracking branch without the refs/remotes/$origin/ prefix.  Since 
there is already a 'branch."blah".remote = $origin' entry, then having 
'branch."blah".merge = $foo' could mean "refs/remotes/$origin/$foo" when 
$foo contains no slash.


Nicolas

^ permalink raw reply

* Re: [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED.
From: Shawn Pearce @ 2006-12-24 20:34 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612241410400.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> All in all it is a good change -- for the builtin programs.
> 
> But it is less good for the libification. Maybe it is time for a 
> discussion about the possible strategies to avoid dying in libgit.a?

Well we have the same problem with xmalloc.  All I've done is move
the MAP_FAILED cases which tend to wind up die()'ing later anyway
into the same scope of area where the xmalloc issue is.

We die() all over the place.  ~1312 times according to 'git grep die'.
Git isn't a program for the living.  :-)

To properly libify we have a few issues:

  - we cannot just exit this process when we run into an error;

  - routines need to cleanup temporary resources (memory, file
    descriptors) when returning an error;

  - static variables like environment.c need to be reorganized to
    support multiple repositories in the same program;

  - objects need to be able to be deallocated, especially
    if the revision walking machinary has done rewriting

Though the die() is the largest issue.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 2/7] Switch git_mmap to use pread.
From: Linus Torvalds @ 2006-12-24 20:14 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612241407250.19693@wbgn013.biozentrum.uni-wuerzburg.de>



On Sun, 24 Dec 2006, Johannes Schindelin wrote:
> 
> I don't think it matters much. The _only_ platform we really use NO_MMAP 
> (other than for testing) is Windows, and AFAICT it does not have pread(), 
> so it is emulated by lseek/read/lseek anyway.

Windows definitely has pread(). It is, of course, possible that Cygwin 
emulates it some other way (including doing a "lseek/read/lseek" 
combination), but pread() should still be better - because maybe some 
future cygwin release ends up using the native interfaces.

		Linus

^ permalink raw reply

* Re: [PATCH 2/7] Switch git_mmap to use pread.
From: Shawn Pearce @ 2006-12-24 20:13 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612241407250.19693@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Sun, 24 Dec 2006, Shawn O. Pearce wrote:
> > Now that Git depends on pread in index-pack its safe to say we can
> > also depend on it within the git_mmap emulation we activate when
> > NO_MMAP is set.  On most systems pread should be slightly faster
> > than an lseek/read/lseek sequence as its one system call vs. three
> > system calls.
> 
> I don't think it matters much. The _only_ platform we really use NO_MMAP 
> (other than for testing) is Windows, and AFAICT it does not have pread(), 
> so it is emulated by lseek/read/lseek anyway.
> 
> But it's a cleanup, and it deletes more lines than it adds, so Ack from 
> me.

Right - that's why I did it.  I was already in there doing other work
and discovered that we had a lot of lines just to avoid using pread.
Initially that may have been because we were trying to avoid using
it, but now that one of our more important tools (index-pack)
depends on it... ;-)

I'm actually thinking of doing a NO_PACK_MMAP, especially for systems
like Mac OS X where the mmap() of small chunks appears to perform
so poorly.  Setting NO_PACK_MMAP and just using smaller windows
(1 MiB) might be worthwhile.  Though in that case we may just want
to compile with NO_MMAP.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 2/7] Switch git_mmap to use pread.
From: Alon Ziv @ 2006-12-24 19:30 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612241407250.19693@wbgn013.biozentrum.uni-wuerzburg.de>

[-- Attachment #1: Type: text/plain, Size: 522 bytes --]

On Sun, 2006-12-24 at 14:09 +0100, Johannes Schindelin wrote:
> I don't think it matters much. The _only_ platform we really use NO_MMAP 
> (other than for testing) is Windows, and AFAICT it does not have pread(), 
> so it is emulated by lseek/read/lseek anyway.
> 

Well, Win32 does have a pread()-like behavior in its generic ReadFile()
system call (using a curiously-named "lpOverlapped" parameter).  I would
have expected Cygwin to use it, but unfortunately from the CVS sources
it appears not to :(

	-az

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2156 bytes --]

^ permalink raw reply


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