Git development
 help / color / mirror / Atom feed
* git-svn fetch fails when a file is renamed changing only case
From: Pazu @ 2006-10-09 17:13 UTC (permalink / raw)
  To: git

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

For example, if you had a file named TestFile and it's renamed to 
TESTFILE, git-svn fails to fetch revisions after the rename.

My perl skills are close to non-existant, so I'm afraid I don't know how 
to fix this. Attached to this message, however, is a sample svn 
repository that can reproduce this bug. Just unpack it somewhere (let's 
say, in /tmp) and try the following:

tar -C /tmp -xzf git-svn-rename-test.tar.gz
mkdir test-wc
cd test-wc
git-svn init file:///tmp/git-svn-rename-test
git-svn fetch

The last command will fail after fetching revision #3, where a file 
named TestFile was renamed to TESTFILE. Here's the stack trace:

svn: 'TestFile' is not under version control
256 at /Users/pazu/bin/git-svn line 2015
         main::safe_qx('svn', 'propget', 'svn:keywords', 
'TestFile@BASE') called at /Users/pazu/bin/git-svn line 2154
         main::svn_propget_base('svn:keywords', 'TestFile') called at 
/Users/pazu/bin/git-svn line 1773
         main::do_update_index('ARRAY(0x180bd68)', 'remove', 'undef') 
called at /Users/pazu/bin/git-svn line 1805
         main::index_changes() called at /Users/pazu/bin/git-svn line 1875
         main::git_commit('HASH(0x180bd98)', 
'c77db38dc752305ba19ebe19b22306551d0f8d52') called at 
/Users/pazu/bin/git-svn line 346
         main::fetch_cmd() called at /Users/pazu/bin/git-svn line 290
         main::fetch() called at /Users/pazu/bin/git-svn line 149

I'm on Mac OS X (Intel) 10.4.8

mini:~ pazu$ uname -a
Darwin mini.intranet.ecore.com.br 8.8.1 Darwin Kernel Version 8.8.1: Mon 
Sep 25 19:42:00 PDT 2006; root:xnu-792.13.8.obj~1/RELEASE_I386 i386 i386

Git was compiled from the released 1.4.2.3 sources, without any 
modifications:

mini:~ pazu$ git-svn --version
git-svn version 1.4.2.3

If you need more information, you can contact me directly, or just use 
the list -- I'll be here listening :)

-- Marcus Brito

[-- Attachment #2: git-svn-rename-test.tar.gz --]
[-- Type: application/x-gzip, Size: 6686 bytes --]

^ permalink raw reply

* Re: [RFC/PATCH] merge: loosen overcautious "working file will be lost" check.
From: Luben Tuikov @ 2006-10-09 17:20 UTC (permalink / raw)
  To: Junio C Hamano, Linus Torvalds; +Cc: git
In-Reply-To: <7v8xjqdoq1.fsf_-_@assigned-by-dhcp.cox.net>

I think this is a good thing.

How about this case I've noticed in my trees:

After branching out, a file is deleted, only to add
a different file with the same file name.

Then any time I pull in from the trunk to merge,
merge fails with git-diff-files showing all 0's and the
file name in question.  Picture:

  Branch B       +-----------------M1---->
                /                 /
               C2 <-- git-add A  /
              /                 /
             C1 <-- git-rm A   /
            /                 /
Trunk -----+-----------------+---->

Since the common ancestor precedes git-rm, any Merge M1,
complains that file A needs resolving with git-show-files
all 0's.  I don't mind that so much and was wondering
what you thought about it.

    Luben

--- Junio C Hamano <junkio@cox.net> wrote:

> The three-way merge complained unconditionally when a path that
> does not exist in the index is involved in a merge when it
> existed in the working tree.  If we are merging an old version
> that had that path tracked, but the path is not tracked anymore,
> and if we are merging that old version in, the result will be
> that the path is not tracked.  In that case we should not
> complain.
> 
> Signed-off-by: Junio C Hamano <junkio@cox.net>
> ---
> 
>  * Consolidated patch to summarize a few crapoids I sent out
>    tonight.
> 
>    The change to merge-one-file still does not do .gitignore
>    check but that is easy to add once we know this is the right
>    direction to go, which I am not sure yet.  If we can convince
>    ourselves that this is the right direction we should update
>    merge-recursive as well.
> 
>  git-merge-one-file.sh       |   16 ++++++++++++-
>  t/t1004-read-tree-m-u-wf.sh |   53 +++++++++++++++++++++++++++++++++++++++++++
>  unpack-trees.c              |    2 -
>  3 files changed, 68 insertions(+), 3 deletions(-)
> 
> diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
> index fba4b0c..74ad4f2 100755
> --- a/git-merge-one-file.sh
> +++ b/git-merge-one-file.sh
> @@ -23,6 +23,12 @@ #
>  "$1.." | "$1.$1" | "$1$1.")
>  	if [ "$2" ]; then
>  		echo "Removing $4"
> +	else
> +		# read-tree checked that index matches HEAD already,
> +		# so we know we do not have this path tracked.
> +		# there may be an unrelated working tree file here,
> +		# which we should just leave unmolested.
> +		exit 0
>  	fi
>  	if test -f "$4"; then
>  		rm -f -- "$4" &&
> @@ -34,8 +40,16 @@ #
>  #
>  # Added in one.
>  #
> -".$2." | "..$3" )
> +".$2.")
> +	# the other side did not add and we added so there is nothing
> +	# to be done.
> +	;;
> +"..$3")
>  	echo "Adding $4"
> +	test -f "$4" || {
> +		echo "ERROR: untracked $4 is overwritten by the merge."
> +		exit 1
> +	}
>  	git-update-index --add --cacheinfo "$6$7" "$2$3" "$4" &&
>  		exec git-checkout-index -u -f -- "$4"
>  	;;
> diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh
> new file mode 100755
> index 0000000..018fbea
> --- /dev/null
> +++ b/t/t1004-read-tree-m-u-wf.sh
> @@ -0,0 +1,53 @@
> +#!/bin/sh
> +
> +test_description='read-tree -m -u checks working tree files'
> +
> +. ./test-lib.sh
> +
> +# two-tree test
> +
> +test_expect_success 'two-way setup' '
> +
> +	echo >file1 file one &&
> +	echo >file2 file two &&
> +	git update-index --add file1 file2 &&
> +	git commit -m initial &&
> +
> +	git branch side &&
> +	git tag -f branch-point &&
> +
> +	echo file2 is not tracked on the master anymore &&
> +	rm -f file2 &&
> +	git update-index --remove file2 &&
> +	git commit -a -m "master removes file2"
> +'
> +
> +test_expect_success 'two-way not clobbering' '
> +
> +	echo >file2 master creates untracked file2 &&
> +	if err=`git read-tree -m -u master side 2>&1`
> +	then
> +		echo should have complained
> +		false
> +	else
> +		echo "happy to see $err"
> +	fi
> +'
> +
> +# three-tree test
> +
> +test_expect_success 'three-way not complaining' '
> +
> +	rm -f file2 &&
> +	git checkout side &&
> +	echo >file3 file three &&
> +	git update-index --add file3 &&
> +	git commit -a -m "side adds file3" &&
> +
> +	git checkout master &&
> +	echo >file2 file two is untracked on the master side &&
> +
> +	git-read-tree -m -u branch-point master side
> +'
> +
> +test_done
> diff --git a/unpack-trees.c b/unpack-trees.c
> index 3ac0289..b1d78b8 100644
> --- a/unpack-trees.c
> +++ b/unpack-trees.c
> @@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **
>  	if (index) {
>  		verify_uptodate(index, o);
>  	}
> -	else if (path)
> -		verify_absent(path, "overwritten", o);
>  
>  	o->nontrivial_merge = 1;
>  
> -- 
> 1.4.2.3.g2c59
> 
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: "fatal: Untracked working tree file 'so-and-so' would be overwritten by merge"
From: Junio C Hamano @ 2006-10-09 16:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0610090858120.3952@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> If the local index doesn't change, we should not print out the "Removing 
> 'so-and-so'" message, but we should also not even _touch_ that file, 
> because it was already "gone" as far as the local tree was concerned.
>
> Agreed?

Yes.

^ permalink raw reply

* Re: Does GIT has vc keywords like CVS/Subversion?
From: Linus Torvalds @ 2006-10-09 16:13 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Dongsheng Song, git
In-Reply-To: <4529B77A.707@gmail.com>



On Mon, 9 Oct 2006, Liu Yubao wrote:
> 
> IMHO, I don't think keyword substitution is a good idea, as it will confuse
> the external diff/merge tools.

There are other reasons why it's a _horrible_ idea, like the fact that it 
can mess up binary files etc (so if you do keyword substitution, you also 
need to suddenly care _deeply_ whether a file is binary or not).

The whole notion of keyword substitution is just totally idiotic. It's 
trivial to do "outside" of the actual content tracking, if you want to 
have it when doing release trees as tar-balls etc.

So:
 - inside of the SCM, keyword substitution is pointless, since you have 
   much better tools available (like "git log filename")
 - outside of the SCM, keyword substitution can make sense, but doing it 
   should be in helper scripts or something that can easily tailor it for 
   the actual need of that particular project.

