Git development
 help / color / mirror / Atom feed
* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Yann Dirson @ 2006-05-19 18:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vsln7lzbj.fsf@assigned-by-dhcp.cox.net>

On Thu, May 18, 2006 at 03:53:36PM -0700, Junio C Hamano wrote:
> Yann Dirson <ydirson@altern.org> writes:
> 
> > To make my point maybe more clear: if someone really wants to make a
> > graft permanent, wouldn't some history rewriting ... be the
> > way to go,...
> 
> Yes.

So if temporary usage is a typical use for grafts, don't we want to
protect people using them from pruning ?  I got no feedback to my
suggestion of changing the default behaviour, even to say it was a bad
idea :)

Best regards,
-- 
Yann Dirson    <ydirson@altern.org> |
Debian-related: <dirson@debian.org> |   Support Debian GNU/Linux:
                                    |  Freedom, Power, Stability, Gratis
     http://ydirson.free.fr/        | Check <http://www.debian.org/>

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Jakub Narebski @ 2006-05-19 19:00 UTC (permalink / raw)
  To: git
In-Reply-To: <20060519185558.GE6535@nowhere.earth>

Yann Dirson wrote:

> On Thu, May 18, 2006 at 03:53:36PM -0700, Junio C Hamano wrote:
>> Yann Dirson <ydirson@altern.org> writes:
>> 
>> > To make my point maybe more clear: if someone really wants to make a
>> > graft permanent, wouldn't some history rewriting ... be the
>> > way to go,...
>> 
>> Yes.
> 
> So if temporary usage is a typical use for grafts, don't we want to
> protect people using them from pruning ?  I got no feedback to my
> suggestion of changing the default behaviour, even to say it was a bad
> idea :)

Perhaps prune should be conservative by default, and follow both grafts and
original parents, and use appropriate options to preserve or not preserve
grafts.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Linus Torvalds @ 2006-05-19 19:02 UTC (permalink / raw)
  To: Yann Dirson; +Cc: Junio C Hamano, git
In-Reply-To: <20060519185558.GE6535@nowhere.earth>



On Fri, 19 May 2006, Yann Dirson wrote:

> On Thu, May 18, 2006 at 03:53:36PM -0700, Junio C Hamano wrote:
> > Yann Dirson <ydirson@altern.org> writes:
> > 
> > > To make my point maybe more clear: if someone really wants to make a
> > > graft permanent, wouldn't some history rewriting ... be the
> > > way to go,...
> > 
> > Yes.
> 
> So if temporary usage is a typical use for grafts, don't we want to
> protect people using them from pruning ?  I got no feedback to my
> suggestion of changing the default behaviour, even to say it was a bad
> idea :)

I don't actually know how much grafts end up being used. Right now, the 
only really valid use I know about is to graft together the old kernel 
history kind of thing, and I suspect not a whole lot of people do that (I 
keep a separate kernel history tree around for when I need to look at it, 
and it doesn't happen all that often).

So I think the lack of feedback on the graft-related issue comes directly 
from that lack of graft usage. 

We _could_ decide that fsck should just follow the "real parents" and the 
grafts _both_. That's the safe thing to do by default. Possibly with a 
flag to say "prefer one over the other", or even a "prefer which-ever 
exists".

		Linus

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Yann Dirson @ 2006-05-19 20:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0605191159520.10823@g5.osdl.org>

On Fri, May 19, 2006 at 12:02:48PM -0700, Linus Torvalds wrote:
> 
> 
> On Fri, 19 May 2006, Yann Dirson wrote:
> 
> > On Thu, May 18, 2006 at 03:53:36PM -0700, Junio C Hamano wrote:
> > > Yann Dirson <ydirson@altern.org> writes:
> > > 
> > > > To make my point maybe more clear: if someone really wants to make a
> > > > graft permanent, wouldn't some history rewriting ... be the
> > > > way to go,...
> > > 
> > > Yes.
> > 
> > So if temporary usage is a typical use for grafts, don't we want to
> > protect people using them from pruning ?  I got no feedback to my
> > suggestion of changing the default behaviour, even to say it was a bad
> > idea :)
> 
> I don't actually know how much grafts end up being used. Right now, the 
> only really valid use I know about is to graft together the old kernel 
> history kind of thing, and I suspect not a whole lot of people do that (I 
> keep a separate kernel history tree around for when I need to look at it, 
> and it doesn't happen all that often).
> 
> So I think the lack of feedback on the graft-related issue comes directly 
> from that lack of graft usage. 

I take this as an incentive to share my use of the think :)

On several projects managed with CVS, I use a git mirror (maintained
with git-cvsimport for now) to prepare my sets of patches with stgit,
before committing them to cvs (through git-cvsexportcommit).  In this
context, since merges are not recorded in cvs, and cvs insists that
all branches must derive from the trunk, I use grafts to:

	1. record merges
	2. cause git to believe that the trunk derives from the vendor
	   branch
	3. hide those pseudo revisions cvs adds to rcs files saying
	   "file was initially added to branch foo"

It is the latter use which caused the loss previously mentionned.  It
could have been avoided by making cvsimport, or more likely cvsps more
clever wrt this case.


