Git development
 help / color / mirror / Atom feed
* Re: obnoxious CLI complaints
From: Junio C Hamano @ 2009-09-11  0:37 UTC (permalink / raw)
  To: demerphq
  Cc: John Tapsell, Jakub Narebski, Wincent Colaiuta, Brendan Miller,
	git
In-Reply-To: <9b18b3110909101619n6904a75dm10dd0b5717fb0d76@mail.gmail.com>

demerphq <demerphq@gmail.com> writes:

> 2009/9/11 Junio C Hamano <gitster@pobox.com>:
>> John Tapsell <johnflux@gmail.com> writes:
>>
>>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>>> Dnia czwartek 10. września 2009 21:46, John Tapsell napisał:
>>>>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>>>
>>>>> > First, it would be consistent with how ordinary archivers such as tar
>>>>> > or zip are used, where you have to specify list of files to archive
>>>>> > (in our case this list is HEAD).  Second, I'd rather not accidentally
>>>>> > dump binary to terminal: "git archive [HEAD]" dumps archive to standard
>>>>> > output.
>>>>>
>>>>> That could be fixed by outputting to a file.  git format-patch outputs
>>>>> to a file, so why wouldn't git achieve?
>>>>
>>>> "git format-patch" outputs to files because it generates _multiple_
>>>> files; generating single patch is special case.  Also git-format-patch
>>>> can generate file names from patch (commit) subject; it is not the case
>>>> for "git archive" (what name should it use?).
>>>
>>> What if it used the current (or topleve) directory name?  Wouldn't
>>> that work in most cases?
>>
>> Following along the same line of reasoning, it would work in most cases if
>> the output is literally named "archive.tar".  If it is not the name the
>> user wants, the user can "mv" afterwards, or give an explicit filename.
>
> Why not $sha1.tar?

Why not $(basename $(dirname $(pwd)))-$(date).tar instead?

See?  archive.tar is as good a compromise (so is a.out from cc).

> Is it portable to assume that piping is always in binmode? From a
> portability POV i could imagine piping being a problem in this
> respect, and might be why tar provides a way to output to a file and
> not just to a handle. For example ISTR that on windows piping is by
> default in text mode. I think its not a showstopper there as you can
> change it, but still, from a portability point of view you might not
> want to depend on piping.

Windows is not a showstopper to me ;-).

But seriously, I am glad that you brought up about a potential issue with
pipe.  There is one fairly important reason that it is better to say

	GZIP=-9 tar zcf here.tar.gz .

than to say

	tar cf - . | gzip -9 >here.tar.gz

but it has nothing to do with binmode.  The reason is error detection.

For exactly the same reason, if we can say

	git archive -9 --output-file=here.tar.gz HEAD

it is much better than having to say

	git archive HEAD | gzip -9 >here.tar.gz

In other words, I am not opposed to supporting a "--output-file here.tar"
at all.  I just do not want it to be mandatory.  I think that it is an
ugly kludge to force people to work it around with "-f /dev/stdout".

Oh wait.

That is exactly what we have, so what's the point of continuing this
discussion any further?  Can we just _really_ stop this time, please?

^ permalink raw reply

* [PATCH v2] add documentation for mailinfo.scissors and '--no-scissors'
From: Nicolas Sebrecht @ 2009-09-11  0:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git, Nicolas Sebrecht
In-Reply-To: <33445216edc4c4e1976cdd81521922042955e6eb.1252626034.git.nicolas.s.dev@gmx.fr>

Signed-off-by: Nicolas Sebrecht <nicolas.s.dev@gmx.fr>
---

I've missed the documentation of --no-scissors in git-am.txt in the previous
round (second hunks here).

Sorry for inconvenience.

 Documentation/git-am.txt       |    5 ++++-
 Documentation/git-mailinfo.txt |    6 ++++++
 builtin-mailinfo.c             |    2 +-
 git-am.sh                      |    1 +
 4 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index 87781f4..14ae3a5 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -13,7 +13,7 @@ SYNOPSIS
 	 [--3way] [--interactive] [--committer-date-is-author-date]
 	 [--ignore-date] [--ignore-space-change | --ignore-whitespace]
 	 [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
-	 [--reject] [-q | --quiet] [--scissors]
+	 [--reject] [-q | --quiet] [--scissors | --no-scissors]
 	 [<mbox> | <Maildir>...]
 'git am' (--skip | --resolved | --abort)
 
@@ -44,6 +44,9 @@ OPTIONS
 	Remove everything in body before a scissors line (see
 	linkgit:git-mailinfo[1]).
 
+---no-scissors::
+	Do not obey to a scissors line (see linkgit:git-mailinfo[1]).
+
 -q::
 --quiet::
 	Be quiet. Only print error messages.
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index 823ab82..55b8c5e 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -62,6 +62,12 @@ This is useful if you want to begin your message in a discussion thread
 with comments and suggestions on the message you are responding to, and to
 conclude it with a patch submission, separating the discussion and the
 beginning of the proposed commit log message with a scissors line.
++
+This can enabled by default with the configuration option mailinfo.scissors.
+
+--no-scissors::
+	Do not obey to a scissors line. This is only useful if mailinfo.scissors is
+	enabled (see --scissors).
 
 <msg>::
 	The commit log message extracted from e-mail, usually
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 7d22fd7..d498b1c 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -1004,7 +1004,7 @@ static int git_mailinfo_config(const char *var, const char *value, void *unused)
 }
 
 static const char mailinfo_usage[] =
-	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] [--scissors] msg patch < mail >info";
+	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] [--scissors | --no-scissors] msg patch < mail >info";
 
 int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
diff --git a/git-am.sh b/git-am.sh
index 26ffe70..f242d1a 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -16,6 +16,7 @@ s,signoff       add a Signed-off-by line to the commit message
 u,utf8          recode into utf8 (default)
 k,keep          pass -k flag to git-mailinfo
 c,scissors      strip everything before a scissors line
+no-scissors     don't obey to a scissors line (default)
 whitespace=     pass it through git-apply
 ignore-space-change pass it through git-apply
 ignore-whitespace pass it through git-apply
-- 
1.6.5.rc0.168.gdcd6e

^ permalink raw reply related

* Re: obnoxious CLI complaints
From: Junio C Hamano @ 2009-09-11  0:25 UTC (permalink / raw)
  To: John Tapsell; +Cc: Jakub Narebski, Wincent Colaiuta, Brendan Miller, git
In-Reply-To: <43d8ce650909101718j2f1f77cbgc347ee755145353f@mail.gmail.com>

John Tapsell <johnflux@gmail.com> writes:

>>        git archive >my.file.tar
>
> I thought you didn't like this because then you dump binary to the
> console by default ?

No. That objection came from Jakub and I said it did not make sense to me.

> Why would it be so bad to do:
>
> git archive -f - | down stream commands

Are you seriously asking "why" after I said this?

>> and people who want to pipe (which is 99% of the use pattern for me) can
>> say

If you really need it to be spelled out,...

Because I have to say "-f -" 99% of the time without no good reason.

^ permalink raw reply

* Re: obnoxious CLI complaints
From: John Tapsell @ 2009-09-11  0:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jakub Narebski, Wincent Colaiuta, Brendan Miller, git
In-Reply-To: <7v4ora76vr.fsf@alter.siamese.dyndns.org>

2009/9/11 Junio C Hamano <gitster@pobox.com>:
> John Tapsell <johnflux@gmail.com> writes:
>
>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>> Dnia czwartek 10. września 2009 21:46, John Tapsell napisał:
>>>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>>
>>>> > First, it would be consistent with how ordinary archivers such as tar
>>>> > or zip are used, where you have to specify list of files to archive
>>>> > (in our case this list is HEAD).  Second, I'd rather not accidentally
>>>> > dump binary to terminal: "git archive [HEAD]" dumps archive to standard
>>>> > output.
>>>>
>>>> That could be fixed by outputting to a file.  git format-patch outputs
>>>> to a file, so why wouldn't git achieve?
>>>
>>> "git format-patch" outputs to files because it generates _multiple_
>>> files; generating single patch is special case.  Also git-format-patch
>>> can generate file names from patch (commit) subject; it is not the case
>>> for "git archive" (what name should it use?).
>>
>> What if it used the current (or topleve) directory name?  Wouldn't
>> that work in most cases?
>
> Following along the same line of reasoning, it would work in most cases if
> the output is literally named "archive.tar".  If it is not the name the
> user wants, the user can "mv" afterwards, or give an explicit filename.

That would also work.  Like how gcc uses "a.out" as the default filename


> What it does _not_ allow is to send the output to a downstream command for
> postprocessing without introducing some magic token to say "standard
> output" (e.g. "git archive -f - | (cd ../foo && tar xf -)").

