* Re: [PATCH 8/8] gitweb: Highlight combined diffs
From: Michal Kiedrowicz @ 2012-02-13 6:48 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <m3ty2wsyt6.fsf@localhost.localdomain>
Jakub Narebski <jnareb@gmail.com> wrote:
> Michał Kiedrowicz <michal.kiedrowicz@gmail.com> writes:
>
> > The highlightning of combined diffs is currently disabled. This is
> > because output from a combined diff is much harder to highlight
> > because it's not obvious which removed and added lines should be
> > compared.
> >
> > Moreover, code that compares added and removed lines doesn't care
> > about combined diffs. It only skips first +/- character, treating
> > second +/- as a line content.
> >
> > Let's start with a simple case: only highlight changes that come
> > from one parent, i.e. when every removed line has a corresponding
> > added line for the same parent. This way the highlightning cannot
> > get wrong. For example, following diffs would be highlighted:
> >
> > - removed line for first parent
> > + added line for first parent
> > context line
> > -removed line for second parent
> > +added line for second parent
> >
> > or
> >
> > - removed line for first parent
> > -removed line for second parent
> > + added line for first parent
> > +added line for second parent
> >
> > but following output will not:
> >
> > - removed line for first parent
> > -removed line for second parent
> > +added line for second parent
> > ++added line for both parents
> >
> That is a very reasonable approach.
Thanks.
>
> > Further changes may introduce more intelligent approach that better
> > handles combined diffs.
> >
> > Signed-off-by: Michał Kiedrowicz <michal.kiedrowicz@gmail.com>
> > ---
> > gitweb/gitweb.perl | 40 +++++++++++++++++++++++++++++++++++++---
> > 1 files changed, 37 insertions(+), 3 deletions(-)
> >
> > diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> > index 1a5b454..2b6cb9e 100755
> > --- a/gitweb/gitweb.perl
> > +++ b/gitweb/gitweb.perl
> > @@ -4944,13 +4944,16 @@ sub esc_html_mark_range {
> >
> > # Format removed and added line, mark changed part and HTML-format
> > them. sub format_rem_add_line {
> > - my ($rem, $add) = @_;
> > + my ($rem, $add, $is_combined) = @_;
> > my @r = split(//, $rem);
> > my @a = split(//, $add);
> > my ($esc_rem, $esc_add);
> > my ($prefix, $suffix_rem, $suffix_add) = (1, $#r, $#a);
> > my ($prefix_is_space, $suffix_is_space) = (1, 1);
> >
> > + # In combined diff we must ignore two +/- characters.
> > + $prefix = 2 if ($is_combined);
> > +
>
> Errr... actually number of prefix is equalt to number of parents, so
> it might be in case of octopus merge more than 2.
OK
>
> > while ($prefix < @r && $prefix < @a) {
> > last if ($r[$prefix] ne $a[$prefix]);
> >
> > @@ -4988,11 +4991,42 @@ sub format_ctx_rem_add_lines {
> > my ($ctx, $rem, $add, $is_combined) = @_;
> > my (@new_ctx, @new_rem, @new_add);
> > my $num_add_lines = @$add;
> > + my $can_highlight;
> > +
> > + # Highlight if every removed line has a corresponding
> > added line.
> > + if ($num_add_lines > 0 && $num_add_lines == @$rem) {
> > + $can_highlight = 1;
> > +
> > + # Highlight lines in combined diff only if the
> > chunk contains
> > + # diff between the same version, e.g.
> > + #
> > + # - a
> > + # - b
> > + # + c
> > + # + d
> > + #
> > + # Otherwise the highlightling would be confusing.
> > + if ($is_combined) {
> > + for (my $i = 0; $i < $num_add_lines; $i++)
> > {
> > + my $prefix_rem =
> > substr($rem->[$i], 0, 2);
> > + my $prefix_add =
> > substr($add->[$i], 0, 2); +
> > + $prefix_rem =~ s/-/+/g;
> > +
> > + if ($prefix_rem ne $prefix_add) {
> > + $can_highlight = 0;
> > + last;
>
> Nb. this assumes that we cannot refine and highlight something like
> this:
>
> # - a
> # - b
> # + c
> # ++ d
>
> But perhaps this is better left for future improvemnt.
I can add a patch for that at the end of this series.
>
> > + }
> > + }
> > + }
> > + } else {
> > + $can_highlight = 0;
> > + }
>
> This 'else' would be not necessary if $can_highlight was initialized
> to 0.
>
OK.
> >
> > - if (!$is_combined && $num_add_lines > 0 && $num_add_lines
> > == @$rem) {
> > + if ($can_highlight) {
> > for (my $i = 0; $i < $num_add_lines; $i++) {
> > my ($line_rem, $line_add) =
> > format_rem_add_line(
> > - $rem->[$i], $add->[$i]);
> > + $rem->[$i], $add->[$i],
> > $is_combined); push @new_rem, $line_rem;
> > push @new_add, $line_add;
>
> O.K.
>
Thanks for your thorough review.
^ permalink raw reply
* Re: [PATCH 6/8] gitweb: Highlight interesting parts of diff
From: Michal Kiedrowicz @ 2012-02-13 6:54 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <m3lio8s57v.fsf@localhost.localdomain>
Jakub Narebski <jnareb@gmail.com> wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
> > Michał Kiedrowicz <michal.kiedrowicz@gmail.com> writes:
>
> > > +# Highlight characters from $prefix to $suffix and escape HTML.
> > > +# $str is a reference to the array of characters.
> > > +sub esc_html_mark_range {
> > > + my ($str, $prefix, $suffix) = @_;
> > > +
> > > + # Don't generate empty <span> element.
> > > + if ($prefix == $suffix + 1) {
> > > + return esc_html(join('', @$str), -nbsp=>1);
> > > + }
> > > +
> > > + my $before = join('', @{$str}[0..($prefix - 1)]);
> > > + my $marked = join('', @{$str}[$prefix..$suffix]);
> > > + my $after = join('', @{$str}[($suffix + 1)..$#{$str}]);
> >
> > Eeeeeek! First you split into letters, in caller at that, then
> > join? Why not pass striung ($str suggests string not array of
> > characters), and use substr instead?
> >
> > [Please disregard this and the next paragraph at first reading]
> >
> > > +
> > > + return esc_html($before, -nbsp=>1) .
> > > + $cgi->span({-class=>'marked'}, esc_html($marked,
> > > -nbsp=>1)) .
> > > + esc_html($after,-nbsp=>1);
> > > +}
> >
> > Anyway I have send to git mailing list a patch series, which in one
> > of patches adds esc_html_match_hl($str, $regexp) to highlight
> > matches in a string.
Yeah, I saw that but after seeing that they accept different arguments
I decided to leave them alone.
> Your esc_html_mark_range(), after a
> > generalization, could be used as underlying "engine".
> >
> > Something like this, perhaps (untested):
I think I'll leave it to you after merging both these series to
master :)
> >
> > # Highlight selected fragments of string, using given CSS class,
> > # and escape HTML. It is assumed that fragments do not overlap.
> > # Regions are passed as list of pairs (array references).
> > sub esc_html_hl {
> > my ($str, $css_class, @sel) = @_;
> > return esc_html($str) unless @sel;
> >
> > my $out = '';
> > my $pos = 0;
> >
> > for my $s (@sel) {
> > $out .= esc_html(substr($str, $pos, $s->[0] - $pos))
> > if ($s->[0] - $pos > 0);
> > $out .= $cgi->span({-class => $css_class},
> > esc_html(substr($str, $s->[0],
> > $s->[1] - $s->[0])));
> >
> > $pos = $m->[1];
> > }
> > $out .= esc_html(substr($str, $pos))
> > if ($pos < length($str));
> >
> > return $out;
> > }
>
> Actually we can accomodate both operating on string and operating on
> array of characters in a single subroutine. Though it can be left for
> later commit, anyway...
>
> # Highlight selected fragments of string, using given CSS class,
> # and escape HTML. It is assumed that fragments do not overlap.
> # Regions are passed as list of pairs (array references).
> sub esc_html_hl {
> my ($sth, $css_class, @sel) = @_;
>
> if (!@sel) {
> if (ref($sth) eq "ARRAY") {
> return esc_html(join('', @$sth), -nbsp=>1);
> } else {
> return esc_html($sth, -nbsp=>1);
> }
>
> if (ref($sth) eq "ARRAY") {
> return esc_html_hl_gen($sth,
> sub {
> my ($arr, $from, $to) = @_;
> return join('', @{$arr}[$from..$to]);
> },
> scalar @{$arr}, $css_class, @sel);
> } else {
> return esc_html_hl_gen($sth,
> sub {
> my ($str, $from, $to) = @_;
> if ($to < 0) { $to += lenght($str); };
> return substr($str, $from, $to -
> $from); },
> length($sth), $css_class, @sel);
> }
> }
>
> # Highlight selected fragments of string or array of characters
> # with given length, using provided $extr subroutine to extract
> # fragment (substring)
> sub esc_html_hl_gen {
> my ($sth, $extr, $len, $css_class, @sel) = @_;
>
> my $out = '';
> my $pos = 0;
>
> for my $s (@sel) {
> $out .= esc_html($extr->($str, $pos, $s->[0]))
> if ($s->[0] - $pos > 0);
> $out .= $cgi->span({-class => $css_class},
> esc_html($extr->($str, $s->[0],
> $s->[1])));
> $pos = $s->[1];
> }
> $out .= esc_html($extr->($str, $pos, $len))
> if ($pos < $len);
>
> return $out;
> }
>
> Or maybe I have read "Higher-Order Perl" one time too many ;-))))
>
^ permalink raw reply
* Re: Bulgarian translation of git
From: Jiang Xin @ 2012-02-13 7:12 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Ævar Arnfjörð,
Alexander Shopov (Александър Шопов)
In-Reply-To: <7vy5s7idxb.fsf@alter.siamese.dyndns.org>
2012/2/13 Junio C Hamano <gitster@pobox.com>:
> Jiang Xin <worldhello.net@gmail.com> writes:
>
>> Junio has a suggestion on how to contrib l10n for git, and you can see the
>> discussion here: http://article.gmane.org/gmane.comp.version-control.git/189584.
>>
>> Seems that the suggested git-po repo has not been setup yet, so let me
>> have a try.
>>
>> 1. Repositiry git-po is hosted on GitHub: https://github.com/gotgit/git-po/
>>
>> 2. I made a commit on the maint branch with a initial version of 'po/git.pot'
>> https://github.com/gotgit/git-po/commit/4247a7a9d39e2a74ce1d58e5eb1f5e5d87977989
This commit is based on current maint branch. Since the translated po files will
first in 1.7.10, so the initial pot file should be generated from master branch.
The pot file from the master branch has 10 new messages than from the maint
branch.
For clarity, I removed the maint and other branches except the master branch,
and made a new commit.
> Somebody needs to eyeball this commit before anything else happens on top
> of it, so that if there is a glaring mistake it can be caught before it
> spreads to affect work by translators for various languages.
So please check this commit with the updated pot file:
https://github.com/gotgit/git-po/commit/816049b7ec0e5f452c77a4c4e71e2cb40a0ccb45
Please note In this commit I removed one line from the 'po/.gitignore' file.
As a translater for Chinese, I also made a commit with the translated po file
'po/zh_CN.po' in branch master-zh-cn (merged back to master branch).
>>
>> I have a question, which version of po should be maintained? master
>> branch or maint branch.
>
> I would say for this round the git-po repository and its pot file should
> pick up whatever new translatable strings are added to 'master'.
>
> After this is merged in 1.7.10, we may want to maintain separate tracks,
> but at this moment there is no point maintaining something mergeable to
> 1.7.9.x maintenance track.
>
--
Jiang Xin
^ permalink raw reply
* Re: Bulgarian translation of git
From: Junio C Hamano @ 2012-02-13 8:07 UTC (permalink / raw)
To: Jiang Xin
Cc: Git List, Christian Stimming, Pat Thoyts, Michele Ballabio,
Alex Riesen, Miklos Vajna, Laszlo Papp, Peter Krefting,
Christian Couder, Emmanuel Trillaud, Nanako Shiraishi, Mizar,
Peter Karlsson, Mikael Magnusson, Ævar Arnfjörð,
Alexander Shopov (Александър Шопов)
In-Reply-To: <CANYiYbFYmGNE09fAeHL_uk+0s+yBapTs4BeGch7iCtWR_v9LXQ@mail.gmail.com>
Jiang Xin <worldhello.net@gmail.com> writes:
>> Somebody needs to eyeball this commit before anything else happens on top
>> of it, so that if there is a glaring mistake it can be caught before it
>> spreads to affect work by translators for various languages.
>
> So please check this commit with the updated pot file:
> https://github.com/gotgit/git-po/commit/816049b7ec0e5f452c77a4c4e71e2cb40a0ccb45
> Please note In this commit I removed one line from the 'po/.gitignore' file.
Thanks.
As far as I can tell, this adds git.pot while removes the entry to remove
it from po/.gitignore (because now it is a tracked file), but there is no
description on how this file was generated in the log message.
Please give a short description to the effect that it was mechanically
created by running xgettext on the sources as of b6b3b6a (Update draft
release notes to 1.7.10, 2012-02-10), or something like that.
Other than that, I do not immediately see anything objectionable in this
commit; I would still appreciate an extra set of eyeballs or two from
people who have worked on gitk and/or git-gui i18n/l10n infrastructure in
the past, just in case I forgot to check some obvious/trivial gotchas.
I am also Cc'ing people who participated in git-gui and gitk l10n with
more than a couple of commits to their po/ part, found by:
$ cd git-gui/po &&
git rev-list --parents HEAD . |
while read commit parent
do
git log --pretty=short $parent..$commit^2 -- :/po
done | git shortlog -n -e
(same for gitk-git)
> As a translater for Chinese, I also made a commit with the translated po file
> 'po/zh_CN.po' in branch master-zh-cn (merged back to master branch).
Thanks.
^ permalink raw reply
* Re: Bulgarian translation of git
From: Jiang Xin @ 2012-02-13 8:52 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Christian Stimming, Pat Thoyts, Michele Ballabio,
Alex Riesen, Miklos Vajna, Laszlo Papp, Peter Krefting,
Christian Couder, Emmanuel Trillaud, Nanako Shiraishi, Mizar,
Mikael Magnusson, Ævar Arnfjörð,
Alexander Shopov (Александър Шопов)
In-Reply-To: <7v8vk7gnqf.fsf@alter.siamese.dyndns.org>
2012/2/13 Junio C Hamano <gitster@pobox.com>:
> Jiang Xin <worldhello.net@gmail.com> writes:
>
>>> Somebody needs to eyeball this commit before anything else happens on top
>>> of it, so that if there is a glaring mistake it can be caught before it
>>> spreads to affect work by translators for various languages.
>>
>> So please check this commit with the updated pot file:
>> ...
Please check this commit with the updated pot file:
https://github.com/gotgit/git-po/commit/master%5E
( The commit with the amended commit message can be access using
the above URL, no longer how this commit is ammended latter.)
> As far as I can tell, this adds git.pot while removes the entry to remove
> it from po/.gitignore (because now it is a tracked file), but there is no
> description on how this file was generated in the log message.
>
> Please give a short description to the effect that it was mechanically
> created by running xgettext on the sources as of b6b3b6a (Update draft
> release notes to 1.7.10, 2012-02-10), or something like that.
I add a prefix 'l10n:' to the new amended commit log, is it OK?
$ git show --stat master^
commit b55102542911326e8191500ff6f53a2e1d52e504
Author: Jiang Xin <worldhello.net@gmail.com>
Date: Mon Feb 13 14:37:59 2012 +0800
l10n: initial git.pot for 1.7.10 upcoming release
The file 'po/git.pot' is generated using the command 'make pot'
against git v1.7.9-209-gb6b3b (Update draft release notes to 1.7.10).
Also removed the entry po/git.pot from po/.gitignore, since it is a
tracked file.
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
po/.gitignore | 1 -
po/git.pot | 3431 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 3431 insertions(+), 1 deletions(-)
--
Jiang Xin
^ permalink raw reply
* [PATCH v5 0/3] push: submodule support
From: Heiko Voigt @ 2012-02-13 9:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Fredrik Gustafsson, Jens Lehmann
I have rewritten and cleaned up the recursive submodule on-demand push
patch from Fredrik. Since this involved changing large parts of it I
have taken over the ownership. To pay credit that this is built upon
Fredriks work I have left the signed-off and mentored-by footers the
same. I hope that this is the proper way to handle such cases. If
someone comes up with a better idea I am happy to change things.
Cheers Heiko
The first iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/176328/focus=176327
The second iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/177992
The third iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/179037/focus=179048
The fourth iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/179731
Heiko Voigt (3):
Teach revision walking machinery to walk multiple times sequencially
Refactor submodule push check to use string list instead of integer
push: teach --recurse-submodules the on-demand option
.gitignore | 1 +
Documentation/git-push.txt | 14 +++-
Documentation/technical/api-revision-walking.txt | 5 +
Makefile | 1 +
builtin/push.c | 7 ++
object.c | 11 +++
object.h | 2 +
revision.c | 5 +
revision.h | 1 +
submodule.c | 70 ++++++++++++++---
submodule.h | 4 +-
t/t0062-revision-walking.sh | 33 ++++++++
t/t5531-deep-submodule-push.sh | 94 ++++++++++++++++++++++
test-revision-walking.c | 66 +++++++++++++++
transport.c | 41 +++++++++-
transport.h | 1 +
16 files changed, 338 insertions(+), 18 deletions(-)
create mode 100755 t/t0062-revision-walking.sh
create mode 100644 test-revision-walking.c
--
1.7.9.114.gead08
^ permalink raw reply
* [PATCH v5 1/3] Teach revision walking machinery to walk multiple times sequencially
From: Heiko Voigt @ 2012-02-13 9:27 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Fredrik Gustafsson, Jens Lehmann
In-Reply-To: <20120213092541.GA15585@t1405.greatnet.de>
Previously it was not possible to iterate revisions twice using the
revision walking api. We add a reset_revision_walk() which clears the
used flags. This allows us to do multiple sequencial revision walks.
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
.gitignore | 1 +
Documentation/technical/api-revision-walking.txt | 5 ++
Makefile | 1 +
object.c | 11 ++++
object.h | 2 +
revision.c | 5 ++
revision.h | 1 +
submodule.c | 2 +
t/t0062-revision-walking.sh | 33 +++++++++++
test-revision-walking.c | 66 ++++++++++++++++++++++
10 files changed, 127 insertions(+), 0 deletions(-)
create mode 100755 t/t0062-revision-walking.sh
create mode 100644 test-revision-walking.c
diff --git a/.gitignore b/.gitignore
index 3b7680e..2f09842 100644
--- a/.gitignore
+++ b/.gitignore
@@ -184,6 +184,7 @@
/test-obj-pool
/test-parse-options
/test-path-utils
+/test-revision-walking
/test-run-command
/test-sha1
/test-sigchain
diff --git a/Documentation/technical/api-revision-walking.txt b/Documentation/technical/api-revision-walking.txt
index 996da05..b7d0d9a 100644
--- a/Documentation/technical/api-revision-walking.txt
+++ b/Documentation/technical/api-revision-walking.txt
@@ -56,6 +56,11 @@ function.
returning a `struct commit *` each time you call it. The end of the
revision list is indicated by returning a NULL pointer.
+`reset_revision_walk`::
+
+ Reset the flags used by the revision walking api. You can use
+ this to do multiple sequencial revision walks.
+
Data structures
---------------
diff --git a/Makefile b/Makefile
index c457c34..bff686f 100644
--- a/Makefile
+++ b/Makefile
@@ -472,6 +472,7 @@ TEST_PROGRAMS_NEED_X += test-mktemp
TEST_PROGRAMS_NEED_X += test-obj-pool
TEST_PROGRAMS_NEED_X += test-parse-options
TEST_PROGRAMS_NEED_X += test-path-utils
+TEST_PROGRAMS_NEED_X += test-revision-walking
TEST_PROGRAMS_NEED_X += test-run-command
TEST_PROGRAMS_NEED_X += test-sha1
TEST_PROGRAMS_NEED_X += test-sigchain
diff --git a/object.c b/object.c
index 6b06297..6291ce9 100644
--- a/object.c
+++ b/object.c
@@ -275,3 +275,14 @@ void object_array_remove_duplicates(struct object_array *array)
array->nr = dst;
}
}
+
+void clear_object_flags(unsigned flags)
+{
+ int i;
+ struct object *obj;
+
+ for (i=0; i < obj_hash_size; i++) {
+ if ((obj = obj_hash[i]) && obj->flags & flags)
+ obj->flags &= ~flags;
+ }
+}
diff --git a/object.h b/object.h
index b6618d9..6a97b6b 100644
--- a/object.h
+++ b/object.h
@@ -76,4 +76,6 @@ void add_object_array(struct object *obj, const char *name, struct object_array
void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode);
void object_array_remove_duplicates(struct object_array *);
+void clear_object_flags(unsigned flags);
+
#endif /* OBJECT_H */
diff --git a/revision.c b/revision.c
index c97d834..77ce6bd 100644
--- a/revision.c
+++ b/revision.c
@@ -2061,6 +2061,11 @@ static void set_children(struct rev_info *revs)
}
}
+void reset_revision_walk()
+{
+ clear_object_flags(SEEN | ADDED | SHOWN);
+}
+
int prepare_revision_walk(struct rev_info *revs)
{
int nr = revs->pending.nr;
diff --git a/revision.h b/revision.h
index b8e9223..3535733 100644
--- a/revision.h
+++ b/revision.h
@@ -192,6 +192,7 @@ extern void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ct
const char * const usagestr[]);
extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
+extern void reset_revision_walk();
extern int prepare_revision_walk(struct rev_info *revs);
extern struct commit *get_revision(struct rev_info *revs);
extern char *get_revision_mark(const struct rev_info *revs, const struct commit *commit);
diff --git a/submodule.c b/submodule.c
index 9a28060..645ff5d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -404,6 +404,7 @@ int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remote
while ((commit = get_revision(&rev)) && !needs_pushing)
commit_need_pushing(commit, &needs_pushing);
+ reset_revision_walk();
free(sha1_copy);
strbuf_release(&remotes_arg);
@@ -741,6 +742,7 @@ static int find_first_merges(struct object_array *result, const char *path,
if (in_merge_bases(b, &commit, 1))
add_object_array(o, NULL, &merges);
}
+ reset_revision_walk();
/* Now we've got all merges that contain a and b. Prune all
* merges that contain another found merge and save them in
diff --git a/t/t0062-revision-walking.sh b/t/t0062-revision-walking.sh
new file mode 100755
index 0000000..3d98eb8
--- /dev/null
+++ b/t/t0062-revision-walking.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Heiko Voigt
+#
+
+test_description='Test revision walking api'
+
+. ./test-lib.sh
+
+cat >run_twice_expected <<-EOF
+1st
+ > add b
+ > add a
+2nd
+ > add b
+ > add a
+EOF
+
+test_expect_success 'setup' '
+ echo a > a &&
+ git add a &&
+ git commit -m "add a" &&
+ echo b > b &&
+ git add b &&
+ git commit -m "add b"
+'
+
+test_expect_success 'revision walking can be done twice' '
+ test-revision-walking run-twice > run_twice_actual
+ test_cmp run_twice_expected run_twice_actual
+'
+
+test_done
diff --git a/test-revision-walking.c b/test-revision-walking.c
new file mode 100644
index 0000000..27ad597
--- /dev/null
+++ b/test-revision-walking.c
@@ -0,0 +1,66 @@
+/*
+ * test-revision-walking.c: test revision walking API.
+ *
+ * (C) 2012 Heiko Voigt <hvoigt@hvoigt.net>
+ *
+ * This code 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.
+ */
+
+#include "cache.h"
+#include "commit.h"
+#include "diff.h"
+#include "revision.h"
+
+static void print_commit(struct commit *commit)
+{
+ struct strbuf sb = STRBUF_INIT;
+ struct pretty_print_context ctx = {0};
+ ctx.date_mode = DATE_NORMAL;
+ format_commit_message(commit, " %m %s", &sb, &ctx);
+ printf("%s\n", sb.buf);
+ strbuf_release(&sb);
+}
+
+static int run_revision_walk()
+{
+ struct rev_info rev;
+ struct commit *commit;
+ const char *argv[] = {NULL, "--all", NULL};
+ int argc = ARRAY_SIZE(argv) - 1;
+ int got_revision = 0;
+
+ init_revisions(&rev, NULL);
+ setup_revisions(argc, argv, &rev, NULL);
+ if (prepare_revision_walk(&rev))
+ die("revision walk setup failed");
+
+ while ((commit = get_revision(&rev)) != NULL) {
+ print_commit(commit);
+ got_revision = 1;
+ }
+
+ reset_revision_walk();
+ return got_revision;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 2)
+ return 1;
+
+ if (!strcmp(argv[1], "run-twice")) {
+ printf("1st\n");
+ if (!run_revision_walk())
+ return 1;
+ printf("2nd\n");
+ if (!run_revision_walk())
+ return 1;
+
+ return 0;
+ }
+
+ fprintf(stderr, "check usage\n");
+ return 1;
+}
--
1.7.9.114.gead08
^ permalink raw reply related
* [PATCH v5 2/3] Refactor submodule push check to use string list instead of integer
From: Heiko Voigt @ 2012-02-13 9:29 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Fredrik Gustafsson, Jens Lehmann
In-Reply-To: <20120213092541.GA15585@t1405.greatnet.de>
This allows us to tell the user which submodules have not been pushed.
Additionally this is helpful when we want to automatically try to push
submodules that have not been pushed.
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
submodule.c | 20 ++++++++++----------
submodule.h | 3 ++-
transport.c | 24 ++++++++++++++++++++++--
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/submodule.c b/submodule.c
index 645ff5d..3c714c2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -357,21 +357,20 @@ static void collect_submodules_from_diff(struct diff_queue_struct *q,
void *data)
{
int i;
- int *needs_pushing = data;
+ struct string_list *needs_pushing = data;
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (!S_ISGITLINK(p->two->mode))
continue;
if (submodule_needs_pushing(p->two->path, p->two->sha1)) {
- *needs_pushing = 1;
- break;
+ if (!string_list_has_string(needs_pushing, p->two->path))
+ string_list_insert(needs_pushing, p->two->path);
}
}
}
-
-static void commit_need_pushing(struct commit *commit, int *needs_pushing)
+static void commit_need_pushing(struct commit *commit, struct string_list *needs_pushing)
{
struct rev_info rev;
@@ -382,14 +381,15 @@ static void commit_need_pushing(struct commit *commit, int *needs_pushing)
diff_tree_combined_merge(commit, 1, &rev);
}
-int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
+int check_submodule_needs_pushing(unsigned char new_sha1[20],
+ const char *remotes_name, struct string_list *needs_pushing)
{
struct rev_info rev;
struct commit *commit;
const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
int argc = ARRAY_SIZE(argv) - 1;
char *sha1_copy;
- int needs_pushing = 0;
+
struct strbuf remotes_arg = STRBUF_INIT;
strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
@@ -401,14 +401,14 @@ int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remote
if (prepare_revision_walk(&rev))
die("revision walk setup failed");
- while ((commit = get_revision(&rev)) && !needs_pushing)
- commit_need_pushing(commit, &needs_pushing);
+ while ((commit = get_revision(&rev)) != NULL)
+ commit_need_pushing(commit, needs_pushing);
reset_revision_walk();
free(sha1_copy);
strbuf_release(&remotes_arg);
- return needs_pushing;
+ return needs_pushing->nr;
}
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
diff --git a/submodule.h b/submodule.h
index 80e04f3..ddd1941 100644
--- a/submodule.h
+++ b/submodule.h
@@ -29,6 +29,7 @@ int fetch_populated_submodules(int num_options, const char **options,
unsigned is_submodule_modified(const char *path, int ignore_untracked);
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
const unsigned char a[20], const unsigned char b[20], int search);
-int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name);
+int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name,
+ struct string_list *needs_pushing);
#endif
diff --git a/transport.c b/transport.c
index cac0c06..d13bd4a 100644
--- a/transport.c
+++ b/transport.c
@@ -11,6 +11,7 @@
#include "branch.h"
#include "url.h"
#include "submodule.h"
+#include "string-list.h"
/* rsync support */
@@ -1000,6 +1001,20 @@ void transport_set_verbosity(struct transport *transport, int verbosity,
transport->progress = force_progress || (verbosity >= 0 && isatty(2));
}
+static void die_with_unpushed_submodules(struct string_list *needs_pushing)
+{
+ int i;
+
+ fprintf(stderr, "The following submodule paths contain changes that can\n"
+ "not be found on any remote:\n");
+ for (i = 0; i < needs_pushing->nr; i++)
+ printf(" %s\n", needs_pushing->items[i].string);
+
+ string_list_clear(needs_pushing, 0);
+
+ die("Aborting.");
+}
+
int transport_push(struct transport *transport,
int refspec_nr, const char **refspec, int flags,
int *nonfastforward)
@@ -1040,10 +1055,15 @@ int transport_push(struct transport *transport,
if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
struct ref *ref = remote_refs;
+ struct string_list needs_pushing;
+
+ memset(&needs_pushing, 0, sizeof(struct string_list));
+ needs_pushing.strdup_strings = 1;
for (; ref; ref = ref->next)
if (!is_null_sha1(ref->new_sha1) &&
- check_submodule_needs_pushing(ref->new_sha1,transport->remote->name))
- die("There are unpushed submodules, aborting.");
+ check_submodule_needs_pushing(ref->new_sha1,
+ transport->remote->name, &needs_pushing))
+ die_with_unpushed_submodules(&needs_pushing);
}
push_ret = transport->push_refs(transport, remote_refs, flags);
--
1.7.9.114.gead08
^ permalink raw reply related
* [PATCH v5 3/3] push: teach --recurse-submodules the on-demand option
From: Heiko Voigt @ 2012-02-13 9:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Fredrik Gustafsson, Jens Lehmann
In-Reply-To: <20120213092541.GA15585@t1405.greatnet.de>
When using this option git will search for all submodules that
have changed in the revisions to be send. It will then try to
push the currently checked out branch of each submodule.
This helps when a user has finished working on a change which
involves submodules and just wants to push everything in one go.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
Documentation/git-push.txt | 14 ++++--
builtin/push.c | 7 +++
submodule.c | 48 ++++++++++++++++++++
submodule.h | 1 +
t/t5531-deep-submodule-push.sh | 94 ++++++++++++++++++++++++++++++++++++++++
transport.c | 17 +++++++-
transport.h | 1 +
7 files changed, 177 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index aede488..649ee3a 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -162,10 +162,16 @@ useful if you write an alias or script around 'git push'.
is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal.
---recurse-submodules=check::
- Check whether all submodule commits used by the revisions to be
- pushed are available on a remote tracking branch. Otherwise the
- push will be aborted and the command will exit with non-zero status.
+--recurse-submodules=<check|on-demand>::
+ Make sure all submodule commits used by the revisions to be
+ pushed are available on a remote tracking branch. If check is
+ used it will be checked that all submodule commits that changed
+ in the revisions to be pushed are available on a remote.
+ Otherwise the push will be aborted and exit with non-zero
+ status. If on-demand is used all submodules that changed in the
+ revisions to be pushed will be pushed. If on-demand was not able
+ to push all necessary revisions it will also be aborted and exit
+ with non-zero status.
include::urls-remotes.txt[]
diff --git a/builtin/push.c b/builtin/push.c
index 35cce53..f2ef8dd 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -224,9 +224,16 @@ static int option_parse_recurse_submodules(const struct option *opt,
const char *arg, int unset)
{
int *flags = opt->value;
+
+ if (*flags & (TRANSPORT_RECURSE_SUBMODULES_CHECK |
+ TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND))
+ die("%s can only be used once.", opt->long_name);
+
if (arg) {
if (!strcmp(arg, "check"))
*flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
+ else if (!strcmp(arg, "on-demand"))
+ *flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
else
die("bad %s argument: %s", opt->long_name, arg);
} else
diff --git a/submodule.c b/submodule.c
index 3c714c2..ff0cfd8 100644
--- a/submodule.c
+++ b/submodule.c
@@ -411,6 +411,54 @@ int check_submodule_needs_pushing(unsigned char new_sha1[20],
return needs_pushing->nr;
}
+static int push_submodule(const char *path)
+{
+ if (add_submodule_odb(path))
+ return 1;
+
+ if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
+ struct child_process cp;
+ const char *argv[] = {"push", NULL};
+
+ memset(&cp, 0, sizeof(cp));
+ cp.argv = argv;
+ cp.env = local_repo_env;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.dir = path;
+ if (run_command(&cp))
+ return 0;
+ close(cp.out);
+ }
+
+ return 1;
+}
+
+int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)
+{
+ int i, ret = 1;
+ struct string_list needs_pushing;
+
+ memset(&needs_pushing, 0, sizeof(struct string_list));
+ needs_pushing.strdup_strings = 1;
+
+ if (!check_submodule_needs_pushing(new_sha1, remotes_name, &needs_pushing))
+ return 1;
+
+ for (i = 0; i < needs_pushing.nr; i++) {
+ const char *path = needs_pushing.items[i].string;
+ fprintf(stderr, "Pushing submodule '%s'\n", path);
+ if (!push_submodule(path)) {
+ fprintf(stderr, "Unable to push submodule '%s'\n", path);
+ ret = 0;
+ }
+ }
+
+ string_list_clear(&needs_pushing, 0);
+
+ return ret;
+}
+
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
{
int is_present = 0;
diff --git a/submodule.h b/submodule.h
index ddd1941..af74941 100644
--- a/submodule.h
+++ b/submodule.h
@@ -31,5 +31,6 @@ int merge_submodule(unsigned char result[20], const char *path, const unsigned c
const unsigned char a[20], const unsigned char b[20], int search);
int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name,
struct string_list *needs_pushing);
+int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);
#endif
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index 30bec4b..1947c28 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -119,4 +119,98 @@ test_expect_success 'push succeeds if submodule has no remote and is on the firs
)
'
+test_expect_success 'push unpushed submodules when not needed' '
+ (
+ cd work &&
+ (
+ cd gar/bage &&
+ git checkout master &&
+ >junk5 &&
+ git add junk5 &&
+ git commit -m "Fifth junk" &&
+ git push &&
+ git rev-parse origin/master >../../../expected
+ ) &&
+ git checkout master &&
+ git add gar/bage &&
+ git commit -m "Fifth commit for gar/bage" &&
+ git push --recurse-submodules=on-demand ../pub.git master
+ ) &&
+ (
+ cd submodule.git &&
+ git rev-parse master >../actual
+ ) &&
+ test_cmp expected actual
+'
+
+test_expect_success 'push unpushed submodules when not needed 2' '
+ (
+ cd submodule.git &&
+ git rev-parse master >../expected
+ ) &&
+ (
+ cd work &&
+ (
+ cd gar/bage &&
+ >junk6 &&
+ git add junk6 &&
+ git commit -m "Sixth junk"
+ ) &&
+ >junk2 &&
+ git add junk2 &&
+ git commit -m "Second junk for work" &&
+ git push --recurse-submodules=on-demand ../pub.git master
+ ) &&
+ (
+ cd submodule.git &&
+ git rev-parse master >../actual
+ ) &&
+ test_cmp expected actual
+'
+
+test_expect_success 'push unpushed submodules recursively' '
+ (
+ cd work &&
+ (
+ cd gar/bage &&
+ git checkout master &&
+ > junk7 &&
+ git add junk7 &&
+ git commit -m "Seventh junk" &&
+ git rev-parse master >../../../expected
+ ) &&
+ git checkout master &&
+ git add gar/bage &&
+ git commit -m "Seventh commit for gar/bage" &&
+ git push --recurse-submodules=on-demand ../pub.git master
+ ) &&
+ (
+ cd submodule.git &&
+ git rev-parse master >../actual
+ ) &&
+ test_cmp expected actual
+'
+
+test_expect_success 'push unpushable submodule recursively fails' '
+ (
+ cd work &&
+ (
+ cd gar/bage &&
+ git rev-parse origin/master >../../../expected &&
+ git checkout master~0 &&
+ > junk8 &&
+ git add junk8 &&
+ git commit -m "Eighth junk"
+ ) &&
+ git add gar/bage &&
+ git commit -m "Eighth commit for gar/bage" &&
+ test_must_fail git push --recurse-submodules=on-demand ../pub.git master
+ ) &&
+ (
+ cd submodule.git &&
+ git rev-parse master >../actual
+ ) &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/transport.c b/transport.c
index d13bd4a..8c0fec0 100644
--- a/transport.c
+++ b/transport.c
@@ -1009,6 +1009,11 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing)
"not be found on any remote:\n");
for (i = 0; i < needs_pushing->nr; i++)
printf(" %s\n", needs_pushing->items[i].string);
+ fprintf(stderr, "\nPlease try\n\n"
+ " git push --recurse-submodules=on-demand\n\n"
+ "or cd to the path and use\n\n"
+ " git push\n\n"
+ "to push them to a remote.\n\n");
string_list_clear(needs_pushing, 0);
@@ -1053,7 +1058,17 @@ int transport_push(struct transport *transport,
flags & TRANSPORT_PUSH_MIRROR,
flags & TRANSPORT_PUSH_FORCE);
- if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
+ if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
+ struct ref *ref = remote_refs;
+ for (; ref; ref = ref->next)
+ if (!is_null_sha1(ref->new_sha1) &&
+ !push_unpushed_submodules(ref->new_sha1,
+ transport->remote->name))
+ die ("Failed to push all needed submodules!");
+ }
+
+ if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
+ TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
struct ref *ref = remote_refs;
struct string_list needs_pushing;
diff --git a/transport.h b/transport.h
index 059b330..9d19c78 100644
--- a/transport.h
+++ b/transport.h
@@ -102,6 +102,7 @@ struct transport {
#define TRANSPORT_PUSH_PORCELAIN 16
#define TRANSPORT_PUSH_SET_UPSTREAM 32
#define TRANSPORT_RECURSE_SUBMODULES_CHECK 64
+#define TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND 128
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
--
1.7.9.114.gead08
^ permalink raw reply related
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Michael Haggerty @ 2012-02-13 9:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Tom Grennan, pclouds, git, krh, jasampler
In-Reply-To: <7vsjifgrwl.fsf@alter.siamese.dyndns.org>
On 02/13/2012 07:37 AM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>
>> Of *course* they operate on different namespaces. But part of the way
>> that revisions are selected using rev-list is by *selecting or excluding
>> refnames* from which it should crawl.
>
> I am appalled if that is truly the understanding of yours, after having
> taken more than a few patches from you to fairly core parts of Git.
>
> "rev-list A ^B" does not say "include A and exclude B from which rev-list
> should crawl" AT ALL. We _actively_ crawl from both A and B. It is that
> what are reachable from B is painted in a color different from the color
> in which we paint what are reachable from A.
Please read my emails more carefully before insulting me.
It is perfectly clear to me that there are two types of exclusion that
we are talking about. And *both* of them are (or should be) relevant to
rev-parse.
Take the following repository with three branches:
o---o---o---o A
\ \
\ o---o C
\
o---o B
If I do "git rev-list A B ^C" then I get the commits marked "*" in the
following diagram
o---o---o---* A
\ \
\ o---o C
\
*---* B
By excluding C I have necessarily excluded a part of the history of A and B.
If we assume that the proposed feature is implemented and I do "git
rev-list $(git for-each-ref --format='%(refname)' A B ^C)", then I get
something different:
*---*---*---* A
\ \
\ o---o C
\
*---* B
I argue that this is a useful selection. For example, maybe I want to
remove the clutter of branch C from my view, but I still want to see the
*whole* history of branches A and B. The middle selection doesn't do it.
Obviously this is not really necessary if there are only three branches,
but if there are dozens, and if A, B, and C are patterns rather than
literal branch names, then it can be very convenient.
For example, suppose I want to see the status of all of my submissions
in your repository in the context of your main branches plus my local
branches. It would be great to be able to type
gitk --with-branch='refs/heads/*' \
--with-branch='remotes/gitster/*' \
--without-branch='remotes/gitster/*/**' \
--with-branch='remotes/gitster/mh/*'
I don't know of a way to do that now.
> A better pair you could have mentioned would be for-each-ref vs rev-parse
> (not rev-list). What Tom wanted with "do not show the refs that match the
> pattern" he originally wanted to give to "tag --list" would be
>
> for-each-ref A ^B
>
> that is "show ref that matches A but do not show if it also matches B",
> while what you want to say is "I want to paint A in positive color and
> paint B in negative color, and I want to get a canonical notation to do
> so", it is spelled with rev-parse, not for-each-ref, like this:
>
> rev-parse A ^B
That's not what I want; see above.
> In other words,
>
> git rev-list $(git rev-parse A ^B)
>
> would be the equivalent to "git rev-list A ^B".
>
> Maybe you are troubled that there are multiple concepts of negation, which
> ultimately comes from the undeniable fact that for-each-ref and rev-parse
> operate on entities in different concept domain (refnames and objects)?
> And if we decide to use "^", then these two different concepts of negation
> are both expressed with the same operator "prefix ^", leading to
> confusion?
Not only that, but also that both concepts of negation are interesting
and useful within "git rev-list", and therefore we should make them
*combinable*.
To be very explicit, I advocate:
1. Implement an explicit syntax for "do not include references matching
this pattern in a list of references". Implement this syntax in
for-each-ref; something like
--with-ref=PATTERN / --without-ref=PATTERN
--with-branch=PATTERN / --without-branch=PATTERN
--with-tag=PATTERN / --without-tag=PATTERN
--with-remote=PATTERN / --without-remote=PATTERN
The point of having multiple with/without pairs would be that the first
would match full refnames explicitly (i.e., the pattern would usually
start with "refs/"), whereas the other pairs would implicitly prepend
"refs/heads/", "refs/tags/", or "refs/remotes/", respectively, to the
pattern for convenience. There should also be an "--all" option that is
equivalent to "--with-ref=**".
The output from for-each-ref would essentially be a *list of positive
references* matching the criteria. In other words,
"--without-branch=foo" would cause "refs/heads/foo" to be *excluded*
from the output altogether, *not* included as "^refs/heads/foo".
The order of the options should be significant, with the last matching
pattern winning.
2. The pattern matching of refnames should be like fnmatch, with the
addition of "**" as a wildcard meaning "any characters, including '/'".
3. Other reference-listing commands should take the same options as
appropriate; for example, "git branch --list" would take
--with(out)?-branch and --with(out)?-remote (and maybe
--with(out)?-ref); "git tag --list" would take --with(out)?-tag (and
maybe --with(out)?-ref), etc.
4. The *exact same options* should be added to rev-list, and would
effectively be expanded into a list of positive references; e.g.,
git rev-list --with-branch=A --with-branch=B --without-branch=C
would be equivalent to
git rev-list $(git for-each-ref --format='%(refname)'
--with-branch=A --with-branch=B --without-branch=C)
If A, B, and C happen to be branch names rather than patterns, the above
would be equivalent to
git rev-list refs/heads/A refs/heads/B
Note that this *differs* (in a useful way!) from
git rev-list refs/heads/A refs/heads/B --not refs/heads/C
or
git rev-list refs/heads/A refs/heads/B ^refs/heads/C
which are useful in other scenarios and whose meanings we would of
course retain.
If "--not" is used in git-rev-list, it would demarcate groups of options
that are passed separately to for-each-ref; for example,
git rev-list --all --with-branch=A --without-branch=B \
--not --with-branch=C --without-branch=D
would be equivalent to
git rev-list $(git for-each-ref --format='%(refname)' --all
--with-branch=A --without-branch=B)\
--not $(git for-each-ref --format='%(refname)'
--with-branch=C --without-branch=D)
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Junio C Hamano @ 2012-02-13 10:23 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Tom Grennan, pclouds, git, krh, jasampler
In-Reply-To: <4F38D9D4.5000203@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu> writes:
> On 02/13/2012 07:37 AM, Junio C Hamano wrote:
>> Michael Haggerty <mhagger@alum.mit.edu> writes:
>>
>>> Of *course* they operate on different namespaces. But part of the way
>>> that revisions are selected using rev-list is by *selecting or excluding
>>> refnames* from which it should crawl.
>>
>> I am appalled if that is truly the understanding of yours, after having
>> taken more than a few patches from you to fairly core parts of Git.
>>
>> "rev-list A ^B" does not say "include A and exclude B from which rev-list
>> should crawl" AT ALL. We _actively_ crawl from both A and B. It is that
>> what are reachable from B is painted in a color different from the color
>> in which we paint what are reachable from A.
>
> Please read my emails more carefully before insulting me.
> ...
> o---o---o---* A
> \ \
> \ o---o C
> \
> *---* B
>
> ... vs ...
>
> *---*---*---* A
> \ \
> \ o---o C
> \
> *---* B
>
> I argue that this is a useful selection.
Then why were you so against the addition of "negation" to for-each-ref?
If you want "I want histories reaching A and B", just say "rev-list A B",
without adding useless "er, I do not want histories reaching C in the
output, but I do not want commits reachable from C to be excluded from the
output either" by mentioning C. Learn to shut your mouth and not talk
about irrelevant "C" in such a case, and you will do just fine.
Especially, re-read your first message where you said that between
git rev-list A B ^C
and
git rev-list $(git for-each-ref A B ^C)
"consistency suggests should do the same". Should the consistency also
suggest that
git rev-list $(git rev-parse A B ^C)
do the same? That is a total bullshit that can only come from somebody
who does not understand the distinction between pattern matching in
refnames vs set operation over commit DAG.
Having said all that, if your argument against using "^" as negation for
for-each-ref *were* with something like this from the beginning:
git rev-list --all --exclude-refs=refs/tags/v\*
it would have been very different. I would wholeheartedly buy the
consistency argument that says
git for-each-ref --exclude-refs=refs/tags/v\*
ought to give all refs (only because for-each-ref "all" is implied) except
for the tagged tips, and
git log --all --exclude-refs=refs/tags/v\*
should be the notation to produce consistently the same result as
git log $(git for-each-ref --format='%(objectname)' --exclude-refs=refs/tags/v\*)
but if we used "^" as negated match in for-each-ref argument, we would
close the door to give such consistency to log family of commands later.
But that wasn't what you said. Why should I get accused of not guessing
what you meant to say but you clearly didn't, and in addition blamed for
insulting merely for pointing out the idiocy in what you said?
No. *YOU* go back and re-read your message more carefully.
^ permalink raw reply
* Re: [PATCH] Remove Git's support for smoke testing
From: Junio C Hamano @ 2012-02-13 10:32 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git
In-Reply-To: <CACBZZX7pDYFqSUjqDjjEFZBaTsoN9oa9vy5Cq4CckP2nZSSRyw@mail.gmail.com>
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> On Fri, Dec 23, 2011 at 18:08, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
>> I'm no longer running the Git smoke testing service at
>> smoke.git.nix.is due to Smolder being a fragile piece of software not
>> having time to follow through on making it easy for third parties to
>> run and submit their own smoke tests.
>
> Junio, could you please apply this? The current release's t/README
> file is pointing to a service I'm not running anymore.
Will apply these three directly to maint (they all look sane, safe and do
not add any new features).
[PATCH] Makefile: Change the default compiler from "gcc" to "cc"
[PATCH] Remove Git's support for smoke testing
[PATCH] t: use sane_unset instead of unset
Thanks.
^ permalink raw reply
* [BUG] git-merge-octopus creates an empty merge commit with one parent
From: Michał Kiedrowicz @ 2012-02-13 11:48 UTC (permalink / raw)
To: git; +Cc: Michał Kiedrowicz
This happens when git merge is run to merge multiple commits that are
descendants of current HEAD (or are HEAD). We've hit this while updating master
to origin/master but accidentaly we called (while being on master):
$ git merge master origin/master
Here is a minimal testcase:
$ git init a
$ cd a
$ echo a>a
$ git commit -minitial
$ echo b>a
$ git add a
$ git commit -msecond
$ git checkout master^
$ git merge master master
Fast-forwarding to: master
Already up-to-date with master
Merge made by the 'octopus' strategy.
a | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
$ git cat-file commit HEAD
tree eebfed94e75e7760540d1485c740902590a00332
parent bd679e85202280b263e20a57639a142fa14c2c64
author Michał Kiedrowicz <michal.kiedrowicz@gmail.com> 1329132996 +0100
committer Michał Kiedrowicz <michal.kiedrowicz@gmail.com> 1329132996 +0100
Merge branches 'master' and 'master' into HEAD
... and below is a patch that adds a testcase to Git's testsuite.
I would expect `git merge master master` to just 'Fast forward'.
Signed-off-by: Michał Kiedrowicz <michal.kiedrowicz@gmail.com>
---
t/t6028-merge-up-to-date.sh | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/t/t6028-merge-up-to-date.sh b/t/t6028-merge-up-to-date.sh
index a91644e..824fca5 100755
--- a/t/t6028-merge-up-to-date.sh
+++ b/t/t6028-merge-up-to-date.sh
@@ -16,7 +16,12 @@ test_expect_success setup '
test_tick &&
git commit -m second &&
git tag c1 &&
- git branch test
+ git branch test &&
+ echo third >file &&
+ git add file &&
+ test_tick &&
+ git commit -m third &&
+ git tag c2
'
test_expect_success 'merge -s recursive up-to-date' '
@@ -74,4 +79,14 @@ test_expect_success 'merge -s subtree up-to-date' '
'
+test_expect_failure 'merge fast-forward octopus' '
+
+ git reset --hard c0 &&
+ test_tick &&
+ git merge c1 c2
+ expect=$(git rev-parse c2) &&
+ current=$(git rev-parse HEAD) &&
+ test "$expect" = "$current"
+'
+
test_done
--
1.7.9.rc2.155.g2e96
^ permalink raw reply related
* Re: User authentication in GIT
From: supadhyay @ 2012-02-13 12:54 UTC (permalink / raw)
To: git
In-Reply-To: <CAMK1S_gOhaX4SaUZk8RrByDa_HPuMLDs=T2M2djXDhvESJu1Vg@mail.gmail.com>
Thanks Sitaram for your reply and guidance.
>From your document I can see there are three different method to install
gitolite. May I know all methods advantage and disadvantage?
Thanks,
Suchi
--
View this message in context: http://git.661346.n2.nabble.com/User-authentication-in-GIT-tp7261349p7280277.html
Sent from the git mailing list archive at Nabble.com.
^ permalink raw reply
* Re: Bulgarian translation of git
From: Jonathan Nieder @ 2012-02-13 14:00 UTC (permalink / raw)
To: Jiang Xin
Cc: Git List, Ævar Arnfjörð Bjarmason,
Alexander Shopov (Александър Шопов),
Junio C Hamano
In-Reply-To: <7vy5s7idxb.fsf@alter.siamese.dyndns.org>
Junio C Hamano wrote:
> Jiang Xin <worldhello.net@gmail.com> writes:
>> I have a question, which version of po should be maintained? master
>> branch or maint branch.
>
> I would say for this round the git-po repository and its pot file should
> pick up whatever new translatable strings are added to 'master'.
>
> After this is merged in 1.7.10, we may want to maintain separate tracks,
> but at this moment there is no point maintaining something mergeable to
> 1.7.9.x maintenance track.
I wonder if there's a simple to ask the gettext tools to make a po
template including strings from both 'maint' and 'master'. (Hackish way
demonstrated below.)
Hopefully that would make it easier for translators to keep both
tracks well maintained at the same time. If a problem in the
translation of a string shared by 'master' and 'maint' is only noticed
while working on 'master', there would be no need to go through the
"switch branches; make the change; switch back; merge" dance.
What do you think?
Jonathan
diff --git i/Makefile w/Makefile
index 1e91b19c..5dbc6205 100644
--- i/Makefile
+++ w/Makefile
@@ -2103,7 +2103,8 @@ LOCALIZED_C := $(C_OBJ:o=c)
LOCALIZED_SH := $(SCRIPT_SH)
po/git.pot: $(LOCALIZED_C)
- $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
+ cp $@ $@+
+ $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
$(LOCALIZED_SH)
mv $@+ $@
^ permalink raw reply related
* Re: User authentication in GIT
From: Sitaram Chamarty @ 2012-02-13 14:32 UTC (permalink / raw)
To: supadhyay; +Cc: git
In-Reply-To: <1329137674044-7280277.post@n2.nabble.com>
On Mon, Feb 13, 2012 at 6:24 PM, supadhyay <supadhyay@imany.com> wrote:
> Thanks Sitaram for your reply and guidance.
>
> From your document I can see there are three different method to install
> gitolite. May I know all methods advantage and disadvantage?
see first para after the 4 bullets in
http://sitaramc.github.com/gitolite/install.html#install_installing_and_upgrading_gitolite_
^ permalink raw reply
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Michael Haggerty @ 2012-02-13 14:34 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Tom Grennan, pclouds, git, krh, jasampler
In-Reply-To: <7v4nuvghfk.fsf@alter.siamese.dyndns.org>
On 02/13/2012 11:23 AM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>
>> On 02/13/2012 07:37 AM, Junio C Hamano wrote:
>>> Michael Haggerty <mhagger@alum.mit.edu> writes:
>>>
>>>> Of *course* they operate on different namespaces. But part of the way
>>>> that revisions are selected using rev-list is by *selecting or excluding
>>>> refnames* from which it should crawl.
>>>
>>> I am appalled if that is truly the understanding of yours, after having
>>> taken more than a few patches from you to fairly core parts of Git.
>>>
>>> "rev-list A ^B" does not say "include A and exclude B from which rev-list
>>> should crawl" AT ALL. We _actively_ crawl from both A and B. It is that
>>> what are reachable from B is painted in a color different from the color
>>> in which we paint what are reachable from A.
>>
>> Please read my emails more carefully before insulting me.
>> ...
>> o---o---o---* A
>> \ \
>> \ o---o C
>> \
>> *---* B
>>
>> ... vs ...
>>
>> *---*---*---* A
>> \ \
>> \ o---o C
>> \
>> *---* B
>>
>> I argue that this is a useful selection.
>
> Then why were you so against the addition of "negation" to for-each-ref?
I'm not against it. I just think it should be spelled differently.
> If you want "I want histories reaching A and B", just say "rev-list A B",
> without adding useless "er, I do not want histories reaching C in the
> output, but I do not want commits reachable from C to be excluded from the
> output either" by mentioning C. Learn to shut your mouth and not talk
> about irrelevant "C" in such a case, and you will do just fine.
That's fine if we're talking about single references. But it does not
generalize to patterns, like my example
gitk --with-branch='refs/heads/*' \
--with-branch='remotes/gitster/*' \
--without-branch='remotes/gitster/*/**' \
--with-branch='remotes/gitster/mh/*'
If these options were supported, I could store this set of arguments as
a "view" in gitk and have it load automatically. It would continue to
work even as you add and delete branches from your repository. Listing
the branches explicitly would be fragile. Currently I would have to
write a script wrapper around gitk that invokes multiple git commands
and filters the results using grep or something. (At least I don't know
a better way.) Even if for-each-ref were taught to exclude branches, I
don't believe it is possible to use arbitrary shell commands to build a
gitk view.
> Especially, re-read your first message where you said that between
>
> git rev-list A B ^C
>
> and
>
> git rev-list $(git for-each-ref A B ^C)
>
> "consistency suggests should do the same".
I should have connected the dots better: consistency suggests they
should do the same, but they obviously cannot. Moreover, it would be
nice if the two types of exclusion could be combined in single commands,
in which case consistency is mandatory. Therefore, let's spell the
for-each-ref option another way that *can* be made consistent across
commands.
> Having said all that, if your argument against using "^" as negation for
> for-each-ref *were* with something like this from the beginning:
>
> git rev-list --all --exclude-refs=refs/tags/v\*
>
> it would have been very different. I would wholeheartedly buy the
> consistency argument that says
>
> git for-each-ref --exclude-refs=refs/tags/v\*
>
> ought to give all refs (only because for-each-ref "all" is implied) except
> for the tagged tips, and
>
> git log --all --exclude-refs=refs/tags/v\*
>
> should be the notation to produce consistently the same result as
>
> git log $(git for-each-ref --format='%(objectname)' --exclude-refs=refs/tags/v\*)
>
> but if we used "^" as negated match in for-each-ref argument, we would
> close the door to give such consistency to log family of commands later.
That *has* been exactly my argument from the beginning [1]. I
cautiously hope that we are now talking about the same thing, even if it
is not yet clear whether we agree on a conclusion.
I think this would be an interesting project, but I won't have time to
work on it in the near future. My first priority is to get the
hierarchical-refs patches rebased on top of the removal of extra refs
and do some more rationalization in that area.
Michael
[1] I don't see where anything I've written is inconsistent with your
phrasing of the argument. But fine, let's just be happy that the
miscommunication now seems to be cleared up.
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: Git documentation at kernel.org
From: Konstantin Ryabitsev @ 2012-02-13 15:15 UTC (permalink / raw)
To: Jeff King
Cc: Matthieu Moy, Junio C Hamano, Clemens Buchacher, ftpadmin,
Petr Onderka, git
In-Reply-To: <20120212222508.GA25619@sigill.intra.peff.net>
[-- Attachment #1: Type: text/plain, Size: 564 bytes --]
On Sun, 2012-02-12 at 17:25 -0500, Jeff King wrote:
> As far as historical reasons, perhaps the right answer is to put the
> documentation where it makes sense to go _now_, and ask kernel.org to
> issue http redirects for http://kernel.org/pub/software/scm/git/docs.
I think that should be fine, unless John objects. The easiest would be
to preserve the same directory structure, so we do a dir-level redirect
instead of creating one-off redirects for each page.
Best,
--
Konstantin Ryabitsev
Systems Administrator, Kernel.org
Montréal, Québec
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 665 bytes --]
^ permalink raw reply
* git cherry doesn't list a merge commit
From: Tajti Ákos @ 2012-02-13 15:17 UTC (permalink / raw)
To: git
Dear List,
I have a question/misunderstanding about 'git cherry'. The scenario is
the following:
I have two repositories (two forks of the same parent repo): A and B. I
created a commit in A, then pulled B to A and finally made an other
commit in A. This resulted the following commits:
-----
commit f6afabb0a734843d5d122b612f0701d27b178e42
Author: akostajti <akos.tajti@intland.com>
Date: Mon Feb 13 15:59:51 2012 +0100
modified a
commit 4ec4d59f632b93456890db139125419d16a10807
Merge: a73e884 2a483e8
Author: akostajti <akos.tajti@intland.com>
Date: Mon Feb 13 15:59:34 2012 +0100
Merge branch 'master' of http://localhost:3180/git/first-60-project
commit a73e884d2dadf29898c2d6b665ed79d352422d26
Author: akostajti <akos.tajti@intland.com>
Date: Mon Feb 13 15:58:48 2012 +0100
hkl
-----
Now If I fetch B to A and run 'git cherry FETCH_HEAD master' I get only
two changeset ids:
+ a73e884d2dadf29898c2d6b665ed79d352422d26
+ f6afabb0a734843d5d122b612f0701d27b178e42
However, the manual of git cherry says:
"*Every* commit that doesn’t exist in the <upstream> branch has its id
(sha1) reported, prefixed by a symbol. The ones that have equivalent
change already in the <upstream> branch are prefixed with a minus (-) sign"
In my understanding this means that the merge commit
(4ec4d59f632b93456890db139125419d16a10807) should be also listed by
cherry, because it doesn't exist in the upstream. Am I doing something
wrong? How can I ge git cherry work as I expect?
Thanks in advance,
Ákos Tajti
^ permalink raw reply
* Re: Bulgarian translation of git
From: Jiang Xin @ 2012-02-13 15:43 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Git List, Ævar Arnfjörð,
Alexander Shopov (Александър Шопов),
Junio C Hamano
In-Reply-To: <20120213133957.GA4838@burratino>
2012/2/13 Jonathan Nieder <jrnieder@gmail.com>:
> I wonder if there's a simple to ask the gettext tools to make a po
> template including strings from both 'maint' and 'master'. (Hackish way
> demonstrated below.)
>
> Hopefully that would make it easier for translators to keep both
> tracks well maintained at the same time. If a problem in the
> translation of a string shared by 'master' and 'maint' is only noticed
> while working on 'master', there would be no need to go through the
> "switch branches; make the change; switch back; merge" dance.
>
> What do you think?
Translators on a new language may not like this. Translating the obsolete
messages in pot file is boring and waste of time.
> po/git.pot: $(LOCALIZED_C)
> - $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
> + cp $@ $@+
Failed if po/git.pot does not exist. touch one first?
> + $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
> $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
> $(LOCALIZED_SH)
> mv $@+ $@
--
Jiang Xin
^ permalink raw reply
* Re: Bulgarian translation of git
From: Jonathan Nieder @ 2012-02-13 15:56 UTC (permalink / raw)
To: Jiang Xin
Cc: Git List, Ævar Arnfjörð,
Alexander Shopov (Александър Шопов),
Junio C Hamano
In-Reply-To: <CANYiYbHkbUvL-d4M0iOyE5F-6rM=swk_knGEFTr9HGBK6T9UDg@mail.gmail.com>
Jiang Xin wrote:
> 2012/2/13 Jonathan Nieder <jrnieder@gmail.com>:
>> I wonder if there's a simple to ask the gettext tools to make a po
>> template including strings from both 'maint' and 'master'. (Hackish way
>> demonstrated below.)
>>
>> Hopefully that would make it easier for translators to keep both
>> tracks well maintained at the same time.
[...]
>> What do you think?
>
> Translators on a new language may not like this. Translating the obsolete
> messages in pot file is boring and waste of time.
Right, doing this for real require somehow removing stale messages,
too, so the pot file would only contain messages from actively
maintained releases (the tip of 'master' and 'maint').
Will experiment privately a little more.
^ permalink raw reply
* Re: [PATCHv2 1/4] refs: add common refname_match_patterns()
From: Tom Grennan @ 2012-02-13 16:29 UTC (permalink / raw)
To: Junio C Hamano; +Cc: pclouds, git, jasampler
In-Reply-To: <7vzkcpkkbd.fsf@alter.siamese.dyndns.org>
[-- Attachment #1: Type: text/plain, Size: 884 bytes --]
On Sat, Feb 11, 2012 at 03:43:34PM -0800, Junio C Hamano wrote:
>Tom Grennan <tmgrennan@gmail.com> writes:
>
>> Yes, I should have stated that this emphasized containment over
>> efficiency. If instead we stipulate that the caller must list exclusion
>> patterns before others, this could simply be:
>
>No.
>
>You have to pre-parse and rearrange the pattern[] list *only once* before
>matching them against dozens of refs, so instead of forcing the callers do
>anything funky, you give a function that gets a pattern[] list and returns
>something that can be efficiently used by the match_pattern() function,
>and have the caller pass that thing, not the original pattern[] list, to
>the match_pattern() function.
Hmm, I'm not communicating very well; this is exactly what I meant by,
>> Of course I'd add a with_exclusions_first() before the
>> respective ref iterator.
--
TomG
[-- Attachment #2: Type: message/rfc822, Size: 2830 bytes --]
From: Tom Grennan <tmgrennan@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: pclouds@gmail.com, git@vger.kernel.org, jasampler@gmail.com
Subject: Re: [PATCHv2 1/4] refs: add common refname_match_patterns()
Date: Sat, 11 Feb 2012 11:37:42 -0800
Message-ID: <20120211193742.GD4903@tgrennan-laptop>
On Sat, Feb 11, 2012 at 12:06:56AM -0800, Junio C Hamano wrote:
>Tom Grennan <tmgrennan@gmail.com> writes:
>
>> +int refname_match_patterns(const char **patterns, const char *refname)
>> +{
>> + int given_match_pattern = 0, had_match = 0;
>> +
>> + for (; *patterns; patterns++)
>> + if (**patterns != '!') {
>> + given_match_pattern = 1;
>> + if (!fnmatch(*patterns, refname, 0))
>> + had_match = 1;
>> + } else if (!fnmatch(*patterns+1, refname, 0))
>> + return 0;
>> + return given_match_pattern ? had_match : 1;
>> +}
>
>This, while its semantics seem sane, is highly inefficient when you have
>many patterns, and you will be calling this to filter dozens of refs. And
>it can trivially improved by first pre-parsing the pattern[] array.
>
> * If you know the patterns do not have any negative entry, you can return
> true upon seeing the first match. Because you do not pre-parse the
> pattern[] array, this loop does not know if there is any negative one,
> and has to scan it always all the way.
>
> * If you arrange the pattern[] array so that it has negative ones early,
> again, you can return false upon seeing the first hit with a negative
> one. If your input has negative ones at the end, the loop ends up
> scanning all the way, noting the positive matches, only to discard upon
> seeing the negative match at the end.
>
>That is why I said Nguyen's idea of reusing pathspec matching logic
>somewhat attractive, even though I think it has downsides (the exact
>matching logic for pathspec is more similar to that of for-each-ref
>and very different from branch/tag).
Yes, I should have stated that this emphasized containment over
efficiency. If instead we stipulate that the caller must list exclusion
patterns before others, this could simply be:
int match_pattern(const char **patterns, const char *refname)
{
if (*patterns)
return 1;
for (; *patterns && **patterns == '!'; patterns++)
if (!fnmatch(*patterns+1, refname, 0))
return 0;
for (; *patterns; patterns++)
if (!fnmatch(*patterns, refname, 0))
return 1;
return 0;
}
Of course I'd add a with_exclusions_first() before the
respective ref iterator.
--
TomG
^ permalink raw reply
* Setting up a Git server (+ gitweb) with .htaccess files HOWTO
From: Matthieu Moy @ 2012-02-13 16:34 UTC (permalink / raw)
To: git
Hi,
I've set up a Git server on a machine on which I have a webspace,
permission to run CGI scripts, but no shell or root access. Good news:
it worked :-).
I've documented the process here in case anyone's interested:
http://www-verimag.imag.fr/~moy/?Host-a-Git-repository-over-HTTP-S
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: git status: small difference between stating whole repository and small subdirectory
From: Piotr Krukowiecki @ 2012-02-13 16:54 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: Git Mailing List
In-Reply-To: <CACsJy8C05wvQRRQJLxrxYKHjXsgh6RugFexkPUKYGxbQkqiXJA@mail.gmail.com>
On Fri, Feb 10, 2012 at 3:37 PM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> I think the cost is in $GIT_DIR, not the working directory.
Could you explain?
I got the problem again today. This time I've made a copy of the
repository so hopefully I'll able to reproduce the problems.
This time it's a different repository but the 'status' on a small
subdirectory is even more than 2x slower than on the whole repository.
Whole repo:
$ find * -type f | wc -l
33021
$ du -shc * | grep total
2.1G total
The subdir:
$ find * -type f | wc -l
17
$ du -shc * | grep total
84K total
As previously, timing was done with cold cache (echo 3 | sudo tee
/proc/sys/vm/drop_caches) and executed several times.
This time I have used recent git (1.7.9.188.g12766) compiled with -pg.
git was executed in the subdirectory. Tracked files were not
changed/deleted, there was just a couple of small untracked files.
Timings:
$ time git status
real 0m16.595s
user 0m0.680s
sys 0m0.616s
$ time git status -- .
real 0m10.030s
user 0m0.464s
sys 0m0.184s
You can find gprof output here:
http://pastebin.com/mhddDUmv - from whole repo status
http://pastebin.com/1LdVn77A - from subdir status
--
Piotr Krukowiecki
^ permalink raw reply
* [PATCH] completion: --no-abbrev-commit for git-log and git-show
From: Michael Schubert @ 2012-02-13 16:57 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
Signed-off-by: Michael Schubert <mschub@elegosoft.com>
---
contrib/completion/git-completion.bash | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index d7367e9..22d7018 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1587,7 +1587,7 @@ _git_log ()
$__git_log_gitk_options
--root --topo-order --date-order --reverse
--follow --full-diff
- --abbrev-commit --abbrev=
+ --abbrev-commit --no-abbrev-commit --abbrev=
--relative-date --date=
--pretty= --format= --oneline
--cherry-pick
@@ -2384,7 +2384,7 @@ _git_show ()
return
;;
--*)
- __gitcomp "--pretty= --format= --abbrev-commit --oneline
+ __gitcomp "--pretty= --format= --abbrev-commit --no-abbrev-commit --online
$__git_diff_common_options
"
return
--
1.7.9.324.g3d1db
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox