Git development
 help / color / mirror / Atom feed
* [RFC/PATCH] Revert "check_packed_git_idx(): check integrity of the idx file itself."
From: Junio C Hamano @ 2006-01-19  4:34 UTC (permalink / raw)
  To: git; +Cc: romieu, Andrew Morton

Andrew noticed that this format-patch in the linux-2.6
repository runs very very very slowly.  I tried it myself and
found it to be 4x slowdown in a repository where I have both
commits still not packed:

   $ git format-patch 7c5c220e 7c4d3367

0.99.9m ran this with 20 seconds wallclock on a Duron 850, while
1.1.3 (and the master) took 47 seconds wallclock.  Comparing
user time is worse: 10 seconds vs 37 seconds.

It turns out that this is due to the pack idx file integrity
check I added about a month ago (bisect is cool -- thanks
Linus):

    commit c5ced64578a82b9d172aceb2f67c6fb9e639f6d9
    Author: Junio C Hamano <junkio@cox.net>
    Date:   Thu Dec 22 22:57:20 2005 -0800

        check_packed_git_idx(): check integrity of the idx file itself.

        Although pack-check.c had routine to verify the checksum for the
        pack index file itself, the core did not check it before using
        it.

The potential problem I saw with the core before this fix was
that after mapping the pack idx file and did some sanity
checks, we did not check the checksum we had in the idx file
that made sure the idx file itself is not corrupt.  Doing it
everytime turned out to be quite expensive as illustrated by
this problem.  With the revert, the same test runs as fast as
0.99.9m used to.

git-fsck-objects should catch it if idx file is corrupt, so this
is removing suspender while we still have belt.

So I am going to propose reverting this "safety measure";
objections?

-- >8 --
Date: Wed Jan 18 20:26:14 2006 -0800

This reverts c5ced64578a82b9d172aceb2f67c6fb9e639f6d9 commit.
It turns out that doing this check every time we map the idx file
is quite expensive.  A corrupt idx file is caught by git-fsck-objects,
so this check is not strictly necessary.

In one unscientific test, 0.99.9m spent 10 seconds usertime for
the same task 1.1.3 takes 37 seconds usertime.  Reverting this gives
us the performance of 0.99.9 back.

---

 sha1_file.c |   16 +---------------
 1 files changed, 1 insertions(+), 15 deletions(-)