For example, we actually do a certain kind of keyword subtituion for the 
kernel. Look at the -git snapshots: the script that generates the snapshot 
diffs has a simple sequence in it to "keyword substitute" the Makefile for 
the EXTRAVERSION flag, so the diff will result in the Makefile having the 
knowledge of which git SHA1 version the resulting patch was, even though 
the thing isn't a git tree any more:

	...
	git-read-tree $CURCOMM
	git-checkout-index Makefile
	perl -pi -e "s/EXTRAVERSION =.*/EXTRAVERSION = $EXTRAVERSION/" Makefile
	git-diff-index -m -p $RELTREE | gzip -9 > $STAGE/patch-$CURNAME.gz
	...

So this is how to do keyword substitution in a _sane_ way.

Sure, we could do something like this as a git script, and support it 
"natively", but the fact is, keyword substitution is just stupid.

		Linus

^ permalink raw reply

* Re: "fatal: Untracked working tree file 'so-and-so' would be overwritten by merge"
From: Linus Torvalds @ 2006-10-09 16:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vodsmdq0m.fsf@assigned-by-dhcp.cox.net>



On Sun, 8 Oct 2006, Junio C Hamano wrote:
> 
> Note note note.  The above patch alone leaves merge risky to
> remove an untracked working tree files, and needs to be
> compensated by corresponding checks to the git-merge-xxx
> strategies.  The original code was overcautious, but was
> protecting valid cases too.

I think the difference _should_ be that we only remove the local file if 
it was removed _remotely_.

In  that case, it was there in the original tree, and removing it is 
correct.

> diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index 
> fba4b0c..25aedb7 100755 --- a/git-merge-one-file.sh +++ 
> b/git-merge-one-file.sh @@ -23,6 +23,9 @@ #
>  "$1.." | "$1.$1" | "$1$1.")

So I actually think that we should NOT consider these three cases to be 
the same.

There are really two distinct cases:

 - "$1.." and "$1.$1"
	The file had already been removed locally, AND WE SHOULD NOT TOUCH 
	IT.

 - "$1$1.":
	The file was removed remotely, and we SHOULD remove it locally.

In fact, we already have that as a "special case":

>  	if [ "$2" ]; then
>  		echo "Removing $4"
> +	elif test -f "$4"
> +		echo "ERROR: untracked $4 is removed by the merge."
> +		exit 1
>  	fi
>  	if test -f "$4"; then
>  		rm -f -- "$4" &&

That

	if [ "$2" ]; then
		echo "Removing $4"

is _exactly_ that case: it is the "$1$1." case, and we already treat it 
differently, but we actually treat it differently the wrong way: we only 
print out the message for that case, but the actual "touch working tree" 
code should _also_ be affected.

If the local index doesn't change, we should not print out the "Removing 
'so-and-so'" message, but we should also not even _touch_ that file, 
because it was already "gone" as far as the local tree was concerned.

Agreed?

		Linus

^ permalink raw reply

* [RFC] gitweb wishlist and TODO list
From: Jakub Narebski @ 2006-10-09 12:49 UTC (permalink / raw)
  To: git

There is a new part of gitweb TODO list and wishlist; planned features and
features it would be nice to have. If you have new ideas, if you want some
features to be implemented first, if you use some web interface to some SCM
you like, please do contribute.

I've tried to divide this TODO/wishlist into categories.


1. Cleanups and refactoring

 * HTML and CSS cleanup. All (or almost all) styling should be done using
   CSS, and not embedded style or presentation elements. All HTML elements
   except perhaps a few should have either class attribute (if such
   element can be multiple times on page) or id attribute (if there can be
   only one such element). Perhaps some class attributes should be changed
   to id attributes. Gitweb has much improved from the incorporation in
   this area.

 * CSS refactoring. Try to avoid repeating the same styling, using
   combination of descendant and _child_ selectors, perhaps also
   adjacent sibling selector and attribute/attribute value selector.
   Perhaps large reorganization patch (moving contents within CSS and adding
   comments) is to be done...

 * Code refactoring. Separate/refactor common parts and put them into
   separate subrotines OR collapse similar subrotines into one subroutine
   with an argument selecting the case. For example git_blob and
   git_blob_plain could be collapsed; git_shortlog, git_tags/git_heads,
   git_log, git_history do similar work. When the new
   --grep/--author/--commiter options to git-rev-list hits released version,
   perhaps also git_search could be put together with the previous set.
   git_rss does similar work as a git_summary.

 * Refactor printing related links (like "blame | history | raw" for blob
   entries in tree view) into separate subroutine. The list depends both on
   the kind of object pointed, and on the current action/view.

 * Perhaps refactor reading and validation of parameters, except the ones
   used for dispatch i.e. project and action parameters, into separate
   subroutine
 
        my ($hash, $hash_base) = gitweb_params('hash', 'hash_base');    

   I'm not sure if it is/would be usefull.


2. Git.pm-ish (subroutines which in generalized version are/could be
   in Git.pm)
 
 * Refactor calling a git command and reading it's output into separate
   subroutine git_command/git_pipe, so for example if someone _has_ to use
   gitweb with ancient Perl version which does not understand list version
   of magic "-|" open could do it changing only one subroutine. Well, we can
   use Git.pm when it hits main release.

 * Add subroutine/subroutines, which given a full name of ref, returns
   either another ref if input ref was symlink/symref, or hash of the
   pointed object, and which work not only with ordinary loose refs, but
   also with symlinks, symrefs (up to some level of recursion) and packed
   refs. All without calling any git command. But I guess that currently
   it is not needed at all.

 * Add simplified git config file parser, which would _read_ only gitweb
   entries (and convert them to bool/int if necessary). With this we could
   move description, category, export_ok, .hide, cloneurl to config file,
   instead of cluttering $GIT_DIR. Or just make it an option (read file
   first, if it doesn't exist try config file).

 * Parsing of remotes/ files _and_ equivalent config entries, for adding
   information (tooltip?) about tracking branches in heads view, and for
   adding information about given subdirectory in refs/remotes/ (see below).


3. Optimizing gitweb

 * Use git-for-each-ref (when it hits released version) to speed up of
   generation of summary, heads and tags views. It would also enable the
   option of having most recent commit date in projects list view, and not
   most recent commit in current branch (in HEAD).
 
 * Add better support for mod_perl, e.g. $r->path_info(), via checking for
   MOD_PERL enviromental variable.

 * Better support for mod_perl/FastCGI, perhaps wrapping the changeable part
   into gitweb_handler subroutine, and calling it.


4. New features

 * Add support for other directories in $refs/ besides "heads" and
   "tags" directories, for example refs/remotes/ generated when cloning with
   --use-separate-remote option. On short TODO list.

 * Add categories support a la gitweb-xmms2 to the projects list view (and
   perhaps also OPML); perhaps with option to use first part of path to
   repository as category.

 * Code highlighting (or generic filter) support in blob view, perhaps as
   a feature. Proposed tools for generating syntax highlighting include
   Highlight (http://www.andre-simon.de) and GNU Source Highlight
   (http://www.gnu.org/software/src-highlite) a la gitweb-xmms2.
   Gitweb-xmms2 uses Highlight, and due to the tags support uses temporary
   files. I think that CSS for code highlighting should be in separate file,
   and that selecting syntax to use should be done using mime.types like
   file rather than gitweb-xmms2 internal configuration (hash of
   extensions).

 * Committags support from gitweb-xmms2 in commit, commitdiff, log views and
   in the top commit summary/title link on most pages. There was preliminary
   patch on git mailing list for committags support (more general than
   the support in gitweb-xmms2), with current commitsha link (now in
   format_log_line_html) implemented as committag. Junio had quite
   a good idea how to avoid having to do committags _after_ HTML escaping,
   and how to stack committags. I'm not sure if it wouldn't be better to try
   to do all committags in one go, instead of stacking. Perhaps also commit
   message "syntax highlighting" (i.e. highlighting signoff lines) and empty
   lines simplification should be done using committags.

 * Crossreferencing in blob view. Gitweb-xmms2 uses if I remember correctly
   etags to generate anchors and to generate hyperlinks to definition of
   function. GNU Highlight can use encumberant-tags IIRC. Both need I think
   temporary files for index. Perhaps this should be done rather as a part
   of gitweb/git integration with LXR Cross Referencer. 

   Do you know other projects that could be used instead of etags here?

   I'm not sure if it is worth to pursue implementing it now.

 * Improve blame view, making use of --porcelain option to git-blame (for
   later). Perhaps change blame view from table based one to div based one.
   Use different colors for different commits (graph coloring problem).

 * Perhaps add some kind of finding closest preceding/following tag. and on
   which branch we are on. Tempered of course by the concerns of
   performance. What is possible for locally run history browser like gitk
   or qgit, might be not feasible on server run web interface.

 * Add information from remotes/ to heads view, for example the following
     tracks branch 'master' of git://git.kernel.org/pub/scm/git/git (origin)
   as a tooltip for 'origin' branch. But what if one branch tracks more than
   one remote? Needs to use also config file.

 * Support for tracking renames in history view. Simple rename tracking
   I think could be done directly in gitweb; more advanced would need
   --follow option (i.e. core git improvement).

 * log/shortlog should be a format, so we could have log-like history, tags,
   heads views.

 * add summary of number of lines changed for each file (a la darcsview)
   in the difftree part of commit and *diff* views, e.g.

        blame.c   +1 -0  diff | history | blame

   or something like that.

 * add extended header to the commitdiff and perhaps blobdiff views,
   hyperlinked. _This_ would add some patches to commitdiff view, which are
   now IIRC visible only in difftree part now.

 * enable sorting tags/heads view by name instead of sorting it by date.


5. New views

 * Reflog view (most probably limited to heads only). I'm not sure if it is
   worth time spend on calling git commands to mark unreachable commits for
   example using strikethrough, and hyperlink reachable. Any ideas how such
   a view should look like?

 * ViewVC-like tree-blame view. There was RFC patch adding tree_blame view
   some time ago here, on git mailing list. The main problem of course is
   performance. We could implement tree_blame purely in gitweb as it was
   done in mentioned patch (having --stdin option to git-ls-tree would
   help), or add new core command/extend git-blame for directories. There is
   also a question if we want to find blame for tree entries, or not.

 * "List of the files in given directory, touched by given commit"

 * Perhaps ad Atom feed support as an alternative to RSS, and XOXO as an
   alternative to OPML.

 * Graph of number of changed files in given branch; probably should be
   cached.


X. Proposed improvements to core git commands
 * add --stdin option to git-ls-tree, a la --stdin option to git-diff-tree.
 * add --follow option to git-rev-list, allow to provide path limiter via
   stdin (with --stdin option) in git-diff-tree
 * add --numstat option to git-diff; currently only git-apply has it.


Thoughts? Comments?
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* gitk feature request..
From: Pierre Marc Dumuid @ 2006-10-09 11:52 UTC (permalink / raw)
  To: git

Hi,
I was adviced on the IRC channel to send my feature requests here...

I have two feature requests:
1. a bugzilla to place feature requests.
2. All the stored "views" that can be created and placed under the 
"view" menu should be unique for each repository.

Currently I am starting to use git for a few projects, and I've found 
that my named view list is growing.. too much.  I think that there 
should be a foluder in the .git directory that contains a list of the 
named views so that a person's menu isn't flooded with entries relating 
to different repositories..

Regards,
Pierre

^ permalink raw reply

* Re: perhaps time to remove git_blame from gitweb, and git-annotate?
From: Ryan Anderson @ 2006-10-09 10:37 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Luben Tuikov, Petr Baudis, Jakub Narebski, Ryan Anderson,
	Johannes Schindelin, Martin Langhoff, Martyn Smith,
	Fredrik Kuivinen, Linus Torvalds
In-Reply-To: <7vu02jfaec.fsf_-_@assigned-by-dhcp.cox.net>

On Thu, Oct 05, 2006 at 01:13:15AM -0700, Junio C Hamano wrote:
> It's been a while since we lost git_blame from %actions list.  I
> am wondering maybe it's time to remove it, after 1.4.3 happens.

I certainly have no objection.  In fact, I sent a patch a moment ago.
(I didn't keep the cc: on it, I figured there was too high a chance of
mishap when pasting the cc: list.)

I forgot to mentio it in the email, but I have the change pullable from:
http://h4x0r5.com/~ryan/git/ryan.git/ del-annotate
(and gitwebed from http://h4x0r5.com/~ryan/gitweb.cgi )
-- 

Ryan Anderson
  sometimes Pug Majere

^ permalink raw reply

* [PATCH 1/1] Remove git-annotate.perl and create a builtin-alias for git-blame
From: Ryan Anderson @ 2006-10-09 10:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Ryan Anderson
In-Reply-To: <7vu02jfaec.fsf_-_@assigned-by-dhcp.cox.net>

Signed-off-by: Ryan Anderson <ryan@michonline.com>
---

I've clearly been too busy to actually fix this, and blame works, so,
let's create an internal alias and delete annotate.

(The tests still pass, for whatever that's worth.)
---
 Makefile           |    3 +-
 builtin-annotate.c |   25 ++
 builtin.h          |    1 +
 git-annotate.perl  |  708 ----------------------------------------------------
 git.c              |    1 +
 5 files changed, 29 insertions(+), 709 deletions(-)

diff --git a/Makefile b/Makefile
index 2c7c338..7e62e76 100644
--- a/Makefile
+++ b/Makefile
@@ -173,7 +173,7 @@ SCRIPT_SH = \
 SCRIPT_PERL = \
 	git-archimport.perl git-cvsimport.perl git-relink.perl \
 	git-shortlog.perl git-rerere.perl \
-	git-annotate.perl git-cvsserver.perl \
+	git-cvsserver.perl \
 	git-svnimport.perl git-cvsexportcommit.perl \
 	git-send-email.perl git-svn.perl
 
@@ -265,6 +265,7 @@ LIB_OBJS = \
 
 BUILTIN_OBJS = \
 	builtin-add.o \
+	builtin-annotate.o \
 	builtin-apply.o \
 	builtin-archive.o \
 	builtin-cat-file.o \
diff --git a/builtin-annotate.c b/builtin-annotate.c
new file mode 100644
index 0000000..2655e60
--- /dev/null
+++ b/builtin-annotate.c
@@ -0,0 +1,25 @@
+/*
+ * "git annotate" builtin alias
+ *
+ * Copyright (C) 2006 Ryan Anderson
+ */
+#include "git-compat-util.h"
+#include "exec_cmd.h"
+
+int cmd_annotate(int argc, const char **argv, const char *prefix)
+{
+	const char **nargv;
+	int i;
+	nargv = xmalloc(sizeof(char *) * (argc + 2));
+	
+	nargv[0] = "blame";
+	nargv[1] = "-c";
+	
+	for (i = 1; i < argc; i++) {
+		nargv[i+1] = argv[i];
+	}
+	nargv[argc + 1] = NULL;
+
+	return execv_git_cmd(nargv);
+}
+	
diff --git a/builtin.h b/builtin.h
index f9fa9ff..2c5d900 100644
--- a/builtin.h
+++ b/builtin.h
@@ -13,6 +13,7 @@ extern void stripspace(FILE *in, FILE *o
 extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
 
 extern int cmd_add(int argc, const char **argv, const char *prefix);
+extern int cmd_annotate(int argc, const char **argv, const char *prefix);
 extern int cmd_apply(int argc, const char **argv, const char *prefix);
 extern int cmd_archive(int argc, const char **argv, const char *prefix);
 extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
diff --git a/git-annotate.perl b/git-annotate.perl
deleted file mode 100755
index 215ed26..0000000
--- a/git-annotate.perl
+++ /dev/null
@@ -1,708 +0,0 @@
-#!/usr/bin/perl
-# Copyright 2006, Ryan Anderson <ryan@michonline.com>
-#
-# GPL v2 (See COPYING)
-#
-# This file is licensed under the GPL v2, or a later version
-# at the discretion of Linus Torvalds.
-
-use warnings;
-use strict;
-use Getopt::Long;
-use POSIX qw(strftime gmtime);
-use File::Basename qw(basename dirname);
-
-sub usage() {
-	print STDERR "Usage: ${\basename $0} [-s] [-S revs-file] file [ revision ]
-	-l, --long
-			Show long rev (Defaults off)
-	-t, --time
-			Show raw timestamp (Defaults off)
-	-r, --rename
-			Follow renames (Defaults on).
-	-S, --rev-file revs-file
-			Use revs from revs-file instead of calling git-rev-list
-	-h, --help
-			This message.
-";
-
-	exit(1);
-}
-
-our ($help, $longrev, $rename, $rawtime, $starting_rev, $rev_file) = (0, 0, 1);
-
-my $rc = GetOptions(	"long|l" => \$longrev,
-			"time|t" => \$rawtime,
-			"help|h" => \$help,
-			"rename|r" => \$rename,
-			"rev-file|S=s" => \$rev_file);
-if (!$rc or $help or !@ARGV) {
-	usage();
-}
-
-my $filename = shift @ARGV;
-if (@ARGV) {
-	$starting_rev = shift @ARGV;
-}
-
-my @stack = (
-	{
-		'rev' => defined $starting_rev ? $starting_rev : "HEAD",
-		'filename' => $filename,
-	},
-);
-
-our @filelines = ();
-
-if (defined $starting_rev) {
-	@filelines = git_cat_file($starting_rev, $filename);
-} else {
-	open(F,"<",$filename)
-		or die "Failed to open filename: $!";
-
-	while(<F>) {
-		chomp;
-		push @filelines, $_;
-	}
-	close(F);
-
-}
-
-our %revs;
-our @revqueue;
-our $head;
-
-my $revsprocessed = 0;
-while (my $bound = pop @stack) {
-	my @revisions = git_rev_list($bound->{'rev'}, $bound->{'filename'});
-	foreach my $revinst (@revisions) {
-		my ($rev, @parents) = @$revinst;
-		$head ||= $rev;
-
-		if (!defined($rev)) {
-			$rev = "";
-		}
-		$revs{$rev}{'filename'} = $bound->{'filename'};
-		if (scalar @parents > 0) {
-			$revs{$rev}{'parents'} = \@parents;
-			next;
-		}
-
-		if (!$rename) {
-			next;
-		}
-
-		my $newbound = find_parent_renames($rev, $bound->{'filename'});
-		if ( exists $newbound->{'filename'} && $newbound->{'filename'} ne $bound->{'filename'}) {
-			push @stack, $newbound;
-			$revs{$rev}{'parents'} = [$newbound->{'rev'}];
-		}
-	}
-}
-push @revqueue, $head;
-init_claim( defined $starting_rev ? $head : 'dirty');
-unless (defined $starting_rev) {
-	my $diff = open_pipe("git","diff","HEAD", "--",$filename)
-		or die "Failed to call git diff to check for dirty state: $!";
-
-	_git_diff_parse($diff, [$head], "dirty", (
-				'author' => gitvar_name("GIT_AUTHOR_IDENT"),
-				'author_date' => sprintf("%s +0000",time()),
-				)
-			);
-	close($diff);
-}
-handle_rev();
-
-
-my $i = 0;
-foreach my $l (@filelines) {
-	my ($output, $rev, $committer, $date);
-	if (ref $l eq 'ARRAY') {
-		($output, $rev, $committer, $date) = @$l;
-		if (!$longrev && length($rev) > 8) {
-			$rev = substr($rev,0,8);
-		}
-	} else {
-		$output = $l;
-		($rev, $committer, $date) = ('unknown', 'unknown', 'unknown');
-	}
-
-	printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer,
-		format_date($date), ++$i, $output);
-}
-
-sub init_claim {
-	my ($rev) = @_;
-	for (my $i = 0; $i < @filelines; $i++) {
-		$filelines[$i] = [ $filelines[$i], '', '', '', 1];
-			# line,
-			# rev,
-			# author,
-			# date,
-			# 1 <-- belongs to the original file.
-	}
-	$revs{$rev}{'lines'} = \@filelines;
-}
-
-
-sub handle_rev {
-	my $revseen = 0;
-	my %seen;
-	while (my $rev = shift @revqueue) {
-		next if $seen{$rev}++;
-
-		my %revinfo = git_commit_info($rev);
-
-		if (exists $revs{$rev}{parents} &&
-		    scalar @{$revs{$rev}{parents}} != 0) {
-
-			git_diff_parse($revs{$rev}{'parents'}, $rev, %revinfo);
-			push @revqueue, @{$revs{$rev}{'parents'}};
-
-		} else {
-			# We must be at the initial rev here, so claim everything that is left.
-			for (my $i = 0; $i < @{$revs{$rev}{lines}}; $i++) {
-				if (ref ${$revs{$rev}{lines}}[$i] eq '' || ${$revs{$rev}{lines}}[$i][1] eq '') {
-					claim_line($i, $rev, $revs{$rev}{lines}, %revinfo);
-				}
-			}
-		}
-	}
-}
-
-
-sub git_rev_list {
-	my ($rev, $file) = @_;
-
-	my $revlist;
-	if ($rev_file) {
-		open($revlist, '<' . $rev_file)
-		    or die "Failed to open $rev_file : $!";
-	} else {
-		$revlist = open_pipe("git-rev-list","--parents","--remove-empty",$rev,"--",$file)
-			or die "Failed to exec git-rev-list: $!";
-	}
-
-	my @revs;
-	while(my $line = <$revlist>) {
-		chomp $line;
-		my ($rev, @parents) = split /\s+/, $line;
-		push @revs, [ $rev, @parents ];
-	}
-	close($revlist);
-
-	printf("0 revs found for rev %s (%s)\n", $rev, $file) if (@revs == 0);
-	return @revs;
-}
-
-sub find_parent_renames {
-	my ($rev, $file) = @_;
-
-	my $patch = open_pipe("git-diff-tree", "-M50", "-r","--name-status", "-z","$rev")
-		or die "Failed to exec git-diff: $!";
-
-	local $/ = "\0";
-	my %bound;
-	my $junk = <$patch>;
-	while (my $change = <$patch>) {
-		chomp $change;
-		my $filename = <$patch>;
-		if (!defined $filename) {
-			next;
-		}
-		chomp $filename;
-
-		if ($change =~ m/^[AMD]$/ ) {
-			next;
-		} elsif ($change =~ m/^R/ ) {
-			my $oldfilename = $filename;
-			$filename = <$patch>;
-			chomp $filename;
-			if ( $file eq $filename ) {
-				my $parent = git_find_parent($rev, $oldfilename);
-				@bound{'rev','filename'} = ($parent, $oldfilename);
-				last;
-			}
-		}
-	}
-	close($patch);
-
-	return \%bound;
-}
-
-
-sub git_find_parent {
-	my ($rev, $filename) = @_;
-
-	my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev","--",$filename)
-		or die "Failed to open git-rev-list to find a single parent: $!";
-
-	my $parentline = <$revparent>;
-	chomp $parentline;
-	my ($revfound,$parent) = split m/\s+/, $parentline;
-
-	close($revparent);
-
-	return $parent;
-}
-
-sub git_find_all_parents {
-	my ($rev) = @_;
-
-	my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev")
-		or die "Failed to open git-rev-list to find a single parent: $!";
-
-	my $parentline = <$revparent>;
-	chomp $parentline;
-	my ($origrev, @parents) = split m/\s+/, $parentline;
-
-	close($revparent);
-
-	return @parents;
-}
-
-sub git_merge_base {
-	my ($rev1, $rev2) = @_;
-
-	my $mb = open_pipe("git-merge-base", $rev1, $rev2)
-	        or die "Failed to open git-merge-base: $!";
-
-	my $base = <$mb>;
-	chomp $base;
-
-	close($mb);
-
-	return $base;
-}
-
-# Construct a set of pseudo parents that are in the same order,
-# and the same quantity as the real parents,
-# but whose SHA1s are as similar to the logical parents
-# as possible.
-sub get_pseudo_parents {
-	my ($all, $fake) = @_;
-
-	my @all = @$all;
-	my @fake = @$fake;
-
-	my @pseudo;
-
-	my %fake = map {$_ => 1} @fake;
-	my %seenfake;
-
-	my $fakeidx = 0;
-	foreach my $p (@all) {
-		if (exists $fake{$p}) {
-			if ($fake[$fakeidx] ne $p) {
-				die sprintf("parent mismatch: %s != %s\nall:%s\nfake:%s\n",
-					    $fake[$fakeidx], $p,
-					    join(", ", @all),
-					    join(", ", @fake),
-					   );
-			}
-
-			push @pseudo, $p;
-			$fakeidx++;
-			$seenfake{$p}++;
-
-		} else {
-			my $base = git_merge_base($fake[$fakeidx], $p);
-			if ($base ne $fake[$fakeidx]) {
-				die sprintf("Result of merge-base doesn't match fake: %s,%s != %s\n",
-				       $fake[$fakeidx], $p, $base);
-			}
-
-			# The details of how we parse the diffs
-			# mean that we cannot have a duplicate
-			# revision in the list, so if we've already
-			# seen the revision we would normally add, just use
-			# the actual revision.
-			if ($seenfake{$base}) {
-				push @pseudo, $p;
-			} else {
-				push @pseudo, $base;
-				$seenfake{$base}++;
-			}
-		}
-	}
-
-	return @pseudo;
-}
-
-
-# Get a diff between the current revision and a parent.
-# Record the commit information that results.
-sub git_diff_parse {
-	my ($parents, $rev, %revinfo) = @_;
-
-	my @pseudo_parents;
-	my @command = ("git-diff-tree");
-	my $revision_spec;
-
-	if (scalar @$parents == 1) {
-
-		$revision_spec = join("..", $parents->[0], $rev);
-		@pseudo_parents = @$parents;
-	} else {
-		my @all_parents = git_find_all_parents($rev);
-
-		if (@all_parents !=  @$parents) {
-			@pseudo_parents = get_pseudo_parents(\@all_parents, $parents);
-		} else {
-			@pseudo_parents = @$parents;
-		}
-
-		$revision_spec = $rev;
-		push @command, "-c";
-	}
-
-	my @filenames = ( $revs{$rev}{'filename'} );
-
-	foreach my $parent (@$parents) {
-		push @filenames, $revs{$parent}{'filename'};
-	}
-
-	push @command, "-p", "-M", $revision_spec, "--", @filenames;
-
-
-	my $diff = open_pipe( @command )
-		or die "Failed to call git-diff for annotation: $!";
-
-	_git_diff_parse($diff, \@pseudo_parents, $rev, %revinfo);
-
-	close($diff);
-}
-
-sub _git_diff_parse {
-	my ($diff, $parents, $rev, %revinfo) = @_;
-
-	my $ri = 0;
-
-	my $slines = $revs{$rev}{'lines'};
-	my (%plines, %pi);
-
-	my $gotheader = 0;
-	my ($remstart);
-	my $parent_count = @$parents;
-
-	my $diff_header_regexp = "^@";
-	$diff_header_regexp .= "@" x @$parents;
-	$diff_header_regexp .= ' -\d+,\d+' x @$parents;
-	$diff_header_regexp .= ' \+(\d+),\d+';
-	$diff_header_regexp .= " " . ("@" x @$parents);
-
-	my %claim_regexps;
-	my $allparentplus = '^' . '\\+' x @$parents . '(.*)$';
-
-	{
-		my $i = 0;
-		foreach my $parent (@$parents) {
-
-			$pi{$parent} = 0;
-			my $r = '^' . '.' x @$parents . '(.*)$';
-			my $p = $r;
-			substr($p,$i+1, 1) = '\\+';
-
-			my $m = $r;
-			substr($m,$i+1, 1) = '-';
-
-			$claim_regexps{$parent}{plus} = $p;
-			$claim_regexps{$parent}{minus} = $m;
-
-			$plines{$parent} = [];
-
-			$i++;
-		}
-	}
-
-	DIFF:
-	while(<$diff>) {
-		chomp;
-		#printf("%d:%s:\n", $gotheader, $_);
-		if (m/$diff_header_regexp/) {
-			$remstart = $1 - 1;
-			# (0-based arrays)
-
-			$gotheader = 1;
-
-			foreach my $parent (@$parents) {
-				for (my $i = $ri; $i < $remstart; $i++) {
-					$plines{$parent}[$pi{$parent}++] = $slines->[$i];
-				}
-			}
-			$ri = $remstart;
-
-			next DIFF;
-
-		} elsif (!$gotheader) {
-			# Skip over the leadin.
-			next DIFF;
-		}
-
-		if (m/^\\/) {
-			;
-			# Skip \No newline at end of file.
-			# But this can be internationalized, so only look
-			# for an initial \
-
-		} else {
-			my %claims = ();
-			my $negclaim = 0;
-			my $allclaimed = 0;
-			my $line;
-
-			if (m/$allparentplus/) {
-				claim_line($ri, $rev, $slines, %revinfo);
-				$allclaimed = 1;
-
-			}
-
-			PARENT:
-			foreach my $parent (keys %claim_regexps) {
-				my $m = $claim_regexps{$parent}{minus};
-				my $p = $claim_regexps{$parent}{plus};
-
-				if (m/$m/) {
-					$line = $1;
-					$plines{$parent}[$pi{$parent}++] = [ $line, '', '', '', 0 ];
-					$negclaim++;
-
-				} elsif (m/$p/) {
-					$line = $1;
-					if (get_line($slines, $ri) eq $line) {
-						# Found a match, claim
-						$claims{$parent}++;
-
-					} else {
-						die sprintf("Sync error: %d\n|%s\n|%s\n%s => %s\n",
-								$ri, $line,
-								get_line($slines, $ri),
-								$rev, $parent);
-					}
-				}
-			}
-
-			if (%claims) {
-				foreach my $parent (@$parents) {
-					next if $claims{$parent} || $allclaimed;
-					$plines{$parent}[$pi{$parent}++] = $slines->[$ri];
-					    #[ $line, '', '', '', 0 ];
-				}
-				$ri++;
-
-			} elsif ($negclaim) {
-				next DIFF;
-
-			} else {
-				if (substr($_,scalar @$parents) ne get_line($slines,$ri) ) {
-				        foreach my $parent (@$parents) {
-						printf("parent %s is on line %d\n", $parent, $pi{$parent});
-					}
-
-					my @context;
-					for (my $i = -2; $i < 2; $i++) {
-						push @context, get_line($slines, $ri + $i);
-					}
-					my $context = join("\n", @context);
-
-					my $justline = substr($_, scalar @$parents);
-					die sprintf("Line %d, does not match:\n|%s|\n|%s|\n%s\n",
-						    $ri,
-						    $justline,
-						    $context);
-				}
-				foreach my $parent (@$parents) {
-					$plines{$parent}[$pi{$parent}++] = $slines->[$ri];
-				}
-				$ri++;
-			}
-		}
-	}
-
-	for (my $i = $ri; $i < @{$slines} ; $i++) {
-		foreach my $parent (@$parents) {
-			push @{$plines{$parent}}, $slines->[$ri];
-		}
-		$ri++;
-	}
-
-	foreach my $parent (@$parents) {
-		$revs{$parent}{lines} = $plines{$parent};
-	}
-
-	return;
-}
-
-sub get_line {
-	my ($lines, $index) = @_;
-
-	return ref $lines->[$index] ne '' ? $lines->[$index][0] : $lines->[$index];
-}
-
-sub git_cat_file {
-	my ($rev, $filename) = @_;
-	return () unless defined $rev && defined $filename;
-
-	my $blob = git_ls_tree($rev, $filename);
-	die "Failed to find a blob for $filename in rev $rev\n" if !defined $blob;
-
-	my $catfile = open_pipe("git","cat-file", "blob", $blob)
-		or die "Failed to git-cat-file blob $blob (rev $rev, file $filename): " . $!;
-
-	my @lines;
-	while(<$catfile>) {
-		chomp;
-		push @lines, $_;
-	}
-	close($catfile);
-
-	return @lines;
-}
-
-sub git_ls_tree {
-	my ($rev, $filename) = @_;
-
-	my $lstree = open_pipe("git","ls-tree",$rev,$filename)
-		or die "Failed to call git ls-tree: $!";
-
-	my ($mode, $type, $blob, $tfilename);
-	while(<$lstree>) {
-		chomp;
-		($mode, $type, $blob, $tfilename) = split(/\s+/, $_, 4);
-		last if ($tfilename eq $filename);
-	}
-	close($lstree);
-
-	return $blob if ($tfilename eq $filename);
-	die "git-ls-tree failed to find blob for $filename";
-
-}
-
-
-
-sub claim_line {
-	my ($floffset, $rev, $lines, %revinfo) = @_;
-	my $oline = get_line($lines, $floffset);
-	@{$lines->[$floffset]} = ( $oline, $rev,
-		$revinfo{'author'}, $revinfo{'author_date'} );
-	#printf("Claiming line %d with rev %s: '%s'\n",
-	#		$floffset, $rev, $oline) if 1;
-}
-
-sub git_commit_info {
-	my ($rev) = @_;
-	my $commit = open_pipe("git-cat-file", "commit", $rev)
-		or die "Failed to call git-cat-file: $!";
-
-	my %info;
-	while(<$commit>) {
-		chomp;
-		last if (length $_ == 0);
-
-		if (m/^author (.*) <(.*)> (.*)$/) {
-			$info{'author'} = $1;
-			$info{'author_email'} = $2;
-			$info{'author_date'} = $3;
-		} elsif (m/^committer (.*) <(.*)> (.*)$/) {
-			$info{'committer'} = $1;
-			$info{'committer_email'} = $2;
-			$info{'committer_date'} = $3;
-		}
-	}
-	close($commit);
-
-	return %info;
-}
-
-sub format_date {
-	if ($rawtime) {
-		return $_[0];
-	}
-	my ($timestamp, $timezone) = split(' ', $_[0]);
-	my $minutes = abs($timezone);
-	$minutes = int($minutes / 100) * 60 + ($minutes % 100);
-	if ($timezone < 0) {
-	    $minutes = -$minutes;
-	}
-	my $t = $timestamp + $minutes * 60;
-	return strftime("%Y-%m-%d %H:%M:%S " . $timezone, gmtime($t));
-}
-
-# Copied from git-send-email.perl - We need a Git.pm module..
-sub gitvar {
-    my ($var) = @_;
-    my $fh;
-    my $pid = open($fh, '-|');
-    die "$!" unless defined $pid;
-    if (!$pid) {
-	exec('git-var', $var) or die "$!";
-    }
-    my ($val) = <$fh>;
-    close $fh or die "$!";
-    chomp($val);
-    return $val;
-}
-
-sub gitvar_name {
-    my ($name) = @_;
-    my $val = gitvar($name);
-    my @field = split(/\s+/, $val);
-    return join(' ', @field[0...(@field-4)]);
-}
-
-sub open_pipe {
-	if ($^O eq '##INSERT_ACTIVESTATE_STRING_HERE##') {
-		return open_pipe_activestate(@_);
-	} else {
-		return open_pipe_normal(@_);
-	}
-}
-
-sub open_pipe_activestate {
-	tie *fh, "Git::ActiveStatePipe", @_;
-	return *fh;
-}
-
-sub open_pipe_normal {
-	my (@execlist) = @_;
-
-	my $pid = open my $kid, "-|";
-	defined $pid or die "Cannot fork: $!";
-
-	unless ($pid) {
-		exec @execlist;
-		die "Cannot exec @execlist: $!";
-	}
-
-	return $kid;
-}
-
-package Git::ActiveStatePipe;
-use strict;
-
-sub TIEHANDLE {
-	my ($class, @params) = @_;
-	my $cmdline = join " ", @params;
-	my  @data = qx{$cmdline};
-	bless { i => 0, data => \@data }, $class;
-}
-
-sub READLINE {
-	my $self = shift;
-	if ($self->{i} >= scalar @{$self->{data}}) {
-		return undef;
-	}
-	return $self->{'data'}->[ $self->{i}++ ];
-}
-
-sub CLOSE {
-	my $self = shift;
-	delete $self->{data};
-	delete $self->{i};
-}
-
-sub EOF {
-	my $self = shift;
-	return ($self->{i} >= scalar @{$self->{data}});
-}
diff --git a/git.c b/git.c
index d7103a4..b32ee0f 100644
--- a/git.c
+++ b/git.c
@@ -219,6 +219,7 @@ static void handle_internal_command(int 
 		int option;
 	} commands[] = {
 		{ "add", cmd_add, RUN_SETUP },
+		{ "annotate", cmd_annotate, },
 		{ "apply", cmd_apply },
 		{ "archive", cmd_archive },
 		{ "cat-file", cmd_cat_file, RUN_SETUP },
-- 
1.4.2.3.gbf37d

^ permalink raw reply related

* Re: [PATCH] gitweb: Cleanup Git logo and Git logo target generation
From: Jakub Narebski @ 2006-10-09  9:26 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vvemtdfst.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
> 
> > Partial improvement is better than no improvement.
> 
> Not necessarily.  As the maintainer, I found that when we say
> "we will fix it later", later tend to never come, and one
> effective way to fight that tendency is to prod the contributors
> a bit harder, which worked reasonably well so far.

Well. Perhaps.

But first, it is also bugfix for esc_html on URL, and second I though 
you rather have one feature per patch; this one has two - cleanup of 
logo generation, and moving style to CSS. "Better" patch would have 
three...

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH] gitweb: Cleanup Git logo and Git logo target generation
From: Junio C Hamano @ 2006-10-09  9:00 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200610090914.59834.jnareb@gmail.com>

Jakub Narebski <jnareb@gmail.com> writes:

> Partial improvement is better than no improvement.

Not necessarily.  As the maintainer, I found that when we say
"we will fix it later", later tend to never come, and one
effective way to fight that tendency is to prod the contributors
a bit harder, which worked reasonably well so far.

^ permalink raw reply

* Re: [PATCH] gitweb: Cleanup Git logo and Git logo target generation
From: Jakub Narebski @ 2006-10-09  7:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vac46gvg8.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> Junio C Hamano wrote:
>>
>>> Petr Baudis <pasky@suse.cz> writes:
>>> 
>>>> Is there a problem with taking <200610061231.06017.jnareb@gmail.com>?
>>>>
>>>> I think it's currently not worth the complexity and breakage of
>>>> backwards compatibility to do the more elaborate form you proposed.
>>> 
>>> I agree with that, except that the 72x27 dimension bit troubles
>>> me.
>>
>> First, that's the problem for the future. The 72x27 was there, I have not
>> introduced this. 
> 
> That's exactly my point.  This is not a "placing blame" game.
> 
> It just feels wrong to update only two things when we already
> know there are others that need fixing in a very similar way.
 
Well, I'd rather have it corrected, than wait for generalized version
which would allow to set dimensions and stuff... which is most probably
not needed.

Partial improvement is better than no improvement (especially as it
corrects 'href="'.esc_html($githelp_url).'"' bug).
-- 
Jakub Narebski
Poland

^ permalink raw reply

* [RFC/PATCH] merge: loosen overcautious "working file will be lost" check.
From: Junio C Hamano @ 2006-10-09  5:48 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <7vodsmdq0m.fsf@assigned-by-dhcp.cox.net>

The three-way merge complained unconditionally when a path that
does not exist in the index is involved in a merge when it
existed in the working tree.  If we are merging an old version
that had that path tracked, but the path is not tracked anymore,
and if we are merging that old version in, the result will be
that the path is not tracked.  In that case we should not
complain.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

 * Consolidated patch to summarize a few crapoids I sent out
   tonight.

   The change to merge-one-file still does not do .gitignore
   check but that is easy to add once we know this is the right
   direction to go, which I am not sure yet.  If we can convince
   ourselves that this is the right direction we should update
   merge-recursive as well.

 git-merge-one-file.sh       |   16 ++++++++++++-
 t/t1004-read-tree-m-u-wf.sh |   53 +++++++++++++++++++++++++++++++++++++++++++
 unpack-trees.c              |    2 -
 3 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index fba4b0c..74ad4f2 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -23,6 +23,12 @@ #
 "$1.." | "$1.$1" | "$1$1.")
 	if [ "$2" ]; then
 		echo "Removing $4"
+	else
+		# read-tree checked that index matches HEAD already,
+		# so we know we do not have this path tracked.
+		# there may be an unrelated working tree file here,
+		# which we should just leave unmolested.
+		exit 0
 	fi
 	if test -f "$4"; then
 		rm -f -- "$4" &&
@@ -34,8 +40,16 @@ #
 #
 # Added in one.
 #
-".$2." | "..$3" )
+".$2.")
+	# the other side did not add and we added so there is nothing
+	# to be done.
+	;;
+"..$3")
 	echo "Adding $4"
+	test -f "$4" || {
+		echo "ERROR: untracked $4 is overwritten by the merge."
+		exit 1
+	}
 	git-update-index --add --cacheinfo "$6$7" "$2$3" "$4" &&
 		exec git-checkout-index -u -f -- "$4"
 	;;
diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh
new file mode 100755
index 0000000..018fbea
--- /dev/null
+++ b/t/t1004-read-tree-m-u-wf.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+test_description='read-tree -m -u checks working tree files'
+
+. ./test-lib.sh
+
+# two-tree test
+
+test_expect_success 'two-way setup' '
+
+	echo >file1 file one &&
+	echo >file2 file two &&
+	git update-index --add file1 file2 &&
+	git commit -m initial &&
+
+	git branch side &&
+	git tag -f branch-point &&
+
+	echo file2 is not tracked on the master anymore &&
+	rm -f file2 &&
+	git update-index --remove file2 &&
+	git commit -a -m "master removes file2"
+'
+
+test_expect_success 'two-way not clobbering' '
+
+	echo >file2 master creates untracked file2 &&
+	if err=`git read-tree -m -u master side 2>&1`
+	then
+		echo should have complained
+		false
+	else
+		echo "happy to see $err"
+	fi
+'
+
+# three-tree test
+
+test_expect_success 'three-way not complaining' '
+
+	rm -f file2 &&
+	git checkout side &&
+	echo >file3 file three &&
+	git update-index --add file3 &&
+	git commit -a -m "side adds file3" &&
+
+	git checkout master &&
+	echo >file2 file two is untracked on the master side &&
+
+	git-read-tree -m -u branch-point master side
+'
+
+test_done
diff --git a/unpack-trees.c b/unpack-trees.c
index 3ac0289..b1d78b8 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **
 	if (index) {
 		verify_uptodate(index, o);
 	}
-	else if (path)
-		verify_absent(path, "overwritten", o);
 
 	o->nontrivial_merge = 1;
 
-- 
1.4.2.3.g2c59

^ permalink raw reply related

* Re: "fatal: Untracked working tree file 'so-and-so' would be overwritten by merge"
From: Junio C Hamano @ 2006-10-09  5:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <7v7izaf62c.fsf@assigned-by-dhcp.cox.net>

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

> But that is a bit tricky.  This is not on the aggressive path,
> and the merge result is decided by the policy implemented by the
> caller of read-tree.  So in that sense we should not be doing
> the working tree check ourselves either.  We just should leave
> that to the caller.
>
> Hence, I think removing the above "else if" part altogether is
> the right thing to do here.
>
> ---
> diff --git a/unpack-trees.c b/unpack-trees.c
> index 3ac0289..b1d78b8 100644
> --- a/unpack-trees.c
> +++ b/unpack-trees.c
> @@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **
>  	if (index) {
>  		verify_uptodate(index, o);
>  	}
> -	else if (path)
> -		verify_absent(path, "overwritten", o);
>  
>  	o->nontrivial_merge = 1;
>  

Note note note.  The above patch alone leaves merge risky to
remove an untracked working tree files, and needs to be
compensated by corresponding checks to the git-merge-xxx
strategies.  The original code was overcautious, but was
protecting valid cases too.

For example, you and I recently independently did something
called show-refs (mine was actually called show-ref but I could
have picked a name that happened to conflict with yours), and it
was when I had an uncommitted, not even in index, work-in-progress
when I saw your version.  If I pulled from you, the version of
read-tree without above check would have happily said it is OK
to do a three-way merge, and git-merge-one-file would have said
you added one while I haven't, and would have tried to overwrite
the file in my working tree.

But this still feels wrong, at two levels.

For one thing, the beauty of git merge was that if there is a
risk of local changes being lost, it was detected at read-tree
stage and we did not even touch index in that case.  Not
detecting problems at read-tree time and leaving it to
merge-one-file feels wrong.  Very wrong.

I suspect the other issue I have is easier to address -- if we
were to implement the check at merge-one-file level, it would be
something like the attached patch, but at the same time it
should take .gitignore file into account.

---

diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index fba4b0c..25aedb7 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -23,6 +23,9 @@ #
 "$1.." | "$1.$1" | "$1$1.")
 	if [ "$2" ]; then
 		echo "Removing $4"
+	elif test -f "$4"
+		echo "ERROR: untracked $4 is removed by the merge."
+		exit 1
 	fi
 	if test -f "$4"; then
 		rm -f -- "$4" &&
@@ -34,8 +37,16 @@ #
 #
 # Added in one.
 #
-".$2." | "..$3" )
+".$2.")
+	# the other side did not add and we added so there is nothing
+	# to be done.
+	;;
+"..$3")
 	echo "Adding $4"
+	test -f "$4" || {
+		echo "ERROR: untracked $4 is overwritten by the merge."
+		exit 1
+	}
 	git-update-index --add --cacheinfo "$6$7" "$2$3" "$4" &&
 		exec git-checkout-index -u -f -- "$4"
 	;;

^ permalink raw reply related

* Re: "fatal: Untracked working tree file 'so-and-so' would be overwritten by merge"
From: Junio C Hamano @ 2006-10-09  4:48 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0610081657400.3952@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Hmm. I'm getting this message annoyingly often, simply because a few files 
> that used to be tracked are now generated, and so they exist in my tree 
> but are no longer tracked.
>
> However, they may be tracked in an older tree that I pull, because in that 
> older tree they _do_ exist, and we get the
>
> 	fatal: Untracked working tree file 'so-and-so' would be overwritten by merge.
>
> which is actually incorrect, because the merge result will not even 
> _contain_ that untracked file any more.

> So the message is misleading - we should only consider this a fatal thing 
> if we actually do generate that file as part of a git-read-tree, but if a 
> merge won't touch a file, it shouldn't be "overwritten".
>
> It's true that if the _other_ end actually removed a file that we used to 
> have (ie the file _disappears_ as part of the merge), then we should 
> verify that that file matched what we're going to remove, but if the old 
> index didn't contain the file at all, and the new index won't contain it 
> either, it really should be a no-op.

True.

I think it is verify_absent() on l.665 in threeway_merge().

	if (index) {
		verify_uptodate(index, o);
	}
	else if (path)
		verify_absent(path, "overwritten", o);

	o->nontrivial_merge = 1;

We say "we know this path is involved in the non-trivial merge;
if the current index has it, it had better be up-to-date" (the
first "if").  I think that up to that check is fine.

However, we say that otherwise, the path should not exist in the
working tree; this should not be done unconditionally.  As you
say, the check should depend on the merge result.

But that is a bit tricky.  This is not on the aggressive path,
and the merge result is decided by the policy implemented by the
caller of read-tree.  So in that sense we should not be doing
the working tree check ourselves either.  We just should leave
that to the caller.

Hence, I think removing the above "else if" part altogether is
the right thing to do here.

---
diff --git a/unpack-trees.c b/unpack-trees.c
index 3ac0289..b1d78b8 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **
 	if (index) {
 		verify_uptodate(index, o);
 	}
-	else if (path)
-		verify_absent(path, "overwritten", o);
 
 	o->nontrivial_merge = 1;
 

^ permalink raw reply related

* Re: Does GIT has vc keywords like CVS/Subversion?
From: Petr Baudis @ 2006-10-09  2:59 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Dongsheng Song, git
In-Reply-To: <4529B77A.707@gmail.com>

Dear diary, on Mon, Oct 09, 2006 at 04:44:10AM CEST, I got a letter
where Liu Yubao <yubao.liu@gmail.com> said that...
> Dongsheng Song wrote:
> >I want to know whether there is a plan to add this feature, or GIT
> >doesn't require it at all.
> >
> >Keywords like LastChangedDate, LastChangedRevision, LastChangedBy, Id
> >are useful for version control.
> >
> I almost mistake I sent my last question twice:-), maybe we need more FAQs
> like this:
> Q: Does GIT [some feature] like [some vcs] ?
> A: No. Because ...

I have added direct link to FAQ in the Git wiki to the Git homepage
header - http://git.or.cz/gitwiki/GitFaq. It's a wiki, so feel free to
add more q/a there.

> IMHO, I don't think keyword substitution is a good idea, as it will confuse
> the external diff/merge tools.

There can be valid usage scenarios for keyword substitution but I tend
to agree that it usually is not necessary to have it (and projects tend
to use it just "because we can", which is of course their right). Also,
implementing it in Git poses some challenges and has some ugly
implications (like actually having to start to worry about binary
files).

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