Right, so what's wrong with the magic token?  There's plenty of precedence.


> If the default is to write to the standard output, we won't have all of
> these issues.

These are issues?

>  People who want a file can name the file by
>
>        git archive >my.file.tar

I thought you didn't like this because then you dump binary to the
console by default ?

> and people who want to pipe (which is 99% of the use pattern for me) can
> say
>
>        git archive | down stream commands.

Why would it be so bad to do:

git archive -f - | down stream commands

?

This is the most logical way forward.  It keeps the command simple for
simple use cases (make an archive - "git archive")  but easily
scalable for more complex use cases (add a  "-f -" if you want to do
magical things)

John

^ permalink raw reply

* [PATCH 2/2] add documentation for mailinfo.scissors and '--no-scissors'
From: Nicolas Sebrecht @ 2009-09-11  0:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git, Nicolas Sebrecht
In-Reply-To: <682ef47420f36d8c53e42981370d377b621d7b86.1252626034.git.nicolas.s.dev@gmx.fr>

Signed-off-by: Nicolas Sebrecht <nicolas.s.dev@gmx.fr>
---
 Documentation/git-am.txt       |    2 +-
 Documentation/git-mailinfo.txt |    6 ++++++
 builtin-mailinfo.c             |    2 +-
 git-am.sh                      |    1 +
 4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index 87781f4..8b2897b 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -13,7 +13,7 @@ SYNOPSIS
 	 [--3way] [--interactive] [--committer-date-is-author-date]
 	 [--ignore-date] [--ignore-space-change | --ignore-whitespace]
 	 [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
-	 [--reject] [-q | --quiet] [--scissors]
+	 [--reject] [-q | --quiet] [--scissors | --no-scissors]
 	 [<mbox> | <Maildir>...]
 'git am' (--skip | --resolved | --abort)
 
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index 823ab82..55b8c5e 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -62,6 +62,12 @@ This is useful if you want to begin your message in a discussion thread
 with comments and suggestions on the message you are responding to, and to
 conclude it with a patch submission, separating the discussion and the
 beginning of the proposed commit log message with a scissors line.
++
+This can enabled by default with the configuration option mailinfo.scissors.
+
+--no-scissors::
+	Do not obey to a scissors line. This is only useful if mailinfo.scissors is
+	enabled (see --scissors).
 
 <msg>::
 	The commit log message extracted from e-mail, usually
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 7d22fd7..d498b1c 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -1004,7 +1004,7 @@ static int git_mailinfo_config(const char *var, const char *value, void *unused)
 }
 
 static const char mailinfo_usage[] =
-	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] [--scissors] msg patch < mail >info";
+	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] [--scissors | --no-scissors] msg patch < mail >info";
 
 int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
diff --git a/git-am.sh b/git-am.sh
index 26ffe70..f242d1a 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -16,6 +16,7 @@ s,signoff       add a Signed-off-by line to the commit message
 u,utf8          recode into utf8 (default)
 k,keep          pass -k flag to git-mailinfo
 c,scissors      strip everything before a scissors line
+no-scissors     don't obey to a scissors line (default)
 whitespace=     pass it through git-apply
 ignore-space-change pass it through git-apply
 ignore-whitespace pass it through git-apply
-- 
1.6.5.rc0.164.g5f6b0

^ permalink raw reply related

* [PATCH 1/2] mailinfo: add '--scissors' to usage message
From: Nicolas Sebrecht @ 2009-09-11  0:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git, Nicolas Sebrecht
In-Reply-To: <7vtyzexnhm.fsf@alter.siamese.dyndns.org>

Signed-off-by: Nicolas Sebrecht <nicolas.s.dev@gmx.fr>
---
 builtin-mailinfo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 03cbcad..7d22fd7 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -1004,7 +1004,7 @@ static int git_mailinfo_config(const char *var, const char *value, void *unused)
 }
 
 static const char mailinfo_usage[] =
-	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] msg patch <mail >info";
+	"git mailinfo [-k] [-u | --encoding=<encoding> | -n] [--scissors] msg patch < mail >info";
 
 int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
-- 
1.6.5.rc0.164.g5f6b0

^ permalink raw reply related

* scissors definition and documentation
From: Nicolas Sebrecht @ 2009-09-11  0:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git
In-Reply-To: <7vtyzexnhm.fsf@alter.siamese.dyndns.org>

The 07/09/09, Junio C Hamano wrote:
> 
> * jc/mailinfo-scissors (2009-08-26) 5 commits
>   (merged to 'next' on 2009-08-30 at 5fc6248)
>  + mailinfo.scissors: new configuration
>  + am/mailinfo: Disable scissors processing by default
>  + Documentation: describe the scissors mark support of "git am"
>  + Teach mailinfo to ignore everything before -- >8 -- mark
>  + builtin-mailinfo.c: fix confusing internal API to mailinfo()
> 
> I didn't pick up the patch to simplify the definition of scissors. I do
> not have strong opinion on it either way, and nobody on the list seemed to
> care too much either.

Since --scissors is an option instead of the default behaviour, I believe that
the definition of scissors is much less critical.

The following two patches is only about documentation.

The last patch mixes documentation of both mailinfo.scissors and --no--scissors
because I think they are very tied from the user POV.

 [PATCH 1/2] mailinfo: add '--scissors' to usage message
 [PATCH 2/2] add documentation for mailinfo.scissors and '--no-scissors'

---
 Documentation/git-am.txt       |    2 +-
 Documentation/git-mailinfo.txt |    6 ++++++
 builtin-mailinfo.c             |    2 +-
 git-am.sh                      |    1 +
 4 files changed, 9 insertions(+), 2 deletions(-)

^ permalink raw reply

* Re: [PATCH 3/4] reset: add option "--merge-dirty" to "git reset"
From: Linus Torvalds @ 2009-09-10 23:24 UTC (permalink / raw)
  To: Christian Couder
  Cc: Junio C Hamano, git, Johannes Schindelin, Stephan Beyer,
	Daniel Barkalow, Jakub Narebski
In-Reply-To: <20090910202333.3722.37592.chriscool@tuxfamily.org>



On Thu, 10 Sep 2009, Christian Couder wrote:
> 
> In fact with "--merge-dirty", changes that are both in
> the work tree and the index are kept in the work tree
> after the reset (but discarded in the index). As with
> "--merge", changes that are in both the work tree and
> the index are discarded after the reset.

Can you explain that again? That paragraph makes no sense, because it 
boils down to saying two different thing for "changes that are in both the 
work tree and the index". First it says such changes are kept in the work 
tree (but discarded in the index), and then it says that the changes are 
discarded.

Which seems very odd.

Or are my reading comprehension skills lacking?

The patch also seems to imply that it's always about HEAD. True?

		Linus

^ permalink raw reply

* Re: obnoxious CLI complaints
From: demerphq @ 2009-09-10 23:19 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: John Tapsell, Jakub Narebski, Wincent Colaiuta, Brendan Miller,
	git
In-Reply-To: <7v4ora76vr.fsf@alter.siamese.dyndns.org>

2009/9/11 Junio C Hamano <gitster@pobox.com>:
> John Tapsell <johnflux@gmail.com> writes:
>
>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>> Dnia czwartek 10. września 2009 21:46, John Tapsell napisał:
>>>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>>
>>>> > First, it would be consistent with how ordinary archivers such as tar
>>>> > or zip are used, where you have to specify list of files to archive
>>>> > (in our case this list is HEAD).  Second, I'd rather not accidentally
>>>> > dump binary to terminal: "git archive [HEAD]" dumps archive to standard
>>>> > output.
>>>>
>>>> That could be fixed by outputting to a file.  git format-patch outputs
>>>> to a file, so why wouldn't git achieve?
>>>
>>> "git format-patch" outputs to files because it generates _multiple_
>>> files; generating single patch is special case.  Also git-format-patch
>>> can generate file names from patch (commit) subject; it is not the case
>>> for "git archive" (what name should it use?).
>>
>> What if it used the current (or topleve) directory name?  Wouldn't
>> that work in most cases?
>
> Following along the same line of reasoning, it would work in most cases if
> the output is literally named "archive.tar".  If it is not the name the
> user wants, the user can "mv" afterwards, or give an explicit filename.

Why not $sha1.tar?

> What it does _not_ allow is to send the output to a downstream command for
> postprocessing without introducing some magic token to say "standard
> output" (e.g. "git archive -f - | (cd ../foo && tar xf -)").
>
> If the default is to write to the standard output, we won't have all of
> these issues.  People who want a file can name the file by
>
>        git archive >my.file.tar
>
> and people who want to pipe (which is 99% of the use pattern for me) can
> say
>
>        git archive | down stream commands.
>
> Oh, wait.
>
> That is exactly what we have, so what's the point of continuing this
> discussion any further?  Can we just stop?