a53f669407a76d01c7271124d06366a2dbd5a12d
diff --git a/sha1_file.c b/sha1_file.c
index 8bebbb2..20f6419 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -349,16 +349,12 @@ struct packed_git *packed_git;
 static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
 				void **idx_map_)
 {
-	SHA_CTX ctx;
-	unsigned char sha1[20];
 	void *idx_map;
 	unsigned int *index;
 	unsigned long idx_size;
 	int nr, i;
-	int fd;
+	int fd = open(path, O_RDONLY);
 	struct stat st;
-
-	fd = open(path, O_RDONLY);
 	if (fd < 0)
 		return -1;
 	if (fstat(fd, &st)) {
@@ -396,16 +392,6 @@ static int check_packed_git_idx(const ch
 	if (idx_size != 4*256 + nr * 24 + 20 + 20)
 		return error("wrong index file size");
 
-	/*
-	 * File checksum.
-	 */
-	SHA1_Init(&ctx);
-	SHA1_Update(&ctx, idx_map, idx_size-20);
-	SHA1_Final(sha1, &ctx);
-
-	if (memcmp(sha1, idx_map + idx_size - 20, 20))
-		return error("index checksum mismatch");
-
 	return 0;
 }
 
-- 
1.1.3.gce7b

^ permalink raw reply related

* /etc in git?
From: Adam Hunt @ 2006-01-19  3:43 UTC (permalink / raw)
  To: git

I was thinking about puting my /etc in SVN or CVS but then I got to
thinking about git?  Has anyone ever tried to version their /ect with
git?

--adam

^ permalink raw reply

* Re: Something wrong with pickaxe?
From: Junio C Hamano @ 2006-01-19  3:29 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601181855570.3240@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> For example, getting the tabs/spaces right is basically impossible with 
> normal cut-and-paste. I assume you do the above inside GNU emacs or some 
> similar special-purpose setup, rather than anything generic.

Ah, that is very very very true.  Sometimes I cut and paste
inside screen and find it annoying to see pasted tabs do not
work properly, so I understand that issue very well.

But most of the time, I always work inside Emacs and rarely step
out if ever.  Thanks for making me realize that.

^ permalink raw reply

* Re: Something wrong with pickaxe?
From: Linus Torvalds @ 2006-01-19  2:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7vwtgxlysf.fsf@assigned-by-dhcp.cox.net>



On Wed, 18 Jan 2006, Junio C Hamano wrote:
> 
> You are so polite to say "non-intuitive" when you mean
> "useless".

No, no. I could imagine that it's useful, but I end up always instead 
doing "git whatchanged | less" and searching for it. 

So I really mean that the semantics are so non-intuitive that I just can't 
use it, rather than totally useless.

> For example, after I start debugging or code change, if I
> suspect the first "if (!nr_match) return;" is bogus in
> filter_refs() of fetch-pack.c, before declaring that code is
> bogus and start butchering it, I run something like this:
> 
> $ git whatchanged -p -S'static void filter_refs(struct ref **refs, int nr_match, char **match)
> {
> 	struct ref *prev, *current, *next;
> 
> 	if (!nr_match)
> 		return;
> ' master -- fetch-pack.c

See, this is what I mean - it looks useful, but it's just so subtle that I 
don't ever use it.

For example, getting the tabs/spaces right is basically impossible with 
normal cut-and-paste. I assume you do the above inside GNU emacs or some 
similar special-purpose setup, rather than anything generic.

		Linus

^ permalink raw reply

* Re: Something wrong with pickaxe?
From: Junio C Hamano @ 2006-01-19  2:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Johannes Schindelin, git
In-Reply-To: <Pine.LNX.4.64.0601181541150.3240@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Me, I find the pickaxe semantics so non-intuitive that I never use it 
> (that said, the counting begaviour is better than what it _used_ to be, 
> which, if I recall correctly, was just "it existed before, doesn't exist 
> now").

You are so polite to say "non-intuitive" when you mean
"useless".

I use pickaxe primarily when I want to find out what commit made
the code into the current shape.

For example, after I start debugging or code change, if I
suspect the first "if (!nr_match) return;" is bogus in
filter_refs() of fetch-pack.c, before declaring that code is
bogus and start butchering it, I run something like this:

$ git whatchanged -p -S'static void filter_refs(struct ref **refs, int nr_match, char **match)
{
	struct ref *prev, *current, *next;

	if (!nr_match)
		return;
' master -- fetch-pack.c

to find the commit that made the function to look like so,
hoping to find the reason _why_ it is that way is explained in
the log message for that commit.  If the commit log is not
enough, then next thing I do is to see its commit/author date
and go back to the mailing list logs to see discussion around
that timeframe.

For this use pattern, even counting behaviour we added later is
redundant, since "did not have it that way but now it does" is
the only thing that matters.

"What commits changed the lines that use this symbol over time"
is not a question I ask pickaxe.  When I ask a question about an
individual symbol, such as "get_remote_heads", I often use "git
grep", to learn what other existing users of the function would
be affected in the current code if I changed that function, or
to learn how other functions in the current code uses that
symbol, but for that kind of research, historical usage of that
symbol does not interest me.

Having said all of the above, I agree a different kind of
pickaxe that gives you "if you were to run diff -u between these
two blobs, the resulting patch would contain this text" might
also be useful, and I am very open to have such an additional
diffcore module next to pickaxe (IOW, not a replacement).

But it might not be as easy to use as the current pickaxe if the
question I want to ask is "who made it into this shape".

^ permalink raw reply

* Re: Joining Repositories
From: Junio C Hamano @ 2006-01-19  2:12 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ryan Anderson, Petr Baudis, Mathias Waack, git
In-Reply-To: <7vbqy9xx2r.fsf@assigned-by-dhcp.cox.net>

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

> Linus Torvalds <torvalds@osdl.org> writes:
>
>> Now, let's see what Junio comes up with,...
>
> Well, since the reason the original RFI came was...
> ...
> So for this case, I think the "coolest merge" is the right
> thing to do.

I said this only because I wanted to recommend a solution
available today to the original requester.

If I were to talk about (one potential) future solution, I would
say "bind" commit would work naturally for this case, without
disrupting the development histories of the projects being
combined.  After all, the "bind" commit approach is not much
different from what you did with "the coolest merge ever", with
a few twists, such as (1) not overlaying but requiring each
subproject to be bound at a non-overlapping subdirectory, and
(2) letting a subproject keep its own independent history that
does not know about other subprojects even after combination
happens (as opposed to the coolest merge, after which there is
no git history that does not have gitk as its part).

Of course, "gitlink" would equally work well and have similar
characteristics.  The implementation details will certainly
differ and the user interaction may somewhat be different as
well, but I do not think of any reason either approach would not
work well in this situation.

So would Cogito subprojects support (will it be in the 0.17?),
but it might look less powerful when compared with the "bind" or
"gitlink", if it comes in the form of the patch Pasky sent to
the list, since it does not attempt to tie the versions of two
projects together.  Certainly that makes it the easiest to use
and understand what is going on, though.

^ permalink raw reply

* Re: [PATCH] "sleep 1" sleeps too little on cygwin
From: Junio C Hamano @ 2006-01-19  1:18 UTC (permalink / raw)
  To: Alex Riesen; +Cc: Johannes Schindelin, git
In-Reply-To: <20060118185229.GA3001@steel.home>

Alex Riesen <raa.lkml@gmail.com> writes:

> this is probable unsafe too: not all systems export inodes
> (the recent cygwin breakage comes to mind).

Hmph.  I thought that breakage was about struct dirent, not what
we read from struct stat; d_ino is XSI extension so that may
have been the reason cygwin folks removed it, but st_ino is in
BASE --- did they remove that as well?

But you are right.  Among "struct stat" members, only S_IFMT
part from st_mode and st_size are meaningful for symlinks after
lstat() and other members are unspecified.  Which means that, in
the strictest sense, the original test that tried to see if the
timestamp change makes the entry for the symlink cache-dirty,
was pointless.

HOWEVER.

We live in the real world, not in a strict POSIX world.  We (the
index file) relies on lstat() to update st_mtime and/or st_ino,
and I think it is OK (IOW, we declare that platforms on which we
cannot rely on these members are not worth supporting).


By the way, if you have an access to git on cygwin with FAT,
could you test your patch ($SECONDS) and then i-num patch (the
machine with cygwin I can borrow has only NTFS) please?

^ permalink raw reply

* Re: StGIT: "stg new" vs "stg new --force"
From: Pavel Roskin @ 2006-01-19  0:49 UTC (permalink / raw)
  To: Yann Dirson; +Cc: Catalin Marinas, git, Charles Lever
In-Reply-To: <20060118193717.GI32585@nowhere.earth>

On Wed, 2006-01-18 at 20:37 +0100, Yann Dirson wrote:
> > > It would even be useful sometimes to dispatch changes to a single file
> > > into several patches.  When they are distinct enough to be in
> > > different diff hunks, it is pretty easy to split an existing patch,
> > > but it could also be useful to only refresh a patch with specific diff
> > > hunks.  A possibility would be to add a filterdiff-like "-#<n>" flag,
> > > in addition to the above-suggested "refresh <file>" (and possibly only
> > > allow to specify a single file together with this flag).
> > 
> > I think if would be better to improve "stg fold" to work on arbitrary
> > patches.  This way, you prepare the patch in the editor (which would not
> > be harder than finding hunk numbers) and fold it into the patch of your
> > choice.  stg should check that the stack remains valid, possibly doing
> > trivial adjustments to the higher patches.  The current tree should not
> > be impacted.
> 
> This sounds like a good idea as well (and I would use it on a near
> daily basis as well ;).  Obviously such a request can also fail,
> eg. when requesting to fold a change into a patch, where a subsequent
> patch modifies the same lines.

Definitely.  Hard cases should be handled by hand.

> But it would not be a replacement to selecting changes with a
> granularity finer than file-level, which is what I wanted to suggest.

Why?  Maybe you got confused by two meanings of the word "patch"?  I
think StGIT should use some other term, e.g. changeset.  I meant that
the diff file (e.g. made by "stg diff") could be edited and folded into
one of the StGIT patches (changesets).  Unless you want non-interactive
separation of the hunks, using an editor should be a reasonable
approach.

I believe StGIT should be primarily designed to be used interactively.
Your approach looks like a usability disaster to me.  The user is
supposed to find numbers of the hunks, although s/he is working on the
whole file (since it's "stg refresh").

My approach suggests that the user work with the diff from the
beginning, and separates the changes by looking at them.

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* Re: [QUESTION] about .git/info/grafts file
From: Junio C Hamano @ 2006-01-19  0:40 UTC (permalink / raw)
  To: Franck; +Cc: Git Mailing List
In-Reply-To: <cda58cb80601170932o6f955469y@mail.gmail.com>

Franck <vagabon.xyz@gmail.com> writes:

> I'm wondering why the "grafts" files is not involved during
> push/pull/clone operations ?

Commit ancestry grafting is a local repository issue and even if
you manage to lie to your local git that 300,000th commit is the
epoch, the commit object you send out to the downloader would
record its true parent (or parents, if it is a merge), so the
downloader would want to go further back.  And no, rewriting
that commit and feeding a parentless commit to the downloader is
not an option, because such a commit object would have different
object name and unpack-objects would be unhappy.

If you choose not to have full history in your public repository
for whatever reason (ISP server diskquota comes to mind) that is
OK, but be honest about it to your downloaders.  Tell them that
you do not have the full history, and they first need to clone
from some other repository you started your development upon, in
order to use what you added upon.  "This repository does not
have all the history -- please first clone from XX repository
(you need at least xxx commit), and then do another 'git pull'
from here", or something like that.

It _might_ work if you tell your downloader to have a proper
graft file in his repository to cauterize the commit ancestry
chain _before_ he pulls from you, though.  I haven't tried it
(and honestly I did not feel that is something important to
support, so it might work by accident but that is not by
design).

>                $ git-merge-base master origin
>                # nothing

Maybe you did not use grafts properly to cauterize?  I tried the
following and am getting expected results.  I did not have
patience to do 300,000, so I cut things at #4, though.

-- 8< -- 

#!/bin/sh

rm -fr .git
git init-db
echo 0 >path
git add path

for i in 1 2 3 4 5 6 7
do
	echo $i >path
	git commit -a -m "Iteration #$i"
	git tag "iter#$i"
done


git checkout -b mine iter#4

for i in A B C D
do
	echo $i >path
	git commit -a -m "Alternate #$i"
	git tag "alt#$i"
done

git log --pretty=oneline --topo-order
echo merge base is `git merge-base master mine` | git name-rev --stdin

git-rev-parse iter#4 >.git/info/grafts
echo "Cauterize away history before #4"

git log --pretty=oneline --topo-order
echo merge base is `git merge-base master mine` | git name-rev --stdin

^ permalink raw reply

* Re: [PATCH] git-fetch-pack: really do not ask for funny refs
From: Junio C Hamano @ 2006-01-19  0:33 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0601190023390.15298@wbgn013.biozentrum.uni-wuerzburg.de>

Good catch.  Thanks.

^ permalink raw reply

* Re: Something wrong with pickaxe?
From: Junio C Hamano @ 2006-01-19  0:25 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Linus Torvalds
In-Reply-To: <Pine.LNX.4.64.0601181541150.3240@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> So when you use pickaxe, you really want to match the whole line you're 
> looking for - otherwise you'll only see when people add or remove a 
> particular string, not when they change things around it. Even then, if 
> that particular line gets _moved_ (but otherwise is unchanged) pickaxe 
> won't pick it up.

True.  I always feed at least couple of lines to it.

> ... Junio would be open to 
> more friendly pickaxe semantics if the suggested semantics change was 
> accompanied by an actual diff to implement them.

True again.  It is hard to be "more friendly" without actually
generating a diff ;-).

^ permalink raw reply

* Re: Something wrong with pickaxe?
From: Linus Torvalds @ 2006-01-18 23:55 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0601190004130.15298@wbgn013.biozentrum.uni-wuerzburg.de>


On Thu, 19 Jan 2006, Johannes Schindelin wrote:
> 
> it is a fact that I'm stupid, but in this case it might be a bug, too. 
> When I call
> 
> 	git-whatchanged -Sget_remote_heads 1baaae5e fetch-pack.c
> 
> the first shown commit is d1c133f5. However, if I substitute the 
> "-Sget_remote_heads" by "-p" I see that the diff of commit 1baaae5e *does* 
> change a line containing that text.
> 
> What am I doing wrong?

Nothing. But pickaxe really has very strange semantics, which imho makes 
it much less useful than it could be.

What pickaxe ends up doing is to literally see if the original has that 
string, and the result does not. I think it _counts_ the number of 
occurrences of a string in the before/after situation, and if the count 
differs, it's considered interesting.

So yes, there's a commit that has "get_remote_heads" as part of the 
change, but that particular string did not actually change in that commit: 
_other_ stuff on the same line did change. That particular string existed 
both before and after.

So when you use pickaxe, you really want to match the whole line you're 
looking for - otherwise you'll only see when people add or remove a 
particular string, not when they change things around it. Even then, if 
that particular line gets _moved_ (but otherwise is unchanged) pickaxe 
won't pick it up.

So you could have done a more exact search:

    git-whatchanged -p \
	-S"get_remote_heads(fd[0], &ref, nr_match, match, 1);" \
	1baaae5e fetch-pack.c

would have found where that particular line was introduced (and deleted).

Me, I find the pickaxe semantics so non-intuitive that I never use it 
(that said, the counting begaviour is better than what it _used_ to be, 
which, if I recall correctly, was just "it existed before, doesn't exist 
now").

I at one point suggested to Junio that the semantics be something else 
("mark the source and destination within 'x' characters of an occurrence 
of that string, and then if the _delta_ touches any of the marked areas, 
consider it to be a hit") but I think the problem was simply that it's 
more complex. You have to look at the ranges that the delta actually 
touches, which is more work than just looking at the original and final 
file contents themselves.

I suspect (but can't speak for him, obviously) that Junio would be open to 
more friendly pickaxe semantics if the suggested semantics change was 
accompanied by an actual diff to implement them.

In the meantime, you really need to think carefully about what you're 
doing when you use "-S". 

		Linus

^ permalink raw reply

* [PATCH] git-fetch-pack: really do not ask for funny refs
From: Johannes Schindelin @ 2006-01-18 23:24 UTC (permalink / raw)
  To: git, junkio


If git-fetch-pack was called with out any refspec, it would ask the server
for funny refs. That cannot work, since the funny refs are not marked
as OUR_REF by upload-pack, which just exits with an error.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

---

 fetch-pack.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

718ad2d76a6c7d350d63c0660aeb69518b765310
diff --git a/fetch-pack.c b/fetch-pack.c
index d34f322..27f5d2a 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -262,9 +262,6 @@ static void filter_refs(struct ref **ref
 {
 	struct ref *prev, *current, *next;
 
-	if (!nr_match)
-		return;
-
 	for (prev = NULL, current = *refs; current; current = next) {
 		next = current->next;
 		if ((!memcmp(current->name, "refs/", 5) &&
-- 
1.1.3.g0bf8-dirty

^ permalink raw reply related

* Something wrong with pickaxe?
From: Johannes Schindelin @ 2006-01-18 23:23 UTC (permalink / raw)
  To: git

Hi,

it is a fact that I'm stupid, but in this case it might be a bug, too. 
When I call

	git-whatchanged -Sget_remote_heads 1baaae5e fetch-pack.c

the first shown commit is d1c133f5. However, if I substitute the 
"-Sget_remote_heads" by "-p" I see that the diff of commit 1baaae5e *does* 
change a line containing that text.

What am I doing wrong?

Ciao,
Dscho

^ permalink raw reply

* Re: Joining Repositories
From: Linus Torvalds @ 2006-01-18 23:15 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601181414530.3240@g5.osdl.org>



On Wed, 18 Jan 2006, Linus Torvalds wrote:
> 
> As an example, let's say that you have a git repository that has had a 
> file called "A" some time in the past. That file gets renamed to B, and 
> then gets renamed back again to A. The old "git-rev-list" would show two 
> commits commits: the commit that renames B to A (because it changes A) 
> _and_ as its parent the commit that renames A to B (because it changes A).

Btw, in case somebody doesn't see what's wrong with that (because those 
two commits happen to be the only ones that matter), let's point out that 
the file may have changed while it was called "B". So to do annotation, we 
really need to _stop_ following the filename, start following the previous
one.

Now, the logic to do that could have been in the "annotate" parts, but the 
decision to stop following the chain actually makes sense as part of 
git-rev-list, since it does the tree difference tracking anyway.

		Linus

^ permalink raw reply

* Re: Joining Repositories
From: Linus Torvalds @ 2006-01-18 22:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601181128060.3240@g5.osdl.org>



On Wed, 18 Jan 2006, Linus Torvalds wrote:
> 
> The one thing I've considered doing (I really should) is to add a "stop 
> when you don't find the file" option to "git-rev-list". This patch does 
> some of the work towards that: it removes the "parent" thing when the 
> file disappears, so a "git annotate" could do do something like
> 
> 	git-rev-list --remove-empty --parents HEAD -- "$filename"
> 
> and it would get a good graph that stops when the filename disappears 
> (it's not perfect though: it won't remove all the unintersting commits).

Here is a somewhat better version of this patch.

It also simplifies the logic of finding tree differences a bit, at the 
cost of making it a tad less efficient.

The old logic was two-phase: it would first simplify _only_ merges tree as 
it traversed the tree, and then simplify the linear parts of the remainder 
independently. That was pretty optimal from an efficiency standpoint 
because it avoids doing any comparisons that we can see are unnecessary, 
but it made it much harder to understand than it really needed to be.

The new logic is a lot more straightforward, and compares the trees as it 
traverses the graph (ie everything is a single phase). That makes it much 
easier to stop graph traversal at any point where a file disappears.

As an example, let's say that you have a git repository that has had a 
file called "A" some time in the past. That file gets renamed to B, and 
then gets renamed back again to A. The old "git-rev-list" would show two 
commits commits: the commit that renames B to A (because it changes A) 
_and_ as its parent the commit that renames A to B (because it changes A).

With the new --remove-empty flag, git-rev-list will show just the commit 
that renames B to A as the "root" commit, and stop traversal there 
(because that's what you want for "annotate" - you want to stop there, and 
for every "root" commit you then separately see if it really is a new 
file, or if the paths history disappeared because it was renamed from some 
other file).

With this patch, you should be able to basically do a "poor mans 'git 
annotate'" with a fairly simple loop:

	push("HEAD", "$filename")
	while (revision,filename = pop()) {
		for each i in $(git-rev-list --parents --remove-empty $revision -- "$filename")

		pseudo-parents($i) = git-rev-list parents for that line

		if (pseudo-parents($i) is non-empty) {
			show diff of $i against pseudo-parents
			continue
		}

		/* See if the _real_ parents of $i had a rename */
		parent($i) = real-parent($i)
		if (find-rename in $parent($i)->$i)
			push $parent($i), "old-name"
	}

which should be doable in perl or something (doing stacks in shell is just 
too painful to be worth it, so I'm not going to do this).

Anybody want to try?

		Linus

---
diff --git a/rev-list.c b/rev-list.c
index d060966..912071d 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -54,6 +54,7 @@ static int stop_traversal = 0;
 static int topo_order = 0;
 static int no_merges = 0;
 static const char **paths = NULL;
+static int remove_empty_trees = 0;
 
 static void show_commit(struct commit *commit)
 {
@@ -424,14 +425,33 @@ static void mark_edges_uninteresting(str
 	}
 }
 
-static int is_different = 0;
+#define TREE_SAME	0
+#define TREE_NEW	1
+#define TREE_DIFFERENT	2
+static int tree_difference = TREE_SAME;
 
 static void file_add_remove(struct diff_options *options,
 		    int addremove, unsigned mode,
 		    const unsigned char *sha1,
 		    const char *base, const char *path)
 {
-	is_different = 1;
+	int diff = TREE_DIFFERENT;
+
+	/*
+	 * Is it an add of a new file? It means that
+	 * the old tree didn't have it at all, so we
+	 * will turn "TREE_SAME" -> "TREE_NEW", but
+	 * leave any "TREE_DIFFERENT" alone (and if
+	 * it already was "TREE_NEW", we'll keep it
+	 * "TREE_NEW" of course).
+	 */
+	if (addremove == '+') {
+		diff = tree_difference;
+		if (diff != TREE_SAME)
+			return;
+		diff = TREE_NEW;
+	}
+	tree_difference = diff;
 }
 
 static void file_change(struct diff_options *options,
@@ -440,7 +460,7 @@ static void file_change(struct diff_opti
 		 const unsigned char *new_sha1,
 		 const char *base, const char *path)
 {
-	is_different = 1;
+	tree_difference = TREE_DIFFERENT;
 }
 
 static struct diff_options diff_opt = {
@@ -449,12 +469,16 @@ static struct diff_options diff_opt = {
 	.change = file_change,
 };
 
-static int same_tree(struct tree *t1, struct tree *t2)
+static int compare_tree(struct tree *t1, struct tree *t2)
 {
-	is_different = 0;
+	if (!t1)
+		return TREE_NEW;
+	if (!t2)
+		return TREE_DIFFERENT;
+	tree_difference = TREE_SAME;
 	if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &diff_opt) < 0)
-		return 0;
-	return !is_different;
+		return TREE_DIFFERENT;
+	return tree_difference;
 }
 
 static int same_tree_as_empty(struct tree *t1)
@@ -474,28 +498,55 @@ static int same_tree_as_empty(struct tre
 	empty.buf = "";
 	empty.size = 0;
 
-	is_different = 0;
+	tree_difference = 0;
 	retval = diff_tree(&empty, &real, "", &diff_opt);
 	free(tree);
 
-	return retval >= 0 && !is_different;
+	return retval >= 0 && !tree_difference;
 }
 
-static struct commit *try_to_simplify_merge(struct commit *commit, struct commit_list *parent)
+static void try_to_simplify_commit(struct commit *commit)
 {
+	struct commit_list **pp, *parent;
+
 	if (!commit->tree)
-		return NULL;
+		return;
 
-	while (parent) {
+	if (!commit->parents) {
+		if (!same_tree_as_empty(commit->tree))
+			commit->object.flags |= TREECHANGE;
+		return;
+	}
+
+	pp = &commit->parents;
+	while ((parent = *pp) != NULL) {
 		struct commit *p = parent->item;
-		parent = parent->next;
+
+		if (p->object.flags & UNINTERESTING) {
+			pp = &parent->next;
+			continue;
+		}
+
 		parse_commit(p);
-		if (!p->tree)
+		switch (compare_tree(p->tree, commit->tree)) {
+		case TREE_SAME:
+			parent->next = NULL;
+			commit->parents = parent;
+			return;
+
+		case TREE_NEW:
+			if (remove_empty_trees && same_tree_as_empty(p->tree)) {
+				*pp = parent->next;
+				continue;
+			}
+		/* fallthrough */
+		case TREE_DIFFERENT:
+			pp = &parent->next;
 			continue;
-		if (same_tree(commit->tree, p->tree))
-			return p;
+		}
+		die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
 	}
-	return NULL;
+	commit->object.flags |= TREECHANGE;
 }
 
 static void add_parents_to_list(struct commit *commit, struct commit_list **list)
@@ -531,20 +582,14 @@ static void add_parents_to_list(struct c
 	}
 
 	/*
-	 * Ok, the commit wasn't uninteresting. If it
-	 * is a merge, try to find the parent that has
-	 * no differences in the path set if one exists.
+	 * Ok, the commit wasn't uninteresting. Try to
+	 * simplify the commit history and find the parent
+	 * that has no differences in the path set if one exists.
 	 */
-	if (paths && parent && parent->next) {
-		struct commit *preferred;
-
-		preferred = try_to_simplify_merge(commit, parent);
-		if (preferred) {
-			parent->item = preferred;
-			parent->next = NULL;
-		}
-	}
+	if (paths)
+		try_to_simplify_commit(commit);
 
+	parent = commit->parents;
 	while (parent) {
 		struct commit *p = parent->item;
 
@@ -558,33 +603,6 @@ static void add_parents_to_list(struct c
 	}
 }
 
-static void compress_list(struct commit_list *list)
-{
-	while (list) {
-		struct commit *commit = list->item;
-		struct commit_list *parent = commit->parents;
-		list = list->next;
-
-		if (!parent) {
-			if (!same_tree_as_empty(commit->tree))
-				commit->object.flags |= TREECHANGE;
-			continue;
-		}
-
-		/*
-		 * Exactly one parent? Check if it leaves the tree
-		 * unchanged
-		 */
-		if (!parent->next) {
-			struct tree *t1 = commit->tree;
-			struct tree *t2 = parent->item->tree;
-			if (!t1 || !t2 || same_tree(t1, t2))
-				continue;
-		}
-		commit->object.flags |= TREECHANGE;
-	}
-}
-
 static struct commit_list *limit_list(struct commit_list *list)
 {
 	struct commit_list *newlist = NULL;
@@ -614,8 +632,6 @@ static struct commit_list *limit_list(st
 	}
 	if (tree_objects)
 		mark_edges_uninteresting(newlist);
-	if (paths && dense)
-		compress_list(newlist);
 	if (bisect_list)
 		newlist = find_bisection(newlist);
 	return newlist;
@@ -808,6 +824,10 @@ int main(int argc, const char **argv)
 			dense = 0;
 			continue;
 		}
+		if (!strcmp(arg, "--remove-empty")) {
+			remove_empty_trees = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--")) {
 			i++;
 			break;

^ permalink raw reply related

* Software
From: Stiflings G. Talker @ 2006-01-18 22:11 UTC (permalink / raw)
  To: Git

You know how it? to work with stable software! 
Corel draw! just at best price 

New software on our site:

Office 2003 Professional (1 CD Edition) - $89.95
Acrobat 6 Professional - $79.95
Acrobat 6 Professional - $79.95
Picture It Premium 9 - $59.95
InDesign CS PageMaker Edition (2CD) - $69.95
Borland Delphi 7 Enterprise Edition (2CD) - $69.95
Visio 2003 Professional - $69.95
Encarta Encyclopedia Delux 2004 (3CD) - $89.95
Plus! XP - $59.95
Office XP Professional - $79.95
FileMaker 7.0 Professional - $69.95
InDesign CS PageMaker Edition (2CD) - $69.95
Creative Suite Standard (3 CD) - $129.95
Streets and Trips 2004 North America (2CD) - $69.95

Our site:
http://haughtlyam.com

^ permalink raw reply

* Re: Cogito wishlist: ability to set merge strategy
From: Martin Langhoff @ 2006-01-18 20:14 UTC (permalink / raw)
  To: Petr Baudis
  Cc: H. Peter Anvin, Git Mailing List, Junio C Hamano,
	Andreas Ericsson
In-Reply-To: <20060118193201.GV28365@pasky.or.cz>

On 1/19/06, Petr Baudis <pasky@suse.cz> wrote:
> though. From the Git merge strategies, I guess only recursive is
> useful for Cogito...

I haven't had time to figure out where the problem is, I do have some
cases where git-merge does the right thing, and cg-merge gets it
wrong. And without renames.

An example from yesterday:
http://locke.catalyst.net.nz/gitweb?p=moodle.git;a=commit;h=b69d60a5141dfe22a073dd9931e6c8ff5dded0b9

(the repo is accessble via http://locke.catalyst.net.nz/git/moodle.org
if anyone is interested)

> Patches welcome.  ;-)

I know I promised patches in that direction, but I haven't had the
time to look into it. Sorry! (and, as a user, I just cheat and fall
back to git-merge)

cheers,


martin

^ permalink raw reply

* Re: Joining Repositories
From: Linus Torvalds @ 2006-01-18 20:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vslrluze6.fsf@assigned-by-dhcp.cox.net>



On Wed, 18 Jan 2006, Junio C Hamano wrote:
> 
> Sorry for having brought up the issue again.  I personally do
> not disagree with you.  Because I did not want to waste your
> time rehashing it, I attempted to make it absolutely clear that
> I was talking about an _optional_ way to tell the tool to do so,
> when somebody so used to "annotate" wants to.  Obviously my
> attempt did not work well X-<.

Well, the main reason I did the "limit git-rev-list with pathnames" was 
literally to try to help the "annotate one file".

So I don't think file following has anything to do with "git-whatchanged". 
It's literally an op we don't have yet - and that we should have. It 
really should be pretty straighforward to do a "git annotate" these days. 
It will never be as fast as git-whatchanged, but it shouldn't be horribly 
inefficient either.

The one thing I've considered doing (I really should) is to add a "stop 
when you don't find the file" option to "git-rev-list". This patch does 
some of the work towards that: it removes the "parent" thing when the 
file disappears, so a "git annotate" could do do something like

	git-rev-list --remove-empty --parents HEAD -- "$filename"

and it would get a good graph that stops when the filename disappears 
(it's not perfect though: it won't remove all the unintersting commits).

		Linus

----
diff --git a/rev-list.c b/rev-list.c
index d060966..3906674 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -54,6 +54,7 @@ static int stop_traversal = 0;
 static int topo_order = 0;
 static int no_merges = 0;
 static const char **paths = NULL;
+static int remove_empty_trees = 0;
 
 static void show_commit(struct commit *commit)
 {
@@ -424,14 +425,33 @@ static void mark_edges_uninteresting(str
 	}
 }
 
-static int is_different = 0;
+#define TREE_SAME	0
+#define TREE_NEW	1
+#define TREE_DIFFERENT	2
+static int tree_difference = TREE_SAME;
 
 static void file_add_remove(struct diff_options *options,
 		    int addremove, unsigned mode,
 		    const unsigned char *sha1,
 		    const char *base, const char *path)
 {
-	is_different = 1;
+	int diff = TREE_DIFFERENT;
+
+	/*
+	 * Is it an add of a new file? It means that
+	 * the old tree didn't have it at all, so we
+	 * will turn "TREE_SAME" -> "TREE_NEW", but
+	 * leave any "TREE_DIFFERENT" alone (and if
+	 * it already was "TREE_NEW", we'll keep it
+	 * "TREE_NEW" of course).
+	 */
+	if (addremove == '+') {
+		diff = tree_difference;
+		if (diff != TREE_SAME)
+			return;
+		diff = TREE_NEW;
+	}
+	tree_difference = diff;
 }
 
 static void file_change(struct diff_options *options,
@@ -440,7 +460,7 @@ static void file_change(struct diff_opti
 		 const unsigned char *new_sha1,
 		 const char *base, const char *path)
 {
-	is_different = 1;
+	tree_difference = TREE_DIFFERENT;
 }
 
 static struct diff_options diff_opt = {
@@ -449,12 +469,16 @@ static struct diff_options diff_opt = {
 	.change = file_change,
 };
 
-static int same_tree(struct tree *t1, struct tree *t2)
+static int compare_tree(struct tree *t1, struct tree *t2)
 {
-	is_different = 0;
+	if (!t1)
+		return TREE_NEW;
+	if (!t2)
+		return TREE_DIFFERENT;
+	tree_difference = TREE_SAME;
 	if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &diff_opt) < 0)
-		return 0;
-	return !is_different;
+		return TREE_DIFFERENT;
+	return tree_difference;
 }
 
 static int same_tree_as_empty(struct tree *t1)
@@ -474,26 +498,38 @@ static int same_tree_as_empty(struct tre
 	empty.buf = "";
 	empty.size = 0;
 
-	is_different = 0;
+	tree_difference = 0;
 	retval = diff_tree(&empty, &real, "", &diff_opt);
 	free(tree);
 
-	return retval >= 0 && !is_different;
+	return retval >= 0 && !tree_difference;
 }
 
-static struct commit *try_to_simplify_merge(struct commit *commit, struct commit_list *parent)
+static struct commit *try_to_simplify_merge(struct commit *commit)
 {
+	struct commit_list **pp, *parent;
+
 	if (!commit->tree)
 		return NULL;
 
-	while (parent) {
+	pp = &commit->parents;
+	while ((parent = *pp) != NULL) {
 		struct commit *p = parent->item;
-		parent = parent->next;
 		parse_commit(p);
-		if (!p->tree)
-			continue;
-		if (same_tree(commit->tree, p->tree))
+		switch (compare_tree(p->tree, commit->tree)) {
+		case TREE_SAME:
 			return p;
+		case TREE_NEW:
+			if (remove_empty_trees) {
+				*pp = parent->next;
+				continue;
+			}
+		/* fallthrough */
+		case TREE_DIFFERENT:
+			pp = &parent->next;
+			continue;
+		}
+		die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
 	}
 	return NULL;
 }
@@ -538,7 +574,7 @@ static void add_parents_to_list(struct c
 	if (paths && parent && parent->next) {
 		struct commit *preferred;
 
-		preferred = try_to_simplify_merge(commit, parent);
+		preferred = try_to_simplify_merge(commit);
 		if (preferred) {
 			parent->item = preferred;
 			parent->next = NULL;
@@ -576,10 +612,18 @@ static void compress_list(struct commit_
 		 * unchanged
 		 */
 		if (!parent->next) {
-			struct tree *t1 = commit->tree;
-			struct tree *t2 = parent->item->tree;
-			if (!t1 || !t2 || same_tree(t1, t2))
+			struct tree *t1 = parent->item->tree;
+			struct tree *t2 = commit->tree;
+			switch (compare_tree(t1, t2)) {
+			case TREE_SAME:
 				continue;
+			case TREE_NEW:
+				if (remove_empty_trees)
+					commit->parents = NULL;
+				break;
+			case TREE_DIFFERENT:
+				break;
+			}
 		}
 		commit->object.flags |= TREECHANGE;
 	}
@@ -808,6 +852,10 @@ int main(int argc, const char **argv)
 			dense = 0;
 			continue;
 		}
+		if (!strcmp(arg, "--remove-empty")) {
+			remove_empty_trees = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--")) {
 			i++;
 			break;

^ permalink raw reply related

* Re: StGIT: "stg new" vs "stg new --force"
From: Yann Dirson @ 2006-01-18 19:37 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: Catalin Marinas, git, Charles Lever
In-Reply-To: <1137539762.12454.11.camel@dv>

On Tue, Jan 17, 2006 at 06:16:02PM -0500, Pavel Roskin wrote:
> > It would even be useful sometimes to dispatch changes to a single file
> > into several patches.  When they are distinct enough to be in
> > different diff hunks, it is pretty easy to split an existing patch,
> > but it could also be useful to only refresh a patch with specific diff
> > hunks.  A possibility would be to add a filterdiff-like "-#<n>" flag,
> > in addition to the above-suggested "refresh <file>" (and possibly only
> > allow to specify a single file together with this flag).
> 
> I think if would be better to improve "stg fold" to work on arbitrary
> patches.  This way, you prepare the patch in the editor (which would not
> be harder than finding hunk numbers) and fold it into the patch of your
> choice.  stg should check that the stack remains valid, possibly doing
> trivial adjustments to the higher patches.  The current tree should not
> be impacted.

This sounds like a good idea as well (and I would use it on a near
daily basis as well ;).  Obviously such a request can also fail,
eg. when requesting to fold a change into a patch, where a subsequent
patch modifies the same lines.

But it would not be a replacement to selecting changes with a
granularity finer than file-level, which is what I wanted to suggest.

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: Cogito wishlist: ability to set merge strategy
From: Petr Baudis @ 2006-01-18 19:32 UTC (permalink / raw)
  To: H. Peter Anvin, Martin Langhoff
  Cc: Git Mailing List, Junio C Hamano, Andreas Ericsson
In-Reply-To: <43CC64AD.30606@zytor.com>

Dear diary, on Tue, Jan 17, 2006 at 04:29:49AM CET, I got a letter
where "H. Peter Anvin" <hpa@zytor.com> said that...
> It would be nice if Cogito would let one override the default merge 
> strategy, i.e. to use the recursive merge strategy.  I've had some 
> moderate luck with using recursive merge for the klibc trees recently.

Dear diary, on Wed, Jan 18, 2006 at 07:06:07PM CET, I got a letter
where Martin Langhoff <martin.langhoff@gmail.com> said that...
> One of these days I'll convince Pasky to use git-merge for
> cg-merge's internals.

For the record, I acknowledge that the merge strategies are useful and I
plan to make cg-merge use them, but I'm unable to tell when that will
happen. I would still like to keep the current Cogito merging the
default merge strategy at least for a while until the dust settles down,
though. From the Git merge strategies, I guess only recursive is
useful for Cogito...

Patches welcome.  ;-)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe.  -- Douglas Adams

^ permalink raw reply

* Re: RFC: Subprojects
From: Daniel Barkalow @ 2006-01-18 19:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4q41wevw.fsf@assigned-by-dhcp.cox.net>

On Wed, 18 Jan 2006, Junio C Hamano wrote:

> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > ... I thought we 
> > decided that the stuff that doesn't know about subprojects sees them as 
> > opaque, rather than as their contents, so your toplevel git diff doesn't 
> > show you a millions lines when you switch from linux-2.6.14 to 15.
> 
> It was discussed in the context of "gitlink" approach as a way
> to keep things simple.  In the "bind" approach, I am doing
> things a bit differently, and this "toplevel has everything" is
> one big difference.

I thought that had been a question of what is best as an interface, but 
either is plausible.

> > I thought we decided that committing the superproject wouldn't
> > commit the subprojects.
> 
> I see it as a policy.  We can forbid the modification of the
> subproject part of the index (i.e. detect and refuse to commit
> and/or do "git reset --mixed" only for the subproject part) so
> that the commit outlined in the "bind" approach does not _have_
> to make a new commit, if you want to work that way.  But if
> somebody else wants to make a related set of changes to the
> superproject and bound subprojects, we _could_ allow a commit
> per subproject.

I think it makes most sense, for the purpose of consolidating code paths, 
if the superproject may only be committed with clean subprojects; the 
porcelain has the option of responding to unclean subprojects by 
committing them to make them clean, and then there is only a single case 
for how the superproject commit happens. I think it makes most sense as a 
command line option, like -a is; if you want to commit dirty suprojects, 
you use --subprojects, and it does that. If you're not expecting to need 
it, you won't start doing the wrong commit.

> > I hope people will want to prepare their commits to the kernel subproject 
> > as would be suitable for pushing to Linus, which would suggest that they'd 
> > tend to do a commit in the kernel subproject embedded in their 
> > superproject separately from doing the commit in the superproject, and 
> > so the branch head would match the index but not the bind line when they 
> > got to committing the superproject.
> 
> Yes, that is the workflow I outlined in the footnote part you
> did not quote.  I think it is cleaner to do things that way: to
> have a separate, kernel-only repository+worktree and do pure
> kernel work there, and fetch into the superproject branch that
> keeps track of the kernel subproject in that superproject.

I actually meant that I expected people to go into superproject/linux-2.6, 
make changes, and commit there, using the place it appears in their 
superproject working tree as a working tree for the subproject, so the 
opposite of your footnote, but still doing the subproject commit as a step 
before the superproject commit.

For example, they might want to send the subproject changes upstream as a 
patch, get feedback, reset the subproject, do revised changes, commit 
that, get it merged upstream, and then commit the changes to the 
superproject, including in the message the fact that the changes have been 
pushed upstream. But they may still want to do this all within the working 
tree of the superproject, so that they can test their changes in context.

> Having more than one working tree with .git/, everything except
> HEAD and index undef which are symlinked to one copy, like you
> do, would be a natural way to work.
> 
> 	embed/.git/HEAD -> refs/heads/master
> 
> 	embed/linux-2.6/.git/HEAD -> refs/heads/kernel
> 	embed/linux-2.6/.git/refs -> ../.git/refs
> 	embed/linux-2.6/.git/objects -> ../.git/objects
> 
> Then, after hacking on the collective whole to make the whole
> thing work in "embed" directory, you would:
> 
> 	$ cd linux-2.6
>         $ git commit
> 
> to make commit that can be sent Linus, at the same time updating
> the "kernel" branch.  Then come back to the toplevel, tell git
> that you updated the "kernel" branch so it does not complain
> that the "bind" in the HEAD commit does not match "kernel" head,
> and make a toplevel commit.

I'm not sure having a .git directory for a subproject inside a 
subdirectory of the superproejct's working tree is all that good an idea, 
and I don't think it should be necessary in any case, because the toplevel 
index has all the information from the subproject index. The only think 
would be having "git commit" notice what you're doing when you run it from 
a directory that's a subproject.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Petr Baudis @ 2006-01-18 19:26 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: luis, git
In-Reply-To: <46a038f90601181107h57e6fb73peb199689349aec41@mail.gmail.com>

Dear diary, on Wed, Jan 18, 2006 at 08:07:27PM CET, I got a letter
where Martin Langhoff <martin.langhoff@gmail.com> said that...
> On 1/19/06, Petr Baudis <pasky@suse.cz> wrote:
> > Now you want to merge the branch as a whole. Cherrypicking-aware VCS
> > would just merge the patch2, but you are taking the whole diff:
> ...
> > And you get a conflict instead of b\nc.
> 
> While I haven't tested your particular example, it looks to me like
> git-cherry would identify it correctly. So far my experience has been
> that git-cherry's strategy detects my cherry-picked patches pretty
> well.
> 
> Why would it not work in your example? Patch 1 has clearly been
> applied in both branches, and git-cherry would normally detect that
> alright.

  It probably would. So? We are talking about git-merge and cg-merge
here. Now, it might be interesting to have a cherry-aware merge
strategy, but I suspect that the conflicts handling there would be quite
non-trivial.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe.  -- Douglas Adams

^ permalink raw reply

* Re: Joining Repositories
From: Junio C Hamano @ 2006-01-18 19:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601181010410.3240@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> On Wed, 18 Jan 2006, Junio C Hamano wrote:
>> 
>> Tracking history across renames is something we have only half
>> of the needed support.  We can notice rename points but there is
>> no way to tell our usability tools to automatically follow it.
>> IOW "whatchanged r1/hello.c" will stop at the point the
>> original project renamed hello.c
>
> Note that "whatchanged" really really _really_ must not follow renames.

Sorry for having brought up the issue again.  I personally do
not disagree with you.  Because I did not want to waste your
time rehashing it, I attempted to make it absolutely clear that
I was talking about an _optional_ way to tell the tool to do so,
when somebody so used to "annotate" wants to.  Obviously my
attempt did not work well X-<.

> I realize that this is heresy to people who are used to "annotate" and 
> want to follow not the path, but the "conceptual inode", but the thing is, 
> paths really really are a lot more important to a maintainer. Following an 
> individual file is a secondary issue.
> ...
> In other words, tracking pathnames is really _fundamentally_ a more 
> powerful operation.

I agree with you including this part. At the same time, I think
annotate-minded people would find it useful if there were an
option (or a separate program similar to whatchanged) that
notices file or directory renames, and adjusts the initial path
limiter, probably by adding not replacing the new "possibly
relevant" paths it discovered to it.

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Martin Langhoff @ 2006-01-18 19:07 UTC (permalink / raw)
  To: Petr Baudis; +Cc: luis, git
In-Reply-To: <20060118185542.GT28365@pasky.or.cz>

On 1/19/06, Petr Baudis <pasky@suse.cz> wrote:
> Now you want to merge the branch as a whole. Cherrypicking-aware VCS
> would just merge the patch2, but you are taking the whole diff:
...
> And you get a conflict instead of b\nc.

While I haven't tested your particular example, it looks to me like
git-cherry would identify it correctly. So far my experience has been
that git-cherry's strategy detects my cherry-picked patches pretty
well.

Why would it not work in your example? Patch 1 has clearly been
applied in both branches, and git-cherry would normally detect that
alright.

btw, when is cg-merge switching to use git-merge? :-p



martin

^ 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