Git development
 help / color / mirror / Atom feed
* [PATCH 1/4] parse-options: abbreviation engine fix.
From: Pierre Habouzit @ 2007-11-05 12:03 UTC (permalink / raw)
  To: gitster, Junio C Hamano; +Cc: git, Pierre Habouzit
In-Reply-To: <1194264204-3475-1-git-send-email-madcoder@debian.org>

When we had at least two long option then followed by another one that was a
prefix of both of them, then the abbreviation detector failed.

Fix the issue, add a test.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 parse-options.c          |   48 +++++++++++++++++++++++-----------------------
 t/t0040-parse-options.sh |   13 ++++++++++++
 test-parse-options.c     |    1 +
 3 files changed, 38 insertions(+), 24 deletions(-)

diff --git a/parse-options.c b/parse-options.c
index cc09c98..d2e32c1 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -119,8 +119,8 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
                           const struct option *options)
 {
 	const char *arg_end = strchr(arg, '=');
-	const struct option *abbrev_option = NULL;
-	int abbrev_flags = 0;
+	const struct option *abbrev_option = NULL, *conflict_option = NULL;
+	int abbrev_flags = 0, conflict_flags = 0;
 
 	if (!arg_end)
 		arg_end = arg + strlen(arg);
@@ -132,42 +132,33 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
 		if (!options->long_name)
 			continue;
 
+		/* special case {n,no,no-} that always conflict */
+		if (!prefixcmp("no-", arg))
+			die("`--{n,no,no-}' cannot be abbreviated forms of options");
+
 		rest = skip_prefix(arg, options->long_name);
 		if (!rest) {
 			/* abbreviated? */
 			if (!strncmp(options->long_name, arg, arg_end - arg)) {
 is_abbreviated:
-				if (abbrev_option)
-					return error("Ambiguous option: %s "
-						"(could be --%s%s or --%s%s)",
-						arg,
-						(flags & OPT_UNSET) ?
-							"no-" : "",
-						options->long_name,
-						(abbrev_flags & OPT_UNSET) ?
-							"no-" : "",
-						abbrev_option->long_name);
-				if (!(flags & OPT_UNSET) && *arg_end)
-					p->opt = arg_end + 1;
+				conflict_option = abbrev_option;
+				conflict_flags = abbrev_flags;
 				abbrev_option = options;
 				abbrev_flags = flags;
 				continue;
 			}
-			/* negated and abbreviated very much? */
-			if (!prefixcmp("no-", arg)) {
-				flags |= OPT_UNSET;
-				goto is_abbreviated;
-			}
 			/* negated? */
 			if (strncmp(arg, "no-", 3))
 				continue;
 			flags |= OPT_UNSET;
-			rest = skip_prefix(arg + 3, options->long_name);
+			arg += 3;
+			rest = skip_prefix(arg, options->long_name);
 			/* abbreviated and negated? */
-			if (!rest && !prefixcmp(options->long_name, arg + 3))
-				goto is_abbreviated;
-			if (!rest)
+			if (!rest) {
+				if (!strncmp(options->long_name, arg, arg_end - arg))
+					goto is_abbreviated;
 				continue;
+			}
 		}
 		if (*rest) {
 			if (*rest != '=')
@@ -176,8 +167,17 @@ is_abbreviated:
 		}
 		return get_value(p, options, flags);
 	}
-	if (abbrev_option)
+	if (conflict_option)
+		return error("Ambiguous option: %s (could be --%s%s or --%s%s)",
+			arg, (conflict_flags & OPT_UNSET) ?  "no-" : "",
+			conflict_option->long_name,
+			(abbrev_flags & OPT_UNSET) ?  "no-" : "",
+			abbrev_option->long_name);
+	if (abbrev_option) {
+		if (!(abbrev_flags & OPT_UNSET) && *arg_end)
+			p->opt = arg_end + 1;
 		return get_value(p, abbrev_option, abbrev_flags);
+	}
 	return error("unknown option `%s'", arg);
 }
 
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index ae49424..ee758e5 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -18,6 +18,7 @@ string options
     -s, --string <string>
                           get a string
     --string2 <str>       get another string
+    --st <st>             get another string (pervert ordering)
 
 EOF
 
@@ -90,4 +91,16 @@ test_expect_failure 'ambiguously abbreviated option' '
         test $? != 129
 '
 
+cat > expect << EOF
+boolean: 0
+integer: 2
+string: 123
+EOF
+
+test_expect_failure 'non ambiguous option (after two options it abbreviates)' '
+	test-parse-options --st 123 &&
+	test ! -s output.err &&
+	git diff expect output
+'
+
 test_done
diff --git a/test-parse-options.c b/test-parse-options.c
index 277cfe4..4d3e2ec 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -18,6 +18,7 @@ int main(int argc, const char **argv)
 		OPT_GROUP("string options"),
 		OPT_STRING('s', "string", &string, "string", "get a string"),
 		OPT_STRING(0, "string2", &string, "str", "get another string"),
+		OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
 		OPT_END(),
 	};
 	int i;
-- 
1.5.3.5.1531.g59008


^ permalink raw reply related

* [PATCH 2/4] Some better parse-options documentation.
From: Pierre Habouzit @ 2007-11-05 12:03 UTC (permalink / raw)
  To: gitster, Junio C Hamano; +Cc: git, Pierre Habouzit
In-Reply-To: <1194264204-3475-2-git-send-email-madcoder@debian.org>

---
 parse-options.h |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/parse-options.h b/parse-options.h
index 3a470e5..65bce6e 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -22,6 +22,41 @@ enum parse_opt_option_flags {
 struct option;
 typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
 
+/*
+ * `type`::
+ *   holds the type of the option, you must have an OPTION_END last in your
+ *   array.
+ *
+ * `short_name`::
+ *   the character to use as a short option name, '\0' if none.
+ *
+ * `long_name`::
+ *   the long option name, without the leading dashes, NULL if none.
+ *
+ * `value`::
+ *   stores pointers to the values to be filled.
+ *
+ * `argh`::
+ *   token to explain the kind of argument this option wants. Keep it
+ *   homogenous across the repository.
+ *
+ * `help`::
+ *   the short help associated to what the option does.
+ *   Must never be NULL (except for OPTION_END).
+ *   OPTION_GROUP uses this pointer to store the group header.
+ *
+ * `flags`::
+ *   mask of parse_opt_option_flags.
+ *   PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs)
+ *   PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
+ *
+ * `callback`::
+ *   pointer to the callback to use for OPTION_CALLBACK.
+ *
+ * `defval`::
+ *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
+ *   CALLBACKS can use it like they want.
+ */
 struct option {
 	enum parse_opt_type type;
 	int short_name;
@@ -32,8 +67,6 @@ struct option {
 
 	int flags;
 	parse_opt_cb *callback;
-	/* holds default value for PARSE_OPT_OPTARG,
-	   though callbacks can use it like they want */
 	intptr_t defval;
 };
 
-- 
1.5.3.5.1531.g59008


^ permalink raw reply related

* Re: [StGit PATCH] Cogito is deprecated, so don't point to it
From: Karl Hasselström @ 2007-11-05 12:00 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Catalin Marinas, git, David Kågedal
In-Reply-To: <vpqejf510ci.fsf@bauges.imag.fr>

On 2007-11-05 10:57:17 +0100, Matthieu Moy wrote:

> Karl Hasselström <kha@treskal.com> writes:
>
> > -directly). For standard SCM operations, either use plain GIT commands
> > -or the Cogito tool but it is not recommended to mix them with the
> > -StGIT commands.
> > +directly). For standard SCM operations, use plain GIT commands.
>
> Doesn't the "but it is not recommended to mix them with the StGIT
> commands." part still hold?

I'm not sure it ever held. Except possibly during merge resolution,
but that mismatch is going away with the patch series by David Kågedal
that's sitting in kha/experimental (which changes StGit to use exactly
the same conflict representation as git).

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: [StGit PATCH] Cogito is deprecated, so don't point to it
From: David Kågedal @ 2007-11-05 11:52 UTC (permalink / raw)
  To: git
