* Re: What's cooking in git.git (Sep 2016, #07; Fri, 23)
From: Junio C Hamano @ 2016-09-26 19:09 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <alpine.DEB.2.20.1609242101100.129229@virtualbox>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Also, I found https://tinyurl.com/gitCal very convenient a URL to point
> to, do you plan to update that for v2.11.0?
Thanks for reminding. I've barely had enough bandwidth to keep up
with the list traffic for the past few weeks, and haven't got around
to it. Will find time this afternoon to do so.
Please just assume the usual 8-12 week cycle til then ;-)
^ permalink raw reply
* Re: [PATCH v3 2/2] mailinfo: unescape quoted-pair in header fields
From: Junio C Hamano @ 2016-09-26 19:11 UTC (permalink / raw)
To: Kevin Daudt; +Cc: git, Swift Geek, Jeff King
In-Reply-To: <20160925210808.26424-2-me@ikke.info>
Kevin Daudt <me@ikke.info> writes:
> rfc2822 has provisions for quoted strings and comments in structured header
> fields, but also allows for escaping these with so-called quoted-pairs.
>
> The only thing git currently does is removing exterior quotes, but
> quotes within are left alone.
>
> Remove exterior quotes and remove escape characters so that they don't
> show up in the author field.
>
> Signed-off-by: Kevin Daudt <me@ikke.info>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> Changes since v2:
>
> - handle comments inside comments recursively
> - renamed the main function to unquote_quoted_pairs because it also
> handles quoted pairs in comments
Sounds good, and the implemention looked straight-forward from a
quick scan.
> diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
> index c4ed0f4..3e983c0 100755
> --- a/t/t5100-mailinfo.sh
> +++ b/t/t5100-mailinfo.sh
> @@ -144,4 +144,18 @@ test_expect_success 'mailinfo unescapes with --mboxrd' '
> test_cmp expect mboxrd/msg
> '
>
> +test_expect_success 'mailinfo handles rfc2822 quoted-string' '
> + mkdir quoted-string &&
> + git mailinfo /dev/null /dev/null <"$DATA"/quoted-string.in \
> + >quoted-string/info &&
> + test_cmp "$DATA"/quoted-string.expect quoted-string/info
> +'
> +
> +test_expect_success 'mailinfo handles rfc2822 comment' '
> + mkdir comment &&
> + git mailinfo /dev/null /dev/null <"$DATA"/comment.in \
> + >comment/info &&
> + test_cmp "$DATA"/comment.expect comment/info
> +'
> +
> test_done
Don't these also need to be downcased if you prefer $data over
$DATA, though?
Thanks.
^ permalink raw reply
* Re: [PATCH v8 06/11] pkt-line: add packet_write_gently()
From: Lars Schneider @ 2016-09-26 19:21 UTC (permalink / raw)
To: Jakub Narębski
Cc: git, Jeff King, Junio C Hamano, Stefan Beller,
Martin-Louis Bright, Torsten Bögershausen, Ramsay Jones
In-Reply-To: <55c5a86e-4055-f36d-bbf1-e8bae919088a@gmail.com>
On 25 Sep 2016, at 13:26, Jakub Narębski <jnareb@gmail.com> wrote:
> W dniu 20.09.2016 o 21:02, larsxschneider@gmail.com pisze:
>> From: Lars Schneider <larsxschneider@gmail.com>
>> ...
>>
>> +static int packet_write_gently(const int fd_out, const char *buf, size_t size)
>
> I'm not sure what naming convention the rest of Git uses, but isn't
> it more like '*data' rather than '*buf' here?
pkt-line seems to use 'buf' or 'buffer' for everything else.
>> +{
>> + static char packet_write_buffer[LARGE_PACKET_MAX];
>
> I think there should be warning (as a comment before function
> declaration, or before function definition), that packet_write_gently()
> is not thread-safe (nor reentrant, but the latter does not matter here,
> I think).
>
> Thread-safe vs reentrant: http://stackoverflow.com/a/33445858/46058
>
> This is not something terribly important; I guess git code has tons
> of functions not marked as thread-unsafe...
I agree that the function is not thread-safe. However, I can't find
an example in the Git source that marks a function as not thread-safe.
Unless is it explicitly stated in the coding guidelines I would prefer
not to start way to mark functions.
>> + if (size > sizeof(packet_write_buffer) - 4) {
>
> First, wouldn't the following be more readable:
>
> + if (size + 4 > LARGE_PACKET_MAX) {
Peff suggested that here:
http://public-inbox.org/git/20160810132814.gqnipsdwyzjmuqjy@sigill.intra.peff.net/
>> + return error("packet write failed - data exceeds max packet size");
>> + }
>
> Second, CodingGuidelines is against using braces (blocks) for one
> line conditionals: "We avoid using braces unnecessarily."
>
> But this is just me nitpicking.
Fixed.
>> + packet_trace(buf, size, 1);
>> + size += 4;
>> + set_packet_header(packet_write_buffer, size);
>> + memcpy(packet_write_buffer + 4, buf, size - 4);
>> + if (write_in_full(fd_out, packet_write_buffer, size) == size)
>
> Hmmm... in some places we use original size, in others (original) size + 4;
> perhaps it would be more readable to add a new local temporary variable
>
> size_t full_size = size + 4;
Agreed. I introduced "packet_size".
Thanks,
Lars
^ permalink raw reply
* Re: [PATCH v3 2/2] mailinfo: unescape quoted-pair in header fields
From: Junio C Hamano @ 2016-09-26 19:26 UTC (permalink / raw)
To: Kevin Daudt; +Cc: git, Swift Geek, Jeff King
In-Reply-To: <xmqq4m52scg7.fsf@gitster.mtv.corp.google.com>
Junio C Hamano <gitster@pobox.com> writes:
> Don't these also need to be downcased if you prefer $data over
> $DATA, though?
For now, I'll queue a SQUASH??? that reverts s/DATA/data/ you did to
1/2 between your 1/2 and 2/2.
Thanks.
^ permalink raw reply
* [PATCH 0/2] tree-walk improvements
From: David Turner @ 2016-09-26 19:32 UTC (permalink / raw)
To: git, peff, mhagger; +Cc: David Turner
The first patch is a re-roll of Peff's patch from 2014 -- here's
the archive message:
http://git.661346.n2.nabble.com/PATCH-tree-walk-be-more-specific-about-corrupt-tree-errors-td7603558.html
Not sure why this wasn't applied then, but I thought it looked pretty
good, so I added a few tests.
Hopefully the encoding works correctly on these patches. If not, you
can fetch from
https://github.com/novalis/git/
on branch dturner/bad-trees
Email address note 1: my employer wants me to use my company address,
but not my company computer, for patches I write on work time. This
means that I'm going to continue corresponding from
novalis@novalis.org, but will send patches with the @twosigma.com
address in the author line.
Email address note 2: I'm not subscribed to the mailing list these
days, so please CC me (at novalis@novalis.org) on replies.
David Turner (1):
fsck: handle bad trees like other errors
Jeff King (1):
tree-walk: be more specific about corrupt tree errors
fsck.c | 18 +++--
t/t1007-hash-object.sh | 15 +++-
t/t1007/tree-with-empty-filename | Bin 0 -> 28 bytes
t/t1007/tree-with-malformed-mode | Bin 0 -> 39 bytes
t/t1450-fsck.sh | 17 ++++-
.../307e300745b82417cc1a903f875c7d22e45ef907 | 4 +
.../f506a346749bb96f52d8605ffba9fb93d46b5ffd | Bin 0 -> 45 bytes
tree-walk.c | 83 ++++++++++++++++++---
tree-walk.h | 8 ++
9 files changed, 125 insertions(+), 20 deletions(-)
create mode 100644 t/t1007/tree-with-empty-filename
create mode 100644 t/t1007/tree-with-malformed-mode
create mode 100644 t/t1450/bad-objects/307e300745b82417cc1a903f875c7d22e45ef907
create mode 100644 t/t1450/bad-objects/f506a346749bb96f52d8605ffba9fb93d46b5ffd
--
2.8.0.rc4.22.g8ae061a
^ permalink raw reply
* [PATCH 1/2] tree-walk: be more specific about corrupt tree errors
From: David Turner @ 2016-09-26 19:32 UTC (permalink / raw)
To: git, peff, mhagger; +Cc: David Turner
In-Reply-To: <1474918365-10937-1-git-send-email-novalis@novalis.org>
From: Jeff King <peff@peff.net>
When the tree-walker runs into an error, it just calls
die(), and the message is always "corrupt tree file".
However, we are actually covering several cases here; let's
give the user a hint about what happened.
Let's also avoid using the word "corrupt", which makes it
seem like the data bit-rotted on disk. Our sha1 check would
already have found that. These errors are ones of data that
is malformed in the first place.
Signed-off-by: David Turner <dturner@twosigma.com>
Signed-off-by: Jeff King <peff@peff.net>
---
t/t1007-hash-object.sh | 15 +++++++++++++--
t/t1007/tree-with-empty-filename | Bin 0 -> 28 bytes
t/t1007/tree-with-malformed-mode | Bin 0 -> 39 bytes
tree-walk.c | 12 +++++++-----
4 files changed, 20 insertions(+), 7 deletions(-)
create mode 100644 t/t1007/tree-with-empty-filename
create mode 100644 t/t1007/tree-with-malformed-mode
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index acca9ac..cd10c73 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -183,9 +183,20 @@ for args in "-w --stdin-paths" "--stdin-paths -w"; do
pop_repo
done
-test_expect_success 'corrupt tree' '
+test_expect_success 'too-short tree' '
echo abc >malformed-tree &&
- test_must_fail git hash-object -t tree malformed-tree
+ test_must_fail git hash-object -t tree malformed-tree 2>err &&
+ grep "too-short tree object" err
+'
+
+test_expect_success 'malformed mode in tree' '
+ test_must_fail git hash-object -t tree ../t1007/tree-with-malformed-mode 2>err &&
+ grep "malformed mode in tree entry for tree" err
+'
+
+test_expect_success 'empty filename in tree' '
+ test_must_fail git hash-object -t tree ../t1007/tree-with-empty-filename 2>err &&
+ grep "empty filename in tree entry for tree" err
'
test_expect_success 'corrupt commit' '
diff --git a/t/t1007/tree-with-empty-filename b/t/t1007/tree-with-empty-filename
new file mode 100644
index 0000000000000000000000000000000000000000..aeb1ceb20e485eebd0acbb81c974d1c6fedcc1fe
GIT binary patch
literal 28
kcmXpsFfcPQQDAsB_tET47q2;ccWbUIkGgT_Nl)-Z0Hx{;SO5S3
literal 0
HcmV?d00001
diff --git a/t/t1007/tree-with-malformed-mode b/t/t1007/tree-with-malformed-mode
new file mode 100644
index 0000000000000000000000000000000000000000..24aa84d60ef8e269fb0b29c67b5208639b9da3ae
GIT binary patch
literal 39
vcmYewPcJRb%}+^HNXyJg%}dNpWq3CC(d<nZuQ_{nYpyGgx^d`9Pw+$lU*Quk
literal 0
HcmV?d00001
diff --git a/tree-walk.c b/tree-walk.c
index ce27842..ba544cf 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -27,12 +27,14 @@ static void decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned
const char *path;
unsigned int mode, len;
- if (size < 24 || buf[size - 21])
- die("corrupt tree file");
+ if (size < 23 || buf[size - 21])
+ die("too-short tree object");
path = get_mode(buf, &mode);
- if (!path || !*path)
- die("corrupt tree file");
+ if (!path)
+ die("malformed mode in tree entry for tree");
+ if (!*path)
+ die("empty filename in tree entry for tree");
len = strlen(path) + 1;
/* Initialize the descriptor entry */
@@ -81,7 +83,7 @@ void update_tree_entry(struct tree_desc *desc)
unsigned long len = end - (const unsigned char *)buf;
if (size < len)
- die("corrupt tree file");
+ die("too-short tree file");
buf = end;
size -= len;
desc->buffer = buf;
--
2.8.0.rc4.22.g8ae061a
^ permalink raw reply related
* [PATCH 2/2] fsck: handle bad trees like other errors
From: David Turner @ 2016-09-26 19:32 UTC (permalink / raw)
To: git, peff, mhagger; +Cc: David Turner
In-Reply-To: <1474918365-10937-1-git-send-email-novalis@novalis.org>
From: David Turner <dturner@twosigma.com>
Instead of dying when fsck hits a malformed tree object, log the error
like any other and continue. Now fsck can tell the user which tree is
bad, too.
Signed-off-by: David Turner <dturner@twosigma.com>
---
fsck.c | 18 +++--
t/t1450-fsck.sh | 17 ++++-
.../307e300745b82417cc1a903f875c7d22e45ef907 | 4 +
.../f506a346749bb96f52d8605ffba9fb93d46b5ffd | Bin 0 -> 45 bytes
tree-walk.c | 83 ++++++++++++++++++---
tree-walk.h | 8 ++
6 files changed, 111 insertions(+), 19 deletions(-)
create mode 100644 t/t1450/bad-objects/307e300745b82417cc1a903f875c7d22e45ef907
create mode 100644 t/t1450/bad-objects/f506a346749bb96f52d8605ffba9fb93d46b5ffd
diff --git a/fsck.c b/fsck.c
index c9cf3de..4a3069e 100644
--- a/fsck.c
+++ b/fsck.c
@@ -347,8 +347,9 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
return -1;
name = get_object_name(options, &tree->object);
- init_tree_desc(&desc, tree->buffer, tree->size);
- while (tree_entry(&desc, &entry)) {
+ if (init_tree_desc_gently(&desc, tree->buffer, tree->size))
+ return -1;
+ while (tree_entry_gently(&desc, &entry)) {
struct object *obj;
int result;
@@ -520,7 +521,7 @@ static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, con
static int fsck_tree(struct tree *item, struct fsck_options *options)
{
- int retval;
+ int retval = 0;
int has_null_sha1 = 0;
int has_full_path = 0;
int has_empty_name = 0;
@@ -535,7 +536,10 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
unsigned o_mode;
const char *o_name;
- init_tree_desc(&desc, item->buffer, item->size);
+ if (init_tree_desc_gently(&desc, item->buffer, item->size)) {
+ retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
+ return retval;
+ }
o_mode = 0;
o_name = NULL;
@@ -556,7 +560,10 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
is_hfs_dotgit(name) ||
is_ntfs_dotgit(name));
has_zero_pad |= *(char *)desc.buffer == '0';
- update_tree_entry(&desc);
+ if (update_tree_entry_gently(&desc)) {
+ retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
+ break;
+ }
switch (mode) {
/*
@@ -597,7 +604,6 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
o_name = name;
}
- retval = 0;
if (has_null_sha1)
retval += report(options, &item->object, FSCK_MSG_NULL_SHA1, "contains entries pointing to null sha1");
if (has_full_path)
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 8f52da2..f456963 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -188,8 +188,7 @@ test_expect_success 'commit with NUL in header' '
grep "error in commit $new.*unterminated header: NUL at offset" out
'
-test_expect_success 'malformatted tree object' '
- test_when_finished "git update-ref -d refs/tags/wrong" &&
+test_expect_success 'tree object with duplicate entries' '
test_when_finished "remove_object \$T" &&
T=$(
GIT_INDEX_FILE=test-index &&
@@ -208,6 +207,20 @@ test_expect_success 'malformatted tree object' '
grep "error in tree .*contains duplicate file entries" out
'
+test_expect_success 'unparseable tree object' '
+ test_when_finished "git update-ref -d refs/heads/wrong" &&
+ test_when_finished "remove_object 307e300745b82417cc1a903f875c7d22e45ef907" &&
+ test_when_finished "remove_object f506a346749bb96f52d8605ffba9fb93d46b5ffd" &&
+ mkdir -p .git/objects/30 mkdir -p .git/objects/f5 &&
+ cp ../t1450/bad-objects/307e300745b82417cc1a903f875c7d22e45ef907 .git/objects/30/7e300745b82417cc1a903f875c7d22e45ef907 &&
+ cp ../t1450/bad-objects/f506a346749bb96f52d8605ffba9fb93d46b5ffd .git/objects/f5/06a346749bb96f52d8605ffba9fb93d46b5ffd &&
+ git update-ref refs/heads/wrong 307e300745b82417cc1a903f875c7d22e45ef907 &&
+ test_must_fail git fsck 2>out &&
+ grep "warning: empty filename in tree entry" out &&
+ grep "f506a346749bb96f52d8605ffba9fb93d46b5ffd" out &&
+ ! grep "fatal: empty filename in tree entry" out
+'
+
test_expect_success 'tag pointing to nonexistent' '
cat >invalid-tag <<-\EOF &&
object ffffffffffffffffffffffffffffffffffffffff
diff --git a/t/t1450/bad-objects/307e300745b82417cc1a903f875c7d22e45ef907 b/t/t1450/bad-objects/307e300745b82417cc1a903f875c7d22e45ef907
new file mode 100644
index 0000000..6e23d62
--- /dev/null
+++ b/t/t1450/bad-objects/307e300745b82417cc1a903f875c7d22e45ef907
@@ -0,0 +1,4 @@
+x\x01A\x0e \x10E]s¹f°@Ä\x18\x17\x1eÁ\v0\x05Z\x12[\x12
+õú¢é \ýüÅ{ÿ\x0fic\x01IòP²÷\x104\x1aÛ)Ó+b&\x13ôÙ]\fê\x10ØR`ê2Ü\x13¶)exØ-:xÖ¼ø\f×%mö\x15×û§Ç^[HÕd\x12{-á
+Q\f¿ÍÒ\x7fè\x1dw,\x13p\x1aë
+ßçâ\x03&ë?Þ
\ No newline at end of file
diff --git a/t/t1450/bad-objects/f506a346749bb96f52d8605ffba9fb93d46b5ffd b/t/t1450/bad-objects/f506a346749bb96f52d8605ffba9fb93d46b5ffd
new file mode 100644
index 0000000000000000000000000000000000000000..9111a7fc3c8578906e13c930a0fbd3cae047762e
GIT binary patch
literal 45
zcmb=Jqpj)X8)~pA!NA18z}PS_p~CF@#W%j<>n*Fxv)5_&?<#!Z>Hoon;loq@NdS%f
B6F2|>
literal 0
HcmV?d00001
diff --git a/tree-walk.c b/tree-walk.c
index ba544cf..0fb830b 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -22,33 +22,60 @@ static const char *get_mode(const char *str, unsigned int *modep)
return str;
}
-static void decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned long size)
+static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned long size, struct strbuf *err)
{
const char *path;
unsigned int mode, len;
- if (size < 23 || buf[size - 21])
- die("too-short tree object");
+ if (size < 23 || buf[size - 21]) {
+ strbuf_addstr(err, "too-short tree object");
+ return -1;
+ }
path = get_mode(buf, &mode);
- if (!path)
- die("malformed mode in tree entry for tree");
- if (!*path)
- die("empty filename in tree entry for tree");
+ if (!path) {
+ strbuf_addstr(err, "malformed mode in tree entry");
+ return -1;
+ }
+ if (!*path) {
+ strbuf_addstr(err, "empty filename in tree entry");
+ return -1;
+ }
len = strlen(path) + 1;
/* Initialize the descriptor entry */
desc->entry.path = path;
desc->entry.mode = canon_mode(mode);
desc->entry.oid = (const struct object_id *)(path + len);
+
+ return 0;
}
-void init_tree_desc(struct tree_desc *desc, const void *buffer, unsigned long size)
+static int init_tree_desc_internal(struct tree_desc *desc, const void *buffer, unsigned long size, struct strbuf *err)
{
desc->buffer = buffer;
desc->size = size;
if (size)
- decode_tree_entry(desc, buffer, size);
+ return decode_tree_entry(desc, buffer, size, err);
+ return 0;
+}
+
+void init_tree_desc(struct tree_desc *desc, const void *buffer, unsigned long size)
+{
+ struct strbuf err = STRBUF_INIT;
+ if (init_tree_desc_internal(desc, buffer, size, &err))
+ die("%s", err.buf);
+ strbuf_release(&err);
+}
+
+int init_tree_desc_gently(struct tree_desc *desc, const void *buffer, unsigned long size)
+{
+ struct strbuf err = STRBUF_INIT;
+ int result = init_tree_desc_internal(desc, buffer, size, &err);
+ if (result)
+ warning("%s", err.buf);
+ strbuf_release(&err);
+ return result;
}
void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1)
@@ -75,7 +102,7 @@ static void entry_extract(struct tree_desc *t, struct name_entry *a)
*a = t->entry;
}
-void update_tree_entry(struct tree_desc *desc)
+static int update_tree_entry_internal(struct tree_desc *desc, struct strbuf *err)
{
const void *buf = desc->buffer;
const unsigned char *end = desc->entry.oid->hash + 20;
@@ -89,7 +116,30 @@ void update_tree_entry(struct tree_desc *desc)
desc->buffer = buf;
desc->size = size;
if (size)
- decode_tree_entry(desc, buf, size);
+ return decode_tree_entry(desc, buf, size, err);
+ return 0;
+}
+
+void update_tree_entry(struct tree_desc *desc)
+{
+ struct strbuf err = STRBUF_INIT;
+ if (update_tree_entry_internal(desc, &err))
+ die("%s", err.buf);
+ strbuf_release(&err);
+}
+
+int update_tree_entry_gently(struct tree_desc *desc)
+{
+ struct strbuf err = STRBUF_INIT;
+ if (update_tree_entry_internal(desc, &err)) {
+ warning("%s", err.buf);
+ strbuf_release(&err);
+ /* Stop processing this tree after error */
+ desc->size = 0;
+ return -1;
+ }
+ strbuf_release(&err);
+ return 0;
}
int tree_entry(struct tree_desc *desc, struct name_entry *entry)
@@ -102,6 +152,17 @@ int tree_entry(struct tree_desc *desc, struct name_entry *entry)
return 1;
}
+int tree_entry_gently(struct tree_desc *desc, struct name_entry *entry)
+{
+ if (!desc->size)
+ return 0;
+
+ *entry = desc->entry;
+ if (update_tree_entry_gently(desc))
+ return 0;
+ return 1;
+}
+
void setup_traverse_info(struct traverse_info *info, const char *base)
{
int pathlen = strlen(base);
diff --git a/tree-walk.h b/tree-walk.h
index 97a7d69..68bb78b 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -25,14 +25,22 @@ static inline int tree_entry_len(const struct name_entry *ne)
return (const char *)ne->oid - ne->path - 1;
}
+/*
+ * The _gently versions of these functions warn and return false on a
+ * corrupt tree entry rather than dying,
+ */
+
void update_tree_entry(struct tree_desc *);
+int update_tree_entry_gently(struct tree_desc *);
void init_tree_desc(struct tree_desc *desc, const void *buf, unsigned long size);
+int init_tree_desc_gently(struct tree_desc *desc, const void *buf, unsigned long size);
/*
* Helper function that does both tree_entry_extract() and update_tree_entry()
* and returns true for success
*/
int tree_entry(struct tree_desc *, struct name_entry *);
+int tree_entry_gently(struct tree_desc *, struct name_entry *);
void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1);
--
2.8.0.rc4.22.g8ae061a
^ permalink raw reply related
* [PATCH] Documentation/fetch-options: emit recurse-submodules, jobs unconditionally
From: Stefan Beller @ 2016-09-26 19:35 UTC (permalink / raw)
To: gitster; +Cc: git, Jens.Lehmann, Stefan Beller
Currently the section about recursing into submodules is repeated in
git-pull word for word as it is in fetch-options.
Don't repeat ourselves here and include the --recurse-submodules via
fetch options.
As a bonus expose the --jobs parameter in git-pull as well as that is
declared as a OPT_PASSTHRU for fetch internally already.
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Documentation/fetch-options.txt | 2 ++
Documentation/git-pull.txt | 9 ---------
2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 9eab1f5..352b640 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -89,6 +89,7 @@ ifndef::git-pull[]
option alone does not subject tags to pruning, even if --prune
is used (though tags may be pruned anyway if they are also the
destination of an explicit refspec; see `--prune`).
+endif::git-pull[]
--recurse-submodules[=yes|on-demand|no]::
This option controls if and under what conditions new commits of
@@ -108,6 +109,7 @@ ifndef::git-pull[]
submodules will be faster. By default submodules will be fetched
one at a time.
+ifndef::git-pull[]
--no-recurse-submodules::
Disable recursive fetching of submodules (this has the same effect as
using the `--recurse-submodules=no` option).
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index d033b25..e4cd56a 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -84,15 +84,6 @@ OPTIONS
--verbose::
Pass --verbose to git-fetch and git-merge.
---[no-]recurse-submodules[=yes|on-demand|no]::
- This option controls if new commits of all populated submodules should
- be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
- That might be necessary to get the data needed for merging submodule
- commits, a feature Git learned in 1.7.3. Notice that the result of a
- merge will not be checked out in the submodule, "git submodule update"
- has to be called afterwards to bring the work tree up to date with the
- merge result.
-
Options related to merging
~~~~~~~~~~~~~~~~~~~~~~~~~~
--
2.10.0.129.g35f6318
^ permalink raw reply related
* Re: [PATCH 0/2] tree-walk improvements
From: Stefan Beller @ 2016-09-26 19:39 UTC (permalink / raw)
To: David Turner; +Cc: git@vger.kernel.org, Jeff King, Michael Haggerty
In-Reply-To: <1474918365-10937-1-git-send-email-novalis@novalis.org>
On Mon, Sep 26, 2016 at 12:32 PM, David Turner <novalis@novalis.org> wrote:
> The first patch is a re-roll of Peff's patch from 2014 -- here's
> the archive message:
>
> http://git.661346.n2.nabble.com/PATCH-tree-walk-be-more-specific-about-corrupt-tree-errors-td7603558.html
>
> Not sure why this wasn't applied then, but I thought it looked pretty
> good, so I added a few tests.
>
> Hopefully the encoding works correctly on these patches. If not, you
> can fetch from
> https://github.com/novalis/git/
> on branch dturner/bad-trees
>
> Email address note 1: my employer wants me to use my company address,
> but not my company computer, for patches I write on work time. This
> means that I'm going to continue corresponding from
> novalis@novalis.org, but will send patches with the @twosigma.com
> address in the author line.
Mind sending a patch for .mailmap to reflect that different email
addresses are still the same person? ;)
^ permalink raw reply
* Re: [PATCH 0/2] tree-walk improvements
From: Junio C Hamano @ 2016-09-26 19:43 UTC (permalink / raw)
To: David Turner; +Cc: git, peff, mhagger
In-Reply-To: <1474918365-10937-1-git-send-email-novalis@novalis.org>
David Turner <novalis@novalis.org> writes:
> The first patch is a re-roll of Peff's patch from 2014 -- here's
> the archive message:
>
> http://git.661346.n2.nabble.com/PATCH-tree-walk-be-more-specific-about-corrupt-tree-errors-td7603558.html
>
> Not sure why this wasn't applied then, but I thought it looked pretty
> good, so I added a few tests.
Thanks. Adding tests is very much appreciated. I however wonder
why you needed to reword a perfectly readable "truncated" to
something else, though?
> Email address note 1: my employer wants me to use my company address,
> but not my company computer, for patches I write on work time. This
> means that I'm going to continue corresponding from
> novalis@novalis.org, but will send patches with the @twosigma.com
> address in the author line.
That seems like not an uncommon practice ;-)
> Email address note 2: I'm not subscribed to the mailing list these
> days, so please CC me (at novalis@novalis.org) on replies.
It is good to tell others this, but I suspect that it is known by
those who are likely to respond to these messages that always CC'ing
to individual is the norm on this list ;-)
Thanks.
^ permalink raw reply
* Re: [PATCH v3 2/2] mailinfo: unescape quoted-pair in header fields
From: Kevin Daudt @ 2016-09-26 19:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Swift Geek, Jeff King
In-Reply-To: <xmqqzimuqx7u.fsf@gitster.mtv.corp.google.com>
On Mon, Sep 26, 2016 at 12:26:13PM -0700, Junio C Hamano wrote:
> Junio C Hamano <gitster@pobox.com> writes:
>
> > Don't these also need to be downcased if you prefer $data over
> > $DATA, though?
>
> For now, I'll queue a SQUASH??? that reverts s/DATA/data/ you did to
> 1/2 between your 1/2 and 2/2.
>
Ugh, thanks. I'd replaced it in the first patch, but forgot it in the
second.
^ permalink raw reply
* Re: [PATCH 2/2] fsck: handle bad trees like other errors
From: Junio C Hamano @ 2016-09-26 19:51 UTC (permalink / raw)
To: David Turner; +Cc: git, peff, mhagger, David Turner
In-Reply-To: <1474918365-10937-3-git-send-email-novalis@novalis.org>
David Turner <novalis@novalis.org> writes:
> @@ -535,7 +536,10 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
> unsigned o_mode;
> const char *o_name;
>
> - init_tree_desc(&desc, item->buffer, item->size);
> + if (init_tree_desc_gently(&desc, item->buffer, item->size)) {
> + retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
> + return retval;
> + }
Good. If BAD_TREE is being ignored, this may report a non-error,
but we won't descend into the unreadable tree so it is OK.
> @@ -556,7 +560,10 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
> is_hfs_dotgit(name) ||
> is_ntfs_dotgit(name));
> has_zero_pad |= *(char *)desc.buffer == '0';
> - update_tree_entry(&desc);
> + if (update_tree_entry_gently(&desc)) {
> + retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
> + break;
> + }
Likewise; breaking out of the loop will stop us from reading further
into the corrupted tree data, so this is good.
> @@ -597,7 +604,6 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
> o_name = name;
> }
>
> - retval = 0;
Good code hygiene that you moved this to the very top where it is
defined, so anybody before this step can set it if it wants to.
Reading purely from the text of this function, it was surprising
that you can do without a gently variant of tree_entry_extract(),
but it merely reads into two variables and does not do any error
detection (which happens all in the caller), so it is not at all
surprising after all ;-)
I didn't see anything objectionable in this patch. Thanks for
working on this.
^ permalink raw reply
* Re: [PATCH] git-gui: Do not reset author details on amend
From: Orgad Shaneh @ 2016-09-26 20:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Pat Thoyts, git
In-Reply-To: <CAGHpTBLgwyw_iYK927Yed+XG9ti+tKboz07-FVYWox9WoQkjOg@mail.gmail.com>
4.5 months and counting... :(
- Orgad
On Sun, Jul 10, 2016 at 7:36 AM, Orgad Shaneh <orgads@gmail.com> wrote:
> It's been over 2 months. Can anyone please review and merge it?
>
> Thanks.
> - Orgad
>
> On Wed, May 18, 2016 at 9:12 AM, Orgad Shaneh <orgads@gmail.com> wrote:
>> ping?
>>
>> On Thu, May 5, 2016 at 8:22 PM, Junio C Hamano <gitster@pobox.com> wrote:
>>> Pat, we haven't heard from you for a long time. Are you still
>>> around and interested in helping us by maintaining git-gui?
>>>
>>> Otherwise we may have to start recruiting a volunteer or two to take
>>> this over.
>>>
>>> Thanks.
>>>
>>> Orgad Shaneh <orgads@gmail.com> writes:
>>>
>>>> git commit --amend preserves the author details unless --reset-author is
>>>> given.
>>>>
>>>> git-gui discards the author details on amend.
>>>>
>>>> Fix by reading the author details along with the commit message, and
>>>> setting the appropriate environment variables required for preserving
>>>> them.
>>>>
>>>> Reported long ago in the mailing list[1].
>>>>
>>>> [1] http://article.gmane.org/gmane.comp.version-control.git/243921
>>>>
>>>> Signed-off-by: Orgad Shaneh <orgads@gmail.com>
>>>> ---
>>>> git-gui/lib/commit.tcl | 19 +++++++++++++++++++
>>>> 1 file changed, 19 insertions(+)
>>>>
>>>> diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl
>>>> index 864b687..60edf99 100644
>>>> --- a/git-gui/lib/commit.tcl
>>>> +++ b/git-gui/lib/commit.tcl
>>>> @@ -1,8 +1,13 @@
>>>> # git-gui misc. commit reading/writing support
>>>> # Copyright (C) 2006, 2007 Shawn Pearce
>>>>
>>>> +set author_name ""
>>>> +set author_email ""
>>>> +set author_date ""
>>>> +
>>>> proc load_last_commit {} {
>>>> global HEAD PARENT MERGE_HEAD commit_type ui_comm
>>>> + global author_name author_email author_date
>>>> global repo_config
>>>>
>>>> if {[llength $PARENT] == 0} {
>>>> @@ -34,6 +39,10 @@ You are currently in the middle of a merge that has not been fully completed. Y
>>>> lappend parents [string range $line 7 end]
>>>> } elseif {[string match {encoding *} $line]} {
>>>> set enc [string tolower [string range $line 9 end]]
>>>> + } elseif {[regexp "author (.*)\\s<(.*)>\\s(\\d.*$)" $line all name email time]} {
>>>> + set author_name $name
>>>> + set author_email $email
>>>> + set author_date $time
>>>> }
>>>> }
>>>> set msg [read $fd]
>>>> @@ -107,8 +116,12 @@ proc do_signoff {} {
>>>>
>>>> proc create_new_commit {} {
>>>> global commit_type ui_comm
>>>> + global author_name author_email author_date
>>>>
>>>> set commit_type normal
>>>> + set author_name ""
>>>> + set author_email ""
>>>> + set author_date ""
>>>> $ui_comm delete 0.0 end
>>>> $ui_comm edit reset
>>>> $ui_comm edit modified false
>>>> @@ -327,6 +340,7 @@ proc commit_committree {fd_wt curHEAD msg_p} {
>>>> global ui_comm selected_commit_type
>>>> global file_states selected_paths rescan_active
>>>> global repo_config
>>>> + global env author_name author_email author_date
>>>>
>>>> gets $fd_wt tree_id
>>>> if {[catch {close $fd_wt} err]} {
>>>> @@ -366,6 +380,11 @@ A rescan will be automatically started now.
>>>> }
>>>> }
>>>>
>>>> + if {$author_name ne ""} {
>>>> + set env(GIT_AUTHOR_NAME) $author_name
>>>> + set env(GIT_AUTHOR_EMAIL) $author_email
>>>> + set env(GIT_AUTHOR_DATE) $author_date
>>>> + }
>>>> # -- Create the commit.
>>>> #
>>>> set cmd [list commit-tree $tree_id]
^ permalink raw reply
* Re: [PATCH 2/2] fsck: handle bad trees like other errors
From: Junio C Hamano @ 2016-09-26 20:08 UTC (permalink / raw)
To: David Turner; +Cc: git, peff, mhagger, David Turner
In-Reply-To: <1474918365-10937-3-git-send-email-novalis@novalis.org>
David Turner <novalis@novalis.org> writes:
> From: David Turner <dturner@twosigma.com>
>
> Instead of dying when fsck hits a malformed tree object, log the error
> like any other and continue. Now fsck can tell the user which tree is
> bad, too.
>
> Signed-off-by: David Turner <dturner@twosigma.com>
> ---
> fsck.c | 18 +++--
> t/t1450-fsck.sh | 17 ++++-
> .../307e300745b82417cc1a903f875c7d22e45ef907 | 4 +
To prevent further headaches in this directory, can we have
.gitattributes that tells us that everything in there are binary
files? Something like the attached.
The other object was transferred as a binary patch, but I have no
faith in what I applied from your e-mail message for this file that
went though latin-1 to utf-8 conversion X-<.
t/t1450/bad-objects/.gitattributes | 1 +
1 file changed, 1 insertion(+)
diff --git a/t/t1450/bad-objects/.gitattributes b/t/t1450/bad-objects/.gitattributes
new file mode 100644
index 0000000..a173f27
--- /dev/null
+++ b/t/t1450/bad-objects/.gitattributes
@@ -0,0 +1 @@
+[0-9a-f]*[0-9a-f] -diff
^ permalink raw reply related
* Re: [PATCH 2/2] fsck: handle bad trees like other errors
From: Junio C Hamano @ 2016-09-26 20:11 UTC (permalink / raw)
To: David Turner; +Cc: git, peff, mhagger, David Turner
In-Reply-To: <xmqqh992qv9a.fsf@gitster.mtv.corp.google.com>
Junio C Hamano <gitster@pobox.com> writes:
> To prevent further headaches in this directory, can we have
> .gitattributes that tells us that everything in there are binary
> files? Something like the attached.
>
> The other object was transferred as a binary patch, but I have no
> faith in what I applied from your e-mail message for this file that
> went though latin-1 to utf-8 conversion X-<.
>
> t/t1450/bad-objects/.gitattributes | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/t/t1450/bad-objects/.gitattributes b/t/t1450/bad-objects/.gitattributes
> new file mode 100644
> index 0000000..a173f27
> --- /dev/null
> +++ b/t/t1450/bad-objects/.gitattributes
> @@ -0,0 +1 @@
> +[0-9a-f]*[0-9a-f] -diff
I suspect that the t/t1007 directory in 1/2 may deserve a similar
treatment.
^ permalink raw reply
* Re: [PATCH 0/2] tree-walk improvements
From: David Turner @ 2016-09-26 20:22 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, peff, mhagger
In-Reply-To: <xmqqshsmqwfr.fsf@gitster.mtv.corp.google.com>
On Mon, 2016-09-26 at 12:43 -0700, Junio C Hamano wrote:
> David Turner <novalis@novalis.org> writes:
>
> > The first patch is a re-roll of Peff's patch from 2014 -- here's
> > the archive message:
> >
> > http://git.661346.n2.nabble.com/PATCH-tree-walk-be-more-specific-about-corrupt-tree-errors-td7603558.html
> >
> > Not sure why this wasn't applied then, but I thought it looked pretty
> > good, so I added a few tests.
>
> Thanks. Adding tests is very much appreciated. I however wonder
> why you needed to reword a perfectly readable "truncated" to
> something else, though?
Because truncated, to me, means "something that has been cut off". Here,
the recorded length is too short, so it's probably not the case that
something was cut off -- it was never right to begin with.
^ permalink raw reply
* Re: [PATCH v8 07/11] pkt-line: add functions to read/write flush terminated packet streams
From: Lars Schneider @ 2016-09-26 20:23 UTC (permalink / raw)
To: Jakub Narębski
Cc: git, Jeff King, Junio C Hamano, Stefan Beller,
Martin-Louis Bright, Torsten Bögershausen, Ramsay Jones
In-Reply-To: <507a29a1-99ff-c13e-cf1f-76631345a822@gmail.com>
On 25 Sep 2016, at 15:46, Jakub Narębski <jnareb@gmail.com> wrote:
> W dniu 20.09.2016 o 21:02, larsxschneider@gmail.com pisze:
>> From: Lars Schneider <larsxschneider@gmail.com>
>> +{
>> + static char buf[PKTLINE_DATA_MAXLEN];
>
> Sidenote: we have LARGE_PACKET_MAX (used in previous patch), but
> PKTLINE_DATA_MAXLEN not LARGE_PACKET_DATA_MAX.
Agreed, I will rename it.
>
>> + int err = 0;
>> + ssize_t bytes_to_write;
>> +
>> + while (!err) {
>> + bytes_to_write = xread(fd_in, buf, sizeof(buf));
>> + if (bytes_to_write < 0)
>> + return COPY_READ_ERROR;
>> + if (bytes_to_write == 0)
>> + break;
>> + err = packet_write_gently(fd_out, buf, bytes_to_write);
>> + }
>> + if (!err)
>> + err = packet_flush_gently(fd_out);
>> + return err;
>> +}
>
> Looks good: clean and readable.
>
> Sidenote (probably outside of scope of this patch): what are the
> errors that we can get from this function, beside COPY_READ_ERROR
> of course?
Everything that is returned by "read()"
>> +
>> static int get_packet_data(int fd, char **src_buf, size_t *src_size,
>> void *dst, unsigned size, int options)
>> {
>> @@ -305,3 +346,30 @@ char *packet_read_line_buf(char **src, size_t *src_len, int *dst_len)
>> {
>> return packet_read_line_generic(-1, src, src_len, dst_len);
>> }
>> +
>> +ssize_t read_packetized_to_buf(int fd_in, struct strbuf *sb_out)
>
> It's a bit strange that the signature of write_packetized_from_buf() is
> that different from read_packetized_to_buf(). This includes the return
> value: int vs ssize_t. As I have checked, write() and read() both
> use ssize_t, while fread() and fwrite() both use size_t.
read_packetized_to_buf() returns the number of bytes read or a negative
error code.
write_packetized_from_buf() returns 0 if the call was successful and an
error code if not.
That's the reason these two functions have a different signature
> Perhaps this function should be named read_packetized_to_strbuf()
> (err, I asked this already)?
I agree with the rename as makes it distinct from
write_packetized_from_buf().
>> +{
>> + int paket_len;
>
> Possible typo: shouldn't it be called packet_len?
True!
> Shouldn't it be initialized to 0?
Well, it is set for sure later. That's why I think it is not necessary.
Plus, Eric Wong thought me not to:
"Compilers complain about uninitialized variables."
http://public-inbox.org/git/20160725072745.GB11634@starla/
(Note: he was talking about pointers there :-)
>> + int options = PACKET_READ_GENTLE_ON_EOF;
>
> Why is this even a local variable? It is never changed, and it is
> used only in one place; we can inline it.
Removed.
>> +
>> + size_t oldlen = sb_out->len;
>> + size_t oldalloc = sb_out->alloc;
>
> Just a nitpick (feel free to ignore): doesn't this looks better:
>
> + size_t old_len = sb_out->len;
> + size_t old_alloc = sb_out->alloc;
>
> Also perhaps s/old_/orig_/g.
Agreed. That matches the other variables better.
>> + strbuf_grow(sb_out, PKTLINE_DATA_MAXLEN+1);
>> + paket_len = packet_read(fd_in, NULL, NULL,
>> + sb_out->buf + sb_out->len, PKTLINE_DATA_MAXLEN+1, options);
>
> A question (which perhaps was answered during the development of this
> patch series): why is this +1 in PKTLINE_DATA_MAXLEN+1 here?
Nice catch. I think this is wrong:
https://github.com/git/git/blob/6fe1b1407ed91823daa5d487abe457ff37463349/pkt-line.c#L196
It should be "if (len > size)" ... then we don't need the "+1" here.
(but I need to think a bit more about this)
>
>> + if (paket_len <= 0)
>> + break;
>> + sb_out->len += paket_len;
>> + }
>> +
>> + if (paket_len < 0) {
>> + if (oldalloc == 0)
>> + strbuf_release(sb_out);
>> + else
>> + strbuf_setlen(sb_out, oldlen);
>
> A question (maybe I don't understand strbufs): why there is a special
> case for oldalloc == 0?
I tried to mimic the behavior of strbuf_read() [1]. The error handling
was introduced in 2fc647 [2] to ease error handling:
"This allows for easier error handling, as callers only need to call
strbuf_release() if A) the command succeeded or B) if they would have had
to do so anyway because they added something to the strbuf themselves."
[1] https://github.com/git/git/blob/cda1bbd474805e653dda8a71d4ea3790e2a66cbb/strbuf.c#L377-L383
[2] https://github.com/git/git/commit/2fc647004ac7016128372a85db8245581e493812
Thanks,
Lars
^ permalink raw reply
* Re: [PATCH] Documentation/fetch-options: emit recurse-submodules, jobs unconditionally
From: Junio C Hamano @ 2016-09-26 20:29 UTC (permalink / raw)
To: Stefan Beller; +Cc: git, Jens.Lehmann
In-Reply-To: <20160926193553.32631-1-sbeller@google.com>
Stefan Beller <sbeller@google.com> writes:
> Currently the section about recursing into submodules is repeated in
> git-pull word for word as it is in fetch-options.
>
> Don't repeat ourselves here and include the --recurse-submodules via
> fetch options.
>
> As a bonus expose the --jobs parameter in git-pull as well as that is
> declared as a OPT_PASSTHRU for fetch internally already.
The above may not be technically wrong, but smells like an
under-researched description.
IOW, "Why did the commit that introduced the option described it
this way in the first place? Was there a specific reason why it had
to be that way, and that reason is no longer with us now, which
makes this change safe?" is a very natural question somebody who
sees this patch, and your description does not answer it.
It seems that the option to recurse into submodules was added by
Jens's 7dce19d3 ("fetch/pull: Add the --recurse-submodules option",
2010-11-12) to both fetch and pull at the same time. I suspected
perhaps we hid it from pull initially while describing it for fetch,
but that does not seem to be the case, and back at that version,
pull and fetch shared the description without duplicating.
So where did we go wrong? Was there a good reason why we have two
instances of these option descriptions, and if so, are we sure that
that reason is no longer applicable to today's system that we can
safely share the description? The proposed log message is a place
to answer these questions.
By the way, 7dce19d3 is interesting in another way and worth
studying in that it adds --submodule-prefix ;-) It may be something
we want to consider consolidating with what Brandon has been working
on.
By the way^2, the "unconditionally" on the title conveyed less
information than their bits weigh. Unless a reader knows
fetch-options are shared between fetch and pull, s/he would not know
you meant by "unconditionally" to show these in both fetch and pull.
Documentation: share more descriptions for options between fetch and pull
perhaps?
Thanks.
^ permalink raw reply
* Re: [PATCH] Documentation/fetch-options: emit recurse-submodules, jobs unconditionally
From: Stefan Beller @ 2016-09-26 20:44 UTC (permalink / raw)
To: Junio C Hamano, Brandon Williams; +Cc: git@vger.kernel.org, Jens Lehmann
In-Reply-To: <xmqq7f9yqu9w.fsf@gitster.mtv.corp.google.com>
On Mon, Sep 26, 2016 at 1:29 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Stefan Beller <sbeller@google.com> writes:
>
>> Currently the section about recursing into submodules is repeated in
>> git-pull word for word as it is in fetch-options.
>>
>> Don't repeat ourselves here and include the --recurse-submodules via
>> fetch options.
>>
>> As a bonus expose the --jobs parameter in git-pull as well as that is
>> declared as a OPT_PASSTHRU for fetch internally already.
>
> The above may not be technically wrong, but smells like an
> under-researched description.
I knew this question was coming, but the research was not as easy to
follow as it seemed convoluted to me.
After a bit more research, I think 8f0700dd33f (fetch/pull: Add the
'on-demand' value to the --recurse-submodules option) is the culprit,
where this patch should have been squashed into, as that made the
both locations word for word equal.
>
> So where did we go wrong? Was there a good reason why we have two
> instances of these option descriptions, and if so, are we sure that
> that reason is no longer applicable to today's system that we can
> safely share the description? The proposed log message is a place
> to answer these questions.
The commit above is where we went wrong; It doesn't seem like a good
reason for not including this is given in there.
>
> By the way, 7dce19d3 is interesting in another way and worth
> studying in that it adds --submodule-prefix ;-) It may be something
> we want to consider consolidating with what Brandon has been working
> on.
That's why Brandon is cc'd now. :)
>
> By the way^2, the "unconditionally" on the title conveyed less
> information than their bits weigh. Unless a reader knows
> fetch-options are shared between fetch and pull, s/he would not know
> you meant by "unconditionally" to show these in both fetch and pull.
>
> Documentation: share more descriptions for options between fetch and pull
>
> perhaps?
That's way better.
I'll resend shortly.
Thanks,
Stefan
^ permalink raw reply
* [RFC PATCH v4] revision: new rev^-n shorthand for rev^n..rev
From: Vegard Nossum @ 2016-09-26 20:49 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Santi Béjar, Kevin Bracey, Philip Oakley,
Matthieu Moy, Ramsay Jones, Jakub Narębski, Vegard Nossum
I often use rev^..rev to get all the commits in the branch that was merged
in by the merge commit 'rev' (including the merge itself). To save typing
(or copy-pasting, if the rev is long -- like a full SHA-1 or branch name)
we can make rev^- a shorthand for that.
The existing syntax rev^! seems like it should do the same thing, but it
doesn't really do the right thing for merge commits (it doesn't include
the commits from side branches).
As a natural generalisation, we also accept rev^-n where n excludes the
nth parent of rev. For example, for a two-parent merge, you can use rev^-2
to get the set of commits which were made to the main branch while the
topic branch was prepared.
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
[v2: Use ^- instead of % as suggested by Junio Hamano and use some
common helper functions for parsing.]
[v3: Use 'struct object_id' instead of 'char[20]' and add some tests as
suggested by Matthieu Moy; fix missing '-' in Documentation/revisions.txt
as suggested by Ramsay Jones; misc changelog + documentation fixes as
suggested by Philip Oakley.]
[v4: Documentation fixes and parsing rework suggested by Junio Hamano
and add some more tests.]
---
Documentation/revisions.txt | 17 +++++++-
builtin/rev-parse.c | 47 +++++++++++++++------
revision.c | 32 +++++++++++++--
t/t6070-rev-parent-exclusion.sh | 90 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 168 insertions(+), 18 deletions(-)
create mode 100755 t/t6070-rev-parent-exclusion.sh
diff --git Documentation/revisions.txt Documentation/revisions.txt
index 4bed5b1..ba11b9c 100644
--- Documentation/revisions.txt
+++ Documentation/revisions.txt
@@ -283,7 +283,7 @@ empty range that is both reachable and unreachable from HEAD.
Other <rev>{caret} Parent Shorthand Notations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Two other shorthands exist, particularly useful for merge commits,
+Three other shorthands exist, particularly useful for merge commits,
for naming a set that is formed by a commit and its parent commits.
The 'r1{caret}@' notation means all parents of 'r1'.
@@ -291,8 +291,15 @@ The 'r1{caret}@' notation means all parents of 'r1'.
The 'r1{caret}!' notation includes commit 'r1' but excludes all of its parents.
By itself, this notation denotes the single commit 'r1'.
+The '<rev>{caret}-{<n>}' notation includes '<rev>' but excludes the <n>th
+parent (i.e. a shorthand for '<rev>{caret}<n>..<rev>'), with '<n>' = 1 if
+not given. This is typically useful for merge commits where you
+can just pass '<commit>{caret}-' to get all the commits in the branch
+that was merged in merge commit '<commit>' (including '<commit>'
+itself).
+
While '<rev>{caret}<n>' was about specifying a single commit parent, these
-two notations consider all its parents. For example you can say
+three notations also consider its parents. For example you can say
'HEAD{caret}2{caret}@', however you cannot say 'HEAD{caret}@{caret}2'.
Revision Range Summary
@@ -326,6 +333,10 @@ Revision Range Summary
as giving commit '<rev>' and then all its parents prefixed with
'{caret}' to exclude them (and their ancestors).
+'<rev>{caret}-{<n>}', e.g. 'HEAD{caret}-, HEAD{caret}-2'::
+ Equivalent to '<rev>{caret}<n>..<rev>', with '<n>' = 1 if not
+ given.
+
Here are a handful of examples using the Loeliger illustration above,
with each step in the notation's expansion and selection carefully
spelt out:
@@ -339,6 +350,8 @@ spelt out:
C I J F C
B..C = ^B C C
B...C = B ^F C G H D E B C
+ B^- = B^..B
+ = ^B^1 B E I J F B
C^@ = C^1
= F I J F
B^@ = B^1 B^2 B^3
diff --git builtin/rev-parse.c builtin/rev-parse.c
index 76cf05e..2c3da19 100644
--- builtin/rev-parse.c
+++ builtin/rev-parse.c
@@ -298,14 +298,30 @@ static int try_parent_shorthands(const char *arg)
unsigned char sha1[20];
struct commit *commit;
struct commit_list *parents;
- int parents_only;
-
- if ((dotdot = strstr(arg, "^!")))
- parents_only = 0;
- else if ((dotdot = strstr(arg, "^@")))
- parents_only = 1;
-
- if (!dotdot || dotdot[2])
+ int parent_number;
+ int include_rev = 0;
+ int include_parents = 0;
+ int exclude_parent = 0;
+
+ if ((dotdot = strstr(arg, "^!"))) {
+ include_rev = 1;
+ if (dotdot[2])
+ return 0;
+ } else if ((dotdot = strstr(arg, "^@"))) {
+ include_parents = 1;
+ if (dotdot[2])
+ return 0;
+ } else if ((dotdot = strstr(arg, "^-"))) {
+ include_rev = 1;
+ exclude_parent = 1;
+
+ if (dotdot[2]) {
+ char *end;
+ exclude_parent = strtoul(dotdot + 2, &end, 10);
+ if (*end != '\0' || !exclude_parent)
+ return 0;
+ }
+ } else
return 0;
*dotdot = 0;
@@ -314,14 +330,21 @@ static int try_parent_shorthands(const char *arg)
return 0;
}
- if (!parents_only)
+ if (include_rev)
show_rev(NORMAL, sha1, arg);
commit = lookup_commit_reference(sha1);
- for (parents = commit->parents; parents; parents = parents->next)
- show_rev(parents_only ? NORMAL : REVERSED,
- parents->item->object.oid.hash, arg);
+ for (parent_number = 1, parents = commit->parents;
+ parents; parents = parents->next, parent_number++) {
+ if (exclude_parent && parent_number != exclude_parent)
+ continue;
+
+ show_rev(include_parents ? NORMAL : REVERSED,
+ parents->item->object.oid.hash, arg);
+ }
*dotdot = '^';
+ if (exclude_parent >= parent_number)
+ return 0;
return 1;
}
diff --git revision.c revision.c
index 969b3d1..9ae95bf 100644
--- revision.c
+++ revision.c
@@ -1289,12 +1289,14 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned flags)
}
}
-static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
+static int add_parents_only(struct rev_info *revs, const char *arg_, int flags,
+ int exclude_parent)
{
unsigned char sha1[20];
struct object *it;
struct commit *commit;
struct commit_list *parents;
+ int parent_number;
const char *arg = arg_;
if (*arg == '^') {
@@ -1316,12 +1318,18 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
if (it->type != OBJ_COMMIT)
return 0;
commit = (struct commit *)it;
- for (parents = commit->parents; parents; parents = parents->next) {
+ for (parent_number = 1, parents = commit->parents;
+ parents; parents = parents->next, parent_number++) {
+ if (exclude_parent && parent_number != exclude_parent)
+ continue;
+
it = &parents->item->object;
it->flags |= flags;
add_rev_cmdline(revs, it, arg_, REV_CMD_PARENTS_ONLY, flags);
add_pending_object(revs, it, arg);
}
+ if (exclude_parent >= parent_number)
+ return 0;
return 1;
}
@@ -1519,17 +1527,33 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
}
*dotdot = '.';
}
+
dotdot = strstr(arg, "^@");
if (dotdot && !dotdot[2]) {
*dotdot = 0;
- if (add_parents_only(revs, arg, flags))
+ if (add_parents_only(revs, arg, flags, 0))
return 0;
*dotdot = '^';
}
dotdot = strstr(arg, "^!");
if (dotdot && !dotdot[2]) {
*dotdot = 0;
- if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM)))
+ if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), 0))
+ *dotdot = '^';
+ }
+ dotdot = strstr(arg, "^-");
+ if (dotdot) {
+ int exclude_parent = 1;
+
+ if (dotdot[2]) {
+ char *end;
+ exclude_parent = strtoul(dotdot + 2, &end, 10);
+ if (*end != '\0' || !exclude_parent)
+ return -1;
+ }
+
+ *dotdot = 0;
+ if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), exclude_parent))
*dotdot = '^';
}
diff --git t/t6070-rev-parent-exclusion.sh t/t6070-rev-parent-exclusion.sh
new file mode 100755
index 0000000..e6e5a8d
--- /dev/null
+++ t/t6070-rev-parent-exclusion.sh
@@ -0,0 +1,90 @@
+#!/bin/sh
+
+test_description='rev-list/rev-parse rev^- parsing'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ test_commit one &&
+ test_commit two &&
+ test_commit three &&
+
+ # Merge in a branch for testing ^-
+ git checkout -b branch &&
+ git checkout HEAD^^ &&
+ git merge -m merge --no-edit --no-ff branch &&
+ git checkout -b merge
+'
+
+# The merged branch has 2 commits + the merge
+test_expect_success 'rev-list --count merge^- = merge^..merge' '
+ git rev-list --count merge^..merge >expect &&
+ echo 3 >actual &&
+ test_cmp expect actual
+'
+
+# All rev-parse tests
+
+test_expect_success 'rev-parse merge^- = merge^..merge' '
+ git rev-parse merge^..merge >expect &&
+ git rev-parse merge^- >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-parse merge^-1 = merge^..merge' '
+ git rev-parse merge^1..merge >expect &&
+ git rev-parse merge^-1 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-parse merge^-2 = merge^2..merge' '
+ git rev-parse merge^2..merge >expect &&
+ git rev-parse merge^-2 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-parse merge^-0' '
+ test_must_fail git rev-parse merge^-0
+'
+
+test_expect_success 'rev-parse merge^-3' '
+ test_must_fail git rev-parse merge^-3
+'
+
+test_expect_success 'rev-parse merge^-^' '
+ test_must_fail git rev-parse merge^-^
+'
+
+# All rev-list tests (should be mostly the same as rev-parse)
+
+test_expect_success 'rev-list merge^- = merge^..merge' '
+ git rev-list merge^..merge >expect &&
+ git rev-list merge^- >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-list merge^-1 = merge^1..merge' '
+ git rev-list merge^1..merge >expect &&
+ git rev-list merge^-1 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-list merge^-2 = merge^2..merge' '
+ git rev-list merge^2..merge >expect &&
+ git rev-list merge^-2 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-list merge^-0' '
+ test_must_fail git rev-list merge^-0
+'
+
+test_expect_success 'rev-list merge^-3' '
+ test_must_fail git rev-list merge^-3
+'
+
+test_expect_success 'rev-list merge^-^' '
+ test_must_fail git rev-list merge^-^
+'
+
+test_done
--
2.10.0.rc0.1.g07c9292
^ permalink raw reply related
* Re: [PATCH] Documentation/fetch-options: emit recurse-submodules, jobs unconditionally
From: Junio C Hamano @ 2016-09-26 20:54 UTC (permalink / raw)
To: Stefan Beller; +Cc: Brandon Williams, git@vger.kernel.org, Jens Lehmann
In-Reply-To: <CAGZ79kbeq+Wznm=ChWO0tU5A_haPQ6DvKNHbK+8Y3es5OVcRag@mail.gmail.com>
Stefan Beller <sbeller@google.com> writes:
> After a bit more research, I think 8f0700dd33f (fetch/pull: Add the
> 'on-demand' value to the --recurse-submodules option) is the culprit,
> where this patch should have been squashed into, as that made the
> both locations word for word equal.
Hmph, my digging points to elsewhere. 7811d960 ("pull: Document the
"--[no-]recurse-submodules" options", 2011-02-07) which is older
than 8f0700dd ("fetch/pull: Add the 'on-demand' value to the
--recurse-submodules option", 2011-03-06) seems to be the real
change that pulled the description of recurse-submodules made in
fetch-options into "show this only when we are not describing pull".
Unfortunately it is not clear why we actively wanted to be sketchier
when showing "git help fetch"; otherwise the change would have been
made to the existing description there without adding a new entry to
"git-pull.txt".
^ permalink raw reply
* Re: [PATCH 0/2] tree-walk improvements
From: Junio C Hamano @ 2016-09-26 21:04 UTC (permalink / raw)
To: David Turner; +Cc: git, peff, mhagger
In-Reply-To: <1474918365-10937-1-git-send-email-novalis@novalis.org>
David Turner <novalis@novalis.org> writes:
> Hopefully the encoding works correctly on these patches. If not, you
> can fetch from
> https://github.com/novalis/git/
> on branch dturner/bad-trees
This does not test cleanly here, unfortunately. Specifically, tests
30 and 31 t1007 do fine with 1/2 alone, but they seem to break with
2/2 applied.
I didn't dug further. At least not yet.
^ permalink raw reply
* Re: [PATCH] Documentation/fetch-options: emit recurse-submodules, jobs unconditionally
From: Stefan Beller @ 2016-09-26 21:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Brandon Williams, git@vger.kernel.org, Jens Lehmann
In-Reply-To: <xmqq37kmqt4a.fsf@gitster.mtv.corp.google.com>
On Mon, Sep 26, 2016 at 1:54 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Stefan Beller <sbeller@google.com> writes:
>
>> After a bit more research, I think 8f0700dd33f (fetch/pull: Add the
>> 'on-demand' value to the --recurse-submodules option) is the culprit,
>> where this patch should have been squashed into, as that made the
>> both locations word for word equal.
>
> Hmph, my digging points to elsewhere. 7811d960 ("pull: Document the
> "--[no-]recurse-submodules" options", 2011-02-07)
That commit seems like it want to intentionally keep it different for
fetch and pull
(otherwise the fetch-options.txt would have been reworded there).
Rereading the actual option descriptions, I realize they are different.
(Initially I used a diff tool to see if there is aminor difference, and I was
surprised they were word for word identical; It must have been a mistake
on copying one of the option texts)
The git-pull part actually conveys pull specific information, so let's drop
this patch entirely.
> which is older
> than 8f0700dd ("fetch/pull: Add the 'on-demand' value to the
> --recurse-submodules option", 2011-03-06) seems to be the real
> change that pulled the description of recurse-submodules made in
> fetch-options into "show this only when we are not describing pull".
>
> Unfortunately it is not clear why we actively wanted to be sketchier
> when showing "git help fetch"; otherwise the change would have been
> made to the existing description there without adding a new entry to
> "git-pull.txt".
>
^ permalink raw reply
* Re: [RFC PATCH v4] revision: new rev^-n shorthand for rev^n..rev
From: Junio C Hamano @ 2016-09-26 21:23 UTC (permalink / raw)
To: Vegard Nossum
Cc: git, Santi Béjar, Kevin Bracey, Philip Oakley, Matthieu Moy,
Ramsay Jones, Jakub Narębski
In-Reply-To: <20160926204959.26007-1-vegard.nossum@oracle.com>
Vegard Nossum <vegard.nossum@oracle.com> writes:
> I often use rev^..rev to get all the commits in the branch that was merged
> in by the merge commit 'rev' (including the merge itself). To save typing
> (or copy-pasting, if the rev is long -- like a full SHA-1 or branch name)
> we can make rev^- a shorthand for that.
>
> The existing syntax rev^! seems like it should do the same thing, but it
> doesn't really do the right thing for merge commits (it doesn't include
> the commits from side branches).
>
> As a natural generalisation, we also accept rev^-n where n excludes the
> nth parent of rev. For example, for a two-parent merge, you can use rev^-2
> to get the set of commits which were made to the main branch while the
> topic branch was prepared.
I am tempted to suggest that this four-line paragraph may be
sufficient:
"git log rev^..rev" is commonly used to show all work done on
and merged from a side branch. Introduce a short-hand "rev^-"
for this, and also allow it to take "rev^-$n" to mean "reachable
from rev, excluding what is reachable from n-th parent of rev".
This alone is not a strong enough reason to ask you to reroll the
patch.
> diff --git builtin/rev-parse.c builtin/rev-parse.c
> index 76cf05e..2c3da19 100644
> --- builtin/rev-parse.c
> +++ builtin/rev-parse.c
> @@ -298,14 +298,30 @@ static int try_parent_shorthands(const char *arg)
> unsigned char sha1[20];
> struct commit *commit;
> struct commit_list *parents;
> - int parents_only;
> -
> - if ((dotdot = strstr(arg, "^!")))
> - parents_only = 0;
> - else if ((dotdot = strstr(arg, "^@")))
> - parents_only = 1;
> -
> - if (!dotdot || dotdot[2])
> + int parent_number;
> + int include_rev = 0;
> + int include_parents = 0;
> + int exclude_parent = 0;
> +
> + if ((dotdot = strstr(arg, "^!"))) {
> + include_rev = 1;
> + if (dotdot[2])
> + return 0;
> + } else if ((dotdot = strstr(arg, "^@"))) {
> + include_parents = 1;
> + if (dotdot[2])
> + return 0;
> + } else if ((dotdot = strstr(arg, "^-"))) {
> + include_rev = 1;
> + exclude_parent = 1;
> +
> + if (dotdot[2]) {
> + char *end;
> + exclude_parent = strtoul(dotdot + 2, &end, 10);
> + if (*end != '\0' || !exclude_parent)
> + return 0;
> + }
> + } else
> return 0;
Nice; we can tell where this is going without looking at the rest,
which is a very good sign that the new variables are doing their
work of telling the readers what is going on clearly.
> @@ -314,14 +330,21 @@ static int try_parent_shorthands(const char *arg)
> return 0;
> }
>
> - if (!parents_only)
> + if (include_rev)
> show_rev(NORMAL, sha1, arg);
> commit = lookup_commit_reference(sha1);
> - for (parents = commit->parents; parents; parents = parents->next)
> - show_rev(parents_only ? NORMAL : REVERSED,
> - parents->item->object.oid.hash, arg);
> + for (parent_number = 1, parents = commit->parents;
> + parents; parents = parents->next, parent_number++) {
Micronit. When splitting "for (init; fini; cont)" into multiple
lines, it is often easier to read to make that into three lines:
for (parent_number = 1, parents = commit->parents;
parents;
parents = parents->next, parent_number++) {
> + if (exclude_parent && parent_number != exclude_parent)
> + continue;
> +
> + show_rev(include_parents ? NORMAL : REVERSED,
> + parents->item->object.oid.hash, arg);
> + }
It is very clear to see what is going on. Good job.
> *dotdot = '^';
> + if (exclude_parent >= parent_number)
> + return 0;
This is not quite nice. You've already called show_rev() number of
times, and it is too late to signal an error here. I think you
would need to count the number of parents much earlier when
exclude_parent option is in effect and error out before making any
call to show_rev().
> diff --git revision.c revision.c
> index 969b3d1..9ae95bf 100644
> --- revision.c
> +++ revision.c
> @@ -1289,12 +1289,14 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned flags)
> }
> }
>
> -static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
> +static int add_parents_only(struct rev_info *revs, const char *arg_, int flags,
> + int exclude_parent)
> {
> unsigned char sha1[20];
> struct object *it;
> struct commit *commit;
> struct commit_list *parents;
> + int parent_number;
> const char *arg = arg_;
>
> if (*arg == '^') {
> @@ -1316,12 +1318,18 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
> if (it->type != OBJ_COMMIT)
> return 0;
> commit = (struct commit *)it;
> - for (parents = commit->parents; parents; parents = parents->next) {
> + for (parent_number = 1, parents = commit->parents;
> + parents; parents = parents->next, parent_number++) {
> + if (exclude_parent && parent_number != exclude_parent)
> + continue;
> +
> it = &parents->item->object;
> it->flags |= flags;
> add_rev_cmdline(revs, it, arg_, REV_CMD_PARENTS_ONLY, flags);
> add_pending_object(revs, it, arg);
> }
> + if (exclude_parent >= parent_number)
> + return 0;
Likewise. It is way too late to say "Nah, this wasn't a valid rev^-
notation after all" to the caller after calling add_rev_cmdline()
and add_pending_object() in the above loop. Just like "blob^-"
silently returns 0 in the pre-context in this hunk, count the number
of parents before entering this loop when exclude_parent is in
effect, and if the number after '-' exceeds the actual number of
parents, silently return 0, perhaps?
> diff --git t/t6070-rev-parent-exclusion.sh t/t6070-rev-parent-exclusion.sh
We already seem to have t6101 as the best place to add test for this
new feature. Near the end of that script, ^@ and ^! are tested.
Thanks.
^ permalink raw reply
* git 2.9.2: is RUNTIME_PREFIX supposed to work?
From: Paul Smith @ 2016-09-26 21:32 UTC (permalink / raw)
To: git
Hi all. I'm trying to create a relocatable installation of Git 2.9.2,
so I can copy it anywhere and it continues to run without any problem.
This is on GNU/Linux systems, FWIW.
Looking through the code (for some other reason) I discovered the
RUNTIME_PREFIX setting which appears to attempt to set up the system
paths based on a prefix determined from the directory containing the
git command. That looks like exactly what I want.
If I set RUNTIME_PREFIX=YesPlease and gitexecdir=libexec/git-core on
the make invocation, it appears to do the right thing when I invoke
.../libexec/git-core/git, even if I move it around. Cool!
Except, when it doesn't. And when it doesn't is all the situations
where Git runs subcommands: for example, "git pull" which wants to
invoke fetch and merge-base commands.
When RUNTIME_PREFIX is defined, it's a requirement that the argv[0] for
the process be a fully-qualified pathname: if it's not, then git will
assert at exec_cmd.c:23 in system_path():
assert(argv0_path);
The argv0_path variable is set based on argv[0] passed in to main().
When I invoke top-level Git commands, that value is a fully-qualified
path just as you'd expect. However, when Git itself invokes
subcommands it does so in a weird way where argv[0] is the command it
wants to invoke, using the magical execv() facility that lets you
invoke a command while providing a different value as argv[0].
For example my core dump from the assert of the merge-base shows:
(gdb) p argv[0]
$2 = 0x7fffd70c338e "merge-base"
(gdb) p argv[1]
$3 = 0x7fffd70c3399 "--fork-point"
(gdb) p argv[2]
$4 = 0x7fffd70c33a6 "refs/remotes/origin/master"
(gdb) p argv[3]
$5 = 0x7fffd70c33c1 "master"
Looking at builtin/pull.c I see get_rebase_fork_point() calls
capture_command() with this Git command, which calls start_command(),
which calls execv_git_command(), which calls sane_execvp(), which
invokes "git" as the filename but with argv[0] as "merge-base":
sane_execvp("git", (char **)nargv.argv);
...calls sane_execvp():
if (!execvp(file, argv))
return 0; /* cannot happen ;-) */
This causes the assert.
So, my question is: is this a bug in RUNTIME_PREFIX support? Or is
RUNTIME_PREFIX no longer supported, or maybe not supported at all on
UNIX-type operating systems?
Cheers!
^ 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