> We _could_ decide that fsck should just follow the "real parents" and the 
> grafts _both_. That's the safe thing to do by default. Possibly with a 
> flag to say "prefer one over the other", or even a "prefer which-ever 
> exists".

I'm not sure I see how "prefer which-ever exists" would be useful - do
you have anything precise in mind ?

Best regards,
-- 
Yann Dirson    <ydirson@altern.org> |
Debian-related: <dirson@debian.org> |   Support Debian GNU/Linux:
                                    |  Freedom, Power, Stability, Gratis
     http://ydirson.free.fr/        | Check <http://www.debian.org/>

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Linus Torvalds @ 2006-05-19 20:45 UTC (permalink / raw)
  To: Yann Dirson; +Cc: Junio C Hamano, git
In-Reply-To: <20060519202540.GF6535@nowhere.earth>



On Fri, 19 May 2006, Yann Dirson wrote:
> 
> > We _could_ decide that fsck should just follow the "real parents" and the 
> > grafts _both_. That's the safe thing to do by default. Possibly with a 
> > flag to say "prefer one over the other", or even a "prefer which-ever 
> > exists".
> 
> I'm not sure I see how "prefer which-ever exists" would be useful - do
> you have anything precise in mind ?

It would be a "once you've pruned one or the other, don't complain any 
more about the fact that it doesn't exist" flag.

		Linus

^ permalink raw reply

* [PATCH] Document that "git add" only adds non-ignored files.
From: Santi @ 2006-05-19 21:02 UTC (permalink / raw)
  To: git, Junio C Hamano

Signed-off-by: Santi Béjar <sbejar@gmail.com>


---

 Documentation/git-add.txt |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

9c057bcba388450963085eb5c751b734c04ff045
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 5e31129..1b6a22a 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -7,18 +7,20 @@ git-add - Add files to the index file

 SYNOPSIS
 --------
-'git-add' [-n] [-v] [--] <file>...
+'git-add' [-n] [-v] [--] <filepattern>...

 DESCRIPTION
 -----------
 A simple wrapper for git-update-index to add files to the index,
 for people used to do "cvs add".

+It only adds non-ignored files, to add ignored files use
+"git update-index --add".

 OPTIONS
 -------
-<file>...::
-       Files to add to the index.
+<filepattern>...::
+       Files to add to the index, see gitlink:git-ls-files[1].

 -n::
         Don't actually add the file(s), just show if they exist.
@@ -68,6 +70,7 @@ git-add git-*.sh::
 See Also
 --------
 gitlink:git-rm[1]
+gitlink:git-ls-files[1]

 Author
 ------
--
1.3.3.g97ee3

^ permalink raw reply related

* Re: [PATCH] built-in tar-tree and remote tar-tree
From: Sven Ekman @ 2006-05-19 21:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7j4ik1fr.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> skrev:

> Sorry for sending a crapoid that does not even
> compile.  I ran format-patch while on a wrong 
> branch.
> 
> Tonight's "pu" will have a fixed up one for 
> people who are interested to play with.

Hi Junio,

Thanks for your answer. I'm looking forward to try the
remote tar-tree at the weekend.  While this will
definitely make it much more easy to grab single
revisions out of a git tree, it only solves a part of
the issue I was trying to address. If one wanted a
simple snapshot of the source, it's usually easier to
download a tarball. 

The great thing about having the kernel source in a
git repository is that it lets me upgrade the kernel
source tree in place with a single simple command. No
firing up a browser, downloading and applying a patch.
It is also braindead easy to maintain a set of local
patches across different kernel versions. Git makes
all this quick and easy.

Is there a simple way to retrieve a single object or a
list of objects _without_ any of their parents? If so
one could retrieve the wanted commit and the
corresponding tree and parse it on the client side to
retrieve its descendents and commits.  If so, the
number of roundtrips would be roughly proportional to
the depth of the trees, which would probably still be
acceptable.

Greetings, Sven

^ permalink raw reply

* Re: [PATCH] built-in tar-tree and remote tar-tree
From: Jakub Narebski @ 2006-05-19 21:56 UTC (permalink / raw)
  To: git
In-Reply-To: <20060519214318.38240.qmail@web25910.mail.ukl.yahoo.com>

Sven Ekman wrote:

> Is there a simple way to retrieve a single object or a
> list of objects _without_ any of their parents? If so
> one could retrieve the wanted commit and the
> corresponding tree and parse it on the client side to
> retrieve its descendents and commits.  If so, the
> number of roundtrips would be roughly proportional to
> the depth of the trees, which would probably still be
> acceptable.

Perhaps alternates file which points to _remote_ git repository, 
leaving all unused objects at remote directory, and needing constant
net access to said remote repository for almost all operations?

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH] Document that "git add" only adds non-ignored files.
From: Junio C Hamano @ 2006-05-19 21:56 UTC (permalink / raw)
  To: Santi; +Cc: git, Junio C Hamano
In-Reply-To: <8aa486160605191402k2863e5edk@mail.gmail.com>

Thanks for the reminder, but I wonder if it is good to update
the description of this command, and ls-files to use the
same wording for consistency.  We seem to use <pathspec> to mean
"this is not necessarily a filename -- we glob", so that may be
a good candidate (we do not have <pathspec> in glossary yet --
we would need to add).