In-Reply-To: <vpqejf510ci.fsf@bauges.imag.fr>

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

> Karl Hasselström <kha@treskal.com> writes:
>
>> -directly). For standard SCM operations, either use plain GIT commands
>> -or the Cogito tool but it is not recommended to mix them with the
>> -StGIT commands.
>> +directly). For standard SCM operations, use plain GIT commands.
>
> Doesn't the "but it is not recommended to mix them with the StGIT
> commands." part still hold?

Karl has been working hard lately to make sure that stg doesn't get
confused when you use git directly.

-- 
David Kågedal

^ permalink raw reply

* [PATCH 2/2] git-svn: t9114: verify merge commit message in test
From: Eric Wong @ 2007-11-05 11:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong
In-Reply-To: <1194261708-32256-1-git-send-email-normalperson@yhbt.net>

It's possible that we end up with an incorrect commit message
in this test after making changes to fix the clobber bug
in dcommit.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 t/t9114-git-svn-dcommit-merge.sh |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index d6ca955..225060b 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -86,4 +86,9 @@ test_expect_success 'verify post-merge ancestry' "
 	git cat-file commit refs/heads/svn^ | grep '^friend$'
 	"
 
+test_expect_success 'verify merge commit message' "
+	git rev-list --pretty=raw -1 refs/heads/svn | \
+	  grep \"    Merge branch 'merge' into svn\"
+	"
+
 test_done
-- 
1.5.3.5.566.gc207

^ permalink raw reply related

* [PATCH 1/2] git-svn: fix dcommit clobbering when committing a series of diffs
From: Eric Wong @ 2007-11-05 11:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong

Our revision number sent to SVN is set to the last revision we
committed if we've made any previous commits in a dcommit
invocation.

Although our SVN Editor code uses the delta of two (old) trees
to generate information to send upstream, it'll still send
complete resultant files upstream; even if the tree they're
based against is out-of-date.

The combination of sending a file that does not include the
latest changes, but set with a revision number of a commit we
just made will cause SVN to accept the resultant file even if it
was generated against an old tree.

More trouble was caused when fixing this because we were
rebasing uncessarily at times.  We used git-diff-tree to check
the imported SVN revision against our HEAD, not the last tree we
committed to SVN.  The unnecessary rebasing caused merge commits
upstream to SVN to fail.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---

 Junio: please apply this to maint, thanks.

 git-svn.perl                              |   47 ++++++++++++++++++++++--
 t/t9106-git-svn-dcommit-clobber-series.sh |   56 +++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 4 deletions(-)
 create mode 100755 t/t9106-git-svn-dcommit-clobber-series.sh

diff --git a/git-svn.perl b/git-svn.perl
index 4900f57..62a4a69 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -406,7 +406,8 @@ sub cmd_dcommit {
 		     "If these changes depend on each other, re-running ",
 		     "without --no-rebase will be required."
 	}
