* [PATCH 6/5] diff -i
From: Junio C Hamano @ 2012-02-20 7:36 UTC (permalink / raw)
To: git
In-Reply-To: <1329704188-9955-1-git-send-email-gitster@pobox.com>
The previous patch to teach "--ignore-case" option to our "diff" machinery
deliberately omitted a short-and-sweet "-i" that GNU diff uses to ask for
"--ignore-case". This is because our diff machinery are often used by and
shares the command line options with the commands in the "git log" family,
where the short option already means something entirely different. Namely,
it instructs to use case-insensitive match when looking for commits that
match information that appear in the commit object itself, e.g. --author
and --grep.
Tweak the option parser so that "-i" means both, so that
$ git log --grep=frotz -i -p
first picks commits that have string "frotz" in any combination of cases,
and then shows patches that ignore case-only changes for the chosen
commits, while "--ignore-case" and "--regexp-ignore-case" can be used to
mean only one, i.e.
$ git log --grep=frotz --regexp-ignore-case -p
would pick the same set of commits, but the patches shown by it does not
ignore case-only changes while
$ git log --grep=frotz --ignore-case -p
would pick commits that has "frotz" in all lowercase, but shows patches
that ignore case-only changes for the chosen commits.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/diff-options.txt | 1 +
diff.c | 2 +-
revision.c | 6 +++++-
t/lib-diff-alternative.sh | 3 ++-
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 791e07f..9ed78c9 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -404,6 +404,7 @@ endif::git-format-patch[]
differences even if one line has whitespace where the other
line has none.
+-i::
--ignore-case::
Ignore changes in case only; only ASCII alphabet is supported for
now.
diff --git a/diff.c b/diff.c
index d7604b7..9d1584e 100644
--- a/diff.c
+++ b/diff.c
@@ -3399,7 +3399,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
else if (!strcmp(arg, "--ignore-space-at-eol"))
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
- else if (!strcmp(arg, "--ignore-case"))
+ else if (!strcmp(arg, "--ignore-case") || !strcmp(arg, "-i"))
DIFF_XDL_SET(options, IGNORE_CASE);
else if (!strcmp(arg, "--patience"))
options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
diff --git a/revision.c b/revision.c
index 8764dde..f1a1354 100644
--- a/revision.c
+++ b/revision.c
@@ -13,6 +13,7 @@
#include "decorate.h"
#include "log-tree.h"
#include "string-list.h"
+#include "xdiff-interface.h"
volatile show_early_output_fn_t show_early_output;
@@ -1557,7 +1558,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
return argcount;
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
revs->grep_filter.regflags |= REG_EXTENDED;
- } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
+ } else if (!strcmp(arg, "-i")) {
+ DIFF_XDL_SET(&revs->diffopt, IGNORE_CASE);
+ revs->grep_filter.regflags |= REG_ICASE;
+ } else if (!strcmp(arg, "--regexp-ignore-case")) {
revs->grep_filter.regflags |= REG_ICASE;
} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
revs->grep_filter.fixed = 1;
diff --git a/t/lib-diff-alternative.sh b/t/lib-diff-alternative.sh
index 45c665e..81609f8 100644
--- a/t/lib-diff-alternative.sh
+++ b/t/lib-diff-alternative.sh
@@ -175,9 +175,10 @@ test_diff_ignore () {
echo " A quick brownfox" >test-w
echo "A quick brown fox " >test--ignore-space-at-eol
echo "A Quick Brown Fox" >test--ignore-case
+ echo "A Quick Brown FoX" >test-i
echo "A Quick Brown Fox" >test--ignore-case-b
echo "A quick brown fox jumps" >test
- cases="-b -w --ignore-space-at-eol --ignore-case"
+ cases="-b -w --ignore-space-at-eol --ignore-case -i"
if test -z "$STRATEGY"
then
^ permalink raw reply related
* Re: [PATCHv2 0/8] gitweb: Faster and improved project search
From: Junio C Hamano @ 2012-02-20 7:09 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <1329338332-30358-1-git-send-email-jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> [Cc-ing Junio because of his involvement in discussion about first
> patch in previous version of this series.]
>
> First three patches in this series are mainly about speeding up
> project search (and perhaps in the future also project pagination).
> Well, first one is unification, refactoring and future-proofing.
> The second and third patch could be squashed together; second adds
> @fill_only, but third actually uses it.
I'll queue these three separately to a topic jn/gitweb-search-optim,
and fork another topic jn/gitweb-hilite-regions from there. I haven't
looked the latter closely, though.
Thanks.
^ permalink raw reply
* Re: [PATCHv2 2/8] gitweb: Option for filling only specified info in fill_project_list_info
From: Junio C Hamano @ 2012-02-20 6:58 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, Junio C Hamano
In-Reply-To: <1329338332-30358-3-git-send-email-jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> Introduce project_info_needs_filling($pr, $key[, \%fill_only]), which
That's "project_info_needs_filling($pr, @key[, \%fill_only])", isn't it?
> +# entry for given @keys needs filling if at least one of interesting keys
> +# in list is not present in %$project_info; key is interesting if $fill_only
> +# is not passed, or is empty (all keys are interesting in both of those cases),
> +# or if key is in $fill_only hash
> +#
> +# USAGE:
> +# * project_info_needs_filling($project_info, 'key', ...)
> +# * project_info_needs_filling($project_info, 'key', ..., \%fill_only)
> +# where %fill_only = map { $_ => 1 } @fill_only;
The reason this spells bad to me is that it gives the readers (and anybody
who may want to touch gitweb code) that the caller has _two_ ways to say
the same thing.
If a caller is interested in finding out $key in $project_info, it can
either (1) pass $key as one of the earlier parameters to the function and
not pass any \%fill_only, or (2) pass $key and pass \%fill_only but after
making sure \%fill_only also has $key defined.
And if the caller passes \%fill_only, it has to remember that it needs to
add $key to it; otherwise the earlier request "I want $key" is ignored by
the function.
Why is it a good thing to have such a convoluted API?
Is it that "fill_project_list_info" is called by multiple callers, and
they do not necessarily need to see all the fields that can be filled by
the function (namely, age, age_string, descr, descr_long, owner, ctags and
category)? If that is the case, I must say that the approach to put the
set filtering logic inside project_info_needs_filling function smells like
a bad API design.
In other words, wouldn't a callchain that uses a more natural set of API
functions be like this?
# the top-level caller that is interested only in these two fields
fill_project_list_info($projlist, 'age', 'owner');
# in fill_project_list_info()
my $projlist = shift;
my %wanted = map { $_ => 1 } @_;
foreach my $pr (@$projlist) {
if (project_info_needs_filling($pr,
filter_set(\%wanted, 'age', 'age_string'))) {
... get @activity ...
($pr->{'age'}, $pr->{'age_string'}) = @activity;
}
...
}
That way, "needs_filling" has to do one and only one thing well: it checks
if any of the fields it was asked is missing and answers. And a generic
set filtering helper that takes a filtering hashref and an array can be
used later outside of the "needs_filling" function.
> sub project_info_needs_filling {
> + my $fill_only = ref($_[-1]) ? pop : undef;
> my ($project_info, @keys) = @_;
>
> # return List::MoreUtils::any { !exists $project_info->{$_} } @keys;
> foreach my $key (@keys) {
> - if (!exists $project_info->{$key}) {
> + if ((!$fill_only || !%$fill_only || $fill_only->{$key}) &&
> + !exists $project_info->{$key}) {
> return 1;
> }
> }
> return;
> }
>
> -
Shouldn't the previous patch updated not to add this blank line in the
first place?
> # fills project list info (age, description, owner, category, forks)
Is this enumeration up-to-date? If we cannot keep it up-to-date, it may
make sense to show only a few as examples and add ellipses.
> # for each project in the list, removing invalid projects from
> -# returned list
> +# returned list, or fill only specified info (removing invalid projects
> +# only when filling 'age').
It is unclear what the added clause wants to say; especially, the link
between the mention of 'age' and 'only when' is unclear. Is asking of
'age' what makes a request a notable exception to remove invalid projects?
Or is asking to partially fill fields what triggers the removal of invalid
projects, and you mentioned 'age' as an example?
If it is the former (I am guessing it is), it would be much clearer to
say:
Invalid projects are removed from the returned list if and only if you
ask 'age' to be filled, because of such and such reasons.
^ permalink raw reply
* Re: Handle HTTP error 511 Network Authentication Required (standard secure proxy authentification/captive portal detection)
From: Nicolas Mailhot @ 2012-02-20 5:38 UTC (permalink / raw)
To: Jeff King; +Cc: Nicolas Mailhot, git
In-Reply-To: <20120220010617.GB4140@sigill.intra.peff.net>
Le Lun 20 février 2012 02:06, Jeff King a écrit :
> On Sun, Feb 19, 2012 at 10:03:37PM +0100, Nicolas Mailhot wrote:
>
>> The IETF finally set up to fix this problem and defined a standard HTTP
>> error
>> that lets access control equipments tell the web client authentication or
>> re-authentication is needed and where the authentication form is located.
>>
>> http://tools.ietf.org/id/draft-nottingham-http-new-status-04.txt
>>
>> → <http://www.rfc-editor.org/queue2.html#draft-nottingham-http-new-status>
>> (the
>> spec is approved and in the queue for publication as RFC)
>>
>> Please add error 511 handling in git, so git users that try to access
>> external
>> git repositories over http can authenticate on the corporate proxy
>
> If I'm reading this right, the process works something like this:
>
> 1. Git wants to make a request to http://example.com
>
> 2. We make our request to a proxy server which is transparently
> proxying our traffic (i.e, a "captive portal").
>
> 3. The proxy returns 511 along with some URL (e.g.,
> "http://login.corporatenetwork"), indicating that we need
> to go to that URL to complete some authentication.
>
> As a non-browser client, what should git do? We can't make sense of the
> content at http://login.corporatenetwork, which is most likely an HTML
> form asking for credentials (or even money, if the captive portal is
> something like a public wireless provider). The best we can probably do
> is die and say "apparently you need to go http://login.corporatenetwork
> in a browser before making your request".
Actually, the best would be to launch something capable of interpreting html
forms on the url given by the error. But short of that, that depends on how
good git is at resuming work later. Error 511 can occur at any time, not just
on initial connection (because credentials can expire at any time). So pausing
may be better than dying.
However without going there: the portal page will usually be pretty simple, a
standard basic auth form, can't git handle this? If simple web clients such as
git have specific constrains on what can appear or not on this page, can you
not define them and send them ietf-side so they can document them in a later
rfc revision?
> Reading that rfc draft, the man impetus for non-browser clients seems
> not to get them to do anything useful, but rather to return them a code
> that is clearly not from the actual site (if it were a redirect, for
> example, then we would think that example.com is redirecting is, which
> is simply not true).
The main impetus from my point of view is that captive portal/proxy auth is a
mess, because they try to trick web clients into displaying something they are
not prepared to and don't want to do, and this spec is replacing trick with
explicit request, which is nice.
Best regards,
--
Nicolas Mailhot
^ permalink raw reply
* Re: Manually decoding a git object
From: 徐迪 @ 2012-02-20 4:45 UTC (permalink / raw)
To: Philip Oakley; +Cc: Git List
In-Reply-To: <A716A27D407F401DAAC373027D5CFF2A@PhilipOakley>
2012/2/20 Philip Oakley <philipoakley@iee.org>:
> If I have a renamed file which is a git object, such a "Git_Object", was
> 8c-something-or-other, what is the easiest way of examining / decoding /
> recreating the original file (either as its sha1, or a cat-file).
>
I don't think I fully understood what you mean, I assume you just move
an object file from $GIT_DIR/objects/ to somewhere and rename it,
let's call it "obj", so if you want to exam its content you can just
simply call "git cat-file -p obj". And you can also use "git cat-file
-t obj" to exam its object type. If it's a blob you can use "git
cat-file -p obj > original" to recreate it, else it's meaningless to
recreate it.
^ permalink raw reply
* Re: git-svn won't remember pem password
From: Nikolaus Demmel @ 2012-02-20 3:08 UTC (permalink / raw)
To: Jeff King; +Cc: Jakub Narebski, Igor, git, Eric Wong
In-Reply-To: <20120220005727.GA4140@sigill.intra.peff.net>
Am 20.02.2012 um 01:57 schrieb Jeff King:
> On Sat, Feb 18, 2012 at 03:30:00AM -0800, Jakub Narebski wrote:
>
>> Igor <mrigor83@gmail.com> writes:
>>
>>> I'm running into an issue where I have to enter my pem certificate
>>> password every time I git-svn fetch or git-svn dcommit. Vanilla svn
>>> uses OS X KeyChain and remembers my password just fine. Is there a
>>> known solution for this? Other users have ran into same issue as
>>> described here:
>>>
>>> http://stackoverflow.com/questions/605519/does-git-svn-store-svn-passwords
>>
>>> However, that solution of removing .subversion folder did not work
>>> for me.
>>
>> I don't know if it is svn that has to remember password, or git that
>> has to remember password. Git 1.7.9 learned "credentials API" that
>> allows integration with platform native keychain mechanisms, and I
>> think OS X Keychain is one of examples / supported platforms (but it
>> might not made it into core git)... though I am not sure if it affects
>> git-svn, or only HTTP(S) transport.
>
> It does not affect git-svn currently.
>
> I have some thoughts on providing access to the credentials API for
> scripts like git-svn (right now, it is accessible only by C git
> programs). However, there is an important question: should password
> prompting in git-svn behave like git, or behave like svn?
>
> So far, it has been the latter, and I think that is reasonable. The
> resource that requires the credentials is an svn repo, not a git repo,
> so you are more likely to want to share credentials for it with real
> svn, and not other git commands.
>
IMHO a normal user would expect git-svn to store credentials in the same way as normal svn. I think this is the way it should be.
Best regards,
Nikolaus
^ permalink raw reply
* [PATCH 4/5] xdiff: introduce XDF_IGNORE_CASE
From: Junio C Hamano @ 2012-02-20 2:16 UTC (permalink / raw)
To: git
In-Reply-To: <1329704188-9955-1-git-send-email-gitster@pobox.com>
Teach the hash function and per-line comparison logic to compare lines
while ignoring the differences in case. It is not an ignore-whitespace
option but still needs to trigger the inexact match logic, and that is
why the previous step introduced XDF_INEXACT_MATCH mask.
Assign the 7th bit for this option, and move the bits to select diff
algorithms out of the way in order to leave room for a few bits to add
more variants of ignore-whitespace, such as --ignore-tab-expansion, if
somebody else is inclined to do so later.
We would still need to teach the front-end to flip this bit, for this
change to be any useful.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
xdiff/xdiff.h | 7 ++++---
xdiff/xutils.c | 50 ++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 48793f9..5a01a0e 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -36,10 +36,11 @@ extern "C" {
(XDF_IGNORE_WHITESPACE | \
XDF_IGNORE_WHITESPACE_CHANGE | \
XDF_IGNORE_WHITESPACE_AT_EOL)
-#define XDF_INEXACT_MATCH XDF_WHITESPACE_FLAGS
+#define XDF_IGNORE_CASE (1 << 7)
+#define XDF_INEXACT_MATCH (XDF_WHITESPACE_FLAGS | XDF_IGNORE_CASE)
-#define XDF_PATIENCE_DIFF (1 << 5)
-#define XDF_HISTOGRAM_DIFF (1 << 6)
+#define XDF_PATIENCE_DIFF (1 << 8)
+#define XDF_HISTOGRAM_DIFF (1 << 9)
#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index aa6de74..925f1d0 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -170,6 +170,19 @@ long xdl_guess_lines(mmfile_t *mf, long sample) {
return nl + 1;
}
+static inline int match_a_byte(char ch1, char ch2, long flags)
+{
+ if (ch1 == ch2)
+ return 1;
+ if (!(flags & XDF_IGNORE_CASE) || ((ch1 | ch2) & 0x80))
+ return 0;
+ if (isupper(ch1))
+ ch1 = tolower(ch1);
+ if (isupper(ch2))
+ ch2 = tolower(ch2);
+ return (ch1 == ch2);
+}
+
int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
{
int i1, i2;
@@ -192,7 +205,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
if (flags & XDF_IGNORE_WHITESPACE) {
goto skip_ws;
while (i1 < s1 && i2 < s2) {
- if (l1[i1++] != l2[i2++])
+ if (!match_a_byte(l1[i1++], l2[i2++], flags))
return 0;
skip_ws:
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
@@ -210,15 +223,28 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
i2++;
continue;
}
- if (l1[i1++] != l2[i2++])
+ if (!match_a_byte(l1[i1++], l2[i2++], flags))
return 0;
}
- } else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) {
- while (i1 < s1 && i2 < s2 && l1[i1++] == l2[i2++])
+ } else {
+ /*
+ * Either XDF_IGNORE_WHITESPACE_AT_EOL is set, or
+ * no whitespace is ignored, but INEXACT_MATCH is
+ * in effect for other reasons.
+ */
+ while (i1 < s1 && i2 < s2 &&
+ match_a_byte(l1[i1++], l2[i2++], flags))
; /* keep going */
}
/*
+ * If we are not ignoring any whitespace, we must have consumed
+ * everything for the lines to match.
+ */
+ if (!(flags & XDF_WHITESPACE_FLAGS))
+ return i1 == s1 && i2 == s2;
+
+ /*
* After running out of one side, the remaining side must have
* nothing but whitespace for the lines to match. Note that
* ignore-whitespace-at-eol case may break out of the loop
@@ -238,6 +264,14 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
return 1;
}
+static inline unsigned long hash_a_byte(const char ch_, long flags)
+{
+ unsigned long ch = ch_ & 0xFF;
+ if ((flags & XDF_IGNORE_CASE) && !(ch & 0x80) && isupper(ch))
+ ch = tolower(ch);
+ return ch;
+}
+
static unsigned long xdl_hash_record_with_whitespace(char const **data,
char const *top, long flags) {
unsigned long ha = 5381;
@@ -256,20 +290,20 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
&& !at_eol) {
ha += (ha << 5);
- ha ^= (unsigned long) ' ';
+ ha ^= hash_a_byte(' ', flags);
}
else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
&& !at_eol) {
while (ptr2 != ptr + 1) {
ha += (ha << 5);
- ha ^= (unsigned long) *ptr2;
+ ha ^= hash_a_byte(*ptr2, flags);
ptr2++;
}
}
continue;
}
ha += (ha << 5);
- ha ^= (unsigned long) *ptr;
+ ha ^= hash_a_byte(*ptr, flags);
}
*data = ptr < top ? ptr + 1: ptr;
@@ -286,7 +320,7 @@ unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
for (; ptr < top && *ptr != '\n'; ptr++) {
ha += (ha << 5);
- ha ^= (unsigned long) *ptr;
+ ha ^= hash_a_byte(*ptr, flags);
}
*data = ptr < top ? ptr + 1: ptr;
--
1.7.9.1.265.g25f75
^ permalink raw reply related
* [PATCH 5/5] diff: --ignore-case
From: Junio C Hamano @ 2012-02-20 2:16 UTC (permalink / raw)
To: git
In-Reply-To: <1329704188-9955-1-git-send-email-gitster@pobox.com>
Teach the front-end to flip XDF_IGNORE_CASE bit with the options GNU diff
uses.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/diff-options.txt | 4 ++++
diff.c | 2 ++
t/lib-diff-alternative.sh | 45 ++++++++++++++++++++++++++++++++++++++--
t/t4033-diff-patience.sh | 6 ++++++
t/t4050-diff-histogram.sh | 2 ++
5 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9f7cba2..791e07f 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -404,6 +404,10 @@ endif::git-format-patch[]
differences even if one line has whitespace where the other
line has none.
+--ignore-case::
+ Ignore changes in case only; only ASCII alphabet is supported for
+ now.
+
--inter-hunk-context=<lines>::
Show the context between diff hunks, up to the specified number
of lines, thereby fusing hunks that are close to each other.
diff --git a/diff.c b/diff.c
index 87b2ec1..d7604b7 100644
--- a/diff.c
+++ b/diff.c
@@ -3399,6 +3399,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
else if (!strcmp(arg, "--ignore-space-at-eol"))
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
+ else if (!strcmp(arg, "--ignore-case"))
+ DIFF_XDL_SET(options, IGNORE_CASE);
else if (!strcmp(arg, "--patience"))
options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
else if (!strcmp(arg, "--histogram"))
diff --git a/t/lib-diff-alternative.sh b/t/lib-diff-alternative.sh
index 75ffd91..45c665e 100644
--- a/t/lib-diff-alternative.sh
+++ b/t/lib-diff-alternative.sh
@@ -104,8 +104,9 @@ EOF
STRATEGY=$1
+ cmd='git diff --no-index'
test_expect_success "$STRATEGY diff" '
- test_must_fail git diff --no-index "--$STRATEGY" file1 file2 > output &&
+ test_must_fail $cmd ${STRATEGY:+"--$STRATEGY"} file1 file2 >output &&
test_cmp expect output
'
@@ -157,9 +158,49 @@ EOF
STRATEGY=$1
+ cmd='git diff --no-index'
test_expect_success 'completely different files' '
- test_must_fail git diff --no-index "--$STRATEGY" uniq1 uniq2 > output &&
+
+ test_must_fail $cmd ${STRATEGY:+"--$STRATEGY"} uniq1 uniq2 >output &&
test_cmp expect output
'
}
+test_diff_ignore () {
+
+ STRATEGY=$1
+
+ echo "A quick brown fox" >test.0
+ echo "A quick brown fox" >test-b
+ echo " A quick brownfox" >test-w
+ echo "A quick brown fox " >test--ignore-space-at-eol
+ echo "A Quick Brown Fox" >test--ignore-case
+ echo "A Quick Brown Fox" >test--ignore-case-b
+ echo "A quick brown fox jumps" >test
+ cases="-b -w --ignore-space-at-eol --ignore-case"
+
+ if test -z "$STRATEGY"
+ then
+ label=baseline
+ else
+ label=$STRATEGY
+ fi
+
+ cmd="git diff --no-index ${STRATEGY:+--$STRATEGY}"
+
+ test_expect_success "$label diff" '
+ test_must_fail $cmd test.0 test
+ '
+ for case in $cases
+ do
+ test_expect_success "$label diff $case" '
+ $cmd $case test.0 test$case &&
+ test_must_fail $cmd test.0 test
+ '
+ done
+
+ test_expect_success "$label diff -b --ignore-case" '
+ $cmd -b --ignore-case test.0 test--ignore-case-b
+ '
+
+}
diff --git a/t/t4033-diff-patience.sh b/t/t4033-diff-patience.sh
index 3c9932e..c7f8c6c 100755
--- a/t/t4033-diff-patience.sh
+++ b/t/t4033-diff-patience.sh
@@ -5,8 +5,14 @@ test_description='patience diff algorithm'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-diff-alternative.sh
+# baseline
+test_diff_unique ""
+test_diff_ignore ""
+
test_diff_frobnitz "patience"
test_diff_unique "patience"
+test_diff_ignore "patience"
+
test_done
diff --git a/t/t4050-diff-histogram.sh b/t/t4050-diff-histogram.sh
index fd3e86a..98c6686 100755
--- a/t/t4050-diff-histogram.sh
+++ b/t/t4050-diff-histogram.sh
@@ -9,4 +9,6 @@ test_diff_frobnitz "histogram"
test_diff_unique "histogram"
+test_diff_ignore "histogram"
+
test_done
--
1.7.9.1.265.g25f75
^ permalink raw reply related
* [PATCH 3/5] xdiff: introduce XDF_INEXACT_MATCH
From: Junio C Hamano @ 2012-02-20 2:16 UTC (permalink / raw)
To: git
In-Reply-To: <1329704188-9955-1-git-send-email-gitster@pobox.com>
The XDF_WHITESPACE_FLAGS mask is used to decide if a simple memcmp() is
sufficient to tell if two lines are the same for the purpose of producing
diff. In the current code, only options in the ignore-whitespace family
happen to call for a matching logic that is more complex than memcmp(),
but when we add new options, e.g. ignore-case, it will become apparent
that the mask is misnamed.
Introduce XDF_INEXACT_MATCH mask to express its true meaning: when any of
these bits are set, we may need to inspect the contents of the two lines
that are not exactly the same, as we may still consider them "matching".
The XDF_WHITESPACE_FLAGS will become useful again in a later patch in the
series and its definition is kept.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
diff.c | 2 +-
xdiff/xdiff.h | 6 +++++-
xdiff/xutils.c | 4 ++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/diff.c b/diff.c
index 52cda7a..87b2ec1 100644
--- a/diff.c
+++ b/diff.c
@@ -2142,7 +2142,7 @@ static void builtin_diff(const char *name_a,
struct emit_callback ecbdata;
const struct userdiff_funcname *pe;
- if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS) || must_show_header) {
+ if (!DIFF_XDL_TST(o, INEXACT_MATCH) || must_show_header) {
fprintf(o->file, "%s", header.buf);
strbuf_reset(&header);
}
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 09215af..48793f9 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -32,7 +32,11 @@ extern "C" {
#define XDF_IGNORE_WHITESPACE (1 << 2)
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
-#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
+#define XDF_WHITESPACE_FLAGS \
+ (XDF_IGNORE_WHITESPACE | \
+ XDF_IGNORE_WHITESPACE_CHANGE | \
+ XDF_IGNORE_WHITESPACE_AT_EOL)
+#define XDF_INEXACT_MATCH XDF_WHITESPACE_FLAGS
#define XDF_PATIENCE_DIFF (1 << 5)
#define XDF_HISTOGRAM_DIFF (1 << 6)
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 0de084e..aa6de74 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -176,7 +176,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
if (s1 == s2 && !memcmp(l1, l2, s1))
return 1;
- if (!(flags & XDF_WHITESPACE_FLAGS))
+ if (!(flags & XDF_INEXACT_MATCH))
return 0;
i1 = 0;
@@ -281,7 +281,7 @@ unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
unsigned long ha = 5381;
char const *ptr = *data;
- if (flags & XDF_WHITESPACE_FLAGS)
+ if (flags & XDF_INEXACT_MATCH)
return xdl_hash_record_with_whitespace(data, top, flags);
for (; ptr < top && *ptr != '\n'; ptr++) {
--
1.7.9.1.265.g25f75
^ permalink raw reply related
* [PATCH 2/5] xdiff: PATIENCE/HISTOGRAM are not independent option bits
From: Junio C Hamano @ 2012-02-20 2:16 UTC (permalink / raw)
To: git
In-Reply-To: <1329704188-9955-1-git-send-email-gitster@pobox.com>
Because the default Myers, patience and histogram algorithms cannot be in
effect at the same time, XDL_PATIENCE_DIFF and XDL_HISTOGRAM_DIFF are not
independent bits. Instead of wasting one bit per algorithm, define a few
macros to access the few bits they occupy and update the code that access
them.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
diff.c | 4 ++--
diff.h | 2 ++
merge-recursive.c | 4 ++--
xdiff/xdiff.h | 5 ++++-
xdiff/xdiffi.c | 4 ++--
xdiff/xhistogram.c | 2 +-
xdiff/xpatience.c | 2 +-
xdiff/xprepare.c | 21 ++++++++++-----------
8 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/diff.c b/diff.c
index 374ecf3..52cda7a 100644
--- a/diff.c
+++ b/diff.c
@@ -3400,9 +3400,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
else if (!strcmp(arg, "--ignore-space-at-eol"))
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
else if (!strcmp(arg, "--patience"))
- DIFF_XDL_SET(options, PATIENCE_DIFF);
+ options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
else if (!strcmp(arg, "--histogram"))
- DIFF_XDL_SET(options, HISTOGRAM_DIFF);
+ options->xdl_opts = DIFF_WITH_ALG(options, HISTOGRAM_DIFF);
/* flags options */
else if (!strcmp(arg, "--binary")) {
diff --git a/diff.h b/diff.h
index 0c51724..e688a48 100644
--- a/diff.h
+++ b/diff.h
@@ -88,6 +88,8 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
#define DIFF_XDL_SET(opts, flag) ((opts)->xdl_opts |= XDF_##flag)
#define DIFF_XDL_CLR(opts, flag) ((opts)->xdl_opts &= ~XDF_##flag)
+#define DIFF_WITH_ALG(opts, flag) (((opts)->xdl_opts & ~XDF_DIFF_ALGORITHM_MASK) | XDF_##flag)
+
enum diff_words_type {
DIFF_WORDS_NONE = 0,
DIFF_WORDS_PORCELAIN,
diff --git a/merge-recursive.c b/merge-recursive.c
index cc664c3..1d574fe 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -2069,9 +2069,9 @@ int parse_merge_opt(struct merge_options *o, const char *s)
else if (!prefixcmp(s, "subtree="))
o->subtree_shift = s + strlen("subtree=");
else if (!strcmp(s, "patience"))
- o->xdl_opts |= XDF_PATIENCE_DIFF;
+ o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
else if (!strcmp(s, "histogram"))
- o->xdl_opts |= XDF_HISTOGRAM_DIFF;
+ o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
else if (!strcmp(s, "ignore-space-change"))
o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else if (!strcmp(s, "ignore-all-space"))
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 70c8b87..09215af 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -32,9 +32,12 @@ extern "C" {
#define XDF_IGNORE_WHITESPACE (1 << 2)
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
+#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
+
#define XDF_PATIENCE_DIFF (1 << 5)
#define XDF_HISTOGRAM_DIFF (1 << 6)
-#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
+#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
+#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
#define XDL_EMIT_FUNCNAMES (1 << 0)
#define XDL_EMIT_COMMON (1 << 1)
diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c
index 75a3922..bc889e8 100644
--- a/xdiff/xdiffi.c
+++ b/xdiff/xdiffi.c
@@ -328,10 +328,10 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdalgoenv_t xenv;
diffdata_t dd1, dd2;
- if (xpp->flags & XDF_PATIENCE_DIFF)
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
return xdl_do_patience_diff(mf1, mf2, xpp, xe);
- if (xpp->flags & XDF_HISTOGRAM_DIFF)
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
diff --git a/xdiff/xhistogram.c b/xdiff/xhistogram.c
index 18f6f99..bf99787 100644
--- a/xdiff/xhistogram.c
+++ b/xdiff/xhistogram.c
@@ -252,7 +252,7 @@ static int fall_back_to_classic_diff(struct histindex *index,
int line1, int count1, int line2, int count2)
{
xpparam_t xpp;
- xpp.flags = index->xpp->flags & ~XDF_HISTOGRAM_DIFF;
+ xpp.flags = index->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
return xdl_fall_back_diff(index->env, &xpp,
line1, count1, line2, count2);
diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c
index fdd7d02..04e1a1a 100644
--- a/xdiff/xpatience.c
+++ b/xdiff/xpatience.c
@@ -288,7 +288,7 @@ static int fall_back_to_classic_diff(struct hashmap *map,
int line1, int count1, int line2, int count2)
{
xpparam_t xpp;
- xpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;
+ xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
return xdl_fall_back_diff(map->env, &xpp,
line1, count1, line2, count2);
diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c
index e419f4f..63a22c6 100644
--- a/xdiff/xprepare.c
+++ b/xdiff/xprepare.c
@@ -181,7 +181,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
goto abort;
- if (xpp->flags & XDF_HISTOGRAM_DIFF)
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
hbits = hsize = 0;
else {
hbits = xdl_hashbits((unsigned int) narec);
@@ -209,8 +209,8 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
crec->ha = hav;
recs[nrec++] = crec;
- if (!(xpp->flags & XDF_HISTOGRAM_DIFF) &&
- xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
+ if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+ xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
goto abort;
}
}
@@ -273,16 +273,15 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
* (nrecs) will be updated correctly anyway by
* xdl_prepare_ctx().
*/
- sample = xpp->flags & XDF_HISTOGRAM_DIFF ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1;
+ sample = (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF
+ ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1);
enl1 = xdl_guess_lines(mf1, sample) + 1;
enl2 = xdl_guess_lines(mf2, sample) + 1;
- if (!(xpp->flags & XDF_HISTOGRAM_DIFF) &&
- xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) {
-
+ if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
+ xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
return -1;
- }
if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
@@ -296,9 +295,9 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
return -1;
}
- if (!(xpp->flags & XDF_PATIENCE_DIFF) &&
- !(xpp->flags & XDF_HISTOGRAM_DIFF) &&
- xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
+ if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
+ (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+ xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
xdl_free_ctx(&xe->xdf2);
xdl_free_ctx(&xe->xdf1);
--
1.7.9.1.265.g25f75
^ permalink raw reply related
* [PATCH 1/5] xdiff: remove XDL_PATCH_* macros
From: Junio C Hamano @ 2012-02-20 2:16 UTC (permalink / raw)
To: git
In-Reply-To: <1329704188-9955-1-git-send-email-gitster@pobox.com>
These are not used anywhere in our codebase, and the bit assignment
definition is merely confusing.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
xdiff/xdiff.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 00d36c3..70c8b87 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -36,11 +36,6 @@ extern "C" {
#define XDF_HISTOGRAM_DIFF (1 << 6)
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
-#define XDL_PATCH_NORMAL '-'
-#define XDL_PATCH_REVERSE '+'
-#define XDL_PATCH_MODEMASK ((1 << 8) - 1)
-#define XDL_PATCH_IGNOREBSPACE (1 << 8)
-
#define XDL_EMIT_FUNCNAMES (1 << 0)
#define XDL_EMIT_COMMON (1 << 1)
#define XDL_EMIT_FUNCCONTEXT (1 << 2)
--
1.7.9.1.265.g25f75
^ permalink raw reply related
* [PATCH 0/5] diff --ignore-case
From: Junio C Hamano @ 2012-02-20 2:16 UTC (permalink / raw)
To: git
This teaches our "diff" machinery to optionally consider lines that are
different only in upper/lower-cases to be equivalent.
Junio C Hamano (5):
xdiff: remove XDL_PATCH_* macros
xdiff: PATIENCE/HISTOGRAM are not independent option bits
xdiff: introduce XDF_INEXACT_MATCH
xdiff: introduce XDF_IGNORE_CASE
diff: --ignore-case
Documentation/diff-options.txt | 4 +++
diff.c | 8 +++---
diff.h | 2 ++
merge-recursive.c | 4 +--
t/lib-diff-alternative.sh | 45 +++++++++++++++++++++++++++++++--
t/t4033-diff-patience.sh | 6 +++++
t/t4050-diff-histogram.sh | 2 ++
xdiff/xdiff.h | 19 ++++++++------
xdiff/xdiffi.c | 4 +--
xdiff/xhistogram.c | 2 +-
xdiff/xpatience.c | 2 +-
xdiff/xprepare.c | 21 ++++++++--------
xdiff/xutils.c | 54 ++++++++++++++++++++++++++++++++--------
13 files changed, 133 insertions(+), 40 deletions(-)
--
1.7.9.1.265.g25f75
^ permalink raw reply
* Re: Handle HTTP error 511 Network Authentication Required (standard secure proxy authentification/captive portal detection)
From: Jeff King @ 2012-02-20 1:06 UTC (permalink / raw)
To: Nicolas Mailhot; +Cc: git
In-Reply-To: <4b8f33ba4c870528a82ab85d6dad68bd.squirrel@arekh.dyndns.org>
On Sun, Feb 19, 2012 at 10:03:37PM +0100, Nicolas Mailhot wrote:
> The IETF finally set up to fix this problem and defined a standard HTTP error
> that lets access control equipments tell the web client authentication or
> re-authentication is needed and where the authentication form is located.
>
> http://tools.ietf.org/id/draft-nottingham-http-new-status-04.txt
>
> → <http://www.rfc-editor.org/queue2.html#draft-nottingham-http-new-status> (the
> spec is approved and in the queue for publication as RFC)
>
> Please add error 511 handling in git, so git users that try to access external
> git repositories over http can authenticate on the corporate proxy
If I'm reading this right, the process works something like this:
1. Git wants to make a request to http://example.com
2. We make our request to a proxy server which is transparently
proxying our traffic (i.e, a "captive portal").
3. The proxy returns 511 along with some URL (e.g.,
"http://login.corporatenetwork"), indicating that we need
to go to that URL to complete some authentication.
As a non-browser client, what should git do? We can't make sense of the
content at http://login.corporatenetwork, which is most likely an HTML
form asking for credentials (or even money, if the captive portal is
something like a public wireless provider). The best we can probably do
is die and say "apparently you need to go http://login.corporatenetwork
in a browser before making your request".
Reading that rfc draft, the man impetus for non-browser clients seems
not to get them to do anything useful, but rather to return them a code
that is clearly not from the actual site (if it were a redirect, for
example, then we would think that example.com is redirecting is, which
is simply not true).
-Peff
^ permalink raw reply
* Re: git-svn won't remember pem password
From: Jeff King @ 2012-02-20 0:57 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Igor, git, Eric Wong
In-Reply-To: <m3zkcgqt0g.fsf@localhost.localdomain>
On Sat, Feb 18, 2012 at 03:30:00AM -0800, Jakub Narebski wrote:
> Igor <mrigor83@gmail.com> writes:
>
> > I'm running into an issue where I have to enter my pem certificate
> > password every time I git-svn fetch or git-svn dcommit. Vanilla svn
> > uses OS X KeyChain and remembers my password just fine. Is there a
> > known solution for this? Other users have ran into same issue as
> > described here:
> >
> > http://stackoverflow.com/questions/605519/does-git-svn-store-svn-passwords
>
> > However, that solution of removing .subversion folder did not work
> > for me.
>
> I don't know if it is svn that has to remember password, or git that
> has to remember password. Git 1.7.9 learned "credentials API" that
> allows integration with platform native keychain mechanisms, and I
> think OS X Keychain is one of examples / supported platforms (but it
> might not made it into core git)... though I am not sure if it affects
> git-svn, or only HTTP(S) transport.
It does not affect git-svn currently.
I have some thoughts on providing access to the credentials API for
scripts like git-svn (right now, it is accessible only by C git
programs). However, there is an important question: should password
prompting in git-svn behave like git, or behave like svn?
So far, it has been the latter, and I think that is reasonable. The
resource that requires the credentials is an svn repo, not a git repo,
so you are more likely to want to share credentials for it with real
svn, and not other git commands.
As to the lack of keychain support, it looks like libsvn should be
handling this for us. We simply give it a callback function that gets
called if the user needs prompted, but I would think things like the
keychain handling would happen before it gets to our prompt (and if I
understand it, for _some_ credential storage formats, it does). So
either there is a bug in libsvn, or we are somehow invoking it
incorrectly.
-Peff
^ permalink raw reply
* Re: Mixing and matching multiple projects
From: Junio C Hamano @ 2012-02-20 0:36 UTC (permalink / raw)
To: Holding, Lawrence; +Cc: git
In-Reply-To: <A5E8E180685CEF45AB9E737A010799802D972E@cdnz-ex1.corp.cubic.cub>
"Holding, Lawrence" <Lawrence.Holding@cubic.com> writes:
> How about
> - creating a "driver" project in the superproject,
> - add a .gitignore or .git/exclude entry for the
> /s/xyzzy/os/drivers/frotz folder into the os project
> - symlinking the /s/xyzzy/os/drivers/frotz folder to the
> /s/xyzzy/driver/frotz folder
Thanks.
I think that is essentially the same as what I wrote with "symlink" in my
last paragraph as a known-to-work workaround. The real location of the
frotz driver, whether it is in a directory directly in the superproject,
or a separate submodule that is bound to the superproject outside the "os"
submodule, does not make an essential difference, as long as it is outside
"os".
I was asking if people who have used submodules have better solutions than
that "symlink" solution.
^ permalink raw reply
* RE: Mixing and matching multiple projects
From: Holding, Lawrence @ 2012-02-20 0:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v39a9tf45.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Junio C Hamano <gitster@pobox.com> writes:
>
> > But I wonder if we can do without forking the /s/xyzzy/os/.git
submodule?
> >
> > If we *could* do this:
> >
> > cd /s/xyzzy
> > mkdir os/drivers/frotz && populate the directory with sources
>
> A crucial step was missing here for my story to make *any* sense.
Sorry.
> A step to create a repository at /s/xyzzy/os/drivers/frotz/.git must
be
> here, like this:
>
> (cd os/drivers/frotz && git init && git add . && git commit)
>
> And then that is added as a submodule to the superproject.
>
> > git add os/drivers/frotz ;# to the top-level superproject!!
> >
> > to add the "frotz driver" submodule directly to the superproject,
then we
> > could leave /s/xyzzy/os/.git intact, letting it follow the open
source
> > world. Because the superproject must be forked in order to keep
track of
> > what happens in the appliance that supports the "frotz" driver
anyway,
> > this could result in the minimum amount of forking from the end
user's
> > point of view.
> >
> ........
> >
How about
- creating a "driver" project in the superproject,
- add a .gitignore or .git/exclude entry for the
/s/xyzzy/os/drivers/frotz folder into the os project
- symlinking the /s/xyzzy/os/drivers/frotz folder to the
/s/xyzzy/driver/frotz folder
some of this can be automated in the post checkout script of the
superproject.
^ permalink raw reply
* Re: [PATCH] tag: refuse tag messages that contain NULs
From: Junio C Hamano @ 2012-02-19 21:40 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1329651837-1102-1-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> diff --git a/builtin/mktag.c b/builtin/mktag.c
> index 640ab64..f51ce20 100644
> --- a/builtin/mktag.c
> +++ b/builtin/mktag.c
> @@ -165,6 +165,9 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
> if (verify_tag(buf.buf, buf.len) < 0)
> die("invalid tag signature file");
>
> + if (memchr(buf.buf, '\0', buf.len))
> + die("a NUL byte in tag message not allowed.");
> +
Is there a good reason why you check _after_ calling verify_tag(), instead
of before?
> if (write_sha1_file(buf.buf, buf.len, tag_type, result_sha1) < 0)
> die("unable to write tag file");
>
> diff --git a/builtin/tag.c b/builtin/tag.c
> index 31f02e8..e66811e 100644
> --- a/builtin/tag.c
> +++ b/builtin/tag.c
> @@ -259,6 +259,8 @@ static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)
> {
> if (sign && do_sign(buf) < 0)
> return error(_("unable to sign the tag"));
> + if (memchr(buf->buf, '\0', buf->len))
> + return error("a NUL byte in tag message not allowed.");
Is there a good reason why you check _after_ calling do_sign(), instead of
before?
^ permalink raw reply
* Re: Working with remotes with (too) many branches
From: Junio C Hamano @ 2012-02-19 21:36 UTC (permalink / raw)
To: Philip Jägenstedt; +Cc: git, Jonathan Nieder
In-Reply-To: <CAKHWUka763XRWyMz2Xq1qQ2rfKqSYdTX0xtdVFm8zWJ_+6tGqA@mail.gmail.com>
Philip Jägenstedt <philip@foolip.org> writes:
> 1. If I make a typo with remote set-branches, fetch will fail with
> "fatal: Couldn't find remote ref refs/heads/typotopic" and not fetch
> anything at all.
At that point you can notice the earlier typo and remove or fix the fetch
refspec you have.
Alternatively, set-branches could run ls-remote against the remote and
notice that there is no such branch over there. However, even if you got
the branch name right when you did "set-branches", you would still see the
same "Couldn't find" when the branch gets removed over there, so you would
need a way to remove or fix the fetch refspec you have *anyway*.
So, assuming that there is no easy way to remove one branch from the set
of branches tracked from a given remote, it is much more important to add
such a way. Checking against a typo when "set-branches" is run is "nicer
to have" but lack of it is not a show-stopper.
Wouldn't "git config --unset remote.origin.fetch '/typotopic'" be
sufficient in the meantime even if a user fears "vi .git/config"?
> 2. If I forget that I've previously worked with footopic and
> set-branches --add it again, I'll get a duplicate line in my config.
I do not know the duplicate hurts anything, but I agree that it would be
more aescetically pleasing if "--add" noticed what you already had and
avoided duplicates.
> 3. When I don't care about footopic anymore, there's no clear way to
> stop fetching it and remove refs/remotes/main/footopic.
Isn't the lack of "set-branches --delete" the same as #1 above? The
latter would be "branch -r -d main/footopic" but I could imagine
"set-branches --delete" would do that for you once implemented.
> 4. If set-branches --delete existed one could end up with no fetch
> lines in the remote config, at which point fetch falls back to
> fetching HEAD, instead of the expected nothing.
Don't do that, then ;-)
I could imagine a new preference "fetch.$remote.default=nothing" that
causes "git fetch" to fail with "You have fetch.$remote.default=nothing
set, so I am not fetching anything from there without any configured
refspec". The default would be fetch.$remote.default=HEAD, I would guess.
The preference can be set automatically when you use "set-branches"
without "--add" for a given remote, as use of "set-branches" is a clear
indication that you want to deviate from the built-in default behaviour
when interacting with that remote.
> I'd appreciate feedback on these issues so that I don't waste time
> trying to patch the wrong problems. Suggestions for an alternative
> work flow is of course also most welcome!
Admittedly I wouldn't use "set-branches" myself (it is far easier to tweak
with "vi .git/config", and I wasn't involved in), but looking at the whole
history of the feature with "git log --grep=set-branch builtin/remote.c",
I have a feeling that not many people used, cut by its still-unrounded
edges, and polished the subcommand by rounding them out yet, and it has a
large room for improvement.
It would have saved you time to wait for a round-trip if you did the above
"git log" yourself to find out from whom this subcommand came from, and
looked at list archive to see if the original author is still active here
(in this case he is), and Cc'ed him before posting the message I am
responding to.
^ permalink raw reply
* Handle HTTP error 511 Network Authentication Required (standard secure proxy authentification/captive portal detection)
From: Nicolas Mailhot @ 2012-02-19 21:03 UTC (permalink / raw)
To: git
Since
http://code.google.com/p/chromium/issues/detail?id=7338 and
https://bugzilla.mozilla.org/show_bug.cgi?id=479880
there is no clean way for a proxy or captive portal to get a web client to
display an authentication dialog when user credentials expire while he is
browsing on an https url.
(to be sure, the previous methods were insecure and hackish but they existed
because nothing better was available)
The IETF finally set up to fix this problem and defined a standard HTTP error
that lets access control equipments tell the web client authentication or
re-authentication is needed and where the authentication form is located.
http://tools.ietf.org/id/draft-nottingham-http-new-status-04.txt
→ <http://www.rfc-editor.org/queue2.html#draft-nottingham-http-new-status> (the
spec is approved and in the queue for publication as RFC)
Please add error 511 handling in git, so git users that try to access external
git repositories over http can authenticate on the corporate proxy
^ permalink raw reply
* git-svn show-externals and svn version
From: Nikolaus Demmel @ 2012-02-19 18:53 UTC (permalink / raw)
To: git
Hi,
I am currently investigating getting support for svn externals in git-svn (you might have noticed my other mails).
It turns out that there are quite a few scripts floating around that use the output of show-externals and then try to pull these externals with git-svn into independent repositories and add the folders as submodules to the root repository.
However, none of them work for me, and the primary reason AFAICT is that they were written for the pre svn1.5 format of svn:externals. From 1.5 svn supports a new format of svn:externals, which changes the order of revision, repository-url, and local folder, and also adds the posibility to add relative urls, peg-revisions, etc [1].
On top that it seems to me that the output of show-externals was purely designed for the old format. For example, if you compare the output of "git svn show-externals" with "git svn propget svn:externals" in an example repository using the new format [2], you find that the in the show-externals output the prepended "/" and "/instantiations/" at the beginning of each line does not make sense. If the target url (all relative with the ^ syntax in this case) and the sub-folder were swapped in order, as of pre 1.5 svn, it would make much more sense. Also apparently the code for show-externals was added in 2007 and not changed since, whereas svn 1.5 was released in 2008.
What I am not completely clear about is, whether svn 1.5 and later enforces the new syntax, or whether it just adds the new syntax and still has to support the old syntax (which could be distinguished, I guess, by checking of the last part on an entry is an absolute URL instead of a subfolder). Also, I'm not sure if the format depends on the version of the svn-server or the client. I would assume you can check out a repository hosted with svn 1.4 with a 1.5 client. Does the client process the svn:externals and present it in the new format, or is this the text string just taken from the server unaltered (I have not much knowledge of how svn actually works internally)?
Another question is whether the perl svn bindings present the svn:externals in some parsed, standard format, or do they just give you the raw text string?
In order to make show-externals more useful with the svn 1.5 and later syntax, one would maybe need to check the underlying svn version. I guess it is also quite important to retain backwards compatibility, such that users of externals with the old syntax would still get the same output as before.
I would suggest that the show-externals output should be as close as possible to the svn:externals syntax, possibly adapting the subfolder path for nested folders. However here the recursive display of externals for subfolders becomes a bit more tricky, since the URL can also be relative to the subfolder as of the new syntax. Maybe the easiest way to deal with the new syntax in show-externals would be to have each line like it is in the svn-properties, but add a space separated relative path to the corresponding subfolder at the beginning. A tool that uses this is then responsible for making sure the relative URLs are resolved correctly.
To sum up, given that all the questions I have are answered like I think is most likely, it would boil down to changing the output of show-externals for svn 1.5 and later just slightly, namely by inserting an additional space between the prepended subfolder and the actual svn:externals definition in each line.
Any thoughts and/or answers?
Cheers,
Nikolaus
[1] http://svnbook.red-bean.com/en/1.7/svn.advanced.externals.html
[2] http://paste.lisp.org/display/127858
^ permalink raw reply
* Manually decoding a git object
From: Philip Oakley @ 2012-02-19 18:07 UTC (permalink / raw)
To: Git List
In-Reply-To: <1329624946-32173-1-git-send-email-pclouds@gmail.com>
If I have a renamed file which is a git object, such a "Git_Object", was
8c-something-or-other, what is the easiest way of examining / decoding /
recreating the original file (either as its sha1, or a cat-file).
I don't appear to be able to unzip the file in its raw format... I'm using
Msysgit on windows XP.
Philip
^ permalink raw reply
* Working with remotes with (too) many branches
From: Philip Jägenstedt @ 2012-02-19 15:29 UTC (permalink / raw)
To: git
Hi,
I work on a project where topic branches are allowed in the main
repository and are not removed even if/when they are merged. This
results in an ever-growing number of branches (and tags), making e.g.
tab completion slow to the point of being useless. We know that this
is not great and it will probably change, but in the meantime I have
set up an alternative origin that only includes the master branch and
annotated tags. However, I still need to collaborate on some topic
branches in the main repository, and have arrived at this solution:
$ git remote add -t footopic -f --no-tags main example.com:/git/main.git
$ git checkout -t main/footopic
# next day
$ git remote set-branches --add main bartopic
$ git fetch main
$ git checkout -t main/bartopic
This works fairly well, but there are a few wrinkles:
1. If I make a typo with remote set-branches, fetch will fail with
"fatal: Couldn't find remote ref refs/heads/typotopic" and not fetch
anything at all.
2. If I forget that I've previously worked with footopic and
set-branches --add it again, I'll get a duplicate line in my config.
3. When I don't care about footopic anymore, there's no clear way to
stop fetching it and remove refs/remotes/main/footopic.
4. If set-branches --delete existed one could end up with no fetch
lines in the remote config, at which point fetch falls back to
fetching HEAD, instead of the expected nothing.
1 and 2 seem fairly easy to fix: add set-branches --delete and use the
same logic to make --add also remove duplicates. Would changing the
git_config_set_multivar call in add_branch (remote.c) be the right
kind of fix here?
3 is less clear to me. Is it a bug that fetch --prune only prunes refs
that it actually tried to fetch, or is it remote prune that should be
taking care of this? Alternatively, should it be the non-existent
set-branches --delete?
4 could be a deliberate fallback, or is it a bug waiting to be exposed?
I'd appreciate feedback on these issues so that I don't waste time
trying to patch the wrong problems. Suggestions for an alternative
work flow is of course also most welcome!
--
Philip Jägenstedt
^ permalink raw reply
* [PATCH] tag: refuse tag messages that contain NULs
From: Nguyễn Thái Ngọc Duy @ 2012-02-19 11:43 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This follows the paranoid spirit in 37576c1 (commit_tree(): refuse
commit messages that contain NULs - 2011-12-15) and stops users from
creating tags that contain NULs. If these tags are merged into a commit
as mergetag lines, they may break the commit header processing badly.
While at it, check for NULs in mergetag and gpgsig lines before
committing too.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/mktag.c | 3 +++
builtin/tag.c | 2 ++
commit.c | 2 ++
t/t7004-tag.sh | 4 ++++
4 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 640ab64..f51ce20 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -165,6 +165,9 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
if (verify_tag(buf.buf, buf.len) < 0)
die("invalid tag signature file");
+ if (memchr(buf.buf, '\0', buf.len))
+ die("a NUL byte in tag message not allowed.");
+
if (write_sha1_file(buf.buf, buf.len, tag_type, result_sha1) < 0)
die("unable to write tag file");
diff --git a/builtin/tag.c b/builtin/tag.c
index 31f02e8..e66811e 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -259,6 +259,8 @@ static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)
{
if (sign && do_sign(buf) < 0)
return error(_("unable to sign the tag"));
+ if (memchr(buf->buf, '\0', buf->len))
+ return error("a NUL byte in tag message not allowed.");
if (write_sha1_file(buf->buf, buf->len, tag_type, result) < 0)
return error(_("unable to write tag file"));
return 0;
diff --git a/commit.c b/commit.c
index 4b39c19..545325f 100644
--- a/commit.c
+++ b/commit.c
@@ -1144,6 +1144,8 @@ int commit_tree_extended(const struct strbuf *msg, unsigned char *tree,
strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
while (extra) {
+ if (memchr(extra->value, '\0', extra->len))
+ return error("a NUL byte in commit header %s not allowed.", extra->key);
add_extra_header(&buffer, extra);
extra = extra->next;
}
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index e93ac73..8cb13e5 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1269,4 +1269,8 @@ test_expect_success 'mixing incompatibles modes and options is forbidden' '
test_must_fail git tag -v -s
'
+test_expect_success 'tag content contains NUL' '
+ test_must_fail git tag -F "$TEST_DIRECTORY"/t3900/UTF-16.txt utf16
+'
+
test_done
--
1.7.8.36.g69ee2
^ permalink raw reply related
* Re: [PATCH 1/2] git-svn.perl: perform deletions before anything else
From: Eric Wong @ 2012-02-19 10:54 UTC (permalink / raw)
To: Steven Walter; +Cc: gitster, git
In-Reply-To: <CAK8d-a+tdK=Jn6D+X=bJmKTzbESPqd8+S2nJr9_sfdb7MhLN1A@mail.gmail.com>
Steven Walter <stevenrwalter@gmail.com> wrote:
> I don't think git-svn should artificially fail in the case. This is
> using svn 1.6.17
> What's the oldest version of svn supported by git-svn? Perhaps if I
> retry with that version of svn, I would see a failure. However, if
> libsvn-perl reports the failure correctly, isn't that good enough
> behavior? No need to fail in git-svn before even trying, IMHO.
Originally (back in 2006/2007), the goal was to support SVN 1.1.x+.
I'm not sure if I we ever lost support for such old versions.
I use Debian stable for testing patches, and SVN is 1.6.12 there.
Otherwise, whatever people are willing to support and send
patches/bugreports for is good.
> Is there a way to validate what the checksums should be, other than to
> look at it and say, "yup, the trees look okay?"
As far as I remember, that's how I originally wrote the tests.
> Assuming you agree with the above analysis, should I squash the test
> changes into my 2/2, or would you prefer a separate patch?
Your analysis seems correct. I always prefer test changes to be
combined with corresponding commits to avoid breakage during bisect.
Thanks!
^ permalink raw reply
* Re: [PATCH/RFC v2] Document format of basic Git objects
From: Junio C Hamano @ 2012-02-19 9:14 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy
Cc: git, Jonathan Niedier, Shawn O. Pearce, Scott Chacon
In-Reply-To: <7vlinzp67m.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>> Still draft for discussion.
Small clarifications and corrections.
> ... from a larger
> workflow point of view it would not be so useful, as it would involve
> steps like this:
>
> ...
> * Then you give the general public the resulting commit.
The point of the above is *not* that it involves hash-object or having to
preserve both author and committer dates when secondary signers sign the
commit---these are something the tool *could* learn to assist. The point
is that adding more signatures *must* change the resulting commit object
name, making it necessary not to expose it to the general public in order
to avoid history rewinding, which *is* what makes it "not so useful".
And that is why I didn't add such a tool support to help producing the end
result that wouldn't be so useful anyway.
>> +TREE OBJECTS
>> +------------
>> +Tree object payload contains a list of entries, each with a mode,
>> +object type, object name, and filename, sorted by filename. It
>> +represents the contents of a single directory tree.
>
> Drop "object type," from this list. It is inferred from the mode. I
> personally would prefer to say "path" or "pathname" when the entity
> referred to may not be a regular file.
The principle is not to say "filename" to give an incorrect impression
that we are only talking about a regular file. This principle applies to
pathnames in general (i.e. covers what is recorded in the index, too), but
because we are talking about an entry in a tree, "pathname component" is
even better than "path" or "pathname", because it has a specific meaning:
one part of pathname delimited by a slash.
POSIX does use "filename" for this purpose (and mentions "pathname
component" as a synonym), but if we use the word, without clarifying that
this document uses it in the strict POSIX sense, the reader can easily
misunderstand that we mean a more general "name of a regular file".
>> +The object type may be a blob, representing the contents of a file,
>> +another tree, representing the contents of a subdirectory, or a commit
>> +(representing a subproject).
>
> and drop the above line.
Should be obvious from the context, but I meant "drop the above three
lines".
> I personally do not think it is necessary to have the above paragraph at
> all in this object.
s/in this object/in this document/;
>> +Encoding
>> +~~~~~~~~
>
> "Encoding" is such a loaded word and does not help clarify what this
> section is really about, which is "format of a tree entry", or simply
> "Entries".
>
>> +Entries are of variable length and self-delimiting. Each entry
>> +consists of
Actually, title this section as "Tree Entries", and begin the paragraph
with
Tre entries are of ...delimiting. Each entry consists of...
>> +Ident strings
>> +~~~~~~~~~~~~~
>> +Ident strings record who's responsible of doing something at what
>> +time. For a commit, the ident string in "author" line records who is
>> +the author of the associated changes and when the changes are
>
> s/are/were/, perhaps? Again, what the purpose of this document? If this
> were more than to strictly describe the "structure", it is OK and even
s/ more than to/to/;
> preferable to leave the meaning the "author" as vague, but if this were
> also to suggest the best current practice interpretation, it may be worth
> to add something like
>
> There may be a case where it is difficult to attribute a commit to
> a single author; think of it as recording the primary contact, the
> person to ask any questions about the commit if needed later.
^ permalink raw reply
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