Git development
 help / color / mirror / Atom feed
* Re: [PATCH] bash-completion: don't add quoted space for ZSH (fix regression)
From: Junio C Hamano @ 2012-01-15  2:29 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: git
In-Reply-To: <1326567336-2173-1-git-send-email-Matthieu.Moy@imag.fr>

Matthieu Moy <Matthieu.Moy@imag.fr> writes:

> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index b0062ba..488e1f4 100755
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -534,6 +534,12 @@ __gitcomp_nl ()
>  		fi
>  	fi
>  
> +	# ZSH would quote the trailing space added with -S. bash users
> +	# will appreciate the extra space to compensate the use of -o nospace.
> +	if [ -n "${ZSH_VERSION-}" ] && [ "$suffix" = " " ]; then
> +		suffix=""
> +	fi

This should take care of the SP set by the beginning of the helper
function

        local cur_="$cur" suffix=" "

but is that the right thing to do if suffix came from "$4"?

As far as I can see, "$4" is used to append "." in very limited cases, and
nobody explicitly passes SP as "$4" when calling this, so it may be easier
to read if you moved this before that "if we have 3 or more args, use the
fourth one as the suffix" block, i.e. something like this?

 contrib/completion/git-completion.bash |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index b0062ba..4ad75ed 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -525,7 +525,10 @@ __gitcomp ()
 __gitcomp_nl ()
 {
 	local s=$'\n' IFS=' '$'\t'$'\n'
-	local cur_="$cur" suffix=" "
+	local cur_="$cur"
+	# Because we use '-o nospace' under bash, we need to compensate
+	# for it by appending SP after completed word ourselves.
+	local suffix="${BASH_VERSION+ }"
 
 	if [ $# -gt 2 ]; then
 		cur_="$3"

^ permalink raw reply related

* Re: Signed tags in octopus merge..
From: Junio C Hamano @ 2012-01-15  2:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <CA+55aFzRN2F5PZDZPRmbj9occZwA6E6Pi+S+M_Qq2EfS6sctyA@mail.gmail.com>

Linus Torvalds <torvalds@linux-foundation.org> writes:

> Just a heads-up and congrats: octopus merges of signed tags work well,
> and did exactly the RightThing(tm), both at merge time and with
> "--show-signature".

Heh, thanks.

^ permalink raw reply

* Re: [PATCH v4 00/10] nd/clone-detached
From: Junio C Hamano @ 2012-01-15  2:34 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <20120114074036.GA27256@do>

Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:

>> Hmm, 'pu' seems to fail its selftest with this merge present, though.
>
> The commit "refuse to clone if --branch points to bogus ref" from this
> series changes clone's behavior that t5500.31, which is added in
> nd/clone-single-branch, relies on.

Ahh, of course.

> Another cleaner approach is to combine the two clone series into
> one.

I think "--single-branch" is much more relevant compared to cloning from a
repository with some funkiness like detached HEAD which is more about a
theoretical fun exercise, so let's rebuild this on top of the other one.

Thanks.

^ permalink raw reply

* Re: [PATCH v2 1/2] Document limited recursion pathspec matching with wildcards
From: Junio C Hamano @ 2012-01-15  2:38 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy
  Cc: git, Jonathan Nieder, Linus Torvalds
In-Reply-To: <1326533003-19686-1-git-send-email-pclouds@gmail.com>

Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> It's actually unlimited recursion if wildcards are active regardless
> --max-depth
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
>  Regarding Junio's question earlier:
>
>  >  - Shouldn't "onelevel_only" be the same as limiting to a single depth
>  >   with "max_depth"?
>
>  Doing that would change the behavior of "git grep --max-depth=0 -- 'a*'"
>  from unlimited recursion currently to limited. We did not come to agree
>  how --max-depth should behave with wildcards last time it was discussed,
>  so it's best separating two flags (in the next patch) for now.

Ok, I 100% agree with the "at least for now" reasoning. Thanks for digging
into the archive.

>  Documentation/git-grep.txt |    3 +++
>  tree-walk.c                |    3 +++
>  2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
> index 15d6711..6a8b1e3 100644
> --- a/Documentation/git-grep.txt
> +++ b/Documentation/git-grep.txt
> @@ -79,6 +79,9 @@ OPTIONS
>  --max-depth <depth>::
>  	For each <pathspec> given on command line, descend at most <depth>
>  	levels of directories. A negative value means no limit.
> +	This option is ignored if <pathspec> contains active wildcards.
> +	In other words if "a*" matches a directory named "a*",
> +	"*" is matched literally so --max-depth is still effective.

Do we have a definition of "active wildcard"?

> diff --git a/tree-walk.c b/tree-walk.c
> index f82dba6..492c7cd 100644
> --- a/tree-walk.c
> +++ b/tree-walk.c
> @@ -661,6 +661,9 @@ match_wildcards:
>  		/*
>  		 * Match all directories. We'll try to match files
>  		 * later on.
> +		 * max_depth is ignored but we may consider support it
> +		 * in future, see
> +		 * http://thread.gmane.org/gmane.comp.version-control.git/163757/focus=163840
>  		 */
>  		if (ps->recursive && S_ISDIR(entry->mode))
>  			return entry_interesting;

^ permalink raw reply

* Re: [PATCH v2 2/2] tree_entry_interesting: make recursive mode default
From: Junio C Hamano @ 2012-01-15  3:12 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy
  Cc: git, Jonathan Nieder, Linus Torvalds
In-Reply-To: <1326533003-19686-2-git-send-email-pclouds@gmail.com>

Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> This patch decouples the use of recursive field. The max_depth feature
> switch is now controlled by max_depth_valid field. diff-tree recursion
> is controlled by onelevel_only, which makes it recursive by default.

> diff --git a/builtin/grep.c b/builtin/grep.c
> index 9ce064a..c081bf4 100644
> --- a/builtin/grep.c
> +++ b/builtin/grep.c
> @@ -1051,7 +1051,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
>  	paths = get_pathspec(prefix, argv + i);
>  	init_pathspec(&pathspec, paths);
>  	pathspec.max_depth = opt.max_depth;
> -	pathspec.recursive = 1;
> +	pathspec.max_depth_valid = 1;

We initialize opt.max_depth to "-1" (unlimited) and then let it be
overridden by the command line, and we set it to pathspec, so max_depth is
always valid, even when it is "-1", and is to be honoured.

> diff --git a/dir.c b/dir.c
> index 0a78d00..5af3567 100644
> --- a/dir.c
> +++ b/dir.c
> @@ -258,7 +258,7 @@ int match_pathspec_depth(const struct pathspec *ps,
>  	int i, retval = 0;
>  
>  	if (!ps->nr) {
> -		if (!ps->recursive || ps->max_depth == -1)
> +		if (!ps->max_depth_valid || ps->max_depth == -1)
>  			return MATCHED_RECURSIVELY;
>  		if (within_depth(name, namelen, 0, ps->max_depth))

When there is no pathspec given, if we do not have a valid depth limiter,
or a valid depth limiter says "-1" (unlimited), it is always a match.
Otherwise we have check the depth. Looks correct.


> @@ -275,7 +275,7 @@ int match_pathspec_depth(const struct pathspec *ps,
>  		if (seen && seen[i] == MATCHED_EXACTLY)
>  			continue;
>  		how = match_pathspec_item(ps->items+i, prefix, name, namelen);
> -		if (ps->recursive && ps->max_depth != -1 &&
> +		if (ps->max_depth_valid && ps->max_depth != -1 &&
>  		    how && how != MATCHED_FNMATCH) {
>  			int len = ps->items[i].len;
>  			if (name[len] == '/')

Likewise. When there is a max_depth defined from the caller, and we did
not get the desired match, we check if we can go deeper to retry the
match. Looks correct.

These assume that tree-diff (the sole user of onelevel_only) never calls
into this function and ask to limit the recursion, though. Is it a good
thing for the longer-term code health?

In any case, both of the above seem to work without max_depth_valid.  If
the caller does not want to use depth limiting, it can set max_depth to
"-1", and all the code after this patch that check ps->max_depth_valid can
pretend that max_depth_valid is set to 1, no?

> diff --git a/tree-diff.c b/tree-diff.c
> index 28ad6db..fbc683c 100644
> --- a/tree-diff.c
> +++ b/tree-diff.c
> @@ -137,8 +137,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
>  	enum interesting t2_match = entry_not_interesting;
>  
>  	/* Enable recursion indefinitely */
> -	opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
> -	opt->pathspec.max_depth = -1;
> +	opt->pathspec.onelevel_only = !DIFF_OPT_TST(opt, RECURSIVE);

The comment "Enable recursion indefinitely" seems stale (not a problem
with this change).

> diff --git a/tree-walk.c b/tree-walk.c
> index 492c7cd..fdecacc 100644
> --- a/tree-walk.c
> +++ b/tree-walk.c
> @@ -588,7 +588,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
>  		entry_not_interesting : all_entries_not_interesting;
>  
>  	if (!ps->nr) {
> -		if (!ps->recursive || ps->max_depth == -1)
> +		if (!ps->max_depth_valid || ps->max_depth == -1)
>  			return all_entries_interesting;
>  		return within_depth(base->buf + base_offset, baselen,
>  				    !!S_ISDIR(entry->mode),

When there is no pathspec given, if we do not have a valid depth limiter
(i.e. caller is diff-tree), or a valid depth limiter says "-1" (unlimited), 
everything in this tree is interesting. If we have depth limit, we need to
check it.

But how would onelevel_only option interact with this codepath? We used to
have recursive == false and max_depth == -1 in a non-recursive diff-tree,
so the old code would have returned all_entries_interesting. Now we rely
on max_depth_valid being invalid. Again, wouldn't this work without
max_depth_valid if max_depth is set to "-1" in diff-tree?

> @@ -609,7 +609,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
>  			if (!match_dir_prefix(base_str, match, matchlen))
>  				goto match_wildcards;
>  
> -			if (!ps->recursive || ps->max_depth == -1)
> +			if (!ps->max_depth_valid || ps->max_depth == -1)
>  				return all_entries_interesting;
>  			return within_depth(base_str + matchlen + 1,

Likewise. Everything is interesting in a matched entry, when not
depth-limited. Otherwise we would need to check the depth. Looks correct.

Again, how would onelevel_only option interact with this part?

> @@ -634,7 +634,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
>  				 * Match all directories. We'll try to
>  				 * match files later on.
>  				 */
> -				if (ps->recursive && S_ISDIR(entry->mode))
> +				if (!ps->onelevel_only && S_ISDIR(entry->mode))
>  					return entry_interesting;
>  			}
>  
> @@ -665,7 +665,7 @@ match_wildcards:
>  		 * in future, see
>  		 * http://thread.gmane.org/gmane.comp.version-control.git/163757/focus=163840
>  		 */
> -		if (ps->recursive && S_ISDIR(entry->mode))
> +		if (!ps->onelevel_only && S_ISDIR(entry->mode))
>  			return entry_interesting;
>  	}
>  	return never_interesting; /* No matches */

Before we had recursive and max_depth. Now you have three instead of two.
The only thing we are trying to say with these three is if we want to
allow unlimited recursion, no recursion or recursion limited to a certain
depth. An integer option ought to work, and various codepaths that used to
look at the old two variables are converted to look at only just a few of
the new three variables, and never all three of them.

That makes my head hurt and makes me suspect there is something
fundamentally wrong in the patch.  Sigh...

^ permalink raw reply

* Re: Bug? Git checkout fails with a wrong error message
From: Yves Goergen @ 2012-01-15  8:14 UTC (permalink / raw)
  To: Holger Hellmuth; +Cc: git, Jeff King, Carlos Martín Nieto
In-Reply-To: <4F1085EC.9010708@ira.uka.de>

On 13.01.2012 20:28 CE(S)T, Holger Hellmuth wrote:
> Is it possible that Visual Studio changes them while you are comitting?

No. Those files may only be modified while open.

>> I renamed the file and created a new one with the same name. Is it so
>> simple to crash the Git repository?
> 
> Who said anything about crash? git simply doesn't care whether a change 
> is because of a rename. It isn't special or different to any change you 
> can make to a file

Well, there is a tracked file about which Git says it's untracked. How
would you describe such internal inconsistency? Maybe corruption would
fit better.

> As an aside, if .Designer.cs is generated automatically from Form1.cs it 
> shouldn't be tracked at all.

Of course, it's important! The file contains everything I draw in the UI
designer. I just don't write that myself which is why I rarely see its
contents.

> Maybe tortoise git has a global gitignore 
> with a line "*.Designer.cs" in it to account for that fact. Maybe this 
> lead to the error message?

It hasn't. This is already triple-checked by now. The file really is
definitely not ignored by any of the both ignore/exclude files known to me.

>>> What does git diff -- Form1.Designer.cs' say?
>> Nothing.
>>
>>> What does 'git diff form-refactoring -- Form1.Designer.cs' say?
>> All lines deleted.
> 
> Really all lines?

I don't have the time to re-check right now, but I remember seeing a
valid file beginning and end and no gaps in between. So I think it was
all files.

> That would indicate that you don't have a file 
> Form1.Designer.cs (or an empty one) in your working directory in branch 
> master. In case there is no file (as seen by git) the output of diff 
> should compare with /dev/null aka the void aka <I don't know how this 
> prints on the windows side>. Also notice the line "deleted file mode ..."
> 
>  > git diff master -- zumf
> diff --git a/zumf b/zumf
> deleted file mode 100644
> index 925eccd..0000000
> --- a/zumf
> +++ /dev/null
> @@ -1 +0,0 @@
> 
> Or did you just mean "all the shown lines in the diff were fronted by a 
> minus sign"?

Yes, and in dark red.

> Which would just indicate that the file in form-refactoring 
> is a superset of the one in master.
> 
> (As you can see, actual reproduction of command line output is very 
> helpful to avoid ambiguity and can give further hints)

That was some kind of less display. I could have attached a screenshot
to show it. It's not common or especially simple to include console
output on Windows, as there often is no console at all.

-- 
Yves Goergen "LonelyPixel" <nospam.list@unclassified.de>
Visit my web laboratory at http://beta.unclassified.de

^ permalink raw reply

* Re: Bug! Git merge also fails with a wrong error message
From: Yves Goergen @ 2012-01-15  8:17 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Carlos Martín Nieto, git
In-Reply-To: <m3mx9re6t0.fsf@localhost.localdomain>

On 13.01.2012 20:34 CE(S)T, Jakub Narebski wrote:
>> Since I don't have access to the news system, I need to use the Gmane
>> website. I don't know exactly what it is.
> 
> GMane is an e-mail to news gateway, and a mailing list archive. It
> exposes mailing list as a newsgroup, so it can be read and written to
> via newsreader (via Usenet).

I have Thunderbird, but I have no usenet server to entry in a usenet
account, so as I said, I don't have access to that part of the internet.
I had at university, but that's some time ago now.

> git@vger.kernel.org is a public non-subscribe mailing list; you don't
> need to subscribe to post requests there.  Note that it is a custom on
> this mailing list to always include all participants in given
> (sub)thread directly in Cc, so you should get responses to your emails
> even if you are not subscribed.

Good to know NOW. It really should have informed me in the first place
on that website. It's a vital information without which you likely won't
get anywhere (as I).

-- 
Yves Goergen "LonelyPixel" <nospam.list@unclassified.de>
Visit my web laboratory at http://beta.unclassified.de

^ permalink raw reply

* Re: [PATCH v3 1/3] Eliminate recursion in setting/clearing marks in commit list
From: Nguyen Thai Ngoc Duy @ 2012-01-15  9:25 UTC (permalink / raw)
  To: Peter Baumann; +Cc: git, Junio C Hamano, Shawn O. Pearce
In-Reply-To: <20120114152316.GA30986@m62s10.vlinux.de>

2012/1/14 Peter Baumann <waste.manager@gmx.de>:
> On Sat, Jan 14, 2012 at 07:19:53PM +0700, Nguyễn Thái Ngọc Duy wrote:
>> Recursion in a DAG is generally a bad idea because it could be very
>> deep. Be defensive and avoid recursion in mark_parents_uninteresting()
>> and clear_commit_marks().
>>
>> mark_parents_uninteresting() learns a trick from clear_commit_marks()
>> to avoid malloc() in (dorminant) single-parent case.
>                        ^^^^^^^^^
>
> I think you ment dominant here.

Yes I meant dominant.
-- 
Duy

^ permalink raw reply

* Cannot push a commit
From: Matthias Fechner @ 2012-01-15  9:09 UTC (permalink / raw)
  To: git

Dear List,

I have a big problem with a file which I cannot push to my central git
repository.
The file can be found here:
http://dl.fechner.net/APP_UD.sch

What I did to reproduce it:
On my server (freebsd with git 1.7.8.3)
cd
mkdir git-test
cd git-test
git init --bare

On my client a windows pc with tortoise git 1.7.6.0 and git 1.7.8.msysgit.0
I cloned the repository over ssh
Added a small test.txt file, commit and pushed it to the server,
everything is fine.
Then a copied the file above to the local repo, added it and commited it.
If I try to push it, I get the error message:
git.exe push --progress  "origin" master:master

Counting objects: 4, done.
Compressing objects: 100% (3/3)
Writing objects: 100% (3/3), 80.00 KiB | 137 KiB/s
Writing objects: 100% (3/3), 91.63 KiB | 137 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
fatal: early EOF
error: unpack failed: unpack-objects abnormal exit
To idefix@fechner.net:git-test
! [remote rejected] master -> master (n/a (unpacker error))
error: failed to push some refs to 'idefix@fechner.net:git-test'

git config -l shows on the windows pc:
core.symlinks=false
core.autocrlf=false
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.name=Matthias Fechner
user.email=idefix@fechner.net
core.autocrlf=false
core.safecrlf=false
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
remote.origin.url=idefix@fechner.net:git-test
remote.origin.puttykeyfile=
branch.master.remote=origin
branch.master.merge=refs/heads/master

How can I solve this problem?
Is this maybe a bug in git?

Thanks a lot
Matthias

-- 

"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the universe trying to
produce bigger and better idiots. So far, the universe is winning." --
Rich Cook

^ permalink raw reply

* Re: git grep doesn't follow symbolic link
From: Nguyen Thai Ngoc Duy @ 2012-01-15  9:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Pang Yan Han, Thomas Rast, Ramkumar Ramachandra, Bertrand BENOIT,
	git
In-Reply-To: <7v1ur1yazf.fsf@alter.siamese.dyndns.org>

On Sun, Jan 15, 2012 at 9:07 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Stop and think what "git diff --follow-symlinks v1.3.0 v1.7.0" should do
> when these versions record a symbolic link, "from user perspective", if
> the link points outside the tracked contents. Naturally, the users would
> expect that the comparison is made between the contents of the file back
> when v1.3.0 was tagged and the contents of the file (which may or may not
> be the same path depending on the target of that symbolic link) back when
> v1.7.0 was tagged.
>
> But that is something that the user is *NOT* tracking with the system, and
> hence something we cannot give the right answer. Your "--follow-symlinks"
> option only encourages the *wrong* perception on the users' side, without
> supporting what it appears to promise to the users. Why could it be an
> improvement?

It's not wrong per se. It's an implication that users have to take
when they choose to use it. We may help make it clear that the
symlinks point to untracked files by putting some indication in the
diff.

When I do "git log -Sfoo -- '*.cxx'" I don't really care if bar.cxx is
a symlink. Neither does my compiler. It may be a symlink's target
change that makes "foo" appear. Git could help me detect that quickly
instead of sticking with tracked contents only.

Even if we decide --follow-symlinks=untracked is a bad idea,
--follow-symlinks=tracked (i.e. follow symlinks to tracked files only)
is still a good thing to support. And I suspect that's a more common
case as linking outside repository could is undeterministic.

The "=tracked" could be dropped if we have no other option value. I'm
thinking of --follow-symlinks=submodule, which is currently covered by
a separate option name.
-- 
Duy

^ permalink raw reply

* Re: [PATCH v2 1/2] Document limited recursion pathspec matching with wildcards
From: Nguyen Thai Ngoc Duy @ 2012-01-15  9:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jonathan Nieder, Linus Torvalds
In-Reply-To: <7vfwfhwuzd.fsf@alter.siamese.dyndns.org>

2012/1/15 Junio C Hamano <gitster@pobox.com>:
>> @@ -79,6 +79,9 @@ OPTIONS
>>  --max-depth <depth>::
>>       For each <pathspec> given on command line, descend at most <depth>
>>       levels of directories. A negative value means no limit.
>> +     This option is ignored if <pathspec> contains active wildcards.
>> +     In other words if "a*" matches a directory named "a*",
>> +     "*" is matched literally so --max-depth is still effective.
>
> Do we have a definition of "active wildcard"?

Probably not. I did not know how to phrase it and ended up with
"active wildcard" and an example for clarification.
-- 
Duy

^ permalink raw reply

* Re: [PATCH v2 2/2] tree_entry_interesting: make recursive mode default
From: Nguyen Thai Ngoc Duy @ 2012-01-15 10:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jonathan Nieder, Linus Torvalds
In-Reply-To: <7v8vl9wtfg.fsf@alter.siamese.dyndns.org>

On Sat, Jan 14, 2012 at 07:12:03PM -0800, Junio C Hamano wrote:
> That makes my head hurt and makes me suspect there is something
> fundamentally wrong in the patch.  Sigh...

I'll need to think about it. In the meantime perhaps the following
bandage patch would suffice, rather than revert 2f88c19 (diff-index:
pass pathspec down to unpack-trees machinery)

-- 8< --
Subject: [PATCH] diff-index: enable recursive pathspec matching in unpack_trees

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 diff-lib.c               |    2 ++
 t/t4010-diff-pathspec.sh |    8 ++++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/diff-lib.c b/diff-lib.c
index 62f4cd9..fc0dff3 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -469,6 +469,8 @@ static int diff_cache(struct rev_info *revs,
 	opts.src_index = &the_index;
 	opts.dst_index = NULL;
 	opts.pathspec = &revs->diffopt.pathspec;
+	opts.pathspec->recursive = 1;
+	opts.pathspec->max_depth = -1;
 
 	init_tree_desc(&t, tree->buffer, tree->size);
 	return unpack_trees(1, &t, &opts);
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index fbc8cd8..af5134b 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -48,6 +48,14 @@ test_expect_success \
      compare_diff_raw current expected'
 
 cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M	path1/file1
+EOF
+test_expect_success \
+    '"*file1" should show path1/file1' \
+    'git diff-index --cached $tree -- "*file1" >current &&
+     compare_diff_raw current expected'
+
+cat >expected <<\EOF
 :100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M	file0
 EOF
 test_expect_success \
-- 
1.7.8.36.g69ee2

-- 8< --
-- 
Duy

^ permalink raw reply related

* Re: Bug! Git merge also fails with a wrong error message
From: Jakub Narebski @ 2012-01-15 10:08 UTC (permalink / raw)
  To: Yves Goergen; +Cc: Carlos Martín Nieto, git
In-Reply-To: <4F128B81.2000502@unclassified.de>

On Sun, 15 Jan 2012, Yves Goergen wrote:
> On 13.01.2012 20:34 CE(S)T, Jakub Narebski wrote:

> > > Since I don't have access to the news system, I need to use the Gmane
> > > website. I don't know exactly what it is.
> > 
> > GMane is an e-mail to news gateway, and a mailing list archive. It
> > exposes mailing list as a newsgroup, so it can be read and written to
> > via newsreader (via Usenet).
> 
> I have Thunderbird, but I have no usenet server to entry in a usenet
> account, so as I said, I don't have access to that part of the internet.
> I had at university, but that's some time ago now.

GMane serves as a Usenet server; that is how it works as mail to news
gateway.  The server name is news.gmane.org... or you can try using the
following URL

  nntp://news.gmane.org/gmane.comp.version-control.git
 
> > git@vger.kernel.org is a public non-subscribe mailing list; you don't
> > need to subscribe to post requests there.  Note that it is a custom on
> > this mailing list to always include all participants in given
> > (sub)thread directly in Cc, so you should get responses to your emails
> > even if you are not subscribed.
> 
> Good to know NOW. It really should have informed me in the first place
> on that website. It's a vital information without which you likely won't
> get anywhere (as I).

You can get this information on GitCommunity page on Git Wiki.  For the
time being (while Git Wiki is served as set of static pages of exported
contents because of lack of hardware) you can find it here:

  https://git.wiki.kernel.org/articles/g/i/t/GitCommunity_c4e3.html

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [PATCH] test-lib: add the test_bash convenience function
From: Jens Lehmann @ 2012-01-15 20:00 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Jeff King, Junio C Hamano

Since 781f76b15 (test-lib: redirect stdin of tests) you can't simply put a
"bash &&" into a test for debugging purposes anymore. Instead you'll have
to use "bash <&6 >&3 2>&4".

As that invocation is not that easy to remember add the test_bash
convenience function. This function also checks if the -v flag is given
and will complain if that is not the case instead of letting the test
hang until ^D is pressed.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

I was tempted to call that method "run_bash" but after looking around
in test-lib.sh "test_bash" seemed like a better name.

 t/test-lib.sh |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/t/test-lib.sh b/t/test-lib.sh
index a65dfc7..f9061e0 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -329,6 +329,17 @@ test_tick () {
 	export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
 }

+# Stop execution and start a bash shell. This is useful for debugging tests
+# and only makes sense together with "-v".
+
+test_bash () {
+	if test "$verbose" = t; then
+		bash <&6 >&3 2>&4
+	else
+		say >&5 "skipping test_bash as it makes no sense without -v"
+	fi
+}
+
 # Call test_commit with the arguments "<message> [<file> [<contents>]]"
 #
 # This will commit a file with the given contents and the given commit
-- 
1.7.9.rc1.1.g46aa0.dirty

^ permalink raw reply related

* Re: [PATCH] test-lib: add the test_bash convenience function
From: Jeff King @ 2012-01-15 23:24 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <4F133069.10308@web.de>

On Sun, Jan 15, 2012 at 09:00:41PM +0100, Jens Lehmann wrote:

> Since 781f76b15 (test-lib: redirect stdin of tests) you can't simply put a
> "bash &&" into a test for debugging purposes anymore. Instead you'll have
> to use "bash <&6 >&3 2>&4".

Yeah, an unfortunate side effect.

If you're not relying on particular state in the middle of a chain of
commands, you can just put the "bash" outside of the test_expect_*. But
sometimes you do care about having it in the middle.

> As that invocation is not that easy to remember add the test_bash
> convenience function. This function also checks if the -v flag is given
> and will complain if that is not the case instead of letting the test
> hang until ^D is pressed.

Nice. Many times I have added such a "bash" or "gdb" invocation then
forgotten "-v", only to scratch my head at why the test seemed to be
hanging.

Two minor nits on the patch itself:

> +# Stop execution and start a bash shell. This is useful for debugging tests
> +# and only makes sense together with "-v".
> +
> +test_bash () {
> +	if test "$verbose" = t; then
> +		bash <&6 >&3 2>&4
> +	else
> +		say >&5 "skipping test_bash as it makes no sense without -v"
> +	fi
> +}

1. It may be worth putting a warning in the comment that this is never
   to be used in a real test, but only temporarily inserted.

2. I do this not just with bash, but with "gdb". I wonder if it is worth
   making this "test_foo bash", for some value of "foo" (the ones that
   occur to me are "debug" and "run", but of course they are taken).

   Actually, I wonder if the existing test_debug could handle this
   already (though you do have to remember to add "--debug" to your
   command line, then).

-Peff

^ permalink raw reply

* Re: Re* Regulator updates for 3.3
From: Pete Harlan @ 2012-01-16  0:14 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Linus Torvalds, Mark Brown, Liam Girdwood, linux-kernel,
	Git Mailing List
In-Reply-To: <7vzkdu7miv.fsf@alter.siamese.dyndns.org>

On 01/10/2012 10:59 PM, Junio C Hamano wrote:
> There may be existing scripts that leave the standard input and the
> standard output of the "git merge" connected to whatever environment the
> scripts were started, and such invocation might trigger the above
> "interactive session" heuristics. Such scripts can export GIT_MERGE_LEGACY
> environment variable set to "yes" to force the traditional behaviour.

The name GIT_MERGE_LEGACY gives no clue about what flavor of legacy
merge behavior is being enabled.  Something like GIT_MERGE_LEGACY_EDIT
might be clearer, or perhaps just have GIT_MERGE_EDIT=0 to get the old
behavior without reference to whether or not that behavior is
considered legacy.

--Pete

^ permalink raw reply

* [PATCH 0/3] git-p4: Search for parent commit on branch creation
From: Vitor Antunes @ 2012-01-16  0:39 UTC (permalink / raw)
  To: git; +Cc: Pete Wyckoff, Vitor Antunes

This patch was originally sent as a RFC and was improved since then
according to feedback given by Pete Wyckoff. At the time it required
calling fast-import with the --force argument. To avoid this the new
version tracks the temporary branches created during post-processing and
removes them at the end of the import process.

Vitor Antunes (3):
  git-p4: Add checkpoint() task
  git-p4: Search for parent commit on branch creation
  git-p4: Add test case for complex branch import

 contrib/fast-import/git-p4 |   39 ++++++++++++++++++++-
 t/t9801-git-p4-branch.sh   |   83 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 121 insertions(+), 1 deletions(-)

-- 
1.7.8.3

^ permalink raw reply

* [PATCH 1/3] git-p4: Add checkpoint() task
From: Vitor Antunes @ 2012-01-16  0:39 UTC (permalink / raw)
  To: git; +Cc: Pete Wyckoff, Vitor Antunes
In-Reply-To: <1326674360-2771-1-git-send-email-vitor.hda@gmail.com>

Signed-off-by: Vitor Antunes <vitor.hda@gmail.com>
---
 contrib/fast-import/git-p4 |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 3e1aa27..417d119 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1450,6 +1450,14 @@ class P4Sync(Command, P4UserMap):
                    .replace("%25", "%")
         return path
 
+    # Force a checkpoint in fast-import and wait for it to finish
+    def checkpoint(self):
+        self.gitStream.write("checkpoint\n\n")
+        self.gitStream.write("progress checkpoint\n\n")
+        out = self.gitOutput.readline()
+        if self.verbose:
+            print "checkpoint finished: " + out
+
     def extractFilesFromCommit(self, commit):
         self.cloneExclude = [re.sub(r"\.\.\.$", "", path)
                              for path in self.cloneExclude]
-- 
1.7.8.3

^ permalink raw reply related

* [PATCH 2/3] git-p4: Search for parent commit on branch creation
From: Vitor Antunes @ 2012-01-16  0:39 UTC (permalink / raw)
  To: git; +Cc: Pete Wyckoff, Vitor Antunes
In-Reply-To: <1326674360-2771-1-git-send-email-vitor.hda@gmail.com>

To find out which is its parent the commit of the new branch is applied
sequentially to each blob of the parent branch from the newest to the
oldest. The first blob which results in a zero diff is considered the
parent commit. If none is found, then the commit is applied to the top
of the parent branch.

A fast-import "checkpoint" call is required for each comparison because
diff-tree is only able to work with blobs on disk. But most of these
commits will not be part of the final imported tree, making fast-import
fail. To avoid this, the temporary branches are tracked and then removed
at the end of the import process.

Signed-off-by: Vitor Antunes <vitor.hda@gmail.com>
---
 contrib/fast-import/git-p4 |   31 ++++++++++++++++++++++++++++++-
 1 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 417d119..e2f9165 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1429,6 +1429,8 @@ class P4Sync(Command, P4UserMap):
         self.cloneExclude = []
         self.useClientSpec = False
         self.clientSpecDirs = None
+        self.tempBranches = []
+        self.tempBranchLocation = "git-p4-tmp"
 
         if gitConfig("git-p4.syncFromOrigin") == "false":
             self.syncWithOrigin = False
@@ -2012,7 +2014,28 @@ class P4Sync(Command, P4UserMap):
                             parent = self.initialParents[branch]
                             del self.initialParents[branch]
 
-                        self.commit(description, filesForCommit, branch, [branchPrefix], parent)
+                        parentFound = 0
+                        if len(parent) > 0:
+                            self.checkpoint()
+                            for blob in read_pipe_lines("git rev-list --reverse --no-merges %s" % parent):
+                                blob = blob.strip()
+                                tempBranch = self.tempBranchLocation + os.sep + "%d-%s" % (change, blob)
+                                if self.verbose:
+                                    print "Creating temporary branch: " + tempBranch
+                                self.commit(description, filesForCommit, tempBranch, [branchPrefix], blob)
+                                self.tempBranches.append(tempBranch)
+                                self.checkpoint()
+                                if len( read_pipe("git diff-tree %s %s" % (blob, tempBranch)) ) == 0:
+                                    parentFound = 1
+                                    if self.verbose:
+                                        print "Found parent of %s in commit %s" % (branch, blob)
+                                    break
+                        if parentFound:
+                            self.commit(description, filesForCommit, branch, [branchPrefix], blob)
+                        else:
+                            if self.verbose:
+                                print "Parent of %s not found. Committing into head of %s" % (branch, parent)
+                            self.commit(description, filesForCommit, branch, [branchPrefix], parent)
                 else:
                     files = self.extractFilesFromCommit(description)
                     self.commit(description, files, self.branch, self.depotPaths,
@@ -2347,6 +2370,12 @@ class P4Sync(Command, P4UserMap):
         self.gitOutput.close()
         self.gitError.close()
 
+        # Cleanup temporary branches created during import
+        if self.tempBranches != []:
+            for branch in self.tempBranches:
+                os.remove(".git" + os.sep + branch)
+            os.rmdir(".git" + os.sep + self.tempBranchLocation)
+
         return True
 
 class P4Rebase(Command):
-- 
1.7.8.3

^ permalink raw reply related

* [PATCH 3/3] git-p4: Add test case for complex branch import
From: Vitor Antunes @ 2012-01-16  0:39 UTC (permalink / raw)
  To: git; +Cc: Pete Wyckoff, Vitor Antunes
In-Reply-To: <1326674360-2771-1-git-send-email-vitor.hda@gmail.com>

Check if branches created from old changelists are correctly imported.

Signed-off-by: Vitor Antunes <vitor.hda@gmail.com>
---
 t/t9801-git-p4-branch.sh |   83 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh
index a25f18d..0f10e00 100755
--- a/t/t9801-git-p4-branch.sh
+++ b/t/t9801-git-p4-branch.sh
@@ -226,6 +226,89 @@ test_expect_success 'git-p4 clone simple branches' '
 	)
 '
 
+# Create a complex branch structure in P4 depot to check if they are correctly
+# cloned. The branches are created from older changelists to check if git-p4 is
+# able to correctly detect them.
+# The final expected structure is:
+# `branch1
+# | `- file1
+# | `- file2 (updated)
+# | `- file3
+# `branch2
+# | `- file1
+# | `- file2
+# `branch3
+# | `- file1
+# | `- file2 (updated)
+# | `- file3
+# `branch4
+# | `- file1
+# | `- file2
+# `branch5
+#   `- file1
+#   `- file2
+#   `- file3
+test_expect_success 'git-p4 add complex branches' '
+	test_when_finished cleanup_git &&
+	test_create_repo "$git" &&
+	(
+		cd "$cli" &&
+		changelist=$(p4 changes -m1 //depot/... | cut -d" " -f2) &&
+		changelist=$((changelist - 5)) &&
+		p4 integrate //depot/branch1/...@$changelist //depot/branch4/... &&
+		p4 submit -d "branch4" &&
+		changelist=$((changelist + 2)) &&
+		p4 integrate //depot/branch1/...@$changelist //depot/branch5/... &&
+		p4 submit -d "branch5" &&
+		cd "$TRASH_DIRECTORY"
+	)
+'
+
+# Configure branches through git-config and clone them. git-p4 will only be able
+# to clone the original structure if it is able to detect the origin changelist
+# of each branch.
+test_expect_success 'git-p4 clone complex branches' '
+	test_when_finished cleanup_git &&
+	test_create_repo "$git" &&
+	(
+		test_when_finished cleanup_git &&
+		test_create_repo "$git" &&
+		cd "$git" &&
+		git config git-p4.branchList branch1:branch2 &&
+		git config --add git-p4.branchList branch1:branch3 &&
+		git config --add git-p4.branchList branch1:branch4 &&
+		git config --add git-p4.branchList branch1:branch5 &&
+		"$GITP4" clone --dest=. --detect-branches //depot@all &&
+		git log --all --graph --decorate --stat &&
+		git reset --hard p4/depot/branch1 &&
+		test -f file1 &&
+		test -f file2 &&
+		test -f file3 &&
+		grep -q update file2 &&
+		git reset --hard p4/depot/branch2 &&
+		test -f file1 &&
+		test -f file2 &&
+		test ! -f file3 &&
+		! grep -q update file2 &&
+		git reset --hard p4/depot/branch3 &&
+		test -f file1 &&
+		test -f file2 &&
+		test -f file3 &&
+		grep -q update file2 &&
+		git reset --hard p4/depot/branch4 &&
+		test -f file1 &&
+		test -f file2 &&
+		test ! -f file3 &&
+		! grep -q update file2 &&
+		git reset --hard p4/depot/branch5 &&
+		test -f file1 &&
+		test -f file2 &&
+		test -f file3 &&
+		! grep -q update file2 &&
+		test ! -d .git/git-p4-tmp
+	)
+'
+
 test_expect_success 'kill p4d' '
 	kill_p4d
 '
-- 
1.7.8.3

^ permalink raw reply related

* Unexpected "clean -Xd" behavior
From: Pete Harlan @ 2012-01-16  2:00 UTC (permalink / raw)
  To: Git Mailing List

Hi,

When a directory contains nothing but an ignored subdirectory, that
subdirectory does not get removed by "git clean -Xdf".

For example, in a new directory:

# git init
Initialized empty Git repository in /tmp/foo/.git/
# echo a/ >.gitignore
# git add .gitignore
# git commit -m "Initial commit"
[master (root-commit) c3af24c] Initial commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
# mkdir -p foo/a
# touch foo/a/junk.o
# git status
# On branch master
nothing to commit (working directory clean)
# git clean -Xdn  # <--- DOES NOT MENTION foo/a
# touch foo/x.c
# git clean -Xdn  # <--- DITTO WITH UNTRACKED IN foo
# git add foo/x.c
# git clean -Xdn  # <--- WITH TRACKED IN foo, WILL REMOVE a/
Would remove foo/a/
#

Is this intentional?  It's interfering with my using "git clean" to
remove built objects, which happen to be in a dedicated temporary
subdirectory.

Thanks,

--Pete Harlan
  pgit@pcharlan.com

^ permalink raw reply

* [PATCH 0/2] nd/commit-ignore-i-t-a replacement
From: Nguyễn Thái Ngọc Duy @ 2012-01-16  2:36 UTC (permalink / raw)
  To: git; +Cc: Jonathan Nieder, Junio C Hamano,
	Nguyễn Thái Ngọc Duy

This replaces current topic branch in pu with a more sensible
approach using config key. write-tree also learns about this.

Nguyễn Thái Ngọc Duy (2):
  cache-tree: update API to take abitrary flags
  commit, write-tree: allow to ignore CE_INTENT_TO_ADD while writing
    trees

 Documentation/config.txt         |    5 +++++
 Documentation/git-add.txt        |   12 ++++++++++--
 Documentation/git-write-tree.txt |    8 +++++++-
 builtin/commit.c                 |   13 ++++++++++---
 builtin/write-tree.c             |    2 ++
 cache-tree.c                     |   35 +++++++++++++++++------------------
 cache-tree.h                     |    5 ++++-
 merge-recursive.c                |    2 +-
 t/t2203-add-intent.sh            |   30 ++++++++++++++++++++++++++++++
 test-dump-cache-tree.c           |    2 +-
 10 files changed, 87 insertions(+), 27 deletions(-)

-- 
1.7.3.1.256.g2539c.dirty

^ permalink raw reply

* [PATCH 2/2] commit, write-tree: allow to ignore CE_INTENT_TO_ADD while writing trees
From: Nguyễn Thái Ngọc Duy @ 2012-01-16  2:36 UTC (permalink / raw)
  To: git; +Cc: Jonathan Nieder, Junio C Hamano,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1326681407-6344-1-git-send-email-pclouds@gmail.com>

Normally cache-tree will not produce trees from an index that has
CE_INTENT_TO_ADD entries. This is a safe measure to avoid
mis-interpreting user's intention regarding this flag.

There are situations however where users want to create trees/commits
regardless i-t-a entries. Allow such cases with commit.ignoreIntentToAdd
for git-commit and --ignore-intent-to-add for git-write-tree.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/config.txt         |    5 +++++
 Documentation/git-add.txt        |   12 ++++++++++--
 Documentation/git-write-tree.txt |    8 +++++++-
 builtin/commit.c                 |   13 ++++++++++---
 builtin/write-tree.c             |    2 ++
 cache-tree.c                     |    8 +++++---
 cache-tree.h                     |    1 +
 t/t2203-add-intent.sh            |   30 ++++++++++++++++++++++++++++++
 8 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index abeb82b..10c3767 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -831,6 +831,11 @@ commit.template::
 	"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
 	specified user's home directory.
 
+commit.ignoreIntentToAdd::
+	Allow to commit the index as-is even if there are
+	intent-to-add entries (see option `-N` in linkgit:git-add[1])
+	in index.
+
 credential.helper::
 	Specify an external helper to be called when a username or
 	password credential is needed; the helper may consult external
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 9c1d395..ec548ea 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -123,8 +123,16 @@ subdirectories.
 	Record only the fact that the path will be added later. An entry
 	for the path is placed in the index with no content. This is
 	useful for, among other things, showing the unstaged content of
-	such files with `git diff` and committing them with `git commit
-	-a`.
+	such files with `git diff`.
++
+Paths added with this option have intent-to-add flag in index. The
+flag is removed once real content is added or updated. By default you
+cannot commit the index as-is from until this flag is removed from all
+entries (i.e. all entries have real content). See commit.ignoreIntentToAdd
+regardless the flag.
++
+Committing with `git commit -a` or with selected paths works
+regardless the config key and the flag.
 
 --refresh::
 	Don't add the file(s), but only refresh their stat()
diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.txt
index f22041a..d511d3a 100644
--- a/Documentation/git-write-tree.txt
+++ b/Documentation/git-write-tree.txt
@@ -9,7 +9,7 @@ git-write-tree - Create a tree object from the current index
 SYNOPSIS
 --------
 [verse]
-'git write-tree' [--missing-ok] [--prefix=<prefix>/]
+'git write-tree' [--missing-ok] [--ignore-intent-to-add] [--prefix=<prefix>/]
 
 DESCRIPTION
 -----------
@@ -32,6 +32,12 @@ OPTIONS
 	directory exist in the object database.  This option disables this
 	check.
 
+--ignore-intent-to-add::
+	Normally 'git write-tree' will refuse to proceed if there are any
+	intent-to-add entries (see `-N` option in linkgit:git-add[1]).
+	This option continues to create object tree as if there are no
+	intent-to-add entries in index.
+
 --prefix=<prefix>/::
 	Writes a tree object that represents a subdirectory
 	`<prefix>`.  This can be used to write the tree object
diff --git a/builtin/commit.c b/builtin/commit.c
index bf42bb3..097699e 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -86,6 +86,7 @@ static int all, also, interactive, patch_interactive, only, amend, signoff;
 static int edit_flag = -1; /* unspecified */
 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
 static int no_post_rewrite, allow_empty_message;
+static int cache_tree_flags;
 static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
 static char *sign_commit;
 
@@ -400,7 +401,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 		fd = hold_locked_index(&index_lock, 1);
 		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
 		refresh_cache_or_die(refresh_flags);
-		update_main_cache_tree(WRITE_TREE_SILENT);
+		update_main_cache_tree(cache_tree_flags | WRITE_TREE_SILENT);
 		if (write_cache(fd, active_cache, active_nr) ||
 		    close_lock_file(&index_lock))
 			die(_("unable to write new_index file"));
@@ -421,7 +422,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 		fd = hold_locked_index(&index_lock, 1);
 		refresh_cache_or_die(refresh_flags);
 		if (active_cache_changed) {
-			update_main_cache_tree(WRITE_TREE_SILENT);
+			update_main_cache_tree(cache_tree_flags | WRITE_TREE_SILENT);
 			if (write_cache(fd, active_cache, active_nr) ||
 			    commit_locked_index(&index_lock))
 				die(_("unable to write new_index file"));
@@ -870,7 +871,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 	 */
 	discard_cache();
 	read_cache_from(index_file);
-	if (update_main_cache_tree(0)) {
+	if (update_main_cache_tree(cache_tree_flags)) {
 		error(_("Error building trees"));
 		return 0;
 	}
@@ -1338,6 +1339,12 @@ static int git_commit_config(const char *k, const char *v, void *cb)
 		include_status = git_config_bool(k, v);
 		return 0;
 	}
+	if (!strcmp(k, "commit.ignoreintenttoadd")) {
+		if (git_config_bool(k, v))
+			cache_tree_flags |= WRITE_TREE_IGNORE_INTENT_TO_ADD;
+		else
+			cache_tree_flags &= ~WRITE_TREE_IGNORE_INTENT_TO_ADD;
+	}
 
 	status = git_gpg_config(k, v, NULL);
 	if (status)
diff --git a/builtin/write-tree.c b/builtin/write-tree.c
index b223af4..07797bb 100644
--- a/builtin/write-tree.c
+++ b/builtin/write-tree.c
@@ -23,6 +23,8 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 	struct option write_tree_options[] = {
 		OPT_BIT(0, "missing-ok", &flags, "allow missing objects",
 			WRITE_TREE_MISSING_OK),
+		OPT_BIT(0, "ignore-intent-to-add", &flags, "ignore i-t-a entries in index",
+			WRITE_TREE_IGNORE_INTENT_TO_ADD ),
 		{ OPTION_STRING, 0, "prefix", &prefix, "<prefix>/",
 		  "write tree object for a subdirectory <prefix>" ,
 		  PARSE_OPT_LITERAL_ARGHELP },
diff --git a/cache-tree.c b/cache-tree.c
index 16355d6..d0be159 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -159,7 +159,9 @@ static int verify_cache(struct cache_entry **cache,
 	funny = 0;
 	for (i = 0; i < entries; i++) {
 		struct cache_entry *ce = cache[i];
-		if (ce_stage(ce) || (ce->ce_flags & CE_INTENT_TO_ADD)) {
+		if (ce_stage(ce) ||
+		    ((flags & WRITE_TREE_IGNORE_INTENT_TO_ADD) == 0 &&
+		     (ce->ce_flags & CE_INTENT_TO_ADD))) {
 			if (silent)
 				return -1;
 			if (10 < ++funny) {
@@ -339,8 +341,8 @@ static int update_one(struct cache_tree *it,
 				mode, sha1_to_hex(sha1), entlen+baselen, path);
 		}
 
-		if (ce->ce_flags & CE_REMOVE)
-			continue; /* entry being removed */
+		if (ce->ce_flags & (CE_REMOVE | CE_INTENT_TO_ADD))
+			continue; /* entry being removed or placeholder */
 
 		strbuf_grow(&buffer, entlen + 100);
 		strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
diff --git a/cache-tree.h b/cache-tree.h
index d8cb2e9..af3b917 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -38,6 +38,7 @@ int update_main_cache_tree(int);
 #define WRITE_TREE_IGNORE_CACHE_TREE 2
 #define WRITE_TREE_DRY_RUN 4
 #define WRITE_TREE_SILENT 8
+#define WRITE_TREE_IGNORE_INTENT_TO_ADD 16
 
 /* error return codes */
 #define WRITE_TREE_UNREADABLE_INDEX (-1)
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index 58a3299..7b447d3 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -44,6 +44,36 @@ test_expect_success 'cannot commit with i-t-a entry' '
 	test_must_fail git commit
 '
 
+test_expect_success 'can write-tree with i-t-a entry' '
+	git reset --hard &&
+	echo xyzzy >rezrov &&
+	echo frotz >nitfol &&
+	git add rezrov &&
+	git add -N nitfol &&
+	git write-tree --ignore-intent-to-add >actual &&
+	echo 150389afa1ccf46e4104667c741cd0e598269511 >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'can commit tree with i-t-a entry' '
+	git reset --hard &&
+	echo xyzzy >rezrov &&
+	echo frotz >nitfol &&
+	git add rezrov &&
+	git add -N nitfol &&
+	git config commit.ignoreIntentToAdd true &&
+	git commit -m initial &&
+	git ls-tree -r HEAD >actual &&
+	cat >expected <<EOF &&
+100644 blob ce013625030ba8dba906f756967f9e9ca394464a	elif
+100644 blob ce013625030ba8dba906f756967f9e9ca394464a	file
+100644 blob cf7711b63209d0dbc2d030f7fe3513745a9880e4	rezrov
+EOF
+	test_cmp expected actual &&
+	git config commit.ignoreIntentToAdd false &&
+	git reset HEAD^
+'
+
 test_expect_success 'can commit with an unrelated i-t-a entry in index' '
 	git reset --hard &&
 	echo xyzzy >rezrov &&
-- 
1.7.3.1.256.g2539c.dirty

^ permalink raw reply related

* [PATCH 1/2] cache-tree: update API to take abitrary flags
From: Nguyễn Thái Ngọc Duy @ 2012-01-16  2:36 UTC (permalink / raw)
  To: git; +Cc: Jonathan Nieder, Junio C Hamano,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1326681407-6344-1-git-send-email-pclouds@gmail.com>


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/commit.c       |    4 ++--
 cache-tree.c           |   27 ++++++++++++---------------
 cache-tree.h           |    4 +++-
 merge-recursive.c      |    2 +-
 test-dump-cache-tree.c |    2 +-
 5 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index eba1377..bf42bb3 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -400,7 +400,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 		fd = hold_locked_index(&index_lock, 1);
 		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
 		refresh_cache_or_die(refresh_flags);
-		update_main_cache_tree(1);
+		update_main_cache_tree(WRITE_TREE_SILENT);
 		if (write_cache(fd, active_cache, active_nr) ||
 		    close_lock_file(&index_lock))
 			die(_("unable to write new_index file"));
@@ -421,7 +421,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 		fd = hold_locked_index(&index_lock, 1);
 		refresh_cache_or_die(refresh_flags);
 		if (active_cache_changed) {
-			update_main_cache_tree(1);
+			update_main_cache_tree(WRITE_TREE_SILENT);
 			if (write_cache(fd, active_cache, active_nr) ||
 			    commit_locked_index(&index_lock))
 				die(_("unable to write new_index file"));
diff --git a/cache-tree.c b/cache-tree.c
index 8de3959..16355d6 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -150,9 +150,10 @@ void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
 }
 
 static int verify_cache(struct cache_entry **cache,
-			int entries, int silent)
+			int entries, int flags)
 {
 	int i, funny;
+	int silent = flags & WRITE_TREE_SILENT;
 
 	/* Verify that the tree is merged */
 	funny = 0;
@@ -241,10 +242,11 @@ static int update_one(struct cache_tree *it,
 		      int entries,
 		      const char *base,
 		      int baselen,
-		      int missing_ok,
-		      int dryrun)
+		      int flags)
 {
 	struct strbuf buffer;
+	int missing_ok = flags & WRITE_TREE_MISSING_OK;
+	int dryrun = flags & WRITE_TREE_DRY_RUN;
 	int i;
 
 	if (0 <= it->entry_count && has_sha1_file(it->sha1))
@@ -288,8 +290,7 @@ static int update_one(struct cache_tree *it,
 				    cache + i, entries - i,
 				    path,
 				    baselen + sublen + 1,
-				    missing_ok,
-				    dryrun);
+				    flags);
 		if (subcnt < 0)
 			return subcnt;
 		i += subcnt - 1;
@@ -371,15 +372,13 @@ static int update_one(struct cache_tree *it,
 int cache_tree_update(struct cache_tree *it,
 		      struct cache_entry **cache,
 		      int entries,
-		      int missing_ok,
-		      int dryrun,
-		      int silent)
+		      int flags)
 {
 	int i;
-	i = verify_cache(cache, entries, silent);
+	i = verify_cache(cache, entries, flags);
 	if (i)
 		return i;
-	i = update_one(it, cache, entries, "", 0, missing_ok, dryrun);
+	i = update_one(it, cache, entries, "", 0, flags);
 	if (i < 0)
 		return i;
 	return 0;
@@ -572,11 +571,9 @@ int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
 
 	was_valid = cache_tree_fully_valid(active_cache_tree);
 	if (!was_valid) {
-		int missing_ok = flags & WRITE_TREE_MISSING_OK;
-
 		if (cache_tree_update(active_cache_tree,
 				      active_cache, active_nr,
-				      missing_ok, 0, 0) < 0)
+				      flags) < 0)
 			return WRITE_TREE_UNMERGED_INDEX;
 		if (0 <= newfd) {
 			if (!write_cache(newfd, active_cache, active_nr) &&
@@ -672,10 +669,10 @@ int cache_tree_matches_traversal(struct cache_tree *root,
 	return 0;
 }
 
-int update_main_cache_tree (int silent)
+int update_main_cache_tree (int flags)
 {
 	if (!the_index.cache_tree)
 		the_index.cache_tree = cache_tree();
 	return cache_tree_update(the_index.cache_tree,
-				 the_index.cache, the_index.cache_nr, 0, 0, silent);
+				 the_index.cache, the_index.cache_nr, flags);
 }
diff --git a/cache-tree.h b/cache-tree.h
index 0ec0b2a..d8cb2e9 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -29,13 +29,15 @@ void cache_tree_write(struct strbuf *, struct cache_tree *root);
 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
 
 int cache_tree_fully_valid(struct cache_tree *);
-int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int, int);
+int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int);
 
 int update_main_cache_tree(int);
 
 /* bitmasks to write_cache_as_tree flags */
 #define WRITE_TREE_MISSING_OK 1
 #define WRITE_TREE_IGNORE_CACHE_TREE 2
+#define WRITE_TREE_DRY_RUN 4
+#define WRITE_TREE_SILENT 8
 
 /* error return codes */
 #define WRITE_TREE_UNREADABLE_INDEX (-1)
diff --git a/merge-recursive.c b/merge-recursive.c
index d83cd6c..6479a60 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -264,7 +264,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
 
 	if (!cache_tree_fully_valid(active_cache_tree) &&
 	    cache_tree_update(active_cache_tree,
-			      active_cache, active_nr, 0, 0, 0) < 0)
+			      active_cache, active_nr, 0) < 0)
 		die("error building trees");
 
 	result = lookup_tree(active_cache_tree->sha1);
diff --git a/test-dump-cache-tree.c b/test-dump-cache-tree.c
index e6c2923..a6ffdf3 100644
--- a/test-dump-cache-tree.c
+++ b/test-dump-cache-tree.c
@@ -59,6 +59,6 @@ int main(int ac, char **av)
 	struct cache_tree *another = cache_tree();
 	if (read_cache() < 0)
 		die("unable to read index file");
-	cache_tree_update(another, active_cache, active_nr, 0, 1, 0);
+	cache_tree_update(another, active_cache, active_nr, WRITE_TREE_DRY_RUN);
 	return dump_cache_tree(active_cache_tree, another, "");
 }
-- 
1.7.3.1.256.g2539c.dirty

^ permalink raw reply related

* [PATCH 0/5] Dynamic diff summary for merge/pull
From: Nguyễn Thái Ngọc Duy @ 2012-01-16  4:47 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Linus Torvalds,
	Nguyễn Thái Ngọc Duy

On Sat, Jan 14, 2012 at 2:49 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> And what I've *really* wanted is to actually see the diff itself if
> it
> is small. So some kind of "dynamic summary": for one-liners (or
> ten-liners), show the whole diff. For medium-sized changes, show the
> whole diffstat. And for really big changes, show an outline and the
> "768 files changed, 179851 lines added, 7630 lines removed" stats.
>
> IOW, whatever fits in, say, 50 lines or less.

Here's an attempt to do that. The main patch is 4/5 to implement
--dynstat. 5/5 just makes merge/pull pass --dynstat to diff machinery.

--dynstat tries various diff output and use one that fits within 50
lines:

 --patch + --shortstat
 --stat (maybe plus --summary)
 --dirstat + --shortstat
 --shortstat

Many hardcoded constants should be more flexible (i.e. 50 lines limit
could be retrieved from terminal settigns), but that's minor for
now imo. I think we should also hint users to do
"git diff --stat --summary HEAD@{1} HEAD" too via advice framework if
we turn --dynstat to default for merge/pull

I have not run "make test" so it may break a few tests because of 2/2.

Nguyễn Thái Ngọc Duy (5):
  diff: add space around "="
  diff: do not duplicate shortstat with "git diff --stat --shortstat"
  diff: buffer dirstat output
  diff: add --dynstat
  merge: support setting merge.[diff]stat to dynstat

 builtin/merge.c |   30 +++++++++++--
 diff.c          |  127 +++++++++++++++++++++++++++++++++++++++++++++++--------
 diff.h          |    1 +
 3 files changed, 135 insertions(+), 23 deletions(-)

-- 
1.7.3.1.256.g2539c.dirty

^ 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