-	foreach my $d (@$linear_refs) {
+	while (1) {
+		my $d = shift @$linear_refs or last;
 		unless (defined $last_rev) {
 			(undef, $last_rev, undef) = cmt_metadata("$d~1");
 			unless (defined $last_rev) {
@@ -439,14 +440,14 @@ sub cmd_dcommit {
 
 			# we always want to rebase against the current HEAD,
 			# not any head that was passed to us
-			my @diff = command('diff-tree', 'HEAD',
+			my @diff = command('diff-tree', $d,
 			                   $gs->refname, '--');
 			my @finish;
 			if (@diff) {
 				@finish = rebase_cmd();
-				print STDERR "W: HEAD and ", $gs->refname,
+				print STDERR "W: $d and ", $gs->refname,
 				             " differ, using @finish:\n",
-				             "@diff";
+				             join("\n", @diff), "\n";
 			} else {
 				print "No changes between current HEAD and ",
 				      $gs->refname,
@@ -455,6 +456,45 @@ sub cmd_dcommit {
 				@finish = qw/reset --mixed/;
 			}
 			command_noisy(@finish, $gs->refname);
+			if (@diff) {
+				@refs = ();
+				my ($url_, $rev_, $uuid_, $gs_) =
+				              working_head_info($head, \@refs);
+				my ($linear_refs_, $parents_) =
+				              linearize_history($gs_, \@refs);
+				if (scalar(@$linear_refs) !=
+				    scalar(@$linear_refs_)) {
+					fatal "# of revisions changed ",
+					  "\nbefore:\n",
+					  join("\n", @$linear_refs),
+					  "\n\nafter:\n",
+					  join("\n", @$linear_refs_), "\n",
+					  'If you are attempting to commit ',
+					  "merges, try running:\n\t",
+					  'git rebase --interactive',
+					  '--preserve-merges ',
+					  $gs->refname,
+					  "\nBefore dcommitting";
+				}
+				if ($url_ ne $url) {
+					fatal "URL mismatch after rebase: ",
+					      "$url_ != $url";
+				}
+				if ($uuid_ ne $uuid) {
+					fatal "uuid mismatch after rebase: ",
+					      "$uuid_ != $uuid";
+				}
+				# remap parents
+				my (%p, @l, $i);
+				for ($i = 0; $i < scalar @$linear_refs; $i++) {
+					my $new = $linear_refs_->[$i] or next;
+					$p{$new} =
+						$parents->{$linear_refs->[$i]};
+					push @l, $new;
+				}
+				$parents = \%p;
+				$linear_refs = \@l;
+			}
 			$last_rev = $cmt_rev;
 		}
 	}
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh
new file mode 100755
index 0000000..4216a88
--- /dev/null
+++ b/t/t9106-git-svn-dcommit-clobber-series.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+test_description='git-svn dcommit clobber series'
+. ./lib-git-svn.sh
+
+test_expect_success 'initialize repo' "
+	mkdir import &&
+	cd import &&
+	awk 'BEGIN { for (i = 1; i < 64; i++) { print i } }' > file
+	svn import -m 'initial' . $svnrepo &&
+	cd .. &&
+	git svn init $svnrepo &&
+	git svn fetch &&
+	test -e file
+	"
+
+test_expect_success '(supposedly) non-conflicting change from SVN' "
+	test x\"\`sed -n -e 58p < file\`\" = x58 &&
+	test x\"\`sed -n -e 61p < file\`\" = x61 &&
+	svn co $svnrepo tmp &&
+	cd tmp &&
+		perl -i -p -e 's/^58\$/5588/' file &&
+		perl -i -p -e 's/^61\$/6611/' file &&
+		test x\"\`sed -n -e 58p < file\`\" = x5588 &&
+		test x\"\`sed -n -e 61p < file\`\" = x6611 &&
+		svn commit -m '58 => 5588, 61 => 6611' &&
+		cd ..
+	"
+
+test_expect_success 'unrelated some unrelated changes to git' "
+	echo hi > life &&
+	git update-index --add life &&
+	git commit -m hi-life &&
+	echo bye >> life &&
+	git commit -m bye-life life
+	"
+
+test_expect_success 'change file but in unrelated area' "
+	test x\"\`sed -n -e 4p < file\`\" = x4 &&
+	test x\"\`sed -n -e 7p < file\`\" = x7 &&
+	perl -i -p -e 's/^4\$/4444/' file &&
+	perl -i -p -e 's/^7\$/7777/' file &&
+	test x\"\`sed -n -e 4p < file\`\" = x4444 &&
+	test x\"\`sed -n -e 7p < file\`\" = x7777 &&
+	git commit -m '4 => 4444, 7 => 7777' file &&
+	git svn dcommit &&
+	svn up tmp &&
+	cd tmp &&
+		test x\"\`sed -n -e 4p < file\`\" = x4444 &&
+		test x\"\`sed -n -e 7p < file\`\" = x7777 &&
+		test x\"\`sed -n -e 58p < file\`\" = x5588 &&
+		test x\"\`sed -n -e 61p < file\`\" = x6611
+	"
+
+test_done
-- 
1.5.3.5.566.gc207

^ permalink raw reply related

* Re: [ANNOUNCE] cgit v0.7
From: Lars Hjemli @ 2007-11-05 10:59 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git list
In-Reply-To: <1194222569-13948-1-git-send-email-jnareb@gmail.com>

On Nov 5, 2007 1:29 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> Lars Hjemli wrote:
> > cgit v0.7 (a fast webinterface for git) is now available
>
>  * Very nice cgit logo,

Thanks!

> but no favicon. Perhaps pacman head and G,
>    or pacman head (like in logo) and +/-...

I've never cared much about favicons, but I guess cgit could provide one.

>
>  * Providing reference with full sha1 of referenced object for tags
>    list is not IMVHO a good design: what is interesting is type of
>    tag, if it is signed it's first line, and if it is lightweight
>    pointing to tag then perhaps commit subject.

Yes, the full sha1 is not very interesting. But I'm not sure what to
replace it with: the first line of annotated tags is very often
identical to tag name. Maybe it should just abbreviate the sha1?

>
>  * Nice diffstat in commit view; the diff view is better, although I
>    wouldn't lump from-file / to-file diff header together with git
>    diff header and extended git diff header.

I've tried to make the diff look similar to 'git log -p' output, but I
agree the first line per file is probably overkill.

>
>  * I like the sidebar very much, although I'm not sure how it would
>    work for larger projects (more branches, much more tags).

How do you think it works out with http://hjemli.net/git/xorg/xserver/
? It's got an impressive number of branches and tags ;-)

> Also the
>    search textbox is not very visible; I'd rather it have "groove"
>    view.

Agreed, it's probably useless trying to style input-controls: the
result is heavily browser/platform dependent.


>  * I like separate 'mirrors' section, although I think it rather
>    clashes badly with notion of forks (alternates).

Well, it's only a section header, i.e. a parameter in cgitrc


>  * I'm not sure if it wouln't be beter to provide -n/+m lines changed
>    instead of nn likes changed column.

Maybe. I think it used to be -n/+m, but then I changed it; don't
remember why...

>
>  * Nice submodule support!

Heh, it's a simple hack, but thanks anyway. It probably needs to be
configurable per repo though.

>
> By the way, Freedesktop provides besides standard gitweb interface
> also cgit interface at
>   http://cgit.freedesktop.org/
> Take a look at how such site looks like with large number of projects
> (perhaps sidebar is noot such a good idea then?), and with large
> projects.

Actually, the filtered branch/tag lists was done partly because of
freedesktop.org. I think it has worked out nicely (but
cgit.freedesktop.org needs to run the latest cgit). Also, the width of
project descriptions is configurable, so it can take up much less
space and leave room for the sidebar.

Thanks for the comments, you've made my day!

-- 
larsh

^ permalink raw reply

* Re: [RFC PATCH] OSX Mail.app IMAP cache support for git-mailsplit?
From: Johannes Schindelin @ 2007-11-05 10:39 UTC (permalink / raw)
  To: Michael Cohen; +Cc: git
In-Reply-To: <7B209F05-B720-41D6-AE98-39FAFF04B9F6@mac.com>

Hi,

you have a very weird mail setting; I had to add the git list back to the 
Cc.  This is just annoying enough for me to write an extra paragraph to 
annoy you back ;-)

On Mon, 5 Nov 2007, Michael Cohen wrote:

> On Nov 4, 2007, at 1:49 AM, Michael J. Cohen wrote:
> 
> > Trivially, adding support for checking for Messages/ inside the specified
> > Maildir after cur/ is found not to exist would be enough to make this work.
> 
> my repo at git://home.325i.org/git-osxmail.git should have that portion.
> 
> unsure as to whether to make it an option, a fallback, a config value, or
> whatever...

A fallback would be sufficient.

Several comments (your patch not inlined, since you did not inline it 
either):

- there needs to be a space between the ) and the { in the first if line.

- you probably forgot to remove the original "if (populate...)...".  That 
  means that populate would be called _twice_, even if successful.

- git is written in C.  Therefore, "//" as a way to comment out is wrong.

- if you still return -1 when the dir could not be opened, I wonder what 
  the rationale is to comment the error out.

Ciao,
Dscho

P.S.: You might want to send patches as these right away, without asking 
if anybody cares (you'll see that very soon), but rather in accord with 
Documentation/SubmittingPatches.

^ permalink raw reply

* Re: [PATCH] t7501-commit.sh: Add test case for fixing author in amend commit.
From: Johannes Schindelin @ 2007-11-05 10:24 UTC (permalink / raw)
  To: Kristian Høgsberg; +Cc: gitster, git
In-Reply-To: <1194234165-9498-1-git-send-email-krh@redhat.com>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 713 bytes --]

Hi,

On Sun, 4 Nov 2007, Kristian Høgsberg wrote:

> +test_tick
>  
>  test_expect_success 'partial commit that involves removal (3)' '

We usually put the test_tick into the test case.  IOW

	test_expect_success 'message' '
		test_tick &&
		...

>  '
>  
> +oldtick=$GIT_AUTHOR_DATE
> +test_tick
> +
> +author="The Real Author <someguy@his.email.org>"
> +committer="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE"
> +
> +test_expect_success 'amend commit to fix author' '

Same here.

BTW: is this committer mangling really necessary? I thought only 
GIT_COMMITTER_DATE was relevant.  And that is easily replaced by

	sed -e "s/^\(committer.* \)[0-9][0-9]*$/\1$GIT_COMMITTER_DATE/"

Ciao,
Dscho

^ permalink raw reply

* Re: [StGit PATCH] Cogito is deprecated, so don't point to it
From: Matthieu Moy @ 2007-11-05  9:57 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Catalin Marinas, git
In-Reply-To: <20071105030608.6033.35208.stgit@yoghurt>

Karl Hasselström <kha@treskal.com> writes:

> -directly). For standard SCM operations, either use plain GIT commands
> -or the Cogito tool but it is not recommended to mix them with the
> -StGIT commands.
> +directly). For standard SCM operations, use plain GIT commands.

Doesn't the "but it is not recommended to mix them with the StGIT
commands." part still hold?

-- 
Matthieu

^ permalink raw reply

* [PATCH] git-daemon: fix remote port number in log entry
From: Gerrit Pape @ 2007-11-05  9:16 UTC (permalink / raw)
  To: git, Junio C Hamano

The port number in struct sockaddr_in needs to be converted from network
byte order to host byte order (on some architectures).

Signed-off-by: Gerrit Pape <pape@smarden.org>
---
 daemon.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/daemon.c b/daemon.c
index 660e155..b8df980 100644
--- a/daemon.c
+++ b/daemon.c
@@ -540,7 +540,7 @@ static int execute(struct sockaddr *addr)
 		if (addr->sa_family == AF_INET) {
 			struct sockaddr_in *sin_addr = (void *) addr;
 			inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
-			port = sin_addr->sin_port;
+			port = ntohs(sin_addr->sin_port);
 #ifndef NO_IPV6
 		} else if (addr && addr->sa_family == AF_INET6) {
 			struct sockaddr_in6 *sin6_addr = (void *) addr;
@@ -550,7 +550,7 @@ static int execute(struct sockaddr *addr)
 			inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
 			strcat(buf, "]");
 
-			port = sin6_addr->sin6_port;
+			port = ntohs(sin6_addr->sin6_port);
 #endif
 		}
 		loginfo("Connection from %s:%d", addrbuf, port);
-- 
1.5.3.5

^ permalink raw reply related

* Re: [PATCH] Use parseopts in builtin-fetch
From: Pierre Habouzit @ 2007-11-05  8:55 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0711042233590.7357@iabervon.org>

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

On Mon, Nov 05, 2007 at 03:35:34AM +0000, Daniel Barkalow wrote:
> I mostly did this and the next one for practice with the API. I'm 
> impressed that "git fetch -vv" is even handled correctly without anything 
> special.

  About that: OPTION_BOOLEAN increments the associated variable, to
support this case specifically.

  The last thing that really miss in parse-options is a way to recurse
into a sub-array of struct option, to be able to port the generic diff
and revision arguments.

  Though, there is a difficulty here that I've not yet found how to
circumvent tastefully: right now options take an absolute pointer to
_the_ variable that will be filled with values. I need to be able to
relocate such a structure for sub-arrays for quite obvious reasons, and
that is quite hard to achieve without hazardous APIs. I currently lean
in the direction of simply memdup-ing the array and do fix-ups on
*values pointers. Though how to do that in a graceful way is not obvious
to me yet :)

  This is the issue that currently prevents me from migrating any log
and diff based, though git diff -wbBCM that doesn't work is irritating me
more and more every day, so I'm confident I'll find a solution soon :)