^ permalink raw reply

* Re: Does GIT require property like Subversion?
From: Liu Yubao @ 2006-10-09  2:53 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200610081752.10940.robin.rosenberg.lists@dewire.com>

Sorry, I forgot to reply all.

Robin Rosenberg wrote:
> söndag 08 oktober 2006 12:16 skrev Jakub Narebski:
>> File content encoding is something (if it is outside US-ASCII of course)
>> that you would want either to have some default convention, or have it
>> embedded in the file itself (like XML, HTML, or Emacs' file variables)
>> to be able to read file _outside_ SCM.
> Except for CR/LF, this is best solved outside of the SCM. There aren't that
> may tools/users to warrant the complexity or performance hit I imagine to 
> solve it.
> 
>> Path name encoding is something that is global property of a repository,
>> I think. We have i18n.commitEncoding configuration variable; we could
>> add i18n.pathnameEncoding quite easily I think (and some way for Git to
>> detect current filesystem pathname encoding, if possible). Although
>> BTW I think that i18n.commitEncoding information should be made persistent,
>> and copied when cloning repository.
> 
> *I* think git should use UTF-8 internally. Always. Clients could then have
> the option to convert to local conventions.
> 
> Same for pathname. Internally all paths should be UTF-8 encoded. Encoding 
> commit info that way would make the i18n option obsolete also.
> 
I am afraid it's not a good idea to convert file content to UTF-8 encoding
as GIT can manage non-text file, it's not safe to modify file content 
stealthily by a VCS.

But I agree to use UTF-8 for path name in tree object, or add an encoding
property(not a user defined property) to the head of tree object, so GIT
won't do useless enc -> UTF-8 -> same_enc conversion. The second way has
a fault: two tree objects with same content in different encoding have 
different SHA1 digests.

> I have a patch for both these, but it's very ugly and probably has some memory 
> management problems, so I'll refrain from submitting for now. Knowing that it 
> exists may perhaps serve as starting point for discussion. It encodes 
> filenames in UTF-8 using LC_CTYPE as the local encoding, as well as commit 
> messages. An exception is when something looks like UTF-8, in which case it 
> will not convert input to git. When UTF-8 cannot be converted to the local 
> encoding on it's way out of git, the data remains in UTF-8 format. Branch and 
> tags names are not managed (yet, at least).
> 
 >
Good, hope GIT can deal with path names that are not in 8859_1 or UTF-8 encoding.

^ permalink raw reply

* Re: Does GIT has vc keywords like CVS/Subversion?
From: Liu Yubao @ 2006-10-09  2:44 UTC (permalink / raw)
  To: Dongsheng Song; +Cc: git
In-Reply-To: <4b3406f0610081825y1d066579yba305b6540c8d0e9@mail.gmail.com>

Dongsheng Song wrote:
> I want to know whether there is a plan to add this feature, or GIT
> doesn't require it at all.
> 
> Keywords like LastChangedDate, LastChangedRevision, LastChangedBy, Id
> are useful for version control.
> 
I almost mistake I sent my last question twice:-), maybe we need more FAQs
like this:
Q: Does GIT [some feature] like [some vcs] ?
A: No. Because ...

IMHO, I don't think keyword substitution is a good idea, as it will confuse
the external diff/merge tools.

^ permalink raw reply

* Does GIT has vc keywords like CVS/Subversion?
From: Dongsheng Song @ 2006-10-09  1:25 UTC (permalink / raw)
  To: git

I want to know whether there is a plan to add this feature, or GIT
doesn't require it at all.

Keywords like LastChangedDate, LastChangedRevision, LastChangedBy, Id
are useful for version control.

Dongsheng

^ permalink raw reply

* Re: [PATCH] gitweb: Cleanup Git logo and Git logo target generation
From: Junio C Hamano @ 2006-10-09  0:54 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <egbogh$d7d$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> writes:

> Junio C Hamano wrote:
>
>> Petr Baudis <pasky@suse.cz> writes:
>> 
>>> Is there a problem with taking <200610061231.06017.jnareb@gmail.com>?
>>>
>>> I think it's currently not worth the complexity and breakage of
>>> backwards compatibility to do the more elaborate form you proposed.
>> 
>> I agree with that, except that the 72x27 dimension bit troubles
>> me.
>
> First, that's the problem for the future. The 72x27 was there, I have not
> introduced this. 

That's exactly my point.  This is not a "placing blame" game.

It just feels wrong to update only two things when we already
know there are others that need fixing in a very similar way.

^ permalink raw reply

* Re: git bisect idea: Asymmetric split points
From: Linus Torvalds @ 2006-10-09  0:19 UTC (permalink / raw)
  To: Peter Osterlund; +Cc: Git Mailing List
In-Reply-To: <m38xjqfk6r.fsf@telia.com>



On Sun, 9 Oct 2006, Peter Osterlund wrote:
> 
> Does this sound like a good idea? Would it be hard to implement?

It should be very easy to implement.

See builtin-rev-list.c: find_bisection(), which has a _very_ simple way of 
trying to find the best commit. It just counts the distance from the 
commit:

	distance = count_distance(p);
	clear_distance(list);

where "distance" is really "how many commits will this cover".

If you wanted to get as close to (say) 75% of the total list of commits as 
possible, you should just do something like

	optimal = nr * percent / 100;
	how_close = abs(optimal - distance);
	if (how_close < closest) {
		best = p;
		closest = how_close;
	}

instead of what we do now (which is just to say that "since we want to get 
half-way, we want to make the biggest distance from _both_ 0 and from 
"nr", which is what it calculates with

 - If we're closer to "nr" than to 0 (ie the difference between nr and 
   distance is smaller than the difference between distance and 0), pick 
   the smaller difference:

	if (nr - distance < distance) 
		distance = nr - distance;

 - if this new distance is larger than any distance we've seen so far, 
   this is the best commit so far:

	if (distance > closest) {
		best = p;
		closest = distance;
	}

and notice how this is really just a special case of the percentage thing 
when percent is 50%.

			Linus

^ permalink raw reply

* "fatal: Untracked working tree file 'so-and-so' would be overwritten by merge"
From: Linus Torvalds @ 2006-10-09  0:11 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


Hmm. I'm getting this message annoyingly often, simply because a few files 
that used to be tracked are now generated, and so they exist in my tree 
but are no longer tracked.

However, they may be tracked in an older tree that I pull, because in that 
older tree they _do_ exist, and we get the

	fatal: Untracked working tree file 'so-and-so' would be overwritten by merge.

which is actually incorrect, because the merge result will not even 
_contain_ that untracked file any more.

So the message is misleading - we should only consider this a fatal thing 
if we actually do generate that file as part of a git-read-tree, but if a 
merge won't touch a file, it shouldn't be "overwritten".

It's true that if the _other_ end actually removed a file that we used to 
have (ie the file _disappears_ as part of the merge), then we should 
verify that that file matched what we're going to remove, but if the old 
index didn't contain the file at all, and the new index won't contain it 
either, it really should be a no-op.

