* [PATCH v3 7/8] fetch: fetch objects by their exact SHA-1 object names
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
Teach "git fetch" to accept an exact SHA-1 object name the user may
obtain out of band on the LHS of a pathspec, and send it on a "want"
message when the server side advertises the allow-tip-sha1-in-want
capability.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
fetch-pack.c | 22 +++++++++++++++++++++-
remote.c | 12 +++++++++++-
remote.h | 1 +
t/t5516-fetch-push.sh | 34 ++++++++++++++++++++++++++++++++++
4 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/fetch-pack.c b/fetch-pack.c
index 915c0b7..70db646 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -36,7 +36,7 @@ static int marked;
#define MAX_IN_VAIN 256
static struct commit_list *rev_list;
-static int non_common_revs, multi_ack, use_sideband;
+static int non_common_revs, multi_ack, use_sideband, allow_tip_sha1_in_want;
static void rev_list_push(struct commit *commit, int mark)
{
@@ -563,6 +563,21 @@ static void filter_refs(struct fetch_pack_args *args,
}
}
+ /* Append unmatched requests to the list */
+ if (allow_tip_sha1_in_want) {
+ for (i = 0; i < nr_sought; i++) {
+ ref = sought[i];
+ if (ref->matched)
+ continue;
+ if (get_sha1_hex(ref->name, ref->old_sha1))
+ continue;
+
+ ref->matched = 1;
+ *newtail = ref;
+ ref->next = NULL;
+ newtail = &ref->next;
+ }
+ }
*refs = newlist;
}
@@ -803,6 +818,11 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
fprintf(stderr, "Server supports side-band\n");
use_sideband = 1;
}
+ if (server_supports("allow-tip-sha1-in-want")) {
+ if (args->verbose)
+ fprintf(stderr, "Server supports allow-tip-sha1-in-want\n");
+ allow_tip_sha1_in_want = 1;
+ }
if (!server_supports("thin-pack"))
args->use_thin_pack = 0;
if (!server_supports("no-progress"))
diff --git a/remote.c b/remote.c
index 1b7828d..1118d05 100644
--- a/remote.c
+++ b/remote.c
@@ -15,6 +15,7 @@ static struct refspec s_tag_refspec = {
0,
1,
0,
+ 0,
"refs/tags/*",
"refs/tags/*"
};
@@ -565,9 +566,13 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp
flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
if (fetch) {
+ unsigned char unused[40];
+
/* LHS */
if (!*rs[i].src)
; /* empty is ok; it means "HEAD" */
+ else if (llen == 40 && !get_sha1_hex(rs[i].src, unused))
+ rs[i].exact_sha1 = 1; /* ok */
else if (!check_refname_format(rs[i].src, flags))
; /* valid looking ref is ok */
else
@@ -1495,7 +1500,12 @@ int get_fetch_map(const struct ref *remote_refs,
} else {
const char *name = refspec->src[0] ? refspec->src : "HEAD";
- ref_map = get_remote_ref(remote_refs, name);
+ if (refspec->exact_sha1) {
+ ref_map = alloc_ref(name);
+ get_sha1_hex(name, ref_map->old_sha1);
+ } else {
+ ref_map = get_remote_ref(remote_refs, name);
+ }
if (!missing_ok && !ref_map)
die("Couldn't find remote ref %s", name);
if (ref_map) {
diff --git a/remote.h b/remote.h
index 251d8fd..f7b08f1 100644
--- a/remote.h
+++ b/remote.h
@@ -62,6 +62,7 @@ struct refspec {
unsigned force : 1;
unsigned pattern : 1;
unsigned matching : 1;
+ unsigned exact_sha1 : 1;
char *src;
char *dst;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 852efb6..522056f 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1037,6 +1037,40 @@ test_expect_success 'push --prune refspec' '
! check_push_result $the_first_commit tmp/foo tmp/bar
'
+test_expect_success 'fetch exact SHA1' '
+ mk_test heads/master hidden/one &&
+ git push testrepo master:refs/hidden/one &&
+ (
+ cd testrepo &&
+ git config transfer.hiderefs refs/hidden
+ ) &&
+ check_push_result $the_commit hidden/one &&
+
+ mk_child child &&
+ (
+ cd child &&
+
+ # make sure $the_commit does not exist here
+ git repack -a -d &&
+ git prune &&
+ test_must_fail git cat-file -t $the_commit &&
+
+ # fetching the hidden object should fail by default
+ test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy &&
+ test_must_fail git rev-parse --verify refs/heads/copy &&
+
+ # the server side can allow it to succeed
+ (
+ cd ../testrepo &&
+ git config uploadpack.allowtipsha1inwant true
+ ) &&
+
+ git fetch -v ../testrepo $the_commit:refs/heads/copy &&
+ result=$(git rev-parse --verify refs/heads/copy) &&
+ test "$the_commit" = "$result"
+ )
+'
+
test_expect_success 'push to update a hidden ref' '
mk_test heads/master hidden/one hidden/two hidden/three &&
(
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* [PATCH v3 6/8] upload-pack: optionally allow fetching from the tips of hidden refs
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
With uploadpack.allowtipsha1inwant configuration option set, future
versions of "git fetch" that allow an exact object name (likely to
have been obtained out of band) on the LHS of the fetch refspec can
make a request with a "want" line that names an object that may not
have been advertised due to transfer.hiderefs configuration.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/config.txt | 8 +++++++-
upload-pack.c | 25 +++++++++++++++++++------
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index f57c802..2dce021 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2066,13 +2066,19 @@ transfer.hiderefs::
and is hidden from `git ls-remote`, `git fetch`, `git push :`,
etc. An attempt to update or delete a hidden ref by `git push`
is rejected, and an attempt to fetch a hidden ref by `git fetch`
- will fail.
+ will fail. See also `uploadpack.allowtipsha1inwant`.
transfer.unpackLimit::
When `fetch.unpackLimit` or `receive.unpackLimit` are
not set, the value of this variable is used instead.
The default value is 100.
+uploadpack.allowtipsha1inwant::
+ When `transfer.hiderefs` is in effect, allow `upload-pack`
+ to accept a fetch request that asks for an object at the tip
+ of a hidden ref (by default, such a request is rejected).
+ see also `transfer.hiderefs`.
+
url.<base>.insteadOf::
Any URL that starts with this value will be rewritten to
start, instead, with <base>. In cases where some site serves a
diff --git a/upload-pack.c b/upload-pack.c
index 6b10843..37977e2 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -26,6 +26,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
#define SHALLOW (1u << 16)
#define NOT_SHALLOW (1u << 17)
#define CLIENT_SHALLOW (1u << 18)
+#define HIDDEN_REF (1u << 19)
static unsigned long oldest_have;
@@ -33,6 +34,7 @@ static int multi_ack;
static int no_done;
static int use_thin_pack, use_ofs_delta, use_include_tag;
static int no_progress, daemon_mode;
+static int allow_tip_sha1_in_want;
static int shallow_nr;
static struct object_array have_obj;
static struct object_array want_obj;
@@ -487,6 +489,12 @@ static int get_common_commits(void)
}
}
+static int is_our_ref(struct object *o)
+{
+ return o->flags &
+ ((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
+}
+
static void check_non_tip(void)
{
static const char *argv[] = {
@@ -523,7 +531,7 @@ static void check_non_tip(void)
o = get_indexed_object(--i);
if (!o)
continue;
- if (!(o->flags & OUR_REF))
+ if (!is_our_ref(o))
continue;
memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
if (write_in_full(cmd.in, namebuf, 42) < 0)
@@ -532,7 +540,7 @@ static void check_non_tip(void)
namebuf[40] = '\n';
for (i = 0; i < want_obj.nr; i++) {
o = want_obj.objects[i].item;
- if (o->flags & OUR_REF)
+ if (is_our_ref(o))
continue;
memcpy(namebuf, sha1_to_hex(o->sha1), 40);
if (write_in_full(cmd.in, namebuf, 41) < 0)
@@ -566,7 +574,7 @@ error:
/* Pick one of them (we know there at least is one) */
for (i = 0; i < want_obj.nr; i++) {
o = want_obj.objects[i].item;
- if (!(o->flags & OUR_REF))
+ if (!is_our_ref(o))
die("git upload-pack: not our ref %s",
sha1_to_hex(o->sha1));
}
@@ -646,7 +654,7 @@ static void receive_needs(void)
sha1_to_hex(sha1_buf));
if (!(o->flags & WANTED)) {
o->flags |= WANTED;
- if (!(o->flags & OUR_REF))
+ if (!is_our_ref(o))
has_non_tip = 1;
add_object_array(o, NULL, &want_obj);
}
@@ -725,8 +733,10 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag
{
struct object *o = lookup_unknown_object(sha1);
- if (ref_is_hidden(refname))
+ if (ref_is_hidden(refname)) {
+ o->flags |= HIDDEN_REF;
return 1;
+ }
if (!o)
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
o->flags |= OUR_REF;
@@ -745,9 +755,10 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
return 0;
if (capabilities)
- packet_write(1, "%s %s%c%s%s agent=%s\n",
+ packet_write(1, "%s %s%c%s%s%s agent=%s\n",
sha1_to_hex(sha1), refname_nons,
0, capabilities,
+ allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
stateless_rpc ? " no-done" : "",
git_user_agent_sanitized());
else
@@ -781,6 +792,8 @@ static void upload_pack(void)
static int upload_pack_config(const char *var, const char *value, void *unused)
{
+ if (!strcmp("uploadpack.allowtipsha1inwant", var))
+ allow_tip_sha1_in_want = git_config_bool(var, value);
return parse_hide_refs_config(var, value, unused);
}
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* [PATCH v3 5/8] fetch: use struct ref to represent refs to be fetched
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
Even though "git fetch" has full infrastructure to parse refspecs to
be fetched and match them against the list of refs to come up with
the final list of refs to be fetched, the list of refs that are
requested to be fetched were internally converted to a plain list of
strings at the transport layer and then passed to the underlying
fetch-pack driver.
Stop this conversion and instead pass around an array of refs.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/fetch-pack.c | 40 ++++++++++++++++++++------
cache.h | 3 +-
fetch-pack.c | 79 +++++++++++++++++++++++++++++++---------------------
fetch-pack.h | 11 ++++----
transport.c | 9 ++----
5 files changed, 89 insertions(+), 53 deletions(-)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 940ae35..cc6bf8f 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -7,12 +7,31 @@ static const char fetch_pack_usage[] =
"[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] "
"[--no-progress] [-v] [<host>:]<directory> [<refs>...]";
+static void add_sought_entry_mem(struct ref ***sought, int *nr, int *alloc,
+ const char *name, int namelen)
+{
+ struct ref *ref = xcalloc(1, sizeof(*ref) + namelen + 1);
+
+ memcpy(ref->name, name, namelen);
+ ref->name[namelen] = '\0';
+ (*nr)++;
+ ALLOC_GROW(*sought, *nr, *alloc);
+ (*sought)[*nr - 1] = ref;
+}
+
+static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,
+ const char *string)
+{
+ add_sought_entry_mem(sought, nr, alloc, string, strlen(string));
+}
+
int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
{
int i, ret;
struct ref *ref = NULL;
const char *dest = NULL;
- struct string_list sought = STRING_LIST_INIT_DUP;
+ struct ref **sought;
+ int nr_sought = 0, alloc_sought = 0;
int fd[2];
char *pack_lockfile = NULL;
char **pack_lockfile_ptr = NULL;
@@ -94,7 +113,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
* refs from the standard input:
*/
for (; i < argc; i++)
- string_list_append(&sought, xstrdup(argv[i]));
+ add_sought_entry(&sought, &nr_sought, &alloc_sought, argv[i]);
if (args.stdin_refs) {
if (args.stateless_rpc) {
/* in stateless RPC mode we use pkt-line to read
@@ -107,14 +126,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
break;
if (line[n-1] == '\n')
n--;
- string_list_append(&sought, xmemdupz(line, n));
+ add_sought_entry_mem(&sought, &nr_sought, &alloc_sought, line, n);
}
}
else {
/* read from stdin one ref per line, until EOF */
struct strbuf line = STRBUF_INIT;
while (strbuf_getline(&line, stdin, '\n') != EOF)
- string_list_append(&sought, strbuf_detach(&line, NULL));
+ add_sought_entry(&sought, &nr_sought, &alloc_sought, line.buf);
strbuf_release(&line);
}
}
@@ -131,7 +150,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
get_remote_heads(fd[0], &ref, 0, NULL);
ref = fetch_pack(&args, fd, conn, ref, dest,
- &sought, pack_lockfile_ptr);
+ sought, nr_sought, pack_lockfile_ptr);
if (pack_lockfile) {
printf("lock %s\n", pack_lockfile);
fflush(stdout);
@@ -141,7 +160,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
if (finish_connect(conn))
return 1;
- ret = !ref || sought.nr;
+ ret = !ref;
/*
* If the heads to pull were given, we should have consumed
@@ -149,8 +168,13 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
* remote no-such-ref' would silently succeed without issuing
* an error.
*/
- for (i = 0; i < sought.nr; i++)
- error("no such remote ref %s", sought.items[i].string);
+ for (i = 0; i < nr_sought; i++) {
+ if (!sought[i] || sought[i]->matched)
+ continue;
+ error("no such remote ref %s", sought[i]->name);
+ ret = 1;
+ }
+
while (ref) {
printf("%s %s\n",
sha1_to_hex(ref->old_sha1), ref->name);
diff --git a/cache.h b/cache.h
index c257953..03b3285 100644
--- a/cache.h
+++ b/cache.h
@@ -1013,7 +1013,8 @@ struct ref {
nonfastforward:1,
not_forwardable:1,
update:1,
- deletion:1;
+ deletion:1,
+ matched:1;
enum {
REF_STATUS_NONE = 0,
REF_STATUS_OK,
diff --git a/fetch-pack.c b/fetch-pack.c
index f0acdf7..915c0b7 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -520,47 +520,37 @@ static void mark_recent_complete_commits(struct fetch_pack_args *args,
}
}
-static int non_matching_ref(struct string_list_item *item, void *unused)
-{
- if (item->util) {
- item->util = NULL;
- return 0;
- }
- else
- return 1;
-}
-
static void filter_refs(struct fetch_pack_args *args,
- struct ref **refs, struct string_list *sought)
+ struct ref **refs,
+ struct ref **sought, int nr_sought)
{
struct ref *newlist = NULL;
struct ref **newtail = &newlist;
struct ref *ref, *next;
- int sought_pos;
+ int i;
- sought_pos = 0;
+ i = 0;
for (ref = *refs; ref; ref = next) {
int keep = 0;
next = ref->next;
+
if (!memcmp(ref->name, "refs/", 5) &&
check_refname_format(ref->name + 5, 0))
; /* trash */
else {
- while (sought_pos < sought->nr) {
- int cmp = strcmp(ref->name, sought->items[sought_pos].string);
+ while (i < nr_sought) {
+ int cmp = strcmp(ref->name, sought[i]->name);
if (cmp < 0)
break; /* definitely do not have it */
else if (cmp == 0) {
keep = 1; /* definitely have it */
- sought->items[sought_pos++].util = "matched";
- break;
+ sought[i]->matched = 1;
}
- else
- sought_pos++; /* might have it; keep looking */
+ i++;
}
}
- if (! keep && args->fetch_all &&
+ if (!keep && args->fetch_all &&
(!args->depth || prefixcmp(ref->name, "refs/tags/")))
keep = 1;
@@ -573,7 +563,6 @@ static void filter_refs(struct fetch_pack_args *args,
}
}
- filter_string_list(sought, 0, non_matching_ref, NULL);
*refs = newlist;
}
@@ -583,7 +572,8 @@ static void mark_alternate_complete(const struct ref *ref, void *unused)
}
static int everything_local(struct fetch_pack_args *args,
- struct ref **refs, struct string_list *sought)
+ struct ref **refs,
+ struct ref **sought, int nr_sought)
{
struct ref *ref;
int retval;
@@ -634,7 +624,7 @@ static int everything_local(struct fetch_pack_args *args,
}
}
- filter_refs(args, refs, sought);
+ filter_refs(args, refs, sought, nr_sought);
for (retval = 1, ref = *refs; ref ; ref = ref->next) {
const unsigned char *remote = ref->old_sha1;
@@ -764,10 +754,17 @@ static int get_pack(struct fetch_pack_args *args,
return 0;
}
+static int cmp_ref_by_name(const void *a_, const void *b_)
+{
+ const struct ref *a = *((const struct ref **)a_);
+ const struct ref *b = *((const struct ref **)b_);
+ return strcmp(a->name, b->name);
+}
+
static struct ref *do_fetch_pack(struct fetch_pack_args *args,
int fd[2],
const struct ref *orig_ref,
- struct string_list *sought,
+ struct ref **sought, int nr_sought,
char **pack_lockfile)
{
struct ref *ref = copy_ref_list(orig_ref);
@@ -776,6 +773,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
int agent_len;
sort_ref_list(&ref, ref_compare_name);
+ qsort(sought, nr_sought, sizeof(*sought), cmp_ref_by_name);
if (is_repository_shallow() && !server_supports("shallow"))
die("Server does not support shallow clients");
@@ -824,7 +822,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
agent_len, agent_feature);
}
- if (everything_local(args, &ref, sought)) {
+ if (everything_local(args, &ref, sought, nr_sought)) {
packet_flush(fd[1]);
goto all_done;
}
@@ -887,11 +885,32 @@ static void fetch_pack_setup(void)
did_setup = 1;
}
+static int remove_duplicates_in_refs(struct ref **ref, int nr)
+{
+ struct string_list names = STRING_LIST_INIT_NODUP;
+ int src, dst;
+
+ for (src = dst = 0; src < nr; src++) {
+ struct string_list_item *item;
+ item = string_list_insert(&names, ref[src]->name);
+ if (item->util)
+ continue; /* already have it */
+ item->util = ref[src];
+ if (src != dst)
+ ref[dst] = ref[src];
+ dst++;
+ }
+ for (src = dst; src < nr; src++)
+ ref[src] = NULL;
+ string_list_clear(&names, 0);
+ return dst;
+}
+
struct ref *fetch_pack(struct fetch_pack_args *args,
int fd[], struct child_process *conn,
const struct ref *ref,
const char *dest,
- struct string_list *sought,
+ struct ref **sought, int nr_sought,
char **pack_lockfile)
{
struct stat st;
@@ -903,16 +922,14 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
st.st_mtime = 0;
}
- if (sought->nr) {
- sort_string_list(sought);
- string_list_remove_duplicates(sought, 0);
- }
+ if (nr_sought)
+ nr_sought = remove_duplicates_in_refs(sought, nr_sought);
if (!ref) {
packet_flush(fd[1]);
die("no matching remote head");
}
- ref_cpy = do_fetch_pack(args, fd, ref, sought, pack_lockfile);
+ ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, pack_lockfile);
if (args->depth > 0) {
static struct lock_file lock;
diff --git a/fetch-pack.h b/fetch-pack.h
index cb14871..dc5266c 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -20,17 +20,16 @@ struct fetch_pack_args {
};
/*
- * sought contains the full names of remote references that should be
- * updated from. On return, the names that were found on the remote
- * will have been removed from the list. The util members of the
- * string_list_items are used internally; they must be NULL on entry
- * (and will be NULL on exit).
+ * sought represents remote references that should be updated from.
+ * On return, the names that were found on the remote will have been
+ * marked as such.
*/
struct ref *fetch_pack(struct fetch_pack_args *args,
int fd[], struct child_process *conn,
const struct ref *ref,
const char *dest,
- struct string_list *sought,
+ struct ref **sought,
+ int nr_sought,
char **pack_lockfile);
#endif
diff --git a/transport.c b/transport.c
index 2673d27..64ce651 100644
--- a/transport.c
+++ b/transport.c
@@ -518,11 +518,9 @@ static int fetch_refs_via_pack(struct transport *transport,
int nr_heads, struct ref **to_fetch)
{
struct git_transport_data *data = transport->data;
- struct string_list sought = STRING_LIST_INIT_DUP;
const struct ref *refs;
char *dest = xstrdup(transport->url);
struct fetch_pack_args args;
- int i;
struct ref *refs_tmp = NULL;
memset(&args, 0, sizeof(args));
@@ -536,9 +534,6 @@ static int fetch_refs_via_pack(struct transport *transport,
args.no_progress = !transport->progress;
args.depth = data->options.depth;
- for (i = 0; i < nr_heads; i++)
- string_list_append(&sought, to_fetch[i]->name);
-
if (!data->got_remote_heads) {
connect_setup(transport, 0, 0);
get_remote_heads(data->fd[0], &refs_tmp, 0, NULL);
@@ -547,7 +542,8 @@ static int fetch_refs_via_pack(struct transport *transport,
refs = fetch_pack(&args, data->fd, data->conn,
refs_tmp ? refs_tmp : transport->remote_refs,
- dest, &sought, &transport->pack_lockfile);
+ dest, to_fetch, nr_heads,
+ &transport->pack_lockfile);
close(data->fd[0]);
close(data->fd[1]);
if (finish_connect(data->conn))
@@ -557,7 +553,6 @@ static int fetch_refs_via_pack(struct transport *transport,
free_refs(refs_tmp);
- string_list_clear(&sought, 0);
free(dest);
return (refs ? 0 : -1);
}
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* [PATCH v3 4/8] parse_fetch_refspec(): clarify the codeflow a bit
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
Most parts of the cascaded if/else if/... checked an allowable
condition but some checked forbidden conditions. This makes adding
new allowable conditions unnecessarily inconvenient.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
remote.c | 29 ++++++++++++-----------------
1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/remote.c b/remote.c
index 4b1153f..1b7828d 100644
--- a/remote.c
+++ b/remote.c
@@ -538,7 +538,7 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp
/*
* Before going on, special case ":" (or "+:") as a refspec
- * for matching refs.
+ * for pushing matching refs.
*/
if (!fetch && rhs == lhs && rhs[1] == '\0') {
rs[i].matching = 1;
@@ -565,26 +565,21 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp
flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
if (fetch) {
- /*
- * LHS
- * - empty is allowed; it means HEAD.
- * - otherwise it must be a valid looking ref.
- */
+ /* LHS */
if (!*rs[i].src)
- ; /* empty is ok */
- else if (check_refname_format(rs[i].src, flags))
+ ; /* empty is ok; it means "HEAD" */
+ else if (!check_refname_format(rs[i].src, flags))
+ ; /* valid looking ref is ok */
+ else
goto invalid;
- /*
- * RHS
- * - missing is ok, and is same as empty.
- * - empty is ok; it means not to store.
- * - otherwise it must be a valid looking ref.
- */
+ /* RHS */
if (!rs[i].dst)
- ; /* ok */
+ ; /* missing is ok; it is the same as empty */
else if (!*rs[i].dst)
- ; /* ok */
- else if (check_refname_format(rs[i].dst, flags))
+ ; /* empty is ok; it means "do not store" */
+ else if (!check_refname_format(rs[i].dst, flags))
+ ; /* valid looking ref is ok */
+ else
goto invalid;
} else {
/*
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* [PATCH v3 3/8] upload/receive-pack: allow hiding ref hierarchies
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
Teach upload-pack and receive-pack to omit some refs from their
initial advertisements by paying attention to the transfer.hiderefs
multi-valued configuration variable. Any ref that is under the
hierarchies listed on the value of this variable is excluded from
responses to requests made by "ls-remote", "fetch", "clone", "push",
etc.
A typical use case may be
[transfer]
hiderefs = refs/pull
to hide the refs that are internally used by the hosting site and
should not be exposed over the network.
Because these hidden refs do not count as OUR_REF, an attempt to
fetch objects at the tip of them will be rejected, and because these
refs do not get advertised, "git push :" will not see local branches
that have the same name as them as "matching" ones to be sent.
An attempt to update/delete these hidden refs with an explicit
refspec, e.g. "git push origin :refs/pull/11/head", is rejected.
This is not a new restriction. To the pusher, it would appear that
there is no such ref, so its push request will conclude with "Now
that I sent you all the data, it is time for you to update the refs.
I saw that the ref did not exist when I started pushing, and I want
the result to point at this commit". The receiving end will apply
the compare-and-swap rule to this request and rejects the push with
"Well, your update request conflicts with somebody else; I see there
is such a ref.", which is the right thing to do. Otherwise a push to
a hidden ref will always be "the last one wins", which is not a good
default.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/config.txt | 11 +++++++++++
builtin/receive-pack.c | 24 ++++++++++++++++++++++++
refs.c | 41 +++++++++++++++++++++++++++++++++++++++++
refs.h | 3 +++
t/t5512-ls-remote.sh | 9 +++++++++
t/t5516-fetch-push.sh | 24 ++++++++++++++++++++++++
upload-pack.c | 14 +++++++++++++-
7 files changed, 125 insertions(+), 1 deletion(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index ef45c99..f57c802 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2057,6 +2057,17 @@ transfer.fsckObjects::
not set, the value of this variable is used instead.
Defaults to false.
+transfer.hiderefs::
+ String(s) `upload-pack` and `receive-pack` use to decide
+ which refs to omit from their initial advertisement. Use
+ more than one transfer.hiderefs configuration variables to
+ specify multiple prefix strings. A ref that are under the
+ hierarchies listed on the value of this variable is excluded,
+ and is hidden from `git ls-remote`, `git fetch`, `git push :`,
+ etc. An attempt to update or delete a hidden ref by `git push`
+ is rejected, and an attempt to fetch a hidden ref by `git fetch`
+ will fail.
+
transfer.unpackLimit::
When `fetch.unpackLimit` or `receive.unpackLimit` are
not set, the value of this variable is used instead.
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index ff781fe..a8248d9 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -59,6 +59,11 @@ static enum deny_action parse_deny_action(const char *var, const char *value)
static int receive_pack_config(const char *var, const char *value, void *cb)
{
+ int status = parse_hide_refs_config(var, value, cb);
+
+ if (status)
+ return status;
+
if (strcmp(var, "receive.denydeletes") == 0) {
deny_deletes = git_config_bool(var, value);
return 0;
@@ -119,6 +124,9 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
static void show_ref(const char *path, const unsigned char *sha1)
{
+ if (ref_is_hidden(path))
+ return;
+
if (sent_capabilities)
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
else
@@ -688,6 +696,20 @@ static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
return -1; /* end of list */
}
+static void reject_updates_to_hidden(struct command *commands)
+{
+ struct command *cmd;
+
+ for (cmd = commands; cmd; cmd = cmd->next) {
+ if (cmd->error_string || !ref_is_hidden(cmd->ref_name))
+ continue;
+ if (is_null_sha1(cmd->new_sha1))
+ cmd->error_string = "deny deleting a hidden ref";
+ else
+ cmd->error_string = "deny updating a hidden ref";
+ }
+}
+
static void execute_commands(struct command *commands, const char *unpacker_error)
{
struct command *cmd;
@@ -704,6 +726,8 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
0, &cmd))
set_connectivity_errors(commands);
+ reject_updates_to_hidden(commands);
+
if (run_receive_hook(commands, pre_receive_hook, 0)) {
for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->error_string)
diff --git a/refs.c b/refs.c
index 541fec2..e3574ca 100644
--- a/refs.c
+++ b/refs.c
@@ -3,6 +3,7 @@
#include "object.h"
#include "tag.h"
#include "dir.h"
+#include "string-list.h"
/*
* Make sure "ref" is something reasonable to have under ".git/refs/";
@@ -2556,3 +2557,43 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
free(short_name);
return xstrdup(refname);
}
+
+static struct string_list *hide_refs;
+
+int parse_hide_refs_config(const char *var, const char *value, void *unused)
+{
+ if (!strcmp("transfer.hiderefs", var)) {
+ char *ref;
+ int len;
+
+ if (!value)
+ return config_error_nonbool(var);
+ ref = xstrdup(value);
+ len = strlen(ref);
+ while (len && ref[len - 1] == '/')
+ ref[--len] = '\0';
+ if (!hide_refs) {
+ hide_refs = xcalloc(1, sizeof(*hide_refs));
+ hide_refs->strdup_strings = 1;
+ }
+ string_list_append(hide_refs, ref);
+ }
+ return 0;
+}
+
+int ref_is_hidden(const char *refname)
+{
+ struct string_list_item *item;
+
+ if (!hide_refs)
+ return 0;
+ for_each_string_list_item(item, hide_refs) {
+ int len;
+ if (prefixcmp(refname, item->string))
+ continue;
+ len = strlen(item->string);
+ if (!refname[len] || refname[len] == '/')
+ return 1;
+ }
+ return 0;
+}
diff --git a/refs.h b/refs.h
index d6c2fe2..50b233f 100644
--- a/refs.h
+++ b/refs.h
@@ -147,4 +147,7 @@ int update_ref(const char *action, const char *refname,
const unsigned char *sha1, const unsigned char *oldval,
int flags, enum action_on_err onerr);
+extern int parse_hide_refs_config(const char *var, const char *value, void *);
+extern int ref_is_hidden(const char *);
+
#endif /* REFS_H */
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index d16e5d3..d0702ed 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -126,4 +126,13 @@ test_expect_success 'Report match with --exit-code' '
test_cmp expect actual
'
+test_expect_success 'Hide some refs' '
+ test_config transfer.hiderefs refs/tags &&
+ git ls-remote . >actual &&
+ test_unconfig transfer.hiderefs &&
+ git ls-remote . |
+ sed -e "/ refs\/tags\//d" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 6009372..852efb6 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1037,4 +1037,28 @@ test_expect_success 'push --prune refspec' '
! check_push_result $the_first_commit tmp/foo tmp/bar
'
+test_expect_success 'push to update a hidden ref' '
+ mk_test heads/master hidden/one hidden/two hidden/three &&
+ (
+ cd testrepo &&
+ git config transfer.hiderefs refs/hidden
+ ) &&
+
+ # push to unhidden ref succeeds normally
+ git push testrepo master:refs/heads/master &&
+ check_push_result $the_commit heads/master &&
+
+ # push to update a hidden ref should fail
+ test_must_fail git push testrepo master:refs/hidden/one &&
+ check_push_result $the_first_commit hidden/one &&
+
+ # push to delete a hidden ref should fail
+ test_must_fail git push testrepo :refs/hidden/two &&
+ check_push_result $the_first_commit hidden/two &&
+
+ # idempotent push to update a hidden ref should fail
+ test_must_fail git push testrepo $the_first_commit:refs/hidden/three &&
+ check_push_result $the_first_commit hidden/three
+'
+
test_done
diff --git a/upload-pack.c b/upload-pack.c
index 3a26a7b..6b10843 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -12,6 +12,7 @@
#include "run-command.h"
#include "sigchain.h"
#include "version.h"
+#include "string-list.h"
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
@@ -719,9 +720,13 @@ static void receive_needs(void)
free(shallows.objects);
}
+/* return non-zero if the ref is hidden, otherwise 0 */
static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
struct object *o = lookup_unknown_object(sha1);
+
+ if (ref_is_hidden(refname))
+ return 1;
if (!o)
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
o->flags |= OUR_REF;
@@ -736,7 +741,8 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
const char *refname_nons = strip_namespace(refname);
unsigned char peeled[20];
- mark_our_ref(refname, sha1, flag, cb_data);
+ if (mark_our_ref(refname, sha1, flag, cb_data))
+ return 0;
if (capabilities)
packet_write(1, "%s %s%c%s%s agent=%s\n",
@@ -773,6 +779,11 @@ static void upload_pack(void)
}
}
+static int upload_pack_config(const char *var, const char *value, void *unused)
+{
+ return parse_hide_refs_config(var, value, unused);
+}
+
int main(int argc, char **argv)
{
char *dir;
@@ -824,6 +835,7 @@ int main(int argc, char **argv)
die("'%s' does not appear to be a git repository", dir);
if (is_repository_shallow())
die("attempt to fetch/clone from a shallow repository");
+ git_config(upload_pack_config, NULL);
if (getenv("GIT_DEBUG_SEND_PACK"))
debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
upload_pack();
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* [PATCH v3 1/8] upload-pack: share more code
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
We mark the objects pointed at our refs with "OUR_REF" flag in two
functions (mark_our_ref() and send_ref()), but we can just use the
former as a helper for the latter.
Update the way mark_our_ref() prepares in-core object to use
lookup_unknown_object() to delay reading the actual object data,
just like we did in 435c833 (upload-pack: use peel_ref for ref
advertisements, 2012-10-04).
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
upload-pack.c | 31 ++++++++++++++-----------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index 95d8313..3dd220d 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -722,15 +722,28 @@ static void receive_needs(void)
free(shallows.objects);
}
+static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+{
+ struct object *o = lookup_unknown_object(sha1);
+ if (!o)
+ die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
+ if (!(o->flags & OUR_REF)) {
+ o->flags |= OUR_REF;
+ nr_our_refs++;
+ }
+ return 0;
+}
+
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
static const char *capabilities = "multi_ack thin-pack side-band"
" side-band-64k ofs-delta shallow no-progress"
" include-tag multi_ack_detailed";
- struct object *o = lookup_unknown_object(sha1);
const char *refname_nons = strip_namespace(refname);
unsigned char peeled[20];
+ mark_our_ref(refname, sha1, flag, cb_data);
+
if (capabilities)
packet_write(1, "%s %s%c%s%s agent=%s\n",
sha1_to_hex(sha1), refname_nons,
@@ -740,27 +753,11 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
else
packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
capabilities = NULL;
- if (!(o->flags & OUR_REF)) {
- o->flags |= OUR_REF;
- nr_our_refs++;
- }
if (!peel_ref(refname, peeled))
packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons);
return 0;
}
-static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
-{
- struct object *o = parse_object(sha1);
- if (!o)
- die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
- if (!(o->flags & OUR_REF)) {
- o->flags |= OUR_REF;
- nr_our_refs++;
- }
- return 0;
-}
-
static void upload_pack(void)
{
if (advertise_refs || !stateless_rpc) {
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* [PATCH v3 0/8] Hiding refs
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
The third round.
- Multi-valued variable transfer.hiderefs lists prefixes of ref
hierarchies to be hidden from the requests coming over the
network.
- A configuration optionally allows uploadpack to accept fetch
requests for an object at the tip of a hidden ref.
Elsewhere, we discussed "delaying ref advertisement" (aka "expand
refs"), but it is an orthogonal feature and this "hiding refs
completely from advertisement" series does not attempt to address.
Patch #2 (simplify request validation), #4 (clarify the codeflow),
and #5 (use struct ref) are new. The are all long overdue clean-ups
for these codepaths.
The last patch is an illustration why it wouldn't make sense to
optionally allow pushing into hidden refs, and not meant to be part
of the series proper.
For those who missed it, earlier rounds are at:
http://thread.gmane.org/gmane.comp.version-control.git/213951
http://thread.gmane.org/gmane.comp.version-control.git/214888
Junio C Hamano (8):
upload-pack: share more code
upload-pack: simplify request validation
upload/receive-pack: allow hiding ref hierarchies
parse_fetch_refspec(): clarify the codeflow a bit
fetch: use struct ref to represent refs to be fetched
upload-pack: optionally allow fetching from the tips of hidden refs
fetch: fetch objects by their exact SHA-1 object names
WIP: receive.allowupdatestohidden
Documentation/config.txt | 23 +++++++++++
builtin/fetch-pack.c | 40 +++++++++++++++----
builtin/receive-pack.c | 31 +++++++++++++++
cache.h | 3 +-
fetch-pack.c | 101 ++++++++++++++++++++++++++++++++---------------
fetch-pack.h | 11 +++---
refs.c | 41 +++++++++++++++++++
refs.h | 3 ++
remote.c | 41 ++++++++++---------
remote.h | 1 +
t/t5512-ls-remote.sh | 9 +++++
t/t5516-fetch-push.sh | 82 ++++++++++++++++++++++++++++++++++++++
transport.c | 9 +----
upload-pack.c | 86 ++++++++++++++++++++++++----------------
14 files changed, 374 insertions(+), 107 deletions(-)
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply
* [PATCH v3 2/8] upload-pack: simplify request validation
From: Junio C Hamano @ 2013-01-30 18:45 UTC (permalink / raw)
To: git; +Cc: Jeff King, Shawn Pearce
In-Reply-To: <1359571542-19852-1-git-send-email-gitster@pobox.com>
Long time ago, we used to punt on a large (read: asking for more
than 256 refs) fetch request and instead sent a full pack, because
we couldn't fit many refs on the command line of rev-list we run
internally to enumerate the objects to be sent. To fix this,
565ebbf (upload-pack: tighten request validation., 2005-10-24),
added a check to count the number of refs in the request and matched
with the number of refs we advertised, and changed the invocation of
rev-list to pass "--all" to it, still keeping us under the command
line argument limit.
However, these days we feed the list of objects requested and the
list of objects the other end is known to have via standard input,
so there is no longer a valid reason to special case a full clone
request. Remove the code associated with "create_full_pack" to
simplify the logic.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
upload-pack.c | 28 +++++++++++-----------------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index 3dd220d..3a26a7b 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -28,7 +28,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
static unsigned long oldest_have;
-static int multi_ack, nr_our_refs;
+static int multi_ack;
static int no_done;
static int use_thin_pack, use_ofs_delta, use_include_tag;
static int no_progress, daemon_mode;
@@ -139,7 +139,6 @@ static void create_pack_file(void)
{
struct async rev_list;
struct child_process pack_objects;
- int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr);
char data[8193], progress[128];
char abort_msg[] = "aborting due to possible repository "
"corruption on the remote side.";
@@ -151,9 +150,7 @@ static void create_pack_file(void)
argv[arg++] = "pack-objects";
if (!shallow_nr) {
argv[arg++] = "--revs";
- if (create_full_pack)
- argv[arg++] = "--all";
- else if (use_thin_pack)
+ if (use_thin_pack)
argv[arg++] = "--thin";
}
@@ -185,15 +182,15 @@ static void create_pack_file(void)
}
else {
FILE *pipe_fd = xfdopen(pack_objects.in, "w");
- if (!create_full_pack) {
- int i;
- for (i = 0; i < want_obj.nr; i++)
- fprintf(pipe_fd, "%s\n", sha1_to_hex(want_obj.objects[i].item->sha1));
- fprintf(pipe_fd, "--not\n");
- for (i = 0; i < have_obj.nr; i++)
- fprintf(pipe_fd, "%s\n", sha1_to_hex(have_obj.objects[i].item->sha1));
- }
+ int i;
+ for (i = 0; i < want_obj.nr; i++)
+ fprintf(pipe_fd, "%s\n",
+ sha1_to_hex(want_obj.objects[i].item->sha1));
+ fprintf(pipe_fd, "--not\n");
+ for (i = 0; i < have_obj.nr; i++)
+ fprintf(pipe_fd, "%s\n",
+ sha1_to_hex(have_obj.objects[i].item->sha1));
fprintf(pipe_fd, "\n");
fflush(pipe_fd);
fclose(pipe_fd);
@@ -727,10 +724,7 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag
struct object *o = lookup_unknown_object(sha1);
if (!o)
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
- if (!(o->flags & OUR_REF)) {
- o->flags |= OUR_REF;
- nr_our_refs++;
- }
+ o->flags |= OUR_REF;
return 0;
}
--
1.8.1.2.589.ga9b91ac
^ permalink raw reply related
* "sha1 information is lacking or useless" when rebasing with a submodule pointer conflict
From: Michael Sims @ 2013-01-30 18:43 UTC (permalink / raw)
To: git
I'm seeing what might be a bug that was introduced in git 1.7.12 (also
observed in 1.8.1.2). If not a bug, it's a changed behavior from
previous versions that I don't understand.
Here's the scenario:
* I have a remote repo containing a pointer to a submodule.
* Developer A and Developer B clone this repo, and both make a commit
to first the submodule, and then the parent repo, changing some files
and also the submodule pointer at the same time.
* Developer A pushes his changes to both the submodule and the parent
module to the shared remote
* Developer B either does a "git pull --rebase" or a "git fetch && git
rebase origin/master"
Results:
When applying Developer B's changes on top of origin/master, the
following messages are observed:
"fatal: sha1 information is lacking or useless (sub).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge."
Furthermore, an immediate "git status" reports "all conflicts fixed",
does not report the submodule pointer as unmerged, and the changes to
the other files in the parent module made by Developer B are not
applied.
Expected Results:
Similar to how 1.7.12.1 behaves. No mention of sha1 information or
blobs being lacking. "git status" should report the submodule pointer
and any other changed files as being unmerged. Conflicting changes
should not be lost.
I'm witnessing this behavior on OS X 10.8.2 with git versions 1.7.12,
1.7.12.1, and 1.8.1.2, installed via homebrew. I do not see this
behavior in 1.7.11.5 or any of the 8 previous versions I've tried back
to 1.7.4.1.
Workaround:
Using an interactive rebase ("git fetch && git rebase -i
origin/master") with no changes made to the commit list seems to
sidestep this behavior.
Thanks in advance for any help with this.
Reproduce script:
Execute the following, then "cd local-b; git pull --rebase"
#!/bin/sh
set -e -v
BASEDIR=`pwd`
# Make bare remote repos
mkdir remotes
pushd remotes
git init --bare super.git
git init --bare sub.git
popd
# Initialize the submodule repo
git clone --no-hardlinks remotes/sub.git sub
pushd sub
echo subfile > subfile
git add subfile
git commit -m initial-submodule
git push origin master
popd
rm -Rf sub
# Clone into local-a and initialize supermodule repo
git clone --no-hardlinks remotes/super.git local-a
pushd local-a
git submodule add $BASEDIR/remotes/sub.git sub
echo file > file
git add sub file
git commit -m initial
git push origin master
popd
# Clone into local-b
git clone --no-hardlinks remotes/super.git local-b
pushd local-b
git submodule init && git submodule update
popd
# Make a change to supermodule file and submodule pointer from local-a
and push to remote
pushd local-a
cd sub
echo subfile changed from local-a > subfile
git add subfile
git commit -m subfile-changed-from-local-a
git push
cd ..
echo file changed from local-a > file
git add sub file
git commit -m change-from-local-a
git push
popd
# Make a conflicting change to both supermodule file and submodule
pointer from local-b
pushd local-b
cd sub
echo subfile changed from local-b > subfile
git add subfile
git commit -m subfile-changed-from-local-b
cd ..
echo file changed from local-b > file
git add sub file
git commit -m change-from-local-b
popd
^ permalink raw reply
* What's cooking in git.git (Jan 2013, #11; Wed, 30)
From: Junio C Hamano @ 2013-01-30 18:33 UTC (permalink / raw)
To: git
Here are the topics that have been cooking. Commits prefixed with
'-' are only in 'pu' (proposed updates) while commits prefixed with
'+' are in 'next'.
As usual, this cycle is expected to last for 8 to 10 weeks, with a
preview -rc0 sometime in the middle of next month.
You can find the changes described here in the integration branches of the
repositories listed at
http://git-blame.blogspot.com/p/git-public-repositories.html
--------------------------------------------------
[New Topics]
* ab/gitweb-use-same-scheme (2013-01-28) 1 commit
- gitweb: refer to picon/gravatar images over the same scheme
Avoid mixed contents on a page coming via http and https when
gitweb is hosted on a https server.
Will merge to 'next'.
* jk/python-styles (2013-01-29) 1 commit
- CodingGuidelines: add Python coding guidelines
Expecting a reroll.
$gmane/215007.
* mn/send-email-authinfo (2013-01-29) 1 commit
- git-send-email: add ~/.authinfo parsing
Expecting a reroll.
$gmane/215004, $gmane/215024.
* nd/edit-branch-desc-while-detached (2013-01-30) 1 commit
(merged to 'next' on 2013-01-30 at 69307d6)
+ branch: no detached HEAD check when editing another branch's description
(this branch is used by nd/branch-error-cases.)
Attempt to "branch --edit-description" an existing branch, while
being on a detached HEAD, errored out.
Will merge to 'master'.
--------------------------------------------------
[Graduated to "master"]
* bc/fix-array-syntax-for-3.0-in-completion-bash (2013-01-18) 1 commit
(merged to 'next' on 2013-01-25 at d113c1a)
+ git-completion.bash: replace zsh notation that breaks bash 3.X
Fix use of an array notation that older versions of bash do not
understand.
* dl/am-hg-locale (2013-01-18) 1 commit
(merged to 'next' on 2013-01-25 at 3419019)
+ am: invoke perl's strftime in C locale
Datestamp recorded in "Hg" format patch was reformatted incorrectly
to an e-mail looking date using locale dependant strftime, causing
patch application to fail.
* jc/help (2013-01-18) 1 commit
(merged to 'next' on 2013-01-25 at b2b087e)
+ help: include <common-cmds.h> only in one file
A header file that has the definition of a static array was
included in two places, wasting the space.
* nd/magic-pathspec-from-root (2013-01-21) 2 commits
(merged to 'next' on 2013-01-25 at b056b57)
+ grep: avoid accepting ambiguous revision
+ Update :/abc ambiguity check
When giving arguments without "--" disambiguation, object names
that come earlier on the command line must not be interpretable as
pathspecs and pathspecs that come later on the command line must
not be interpretable as object names. Tweak the disambiguation
rule so that ":/" (no other string before or after) is always
interpreted as a pathspec, to avoid having to say "git cmd -- :/".
* rr/minimal-stat (2013-01-22) 1 commit
(merged to 'next' on 2013-01-25 at 11c4453)
+ Enable minimal stat checking
Some reimplementations of Git does not write all the stat info back
to the index due to their implementation limitations (e.g. jgit
running on Java). A configuration option can tell Git to ignore
changes to most of the stat fields and only pay attention to mtime
and size, which these implementations can reliably update. This
avoids excessive revalidation of contents.
* tb/t0050-maint (2013-01-21) 3 commits
(merged to 'next' on 2013-01-25 at 682b1e2)
+ t0050: Use TAB for indentation
+ t0050: honor CASE_INSENSITIVE_FS in add (with different case)
+ t0050: known breakage vanished in merge (case change)
Update tests that were expecting to fail due to a bug that was
fixed earlier.
--------------------------------------------------
[Stalled]
* dg/subtree-fixes (2013-01-08) 7 commits
- contrib/subtree: mkdir the manual directory if needed
- contrib/subtree: honor $(DESTDIR)
- contrib/subtree: fix synopsis and command help
- contrib/subtree: better error handling for "add"
- contrib/subtree: add --unannotate option
- contrib/subtree: use %B for split Subject/Body
- t7900: remove test number comments
contrib/subtree updates; there are a few more from T. Zheng that
were posted separately, with an overlap.
Expecting a reroll.
* mp/diff-algo-config (2013-01-16) 3 commits
- diff: Introduce --diff-algorithm command line option
- config: Introduce diff.algorithm variable
- git-completion.bash: Autocomplete --minimal and --histogram for git-diff
Add diff.algorithm configuration so that the user does not type
"diff --histogram".
Looking better; may want tests to protect it from future breakages,
but otherwise it looks ready for 'next'.
Expecting a follow-up to add tests.
* mb/gitweb-highlight-link-target (2012-12-20) 1 commit
- Highlight the link target line in Gitweb using CSS
Expecting a reroll.
$gmane/211935
* jl/submodule-deinit (2012-12-04) 1 commit
- submodule: add 'deinit' command
There was no Porcelain way to say "I no longer am interested in
this submodule", once you express your interest in a submodule with
"submodule init". "submodule deinit" is the way to do so.
Expecting a reroll.
$gmane/212884
* jk/lua-hackery (2012-10-07) 6 commits
- pretty: fix up one-off format_commit_message calls
- Minimum compilation fixup
- Makefile: make "lua" a bit more configurable
- add a "lua" pretty format
- add basic lua infrastructure
- pretty: make some commit-parsing helpers more public
Interesting exercise. When we do this for real, we probably would want
to wrap a commit to make it more like an "object" with methods like
"parents", etc.
* rc/maint-complete-git-p4 (2012-09-24) 1 commit
- Teach git-completion about git p4
Comment from Pete will need to be addressed ($gmane/206172).
* jc/maint-name-rev (2012-09-17) 7 commits
- describe --contains: use "name-rev --algorithm=weight"
- name-rev --algorithm=weight: tests and documentation
- name-rev --algorithm=weight: cache the computed weight in notes
- name-rev --algorithm=weight: trivial optimization
- name-rev: --algorithm option
- name_rev: clarify the logic to assign a new tip-name to a commit
- name-rev: lose unnecessary typedef
"git name-rev" names the given revision based on a ref that can be
reached in the smallest number of steps from the rev, but that is
not useful when the caller wants to know which tag is the oldest one
that contains the rev. This teaches a new mode to the command that
uses the oldest ref among those which contain the rev.
I am not sure if this is worth it; for one thing, even with the help
from notes-cache, it seems to make the "describe --contains" even
slower. Also the command will be unusably slow for a user who does
not have a write access (hence unable to create or update the
notes-cache).
Stalled mostly due to lack of responses.
* jc/xprm-generation (2012-09-14) 1 commit
- test-generation: compute generation numbers and clock skews
A toy to analyze how bad the clock skews are in histories of real
world projects.
Stalled mostly due to lack of responses.
* jc/add-delete-default (2012-08-13) 1 commit
- git add: notice removal of tracked paths by default
"git add dir/" updated modified files and added new files, but does
not notice removed files, which may be "Huh?" to some users. They
can of course use "git add -A dir/", but why should they?
Resurrected from graveyard, as I thought it was a worthwhile thing
to do in the longer term.
Stalled mostly due to lack of responses.
* mb/remote-default-nn-origin (2012-07-11) 6 commits
- Teach get_default_remote to respect remote.default.
- Test that plain "git fetch" uses remote.default when on a detached HEAD.
- Teach clone to set remote.default.
- Teach "git remote" about remote.default.
- Teach remote.c about the remote.default configuration setting.
- Rename remote.c's default_remote_name static variables.
When the user does not specify what remote to interact with, we
often attempt to use 'origin'. This can now be customized via a
configuration variable.
Expecting a reroll.
$gmane/210151
"The first remote becomes the default" bit is better done as a
separate step.
* nd/parse-pathspec (2013-01-11) 20 commits
. Convert more init_pathspec() to parse_pathspec()
. Convert add_files_to_cache to take struct pathspec
. Convert {read,fill}_directory to take struct pathspec
. Convert refresh_index to take struct pathspec
. Convert report_path_error to take struct pathspec
. checkout: convert read_tree_some to take struct pathspec
. Convert unmerge_cache to take struct pathspec
. Convert read_cache_preload() to take struct pathspec
. add: convert to use parse_pathspec
. archive: convert to use parse_pathspec
. ls-files: convert to use parse_pathspec
. rm: convert to use parse_pathspec
. checkout: convert to use parse_pathspec
. rerere: convert to use parse_pathspec
. status: convert to use parse_pathspec
. commit: convert to use parse_pathspec
. clean: convert to use parse_pathspec
. Export parse_pathspec() and convert some get_pathspec() calls
. Add parse_pathspec() that converts cmdline args to struct pathspec
. pathspec: save the non-wildcard length part
Uses the parsed pathspec structure in more places where we used to
use the raw "array of strings" pathspec.
Ejected from 'pu' for now; will take a look at the rerolled one
later ($gmane/213340).
--------------------------------------------------
[Cooking]
* mp/complete-paths (2013-01-11) 1 commit
(merged to 'next' on 2013-01-30 at 70e4f1a)
+ git-completion.bash: add support for path completion
The completion script used to let the default completer to suggest
pathnames, which gave too many irrelevant choices (e.g. "git add"
would not want to add an unmodified path). Teach it to use a more
git-aware logic to enumerate only relevant ones.
This is logically the right thing to do, and we would really love
to see people who have been involved in completion code to review
and comment on the implementation.
Will cook in 'next' to see if anybody screams.
* bc/git-p4-for-python-2.4 (2013-01-26) 2 commits
(merged to 'next' on 2013-01-30 at 5d81ed2)
+ git-p4.py: support Python 2.4
+ git-p4.py: support Python 2.5
With small updates to remove dependency on newer features of
Python, keep git-p4 usable with older Python.
Will merge to 'master'.
* jk/gc-auto-after-fetch (2013-01-26) 1 commit
(merged to 'next' on 2013-01-30 at 472d07b)
+ Merge branch 'jk/maint-gc-auto-after-fetch' into jk/gc-auto-after-fetch
(this branch uses jk/maint-gc-auto-after-fetch.)
This is to resolve merge conflicts early for the same topic to
recent codebase.
Will merge to 'master'.
* jk/maint-gc-auto-after-fetch (2013-01-26) 2 commits
+ fetch-pack: avoid repeatedly re-scanning pack directory
+ fetch: run gc --auto after fetching
(this branch is used by jk/gc-auto-after-fetch.)
Help "fetch only" repositories that do not trigger "gc --auto"
often enough.
Will merge to 'master' via jk/gc-auto-after-fetch and later merge to 'maint'.
* jk/read-commit-buffer-data-after-free (2013-01-26) 3 commits
(merged to 'next' on 2013-01-30 at c6d7e16)
+ logmsg_reencode: lazily load missing commit buffers
+ logmsg_reencode: never return NULL
+ commit: drop useless xstrdup of commit message
Clarify the ownership rule for commit->buffer field, which some
callers incorrectly accessed without making sure it is populated.
Will merge to 'master'.
* pw/git-p4-on-cygwin (2013-01-26) 21 commits
(merged to 'next' on 2013-01-30 at 958ae3a)
+ git p4: introduce gitConfigBool
+ git p4: avoid shell when calling git config
+ git p4: avoid shell when invoking git config --get-all
+ git p4: avoid shell when invoking git rev-list
+ git p4: avoid shell when mapping users
+ git p4: disable read-only attribute before deleting
+ git p4 test: use test_chmod for cygwin
+ git p4: cygwin p4 client does not mark read-only
+ git p4 test: avoid wildcard * in windows
+ git p4 test: use LineEnd unix in windows tests too
+ git p4 test: newline handling
+ git p4: scrub crlf for utf16 files on windows
+ git p4: remove unreachable windows \r\n conversion code
+ git p4 test: translate windows paths for cygwin
+ git p4 test: start p4d inside its db dir
+ git p4 test: use client_view in t9806
+ git p4 test: avoid loop in client_view
+ git p4 test: use client_view to build the initial client
+ git p4: generate better error message for bad depot path
+ git p4: remove unused imports
+ git p4: temp branch name should use / even on windows
Improve "git p4" on Cygwin.
Will merge to 'master'.
* ss/mergetools-tortoise (2013-01-26) 2 commits
- mergetools: allow passing pathnames with SP in them to TortoiseGitMerge
- mergetools: support TortoiseGitMerge
Update mergetools to work better with newer merge helper tortoise ships.
Will merge to 'next'.
* da/mergetool-docs (2013-01-30) 4 commits
- doc: generate a list of valid merge tools
- mergetool--lib: add functions for finding available tools
- mergetool--lib: improve the help text in guess_merge_tool()
- mergetool--lib: simplify command expressions
(this branch uses jk/mergetool.)
Build on top of the clean-up done by jk/mergetool and automatically
generate the list of mergetool and difftool backends the build
supports to be included in the documentation.
This is looking ready for 'next'.
* nd/branch-error-cases (2013-01-30) 4 commits
- branch: mark more strings for translation
- Merge branch 'nd/edit-branch-desc-while-detached' into HEAD
- branch: give a more helpful message on redundant arguments
- branch: reject -D/-d without branch name
(this branch uses nd/edit-branch-desc-while-detached.)
Fix various error messages and conditions in "git branch", e.g. we
advertised "branch -d/-D" to remove one or more branches but actually
implemented removal of zero or more branches---request to remove no
branches was not rejected.
Will merge to 'next'.
* jc/push-reject-reasons (2013-01-24) 4 commits
(merged to 'next' on 2013-01-28 at b60be93)
+ push: finishing touches to explain REJECT_ALREADY_EXISTS better
+ push: introduce REJECT_FETCH_FIRST and REJECT_NEEDS_FORCE
+ push: further simplify the logic to assign rejection reason
+ push: further clean up fields of "struct ref"
Improve error and advice messages given locally when "git push"
refuses when it cannot compute fast-forwardness by separating these
cases from the normal "not a fast-forward; merge first and push
again" case.
Will merge to 'master'.
* as/test-cleanup (2013-01-24) 1 commit
(merged to 'next' on 2013-01-28 at cc1147d)
+ t7102 (reset): don't hardcode SHA-1 in expected outputs
Will merge to 'master'.
* jc/do-not-let-random-file-interfere-with-completion-tests (2013-01-24) 1 commit
(merged to 'next' on 2013-01-28 at df27f53)
+ t9902: protect test from stray build artifacts
Scripts to test bash completion was inherently flaky as it was
affected by whatever random things the user may have on $PATH.
Will merge to 'master'.
* jk/cvsimport-does-not-work-with-cvsps3 (2013-01-24) 1 commit
(merged to 'next' on 2013-01-28 at fef4eb2)
+ git-cvsimport.txt: cvsps-2 is deprecated
Warn people that other tools are more recommendable over
cvsimport+cvsps2 combo when doing a one-shot import, and cvsimport
will not work with cvsps3.
Will merge to 'master'.
* jk/mergetool (2013-01-28) 8 commits
- mergetools: simplify how we handle "vim" and "defaults"
- mergetool--lib: don't call "exit" in setup_tool
- mergetool--lib: improve show_tool_help() output
- mergetools/vim: remove redundant diff command
- git-difftool: use git-mergetool--lib for "--tool-help"
- git-mergetool: don't hardcode 'mergetool' in show_tool_help
- git-mergetool: remove redundant assignment
- git-mergetool: move show_tool_help to mergetool--lib
(this branch is used by da/mergetool-docs.)
Cleans up mergetool/difftool combo.
This is looking ready for 'next'.
* jn/do-not-drop-username-when-reading-from-etc-mailname (2013-01-25) 1 commit
(merged to 'next' on 2013-01-28 at e0a8222)
+ ident: do not drop username when reading from /etc/mailname
We used to stuff "user@" and then append what we read from
/etc/mailname to come up with a default e-mail ident, but a bug
lost the "user@" part. This is to fix it.
Will merge to 'master'.
* mm/add-u-A-sans-pathspec (2013-01-28) 1 commit
(merged to 'next' on 2013-01-28 at fe762a6)
+ add: warn when -u or -A is used without pathspec
Forbid "git add -u" and "git add -A" without pathspec run from a
subdirectory, to train people to type "." (or ":/") to make the
choice of default does not matter.
Will merge to 'master'.
* jc/hidden-refs (2013-01-30) 8 commits
- WIP: receive.allowupdatestohidden
- fetch: fetch objects by their exact SHA-1 object names
- upload-pack: optionally allow fetching from the tips of hidden refs
- fetch: use struct ref to represent refs to be fetched
- parse_fetch_refspec(): clarify the codeflow a bit
- upload/receive-pack: allow hiding ref hierarchies
- upload-pack: simplify request validation
- upload-pack: share more code
Allow the server side to unclutter the refs/ namespace it shows to
the client. Optionally allow requests for histories leading to the
tips of hidden refs by updated clients.
* ta/doc-no-small-caps (2013-01-22) 10 commits
- fixup! Change 'git' to 'Git' whenever the whole system is referred to #4
- Change 'git' to 'Git' whenever the whole system is referred to #4
- fixup! Change 'git' to 'Git' whenever the whole system is referred to #3
- Change 'git' to 'Git' whenever the whole system is referred to #3
- fixup! Change 'git' to 'Git' whenever the whole system is referred to #2
- Change 'git' to 'Git' whenever the whole system is referred to #2
- fixup! fixup! Change 'git' to 'Git' whenever the whole system is referred to #1
- fixup! Change 'git' to 'Git' whenever the whole system is referred to #1
- Change 'git' to 'Git' whenever the whole system is referred to #1
- Documentation: avoid poor-man's small caps
Update documentation to change "GIT" which was a poor-man's small
caps to "Git" which was the intended spelling. Also change "git"
spelled in all-lowercase to "Git" when it refers to the system as
the whole or the concept it embodies, as opposed to the command the
end users would type.
Will wait for a week or so (say, til end of January) for Thomas to
collect fix-ups, squash the result into two patches and then merge
to 'next'.
* jc/remove-treesame-parent-in-simplify-merges (2013-01-17) 1 commit
(merged to 'next' on 2013-01-30 at b639b47)
+ simplify-merges: drop merge from irrelevant side branch
The --simplify-merges logic did not cull irrelevant parents from a
merge that is otherwise not interesting with respect to the paths
we are following.
This touches a fairly core part of the revision traversal
infrastructure; even though I think this change is correct, please
report immediately if you find any unintended side effect.
Will merge to 'next'.
* jk/remote-helpers-in-python-3 (2013-01-28) 9 commits
(merged to 'next' on 2013-01-28 at d898471)
+ git-remote-testpy: fix path hashing on Python 3
(merged to 'next' on 2013-01-25 at acf9419)
+ git-remote-testpy: call print as a function
+ git-remote-testpy: don't do unbuffered text I/O
+ git-remote-testpy: hash bytes explicitly
+ svn-fe: allow svnrdump_sim.py to run with Python 3
+ git_remote_helpers: use 2to3 if building with Python 3
+ git_remote_helpers: force rebuild if python version changes
+ git_remote_helpers: fix input when running under Python 3
+ git_remote_helpers: allow building with Python 3
Prepare remote-helper test written in Python to be run with Python3.
Will merge to 'master'.
* jk/config-parsing-cleanup (2013-01-23) 8 commits
(merged to 'next' on 2013-01-28 at 9bc9411)
+ reflog: use parse_config_key in config callback
+ help: use parse_config_key for man config
+ submodule: simplify memory handling in config parsing
+ submodule: use parse_config_key when parsing config
+ userdiff: drop parse_driver function
+ convert some config callbacks to parse_config_key
+ archive-tar: use parse_config_key when parsing config
+ config: add helper function for parsing key names
Configuration parsing for tar.* configuration variables were
broken. Introduce a new config-keyname parser API to make the
callers much less error prone.
Will merge to 'master'.
* jc/custom-comment-char (2013-01-16) 1 commit
(merged to 'next' on 2013-01-25 at 91d8a5d)
+ Allow custom "comment char"
An illustration to show codepaths that need to be touched to change
the hint lines in the edited text to begin with something other
than '#'.
This is half my work and half by Ralf Thielow. There may still be
leftover '#' lurking around, though. My "git grep" says C code
should be already fine, but git-rebase--interactive.sh could be
converted (it should not matter, as the file is not really a
free-form text).
Will merge to 'master'.
* nd/fetch-depth-is-broken (2013-01-11) 3 commits
(merged to 'next' on 2013-01-15 at 70a5ca7)
+ fetch: elaborate --depth action
+ upload-pack: fix off-by-one depth calculation in shallow clone
+ fetch: add --unshallow for turning shallow repo into complete one
"git fetch --depth" was broken in at least three ways. The
resulting history was deeper than specified by one commit, it was
unclear how to wipe the shallowness of the repository with the
command, and documentation was misleading.
Will merge to 'master'.
* jc/no-git-config-in-clone (2013-01-11) 1 commit
(merged to 'next' on 2013-01-15 at feeffe1)
+ clone: do not export and unexport GIT_CONFIG
We stopped paying attention to $GIT_CONFIG environment that points
at a single configuration file from any command other than "git config"
quite a while ago, but "git clone" internally set, exported, and
then unexported the variable during its operation unnecessarily.
Will merge to 'master'.
* jc/push-2.0-default-to-simple (2013-01-16) 14 commits
(merged to 'next' on 2013-01-16 at 23f5df2)
+ t5570: do not assume the "matching" push is the default
+ t5551: do not assume the "matching" push is the default
+ t5550: do not assume the "matching" push is the default
(merged to 'next' on 2013-01-09 at 74c3498)
+ doc: push.default is no longer "matching"
+ push: switch default from "matching" to "simple"
+ t9401: do not assume the "matching" push is the default
+ t9400: do not assume the "matching" push is the default
+ t7406: do not assume the "matching" push is the default
+ t5531: do not assume the "matching" push is the default
+ t5519: do not assume the "matching" push is the default
+ t5517: do not assume the "matching" push is the default
+ t5516: do not assume the "matching" push is the default
+ t5505: do not assume the "matching" push is the default
+ t5404: do not assume the "matching" push is the default
Will cook in 'next' until Git 2.0 ;-).
* bc/append-signed-off-by (2013-01-27) 11 commits
- Unify appending signoff in format-patch, commit and sequencer
- format-patch: update append_signoff prototype
- t4014: more tests about appending s-o-b lines
- sequencer.c: teach append_signoff to avoid adding a duplicate newline
- sequencer.c: teach append_signoff how to detect duplicate s-o-b
- sequencer.c: always separate "(cherry picked from" from commit body
- sequencer.c: recognize "(cherry picked from ..." as part of s-o-b footer
- t/t3511: add some tests of 'cherry-pick -s' functionality
- t/test-lib-functions.sh: allow to specify the tag name to test_commit
- commit, cherry-pick -s: remove broken support for multiline rfc2822 fields
- sequencer.c: rework search for start of footer to improve clarity
Rerolled. With help from Jonathan, I think this is getting closer.
--------------------------------------------------
[Discarded]
* jk/update-install-for-p4 (2013-01-20) 1 commit
. INSTALL: git-p4 doesn't support Python 3
Made obsolete by bc/git-p4-for-python-2.4 topic.
^ permalink raw reply
* Re: [feature request] git add completion should exclude staged content
From: Manlio Perillo @ 2013-01-30 18:24 UTC (permalink / raw)
To: Marc Khouzam
Cc: 'Junio C Hamano', 'Michael J Gruber',
'wookietreiber', 'git@vger.kernel.org'
In-Reply-To: <E59706EF8DB1D147B15BECA3322E4BDC097A7E@eusaamb103.ericsson.se>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Il 30/01/2013 15:06, Marc Khouzam ha scritto:
> [...]
>> I will try to update the patch, with your latest suggestions (avoid
>> tricky POSIX shell syntax, and CDPATH issue - if I remember
>> correctly),
>> and with an update for the t/t9902-completion.sh test (that I
>> completely
>> missed).
>
> Hi Manlio,
>
Hi.
> I'm trying to update git-completion.tcsh to work properly with
> your nice new completion feature. But I'm having trouble with
> the missing '/' at the end of directories.
>
> The new logic in git-completion.bash tells bash that 'filenames'
> completion is ongoing so bash will add a '/' after directories.
> Sadly, tcsh won't do that, so it would be simpler if
> git-completion.bash added the '/' itself. I looked at the
> git-completion.bash script changes and I noticed that for
> bash version < 4, you have to add the '/' yourself.
The compatible version is not only required for Bash; you can use it for
other shells.
Try to redefine the __git_index_file_list_filter function to use the
version that adds a slash to directory names.
> I also noticed the following comment:
>
> # XXX if we append a slash to directory names when using
> # `compopt -o filenames`, Bash will append another slash.
> # This is pretty stupid, and this the reason why we have to
> # define a compatible version for this function.
>
> So I gather you would rather add a '/' all the time to deal
> with older bash version transparently. This would be great
> for tcsh also. I'm trying to figure out
> when bash mis-behaves when you add the '/' all the time?
> When I try it (I have bash 4.1.5(1)-release) I didn't run
> into the double slash problem you mention in the comment.
>
I'm using the same version: 4.1.5(1), on Debian stable.
> I'm hoping we can straighten this out and have
> git-completion.bash add the '/' all the time.
>
> Could you explain when the problem happens?
>
Bash 4.1.5(1) always adds an additional slash for directories.
I have tested it right now: change the filter function to use the
compatible version:
__git_index_file_list_filter ()
{
# Default to Bash >= 4.x
__git_index_file_list_filter_compat
}
Then running `git add <TAB>` inside the git repository, I get this file
completion list:
$ git add <TAB>
contrib//
> Thanks
>
Thanks to you
Manlio
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAlEJZUMACgkQscQJ24LbaUQUGACgkMG/bZrJKBzlZ8toEQwmggQX
m9kAn2ATJbSp87kOkoCCc00eHmh71r3y
=D9iu
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: [PATCH v3 00/11] unify appending of sob
From: Junio C Hamano @ 2013-01-30 17:37 UTC (permalink / raw)
To: Brandon Casey, Jonathan Nieder; +Cc: git, pclouds
In-Reply-To: <7v7gmxzwkj.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
>> Brandon Casey wrote:
>>
>>> Round 3.
>>
>> Thanks for a pleasant read. My only remaining observations are
>> cosmetic, except for a portability question in Duy's test script, a
>> small behavior change when the commit message ends with an
>> RFC2822-style header with no trailing newline and the possibility of
>> tightening the pattern in sequencer.c to match the strictness of
>> format-patch (which could easily wait for a later patch).
>
> Thanks for a quick review. I agree that this series is getting very
> close with your help.
Unless Brandon and/or Jonathan wants to have another chance to
excise warts from the recorded history by rerolling the entire
series one more time, I think what we have queued is in a good
enough shape to merge to 'next' and any further improvement and fix
can be done incrementally.
OK? Or "stop, I want to reroll"?
I'll wait for a day or two.
^ permalink raw reply
* [PATCH 7/7] perl/Git.pm: rename 'ActiveState' to 'Windows'
From: Gustavo L. de M. Chaves @ 2013-01-30 17:23 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
Windows specific code was mentioning ActiveState Perl specifically,
but that code works with Strawberry Perl too.
Hence, we rename every instance of 'ActivePerl' to 'Windows' to convey
the more general idea.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index fdef024..e03b82f 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1297,11 +1297,10 @@ sub _command_common_pipe {
my $fh;
if ($^O eq 'MSWin32') {
- # ActiveState Perl
#defined $opts{STDERR} and
- # warn 'ignoring STDERR option - running w/ ActiveState';
+ # warn 'ignoring STDERR option - running on Windows;
$direction eq '-|' or
- die 'input pipe for ActiveState not implemented';
+ die 'input pipe for Windows not implemented';
# Set up repo environment
local $ENV{GIT_DIR} = $self->repo_path() if defined $self && $self->repo_path();
@@ -1315,13 +1314,13 @@ sub _command_common_pipe {
chdir $self->wc_subdir() if $self->wc_subdir();
}
- # the strange construction with *ACPIPE is just to
+ # the strange construction with *WINPIPE is just to
# explain the tie below that we want to bind to
# a handle class, not scalar. It is not known if
- # it is something specific to ActiveState Perl or
+ # it is something specific to Perl on Windows or
# just a Perl quirk.
- tie (*ACPIPE, 'Git::activestate_pipe', $cmd, @args);
- $fh = *ACPIPE;
+ tie (*WINPIPE, 'Git::windows_pipe', $cmd, @args);
+ $fh = *WINPIPE;
chdir $cwd;
} else {
@@ -1391,9 +1390,9 @@ sub DESTROY {
}
-# Pipe implementation for ActiveState Perl.
+# Pipe implementation for Perl on Windows.
-package Git::activestate_pipe;
+package Git::windows_pipe;
use strict;
sub TIEHANDLE {
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 1/7] perl/Git.pm: test portably if a path is absolute
From: Gustavo L. de M. Chaves @ 2013-01-30 17:22 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
The code was testing if a path was absolute by checking if its first
character was a '/'. This does not work on Windows.
The portable way to do it is to use File::Spec::file_name_is_absolute.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 931047c..658b602 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -185,7 +185,7 @@ sub repository {
};
if ($dir) {
- $dir =~ m#^/# or $dir = $opts{Directory} . '/' . $dir;
+ $dir = $opts{Directory} . '/' . $dir unless File::Spec->file_name_is_absolute($dir);
$opts{Repository} = abs_path($dir);
# If --git-dir went ok, this shouldn't die either.
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 3/7] perl/Git.pm: fix _cmd_close on Windows
From: Gustavo L. de M. Chaves @ 2013-01-30 17:22 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
The Git::activestate_pipe::CLOSE routine wasn't explicitly returning
anything. This means that on Windows the routine _cmd_close wasn't
checking correctly the external command's exit code.
Now we store the command's exit code on the object created by
Git::activestate_pipe::TIEHANDLE and return a sensible value on
Git::activestate_pipe::CLOSE to _cmd_close.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index e14b41a..ef3134b 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1404,7 +1404,7 @@ sub TIEHANDLE {
# Let's just hope ActiveState Perl does at least the quoting
# correctly.
my @data = qx{git @params};
- bless { i => 0, data => \@data }, $class;
+ bless { i => 0, data => \@data, exit => $? }, $class;
}
sub READLINE {
@@ -1425,6 +1425,7 @@ sub CLOSE {
my $self = shift;
delete $self->{data};
delete $self->{i};
+ return $self->{exit} == 0;
}
sub EOF {
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 6/7] perl/Git.pm: make command pipe work in slurp-mode on Windows
From: Gustavo L. de M. Chaves @ 2013-01-30 17:23 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
Git::activestate_pipe::READLINE implementation wasn't working when the
pipe was read in slurp-mode (i.e., with $/ undefined).
Now, when in slurp-mode it correctly returns the remaining lines
joined together.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 2d88b89..fdef024 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1410,8 +1410,10 @@ sub READLINE {
return unless @{$self->{data}};
if (wantarray) {
return splice @{$self->{data}};
- } else {
+ } elsif (defined $/) {
return shift @{$self->{data}};
+ } else {
+ return join('', splice @{$self->{data}});
}
}
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 4/7] perl/Git.pm: escape external command's arguments on Windows
From: Gustavo L. de M. Chaves @ 2013-01-30 17:23 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
On Windows, the external git commands are invoked using backticks by
Git::activestate_pipe::TIEHANDLE, but there was no attempt to properly
quote their arguments. This caused problems with all but the simplest
command invokations.
The arguments are now surrounded by quotes and internal quotes are
doubled. This is not a complete quoting solution but takes care of
some of the most common problems on Windows.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index ef3134b..42c3971 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1398,12 +1398,10 @@ use strict;
sub TIEHANDLE {
my ($class, @params) = @_;
- # FIXME: This is probably horrible idea and the thing will explode
- # at the moment you give it arguments that require some quoting,
- # but I have no ActiveState clue... --pasky
- # Let's just hope ActiveState Perl does at least the quoting
- # correctly.
- my @data = qx{git @params};
+ # FIXME: The quoting done below is not completely right but it
+ # should take care of the most common cases.
+ my @escaped_params = map { "\"$_\"" } map { s/"/""/g; $_ } @params;
+ my @data = qx{git @escaped_params};
bless { i => 0, data => \@data, exit => $? }, $class;
}
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 5/7] perl/Git.pm: simplify Git::activestate_pipe
From: Gustavo L. de M. Chaves @ 2013-01-30 17:23 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
Git::activestate_pipe::TIEHANDLE creates an object to keep the
external command's output as an array of lines. The object also kept
an index into the array to know up to which line had already been read
via Git::activestate_pipe::READLINE.
We don't really need that index because lines already read don't need
to be kept. So, we simply unshift lines as they're being read and use
the array's size to know when we have read all lines.
This implementation uses more idiomatic Perl, which makes it more
readable and probably a little bit faster.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 42c3971..2d88b89 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1402,33 +1402,28 @@ sub TIEHANDLE {
# should take care of the most common cases.
my @escaped_params = map { "\"$_\"" } map { s/"/""/g; $_ } @params;
my @data = qx{git @escaped_params};
- bless { i => 0, data => \@data, exit => $? }, $class;
+ bless { data => \@data, exit => $? }, $class;
}
sub READLINE {
my $self = shift;
- if ($self->{i} >= scalar @{$self->{data}}) {
- return undef;
- }
- my $i = $self->{i};
+ return unless @{$self->{data}};
if (wantarray) {
- $self->{i} = $#{$self->{'data'}} + 1;
- return splice(@{$self->{'data'}}, $i);
+ return splice @{$self->{data}};
+ } else {
+ return shift @{$self->{data}};
}
- $self->{i} = $i + 1;
- return $self->{'data'}->[ $i ];
}
sub CLOSE {
my $self = shift;
delete $self->{data};
- delete $self->{i};
return $self->{exit} == 0;
}
sub EOF {
my $self = shift;
- return ($self->{i} >= scalar @{$self->{data}});
+ return @{$self->{data}} == 0;
}
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 2/7] perl/Git.pm: set up command environment on Windows
From: Gustavo L. de M. Chaves @ 2013-01-30 17:22 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
In-Reply-To: <1359566583-19654-1-git-send-email-gnustavo@cpan.org>
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
Routine _cmd_exec invokes _setup_git_cmd_env inside the child process
before invoking an external git command to set up the environment
variables GIT_DIR and GIT_WORK_TREE and, also, to chdir to the
repository. But _cmd_exec is only used on Unix. On Windows, it's not
used and the main code path is in _command_common_pipe, which didn't
prepare the environment like _cmd_exec.
Without this environment preparation some git commands, such as "git
clone", don't work.
We can't use _setup_git_cmd_env in this case because we don't use a
forking open like _cmd_exec does and don't get a chance to make such
preparations on the child process.
So, the preparation is done on _command_common_pipe by setting up
localized environment variables and by chdir temporarily just before
invoking the external command.
Signed-off-by: Gustavo L. de M. Chaves <gnustavo@cpan.org>
---
perl/Git.pm | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/perl/Git.pm b/perl/Git.pm
index 658b602..e14b41a 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1302,6 +1302,19 @@ sub _command_common_pipe {
# warn 'ignoring STDERR option - running w/ ActiveState';
$direction eq '-|' or
die 'input pipe for ActiveState not implemented';
+
+ # Set up repo environment
+ local $ENV{GIT_DIR} = $self->repo_path() if defined $self && $self->repo_path();
+ local $ENV{GIT_WORK_TREE} = $self->wc_path() if defined $self && $self->repo_path() && $self->wc_path();
+
+ my $cwd = cwd;
+
+ if (defined $self) {
+ chdir $self->repo_path() if $self->repo_path();
+ chdir $self->wc_path() if $self->wc_path();
+ chdir $self->wc_subdir() if $self->wc_subdir();
+ }
+
# the strange construction with *ACPIPE is just to
# explain the tie below that we want to bind to
# a handle class, not scalar. It is not known if
@@ -1310,6 +1323,7 @@ sub _command_common_pipe {
tie (*ACPIPE, 'Git::activestate_pipe', $cmd, @args);
$fh = *ACPIPE;
+ chdir $cwd;
} else {
my $pid = open($fh, $direction);
if (not defined $pid) {
--
1.7.12.464.g83379df.dirty
^ permalink raw reply related
* [PATCH 0/7] perl/Git.pm: a bunch of fixes for Windows
From: Gustavo L. de M. Chaves @ 2013-01-30 17:22 UTC (permalink / raw)
To: git; +Cc: Gustavo L. de M. Chaves
From: "Gustavo L. de M. Chaves" <gnustavo@cpan.org>
I'm working on Git::Hooks, a Perl module to facilitate the
implementation of git hooks. (http://search.cpan.org/dist/Git-Hooks/)
Git::Hooks uses the Git module implemented in perl/Git.pm and
distributed with git.
While working on porting Git::Hooks to Windows I stumbled upon a few
problems in the Git module, problems specific to the Windows
environment. In the following sequence of patches I try to fix them.
For the record, I'm using Strawberry Perl on Windows.
This is my first patch submission to git. I tried to follow all the
project conventions but I may have done it wrong. If so, please, help
me learn it.
Thanks!
Gustavo L. de M. Chaves (7):
perl/Git.pm: test portably if a path is absolute
perl/Git.pm: set up command environment on Windows
perl/Git.pm: fix _cmd_close on Windows
perl/Git.pm: escape external command's arguments on Windows
perl/Git.pm: simplify Git::activestate_pipe
perl/Git.pm: make command pipe work in slurp-mode on Windows
perl/Git.pm: rename 'ActiveState' to 'Windows'
perl/Git.pm | 63 +++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 36 insertions(+), 27 deletions(-)
--
1.7.12.464.g83379df.dirty
^ permalink raw reply
* Re: Anybody know a website with up-to-date git documentation?
From: Junio C Hamano @ 2013-01-30 17:18 UTC (permalink / raw)
To: Max Horn; +Cc: Sitaram Chamarty, John Keeping, git, Scott Chacon
In-Reply-To: <6BE76AE4-254E-43DD-A3FF-88B5486029A5@quendi.de>
Max Horn <max@quendi.de> writes:
[administrivia: please wrap lines to a reasonable width]
> On 30.01.2013, at 16:59, Sitaram Chamarty wrote:
>
>> I'm curious... what's wrong with 'git checkout html' from the git repo
>> and just browsing them using a web browser?
>
> Hm, do you mean "make html", perhaps? At least I couldn't figure
> out what "git checkout html" should do, but out of curiosity gave
> it a try and got an error...
Perhaps some information from "A note from the maintainer" (posted
to this list from time to time) is lacking. Some excerpts:
You can browse the HTML manual pages at:
http://git-htmldocs.googlecode.com/git/git.html
Preformatted documentation from the tip of the "master" branch can be
found in:
git://git.kernel.org/pub/scm/git/git-{htmldocs,manpages}.git/
git://repo.or.cz/git-{htmldocs,manpages}.git/
...
Armed with that knowledge, I think Sitaram may have something like
this:
[remote "htmldocs"]
url = git://git.kernel.org/pub/scm/git/git-htmldocs.git/
fetch = +refs/heads/master:refs/heads/html
and does
git fetch htmldocs
git checkout html
You can, too, of course ;-)
^ permalink raw reply
* Re: Anybody know a website with up-to-date git documentation?
From: Max Horn @ 2013-01-30 17:05 UTC (permalink / raw)
To: Sitaram Chamarty; +Cc: John Keeping, git, Scott Chacon
In-Reply-To: <CAMK1S_i+ML+HuTRuox5rU4bsV0+xoFLWpK63WrdXuzhgyHJbrA@mail.gmail.com>
On 30.01.2013, at 16:59, Sitaram Chamarty wrote:
> I'm curious... what's wrong with 'git checkout html' from the git repo
> and just browsing them using a web browser?
Hm, do you mean "make html", perhaps? At least I couldn't figure out what "git checkout html" should do, but out of curiosity gave it a try and got an error...
But supposing that you meant "make html": There is nothing "wrong" with it. This is mostly a matter of convenience:
* Many people just use git and don't have the git.git repos (or any git sources) at hand. And while for many things, older versions of the reference pages may suffice, this is not always the case.
* When I want to point somebody at something specific in the git docs while, say, while discussing on IRC or a mailing list, it is very convenient to point them at a website, like this:
http://git-htmldocs.googlecode.com/git/git-fast-import.html#_code_notemodify_code
* Similarly if I am standing physically next to somebody sitting at their computer and they ask me something about git, it is nice to be able to send them to a current version of the docs online
* I can access the web version from my tablet -- and I actually do that (use my tablet as "secondary screen" showing some git refs and other docs while coding on my laptop).
* a website can be update by one person (or ideally: one script) and serve many people with the same need Seems more efficient than each of those people setting up an appropriate clone & a cron job to keep it up-to-date on each machine where they need it.
But of course, the "make html" has its own clear advantages, e.g. I can use it online, I have full control over which exact version of the docs I get, including most recent changes, etc. To me, the two complement each other.
Anyway, I'll stop spamming the list, I got my answers from John and Junio:
http://git-htmldocs.googlecode.com/git/git.html
and in addition
http://manned.org/git.1
Thanks again,
Max
^ permalink raw reply
* Re: What's cooking in git.git (Jan 2013, #10; Sun, 27)
From: Junio C Hamano @ 2013-01-30 16:47 UTC (permalink / raw)
To: Pete Wyckoff; +Cc: git
In-Reply-To: <20130130123420.GA3793@padd.com>
Pete Wyckoff <pw@padd.com> writes:
> gitster@pobox.com wrote on Sun, 27 Jan 2013 22:45 -0800:
>> * pw/git-p4-on-cygwin (2013-01-26) 21 commits
>> ...
>> Improve "git p4" on Cygwin. The cover letter said it is not yet
>> ready for full Windows support so I won't move this to 'next' until
>> told by the author (the area maintainer) otherwise.
>
> The series is ready as is to support Cygwin platforms, and
> thus useful to people who would use git on windows via cygwin.
>
> Future work will be to add support for Msysgit. That work
> will need much of the changes in this Cygwin series as well.
OK, so let's treat that as a completely separate topic that comes on
top after this series is done.
Thanks; will start merging down.
^ permalink raw reply
* Re: Anybody know a website with up-to-date git documentation?
From: Junio C Hamano @ 2013-01-30 16:46 UTC (permalink / raw)
To: Max Horn; +Cc: git, Scott Chacon
In-Reply-To: <D6EAC791-63E2-4B0E-92AA-676112039BD9@quendi.de>
Max Horn <max@quendi.de> writes:
> does anybody know a website where one can view that latest git
> documentation? Here, "latest" means "latest release" (though being
> also able to access it for "next" would of course be a nice bonus,
> likewise for older versions).
Preformatted ones for the tip of 'master' are reachable from
http://git-htmldocs.googlecode.com/git/git.html
^ permalink raw reply
* Re: Files excluded but not ignored
From: Junio C Hamano @ 2013-01-30 16:17 UTC (permalink / raw)
To: Jason Wenger; +Cc: git
In-Reply-To: <loom.20130130T161911-66@post.gmane.org>
Jason Wenger <jcwenger@gmail.com> writes:
> I prefer to not add core.* files to my ignore listings because I find it helpful
> to see them in git status -- It helps me notice and clean them up periodically.
> Not having them ignored is also good ,because it allows git clean to care of
> core.* files.
>
> The problem is that git add -A, git stash -u, etc, remain interested in the core
> files.
>
> Trying to start up discussion of whether there would be merit to a "half-
> ignored" state -- Files which are excluded from tracking, but which still
> show in git status, and which are removed by git clean.
>
> Not trying to propose yet how .git/exclude or .gitignore would be formatted
> or anything like that. Just looking for opinions on whether such a state
> would be considered by the community as a good thing and merit the added
> complexity in the code.
I see no merit for "ignored and never to be tracked, but are still
shown loudly in the untracked list" myself. Use cases for "ignored
and never to be tracked, but not expendable" class were mentioned
often in the past, though.
^ 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