-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] Use parseopts in builtin-fetch
From: Pierre Habouzit @ 2007-11-05  8:43 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0711042233590.7357@iabervon.org>

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

On Mon, Nov 05, 2007 at 03:35:34AM +0000, Daniel Barkalow wrote:
> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
> ---
> I mostly did this and the next one for practice with the API. I'm 
> impressed that "git fetch -vv" is even handled correctly without anything 
> special. Now that I've done it, assuming I did it right, it might as well 
> get added to the series.

  I believe the same patches (or very similar ones) are in pu but are
not in next yet because they conflict with the builtin-fetch recent
series.

  see http://git.madism.org/?p=git.git;a=blobdiff;f=builtin-fetch.c;h=12b1c4;hp=6b1750d;hb=7407915;hpb=61610e6

> +		OPT_BOOLEAN('q', "quiet", &quiet, "fetch silently"),

  there is an OPT__QUIET(&quiet) for this one.

> +	i = 1;
>  	if (i < argc) {
>  		int j = 0;
>  		refs = xcalloc(argc - i + 1, sizeof(const char *));

  this is wrong, you meant i = 0, and frankly, it's better to just strip
i altogether.

-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 0/3] more terse push output
From: Steffen Prohaska @ 2007-11-05  7:09 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git, Nicolas Pitre, Johannes Schindelin
In-Reply-To: <20071105050517.GA6244@sigill.intra.peff.net>


On Nov 5, 2007, at 6:05 AM, Jeff King wrote:

>   - the 'ref is not up-to-date, maybe you need to push' message has  
> gone
>     away in favor of the terse '[rejected] ... (non-fast forward)'. I
>     know there was some discussion recently of enhancing that message.
>     Is this perhaps too terse?

I like the general idea of the terse output.

If we want a suggestion to the user, we could put it as
a summary. If a ref was rejected send-pack could print a
concluding message:

---
To file:///tmp/parent
  + f3325dc...3b91d1c hasforce -> mirror/hasforce (forced update)
    f3325dc..bb022dc  master -> mirror/master
  ! [rejected]        needsforce -> mirror/needsforce (non-fast forward)
  * [new branch]      newbranch -> mirror/newbranch
  * [new tag]         v1.0 -> v1.0
Counting objects: 5, done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.

warning: some refs were rejected.
  Maybe they are not up-to-date and you want to pull or rebase first?
  Or you may need to force an update?
---

In this way the terse output would not be disrupted and the
suggestion would be given to the user nonetheless.

I propose to use "warning" because it is not a real error. push
updates all other refs as expected. It only rejects some
refs. An error would be appropriate only after push learnt
transactions, that is either completely succeeds or doesn't
update any ref at all.

	Steffen

^ permalink raw reply

* [RFC PATCH] OSX Mail.app IMAP cache support for git-mailsplit?
From: Michael Cohen @ 2007-11-05  6:36 UTC (permalink / raw)
  To: Michael J. Cohen
In-Reply-To: <06FE21A2-20D0-4AAA-B0C7-35783C604B68@mac.com>

On Nov 4, 2007, at 1:49 AM, Michael J. Cohen wrote:

> Trivially, adding support for checking for Messages/ inside the  
> specified Maildir after cur/ is found not to exist would be enough  
> to make this work.

my repo at git://home.325i.org/git-osxmail.git should have that portion.

unsure as to whether to make it an option, a fallback, a config value,  
or whatever...

-mjc

^ permalink raw reply

* [PATCH 3/3] send-pack: require --verbose to show update of tracking refs
From: Jeff King @ 2007-11-05  5:12 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nicolas Pitre, Johannes Schindelin
In-Reply-To: <20071105050517.GA6244@sigill.intra.peff.net>

This is really an uninteresting detail, and it just takes
attention away from the actual push updates and posssible
errors.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin-send-pack.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index d74cc3c..c1fd3f5 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -195,7 +195,8 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
 		return;
 
 	if (!remote_find_tracking(remote, &rs)) {
-		fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
+		if (args.verbose)
+			fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
 		if (is_null_sha1(ref->peer_ref->new_sha1)) {
 			if (delete_ref(rs.dst, NULL))
 				error("Failed to delete");
-- 
1.5.3.5.1530.g7353

^ permalink raw reply related

* [PATCH 2/3] receive-pack: don't mention successful updates
From: Jeff King @ 2007-11-05  5:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nicolas Pitre, Johannes Schindelin
In-Reply-To: <20071105050517.GA6244@sigill.intra.peff.net>

The proposed updates are already shown to the user by
send-pack, so there's no point. We continue to show errors,
since they are unexpected.

Signed-off-by: Jeff King <peff@peff.net>
---
 receive-pack.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/receive-pack.c b/receive-pack.c
index 38e35c0..ed44b89 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -204,8 +204,6 @@ static const char *update(struct command *cmd)
 			error("failed to delete %s", name);
 			return "failed to delete";
 		}
-		fprintf(stderr, "%s: %s -> deleted\n", name,
-			sha1_to_hex(old_sha1));
 		return NULL; /* good */
 	}
 	else {
@@ -217,8 +215,6 @@ static const char *update(struct command *cmd)
 		if (write_ref_sha1(lock, new_sha1, "push")) {
 			return "failed to write"; /* error() already called */
 		}
-		fprintf(stderr, "%s: %s -> %s\n", name,
-			sha1_to_hex(old_sha1), sha1_to_hex(new_sha1));
 		return NULL; /* good */
 	}
 }
-- 
1.5.3.5.1530.g7353

^ permalink raw reply related

* [PATCH 1/3] more terse push output
From: Jeff King @ 2007-11-05  5:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nicolas Pitre, Johannes Schindelin
In-Reply-To: <20071105050517.GA6244@sigill.intra.peff.net>

This changes the output of send-pack to match the new,
more terse fetch output. It looks like this:

To git://host.tld/path/to/repo
 + f3325dc...3b91d1c hasforce -> mirror/hasforce (forced update)
   f3325dc..bb022dc  master -> mirror/master
 ! [rejected]        needsforce -> mirror/needsforce (non-fast forward)
 * [new branch]      newbranch -> mirror/newbranch
 * [new tag]         v1.0 -> v1.0

instead of:

updating 'refs/heads/mirror/hasforce' using 'refs/heads/hasforce'
  from f3325dca9c4a34d74012c0e159254f454930cec7
  to   3b91d1c310ca9d7b547b85466dd876e143498304
updating 'refs/heads/mirror/master' using 'refs/heads/master'
  from f3325dca9c4a34d74012c0e159254f454930cec7
  to   bb022dc363d5c2aa9aa3026beb9706d44fbe1328
error: remote 'refs/heads/mirror/needsforce' is not an ancestor of
 local  'refs/heads/needsforce'.
 Maybe you are not up-to-date and need to pull first?
updating 'refs/heads/mirror/newbranch' using 'refs/heads/newbranch'
  from 0000000000000000000000000000000000000000
  to   3b91d1c310ca9d7b547b85466dd876e143498304
updating 'refs/tags/v1.0'
  from 0000000000000000000000000000000000000000
  to   bb022dc363d5c2aa9aa3026beb9706d44fbe1328

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin-send-pack.c |   81 ++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index 947c42b..d74cc3c 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -206,7 +206,18 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
 	}
 }
 