Is it portable to assume that piping is always in binmode? From a
portability POV i could imagine piping being a problem in this
respect, and might be why tar provides a way to output to a file and
not just to a handle. For example ISTR that on windows piping is by
default in text mode. I think its not a showstopper there as you can
change it, but still, from a portability point of view you might not
want to depend on piping.

cheers,
Yves


-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

^ permalink raw reply

* Re: obnoxious CLI complaints
From: Junio C Hamano @ 2009-09-10 22:49 UTC (permalink / raw)
  To: John Tapsell; +Cc: Jakub Narebski, Wincent Colaiuta, Brendan Miller, git
In-Reply-To: <43d8ce650909101504q32448cb9w562a43969d01b1fe@mail.gmail.com>

John Tapsell <johnflux@gmail.com> writes:

> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>> Dnia czwartek 10. września 2009 21:46, John Tapsell napisał:
>>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>>
>>> > First, it would be consistent with how ordinary archivers such as tar
>>> > or zip are used, where you have to specify list of files to archive
>>> > (in our case this list is HEAD).  Second, I'd rather not accidentally
>>> > dump binary to terminal: "git archive [HEAD]" dumps archive to standard
>>> > output.
>>>
>>> That could be fixed by outputting to a file.  git format-patch outputs
>>> to a file, so why wouldn't git achieve?
>>
>> "git format-patch" outputs to files because it generates _multiple_
>> files; generating single patch is special case.  Also git-format-patch
>> can generate file names from patch (commit) subject; it is not the case
>> for "git archive" (what name should it use?).
>
> What if it used the current (or topleve) directory name?  Wouldn't
> that work in most cases?

Following along the same line of reasoning, it would work in most cases if
the output is literally named "archive.tar".  If it is not the name the
user wants, the user can "mv" afterwards, or give an explicit filename.

What it does _not_ allow is to send the output to a downstream command for
postprocessing without introducing some magic token to say "standard
output" (e.g. "git archive -f - | (cd ../foo && tar xf -)").

If the default is to write to the standard output, we won't have all of
these issues.  People who want a file can name the file by

	git archive >my.file.tar

and people who want to pipe (which is 99% of the use pattern for me) can
say

	git archive | down stream commands.

Oh, wait.

That is exactly what we have, so what's the point of continuing this
discussion any further?  Can we just stop?

^ permalink raw reply

* Cannot clone redirecting stdout
From: Aloisio @ 2009-09-10 22:33 UTC (permalink / raw)
  To: git

Hi all,

I faced a problem when trying to clone git://gitorious.org/qt/qt.git

this works:
git clone -n git://gitorious.org/qt/qt.git repo

this doesn't:
git clone -n git://gitorious.org/qt/qt.git repo >log
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

I reproduced the error in the following versions:
git version 1.6.0.4
git version 1.6.4.2
git version 1.5.4.7

Any clues?
Thanks

Aloisio Almeida

^ permalink raw reply

* Re: obnoxious CLI complaints
From: René Scharfe @ 2009-09-10 22:19 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Brendan Miller, git
In-Reply-To: <200909101116.55098.jnareb@gmail.com>

Jakub Narebski schrieb:
> [...] Second, compression is better left to separate program, but
> I guess we can follow GNU tar example and add equivalents of -Z/-z/-j
> and --use-compress-program options when using --output=<file>. [...]

Compression only makes sense for the tar format, so I think it's better
exposed by new formats and not by generic options.

For compress and bzip2 we'd need to call the external archiver, similar
to a pager.  Interesting idea.

For gzip, we can use the zlib helper functions, since we're linking
against it anyway.  I mention this because the following patch has been
laying around here for a while, collecting dust because it was a feature
waiting for a requester.

Using zlib directly avoids the overhead of a pipe and of buffering the
output for blocked writes; surprisingly (to me), it isn't any faster.
I didn't make any tuning efforts, yet, though.  Anyway, here it is:

---
 Documentation/git-archive.txt |    2 +-
 archive-tar.c                 |   76 ++++++++++++++++++++++++++++++++++++----
 archive.c                     |   43 ++++++++++++++++++++++-
 archive.h                     |    1 +
 t/t5000-tar-tree.sh           |   30 ++++++++++++++++
 5 files changed, 141 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 92444dd..2935246 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -34,7 +34,7 @@ OPTIONS
 -------
 
 --format=<fmt>::
-	Format of the resulting archive: 'tar' or 'zip'.  The default
+	Format of the resulting archive: 'tar', 'tar.gz' or 'zip'.  The default
 	is 'tar'.
 
 -l::
diff --git a/archive-tar.c b/archive-tar.c
index cee06ce..f22304d 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -58,18 +58,78 @@ static void write_blocked(const void *data, unsigned long size)
 	write_if_needed();
 }
 
+static void gzwrite_or_die(gzFile *gzfile, const void *buf, size_t count)
+{
+	const int chunk = 1 << 30; /* Big arbitrary value that fits into int. */
+	const char *p = buf;
+
+	while (count > 0) {
+		unsigned int to_write = (count < chunk) ? count : chunk;
+		int written = gzwrite(gzfile, p, to_write);
+		if (written <= 0) {
+			int err;
+			const char *msg = gzerror(gzfile, &err);
+			if (err != Z_ERRNO)
+				die("zlib error: %s", msg);
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			if (errno == EPIPE)
+				exit(0);
+			die_errno("write error");
+		}
+		count -= written;
+		p += written;
+	}
+}
+
+/*
+ * Writes directly through zlib and pads with NUL bytes to multiples of
+ * RECORDSIZE.  Updates offset because the length of the trailer depends
+ * on it.
+ */
+static void write_to_tgz(struct archiver_args *args, const void *data,
+			 unsigned long size)
+{
+	unsigned long tail = size % RECORDSIZE;
+	gzwrite_or_die(args->gzfile, data, size);
+	if (tail) {
+		tail = RECORDSIZE - tail;
+		if (gzseek(args->gzfile, tail, SEEK_CUR) == -1)
+			die("zlib error while seeking.");
+	}
+	offset = (offset + size + tail) % BLOCKSIZE;
+}
+
+static void write_to_archive(struct archiver_args *args, const void *data,
+			     unsigned long size)
+{
+	if (args->gzfile)
+		write_to_tgz(args, data, size);
+	else
+		write_blocked(data, size);
+}
+
 /*
  * The end of tar archives is marked by 2*512 nul bytes and after that
  * follows the rest of the block (if any).
  */
-static void write_trailer(void)
+static void write_trailer(struct archiver_args *args)
 {
 	int tail = BLOCKSIZE - offset;
-	memset(block + offset, 0, tail);
-	write_or_die(1, block, BLOCKSIZE);
-	if (tail < 2 * RECORDSIZE) {
-		memset(block, 0, offset);
+	if (args->gzfile) {
+		if (tail < 2 * RECORDSIZE)
+			tail += BLOCKSIZE;
+		if (gzseek(args->gzfile, tail - 1, SEEK_CUR) == -1)
+			die("zlib error while seeking.");
+		if (gzputc(args->gzfile, '\0') == -1)
+			die("zlib error while writing a NUL byte.");
+	} else {
+		memset(block + offset, 0, tail);
 		write_or_die(1, block, BLOCKSIZE);
+		if (tail < 2 * RECORDSIZE) {
+			memset(block, 0, offset);
+			write_or_die(1, block, BLOCKSIZE);
+		}
 	}
 }
 
@@ -201,9 +261,9 @@ static int write_tar_entry(struct archiver_args *args,
 			return err;
 	}
 	strbuf_release(&ext_header);
-	write_blocked(&header, sizeof(header));
+	write_to_archive(args, &header, sizeof(header));
 	if (S_ISREG(mode) && buffer && size > 0)
-		write_blocked(buffer, size);
+		write_to_archive(args, buffer, size);
 	return err;
 }
 
@@ -245,6 +305,6 @@ int write_tar_archive(struct archiver_args *args)
 	if (!err)
 		err = write_archive_entries(args, write_tar_entry);
 	if (!err)
-		write_trailer();
+		write_trailer(args);
 	return err;
 }
diff --git a/archive.c b/archive.c
index 0bca9ca..8809f51 100644
--- a/archive.c
+++ b/archive.c
@@ -15,6 +15,8 @@ static char const * const archive_usage[] = {
 };
 
 #define USES_ZLIB_COMPRESSION 1
+#define USES_GZIP_COMPRESSION 2
+#define USES_COMPRESSION (USES_ZLIB_COMPRESSION | USES_GZIP_COMPRESSION)
 
 static const struct archiver {
 	const char *name;
@@ -22,6 +24,7 @@ static const struct archiver {
 	unsigned int flags;
 } archivers[] = {
 	{ "tar", write_tar_archive },
+	{ "tar.gz", write_tar_archive, USES_GZIP_COMPRESSION },
 	{ "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
 };
 
@@ -336,7 +339,7 @@ static int parse_archive_args(int argc, const char **argv,
 
 	args->compression_level = Z_DEFAULT_COMPRESSION;
 	if (compression_level != -1) {
-		if ((*ar)->flags & USES_ZLIB_COMPRESSION)
+		if ((*ar)->flags & USES_COMPRESSION)
 			args->compression_level = compression_level;
 		else {
 			die("Argument not supported for format '%s': -%d",
@@ -351,11 +354,38 @@ static int parse_archive_args(int argc, const char **argv,
 	return argc;
 }
 
+static void archive_gzfile_open(struct archiver_args *args)
+{
+	char mode[] = "wbX";
+	if (args->compression_level == Z_DEFAULT_COMPRESSION)
+		mode[2] = '\0';
+	else
+		mode[2] = '0' + args->compression_level;
+	args->gzfile = gzdopen(xdup(1), mode);
+	if (!args->gzfile)
+		die("zlib error: out of memory.");
+}
+
+static void archive_gzfile_close(struct archiver_args *args)
+{
+	int err = gzclose(args->gzfile);
+	switch (err) {
+	case Z_OK:
+		break;
+	case Z_ERRNO:
+		die_errno("zlib error");
+	default:
+		die("zlib error %d while closing.", err);
+	}
+	args->gzfile = NULL;
+}
+
 int write_archive(int argc, const char **argv, const char *prefix,
 		int setup_prefix)
 {
 	const struct archiver *ar = NULL;
 	struct archiver_args args;
+	int err;
 
 	argc = parse_archive_args(argc, argv, &ar, &args);
 	if (setup_prefix && prefix == NULL)
@@ -366,5 +396,14 @@ int write_archive(int argc, const char **argv, const char *prefix,
 
 	git_config(git_default_config, NULL);
 
-	return ar->write_archive(&args);
+	args.gzfile = NULL;
+	if (ar->flags & USES_GZIP_COMPRESSION)
+		archive_gzfile_open(&args);
+
+	err = ar->write_archive(&args);
+
+	if (!err && (ar->flags & USES_GZIP_COMPRESSION))
+		archive_gzfile_close(&args);
+
+	return err;
 }
diff --git a/archive.h b/archive.h
index 038ac35..638a7ba 100644
--- a/archive.h
+++ b/archive.h
@@ -12,6 +12,7 @@ struct archiver_args {
 	unsigned int verbose : 1;
 	unsigned int worktree_attributes : 1;
 	int compression_level;
+	gzFile gzfile;
 };
 
 typedef int (*write_archive_fn_t)(struct archiver_args *);
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 5f84b18..4094c18 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -26,6 +26,8 @@ commit id embedding:
 
 . ./test-lib.sh
 UNZIP=${UNZIP:-unzip}
+GZIP=${GZIP:-gzip}
+GUNZIP=${GUNZIP:-$GZIP -d}
 
 SUBSTFORMAT=%H%n
 
@@ -79,6 +81,15 @@ test_expect_success \
     'git tar-tree HEAD >b2.tar'
 
 test_expect_success \
+    'git archive --format=tar.gz' \
+    'git archive --format=tar.gz HEAD >bz.tar.gz'
+
+test_expect_success \
+    'git archive --format=tar.gz with --output' \
+    'git archive --format=tar.gz --output=bz1.tar.gz HEAD &&
+     test_cmp bz.tar.gz bz1.tar.gz'
+
+test_expect_success \
     'git archive vs. git tar-tree' \
     'test_cmp b.tar b2.tar'
 
@@ -146,7 +157,9 @@ test_expect_success \
     'cp .git/info/attributes .git/info/attributes.before &&
      echo "substfile?" export-subst >>.git/info/attributes &&
      git archive HEAD >f.tar &&
+     git archive --format=tar.gz HEAD >fz.tar.gz &&
      git archive --prefix=prefix/ HEAD >g.tar &&
+     git archive --format=tar.gz --prefix=prefix/ HEAD >gz.tar.gz &&
      mv .git/info/attributes.before .git/info/attributes'
 
 test_expect_success \
@@ -173,6 +186,23 @@ test_expect_success \
       test_cmp a/substfile2 g/prefix/a/substfile2
 '
 
+$GUNZIP -h >/dev/null 2>&1
+if [ $? -eq 127 ]; then
+	echo "Skipping tar.gz expansion tests, because gunzip was not found"
+else
+	test_expect_success \
+		'expand *.tar.gz' \
+		'$GUNZIP bz.tar.gz &&
+		 $GUNZIP fz.tar.gz &&
+		 $GUNZIP gz.tar.gz'
+
+	test_expect_success \
+		'compare files created by formats tar and tar.gz' \
+		'test_cmp b.tar bz.tar &&
+		 test_cmp f.tar fz.tar &&
+		 test_cmp g.tar gz.tar'
+fi
+
 test_expect_success \
     'git archive --format=zip' \
     'git archive --format=zip HEAD >d.zip'
-- 
1.6.5.rc0

^ permalink raw reply related

* Re: obnoxious CLI complaints
From: René Scharfe @ 2009-09-10 22:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jakub Narebski, Wincent Colaiuta, Brendan Miller, git
In-Reply-To: <7vbpliaaxo.fsf@alter.siamese.dyndns.org>

Junio C Hamano schrieb:
> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> First, it would be consistent with how ordinary archivers such as tar
>> or zip are used, where you have to specify list of files to archive
>> (in our case this list is HEAD).  Second, I'd rather not accidentally
>> dump binary to terminal: "git archive [HEAD]" dumps archive to standard
>> output.
> 
> So does "cat".  I do not agree with your second point.
> 
> While I somewhat see the similarity argument, your first point, I am not
> sure if it is relevant.  It is not like "tar or zip allows us to say what
> files to archive, but git-archive doesn't and it always archives HEAD";
> you are saying "they require us to specify, so should we".
> 
> But I do not see a strong reason not to default to HEAD.  The case that
> would make difference would be to differentiate among
> 
> 	$ git archive HEAD TAIL
>         $ git archive HEAD -- TAIL
>         $ git archive -- HEAD TAIL
> 
> i.e. what if you happen to have a tracked content called HEAD.  I didn't
> check the current command line parser in git-archive understands the "--"
> convention for that, but it is not a rocket science to add it if it
> doesn't.

Currently it doesn't.  An attempt to implement it is below (tests and
documentation update missing).

I wonder if we want to make treeless calls to archive the worktree (or the
index) instead of HEAD, similar to git grep, though.  Not that I remember
someone requesting such a thing, but I'm already slightly surprised about
archive being used to tar up HEAD in any case -- I imagined it would mostly
be used to make releases of tagged versions.

---
 archive.c |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/archive.c b/archive.c
index 0bca9ca..04fa6a5 100644
--- a/archive.c
+++ b/archive.c
@@ -214,18 +214,32 @@ static void parse_pathspec_arg(const char **pathspec,
 	ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
 }
 
-static void parse_treeish_arg(const char **argv,
-		struct archiver_args *ar_args, const char *prefix)
+static int parse_treeish_arg(int argc, const char **argv,
+			     struct archiver_args *ar_args, const char *prefix)
 {
-	const char *name = argv[0];
+	const char *name = "HEAD";
 	const unsigned char *commit_sha1;
 	time_t archive_time;
 	struct tree *tree;
 	const struct commit *commit;
 	unsigned char sha1[20];
 
+	if (argc > 0) {
+		int consume = 1;
+
+		if (strcmp(argv[0], "--")) {
+			name = argv[0];
+			if (argc > 1 && !strcmp(argv[1], "--"))
+				consume++;
+		}
+
+		argc -= consume;
+		memmove(argv, argv + consume, argc * sizeof(*argv));
+		argv[argc] = NULL;
+	}
+
 	if (get_sha1(name, sha1))
-		die("Not a valid object name");
+		die("Not a valid object name: %s", name);
 
 	commit = lookup_commit_reference_gently(sha1, 1);
 	if (commit) {
@@ -256,6 +270,8 @@ static void parse_treeish_arg(const char **argv,
 	ar_args->commit_sha1 = commit_sha1;
 	ar_args->commit = commit;
 	ar_args->time = archive_time;
+
+	return argc;
 }
 
 #define OPT__COMPR(s, v, h, p) \
@@ -309,7 +325,8 @@ static int parse_archive_args(int argc, const char **argv,
 		OPT_END()
 	};
 
-	argc = parse_options(argc, argv, NULL, opts, archive_usage, 0);
+	argc = parse_options(argc, argv, NULL, opts, archive_usage,
+			     PARSE_OPT_KEEP_DASHDASH);
 
 	if (remote)
 		die("Unexpected option --remote");
@@ -327,9 +344,6 @@ static int parse_archive_args(int argc, const char **argv,
 		exit(0);
 	}
 
-	/* We need at least one parameter -- tree-ish */
-	if (argc < 1)
-		usage_with_options(archive_usage, opts);
 	*ar = lookup_archiver(format);
 	if (!*ar)
 		die("Unknown archive format '%s'", format);
@@ -361,8 +375,8 @@ int write_archive(int argc, const char **argv, const char *prefix,
 	if (setup_prefix && prefix == NULL)
 		prefix = setup_git_directory();
 
-	parse_treeish_arg(argv, &args, prefix);
-	parse_pathspec_arg(argv + 1, &args);
+	argc = parse_treeish_arg(argc, argv, &args, prefix);
+	parse_pathspec_arg(argv, &args);
 
 	git_config(git_default_config, NULL);
 
-- 
1.6.5.rc0

^ permalink raw reply related

* Re: [PATCH 4/4] reset: add test cases for "--merge-dirty" option
From: Daniel Barkalow @ 2009-09-10 22:14 UTC (permalink / raw)
  To: Christian Couder
  Cc: Junio C Hamano, git, Johannes Schindelin, Stephan Beyer,
	Jakub Narebski, Linus Torvalds
In-Reply-To: <20090910202333.3722.13214.chriscool@tuxfamily.org>

On Thu, 10 Sep 2009, Christian Couder wrote:

    This shows that with the "--merge-dirty" option, 

  changes that are both in the work tree and the index are kept

    in the work tree after the reset (but discarded in the index). As with 
    the "--merge" option, 

  changes that are in both the work tree and the index are discarded

    after the reset.

I'm lost here.

If you have:

         working index HEAD target
version     B      B     A     A

You get:

         working index HEAD target
--m-d       B      A     A     A
--merge     A      A     A     A

?

> ---
>  t/t7110-reset-merge.sh |   54 +++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 49 insertions(+), 5 deletions(-)
> 
> diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
> index 45714ae..1e6d634 100755
> --- a/t/t7110-reset-merge.sh
> +++ b/t/t7110-reset-merge.sh
> @@ -19,7 +19,7 @@ test_expect_success 'creating initial files' '
>       git commit -m "Initial commit"
>  '
>  
> -test_expect_success 'ok with changes in file not changed by reset' '
> +test_expect_success '--merge: ok if changes in file not touched by reset' '

Should probably have the "--merge: " from the beginning, since you're 
adding the test in this series anyway. That would make the diff come out 
clearer.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: obnoxious CLI complaints
From: John Tapsell @ 2009-09-10 22:04 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Wincent Colaiuta, Brendan Miller, git
In-Reply-To: <200909102223.31602.jnareb@gmail.com>

2009/9/10 Jakub Narebski <jnareb@gmail.com>:
> Dnia czwartek 10. września 2009 21:46, John Tapsell napisał:
>> 2009/9/10 Jakub Narebski <jnareb@gmail.com>:
>
>> > First, it would be consistent with how ordinary archivers such as tar
>> > or zip are used, where you have to specify list of files to archive
>> > (in our case this list is HEAD).  Second, I'd rather not accidentally
>> > dump binary to terminal: "git archive [HEAD]" dumps archive to standard
>> > output.
>>
>> That could be fixed by outputting to a file.  git format-patch outputs
>> to a file, so why wouldn't git achieve?
>
> "git format-patch" outputs to files because it generates _multiple_
> files; generating single patch is special case.  Also git-format-patch
> can generate file names from patch (commit) subject; it is not the case
> for "git archive" (what name should it use?).

What if it used the current (or topleve) directory name?  Wouldn't
that work in most cases?  For cases it doesn't work, the user can just
rename or specify the output name, so it would be no worse than the
current case.

John

^ permalink raw reply

* Re: [RFC/PATCH 1/2] gitweb: extend &git_get_head_hash to be &git_get_hash
From: Jakub Narebski @ 2009-09-10 21:49 UTC (permalink / raw)
  To: Mark Rada; +Cc: git, Junio C Hamano
In-Reply-To: <4AA96D9B.6090003@mailservices.uwaterloo.ca>

On Thu, 10 Sep 2009, Mark Rada wrote:

> gitweb: extend &git_get_head_hash to be &git_get_hash

Should be "extend git_get_head_hash to be git_get_hash", see below.

>
> This adds an optional second argument to the routine which lets the
> caller specify a treeish that can be translated to a hash id by
> rev-parse.

Minor nit: we use "tree-ish" not "treeish" in documentation.

> 
> To maintain some backwards compatability, the second argument is
> optional and it will default to `HEAD' if not specified.

Why 'some'?  It does maintain backward compatibility.

Also i am not sure about git_get_hash defaulting to "HEAD". Perhaps
it would be better to keep git_get_head_hash as warpper around 
git_get_hash?  Or perhaps it would be better to explicitly pass
"HEAD" as second parameter?

> 
> Signed-off-by: Mark Rada <marada@uwaterloo.ca>

It looks like a good idea, even if it doesn't make much sense as
a standalone patch.

> ---
>  gitweb/gitweb.perl |   31 ++++++++++++++++---------------
>  1 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 24b2193..d650188 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -1981,13 +1981,14 @@ sub quote_command {
>  		map { my $a = $_; $a =~ s/(['!])/'\\$1'/g; "'$a'" } @_ );
>  }
>  
> -# get HEAD ref of given project as hash
> -sub git_get_head_hash {
> +# get object id of given project as full hash, defaults to HEAD
> +sub git_get_hash {

I'm not sure about naming (not that git_get_head_hash was best), as
you don't see from git_get_hash subroutine name that the first parameter
is the name of repository (the git_get_head_hash at least hinted, if
very weekly, at it).

>  	my $project = shift;
> +	my $hash = shift || 'HEAD';
>  	my $o_git_dir = $git_dir;
>  	my $retval = undef;
>  	$git_dir = "$projectroot/$project";
> -	if (open my $fd, "-|", git_cmd(), "rev-parse", "--verify", "HEAD") {
> +	if (open my $fd, '-|', git_cmd(), 'rev-parse', '--verify', "$hash") {

Minor nit: we don't need to quote (stringify) single variable here; 
using 
  ..., '--verify', $hash)
would work as well.

>  		my $head = <$fd>;
>  		close $fd;
>  		if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) {
> @@ -4737,7 +4738,7 @@ sub git_summary {
>  }
>  
>  sub git_tag {
> -	my $head = git_get_head_hash($project);
> +	my $head = &git_get_hash($project);

One very rarely needs to use explicit "&" subroutine calling syntax;
I think only when you want to circumvent subroutine prototype (which
is different from function/procedure prototypes in other languages).
Current practice is to not use it.

Besides it it not used anywhere else in gitweb (consistency).

>  	git_header_html();
>  	git_print_page_nav('','', $head,undef,$head);
>  	my %tag = parse_tag($hash);
> @@ -4778,7 +4779,7 @@ sub git_blame {
>  
>  	# error checking
>  	die_error(400, "No file name given") unless $file_name;
> -	$hash_base ||= git_get_head_hash($project);
> +	$hash_base ||= &git_get_hash($project);

Same as above: use "git_get_hash($project)" or "git_get_hash($project, 'HEAD');"

>  	die_error(404, "Couldn't find base commit") unless $hash_base;
>  	my %co = parse_commit($hash_base)
>  		or die_error(404, "Commit not found");
> @@ -4911,7 +4912,7 @@ HTML
>  }
>  
>  sub git_tags {
> -	my $head = git_get_head_hash($project);
> +	my $head = &git_get_hash($project);

Same as above: use "git_get_hash($project)"

>  	git_header_html();
>  	git_print_page_nav('','', $head,undef,$head);
>  	git_print_header_div('summary', $project);
> @@ -4924,7 +4925,7 @@ sub git_tags {
>  }
>  
>  sub git_heads {
> -	my $head = git_get_head_hash($project);
> +	my $head = &git_get_hash($project);

Same as above: use "git_get_hash($project)"

>  	git_header_html();
>  	git_print_page_nav('','', $head,undef,$head);
>  	git_print_header_div('summary', $project);
> @@ -4942,7 +4943,7 @@ sub git_blob_plain {
>  
>  	if (!defined $hash) {
>  		if (defined $file_name) {
> -			my $base = $hash_base || git_get_head_hash($project);
> +			my $base = $hash_base || &git_get_hash($project);

Same as above: use "git_get_hash($project)"
[...]

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [RFC/PATCH 2/2] gitweb: check given hash before trying to create snapshot
From: Mark Rada @ 2009-09-10 21:20 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski, Junio C Hamano

This patch is dual purposed.

First, it makes things nicer in cases when you hand craft the snapshot
URL but make a typo (e.g. netx instead of next); you will now get an
error message instead of a broken tarball.

Second, any given treeish will always be translated to the full length,
unambiguous, hash id; this will be useful for things like creating
unique names for snapshot caches.

This patch includes test for t9501 to demonstrate the changed
functionality.

Signed-off-by: Mark Rada <marada@uwaterloo.ca>
---
 gitweb/gitweb.perl                       |    5 +++--
 t/t9501-gitweb-standalone-http-status.sh |   26 ++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index d650188..4ae960c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -5197,8 +5197,9 @@ sub git_snapshot {
 		die_error(403, "Unsupported snapshot format");
 	}
 
-	if (!defined $hash) {
-		$hash = &git_get_hash($project);
+	my $snapshot = &git_get_hash($project, $hash);
+	if (!$snapshot) {
+		die_error(400, "Not a valid hash id: $hash");
 	}
 
 	my $name = $project;
diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh
index d0ff21d..4f8f147 100644
--- a/t/t9501-gitweb-standalone-http-status.sh
+++ b/t/t9501-gitweb-standalone-http-status.sh
@@ -75,4 +75,30 @@ test_expect_success \
 test_debug 'cat gitweb.output'
 
 
+test_expect_success \
+	'snapshots: bad treeish id' \
+	'gitweb_run "p=.git;a=snapshot;h=frizzumFrazzum;sf=tgz" &&
+	grep "400 - Not a valid hash id:" gitweb.output'
+test_debug 'cat gitweb.output'
+
+test_expect_success \
+	'snapshots: good treeish id' \
+	'gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
+	grep "Status: 200 OK" gitweb.output'
+test_debug 'cat gitweb.output'
+
+test_expect_success \
+	'snapshots: good object id' \
+	'ID=`git rev-parse --verify HEAD` &&
+	gitweb_run "p=.git;a=snapshot;h=$ID;sf=tgz" &&
+	grep "Status: 200 OK" gitweb.output'
+test_debug 'cat gitweb.output'
+
+test_expect_success \
+	'snapshots: bad object id' \
+	'gitweb_run "p=.git;a=snapshot;h=abcdef01234;sf=tgz" &&
+	grep "400 - Not a valid hash id:" gitweb.output'
+test_debug 'cat gitweb.output'
+
+
 test_done
-- 
1.6.4.2

^ permalink raw reply related

* [RFC/PATCH 1/2] gitweb: extend &git_get_head_hash to be &git_get_hash
From: Mark Rada @ 2009-09-10 21:20 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski, Junio C Hamano

This adds an optional second argument to the routine which lets the
caller specify a treeish that can be translated to a hash id by
rev-parse.

To maintain some backwards compatability, the second argument is
optional and it will default to `HEAD' if not specified.

Signed-off-by: Mark Rada <marada@uwaterloo.ca>
---
 gitweb/gitweb.perl |   31 ++++++++++++++++---------------
 1 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 24b2193..d650188 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1981,13 +1981,14 @@ sub quote_command {
 		map { my $a = $_; $a =~ s/(['!])/'\\$1'/g; "'$a'" } @_ );
 }
 
-# get HEAD ref of given project as hash
-sub git_get_head_hash {
+# get object id of given project as full hash, defaults to HEAD
+sub git_get_hash {
 	my $project = shift;
+	my $hash = shift || 'HEAD';
 	my $o_git_dir = $git_dir;
 	my $retval = undef;
 	$git_dir = "$projectroot/$project";
-	if (open my $fd, "-|", git_cmd(), "rev-parse", "--verify", "HEAD") {
+	if (open my $fd, '-|', git_cmd(), 'rev-parse', '--verify', "$hash") {
 		my $head = <$fd>;
 		close $fd;
 		if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) {
@@ -4737,7 +4738,7 @@ sub git_summary {
 }
 
 sub git_tag {
-	my $head = git_get_head_hash($project);
+	my $head = &git_get_hash($project);
 	git_header_html();
 	git_print_page_nav('','', $head,undef,$head);
 	my %tag = parse_tag($hash);
@@ -4778,7 +4779,7 @@ sub git_blame {
 
 	# error checking
 	die_error(400, "No file name given") unless $file_name;
-	$hash_base ||= git_get_head_hash($project);
+	$hash_base ||= &git_get_hash($project);
 	die_error(404, "Couldn't find base commit") unless $hash_base;
 	my %co = parse_commit($hash_base)
 		or die_error(404, "Commit not found");
@@ -4911,7 +4912,7 @@ HTML
 }
 
 sub git_tags {
-	my $head = git_get_head_hash($project);
+	my $head = &git_get_hash($project);
 	git_header_html();
 	git_print_page_nav('','', $head,undef,$head);
 	git_print_header_div('summary', $project);
@@ -4924,7 +4925,7 @@ sub git_tags {
 }
 
 sub git_heads {
-	my $head = git_get_head_hash($project);
+	my $head = &git_get_hash($project);
 	git_header_html();
 	git_print_page_nav('','', $head,undef,$head);
 	git_print_header_div('summary', $project);
@@ -4942,7 +4943,7 @@ sub git_blob_plain {
 
 	if (!defined $hash) {
 		if (defined $file_name) {
-			my $base = $hash_base || git_get_head_hash($project);
+			my $base = $hash_base || &git_get_hash($project);
 			$hash = git_get_hash_by_path($base, $file_name, "blob")
 				or die_error(404, "Cannot find file");
 		} else {
@@ -4994,7 +4995,7 @@ sub git_blob {
 
 	if (!defined $hash) {
 		if (defined $file_name) {
-			my $base = $hash_base || git_get_head_hash($project);
+			my $base = $hash_base || &git_get_hash($project);
 			$hash = git_get_hash_by_path($base, $file_name, "blob")
 				or die_error(404, "Cannot find file");
 		} else {
@@ -5197,7 +5198,7 @@ sub git_snapshot {
 	}
 
 	if (!defined $hash) {
-		$hash = git_get_head_hash($project);
+		$hash = &git_get_hash($project);
 	}
 
 	my $name = $project;
@@ -5229,7 +5230,7 @@ sub git_snapshot {
 }
 
 sub git_log {
-	my $head = git_get_head_hash($project);
+	my $head = &git_get_hash($project);
 	if (!defined $hash) {
 		$hash = $head;
 	}
@@ -5833,7 +5834,7 @@ sub git_patches {
 
 sub git_history {
 	if (!defined $hash_base) {
-		$hash_base = git_get_head_hash($project);
+		$hash_base = &git_get_hash($project);
 	}
 	if (!defined $page) {
 		$page = 0;
@@ -5904,7 +5905,7 @@ sub git_search {
 		die_error(400, "Text field is empty");
 	}
 	if (!defined $hash) {
-		$hash = git_get_head_hash($project);
+		$hash = &git_get_hash($project);
 	}
 	my %co = parse_commit($hash);
 	if (!%co) {
@@ -6159,7 +6160,7 @@ EOT
 }
 
 sub git_shortlog {
-	my $head = git_get_head_hash($project);
+	my $head = &git_get_hash($project);
 	if (!defined $hash) {
 		$hash = $head;
 	}
@@ -6486,7 +6487,7 @@ XML
 
 	foreach my $pr (@list) {
 		my %proj = %$pr;
-		my $head = git_get_head_hash($proj{'path'});
+		my $head = &git_get_hash($proj{'path'});
 		if (!defined $head) {
 			next;
 		}
-- 
1.6.4.2

^ permalink raw reply related

* Re: [PATCH 1/4] reset: add a few tests for "git reset --merge"
From: Jakub Narebski @ 2009-09-10 20:59 UTC (permalink / raw)
  To: Christian Couder; +Cc: git, Stephan Beyer, Daniel Barkalow
In-Reply-To: <20090910202333.3722.45063.chriscool@tuxfamily.org>

Christian Couder wrote:

> diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
> new file mode 100755
> index 0000000..45714ae
> --- /dev/null
> +++ b/t/t7110-reset-merge.sh
> @@ -0,0 +1,70 @@
> +#!/bin/sh
> +#
> +# Copyright (c) 2009 Christian Couder
> +#
> +
> +test_description='Tests for "git reset --merge"'
> +
> +exec </dev/null

What does this do?

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [BUG] 'add -u' doesn't work from untracked subdir
From: Clemens Buchacher @ 2009-09-10 20:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, Jeff King, SZEDER Gbor, git
In-Reply-To: <7vmy527f0b.fsf@alter.siamese.dyndns.org>

On Thu, Sep 10, 2009 at 12:53:40PM -0700, Junio C Hamano wrote:

> If this were going to happen as a list concensus, I am very tempted to
> suggest that we at least _consider_ applying the same rule even to
> ls-files and ls-tree.  That would impact scripts, so we need to be extra
> careful, though.

I originally thought those commands should be consistent with plain "ls",
simply because of their name. However, ls-files is already inconsistent
because "ls-files <subdir>" lists files relative to the current directory,
as opposed to "ls <subdir>", which does so relative to <subdir>. And ls-tree
is even more different from "ls".

So I don't think users are tempted to associate those commands with the
behavior they are used from "ls". From that perspective it would therefore
be ok to traverse the entire tree by default. To me that seems perfectly
natural, especially for ls-tree.

In case of ls-files, I don't know. Its current behavior certainly did not
bother me so far. But the same arguments as for "add -u" apply if you think
of doing something like "git ls-files -u | cut -f2 | xargs git add", for
example.

I can't really speak for the impact on scripts. But that is certainly an
issue, more so than with "add -u" or "grep", which are more typically used
interactively.

> If we try to give a sensible default to make it easier for the user,
> perhaps we should also default to HEAD when the user did not specify which
> tree-ish to archive from.  This is a topic in a separate thread.

I don't see why not.

> *3* Command line pathspec of course should honor cwd as before.

No argument there.

Clemens

^ permalink raw reply

* [PATCH v3 3/3] INSTALL: Describe dependency knobs from Makefile
From: Brian Gernhardt @ 2009-09-10 20:28 UTC (permalink / raw)
  To: Git List; +Cc: Junio C Hamano
In-Reply-To: <7v7hw6aas8.fsf@alter.siamese.dyndns.org>

We said that some of our dependencies were optional, but didn't say
how to turn them off.  Add information for that and mention where to
save the options close to the top of the file.

Also, standardize on both using quotes for the names of the dependencies
and tabs for indentation of the list.

Signed-off-by: Brian Gernhardt <brian@gernhardtsoftware.com>
---
 INSTALL |   38 ++++++++++++++++++++++++--------------
 1 files changed, 24 insertions(+), 14 deletions(-)

 Junio C Hamano <gitster@pobox.com> wrote:

 > Sorry, but the description still speaks of options and does not say what
 > good they are.  Sent a wrong patch?

 Wrong patch?  Never.  A good git developer always makes sure he re-generated
 patch files before making a fool of himself on a public list.

 Ahem.

diff --git a/INSTALL b/INSTALL
index 7ab2580..be504c9 100644
--- a/INSTALL
+++ b/INSTALL
@@ -13,6 +13,10 @@ that uses $prefix, the built results have some paths encoded,
 which are derived from $prefix, so "make all; make prefix=/usr
 install" would not work.
 
+The beginning of the Makefile documents many variables that affect the way
+git is built.  You can override them either from the command line, or in a
+config.mak file.
+
 Alternatively you can use autoconf generated ./configure script to
 set up install paths (via config.mak.autogen), so you can write instead
 
@@ -48,7 +52,9 @@ Issues of note:
 	export GIT_EXEC_PATH PATH GITPERLLIB
 
  - Git is reasonably self-sufficient, but does depend on a few external
-   programs and libraries:
+   programs and libraries.  Git can be used without most of them by adding
+   the approriate "NO_<LIBRARY>=YesPlease" to the make command line or
+   config.mak file.
 
 	- "zlib", the compression library. Git won't build without it.
 
@@ -59,25 +65,29 @@ Issues of note:
 
 	- "Perl" is needed to use some of the features (e.g. preparing a
 	  partial commit using "git add -i/-p", interacting with svn
-	  repositories with "git svn").
+	  repositories with "git svn").  If you can live without these, use
+	  NO_PERL.
 
-	- "openssl".  Unless you specify otherwise, you'll get the SHA1
-	  library from here.
+	- "openssl" library is used by git-imap-send to use IMAP over SSL.
+	  If you don't need it, use NO_OPENSSL.
 
-	  If you don't have openssl, you can use one of the SHA1 libraries
-	  that come with git (git includes one inspired by Mozilla's and a
-	  PowerPC optimized one too - see the Makefile).
+	  By default, git uses OpenSSL for SHA1 but it will use it's own
+	  library (inspired by Mozilla's) with either NO_OPENSSL or
+	  BLK_SHA1.  Also included is a version optimized for PowerPC
+	  (PPC_SHA1).
 
-	- libcurl library; git-http-fetch and git-fetch use them.  You
+	- "libcurl" library is used by git-http-fetch and git-fetch.  You
 	  might also want the "curl" executable for debugging purposes.
-	  If you do not use http transfer, you are probably OK if you
-	  do not have them.
+	  If you do not use http:// or https:// repositories, you do not
+	  have to have them (use NO_CURL).
 
-	- expat library; git-http-push uses it for remote lock
-	  management over DAV.  Similar to "curl" above, this is optional.
+	- "expat" library; git-http-push uses it for remote lock
+	  management over DAV.  Similar to "curl" above, this is optional
+	  (with NO_EXPAT).
 
-        - "wish", the Tcl/Tk windowing shell is used in gitk to show the
-          history graphically, and in git-gui.
+	- "wish", the Tcl/Tk windowing shell is used in gitk to show the
+	  history graphically, and in git-gui.  If you don't want gitk or
+	  git-gui, you can use NO_TCLTK.
 
  - Some platform specific issues are dealt with Makefile rules,
    but depending on your specific installation, you may not
-- 
1.6.4.2.420.g30ecf

^ permalink raw reply related

* [PATCH 4/4] reset: add test cases for "--merge-dirty" option
From: Christian Couder @ 2009-09-10 20:23 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
	Jakub Narebski, Linus Torvalds
In-Reply-To: <20090910200334.3722.20140.chriscool@tuxfamily.org>

This shows that with the "--merge-dirty" option, changes that are
both in the work tree and the index are kept in the work tree after
the reset (but discarded in the index). As with the "--merge" option,
changes that are in both the work tree and the index are discarded
after the reset.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 t/t7110-reset-merge.sh |   54 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
index 45714ae..1e6d634 100755
--- a/t/t7110-reset-merge.sh
+++ b/t/t7110-reset-merge.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2009 Christian Couder
 #
 
-test_description='Tests for "git reset --merge"'
+test_description='Tests for "git reset" with --merge and --merge-dirty'
 
 exec </dev/null
 
@@ -19,7 +19,7 @@ test_expect_success 'creating initial files' '
      git commit -m "Initial commit"
 '
 
-test_expect_success 'ok with changes in file not changed by reset' '
+test_expect_success '--merge: ok if changes in file not touched by reset' '
      echo "line 4" >> file1 &&
      echo "line 4" >> file2 &&
      test_tick &&
@@ -32,7 +32,21 @@ test_expect_success 'ok with changes in file not changed by reset' '
      grep 4 file2
 '
 
-test_expect_success 'discard changes added to index 1' '
+test_expect_success '--merge-dirty: ok if changes in file untouched by reset' '
+     git reset --hard HEAD^ &&
+     echo "line 4" >> file1 &&
+     echo "line 4" >> file2 &&
+     test_tick &&
+     git commit -m "add line 4" file1 &&
+     git reset --merge-dirty HEAD^ &&
+     ! grep 4 file1 &&
+     grep 4 file2 &&
+     git reset --merge-dirty HEAD@{1} &&
+     grep 4 file1 &&
+     grep 4 file2
+'
+
+test_expect_success '--merge: discard changes added to index 1' '
      echo "line 5" >> file1 &&
      git add file1 &&
      git reset --merge HEAD^ &&
@@ -47,7 +61,7 @@ test_expect_success 'discard changes added to index 1' '
      grep 4 file1
 '
 
-test_expect_success 'discard changes added to index 2' '
+test_expect_success '--merge: discard changes added to index 2' '
      echo "line 4" >> file2 &&
      git add file2 &&
      git reset --merge HEAD^ &&
@@ -57,7 +71,37 @@ test_expect_success 'discard changes added to index 2' '
      grep 4 file1
 '
 
-test_expect_success 'not ok with changes in file changed by reset' '
+test_expect_success '--merge-dirty: not ok with touched changes in index' '
+     echo "line 4" >> file2 &&
+     echo "line 5" >> file1 &&
+     git add file1 &&
+     test_must_fail git reset --merge-dirty HEAD^ &&
+     git reset --hard HEAD
+'
+
+test_expect_success '--merge-dirty: keep untouched changes' '
+     echo "line 4" >> file2 &&
+     git add file2 &&
+     git reset --merge-dirty HEAD^ &&
+     grep 4 file2 &&
+     git reset --merge HEAD@{1} &&
+     grep 4 file2 &&
+     grep 4 file1 &&
+     git reset --hard HEAD
+'
+
+test_expect_success '--merge: not ok with changes in file changed by reset' '
+     echo "line 6" >> file1 &&
+     test_tick &&
+     git commit -m "add line 6" file1 &&
+     sed -e "s/line 1/changed line 1/" <file1 >file3 &&
+     mv file3 file1 &&
+     test_must_fail git reset --merge HEAD^ 2>err.log &&
+     grep file1 err.log | grep "not uptodate"
+'
+
+test_expect_success '--merge-dirty: not ok with changes in file changed by reset' '
+     git reset --hard HEAD^ &&
      echo "line 6" >> file1 &&
      test_tick &&
      git commit -m "add line 6" file1 &&
-- 
1.6.4.271.ge010d

^ permalink raw reply related

* [PATCH 0/4] "git reset --merge" related improvements
From: Christian Couder @ 2009-09-10 20:23 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
	Jakub Narebski, Linus Torvalds

As agreed during private discussions, I am trying to refactor and
merge some interesting bits of code from the GSoC sequencer project.

So here is a first round about "git reset".

Patches 1/4 and 2/4 are using sequencer code to speed up "git reset" and
add some test cases for "git reset --merge".

Patches 3/4 and 4/4 are implementing "git reset --merge-dirty" and
showing the differences with "--merge". "--merge-dirty" is a really bad
name for the index reset option that is available using the "allow_dirty"
global variable in the sequencer. These 2 patches are for discussing
this feature.

Christian Couder (2):
  reset: add a few tests for "git reset --merge"
  reset: add test cases for "--merge-dirty" option

Stephan Beyer (2):
  reset: use "unpack_trees()" directly instead of "git read-tree"
  reset: add option "--merge-dirty" to "git reset"

 builtin-reset.c        |   81 +++++++++++++++++++++++++++-------
 t/t7110-reset-merge.sh |  114 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 16 deletions(-)
 create mode 100755 t/t7110-reset-merge.sh

^ permalink raw reply

* [PATCH 1/4] reset: add a few tests for "git reset --merge"
From: Christian Couder @ 2009-09-10 20:23 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
	Jakub Narebski, Linus Torvalds
In-Reply-To: <20090910200334.3722.20140.chriscool@tuxfamily.org>

Commit 9e8eceab ("Add 'merge' mode to 'git reset'", 2008-12-01),
added the --merge option to git reset, but there were no test cases
for it.

This was not a big problem because "git reset" was just forking and
execing "git read-tree", but this will change in a following patch.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 t/t7110-reset-merge.sh |   70 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)
 create mode 100755 t/t7110-reset-merge.sh

diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
new file mode 100755
index 0000000..45714ae
--- /dev/null
+++ b/t/t7110-reset-merge.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Christian Couder
+#
+
+test_description='Tests for "git reset --merge"'
+
+exec </dev/null
+
+. ./test-lib.sh
+
+test_expect_success 'creating initial files' '
+     echo "line 1" >> file1 &&
+     echo "line 2" >> file1 &&
+     echo "line 3" >> file1 &&
+     cp file1 file2 &&
+     git add file1 file2 &&
+     test_tick &&
+     git commit -m "Initial commit"
+'
+
+test_expect_success 'ok with changes in file not changed by reset' '
+     echo "line 4" >> file1 &&
+     echo "line 4" >> file2 &&
+     test_tick &&
+     git commit -m "add line 4" file1 &&
+     git reset --merge HEAD^ &&
+     ! grep 4 file1 &&
+     grep 4 file2 &&
+     git reset --merge HEAD@{1} &&
+     grep 4 file1 &&
+     grep 4 file2
+'
+
+test_expect_success 'discard changes added to index 1' '
+     echo "line 5" >> file1 &&
+     git add file1 &&
+     git reset --merge HEAD^ &&
+     ! grep 4 file1 &&
+     ! grep 5 file1 &&
+     grep 4 file2 &&
+     echo "line 5" >> file2 &&
+     git add file2 &&
+     git reset --merge HEAD@{1} &&
+     ! grep 4 file2 &&
+     ! grep 5 file1 &&
+     grep 4 file1
+'
+
+test_expect_success 'discard changes added to index 2' '
+     echo "line 4" >> file2 &&
+     git add file2 &&
+     git reset --merge HEAD^ &&
+     ! grep 4 file2 &&
+     git reset --merge HEAD@{1} &&
+     ! grep 4 file2 &&
+     grep 4 file1
+'
+
+test_expect_success 'not ok with changes in file changed by reset' '
+     echo "line 6" >> file1 &&
+     test_tick &&
+     git commit -m "add line 6" file1 &&
+     sed -e "s/line 1/changed line 1/" <file1 >file3 &&
+     mv file3 file1 &&
+     test_must_fail git reset --merge HEAD^ 2>err.log &&
+     grep file1 err.log | grep "not uptodate"
+'
+
+test_done
-- 
1.6.4.271.ge010d

^ permalink raw reply related

* [PATCH 2/4] reset: use "unpack_trees()" directly instead of "git read-tree"
From: Christian Couder @ 2009-09-10 20:23 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
	Jakub Narebski, Linus Torvalds
In-Reply-To: <20090910200334.3722.20140.chriscool@tuxfamily.org>

From: Stephan Beyer <s-beyer@gmx.net>

This patch makes "reset_index_file()" call "unpack_trees()" directly
instead of forking and execing "git read-tree".

The code comes from the sequencer GSoC project:

git://repo.or.cz/git/sbeyer.git

(at commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)

Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 builtin-reset.c |   51 ++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/builtin-reset.c b/builtin-reset.c
index 73e6022..ddb81f3 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -18,6 +18,8 @@
 #include "tree.h"
 #include "branch.h"
 #include "parse-options.h"
+#include "unpack-trees.h"
+#include "cache-tree.h"
 
 static const char * const git_reset_usage[] = {
 	"git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
@@ -52,29 +54,56 @@ static inline int is_merge(void)
 	return !access(git_path("MERGE_HEAD"), F_OK);
 }
 
+static int parse_and_init_tree_desc(const unsigned char *sha1,
+					     struct tree_desc *desc)
+{
+	struct tree *tree = parse_tree_indirect(sha1);
+	if (!tree)
+		return 1;
+	init_tree_desc(desc, tree->buffer, tree->size);
+	return 0;
+}
+
 static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet)
 {
-	int i = 0;
-	const char *args[6];
+	int nr = 1;
+	int newfd;
+	struct tree_desc desc[2];
+	struct unpack_trees_options opts;
+	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
 
-	args[i++] = "read-tree";
+	memset(&opts, 0, sizeof(opts));
+	opts.head_idx = 1;
+	opts.src_index = &the_index;
+	opts.dst_index = &the_index;
+	opts.fn = oneway_merge;
+	opts.merge = 1;
 	if (!quiet)
-		args[i++] = "-v";
+		opts.verbose_update = 1;
 	switch (reset_type) {
 	case MERGE:
-		args[i++] = "-u";
-		args[i++] = "-m";
+		opts.update = 1;
 		break;
 	case HARD:
-		args[i++] = "-u";
+		opts.update = 1;
 		/* fallthrough */
 	default:
-		args[i++] = "--reset";
+		opts.reset = 1;
 	}
-	args[i++] = sha1_to_hex(sha1);
-	args[i] = NULL;
 
-	return run_command_v_opt(args, RUN_GIT_CMD);
+	newfd = hold_locked_index(lock, 1);
+
+	read_cache_unmerged();
+
+	if (parse_and_init_tree_desc(sha1, desc + nr - 1))
+		return error("Failed to find tree of %s.", sha1_to_hex(sha1));
+	if (unpack_trees(nr, desc, &opts))
+		return -1;
+	if (write_cache(newfd, active_cache, active_nr) ||
+	    commit_locked_index(lock))
+		return error("Could not write new index file.");
+
+	return 0;
 }
 
 static void print_new_head_line(struct commit *commit)
-- 
1.6.4.271.ge010d

^ permalink raw reply related


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