Please don't touch description for diff-* family -- right now,
they say <path>, because they do not glob.  If we decide that it
is a good idea to glob (which I suspect we don't for the
low-level stuff, but we probably do for the "git-diff" wrapper),
we would update the code and the description at the same time.

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Junio C Hamano @ 2006-05-19 22:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Yann Dirson, git
In-Reply-To: <Pine.LNX.4.64.0605191159520.10823@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> On Fri, 19 May 2006, Yann Dirson wrote:
>
>> On Thu, May 18, 2006 at 03:53:36PM -0700, Junio C Hamano wrote:
>> > Yann Dirson <ydirson@altern.org> writes:
>> > 
>> > > To make my point maybe more clear: if someone really wants to make a
>> > > graft permanent, wouldn't some history rewriting ... be the
>> > > way to go,...
>> > 
>> > Yes.
>> 
>> So if temporary usage is a typical use for grafts, don't we want to
>> protect people using them from pruning ?  I got no feedback to my
>> suggestion of changing the default behaviour, even to say it was a bad
>> idea :)

I just gave a terse "Yes" because I agree with Yann that if
really a permanent history rewriting is needed it should be done
by history rewriting not with graft (I do not necessarily
encourage people to rewrite history but if somebody wants to,
that is).

> We _could_ decide that fsck should just follow the "real parents" and the 
> grafts _both_. That's the safe thing to do by default. Possibly with a 
> flag to say "prefer one over the other", or even a "prefer which-ever 
> exists".

I agree with everything Linus said about the current grafts
usage.  My vote for fsck is to make it default to follow both by
default for safety, and perhaps an optional --ignore-graft
flag.

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw  awayrevs hidden by a graft.
From: David Lang @ 2006-05-19 22:26 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Yann Dirson, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0605191159520.10823@g5.osdl.org>

On Fri, 19 May 2006, Linus Torvalds wrote:

> On Fri, 19 May 2006, Yann Dirson wrote:
>
>> On Thu, May 18, 2006 at 03:53:36PM -0700, Junio C Hamano wrote:
>>> Yann Dirson <ydirson@altern.org> writes:
>>>
>>>> To make my point maybe more clear: if someone really wants to make a
>>>> graft permanent, wouldn't some history rewriting ... be the
>>>> way to go,...
>>>
>>> Yes.
>>
>> So if temporary usage is a typical use for grafts, don't we want to
>> protect people using them from pruning ?  I got no feedback to my
>> suggestion of changing the default behaviour, even to say it was a bad
>> idea :)
>
> I don't actually know how much grafts end up being used. Right now, the
> only really valid use I know about is to graft together the old kernel
> history kind of thing, and I suspect not a whole lot of people do that (I
> keep a separate kernel history tree around for when I need to look at it,
> and it doesn't happen all that often).
>
> So I think the lack of feedback on the graft-related issue comes directly
> from that lack of graft usage.

if/when shallow clones become available I would expect to see graft useage 
climb significantly

David Lang

-- 
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
  -- C.A.R. Hoare

^ permalink raw reply

* Re: Libify the index refresh logic
From: Junio C Hamano @ 2006-05-19 22:36 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605190942060.10823@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> This cleans up and libifies the "git update-index --[really-]refresh" 
> functionality. This will be eventually required for eventually doing the 
> "commit" and "status" commands as built-ins.

Thanks.

With the recent torrent of moving functions around across files
without necessarily making the old file empty (thus resulting in
what some people call "file rename"), the Porcelainish people
would have enough testcases to think about how to handle merges
that involve with cases like these.

^ permalink raw reply

* Re: [PATCH] built-in tar-tree and remote tar-tree
From: Junio C Hamano @ 2006-05-19 22:56 UTC (permalink / raw)
  To: Sven Ekman; +Cc: git
In-Reply-To: <20060519214318.38240.qmail@web25910.mail.ukl.yahoo.com>

Sven Ekman <svekman@yahoo.se> writes:

> Thanks for your answer. I'm looking forward to try the
> remote tar-tree at the weekend.

A word of caution.  This obviously needs the updated stuff on
both ends.  The downloader needs to have updated tar-tree, and
the other end needs the new command upload-tar.

> Is there a simple way to retrieve a single object or a
> list of objects _without_ any of their parents?

The thing is, I do not think that is what you really want.

If you do not have the necessary parents, many of the benefit
you list as "why do I want kernel from git repo" would not work.
The next fetch will try to see where the common ancestry commit
is, in order to download only from that one, for example. For
that you would need a well formed repositories on both ends.

Obviously bisect and anything that deal with the traversal of
ancestry chain would break, and while you would say "I accept
that some things may not work", their failure mode do not even
consider that the user might start from such an incomplete
repositories to begin with, so one thing is that the user would
be very confused, and another thing is that I would not be
surprised if some operations further "corrupt" such an already
incomplete repository (fsck, prune and probably bisect when it
tries to rewind the bisection branch -- your branch head may
point at nowhere and the user might need to do manual update-ref
instead of "git checkout master" to recover from it), causing
further grief.

In other words, to support such partial/incomplete repositories
properly, you are talking about a major major surgery.  I just
do not want to think about it right now.

On the other hand, the primary point of my patch is that the
result does _not_ pretend it is a proper git repository, so we
do not have to worry about all the above issues.

^ permalink raw reply

* [PATCH 1/2] Move pathspec matching from builtin-add.c into dir.c
From: Linus Torvalds @ 2006-05-19 23:07 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


I'll use it for builtin-rm.c too.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

diff --git a/builtin-add.c b/builtin-add.c
index 2afb82d..02fe38b 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -13,86 +13,6 @@ #include "cache-tree.h"
 static const char builtin_add_usage[] =
 "git-add [-n] [-v] <filepattern>...";
 
-static int common_prefix(const char **pathspec)
-{
-	const char *path, *slash, *next;
-	int prefix;
-
-	if (!pathspec)
-		return 0;
-
-	path = *pathspec;
-	slash = strrchr(path, '/');
-	if (!slash)
-		return 0;
-
-	prefix = slash - path + 1;
-	while ((next = *++pathspec) != NULL) {
-		int len = strlen(next);
-		if (len >= prefix && !memcmp(path, next, len))
-			continue;
-		for (;;) {
-			if (!len)
-				return 0;
-			if (next[--len] != '/')
-				continue;
-			if (memcmp(path, next, len+1))
-				continue;
-			prefix = len + 1;
-			break;
-		}
-	}
-	return prefix;
-}
-
-static int match_one(const char *match, const char *name, int namelen)
-{
-	int matchlen;
-
-	/* If the match was just the prefix, we matched */
-	matchlen = strlen(match);
-	if (!matchlen)
-		return 1;
-
-	/*
-	 * If we don't match the matchstring exactly,
-	 * we need to match by fnmatch
-	 */
-	if (strncmp(match, name, matchlen))
-		return !fnmatch(match, name, 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];
-}
-
-static int match(const char **pathspec, const char *name, int namelen, int prefix, char *seen)
-{
-	int retval;
-	const char *match;
-
-	name += prefix;
-	namelen -= prefix;
-
-	for (retval = 0; (match = *pathspec++) != NULL; seen++) {
-		if (retval & *seen)
-			continue;
-		match += prefix;
-		if (match_one(match, name, namelen)) {
-			retval = 1;
-			*seen = 1;
-		}
-	}
-	return retval;
-}
-
 static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
 {
 	char *seen;
@@ -108,7 +28,7 @@ static void prune_directory(struct dir_s
 	i = dir->nr;
 	while (--i >= 0) {
 		struct dir_entry *entry = *src++;
-		if (!match(pathspec, entry->name, entry->len, prefix, seen)) {
+		if (!match_pathspec(pathspec, entry->name, entry->len, prefix, seen)) {
 			free(entry);
 			continue;
 		}
diff --git a/dir.c b/dir.c
index d40b62e..d778ecd 100644
--- a/dir.c
+++ b/dir.c
@@ -11,6 +11,86 @@ #include <fnmatch.h>
 #include "cache.h"
 #include "dir.h"
 
+int common_prefix(const char **pathspec)
+{
+	const char *path, *slash, *next;
+	int prefix;
+
+	if (!pathspec)
+		return 0;
+
+	path = *pathspec;
+	slash = strrchr(path, '/');
+	if (!slash)
+		return 0;
+
+	prefix = slash - path + 1;
+	while ((next = *++pathspec) != NULL) {
+		int len = strlen(next);
+		if (len >= prefix && !memcmp(path, next, len))
+			continue;
+		for (;;) {
+			if (!len)
+				return 0;
+			if (next[--len] != '/')
+				continue;
+			if (memcmp(path, next, len+1))
+				continue;
+			prefix = len + 1;
+			break;
+		}
+	}
+	return prefix;
+}
+
+static int match_one(const char *match, const char *name, int namelen)
+{
+	int matchlen;
+
+	/* If the match was just the prefix, we matched */
+	matchlen = strlen(match);
+	if (!matchlen)
+		return 1;
+
+	/*
+	 * If we don't match the matchstring exactly,
+	 * we need to match by fnmatch
+	 */
+	if (strncmp(match, name, matchlen))
+		return !fnmatch(match, name, 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];
+}
+
+int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen)
+{
+	int retval;
+	const char *match;
+
+	name += prefix;
+	namelen -= prefix;
+
+	for (retval = 0; (match = *pathspec++) != NULL; seen++) {
+		if (retval & *seen)
+			continue;
+		match += prefix;
+		if (match_one(match, name, namelen)) {
+			retval = 1;
+			*seen = 1;
+		}
+	}
+	return retval;
+}
+
 void add_exclude(const char *string, const char *base,
 		 int baselen, struct exclude_list *which)
 {
diff --git a/dir.h b/dir.h
index 4f65f57..56a1b7f 100644
--- a/dir.h
+++ b/dir.h
@@ -39,6 +39,9 @@ struct dir_struct {
 	struct exclude_list exclude_list[3];
 };
 
+extern int common_prefix(const char **pathspec);
+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);
 extern int excluded(struct dir_struct *, const char *);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);

^ permalink raw reply related

* [PATCH 2/2] Add builtin "git rm" command
From: Linus Torvalds @ 2006-05-19 23:19 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605191607010.10823@g5.osdl.org>


This changes semantics very subtly, because it adds a new atomicity 
guarantee.

In particular, if you "git rm" several files, it will now do all or 
nothing. The old shell-script really looped over the removed files one by 
one, and would basically randomly fail in the middle if "-f" was used and 
one of the files didn't exist in the working directory.

This C builtin one will not re-write the index after each remove, but 
instead remove all files at once. However, that means that if "-f" is used 
(to also force removal of the file from the working directory), and some 
files have already been removed from the workspace, it won't stop in the 
middle in some half-way state like the old one did.

So what happens is that if the _first_ file fails to be removed with "-f", 
we abort the whole "git rm". But once we've started removing, we don't 
leave anything half done. If some of the other files don't exist, we'll 
just ignore errors of removal from the working tree.

This is only an issue with "-f", of course.

I think the new behaviour is strictly an improvement, but perhaps more 
importantly, it is _different_. As a special case, the semantics are 
identical for the single-file case (which is the only one our test-suite 
seems to test).

The other question is what to do with leading directories. The old "git 
rm" script didn't do anything, which is somewhat inconsistent. This one 
will actually clean up directories that have become empty as a result of 
removing the last file, but maybe we want to have a flag to decide the 
behaviour?

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

diff --git a/Makefile b/Makefile
index 5373986..06b31d8 100644
--- a/Makefile
+++ b/Makefile
@@ -120,7 +120,7 @@ SCRIPT_SH = \
 	git-merge-one-file.sh git-parse-remote.sh \
 	git-prune.sh git-pull.sh git-rebase.sh \
 	git-repack.sh git-request-pull.sh git-reset.sh \
-	git-resolve.sh git-revert.sh git-rm.sh git-sh-setup.sh \
+	git-resolve.sh git-revert.sh git-sh-setup.sh \
 	git-tag.sh git-verify-tag.sh \
 	git-applymbox.sh git-applypatch.sh git-am.sh \
 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
@@ -170,7 +170,8 @@ PROGRAMS = \
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X \
 	git-count-objects$X git-diff$X git-push$X \
-	git-grep$X git-add$X git-rev-list$X git-check-ref-format$X
+	git-grep$X git-add$X git-rm$X git-rev-list$X \
+	git-check-ref-format$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -218,7 +219,8 @@ LIB_OBJS = \
 
 BUILTIN_OBJS = \
 	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-	builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o
+	builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o \
+	builtin-rm.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/builtin-rm.c b/builtin-rm.c
new file mode 100644
index 0000000..67e0f79
--- /dev/null
+++ b/builtin-rm.c
@@ -0,0 +1,150 @@
+/*
+ * "git rm" builtin command
+ *
+ * Copyright (C) Linus Torvalds 2006
+ */
+#include "cache.h"
+#include "builtin.h"
+#include "dir.h"
+
+static const char builtin_rm_usage[] =
+"git-rm [-n] [-v] [-f] <filepattern>...";
+
+static struct {
+	int nr, alloc;
+	const char **name;
+} list;
+
+static void add_list(const char *name)
+{
+	if (list.nr >= list.alloc) {
+		list.alloc = alloc_nr(list.alloc);
+		list.name = xrealloc(list.name, list.alloc * sizeof(const char *));
+	}
+	list.name[list.nr++] = name;
+}
+
+static int remove_file(const char *name)
+{
+	int ret;
+	char *slash;
+
+	ret = unlink(name);
+	if (!ret && (slash = strrchr(name, '/'))) {
+		char *n = strdup(name);
+		do {
+			n[slash - name] = 0;
+			name = n;
+		} while (!rmdir(name) && (slash = strrchr(name, '/')));
+	}
+	return ret;
+}
+
+static struct cache_file cache_file;
+
+int cmd_rm(int argc, const char **argv, char **envp)
+{
+	int i, newfd;
+	int verbose = 0, show_only = 0, force = 0;
+	const char *prefix = setup_git_directory();
+	const char **pathspec;
+	char *seen;
+
+	git_config(git_default_config);
+
+	newfd = hold_index_file_for_update(&cache_file, get_index_file());
+	if (newfd < 0)
+		die("unable to create new index file");
+
+	if (read_cache() < 0)
+		die("index file corrupt");
+
+	for (i = 1 ; i < argc ; i++) {
+		const char *arg = argv[i];
+
+		if (*arg != '-')
+			break;
+		if (!strcmp(arg, "--")) {
+			i++;
+			break;
+		}
+		if (!strcmp(arg, "-n")) {
+			show_only = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-v")) {
+			verbose = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-f")) {
+			force = 1;
+			continue;
+		}
+		die(builtin_rm_usage);
+	}
+	pathspec = get_pathspec(prefix, argv + i);
+
+	seen = NULL;
+	if (pathspec) {
+		for (i = 0; pathspec[i] ; i++)
+			/* nothing */;
+		seen = xmalloc(i);
+		memset(seen, 0, i);
+	}
+
+	for (i = 0; i < active_nr; i++) {
+		struct cache_entry *ce = active_cache[i];
+		if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+			continue;
+		add_list(ce->name);
+	}
+
+	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);
+		}
+	}
+
+	/*
+	 * First remove the names from the index: we won't commit
+	 * the index unless all of them succeed
+	 */
+	for (i = 0; i < list.nr; i++) {
+		const char *path = list.name[i];
+		printf("rm '%s'\n", path);
+
+		if (remove_file_from_cache(path))
+			die("git rm: unable to remove %s", path);
+	}
+
+	/*
+	 * Then, if we used "-f", 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 ourself and can't fail
+	 * in the middle)
+	 */
+	if (force) {
+		int removed = 0;
+		for (i = 0; i < list.nr; i++) {  
+			const char *path = list.name[i];
+			if (!remove_file(path)) {
+				removed = 1;
+				continue;
+			}
+			if (!removed)
+				die("git rm: %s: %s", path, strerror(errno));
+		}
+	}
+
+	if (active_cache_changed) {
+		if (write_cache(newfd, active_cache, active_nr) ||
+		    commit_index_file(&cache_file))
+			die("Unable to write new index file");
+	}
+	
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index 78275ea..d150c7c 100644
--- a/builtin.h
+++ b/builtin.h
@@ -25,6 +25,7 @@ extern int cmd_count_objects(int argc, c
 
 extern int cmd_push(int argc, const char **argv, char **envp);
 extern int cmd_grep(int argc, const char **argv, char **envp);
+extern int cmd_rm(int argc, const char **argv, char **envp);
 extern int cmd_add(int argc, const char **argv, char **envp);
 extern int cmd_rev_list(int argc, const char **argv, char **envp);
 extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
diff --git a/git-rm.sh b/git-rm.sh
deleted file mode 100755
index fda4541..0000000
--- a/git-rm.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-
-USAGE='[-f] [-n] [-v] [--] <file>...'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-remove_files=
-show_only=
-verbose=
-while : ; do
-  case "$1" in
-    -f)
-	remove_files=true
-	;;
-    -n)
-	show_only=true
-	;;
-    -v)
-	verbose=--verbose
-	;;
-    --)
-	shift; break
-	;;
-    -*)
-	usage
-	;;
-    *)
-	break
-	;;
-  esac
-  shift
-done
-
-# This is typo-proofing. If some paths match and some do not, we want
-# to do nothing.
-case "$#" in
-0)	;;
-*)
-	git-ls-files --error-unmatch -- "$@" >/dev/null || {
-		echo >&2 "Maybe you misspelled it?"
-		exit 1
-	}
-	;;
-esac
-
-if test -f "$GIT_DIR/info/exclude"
-then
-	git-ls-files -z \
-	--exclude-from="$GIT_DIR/info/exclude" \
-	--exclude-per-directory=.gitignore -- "$@"
-else
-	git-ls-files -z \
-	--exclude-per-directory=.gitignore -- "$@"
-fi |
-case "$show_only,$remove_files" in
-true,*)
-	xargs -0 echo
-	;;
-*,true)
-	xargs -0 sh -c "
-		while [ \$# -gt 0 ]; do
-			file=\$1; shift
-			rm -- \"\$file\" && git-update-index --remove $verbose \"\$file\"
-		done
-	" inline
-	;;
-*)
-	git-update-index --force-remove $verbose -z --stdin
-	;;
-esac
diff --git a/git.c b/git.c
index 7db5cc1..63aa311 100644
--- a/git.c
+++ b/git.c
@@ -51,6 +51,7 @@ static void handle_internal_command(int 
 		{ "count-objects", cmd_count_objects },
 		{ "diff", cmd_diff },
 		{ "grep", cmd_grep },
+		{ "rm", cmd_rm },
 		{ "add", cmd_add },
 		{ "rev-list", cmd_rev_list },
 		{ "check-ref-format", cmd_check_ref_format }

^ permalink raw reply related

* Re: [PATCH] Implement git-quiltimport (take 2)
From: Greg KH @ 2006-05-19 23:58 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Junio C Hamano, git
In-Reply-To: <m1ejyr38xx.fsf@ebiederm.dsl.xmission.com>

On Thu, May 18, 2006 at 04:48:26AM -0600, Eric W. Biederman wrote:
> Junio C Hamano <junkio@cox.net> writes:
> 
> > ebiederm@xmission.com (Eric W. Biederman) writes:
> >
> >> Junio C Hamano <junkio@cox.net> writes:
> >>
> >>> What's the expected workflow for you to work on a 1300 patch
> >>> series you get from Andrew in the next installment to deal with
> >>> 88 unattributed patches?  Answer the question 88 times and make
> >>> sure you get the answers right every time?  Or abort and
> >>> hand-edit them to help mailinfo to notice the correct
> >>> attribution and re-run?
> >>
> >> For the internal consumption case it isn't a big deal.  I
> >> can specify --author with something bogus and it works. 
> >
> > Yes.
> >
> >>> I know I am guilty of suggesting "going interactive", but I have
> >>> a feeling that having an optional file that maps patch-name to
> >>> author might be easier to work with.  If the old patches are
> >>> recycled in the updated -mm set, you probably can reuse the
> >>> mapping for them, adding entries for newly introduced "unnamed"
> >>> patches as needed.
> >>
> >> Short of getting the script where it has a sane restart in the
> >> middle mode going interactive and asking questions makes a lot
> >> of sense.  Especially with smaller trees.
> >
> > Yes perhaps on smaller trees, but that does not mean much.  For
> > smaller trees and/or smaller patch series almost anything would
> > do.
> 
> Yes, a smaller patch series, that is what I meant.
> Most quilt trees that I know about are in needed small.

$ quilt series | wc -l
207

And that is about "normal" for me.  Sometimes it grows to about 500+
patches, but that only happens when there's a longer kernel release
cycle.

Another tree that I work on all the time is about 700+ patches, and yet
another 2000+.  So you might re-evaluate your statement about "small"
quilt series :)