-static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec, const char **refspec)
+static const char *prettify_ref(const char *name)
+{
+	return name + (
+		!prefixcmp(name, "refs/heads/") ? 11 :
+		!prefixcmp(name, "refs/tags/") ? 10 :
+		!prefixcmp(name, "refs/remotes/") ? 13 :
+		0);
+}
+
+#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
+
+static int do_send_pack(int in, int out, struct remote *remote, const char *dest, int nr_refspec, const char **refspec)
 {
 	struct ref *ref;
 	int new_refs;
@@ -214,6 +225,7 @@ static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec,
 	int ask_for_status_report = 0;
 	int allow_deleting_refs = 0;
 	int expect_status_report = 0;
+	int shown_dest = 0;
 
 	/* No funny business with the matcher */
 	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
@@ -245,21 +257,33 @@ static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec,
 	for (ref = remote_refs; ref; ref = ref->next) {
 		char old_hex[60], *new_hex;
 		int will_delete_ref;
+		const char *pretty_ref;
+		const char *pretty_peer;
 
 		if (!ref->peer_ref)
 			continue;
 
+		if (!shown_dest) {
+			fprintf(stderr, "To %s\n", dest);
+			shown_dest = 1;
+		}
+
+		pretty_ref = prettify_ref(ref->name);
+		pretty_peer = prettify_ref(ref->peer_ref->name);
 
 		will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
 		if (will_delete_ref && !allow_deleting_refs) {
-			error("remote does not support deleting refs");
+			fprintf(stderr, " ! %-*s %s (remote does not support deleting refs)\n",
+					SUMMARY_WIDTH, "[rejected]", pretty_ref);
 			ret = -2;
 			continue;
 		}
 		if (!will_delete_ref &&
 		    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
 			if (args.verbose)
-				fprintf(stderr, "'%s': up-to-date\n", ref->name);
+				fprintf(stderr, " = %-*s %s -> %s\n",
+					SUMMARY_WIDTH, "[up to date]",
+					pretty_peer, pretty_ref);
 			continue;
 		}
 
@@ -296,12 +320,9 @@ static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec,
 				 * commits at the remote end and likely
 				 * we were not up to date to begin with.
 				 */
-				error("remote '%s' is not an ancestor of\n"
-				      " local  '%s'.\n"
-				      " Maybe you are not up-to-date and "
-				      "need to pull first?",
-				      ref->name,
-				      ref->peer_ref->name);
+				fprintf(stderr, " ! %-*s %s -> %s (non-fast forward)\n",
+						SUMMARY_WIDTH, "[rejected]",
+						pretty_peer, pretty_ref);
 				ret = -2;
 				continue;
 			}
@@ -325,14 +346,40 @@ static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec,
 					old_hex, new_hex, ref->name);
 		}
 		if (will_delete_ref)
-			fprintf(stderr, "deleting '%s'\n", ref->name);
+			fprintf(stderr, " - %-*s %s\n",
+				SUMMARY_WIDTH, "[deleting]",
+				pretty_ref);
+		else if (is_null_sha1(ref->old_sha1)) {
+			const char *msg;
+
+			if (!prefixcmp(ref->name, "refs/tags/"))
+				msg = "[new tag]";
+			else
+				msg = "[new branch]";
+			fprintf(stderr, " * %-*s %s -> %s\n",
+				SUMMARY_WIDTH, msg,
+				pretty_peer, pretty_ref);
+		}
 		else {
-			fprintf(stderr, "updating '%s'", ref->name);
-			if (strcmp(ref->name, ref->peer_ref->name))
-				fprintf(stderr, " using '%s'",
-					ref->peer_ref->name);
-			fprintf(stderr, "\n  from %s\n  to   %s\n",
-				old_hex, new_hex);
+			char quickref[83];
+			char type = ' ';
+			const char *msg = "";
+
+			strcpy(quickref, find_unique_abbrev(ref->old_sha1, DEFAULT_ABBREV));
+			if (ref_newer(ref->peer_ref->new_sha1, ref->old_sha1))
+				strcat(quickref, "..");
+			else {
+				strcat(quickref, "...");
+				type = '+';
+				msg = " (forced update)";
+			}
+			strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
+
+			fprintf(stderr, " %c %-*s %s -> %s%s\n",
+				type,
+				SUMMARY_WIDTH, quickref,
+				pretty_peer, pretty_ref,
+				msg);
 		}
 	}
 