IOW, I think there is one "verify_absent()" too many somewhere, where we 
check this unnecessarily. I think it's the one in "deleted_entry()" in 
unpack-trees.c, but I'm not sure.

		Linus

^ permalink raw reply

* git bisect idea: Asymmetric split points
From: Peter Osterlund @ 2006-10-08 23:43 UTC (permalink / raw)
  To: Git Mailing List

I was using git bisect today when trying to track down a random kernel
hang during boot. Since the hang is random, ie it only hangs during
some boots, identifying a bad version is easier than identifying a
good version. If it hangs during one boot, the kernel is clearly bad,
but if it doesn't hang I can't be sure if it's good or bad. I have to
test several times to be reasonably sure that a kernel is good.

In this scenario identifying a bad kernel is easier than identifying a
good kernel. This means that if I want to find the guilty commit as
fast as possible the best strategy is not to split the remaining
commit list in half. In this case it would be better to split closer
to a known bad commit.

You can also imagine cases where identifying a bad version is more
costly than identifying a good one. One example would be if a bad
kernel has nasty side effects, such as file system corruption, that
you have to fix up before you can continue bisecting.

To handle these cases more efficiently, I think it would be nice to be
able to tell git bisect where the bisection point is wanted, for
example by specifying a percentage.

Does this sound like a good idea? Would it be hard to implement?

-- 
Peter Osterlund - petero2@telia.com
http://web.telia.com/~u89404340

^ permalink raw reply

* [PATCH] git-svnimport.perl: copying directory from original SVN place
From: Sasha Khapyorsky @ 2006-10-08 21:31 UTC (permalink / raw)
  To: Junio C Hamano, Matthias Urlichs; +Cc: git


When copying whole directory, if source directory is not in already
imported tree, try to get it from original SVN location. This happens
when source directory is not matched by provided 'trunk' and/or
'tags/branches' templates or when it is not part of specified SVN
sub-project.

Signed-off-by: Sasha Khapyorsky <sashak@voltaire.com>
---
 git-svnimport.perl |   93 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 54 insertions(+), 39 deletions(-)

diff --git a/git-svnimport.perl b/git-svnimport.perl
index 988514e..4ae0eec 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -193,6 +193,13 @@ sub ignore {
 	}
 }
 
+sub dir_list {
+	my($self,$path,$rev) = @_;
+	my ($dirents,undef,$properties)
+	    = $self->{'svn'}->get_dir($path,$rev,undef);
+	return $dirents;
+}
+
 package main;
 use URI;
 
@@ -342,35 +349,16 @@ if ($opt_A) {
 
 open BRANCHES,">>", "$git_dir/svn2git";
 
-sub node_kind($$$) {
-	my ($branch, $path, $revision) = @_;
+sub node_kind($$) {
+	my ($svnpath, $revision) = @_;
 	my $pool=SVN::Pool->new;
-	my $kind = $svn->{'svn'}->check_path(revert_split_path($branch,$path),$revision,$pool);
+	my $kind = $svn->{'svn'}->check_path($svnpath,$revision,$pool);
 	$pool->clear;
 	return $kind;
 }
 
-sub revert_split_path($$) {
-	my($branch,$path) = @_;
-
-	my $svnpath;
-	$path = "" if $path eq "/"; # this should not happen, but ...
-	if($branch eq "/") {
-		$svnpath = "$trunk_name/$path";
-	} elsif($branch =~ m#^/#) {
-		$svnpath = "$tag_name$branch/$path";
-	} else {
-		$svnpath = "$branch_name/$branch/$path";
-	}
-
-	$svnpath =~ s#/+$##;
-	return $svnpath;
-}
-
 sub get_file($$$) {
-	my($rev,$branch,$path) = @_;
-
-	my $svnpath = revert_split_path($branch,$path);
+	my($svnpath,$rev,$path) = @_;
 
 	# now get it
 	my ($name,$mode);
@@ -413,10 +401,9 @@ sub get_file($$$) {
 }
 
 sub get_ignore($$$$$) {
-	my($new,$old,$rev,$branch,$path) = @_;
+	my($new,$old,$rev,$path,$svnpath) = @_;
 
 	return unless $opt_I;
-	my $svnpath = revert_split_path($branch,$path);
 	my $name = $svn->ignore("$svnpath",$rev);
 	if ($path eq '/') {
 		$path = $opt_I;
@@ -435,7 +422,7 @@ sub get_ignore($$$$$) {
 		close $F;
 		unlink $name;
 		push(@$new,['0644',$sha,$path]);
-	} else {
+	} elsif (defined $old) {
 		push(@$old,$path);
 	}
 }
@@ -480,6 +467,27 @@ sub branch_rev($$) {
 	return $therev;
 }
 
+sub expand_svndir($$$);
+
+sub expand_svndir($$$)
+{
+	my ($svnpath, $rev, $path) = @_;
+	my @list;
+	get_ignore(\@list, undef, $rev, $path, $svnpath);
+	my $dirents = $svn->dir_list($svnpath, $rev);
+	foreach my $p(keys %$dirents) {
+		my $kind = node_kind($svnpath.'/'.$p, $rev);
+		if ($kind eq $SVN::Node::file) {
+			my $f = get_file($svnpath.'/'.$p, $rev, $path.'/'.$p);
+			push(@list, $f) if $f;
+		} elsif ($kind eq $SVN::Node::dir) {
+			push(@list,
+			     expand_svndir($svnpath.'/'.$p, $rev, $path.'/'.$p));
+		}
+	}
+	return @list;
+}
+
 sub copy_path($$$$$$$$) {
 	# Somebody copied a whole subdirectory.
 	# We need to find the index entries from the old version which the
@@ -488,8 +496,11 @@ sub copy_path($$$$$$$$) {
 	my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_;
 
 	my($srcbranch,$srcpath) = split_path($rev,$oldpath);
-	unless(defined $srcbranch) {
-		print "Path not found when copying from $oldpath @ $rev\n";
+	unless(defined $srcbranch && defined $srcpath) {
+		print "Path not found when copying from $oldpath @ $rev.\n".
+			"Will try to copy from original SVN location...\n"
+			if $opt_v;
+		push (@$new, expand_svndir($oldpath, $rev, $path));
 		return;
 	}
 	my $therev = branch_rev($srcbranch, $rev);
@@ -503,7 +514,7 @@ sub copy_path($$$$$$$$) {
 	}
 	print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v;
 	if ($node_kind eq $SVN::Node::dir) {
-			$srcpath =~ s#/*$#/#;
+		$srcpath =~ s#/*$#/#;
 	}
 	
 	my $pid = open my $f,'-|';
@@ -582,10 +593,12 @@ sub commit {
 		if(defined $oldpath) {
 			my $p;
 			($parent,$p) = split_path($revision,$oldpath);
-			if($parent eq "/") {
-				$parent = $opt_o;
-			} else {
-				$parent =~ s#^/##; # if it's a tag
+			if(defined $parent) {
+				if($parent eq "/") {
+					$parent = $opt_o;
+				} else {
+					$parent =~ s#^/##; # if it's a tag
+				}
 			}
 		} else {
 			$parent = undef;
@@ -651,9 +664,10 @@ #	}
 				push(@old,$path); # remove any old stuff
 			}
 			if(($action->[0] eq "A") || ($action->[0] eq "R")) {
-				my $node_kind = node_kind($branch,$path,$revision);
+				my $node_kind = node_kind($action->[3], $revision);
 				if ($node_kind eq $SVN::Node::file) {
-					my $f = get_file($revision,$branch,$path);
+					my $f = get_file($action->[3],
+							 $revision, $path);
 					if ($f) {
 						push(@new,$f) if $f;
 					} else {
@@ -668,19 +682,20 @@ #	}
 							  \@new, \@parents);
 					} else {
 						get_ignore(\@new, \@old, $revision,
-							   $branch, $path);
+							   $path, $action->[3]);
 					}
 				}
 			} elsif ($action->[0] eq "D") {
 				push(@old,$path);
 			} elsif ($action->[0] eq "M") {
-				my $node_kind = node_kind($branch,$path,$revision);
+				my $node_kind = node_kind($action->[3], $revision);
 				if ($node_kind eq $SVN::Node::file) {
-					my $f = get_file($revision,$branch,$path);
+					my $f = get_file($action->[3],
+							 $revision, $path);
 					push(@new,$f) if $f;
 				} elsif ($node_kind eq $SVN::Node::dir) {
 					get_ignore(\@new, \@old, $revision,
-						   $branch,$path);
+						   $path, $action->[3]);
 				}
 			} else {
 				die "$revision: unknown action '".$action->[0]."' for $path\n";
-- 
1.4.2.3

^ permalink raw reply related

* Re: [PATCH] gitweb: Cleanup Git logo and Git logo target generation
From: Jakub Narebski @ 2006-10-08 20:54 UTC (permalink / raw)
  To: git
In-Reply-To: <7vbqomim46.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> Petr Baudis <pasky@suse.cz> writes:
> 
>> Is there a problem with taking <200610061231.06017.jnareb@gmail.com>?
>>
>> I think it's currently not worth the complexity and breakage of
>> backwards compatibility to do the more elaborate form you proposed.
> 
> I agree with that, except that the 72x27 dimension bit troubles
> me.

First, that's the problem for the future. The 72x27 was there, I have not
introduced this. 

Second, 72x27 is size override, so although logo would better be 72x27,
but if it is not it will be scaled to given size.
  http://www.w3.org/TR/html401/struct/objects.html#visual
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ 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