In looking at your script, it doesn't seem to be able to handle patches
in quilt that are in mbox format.  Any thoughts to allow this to handle
the attribution properly?

Right now my development flow has me converting my quilt tree to one big
mbox file and then using 'git applymbox' to import it before asking
Linus to pull from it.

With your script I could skip at least one step, which would save me
some time...

thanks,

greg k-h

^ permalink raw reply

* Re: gitk highlight feature
From: Paul Mackerras @ 2006-05-20  0:07 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605030946260.4086@g5.osdl.org>

Linus Torvalds writes:

> But the real thing I found is that when I decided I wanted to highlight, I 
> didn't actually want to highlight by "git-rev-list" at all. At least not 
> most of the time.

I just pushed some changes to the "new" branch of the gitk.git
repository which change the way we do highlighting.  There is now a
row of controls across the middle of the window, just below the row
containing the sha1 ID, "Find" button, etc., which controls the
highlighting.  There are (currently) three ways to do highlighting: by
path, by view, and by author/committer.  The author/committer matching
is case-insensitive (since I'm clearly an insensitive sort of guy :)
and matches any of the given strings anywhere in the author and
committer fields.  The path and author/committer entry widgets take a
whitespace-delimited list of paths or names of interest, using shell
quoting rules, so you can put for example:

"david s. miller" benh

in there and you'll get commits from either davem or benh highlighted.

Do people think this is useful and on the right track interface-wise?

Paul.

^ permalink raw reply

* Re: [RFD] Git glossary: 'branch' and 'head' description
From: Daniel Barkalow @ 2006-05-20  0:28 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: David Kågedal, git
In-Reply-To: <20060519092136.GN22257@spearce.org>

On Fri, 19 May 2006, Shawn Pearce wrote:

> David K?gedal <davidk@lysator.liu.se> wrote:
> > I noticed that some of this seems to be changing slightly with the
> > introduction of branch logs, but I don't know how those are supposed
> > to be used yet.
> 
> 	$ git commit -a
> 	$ git pull . some/other-tag
> 	# go to lunch
> 	$ git pull . some/bad-stuff
> 	$ git commit -a
> 	# go home
> 	$ test...
> 	# realize this is all bad
> 	$ git reset --hard "master@{yesterday}"
> 
> :-)
> 
> Its really only useful for recording the history of your ref's state,
> so you can 'undo' a bad merge that you might have done a few days
> ago but not realized was bad until now.