@@ -460,7 +507,7 @@ int send_pack(struct send_pack_args *my_args,
 	verify_remote_names(nr_heads, heads);
 
 	conn = git_connect(fd, dest, args.receivepack, args.verbose ? CONNECT_VERBOSE : 0);
-	ret = do_send_pack(fd[0], fd[1], remote, nr_heads, heads);
+	ret = do_send_pack(fd[0], fd[1], remote, dest, nr_heads, heads);
 	close(fd[0]);
 	close(fd[1]);
 	ret |= finish_connect(conn);
-- 
1.5.3.5.1530.g7353

^ permalink raw reply related

* [PATCH 0/3] more terse push output
From: Jeff King @ 2007-11-05  5:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nicolas Pitre, Johannes Schindelin

Here are some patches to match push output to the new fetch output. The
entire output of "git-push" for my test repo now looks like this:

To file:///tmp/parent
 + f3325dc...3b91d1c hasforce -> mirror/hasforce (forced update)
   f3325dc..bb022dc  master -> mirror/master
 ! [rejected]        needsforce -> mirror/needsforce (non-fast forward)
 * [new branch]      newbranch -> mirror/newbranch
 * [new tag]         v1.0 -> v1.0
Counting objects: 5, done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.

(where I'm mirroring the heads in refs/heads/mirror/* to show off the name
mapping).

The interesting part is in the first patch; the other two are just
removing clutter on stderr. The patches are based on 'next' to follow
Daniel's send-pack work. I'm happy to hold on to them and rebase once
things settle down in this area.

A few caveats:

  - the output is generated by send-pack, so it's actually "here's what
    I'm about to do" rather than "here's what has happened or is
    happening." receive-pack could generate more accurate results
    (including marking rejections based on hooks), but it has no
    knowledge of the name mapping (so it can't say "foo -> other/foo").
    Right now receive-pack generates 'error: blah blah blah' as it
    always has.

  - the name mapping is perhaps superfluous here, since most of the time
    people are just pushing using the same branch name. But it matches
    the new fetch output, and if you do use a refspec, it's a lot more
    clear.

  - this only covers send-pack, since that is where we do the ref
    matching. Presumably it would be possible to cover pushing over http
    and rsync, but it would have to be totally separate code.

  - no code is shared with the git-fetch implementation (they just
    happen to use the same format). The code is short enough that I
    think it would just end up more confusing to try to factor out the
    commonality.

  - the 'ref is not up-to-date, maybe you need to push' message has gone
    away in favor of the terse '[rejected] ... (non-fast forward)'. I
    know there was some discussion recently of enhancing that message.
    Is this perhaps too terse?

-Peff

^ permalink raw reply

* [PATCH] Add more tests for git-clean
From: Shawn Bohrer @ 2007-11-05  4:28 UTC (permalink / raw)
  To: gitster; +Cc: madcoder, git, Shawn Bohrer

Signed-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>
---
 t/t7300-clean.sh |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 105 insertions(+), 0 deletions(-)

On Sun, Nov 04, 2007 at 04:17:47PM -0800, Junio C Hamano wrote:
>       ...
>       ( cd src && git-clean ) &&
>       ...
>
> would be the best way to write this.

Agreed here is an updated patch that does this.

diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 8697213..25d3102 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -39,6 +39,93 @@ test_expect_success 'git-clean' '
 
 '
 
+test_expect_success 'git-clean src/' '
+
+	mkdir -p build docs &&
+	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
+	git-clean src/ &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test -f a.out &&
+	test ! -f src/part3.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+
+test_expect_success 'git-clean src/ src/' '
+
+	mkdir -p build docs &&
+	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
+	git-clean src/ src/ &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test -f a.out &&
+	test ! -f src/part3.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+
+test_expect_success 'git-clean with prefix' '
+
+	mkdir -p build docs &&
+	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
+	(cd src/ && git-clean) &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test -f a.out &&
+	test ! -f src/part3.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+test_expect_success 'git-clean -d with prefix and path' '
+
+	mkdir -p build docs src/feature &&
+	touch a.out src/part3.c src/feature/file.c docs/manual.txt obj.o build/lib.so &&
+	(cd src/ && git-clean -d feature/) &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test -f a.out &&
+	test -f src/part3.c &&
+	test ! -f src/feature/file.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+
+test_expect_success 'git-clean symbolic link' '
+
+	mkdir -p build docs &&
+	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
+	ln -s docs/manual.txt src/part4.c
+	git-clean &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test ! -f a.out &&
+	test ! -f src/part3.c &&
+	test ! -f src/part4.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+
 test_expect_success 'git-clean -n' '
 
 	mkdir -p build docs &&
@@ -73,6 +160,24 @@ test_expect_success 'git-clean -d' '
 
 '
 
+test_expect_success 'git-clean -d src/ examples/' '
+
+	mkdir -p build docs examples &&
+	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so examples/1.c &&
+	git-clean -d src/ examples/ &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test -f a.out &&
+	test ! -f src/part3.c &&
+	test ! -f examples/1.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+
 test_expect_success 'git-clean -x' '
 
 	mkdir -p build docs &&
-- 
1.5.3.GIT

^ permalink raw reply related

* [PATCH] remove dead code from the csum-file interface
From: Nicolas Pitre @ 2007-11-05  3:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

The provided name argument is always constant and valid in every 
caller's context, so no need to have an array of PATH_MAX chars to copy 
it into when a simple pointer will do.  Unfortunately that means getting 
rid of wascally wabbits too.

The 'error' field is also unused.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
diff --git a/csum-file.c b/csum-file.c
index b445e6a..9728a99 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -88,22 +88,12 @@ struct sha1file *sha1fd(int fd, const char *name)
 
 struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp)
 {
-	struct sha1file *f;
-	unsigned len;
-
-	f = xmalloc(sizeof(*f));
-
-	len = strlen(name);
-	if (len >= PATH_MAX)
-		die("you wascally wabbit, you");
-	f->namelen = len;
-	memcpy(f->name, name, len+1);
-
+	struct sha1file *f = xmalloc(sizeof(*f));
 	f->fd = fd;
-	f->error = 0;
 	f->offset = 0;
 	f->total = 0;
 	f->tp = tp;
+	f->name = name;
 	f->do_crc = 0;
 	SHA1_Init(&f->ctx);
 	return f;
diff --git a/csum-file.h b/csum-file.h
index a38cc3a..1af7656 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -5,12 +5,12 @@ struct progress;
 
 /* A SHA1-protected file */
 struct sha1file {
-	int fd, error;
-	unsigned int offset, namelen;
+	int fd;
+	unsigned int offset;
 	SHA_CTX ctx;
 	off_t total;
 	struct progress *tp;
-	char name[PATH_MAX];
+	const char *name;
 	int do_crc;
 	uint32_t crc32;
 	unsigned char buffer[8192];

^ permalink raw reply related

* [PATCH] Use parseopts in builtin-push
From: Daniel Barkalow @ 2007-11-05  3:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 builtin-push.c |   88 +++++++++++++++++++++++---------------------------------
 1 files changed, 36 insertions(+), 52 deletions(-)

diff --git a/builtin-push.c b/builtin-push.c
index 4b39ef3..2c56195 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -7,8 +7,12 @@
 #include "builtin.h"
 #include "remote.h"
 #include "transport.h"
+#include "parse-options.h"
 
-static const char push_usage[] = "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
+static const char * const push_usage[] = {
+	"git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
+	NULL,
+};
 
 static int thin, verbose;
 static const char *receivepack;
@@ -85,63 +89,43 @@ static int do_push(const char *repo, int flags)
 
 int cmd_push(int argc, const char **argv, const char *prefix)
 {
-	int i;
 	int flags = 0;
+	int all = 0;
+	int dry_run = 0;
+	int force = 0;
+	int tags = 0;
 	const char *repo = NULL;	/* default repository */
 
-	for (i = 1; i < argc; i++) {
-		const char *arg = argv[i];
+	struct option options[] = {
+		OPT__VERBOSE(&verbose),
+		OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
+		OPT_BOOLEAN( 0 , "all", &all, "push all refs"),
+		OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
+		OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"),
+		OPT_BOOLEAN('f', "force", &force, "force updates"),
+		OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
+		OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
+		OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
+		OPT_END()
+	};
 
-		if (arg[0] != '-') {
-			repo = arg;
-			i++;
-			break;
-		}
-		if (!strcmp(arg, "-v")) {
-			verbose=1;
-			continue;
-		}
-		if (!prefixcmp(arg, "--repo=")) {
-			repo = arg+7;
-			continue;
-		}
-		if (!strcmp(arg, "--all")) {
-			flags |= TRANSPORT_PUSH_ALL;
-			continue;
-		}
-		if (!strcmp(arg, "--dry-run")) {
-			flags |= TRANSPORT_PUSH_DRY_RUN;
-			continue;
-		}
-		if (!strcmp(arg, "--tags")) {
-			add_refspec("refs/tags/*");
-			continue;
-		}
-		if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
-			flags |= TRANSPORT_PUSH_FORCE;
-			continue;
-		}
-		if (!strcmp(arg, "--thin")) {
-			thin = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--no-thin")) {
-			thin = 0;
-			continue;
-		}
-		if (!prefixcmp(arg, "--receive-pack=")) {
-			receivepack = arg + 15;
-			continue;
-		}
-		if (!prefixcmp(arg, "--exec=")) {
-			receivepack = arg + 7;
-			continue;
-		}
-		usage(push_usage);
+	argc = parse_options(argc, argv, options, push_usage, 0);
+
+	if (force)
+		flags |= TRANSPORT_PUSH_FORCE;
+	if (dry_run)
+		flags |= TRANSPORT_PUSH_DRY_RUN;
+	if (tags)
+		add_refspec("refs/tags/*");
+	if (all)
+		flags |= TRANSPORT_PUSH_ALL;
+
+	if (argc > 0) {
+		repo = argv[0];
+		set_refspecs(argv + 1, argc - 1);
 	}
-	set_refspecs(argv + i, argc - i);
 	if ((flags & TRANSPORT_PUSH_ALL) && refspec)
-		usage(push_usage);
+		usage_with_options(push_usage, options);
 
 	return do_push(repo, flags);
 }
-- 
1.5.3.5.1528.gb6568-dirty

^ permalink raw reply related

* [PATCH] Use parseopts in builtin-fetch
From: Daniel Barkalow @ 2007-11-05  3:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
I mostly did this and the next one for practice with the API. I'm 
impressed that "git fetch -vv" is even handled correctly without anything 
special. Now that I've done it, assuming I did it right, it might as well 
get added to the series.

 builtin-fetch.c |   95 +++++++++++++++---------------------------------------
 1 files changed, 27 insertions(+), 68 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index 6b1750d..a079cb0 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -8,8 +8,12 @@
 #include "path-list.h"
 #include "remote.h"
 #include "transport.h"
+#include "parse-options.h"
 
-static const char fetch_usage[] = "git-fetch [-a | --append] [--upload-pack <upload-pack>] [-f | --force] [--no-tags] [-t | --tags] [-k | --keep] [-u | --update-head-ok] [--depth <depth>] [-v | --verbose] [<repository> <refspec>...]";
+static const char * const fetch_usage[] = {
+	"git-fetch [option] [<repository> <refspec>...]",
+	NULL
+};
 
 static int append, force, tags, no_tags, update_head_ok, verbose, quiet;
 static char *default_rla = NULL;
@@ -470,71 +474,21 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	int cmd_len = 0;
 	const char *depth = NULL, *upload_pack = NULL;
 	int keep = 0;
-
-	for (i = 1; i < argc; i++) {
-		const char *arg = argv[i];
-		cmd_len += strlen(arg);
-
-		if (arg[0] != '-')
-			break;
-		if (!strcmp(arg, "--append") || !strcmp(arg, "-a")) {
-			append = 1;
-			continue;
-		}
-		if (!prefixcmp(arg, "--upload-pack=")) {
-			upload_pack = arg + 14;
-			continue;
-		}
-		if (!strcmp(arg, "--upload-pack")) {
-			i++;
-			if (i == argc)
-				usage(fetch_usage);
-			upload_pack = argv[i];
-			continue;
-		}
-		if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
-			force = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--no-tags")) {
-			no_tags = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--tags") || !strcmp(arg, "-t")) {
-			tags = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--keep") || !strcmp(arg, "-k")) {
-			keep = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--update-head-ok") || !strcmp(arg, "-u")) {
-			update_head_ok = 1;
-			continue;
-		}
-		if (!prefixcmp(arg, "--depth=")) {
-			depth = arg + 8;
-			continue;
-		}
-		if (!strcmp(arg, "--depth")) {
-			i++;
-			if (i == argc)
-				usage(fetch_usage);
-			depth = argv[i];
-			continue;
-		}
-		if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) {
-			quiet = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
-			verbose++;
-			continue;
-		}
-		usage(fetch_usage);
-	}
-
-	for (j = i; j < argc; j++)
+	struct option options[] = {
+		OPT__VERBOSE(&verbose),
+		OPT_BOOLEAN('a', "append", &append, "append fetched data to exisitng FETCH_HEAD"),
+		OPT_BOOLEAN('f', "force", &force, "force"),
+		OPT_BOOLEAN( 0 , "no-tags", &no_tags, "don't fetch tags"),
+		OPT_BOOLEAN('t', "tags", &tags, "fetch all tags"),
+		OPT_BOOLEAN('k', "keep", &keep, "keep pack file"),
+		OPT_STRING( 0, "depth", &depth, "depth", "deepen the repository by <depth> commits"),
+		OPT_BOOLEAN('u', "update-head-ok", &update_head_ok, "allow updating head"),
+		OPT_BOOLEAN('q', "quiet", &quiet, "fetch silently"),
+		OPT_STRING( 0 , "upload-pack", &upload_pack, "upload-pack", "remote executable for git-upload-pack"),
+		OPT_END(),
+	};
+
+	for (j = 1; j < argc; j++)
 		cmd_len += strlen(argv[j]);
 
 	default_rla = xmalloc(cmd_len + 5 + argc + 1);
@@ -545,12 +499,16 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 		rla_offset += strlen(argv[j]) + 1;
 	}
 