I still think it's useful for presenting a local view of how things have 
changed. I.e.:

$ git pull . stuff
# Notice that the diffstat is exciting
# What did I just get?
$ git log master@{5 minutes ago}..master

This is about the only easy way to find out that the fast-forward you just 
did included merging a line which contains a commit from several weeks 
ago. (Because the "before" state isn't easily accessible for a 
fast-forward, and the date of the old commit puts it way back in a 
date-ordered log.)

I still think that a local changelog, which groups the additions due to 
each logged value, would be a useful way of viewing the history in a way 
that's meaningful to the particular user, and I think it would fit user 
expectations of gitweb (i.e., when looking at Linus's tree's summary, 
things would be ordered by when they hit Linus's tree, not when they were 
originally committed, so between the listing of the merge at 23:48:54 
today and the one 7 minutes before would be those things which weren't in 
Linus's tree during those 7 minutes).

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [RFD] Git glossary: 'branch' and 'head' description
From: Junio C Hamano @ 2006-05-20  0:35 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605192006400.6713@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> writes:

> $ git pull . stuff
> # Notice that the diffstat is exciting
> # What did I just get?
> $ git log master@{5 minutes ago}..master
>
> This is about the only easy way to find out that the fast-forward you just 
> did included merging a line which contains a commit from several weeks 
> ago. (Because the "before" state isn't easily accessible for a 
> fast-forward, and the date of the old commit puts it way back in a 
> date-ordered log.)

Did you forget about "git log ORIG_HEAD.."?

^ permalink raw reply

* Re: [RFD] Git glossary: 'branch' and 'head' description
From: Daniel Barkalow @ 2006-05-20  1:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy7wxfs7v.fsf@assigned-by-dhcp.cox.net>

On Fri, 19 May 2006, Junio C Hamano wrote:

> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > $ git pull . stuff
> > # Notice that the diffstat is exciting
> > # What did I just get?
> > $ git log master@{5 minutes ago}..master
> >
> > This is about the only easy way to find out that the fast-forward you just 
> > did included merging a line which contains a commit from several weeks 
> > ago. (Because the "before" state isn't easily accessible for a 
> > fast-forward, and the date of the old commit puts it way back in a 
> > date-ordered log.)
> 
> Did you forget about "git log ORIG_HEAD.."?

I guess I did forget that it sticks around. So you have to be doing 
something somewhat more complicated, like fetching the latest versions of 
multiple topic branches.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [RFD] Git glossary: 'branch' and 'head' description
From: Linus Torvalds @ 2006-05-20  2:06 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0605192116360.6713@iabervon.org>



On Fri, 19 May 2006, Daniel Barkalow wrote:
> 
> I guess I did forget that it sticks around. So you have to be doing 
> something somewhat more complicated, like fetching the latest versions of 
> multiple topic branches.

I actually don't think it's at all unlikely that I'd start using this.

I tend to work in "spurts", where I do one thing for a while, and then 
merge several pull requests in fairly short order. So while I use 
ORIG_HEAD a lot, I can certainly imagine myself using the "since 2 hours 
ago" format too.

I'm not entirely sure about the syntax, though. It ends up being pretty 
command-line-unfriendly. The "gitk ORIG_HEAD.." thing is fairly easy to 
type, but typing

	gitk 'master@{2 hours ago}'..

on a Finnish keyboard (yeah, that's what I still use) is "interesting", 
since all of '@', '{' and '}' are complex characters (AltGr + '2', AltGr + 
'7' and AltGr + '0' respectively), and you have to remember the quoting.

Not that I see any obvious better syntax. Although allowing a shorthand 
like "@2.hours.ago" for "current branch, at given date" might help a 
bit, at least that wouldn't need quoting:

	gitk @2.hours.ago..

			Linus

^ permalink raw reply

* Re: [PATCH] Implement git-quiltimport (take 2)
From: Eric W. Biederman @ 2006-05-20  2:42 UTC (permalink / raw)
  To: Greg KH; +Cc: Junio C Hamano, git
In-Reply-To: <20060519235825.GA3289@kroah.com>

Greg KH <greg@kroah.com> writes:

> On Thu, May 18, 2006 at 04:48:26AM -0600, Eric W. Biederman wrote:
>> 
>> Yes, a smaller patch series, that is what I meant.
>> Most quilt trees that I know about are  small.
>
> $ quilt series | wc -l
> 207
>
> And that is about "normal" for me.  Sometimes it grows to about 500+
> patches, but that only happens when there's a longer kernel release
> cycle.
>
> Another tree that I work on all the time is about 700+ patches, and yet
> another 2000+.  So you might re-evaluate your statement about "small"
> quilt series :)

Sure.  On fixing the upstream attribution issue you and Andi Kleen 
look like people that are worth talking to, as there were several
patches in Andrews tree from both of you that were lacking attribution.

> In looking at your script, it doesn't seem to be able to handle patches
> in quilt that are in mbox format.  Any thoughts to allow this to handle
> the attribution properly?

Mbox format but one patch per file, or multiple patches in one mbox file?

If it is one patch per file but with mbox headers, it is relatively
simple to teach git-mailinfo to parse things in a slightly more intelligent
way.  I played with that but I didn't have any patches that helped with.

> Right now my development flow has me converting my quilt tree to one big
> mbox file and then using 'git applymbox' to import it before asking
> Linus to pull from it.
>
> With your script I could skip at least one step, which would save me
> some time...

Sure. That is the point of making it generic.

Eric

^ permalink raw reply

* Re: [RFC] qgit with tabs
From: Pavel Roskin @ 2006-05-20  9:42 UTC (permalink / raw)
  To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550605190954w4baab5fcj4f48a539bd120364@mail.gmail.com>

Quoting Marco Costalba <mcostalba@gmail.com>:

> > If I see the list of the recent patches, I see the descriptions and the
> > affected files.  If I'm interested to see what changed in the file, it's
> > only natural for me to double-click the corresponding entry in the list.
> >
>
> Ok. patch pushed.

Working fine here.  Thank you!

--
Regards,
Pavel Roskin

^ permalink raw reply

* Re: [PATCH] Document that "git add" only adds non-ignored files.
From: Santi @ 2006-05-20  9:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfyj5ispx.fsf@assigned-by-dhcp.cox.net>

2006/5/19, Junio C Hamano <junkio@cox.net>:
> Thanks for the reminder, but I wonder if it is good to update
> the description of this command, and ls-files to use the
> same wording for consistency.  We seem to use <pathspec> to mean
> "this is not necessarily a filename -- we glob", so that may be
> a good candidate (we do not have <pathspec> in glossary yet --
> we would need to add).

I changed it to match with the new usage string in the buildin-add.c.

>
> Please don't touch description for diff-* family -- right now,
> they say <path>, because they do not glob.  If we decide that it
> is a good idea to glob (which I suspect we don't for the
> low-level stuff, but we probably do for the "git-diff" wrapper),
> we would update the code and the description at the same time.
>

OK.

Santi

^ permalink raw reply

* Re: [RFC] qgit with tabs
From: Paul Mackerras @ 2006-05-20 10:28 UTC (permalink / raw)
  To: Marco Costalba; +Cc: Pavel Roskin, git
In-Reply-To: <e5bfff550605130431w417b8aacl2b17cf5655b46f31@mail.gmail.com>

Marco Costalba writes:

> FWIK gitk does not have a file content viewer.

It does now, actually.

Paul.

^ 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