-	if (i == argc)
+	argc = parse_options(argc, argv, options, fetch_usage, 0);
+
+	if (argc == 0)
 		remote = remote_get(NULL);
 	else
-		remote = remote_get(argv[i++]);
+		remote = remote_get(argv[0]);
 
 	transport = transport_get(remote, remote->url[0]);
+	if (!transport)
+		die("couldn't get transport");
 	if (verbose >= 2)
 		transport->verbose = 1;
 	if (quiet)
@@ -565,6 +523,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	if (!transport->url)
 		die("Where do you want to fetch from today?");
 
+	i = 1;
 	if (i < argc) {
 		int j = 0;
 		refs = xcalloc(argc - i + 1, sizeof(const char *));
-- 
1.5.3.5.1528.gb6568-dirty

^ permalink raw reply related

* [PATCH] make display of total transferred more accurate
From: Nicolas Pitre @ 2007-11-05  3:15 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

The throughput display needs a delay period before accounting and 
displaying anything.  Yet it might be called after some amount of data 
has already been transferred.  The display of total data is therefore 
accounted late and therefore smaller than the reality.

Let's call display_throughput() with an absolute amount of transferred 
data instead of a relative number, and let the throughput code find the 
relative amount of data by itself as needed.  This way the displayed 
total is always exact.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
diff --git a/csum-file.c b/csum-file.c
index 3729e73..b445e6a 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -18,7 +18,8 @@ static void sha1flush(struct sha1file *f, unsigned int count)
 	for (;;) {
 		int ret = xwrite(f->fd, buf, count);
 		if (ret > 0) {
-			display_throughput(f->tp, ret);
+			f->total += ret;
+			display_throughput(f->tp, f->total);
 			buf = (char *) buf + ret;
 			count -= ret;
 			if (count)
@@ -101,6 +102,7 @@ struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp
 	f->fd = fd;
 	f->error = 0;
 	f->offset = 0;
+	f->total = 0;
 	f->tp = tp;
 	f->do_crc = 0;
 	SHA1_Init(&f->ctx);
diff --git a/csum-file.h b/csum-file.h
index 4d1b231..a38cc3a 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -8,6 +8,7 @@ struct sha1file {
 	int fd, error;
 	unsigned int offset, namelen;
 	SHA_CTX ctx;
+	off_t total;
 	struct progress *tp;
 	char name[PATH_MAX];
 	int do_crc;
diff --git a/index-pack.c b/index-pack.c
index 715a5bb..581a7f5 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -87,9 +87,9 @@ static void *fill(int min)
 				die("early EOF");
 			die("read error on input: %s", strerror(errno));
 		}
-		if (from_stdin)
-			display_throughput(progress, ret);
 		input_len += ret;
+		if (from_stdin)
+			display_throughput(progress, consumed_bytes + input_len);
 	} while (input_len < min);
 	return input_buffer;
 }
diff --git a/progress.c b/progress.c
index 3f6a602..a963bd8 100644
--- a/progress.c
+++ b/progress.c
@@ -14,11 +14,10 @@
 #define TP_IDX_MAX      8
 
 struct throughput {
+	off_t prev_total;
 	struct timeval prev_tv;
-	off_t total;
-	unsigned long count;
-	unsigned long avg_bytes;
-	unsigned long last_bytes[TP_IDX_MAX];
+	unsigned int avg_bytes;
+	unsigned int last_bytes[TP_IDX_MAX];
 	unsigned int avg_misecs;
 	unsigned int last_misecs[TP_IDX_MAX];
 	unsigned int idx;
@@ -110,7 +109,7 @@ static int display(struct progress *progress, unsigned n, int done)
 	return 0;
 }
 
-void display_throughput(struct progress *progress, unsigned long n)
+void display_throughput(struct progress *progress, off_t total)
 {
 	struct throughput *tp;
 	struct timeval tv;
@@ -124,14 +123,13 @@ void display_throughput(struct progress *progress, unsigned long n)
 
 	if (!tp) {
 		progress->throughput = tp = calloc(1, sizeof(*tp));
-		if (tp)
+		if (tp) {
+			tp->prev_total = total;
 			tp->prev_tv = tv;
+		}
 		return;
 	}
 
-	tp->total += n;
-	tp->count += n;
-
 	/*
 	 * We have x = bytes and y = microsecs.  We want z = KiB/s:
 	 *
@@ -152,37 +150,37 @@ void display_throughput(struct progress *progress, unsigned long n)
 
 	if (misecs > 512) {
 		int l = sizeof(tp->display);
+		unsigned int count = total - tp->prev_total;
+		tp->prev_total = total;
 		tp->prev_tv = tv;
-		tp->avg_bytes += tp->count;
+		tp->avg_bytes += count;
 		tp->avg_misecs += misecs;
 
-		if (tp->total > 1 << 30) {
+		if (total > 1 << 30) {
 			l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
-				      (int)(tp->total >> 30),
-				      (int)(tp->total & ((1 << 30) - 1)) / 10737419);
-		} else if (tp->total > 1 << 20) {
+				      (int)(total >> 30),
+				      (int)(total & ((1 << 30) - 1)) / 10737419);
+		} else if (total > 1 << 20) {
 			l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
-				      (int)(tp->total >> 20),
-				      ((int)(tp->total & ((1 << 20) - 1))
+				      (int)(total >> 20),
+				      ((int)(total & ((1 << 20) - 1))
 				       * 100) >> 20);
-		} else if (tp->total > 1 << 10) {
+		} else if (total > 1 << 10) {
 			l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
-				      (int)(tp->total >> 10),
-				      ((int)(tp->total & ((1 << 10) - 1))
+				      (int)(total >> 10),
+				      ((int)(total & ((1 << 10) - 1))
 				       * 100) >> 10);
 		} else {
-			l -= snprintf(tp->display, l, ", %u bytes",
-				      (int)tp->total);
+			l -= snprintf(tp->display, l, ", %u bytes", (int)total);
 		}
 		snprintf(tp->display + sizeof(tp->display) - l, l,
-			 " | %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
+			 " | %u KiB/s", tp->avg_bytes / tp->avg_misecs);
 
 		tp->avg_bytes -= tp->last_bytes[tp->idx];
 		tp->avg_misecs -= tp->last_misecs[tp->idx];
-		tp->last_bytes[tp->idx] = tp->count;
+		tp->last_bytes[tp->idx] = count;
 		tp->last_misecs[tp->idx] = misecs;
 		tp->idx = (tp->idx + 1) % TP_IDX_MAX;
-		tp->count = 0;
 
 		if (progress->last_value != -1 && progress_update)
 			display(progress, progress->last_value, 0);
diff --git a/progress.h b/progress.h
index 61cb68d..3912969 100644
--- a/progress.h
+++ b/progress.h
@@ -3,7 +3,7 @@
 
 struct progress;
 
-void display_throughput(struct progress *progress, unsigned long n);
+void display_throughput(struct progress *progress, off_t total);
 int display_progress(struct progress *progress, unsigned n);
 struct progress *start_progress(const char *title, unsigned total);
 struct progress *start_progress_delay(const char *title, unsigned total,

^ permalink raw reply related

* [StGit PATCH 5/5] Add "stg coalesce"
From: Karl Hasselström @ 2007-11-05  3:15 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20071105030847.6108.44653.stgit@yoghurt>

It coalesces two or more consecutive applied patches, with no need to
touch index/worktree, and no possibiliy of conflicts.

Future improvements could relax the "consecutive" and "applied"
restrictions, by building a new chain of commits just like "stg push"
will do once it's been converted to the new infrastructure.

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 stgit/commands/coalesce.py |   87 ++++++++++++++++++++++++++++++++++++++++++++
 stgit/main.py              |    2 +
 stgit/utils.py             |   11 ++++++
 t/t2600-coalesce.sh        |   31 ++++++++++++++++
 4 files changed, 131 insertions(+), 0 deletions(-)
 create mode 100644 stgit/commands/coalesce.py
 create mode 100755 t/t2600-coalesce.sh


diff --git a/stgit/commands/coalesce.py b/stgit/commands/coalesce.py
new file mode 100644
index 0000000..11b7b52
--- /dev/null
+++ b/stgit/commands/coalesce.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+
+__copyright__ = """
+Copyright (C) 2007, Karl Hasselström <kha@treskal.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+from optparse import make_option
+from stgit.out import *
+from stgit import utils
+from stgit.commands import common
+from stgit.lib import git, transaction
+
+help = 'coalesce two or more patches into one'
+usage = """%prog [options] <patches>
+
+Coalesce two or more patches, creating one big patch that contains all
+their changes. The patches must all be applied, and must be
+consecutive."""
+
+directory = common.DirectoryHasRepositoryLib()
+options = [make_option('-n', '--name', help = 'name of coalesced patch'),
+           make_option('-m', '--message',
+                       help = 'commit message of coalesced patch')]
+
+def _coalesce(stack, name, msg, patches):
+    applied = stack.patchorder.applied
+
+    # Make sure the patches are consecutive.
+    applied_ix = dict((applied[i], i) for i in xrange(len(applied)))
+    ixes = list(sorted(applied_ix[p] for p in patches))
+    i0, i1 = ixes[0], ixes[-1]
+    if i1 - i0 + 1 != len(patches):
+        raise common.CmdException('The patches must be consecutive')
+
+    # Make a commit for the coalesced patch.
+    def bad_name(pn):
+        return pn not in patches and stack.patches.exists(pn)
+    if name and bad_name(name):
+        raise common.CmdException('Patch name "%s" already taken')
+    ps = [stack.patches.get(pn) for pn in applied[i0:i1+1]]
+    if msg == None:
+        msg = '\n\n'.join('%s\n\n%s' % (p.name.ljust(70, '-'),
+                                        p.commit.data.message)
+                          for p in ps)
+        msg = utils.edit_string(msg, '.stgit-coalesce.txt').strip()
+    if not name:
+        name = utils.make_patch_name(msg, bad_name)
+    cd = git.Commitdata(tree = ps[-1].commit.data.tree,
+                        parents = ps[0].commit.data.parents, message = msg)
+
+    # Rewrite refs.
+    trans = transaction.StackTransaction(stack, 'coalesce')
+    parent = trans.patches[name] = stack.repository.commit(cd)
+    trans.applied = applied[:i0]
+    trans.applied.append(name)
+    for pn in applied[i0:i1+1]:
+        trans.patches[pn] = None
+    for pn in applied[i1+1:]:
+        p = stack.patches.get(pn)
+        parent = trans.patches[pn] = stack.repository.commit(
+            p.commit.data.set_parent(parent))
+        trans.applied.append(pn)
+    trans.run()
+
+def func(parser, options, args):
+    stack = directory.repository.current_stack
+    applied = set(stack.patchorder.applied)
+    for pn in args:
+        if not pn in applied:
+            raise common.CmdException('%s is not applied' % pn)
+    patches = set(args)
+    if len(patches) < 2:
+        raise common.CmdException('Need at least two patches')
+    _coalesce(stack, options.name, options.message, args)
diff --git a/stgit/main.py b/stgit/main.py
index 9ef6d44..ac46cde 100644
--- a/stgit/main.py
+++ b/stgit/main.py
@@ -65,6 +65,7 @@ commands = Commands({
     'diff':             'diff',
     'clean':            'clean',
     'clone':            'clone',
+    'coalesce':         'coalesce',
     'commit':           'commit',
     'edit':             'edit',
     'export':           'export',
@@ -109,6 +110,7 @@ stackcommands = (
     'assimilate',
     'branch',
     'clean',
+    'coalesce',
     'commit',
     'float',
     'goto',
diff --git a/stgit/utils.py b/stgit/utils.py
index b3f6232..688276c 100644
--- a/stgit/utils.py
+++ b/stgit/utils.py
@@ -189,6 +189,17 @@ def call_editor(filename):
         raise EditorException, 'editor failed, exit code: %d' % err
     out.done()
 
+def edit_string(s, filename):
+    f = file(filename, 'w')
+    f.write(s)
+    f.close()
+    call_editor(filename)
+    f = file(filename)
+    s = f.read()
+    f.close()
+    os.remove(filename)
+    return s
+
 def patch_name_from_msg(msg):
     """Return a string to be used as a patch name. This is generated
     from the top line of the string passed as argument."""
diff --git a/t/t2600-coalesce.sh b/t/t2600-coalesce.sh
new file mode 100755
index 0000000..f13a309
--- /dev/null
+++ b/t/t2600-coalesce.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='Run "stg coalesce"'
+
+. ./test-lib.sh
+
+test_expect_success 'Initialize StGit stack' '
+    stg init &&
+    for i in 0 1 2 3; do
+        stg new p$i -m "foo $i" &&
+        echo "foo $i" >> foo.txt &&
+        git add foo.txt &&
+        stg refresh
+    done
+'
+
+test_expect_success 'Coalesce some patches' '
+    [ "$(echo $(stg applied))" = "p0 p1 p2 p3" ] &&
+    [ "$(echo $(stg unapplied))" = "" ] &&
+    stg coalesce --name=q0 --message="wee woo" p1 p2 &&
+    [ "$(echo $(stg applied))" = "p0 q0 p3" ] &&
+    [ "$(echo $(stg unapplied))" = "" ]
+'
+
+test_expect_success 'Coalesce at stack top' '
+    stg coalesce --name=q1 --message="wee woo wham" q0 p3 &&
+    [ "$(echo $(stg applied))" = "p0 q1" ] &&
+    [ "$(echo $(stg unapplied))" = "" ]
+'
+
+test_done

^ 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