* [PATCH v4 0/2] push: submodule support
From: Fredrik Gustafsson @ 2011-08-19 22:08 UTC (permalink / raw)
To: git; +Cc: iveqy, hvoigt, jens.lehmann, gitster
The first iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/176328/focus=176327
The second iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/177992
The third iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/179037/focus=179048
Fredrik Gustafsson (2):
push: Don't push a repository with unpushed submodules
push: teach --recurse-submodules the on-demand option
Documentation/git-push.txt | 9 ++
builtin/push.c | 26 +++++++
combine-diff.c | 2 +-
submodule.c | 161 ++++++++++++++++++++++++++++++++++++++++
submodule.h | 2 +
t/t5531-deep-submodule-push.sh | 111 +++++++++++++++++++++++++++
transport.c | 17 ++++
transport.h | 2 +
8 files changed, 329 insertions(+), 1 deletions(-)
--
1.7.6.551.gfb18e
^ permalink raw reply
* [PATCH v4 2/2] push: teach --recurse-submodules the on-demand option
From: Fredrik Gustafsson @ 2011-08-19 22:08 UTC (permalink / raw)
To: git; +Cc: iveqy, hvoigt, jens.lehmann, gitster
In-Reply-To: <1313791728-11328-1-git-send-email-iveqy@iveqy.com>
When using this option git will search for all submodules that
have changed in the revisions to be send. It will then try to
push the currently checked out branch of each submodule.
This helps when a user has finished working on a change which
involves submodules and just wants to push everything in one go.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
Documentation/git-push.txt | 13 ++++--
builtin/push.c | 7 +++
submodule.c | 89 ++++++++++++++++++++++++++++++++--------
submodule.h | 1 +
t/t5531-deep-submodule-push.sh | 24 +++++++++++
transport.c | 10 ++++-
transport.h | 1 +
7 files changed, 121 insertions(+), 24 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index aede488..fe60d28 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -162,11 +162,14 @@ useful if you write an alias or script around 'git push'.
is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal.
---recurse-submodules=check::
- Check whether all submodule commits used by the revisions to be
- pushed are available on a remote tracking branch. Otherwise the
- push will be aborted and the command will exit with non-zero status.
-
+--recurse-submodules=<check|on-demand>::
+ Check whether all submodule commits used by the revisions to be pushed
+ are available on a remote tracking branch. If check is used the push
+ will be aborted and the command will exit with non-zero status.
+ If on-demand is used all submodules that changed in the
+ to be pushed will be pushed. If on-demand was not able
+ to push all necessary revisions it will also be aborted and exit
+ with non-zero status.
include::urls-remotes.txt[]
diff --git a/builtin/push.c b/builtin/push.c
index 35cce53..f2ef8dd 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -224,9 +224,16 @@ static int option_parse_recurse_submodules(const struct option *opt,
const char *arg, int unset)
{
int *flags = opt->value;
+
+ if (*flags & (TRANSPORT_RECURSE_SUBMODULES_CHECK |
+ TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND))
+ die("%s can only be used once.", opt->long_name);
+
if (arg) {
if (!strcmp(arg, "check"))
*flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
+ else if (!strcmp(arg, "on-demand"))
+ *flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
else
die("bad %s argument: %s", opt->long_name, arg);
} else
diff --git a/submodule.c b/submodule.c
index 45f508c..dc95498 100644
--- a/submodule.c
+++ b/submodule.c
@@ -8,7 +8,10 @@
#include "diffcore.h"
#include "refs.h"
#include "string-list.h"
+#include "transport.h"
+typedef int (*needs_push_func_t)(const char *path, const unsigned char sha1[20],
+ void *data);
static struct string_list config_name_for_path;
static struct string_list config_fetch_recurse_submodules_for_name;
static struct string_list config_ignore_for_name;
@@ -308,21 +311,24 @@ void set_config_fetch_recurse_submodules(int value)
config_fetch_recurse_submodules = value;
}
+typedef int (*module_func_t)(const char *path, const unsigned char sha1[20], void *data);
+
static int has_remote(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
return 1;
}
-static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])
+int submodule_needs_pushing(const char *path, const unsigned char sha1[20], void *data)
{
+ int *needs_pushing = data;
+
if (add_submodule_odb(path) || !lookup_commit_reference(sha1))
- return 0;
+ return 1;
if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
struct child_process cp;
const char *argv[] = {"rev-list", NULL, "--not", "--remotes", "-n", "1" , NULL};
struct strbuf buf = STRBUF_INIT;
- int needs_pushing = 0;
argv[1] = sha1_to_hex(sha1);
memset(&cp, 0, sizeof(cp));
@@ -336,41 +342,74 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20
die("Could not run 'git rev-list %s --not --remotes -n 1' command in submodule %s",
sha1_to_hex(sha1), path);
if (strbuf_read(&buf, cp.out, 41))
- needs_pushing = 1;
+ *needs_pushing = 1;
finish_command(&cp);
close(cp.out);
strbuf_release(&buf);
- return needs_pushing;
+ return !*needs_pushing;
}
- return 0;
+ return 1;
+}
+
+int push_submodule(const char *path, const unsigned char sha1[20], void *data)
+{
+ if (add_submodule_odb(path) || !lookup_commit_reference(sha1))
+ return 1;
+
+ if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
+ struct child_process cp;
+ const char *argv[] = {"push", NULL};
+
+ memset(&cp, 0, sizeof(cp));
+ cp.argv = argv;
+ cp.env = local_repo_env;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.out = -1;
+ cp.dir = path;
+ if (run_command(&cp))
+ die("Could not run 'git push' command in submodule %s", path);
+ close(cp.out);
+ }
+
+ return 1;
}
+struct collect_submodules_data {
+ module_func_t func;
+ void *data;
+ int ret;
+};
+
static void collect_submodules_from_diff(struct diff_queue_struct *q,
struct diff_options *options,
void *data)
{
int i;
- int *needs_pushing = data;
+ struct collect_submodules_data *me = data;
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (!S_ISGITLINK(p->two->mode))
continue;
- if (submodule_needs_pushing(p->two->path, p->two->sha1)) {
- *needs_pushing = 1;
+ if (!(me->ret = me->func(p->two->path, p->two->sha1, me->data)))
break;
- }
}
}
-
-static void commit_need_pushing(struct commit *commit, struct commit_list *parent, int *needs_pushing)
+static int commit_need_pushing(struct commit *commit, struct commit_list *parent,
+ module_func_t func, void *data)
{
const unsigned char (*parents)[20];
unsigned int i, n;
struct rev_info rev;
+ struct collect_submodules_data cb;
+ cb.func = func;
+ cb.data = data;
+ cb.ret = 1;
+
n = commit_list_count(parent);
parents = xmalloc(n * sizeof(*parents));
@@ -382,21 +421,23 @@ static void commit_need_pushing(struct commit *commit, struct commit_list *paren
init_revisions(&rev, NULL);
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = collect_submodules_from_diff;
- rev.diffopt.format_callback_data = needs_pushing;
+ rev.diffopt.format_callback_data = &cb;
diff_tree_combined(commit->object.sha1, parents, n, 1, &rev);
free(parents);
+ return cb.ret;
}
-int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
+static int inspect_superproject_commits(unsigned char new_sha1[20], const char *remotes_name,
+ module_func_t func, void *data)
{
struct rev_info rev;
struct commit *commit;
const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
int argc = ARRAY_SIZE(argv) - 1;
char *sha1_copy;
- int needs_pushing = 0;
struct strbuf remotes_arg = STRBUF_INIT;
+ int do_continue = 1;
strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
init_revisions(&rev, NULL);
@@ -407,13 +448,25 @@ int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remote
if (prepare_revision_walk(&rev))
die("revision walk setup failed");
- while ((commit = get_revision(&rev)) && !needs_pushing)
- commit_need_pushing(commit, commit->parents, &needs_pushing);
+ while ((commit = get_revision(&rev)) && do_continue)
+ do_continue = commit_need_pushing(commit, commit->parents, func, data);
free(sha1_copy);
strbuf_release(&remotes_arg);
- return needs_pushing;
+ return do_continue;
+}
+
+int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
+{
+ int needs_push = 0;
+ inspect_superproject_commits(new_sha1, remotes_name, submodule_needs_pushing, &needs_push);
+ return needs_push;
+}
+
+void push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)
+{
+ inspect_superproject_commits(new_sha1, remotes_name, push_submodule, NULL);
}
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
diff --git a/submodule.h b/submodule.h
index 799c22d..a0074aa 100644
--- a/submodule.h
+++ b/submodule.h
@@ -30,5 +30,6 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked);
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
const unsigned char a[20], const unsigned char b[20]);
int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name);
+void push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);
#endif
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index 30bec4b..35820ec 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -119,4 +119,28 @@ test_expect_success 'push succeeds if submodule has no remote and is on the firs
)
'
+test_expect_success 'push unpushed submodules' '
+ (
+ cd work &&
+ git checkout master &&
+ git push --recurse-submodules=on-demand ../pub.git master
+ )
+'
+
+test_expect_success 'push unpushed submodules when not needed' '
+ (
+ cd work &&
+ (
+ cd gar/bage &&
+ >junk4 &&
+ git add junk4 &&
+ git commit -m "junk4" &&
+ git push
+ ) &&
+ git add gar/bage &&
+ git commit -m "updated submodule" &&
+ git push --recurse-submodules=on-demand ../pub.git master
+ )
+'
+
test_done
diff --git a/transport.c b/transport.c
index d2725e5..59c90c7 100644
--- a/transport.c
+++ b/transport.c
@@ -1046,7 +1046,15 @@ int transport_push(struct transport *transport,
flags & TRANSPORT_PUSH_MIRROR,
flags & TRANSPORT_PUSH_FORCE);
- if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
+ if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
+ struct ref *ref = remote_refs;
+ for (; ref; ref = ref->next)
+ if (!is_null_sha1(ref->new_sha1))
+ push_unpushed_submodules(ref->new_sha1,transport->remote->name);
+ }
+
+ if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
+ TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
struct ref *ref = remote_refs;
for (; ref; ref = ref->next)
if (!is_null_sha1(ref->new_sha1) &&
diff --git a/transport.h b/transport.h
index 059b330..9d19c78 100644
--- a/transport.h
+++ b/transport.h
@@ -102,6 +102,7 @@ struct transport {
#define TRANSPORT_PUSH_PORCELAIN 16
#define TRANSPORT_PUSH_SET_UPSTREAM 32
#define TRANSPORT_RECURSE_SUBMODULES_CHECK 64
+#define TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND 128
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
--
1.7.6.551.gfb18e
^ permalink raw reply related
* [PATCH v4 1/2] push: Don't push a repository with unpushed submodules
From: Fredrik Gustafsson @ 2011-08-19 22:08 UTC (permalink / raw)
To: git; +Cc: iveqy, hvoigt, jens.lehmann, gitster
In-Reply-To: <1313791728-11328-1-git-send-email-iveqy@iveqy.com>
When working with submodules it is easy to forget to push a
submodule to the server but pushing a super-project that
contains a commit for that submodule. The result is that the
superproject points at a submodule commit that is not available
on the server.
This adds the option --recurse-submodules=check to push. When
using this option git will check that all submodule commits that
are about to be pushed are present on a remote of the submodule.
To be able to use a combined diff, disabling a diff callback has
been removed from combined-diff.c.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
Documentation/git-push.txt | 6 ++
builtin/push.c | 19 +++++++
combine-diff.c | 2 +-
submodule.c | 108 ++++++++++++++++++++++++++++++++++++++++
submodule.h | 1 +
t/t5531-deep-submodule-push.sh | 87 ++++++++++++++++++++++++++++++++
transport.c | 9 +++
transport.h | 1 +
8 files changed, 232 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 49c6e9f..aede488 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -162,6 +162,12 @@ useful if you write an alias or script around 'git push'.
is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal.
+--recurse-submodules=check::
+ Check whether all submodule commits used by the revisions to be
+ pushed are available on a remote tracking branch. Otherwise the
+ push will be aborted and the command will exit with non-zero status.
+
+
include::urls-remotes.txt[]
OUTPUT
diff --git a/builtin/push.c b/builtin/push.c
index 9cebf9e..35cce53 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -8,6 +8,7 @@
#include "remote.h"
#include "transport.h"
#include "parse-options.h"
+#include "submodule.h"
static const char * const push_usage[] = {
"git push [<options>] [<repository> [<refspec>...]]",
@@ -219,6 +220,21 @@ static int do_push(const char *repo, int flags)
return !!errs;
}
+static int option_parse_recurse_submodules(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *flags = opt->value;
+ if (arg) {
+ if (!strcmp(arg, "check"))
+ *flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
+ else
+ die("bad %s argument: %s", opt->long_name, arg);
+ } else
+ die("option %s needs an argument (check)", opt->long_name);
+
+ return 0;
+}
+
int cmd_push(int argc, const char **argv, const char *prefix)
{
int flags = 0;
@@ -236,6 +252,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
OPT_BIT( 0, "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN),
OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
+ { OPTION_CALLBACK, 0, "recurse-submodules", &flags, "check",
+ "controls recursive pushing of submodules",
+ PARSE_OPT_OPTARG, option_parse_recurse_submodules },
OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
diff --git a/combine-diff.c b/combine-diff.c
index b11eb71..f7a8978 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1074,7 +1074,7 @@ void diff_tree_combined(const unsigned char *sha1,
* when doing combined diff.
*/
int stat_opt = (opt->output_format &
- (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
+ (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT|DIFF_FORMAT_CALLBACK));
if (i == 0 && stat_opt)
diffopts.output_format = stat_opt;
else
diff --git a/submodule.c b/submodule.c
index 1ba9646..45f508c 100644
--- a/submodule.c
+++ b/submodule.c
@@ -308,6 +308,114 @@ void set_config_fetch_recurse_submodules(int value)
config_fetch_recurse_submodules = value;
}
+static int has_remote(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+ return 1;
+}
+
+static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])
+{
+ if (add_submodule_odb(path) || !lookup_commit_reference(sha1))
+ return 0;
+
+ if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
+ struct child_process cp;
+ const char *argv[] = {"rev-list", NULL, "--not", "--remotes", "-n", "1" , NULL};
+ struct strbuf buf = STRBUF_INIT;
+ int needs_pushing = 0;
+
+ argv[1] = sha1_to_hex(sha1);
+ memset(&cp, 0, sizeof(cp));
+ cp.argv = argv;
+ cp.env = local_repo_env;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.out = -1;
+ cp.dir = path;
+ if (start_command(&cp))
+ die("Could not run 'git rev-list %s --not --remotes -n 1' command in submodule %s",
+ sha1_to_hex(sha1), path);
+ if (strbuf_read(&buf, cp.out, 41))
+ needs_pushing = 1;
+ finish_command(&cp);
+ close(cp.out);
+ strbuf_release(&buf);
+ return needs_pushing;
+ }
+
+ return 0;
+}
+
+static void collect_submodules_from_diff(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ int i;
+ int *needs_pushing = data;
+
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ if (!S_ISGITLINK(p->two->mode))
+ continue;
+ if (submodule_needs_pushing(p->two->path, p->two->sha1)) {
+ *needs_pushing = 1;
+ break;
+ }
+ }
+}
+
+
+static void commit_need_pushing(struct commit *commit, struct commit_list *parent, int *needs_pushing)
+{
+ const unsigned char (*parents)[20];
+ unsigned int i, n;
+ struct rev_info rev;
+
+ n = commit_list_count(parent);
+ parents = xmalloc(n * sizeof(*parents));
+
+ for (i = 0; i < n; i++) {
+ hashcpy((unsigned char *)(parents + i), parent->item->object.sha1);
+ parent = parent->next;
+ }
+
+ init_revisions(&rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = collect_submodules_from_diff;
+ rev.diffopt.format_callback_data = needs_pushing;
+ diff_tree_combined(commit->object.sha1, parents, n, 1, &rev);
+
+ free(parents);
+}
+
+int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
+{
+ struct rev_info rev;
+ struct commit *commit;
+ const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
+ int argc = ARRAY_SIZE(argv) - 1;
+ char *sha1_copy;
+ int needs_pushing = 0;
+ struct strbuf remotes_arg = STRBUF_INIT;
+
+ strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
+ init_revisions(&rev, NULL);
+ sha1_copy = xstrdup(sha1_to_hex(new_sha1));
+ argv[1] = sha1_copy;
+ argv[3] = remotes_arg.buf;
+ setup_revisions(argc, argv, &rev, NULL);
+ if (prepare_revision_walk(&rev))
+ die("revision walk setup failed");
+
+ while ((commit = get_revision(&rev)) && !needs_pushing)
+ commit_need_pushing(commit, commit->parents, &needs_pushing);
+
+ free(sha1_copy);
+ strbuf_release(&remotes_arg);
+
+ return needs_pushing;
+}
+
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
{
int is_present = 0;
diff --git a/submodule.h b/submodule.h
index 5350b0d..799c22d 100644
--- a/submodule.h
+++ b/submodule.h
@@ -29,5 +29,6 @@ int fetch_populated_submodules(int num_options, const char **options,
unsigned is_submodule_modified(const char *path, int ignore_untracked);
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
const unsigned char a[20], const unsigned char b[20]);
+int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name);
#endif
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index faa2e96..30bec4b 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -32,4 +32,91 @@ test_expect_success push '
)
'
+test_expect_success 'push if submodule has no remote' '
+ (
+ cd work/gar/bage &&
+ >junk2 &&
+ git add junk2 &&
+ git commit -m "Second junk"
+ ) &&
+ (
+ cd work &&
+ git add gar/bage &&
+ git commit -m "Second commit for gar/bage" &&
+ git push --recurse-submodules=check ../pub.git master
+ )
+'
+
+test_expect_success 'push fails if submodule commit not on remote' '
+ (
+ cd work/gar &&
+ git clone --bare bage ../../submodule.git &&
+ cd bage &&
+ git remote add origin ../../../submodule.git &&
+ git fetch &&
+ >junk3 &&
+ git add junk3 &&
+ git commit -m "Third junk"
+ ) &&
+ (
+ cd work &&
+ git add gar/bage &&
+ git commit -m "Third commit for gar/bage" &&
+ test_must_fail git push --recurse-submodules=check ../pub.git master
+ )
+'
+
+test_expect_success 'push succeeds after commit was pushed to remote' '
+ (
+ cd work/gar/bage &&
+ git push origin master
+ ) &&
+ (
+ cd work &&
+ git push --recurse-submodules=check ../pub.git master
+ )
+'
+
+test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
+ (
+ cd work/gar/bage &&
+ >junk4 &&
+ git add junk4 &&
+ git commit -m "Fourth junk"
+ ) &&
+ (
+ cd work &&
+ git branch branch2 &&
+ git add gar/bage &&
+ git commit -m "Fourth commit for gar/bage" &&
+ git checkout branch2 &&
+ (
+ cd gar/bage &&
+ git checkout HEAD~1
+ ) &&
+ >junk1 &&
+ git add junk1 &&
+ git commit -m "First junk" &&
+ test_must_fail git push --recurse-submodules=check ../pub.git
+ )
+'
+
+test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
+ git init --bare a
+ git clone a a1 &&
+ (
+ cd a1 &&
+ git init b
+ (
+ cd b &&
+ >junk &&
+ git add junk &&
+ git commit -m "initial"
+ ) &&
+ git add b &&
+ git commit -m "added submodule" &&
+ git push --recurse-submodule=check origin master
+ )
+'
+
test_done
diff --git a/transport.c b/transport.c
index 98c5778..d2725e5 100644
--- a/transport.c
+++ b/transport.c
@@ -10,6 +10,7 @@
#include "refs.h"
#include "branch.h"
#include "url.h"
+#include "submodule.h"
/* rsync support */
@@ -1045,6 +1046,14 @@ int transport_push(struct transport *transport,
flags & TRANSPORT_PUSH_MIRROR,
flags & TRANSPORT_PUSH_FORCE);
+ if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
+ struct ref *ref = remote_refs;
+ for (; ref; ref = ref->next)
+ if (!is_null_sha1(ref->new_sha1) &&
+ check_submodule_needs_pushing(ref->new_sha1,transport->remote->name))
+ die("There are unpushed submodules, aborting.");
+ }
+
push_ret = transport->push_refs(transport, remote_refs, flags);
err = push_had_errors(remote_refs);
ret = push_ret | err;
diff --git a/transport.h b/transport.h
index 161d724..059b330 100644
--- a/transport.h
+++ b/transport.h
@@ -101,6 +101,7 @@ struct transport {
#define TRANSPORT_PUSH_MIRROR 8
#define TRANSPORT_PUSH_PORCELAIN 16
#define TRANSPORT_PUSH_SET_UPSTREAM 32
+#define TRANSPORT_RECURSE_SUBMODULES_CHECK 64
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
--
1.7.6.551.gfb18e
^ permalink raw reply related
* Re: Unable to build git on Lion - missing config.h from Perl header files
From: Thomas Rast @ 2011-08-19 22:12 UTC (permalink / raw)
To: Sorin Sbarnea; +Cc: David Aguilar, git@vger.kernel.org
In-Reply-To: <CAGDPfJoG_ksfL5vqzGWe5jqW646CKB=Qxm9_G5d=ZHMWfixweA@mail.gmail.com>
Sorin Sbarnea wrote:
> This was a clean-new Lion install, not an upgrade. I just installed
> Xcode on alternate location /Developer41 instead of /Developer
>
> Yes, I did a `make clean` but it has no effect.
>
> The problem is that on Lion there is no config.h in the perl
> directory, only a perl.h file.
Color me puzzled, but where is it getting the config.h idea from?
$ git grep config\\.h
compat/fnmatch/fnmatch.c:# include <config.h>
compat/regex/regex.c:#include "config.h"
t/t4014-format-patch.sh:test_expect_success '--no-add-headers overrides config.headers' '
Similarly, 'git grep config perl' only turns up matches in perl code.
So what tells it to use config.h?
--
Thomas Rast
trast@{inf,student}.ethz.ch
^ permalink raw reply
* What's cooking in git.git (Aug 2011, #05; Fri, 19)
From: Junio C Hamano @ 2011-08-19 22:19 UTC (permalink / raw)
To: git
Here are the topics that have been cooking. Commits prefixed with '-' are
only in 'pu' while commits prefixed with '+' are in 'next'.
There are a few 'fixup!' commits queued in topics still in 'pu', so that
authors have a choice to just say "that fix looks good, squash it in!"
instead of going through an extra round.
--------------------------------------------------
[New Topics]
* jc/traverse-commit-list (2011-08-17) 3 commits
- revision.c: update show_object_with_name() without using malloc()
- revision.c: add show_object_with_name() helper function
- rev-list: fix finish_object() call
* rc/diff-cleanup-records (2011-08-17) 2 commits
- Merge branch 'rc/histogram-diff' into HEAD
- xdiff/xprepare: improve O(n*m) performance in xdl_cleanup_records()
* fk/make-auto-header-dependencies (2011-08-18) 1 commit
- Makefile: Use computed header dependencies if the compiler supports it
* jk/color-and-pager (2011-08-18) 10 commits
- want_color: automatically fallback to color.ui
- diff: don't load color config in plumbing
- config: refactor get_colorbool function
- color: delay auto-color decision until point of use
- git_config_colorbool: refactor stdout_is_tty handling
- diff: refactor COLOR_DIFF from a flag into an int
- setup_pager: set GIT_PAGER_IN_USE
- t7006: use test_config helpers
- test-lib: add helper functions for config
- t7006: modernize calls to unset
(this branch is used by jk/pager-with-alias.)
Looked reasonable.
Will merge to "next".
* jk/pager-with-alias (2011-08-18) 2 commits
- support pager.* for aliases
- support pager.* for external commands
(this branch uses jk/color-and-pager.)
* nd/decorate-grafts (2011-08-19) 5 commits
- log: decorate "replaced" on to replaced commits
- log: decorate grafted commits with "grafted"
- Move write_shallow_commits to fetch-pack.c
- Add for_each_commit_graft() to iterate all grafts
- decoration: do not mis-decorate refs with same prefix
Looked reasonable.
Will merge to "next".
* va/p4-branch-import (2011-08-19) 4 commits
- git-p4: Add simple test case for branch import
- git-p4: Allow branch definition with git config
- git-p4: Allow filtering Perforce branches by user
- git-p4: Correct branch base depot path detection
(this branch uses va/p4-rename-copy.)
* va/p4-rename-copy (2011-08-18) 4 commits
- git-p4: Add test case for copy detection.
- git-p4: Add test case for rename detection.
- git-p4: Add description of rename/copy detection options.
- git-p4: Allow setting rename/copy detection threshold.
(this branch is used by va/p4-branch-import.)
* da/difftool-mergtool-refactor (2011-08-19) 4 commits
- mergetools/meld: Use '--output' when available
- mergetool--lib: Refactor tools into separate files
- mergetool--lib: Make style consistent with git
- difftool--helper: Make style consistent with git
* mg/branch-set-upstream-previous (2011-08-19) 1 commit
- branch.c: use the parsed branch name
--------------------------------------------------
[Graduated to "master"]
* cb/maint-exec-error-report (2011-08-01) 2 commits
(merged to 'next' on 2011-08-05 at 2764424)
+ notice error exit from pager
+ error_routine: use parent's stderr if exec fails
* cb/maint-quiet-push (2011-08-08) 2 commits
(merged to 'next' on 2011-08-08 at 917d73b)
+ receive-pack: do not overstep command line argument array
(merged to 'next' on 2011-08-01 at 87df938)
+ propagate --quiet to send-pack/receive-pack
* db/am-skip-blank-at-the-beginning (2011-08-11) 1 commit
(merged to 'next' on 2011-08-11 at 3637843)
+ am: ignore leading whitespace before patch
* jc/maint-combined-diff-work-tree (2011-08-04) 1 commit
(merged to 'next' on 2011-08-05 at 976a4d4)
+ diff -c/--cc: do not mistake "resolved as deletion" as "use working tree"
* jc/maint-smart-http-race-upload-pack (2011-08-08) 1 commit
(merged to 'next' on 2011-08-11 at 3f24b64)
+ helping smart-http/stateless-rpc fetch race
* js/bisect-no-checkout (2011-08-09) 11 commits
(merged to 'next' on 2011-08-11 at 6c94a45)
+ bisect: add support for bisecting bare repositories
+ bisect: further style nitpicks
+ bisect: replace "; then" with "\n<tab>*then"
+ bisect: cleanup whitespace errors in git-bisect.sh.
+ bisect: add documentation for --no-checkout option.
+ bisect: add tests for the --no-checkout option.
+ bisect: introduce --no-checkout support into porcelain.
+ bisect: introduce support for --no-checkout option.
+ bisect: add tests to document expected behaviour in presence of broken trees.
+ bisect: use && to connect statements that are deferred with eval.
+ bisect: move argument parsing before state modification.
* js/ref-namespaces (2011-07-21) 5 commits
(merged to 'next' on 2011-07-25 at 5b7dcfe)
+ ref namespaces: tests
+ ref namespaces: documentation
+ ref namespaces: Support remote repositories via upload-pack and receive-pack
+ ref namespaces: infrastructure
+ Fix prefix handling in ref iteration functions
* js/sh-style (2011-08-05) 2 commits
(merged to 'next' on 2011-08-11 at 4a4c22c)
+ filter-branch.sh: de-dent usage string
+ misc-sh: fix up whitespace in some other .sh files.
* ma/am-exclude (2011-08-09) 2 commits
(merged to 'next' on 2011-08-11 at cf0ba4d)
+ am: Document new --exclude=<path> option
(merged to 'next' on 2011-08-05 at 658e57c)
+ am: pass exclude down to apply
* mh/check-attr-listing (2011-08-04) 23 commits
(merged to 'next' on 2011-08-11 at f73ad50)
+ Rename git_checkattr() to git_check_attr()
+ git-check-attr: Fix command-line handling to match docs
+ git-check-attr: Drive two tests using the same raw data
+ git-check-attr: Add an --all option to show all attributes
+ git-check-attr: Error out if no pathnames are specified
+ git-check-attr: Process command-line args more systematically
+ git-check-attr: Handle each error separately
+ git-check-attr: Extract a function error_with_usage()
+ git-check-attr: Introduce a new variable
+ git-check-attr: Extract a function output_attr()
+ Allow querying all attributes on a file
+ Remove redundant check
+ Remove redundant call to bootstrap_attr_stack()
+ Extract a function collect_all_attrs()
+ Teach prepare_attr_stack() to figure out dirlen itself
+ git-check-attr: Use git_attr_name()
+ Provide access to the name attribute of git_attr
+ git-check-attr: Add tests of command-line parsing
+ git-check-attr: Add missing "&&"
+ Disallow the empty string as an attribute name
+ Remove anachronism from comment
+ doc: Correct git_attr() calls in example code
+ doc: Add a link from gitattributes(5) to git-check-attr(1)
(this branch is used by mh/check-attr-relative.)
* mh/check-attr-relative (2011-08-04) 6 commits
(merged to 'next' on 2011-08-11 at f94550c)
+ test-path-utils: Add subcommand "prefix_path"
+ test-path-utils: Add subcommand "absolute_path"
+ git-check-attr: Normalize paths
+ git-check-attr: Demonstrate problems with relative paths
+ git-check-attr: Demonstrate problems with unnormalized paths
+ git-check-attr: test that no output is written to stderr
(this branch uses mh/check-attr-listing.)
* rc/histogram-diff (2011-08-08) 12 commits
(merged to 'next' on 2011-08-11 at 684dfd1)
+ xdiff/xhistogram: drop need for additional variable
+ xdiff/xhistogram: rely on xdl_trim_ends()
+ xdiff/xhistogram: rework handling of recursed results
+ xdiff: do away with xdl_mmfile_next()
(merged to 'next' on 2011-08-03 at f9e2328)
+ Make test number unique
(merged to 'next' on 2011-07-25 at 3351028)
+ xdiff/xprepare: use a smaller sample size for histogram diff
+ xdiff/xprepare: skip classification
+ teach --histogram to diff
+ t4033-diff-patience: factor out tests
+ xdiff/xpatience: factor out fall-back-diff function
+ xdiff/xprepare: refactor abort cleanups
+ xdiff/xprepare: use memset()
--------------------------------------------------
[Stalled]
* jc/merge-reword (2011-05-25) 2 commits
- merge: mark the final "Merge made by..." message for l10n
- merge: reword the final message
Probably the topmost commit should be dropped.
* nk/branch-v-abbrev (2011-07-01) 1 commit
- branch -v: honor core.abbrev
Perhaps needs an updated commit log message?
* jh/receive-count-limit (2011-05-23) 10 commits
- receive-pack: Allow server to refuse pushes with too many objects
- pack-objects: Estimate pack size; abort early if pack size limit is exceeded
- send-pack/receive-pack: Allow server to refuse pushing too large packs
- pack-objects: Allow --max-pack-size to be used together with --stdout
- send-pack/receive-pack: Allow server to refuse pushes with too many commits
- pack-objects: Teach new option --max-commit-count, limiting #commits in pack
- receive-pack: Prepare for addition of the new 'limit-*' family of capabilities
- Tighten rules for matching server capabilities in server_supports()
- send-pack: Attempt to retrieve remote status even if pack-objects fails
- Update technical docs to reflect side-band-64k capability in receive-pack
Would need another round to separate per-pack and per-session limits.
* jm/mergetool-pathspec (2011-06-22) 2 commits
- mergetool: Don't assume paths are unmerged
- mergetool: Add tests for filename with whitespace
I think this is a good idea, but it probably needs a re-roll.
Cf. $gmane/176254, 176255, 166256
* jk/generation-numbers (2011-07-14) 7 commits
- limit "contains" traversals based on commit generation
- check commit generation cache validity against grafts
- pretty: support %G to show the generation number of a commit
- commit: add commit_generation function
- add metadata-cache infrastructure
- decorate: allow storing values instead of pointers
- Merge branch 'jk/tag-contains-ab' (early part) into HEAD
The initial "tag --contains" de-pessimization without need for generation
numbers is already in; backburnered.
* sr/transport-helper-fix-rfc (2011-07-19) 2 commits
- t5800: point out that deleting branches does not work
- t5800: document inability to push new branch with old content
* po/cygwin-backslash (2011-08-05) 2 commits
- On Cygwin support both UNIX and DOS style path-names
- git-compat-util: add generic find_last_dir_sep that respects is_dir_sep
I think a further refactoring (no, not my suggestion) was offered?
--------------------------------------------------
[Cooking]
* di/fast-import-doc (2011-08-17) 1 commit
- doc/fast-import: document feature import-marks-if-exists
Comments from fast-import folks?
* di/fast-import-deltified-tree (2011-08-14) 2 commits
- fast-import: prevent producing bad delta
- fast-import: add a test for tree delta base corruption
Comments from fast-import folks?
* di/fast-import-ident (2011-08-11) 5 commits
- fsck: improve committer/author check
- fsck: add a few committer name tests
- fast-import: check committer name more strictly
- fast-import: don't fail on omitted committer name
- fast-import: add input format tests
Comments from fast-import folks?
* di/parse-options-split (2011-08-11) 2 commits
- Reduce parse-options.o dependencies
- parse-options: export opterr, optbug
Looked reasonable.
Will merge to "next".
* mh/attr (2011-08-14) 7 commits
- Unroll the loop over passes
- Change while loop into for loop
- Determine the start of the states outside of the pass loop
- Change parse_attr() to take a pointer to struct attr_state
- Increment num_attr in parse_attr_line(), not parse_attr()
- Document struct match_attr
- Add a file comment
All looked reasonable.
Will merge to "next".
* mh/iterate-refs (2011-08-14) 6 commits
- Retain caches of submodule refs
- Store the submodule name in struct cached_refs
- Allocate cached_refs objects dynamically
- Change the signature of read_packed_refs()
- Access reference caches only through new function get_cached_refs()
- Extract a function clear_cached_refs()
I did not see anything wrong per-se, but it was unclear what the benefit
of these changes are. I probably need to read it once again.
* jn/plug-empty-tree-leak (2011-08-16) 2 commits
- merge-recursive: take advantage of hardcoded empty tree
- revert: plug memory leak in "cherry-pick root commit" codepath
Both looked reasonable.
Will merge to "next".
* ac/describe-dirty-refresh (2011-08-11) 1 commit
- describe: Refresh the index when run with --dirty
Will merge to "next", but needs Sign-off.
* en/merge-recursive-2 (2011-08-14) 57 commits
- merge-recursive: Don't re-sort a list whose order we depend upon
- merge-recursive: Fix virtual merge base for rename/rename(1to2)/add-dest
- t6036: criss-cross + rename/rename(1to2)/add-dest + simple modify
- merge-recursive: Avoid unnecessary file rewrites
- t6022: Additional tests checking for unnecessary updates of files
- merge-recursive: Fix spurious 'refusing to lose untracked file...' messages
- t6022: Add testcase for spurious "refusing to lose untracked" messages
- t3030: fix accidental success in symlink rename
- merge-recursive: Fix working copy handling for rename/rename/add/add
- merge-recursive: add handling for rename/rename/add-dest/add-dest
- merge-recursive: Have conflict_rename_delete reuse modify/delete code
- merge-recursive: Make modify/delete handling code reusable
- merge-recursive: Consider modifications in rename/rename(2to1) conflicts
- merge-recursive: Create function for merging with branchname:file markers
- merge-recursive: Record more data needed for merging with dual renames
- merge-recursive: Defer rename/rename(2to1) handling until process_entry
- merge-recursive: Small cleanups for conflict_rename_rename_1to2
- merge-recursive: Fix rename/rename(1to2) resolution for virtual merge base
- merge-recursive: Introduce a merge_file convenience function
- merge-recursive: Fix modify/delete resolution in the recursive case
- merge-recursive: When we detect we can skip an update, actually skip it
- merge-recursive: Provide more info in conflict markers with file renames
- merge-recursive: Cleanup and consolidation of rename_conflict_info
- merge-recursive: Consolidate process_entry() and process_df_entry()
- merge-recursive: Improve handling of rename target vs. directory addition
- merge-recursive: Add comments about handling rename/add-source cases
- merge-recursive: Make dead code for rename/rename(2to1) conflicts undead
- merge-recursive: Fix deletion of untracked file in rename/delete conflicts
- merge-recursive: Split update_stages_and_entry; only update stages at end
- merge-recursive: Allow make_room_for_path() to remove D/F entries
- string-list: Add API to remove an item from an unsorted list
- merge-recursive: Split was_tracked() out of would_lose_untracked()
- merge-recursive: Save D/F conflict filenames instead of unlinking them
- merge-recursive: Fix code checking for D/F conflicts still being present
- merge-recursive: Fix sorting order and directory change assumptions
- merge-recursive: Fix recursive case with D/F conflict via add/add conflict
- merge-recursive: Avoid working directory changes during recursive case
- merge-recursive: Remember to free generated unique path names
- merge-recursive: Consolidate different update_stages functions
- merge-recursive: Mark some diff_filespec struct arguments const
- merge-recursive: Correct a comment
- merge-recursive: Make BUG message more legible by adding a newline
- t6022: Add testcase for merging a renamed file with a simple change
- t6022: New tests checking for unnecessary updates of files
- t6022: Remove unnecessary untracked files to make test cleaner
- t6036: criss-cross + rename/rename(1to2)/add-source + modify/modify
- t6036: criss-cross w/ rename/rename(1to2)/modify+rename/rename(2to1)/modify
- t6036: tests for criss-cross merges with various directory/file conflicts
- t6036: criss-cross with weird content can fool git into clean merge
- t6036: Add differently resolved modify/delete conflict in criss-cross test
- t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
- t6042: Ensure rename/rename conflicts leave index and workdir in sane state
- t6042: Add tests for content issues with modify/rename/directory conflicts
- t6042: Add a testcase where undetected rename causes silent file deletion
- t6042: Add a pair of cases where undetected renames cause issues
- t6042: Add failing testcase for rename/modify/add-source conflict
- t6042: Add a testcase where git deletes an untracked file
Rerolled.
Will merge to "next".
* fg/submodule-ff-check-before-push (2011-08-09) 1 commit
- push: Don't push a repository with unpushed submodules
* hv/submodule-update-none (2011-08-11) 2 commits
- add update 'none' flag to disable update of submodule by default
- submodule: move update configuration variable further up
Will merge to "next".
* jc/lookup-object-hash (2011-08-11) 6 commits
- object hash: replace linear probing with 4-way cuckoo hashing
- object hash: we know the table size is a power of two
- object hash: next_size() helper for readability
- pack-objects --count-only
- object.c: remove duplicated code for object hashing
- object.c: code movement for readability
* js/i18n-scripts (2011-08-08) 5 commits
- submodule: take advantage of gettextln and eval_gettextln.
- stash: take advantage of eval_gettextln
- pull: take advantage of eval_gettextln
- git-am: take advantage of gettextln and eval_gettextln.
- gettext: add gettextln, eval_gettextln to encode common idiom
Will merge to "next".
* cb/maint-ls-files-error-report (2011-08-11) 1 commit
(merged to 'next' on 2011-08-15 at 69f41cf)
+ ls-files: fix pathspec display on error
Will merge to "master".
* jn/maint-test-return (2011-08-11) 3 commits
(merged to 'next' on 2011-08-15 at 5a42301)
+ t3900: do not reference numbered arguments from the test script
+ test: cope better with use of return for errors
+ test: simplify return value of test_run_
Will merge to "master".
* rt/zlib-smaller-window (2011-08-11) 2 commits
(merged to 'next' on 2011-08-15 at e05b26b)
+ test: consolidate definition of $LF
+ Tolerate zlib deflation with window size < 32Kb
Will merge to "master".
* fg/submodule-git-file-git-dir (2011-08-16) 3 commits
- fixup! Move git-dir for submodules
- Move git-dir for submodules
- rev-parse: add option --resolve-git-dir <path>
Will merge to "next", after squashing the top one.
* jk/add-i-hunk-filter (2011-07-27) 5 commits
(merged to 'next' on 2011-08-11 at 8ff9a56)
+ add--interactive: add option to autosplit hunks
+ add--interactive: allow negatation of hunk filters
+ add--interactive: allow hunk filtering on command line
+ add--interactive: factor out regex error handling
+ add--interactive: refactor patch mode argument processing
Needs documentation updates.
* jk/http-auth-keyring (2011-08-03) 13 commits
(merged to 'next' on 2011-08-03 at b06e80e)
+ credentials: add "getpass" helper
+ credentials: add "store" helper
+ credentials: add "cache" helper
+ docs: end-user documentation for the credential subsystem
+ http: use hostname in credential description
+ allow the user to configure credential helpers
+ look for credentials in config before prompting
+ http: use credential API to get passwords
+ introduce credentials API
+ http: retry authentication failures for all http requests
+ remote-curl: don't retry auth failures with dumb protocol
+ improve httpd auth tests
+ url: decode buffers that are not NUL-terminated
Looked mostly reasonable except for the limitation that it is not clear
how to deal with a site at which a user needs to use different passwords
for different repositories.
* rr/revert-cherry-pick-continue (2011-08-08) 18 commits
- revert: Propagate errors upwards from do_pick_commit
- revert: Introduce --continue to continue the operation
- revert: Don't implicitly stomp pending sequencer operation
- revert: Remove sequencer state when no commits are pending
- reset: Make reset remove the sequencer state
- revert: Introduce --reset to remove sequencer state
- revert: Make pick_commits functionally act on a commit list
- revert: Save command-line options for continuing operation
- revert: Save data for continuing after conflict resolution
- revert: Don't create invalid replay_opts in parse_args
- revert: Separate cmdline parsing from functional code
- revert: Introduce struct to keep command-line options
- revert: Eliminate global "commit" variable
- revert: Rename no_replay to record_origin
- revert: Don't check lone argument in get_encoding
- revert: Simplify and inline add_message_to_msg
- config: Introduce functions to write non-standard file
- advice: Introduce error_resolve_conflict
Will merge to "next".
^ permalink raw reply
* Re: Unable to build git on Lion - missing config.h from Perl header files
From: Sorin Sbarnea @ 2011-08-19 22:27 UTC (permalink / raw)
To: Brandon Casey; +Cc: Thomas Rast, David Aguilar, git@vger.kernel.org
In-Reply-To: <6LbwaepC5kIygT8uWl1Wf2A7S_AD1YkTya7FLCpDK4LOS7CNxjOveFLpzZtHv0dg_JJ8l78oW6XVugLUDAHkvBFItwH2yzYH6BgRAAZkFuM@cipher.nrlssc.navy.mil>
I confirm that this workaround solved the problem. Now the question is
what should be changed so git will be installed (and build) without
problems by homebrew?
Thanks
Sorin Sbarnea
On Fri, Aug 19, 2011 at 23:19, Brandon Casey
<brandon.casey.ctr@nrlssc.navy.mil> wrote:
> On 08/19/2011 05:12 PM, Thomas Rast wrote:
>> Sorin Sbarnea wrote:
>>> This was a clean-new Lion install, not an upgrade. I just installed
>>> Xcode on alternate location /Developer41 instead of /Developer
>>>
>>> Yes, I did a `make clean` but it has no effect.
>>>
>>> The problem is that on Lion there is no config.h in the perl
>>> directory, only a perl.h file.
>>
>> Color me puzzled, but where is it getting the config.h idea from?
>>
>> $ git grep config\\.h
>> compat/fnmatch/fnmatch.c:# include <config.h>
>> compat/regex/regex.c:#include "config.h"
>> t/t4014-format-patch.sh:test_expect_success '--no-add-headers overrides config.headers' '
>>
>> Similarly, 'git grep config perl' only turns up matches in perl code.
>> So what tells it to use config.h?
>
> Probably MakeMaker.
>
> Setting NO_PERL_MAKEMAKER may help:
>
> rm perl/perl.mak
> make NO_PERL_MAKEMAKER=1
>
> -Brandon
>
^ permalink raw reply
* Re: Unable to build git on Lion - missing config.h from Perl header files
From: Brandon Casey @ 2011-08-19 22:19 UTC (permalink / raw)
To: Thomas Rast; +Cc: Sorin Sbarnea, David Aguilar, git@vger.kernel.org
In-Reply-To: <201108200012.17580.trast@student.ethz.ch>
On 08/19/2011 05:12 PM, Thomas Rast wrote:
> Sorin Sbarnea wrote:
>> This was a clean-new Lion install, not an upgrade. I just installed
>> Xcode on alternate location /Developer41 instead of /Developer
>>
>> Yes, I did a `make clean` but it has no effect.
>>
>> The problem is that on Lion there is no config.h in the perl
>> directory, only a perl.h file.
>
> Color me puzzled, but where is it getting the config.h idea from?
>
> $ git grep config\\.h
> compat/fnmatch/fnmatch.c:# include <config.h>
> compat/regex/regex.c:#include "config.h"
> t/t4014-format-patch.sh:test_expect_success '--no-add-headers overrides config.headers' '
>
> Similarly, 'git grep config perl' only turns up matches in perl code.
> So what tells it to use config.h?
Probably MakeMaker.
Setting NO_PERL_MAKEMAKER may help:
rm perl/perl.mak
make NO_PERL_MAKEMAKER=1
-Brandon
^ permalink raw reply
* Re: Unable to build git on Lion - missing config.h from Perl header files
From: Junio C Hamano @ 2011-08-19 22:42 UTC (permalink / raw)
To: Sorin Sbarnea
Cc: Brandon Casey, Thomas Rast, David Aguilar, git@vger.kernel.org
In-Reply-To: <CAGDPfJpSVknybUjUsHkb1Mb8_SqQxJB2idRTxxfsT8eRSA91CQ@mail.gmail.com>
Sorin Sbarnea <sorin.sbarnea@gmail.com> writes:
> On Fri, Aug 19, 2011 at 23:19, Brandon Casey
>> Probably MakeMaker.
>>
>> Setting NO_PERL_MAKEMAKER may help:
>>
>> rm perl/perl.mak
>> make NO_PERL_MAKEMAKER=1
>>
> I confirm that this workaround solved the problem. Now the question is
> what should be changed so git will be installed (and build) without
> problems by homebrew?
If the user's distro does not have packaged makemaker, or if the user
chooses not to install it, then the build procedure of git can be told to
avoid using it, which is what you did. So there is nothing to fix there.
If you are not going to tell git to avoid makemaker, in other words, if
you want to use makemaker, then installing it before starting the build
procedure would help, too. But that is outside the scope of git project.
Please do not top post.
^ permalink raw reply
* [PATCH] git-p4: don't convert utf16 files.
From: Chris Li @ 2011-08-19 22:50 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
Some repository has some utf16 files git-p4 don't know
how to convert. For those files, git-p4 just write the utf8
files. That is wrong, because git get different file than
perforce does, causing some windows resource file fail
to compile.
Using the "p4 print -o tmpfile depotfile" can avoid this
convertion (and possible failure) all together.
Signed-off-by: Chris Li <git@chrisli.org>
---
git-p4 | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/git-p4 b/git-p4
index 672b0c2..0c6a5cc 100755
--- a/git-p4
+++ b/git-p4
@@ -755,12 +755,11 @@ class P4FileReader:
break
if header['type'].startswith('utf16'):
- try:
- text = textBuffer.getvalue().encode('utf_16')
- except UnicodeDecodeError:
- # File checked in to Perforce has an error. Try
without encoding
- print "Corrupt UTF-16 file in Perforce: %s" %
header['depotFile']
- text = textBuffer.getvalue()
+ # Don't even try to convert utf16. Ask p4 to write
the file directly.
+ tmpFile = tempfile.NamedTemporaryFile()
+ P4Helper().p4_system("print -o %s %s"%(tmpFile.name,
header['depotFile']))
+ text = open(tmpFile.name).read()
+ tmpFile.close()
else:
text = textBuffer.getvalue()
textBuffer.close()
--
1.7.6
^ permalink raw reply related
* Re: Unable to build git on Lion - missing config.h from Perl header files
From: Brandon Casey @ 2011-08-19 22:57 UTC (permalink / raw)
To: Junio C Hamano
Cc: Sorin Sbarnea, Thomas Rast, David Aguilar, git@vger.kernel.org
In-Reply-To: <7vk4a910rd.fsf@alter.siamese.dyndns.org>
On 08/19/2011 05:42 PM, Junio C Hamano wrote:
> Sorin Sbarnea <sorin.sbarnea@gmail.com> writes:
>
>> On Fri, Aug 19, 2011 at 23:19, Brandon Casey
>>> Probably MakeMaker.
>>>
>>> Setting NO_PERL_MAKEMAKER may help:
>>>
>>> rm perl/perl.mak
>>> make NO_PERL_MAKEMAKER=1
>>>
>> I confirm that this workaround solved the problem. Now the question is
>> what should be changed so git will be installed (and build) without
>> problems by homebrew?
>
> If the user's distro does not have packaged makemaker, or if the user
> chooses not to install it, then the build procedure of git can be told to
> avoid using it, which is what you did. So there is nothing to fix there.
>
> If you are not going to tell git to avoid makemaker, in other words, if
> you want to use makemaker, then installing it before starting the build
> procedure would help, too. But that is outside the scope of git project.
I got the impression that his system did have makemaker, and that it
created the perl.mak file, but then building git failed because some
header files were missing from his perl installation.
Earlier he said:
>> The only files existing in
>> /System/Library/Perl/5.12/darwin-thread-multi-2level/CORE/ are
>> libperl.dylib andperl.h.
I don't have access to a mac, but on my system I have many header files
in .../x86_64-linux-thread-multi/CORE/ including config.h. These files
are part of the base perl installation rpm (i.e. not some -devel rpm).
But like you said, there is nothing to fix on the git side of things.
-Brandon
^ permalink raw reply
* Re: [PATCH v2 4/4] mergetools/meld: Use '--output' when available
From: Junio C Hamano @ 2011-08-19 22:58 UTC (permalink / raw)
To: David Aguilar
Cc: git, Jonathan Nieder, Tanguy Ortolo, Charles Bailey,
Sebastian Schuberth
In-Reply-To: <20110819091444.GB18054@gmail.com>
David Aguilar <davvid@gmail.com> writes:
> meld 1.5.0 and newer allow the output file to be specified
> when merging multiple files. Check whether the meld command
> supports '--output' and use it when available.
>
> Signed-off-by: David Aguilar <davvid@gmail.com>
> ---
> mergetools/meld | 25 ++++++++++++++++++++++++-
> 1 files changed, 24 insertions(+), 1 deletions(-)
>
> Changes since v1 with help from Jonathan Nieder:
Thanks, both of you. Queued all patches in the series.
^ permalink raw reply
* Re: [PATCH v4 2/4] merge: keep stash[] a local variable
From: Junio C Hamano @ 2011-08-19 22:59 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1313765407-29925-2-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> A stash is created by save_state() and used by restore_state(). Pass
> SHA-1 explicitly for clarity and keep stash[] to cmd_merge().
Makes tons of sense; thanks.
^ permalink raw reply
* Re: Why isn't the index a tree?
From: Jon Seymour @ 2011-08-19 23:05 UTC (permalink / raw)
To: Richard Hansen; +Cc: git
In-Reply-To: <4E4ED49C.6050405@bbn.com>
On Sat, Aug 20, 2011 at 7:24 AM, Richard Hansen <rhansen@bbn.com> wrote:
> I expected the index to be implemented something like a ref to a tree object
> (per stage) plus some stat()/assume-unchanged/etc. metadata. Instead, it
> appears to be a (sorted?) flat list of full paths with their associated
> SHA1s and metadata.
>
> Is there a reason why each stage in the index isn't implemented as a tree?
>
I think the answer is that there is meta data in the index
(particularly timestamps) needed for efficiently tracking changes to
the filesystem that isn't needed in a tree - forcing everything into a
tree early would necessitate creating SHA1 hashes for lots of trees
that will eventually not be needed.
So, the index is a data structure tuned for performance in ways that a
tree cannot be.
jon
| reposted from a MUA that doesn't insert HTML
^ permalink raw reply
* Re: [PATCH] git-send-email: Add AUTH LOGIN support
From: Junio C Hamano @ 2011-08-19 23:09 UTC (permalink / raw)
To: Joe Perches; +Cc: git, Graham Barr
In-Reply-To: <1313716585.11178.2.camel@Joe-Laptop>
Joe Perches <joe@perches.com> writes:
> On Fri, 2011-08-05 at 22:21 -0700, Joe Perches wrote:
>>
>> I needed something now.
>>
>> You are right but I believe it would take too long
>> to get updates to Net::SMTP in place. Doing this
>> admitted ugliness in git-send-email works for me and
>> seems to me to be appropriate for now.
>>
>> I looked, there isn't a method to force a particular
>> AUTH type documented. I also didn't care to rewrite
>> Net::SMTP right now. This "works for me"...
Good for you ;-)
>> > It probably is not as simple as installing Authen::SASL::*::LOGIN, but
>> > still...
>
> I think my patch should be applied until Net::SMTP is updated.
And you already have applied to your copy, no?
I understand you needed something _now_ and that is why you wrote it, but
the thing is, I don't need the ugliness nor an ability to force AUTH LOGIN
right now, so I do not necessarily agree with you that the patch _should_
be applied to my tree.
^ permalink raw reply
* Re: [PATCH] git-send-email: Add AUTH LOGIN support
From: Joe Perches @ 2011-08-19 23:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Graham Barr
In-Reply-To: <7v1uwh0zj4.fsf@alter.siamese.dyndns.org>
On Fri, 2011-08-19 at 16:09 -0700, Junio C Hamano wrote:
> Joe Perches <joe@perches.com> writes:
> > I think my patch should be applied until Net::SMTP is updated.
> And you already have applied to your copy, no?
True.
> I do not necessarily agree with you that the patch _should_
> be applied to my tree.
Your choice. It does make tracking git development
a bit of a pain for me though.
There doesn't seem to be anything like a patchwork queue
for git development to check status of patches.
I've sent a couple of other patches to git-send-email.
http://marc.info/?l=git&m=131190328311281&w=2
http://marc.info/?l=git&m=131131975804893&w=2
Any comments or plans to ack/nack those?
^ permalink raw reply
* Re: [PATCH v4 1/2] push: Don't push a repository with unpushed submodules
From: Junio C Hamano @ 2011-08-19 23:26 UTC (permalink / raw)
To: Fredrik Gustafsson; +Cc: git, hvoigt, jens.lehmann
In-Reply-To: <1313791728-11328-2-git-send-email-iveqy@iveqy.com>
Fredrik Gustafsson <iveqy@iveqy.com> writes:
> diff --git a/combine-diff.c b/combine-diff.c
> index b11eb71..f7a8978 100644
> --- a/combine-diff.c
> +++ b/combine-diff.c
> @@ -1074,7 +1074,7 @@ void diff_tree_combined(const unsigned char *sha1,
> * when doing combined diff.
> */
> int stat_opt = (opt->output_format &
> - (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
> + (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT|DIFF_FORMAT_CALLBACK));
> if (i == 0 && stat_opt)
> diffopts.output_format = stat_opt;
> else
Sorry, but this is not what I meant. With this change, you are running N
(= number of parents) diffs with the end result, but only making a
callback while running a diff with the first parent, and not getting
anything from comparison with other parents.
The existing NUMSTAT/STAT exception is only justified because that is how
"diff --stat" shows merges (i.e. showing the extent of damage to the
mainline, assuming you are viewing a merge to the mainline from a side
branch).
What I meant was more along the lines of the following, but I think we
would need a new kind of callback that can take N-way parents (which is
not depicted here).
Let me cook up something and get back to you later tonight.
combine-diff.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/combine-diff.c b/combine-diff.c
index 655fa89..51ebd31 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1017,6 +1017,12 @@ void diff_tree_combined(const unsigned char *sha1,
num_paths++;
}
if (num_paths) {
+ if (opt->output_format & DIFF_FORMAT_CALLBACK) {
+ for (p = paths; p; p = p->next) {
+ if (p->len)
+ ... make callback here ...
+ }
+ }
if (opt->output_format & (DIFF_FORMAT_RAW |
DIFF_FORMAT_NAME |
DIFF_FORMAT_NAME_STATUS)) {
^ permalink raw reply related
* Re: [PATCH] git-send-email: Add AUTH LOGIN support
From: Junio C Hamano @ 2011-08-20 1:01 UTC (permalink / raw)
To: Joe Perches; +Cc: git, Graham Barr
In-Reply-To: <1313796280.11178.25.camel@Joe-Laptop>
Joe Perches <joe@perches.com> writes:
> I've sent a couple of other patches to git-send-email.
>
> http://marc.info/?l=git&m=131190328311281&w=2
> http://marc.info/?l=git&m=131131975804893&w=2
>
> Any comments or plans to ack/nack those?
Sorry, but I am not personally interested in send-email enough to go to
marc.info archive that does not give me the message in ready-to-apply
format with "git am".
On-list discussion is the most important signal I use to convince myself
that the issues that discussed patches attempt to tackle are worth
addressing. When I do not see any discussion, I myself may decide that
they are important, or I may not.
Re-sending them might get others with similar needs for the patches
involved in the discussion.
Here are what _I_ think about the above two.
- I've seen enough complaints that send-email sends too many Cc:s to
unintended parties, and of an opinion that these extra recipients should
be added to the files you feed to send-email as headers, instead of adding
noise to commit log messages, so adding new Cc sources and then giving a
way to suppress them didn't look like a good change to me.
- I think I saw a few positive responses to the "editor cruft" patch, but
the way the patch was implemented, it will invite low-value "my obscure
editor uses this pattern, so add it" follow-up patches, and compared to
that downside, I didn't like the benefit of the patch well enough to pick
it up.
^ permalink raw reply
* [PATCH v3] fast-import: do not write bad delta for replaced subtrees
From: Jonathan Nieder @ 2011-08-20 1:09 UTC (permalink / raw)
To: Dmitry Ivankov; +Cc: git, Shawn O. Pearce, David Barr
In-Reply-To: <1313346744-30340-3-git-send-email-divanorama@gmail.com>
Dmitry Ivankov wrote:
> To produce deltas for tree objects fast-import tracks two versions
> of tree's entries - base and current one. Base version stands both
> for a delta base of this tree, and for a entry inside a delta base
> of a parent tree. So care should be taken to keep it in sync.
Thanks again for this. Abusing (S_ISDIR | S_ISUID) still leaves a bad
taste in my mouth, but after your description I'm convinced that
behavior-wise it's the right thing to do.
I'm thinking of queueing the following to svn-fe-maint. If there's
something wrong with it, I'd be happy to hear that now; otherwise,
we can put fixes on top. In other words, "please speak now or forever
hold your peace". Changes since v2:
- clarify description
- some tiny style nitpicks in the code and test
- made a pass through checking uses of "mode" to make sure we are
scrubbing out the S_ISUID bit before passing it to code that is not
aware of that bit.
The result is a few assert() calls to document those cases that
required a second's thought and some extra scrubbing in tecmp0()
when passing the mode to base_name_compare. Although the latter is
not needed and base_name_compare() only pays attention to the
S_IFDIR bit, it seems best to stick to the expected interface and
pass a real mode.
- take care of a missed case where NO_DELTA was not being set:
create branch "basis":
M 100644 inline dir/hello.c
data <<EOF
hello
EOF
C dir/hello.c unrelated
on branch "master":
from refs/heads/basis
D dir
corrupt the subtree
C unrelated dir/nothello.c
The patch has way too few tests. Oh, well.
Bugs? Improvements?
-- >8 --
Subject: fast-import: do not write bad delta for replaced subtrees
To produce deltas for tree objects, fast-import tracks two versions of
each tree entry - a base and the current version. The base version on
a tree stands both for a delta base of this tree, and for a entry
inside the delta base of the parent tree. So care needs to be taken to
keep them consistent.
Unfortunately this all gets forgotten when replacing one subtree by
another using tree_content_set. When writing an entry representing
the new subtree, it keeps the old base sha1, since it is needed by the
parent tree. But the new tree doesn't have the implied base version
entries, and when it is time to write it to pack, git writes an
invalid delta that is declared to have one base (the old tree name)
but actually has another one (the new tree for an "M" command, or the
tree's old base for an "R" or "C" command).
How to fix it? Modifying the new subtree's entries to match the
declared base would be expensive, since it requires reading the tree
corresponding to the declared base from the object db and recursively
rewriting children's base versions to match. Invalidating the parent
trees' bases would involve recursively walking up the tree and
disables deltas for each tree it touches, meaning a larger pack.
Let's just mark the new tree as do-not-delta-me instead. We abuse the
setuid bit in the base "mode" field for this purpose.
tree_content_replace is in a similar predicament to tree_content_set,
except that because it is only used to replace the root, just
invalidating the base sha1 there (instead of setting the no-delta bit)
is fine.
Initial hack by Jonathan, test and description by Dmitry.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
fast-import.c | 55 ++++++++++++++++++++++++++++++++++++++++++-----
t/t9300-fast-import.sh | 40 ++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 6 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index 65d65bf8..95919b63 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -170,6 +170,11 @@ Format of STDIN stream:
#define DEPTH_BITS 13
#define MAX_DEPTH ((1<<DEPTH_BITS)-1)
+/*
+ * We abuse the setuid bit on directories to mean "do not delta".
+ */
+#define NO_DELTA S_ISUID
+
struct object_entry {
struct pack_idx_entry idx;
struct object_entry *next;
@@ -1380,9 +1385,12 @@ static int tecmp0 (const void *_a, const void *_b)
{
struct tree_entry *a = *((struct tree_entry**)_a);
struct tree_entry *b = *((struct tree_entry**)_b);
+
return base_name_compare(
- a->name->str_dat, a->name->str_len, a->versions[0].mode,
- b->name->str_dat, b->name->str_len, b->versions[0].mode);
+ a->name->str_dat, a->name->str_len,
+ a->versions[0].mode & ~NO_DELTA,
+ b->name->str_dat, b->name->str_len,
+ b->versions[0].mode & ~NO_DELTA);
}
static int tecmp1 (const void *_a, const void *_b)
@@ -1405,6 +1413,14 @@ static void mktree(struct tree_content *t, int v, struct strbuf *b)
qsort(t->entries,t->entry_count,sizeof(t->entries[0]),tecmp1);
for (i = 0; i < t->entry_count; i++) {
+ /*
+ * A hypothetical mode == (0 | NO_DELTA) would mean
+ * "this version does not exist, and please don't
+ * make deltas against it when writing a tree object
+ * based on it". That is spelled as "mode == 0".
+ */
+ assert(t->entries[i]->versions[v].mode != NO_DELTA);
+
if (t->entries[i]->versions[v].mode)
maxlen += t->entries[i]->name->str_len + 34;
}
@@ -1415,8 +1431,9 @@ static void mktree(struct tree_content *t, int v, struct strbuf *b)
struct tree_entry *e = t->entries[i];
if (!e->versions[v].mode)
continue;
- strbuf_addf(b, "%o %s%c", (unsigned int)e->versions[v].mode,
- e->name->str_dat, '\0');
+ strbuf_addf(b, "%o %s%c",
+ (unsigned int)(e->versions[v].mode & ~NO_DELTA),
+ e->name->str_dat, '\0');
strbuf_add(b, e->versions[v].sha1, 20);
}
}
@@ -1436,7 +1453,10 @@ static void store_tree(struct tree_entry *root)
store_tree(t->entries[i]);
}
- le = find_object(root->versions[0].sha1);
+ if (root->versions[0].mode & NO_DELTA)
+ le = NULL;
+ else
+ le = find_object(root->versions[0].sha1);
if (S_ISDIR(root->versions[0].mode) && le && le->pack_id == pack_id) {
mktree(t, 0, &old_tree);
lo.data = old_tree;
@@ -1470,6 +1490,7 @@ static void tree_content_replace(
{
if (!S_ISDIR(mode))
die("Root cannot be a non-directory");
+ hashclr(root->versions[0].sha1);
hashcpy(root->versions[1].sha1, sha1);
if (root->tree)
release_tree_content_recursive(root->tree);
@@ -1514,11 +1535,30 @@ static int tree_content_set(
if (e->tree)
release_tree_content_recursive(e->tree);
e->tree = subtree;
+
+ /*
+ * We need to leave e->versions[0].sha1 alone
+ * to avoid modifying the preimage tree used
+ * when writing out the parent directory.
+ * But after replacing the subdir with a
+ * completely different one, e->versions[0]
+ * is not a good delta base any more, and
+ * besides, we've thrown away the tree
+ * entries needed to make a delta against it.
+ *
+ * Let's just disable deltas when the time
+ * comes to write this subtree to pack.
+ */
+ if (S_ISDIR(e->versions[0].mode))
+ e->versions[0].mode |= NO_DELTA;
+
hashclr(root->versions[1].sha1);
return 1;
}
if (!S_ISDIR(e->versions[1].mode)) {
e->tree = new_tree_content(8);
+ if (S_ISDIR(e->versions[0].mode))
+ e->versions[0].mode |= NO_DELTA;
e->versions[1].mode = S_IFDIR;
}
if (!e->tree)
@@ -2918,6 +2958,9 @@ static void print_ls(int mode, const unsigned char *sha1, const char *path)
S_ISDIR(mode) ? tree_type :
blob_type;
+ /* NO_DELTA is only used with tree objects. */
+ assert(mode != NO_DELTA);
+
if (!mode) {
/* missing SP path LF */
strbuf_reset(&line);
@@ -2928,7 +2971,7 @@ static void print_ls(int mode, const unsigned char *sha1, const char *path)
/* mode SP type SP object_name TAB path LF */
strbuf_reset(&line);
strbuf_addf(&line, "%06o %s %s\t",
- mode, type, sha1_to_hex(sha1));
+ mode & ~NO_DELTA, type, sha1_to_hex(sha1));
quote_c_style(path, &line, NULL, 0);
strbuf_addch(&line, '\n');
}
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 6b1ba6c8..180d357b 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -734,6 +734,46 @@ test_expect_success \
git diff-tree --abbrev --raw L^ L >output &&
test_cmp expect output'
+cat >input <<INPUT_END
+blob
+mark :1
+data <<EOF
+the data
+EOF
+
+commit refs/heads/L2
+committer C O Mitter <committer@example.com> 1112912473 -0700
+data <<COMMIT
+init L2
+COMMIT
+M 644 :1 a/b/c
+M 644 :1 a/b/d
+M 644 :1 a/e/f
+
+commit refs/heads/L2
+committer C O Mitter <committer@example.com> 1112912473 -0700
+data <<COMMIT
+update L2
+COMMIT
+C a g
+C a/e g/b
+M 644 :1 g/b/h
+INPUT_END
+
+cat <<EOF >expect
+g/b/f
+g/b/h
+EOF
+
+test_expect_success \
+ 'L: modifying a copied tree does not produce a corrupt pack' \
+ 'test_when_finished "git update-ref -d refs/heads/L2" &&
+ git fast-import <input &&
+ git ls-tree L2 g/b/ >tmp &&
+ cut -f 2 <tmp >actual &&
+ test_cmp expect actual &&
+ git fsck L2'
+
###
### series M
###
--
1.7.6
^ permalink raw reply related
* Re: update-index --index-info producing spurious submodule commits
From: Jonathan Nieder @ 2011-08-20 2:15 UTC (permalink / raw)
To: Greg Troxel; +Cc: Junio C Hamano, git, Richard Hansen
In-Reply-To: <rmi39gxacp1.fsf@fnord.ir.bbn.com>
Greg Troxel wrote:
> Junio C Hamano <gitster@pobox.com> writes:
>> "ls-tree -r HEAD foo" is probably what you meant to say.
>
> Thanks very much for the clue - that works. The update-index
> documentation should probably say that only blobs (or perhaps commits
> intended to be submodules??) are acceptable, and perhaps say "ls-tree
> -r" instead of ls-tree.
Makes sense. Please make it so.
By the way, for this particular application I wonder if something like
git ls-files -z <dir> | git update-index -z --force-remove --stdin
git read-tree --prefix=<dir>/ <tree>
would be easier. Or a commit-filter. :)
tree=$1
shift
tree=$(
git ls-tree -z "$tree" |
perl -0ne '
chop;
my ($info, $name) = split(/\t/, $_, 2);
if ($name eq "<dir>") {
printf("040000 tree <good tree>\t<dir>\0");
} else {
printf("%s\0", $_);
}
' |
git mktree -z
)
git commit-tree "$tree" "$@"
Thanks,
Jonathan
^ permalink raw reply
* How to use .gitattributes to tell git that .ini is text file?
From: jelly @ 2011-08-20 2:06 UTC (permalink / raw)
To: Git讨论组(无须订阅)
When I use like this, it takes no effect.
C:\Users\jelly\Documents\My Knowledge\Plugins>cat .gitattributes*.ini text
C:\Users\jelly\Documents\My Knowledge\Plugins>git diffdiff --git a/Misc/plugin.ini b/Misc/plugin.iniindex 078c8a9..f73153c 100755Binary files a/Misc/plugin.ini and b/Misc/plugin.ini differ
^ permalink raw reply
* [PATCH] Grammar and wording fixes in gitrepository-layout
From: Ben Walton @ 2011-08-20 2:43 UTC (permalink / raw)
To: git, gitster; +Cc: Ben Walton
This patch corrects a few grammar issues in gitrepository-layout.txt
and also rewords a few sections for clarity.
Signed-off-by: Ben Walton <bwalton@artsci.utoronto.ca>
---
Documentation/gitrepository-layout.txt | 46 +++++++++++++++----------------
1 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index eb3d040..02a6167 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -23,32 +23,30 @@ objects::
Object store associated with this repository. Usually
an object store is self sufficient (i.e. all the objects
that are referred to by an object found in it are also
- found in it), but there are couple of ways to violate
- it.
+ found in it), but there are a few ways to violate it.
+
. You could populate the repository by running a commit walker
-without `-a` option. Depending on which options are given, you
+without `-a` option. Depending on the options given, you
could have only commit objects without associated blobs and
trees this way, for example. A repository with this kind of
incomplete object store is not suitable to be published to the
-outside world but sometimes useful for private repository.
+outside world but is sometimes useful in a private repository.
. You also could have an incomplete but locally usable repository
-by cloning shallowly. See linkgit:git-clone[1].
-. You can be using `objects/info/alternates` mechanism, or
-`$GIT_ALTERNATE_OBJECT_DIRECTORIES` mechanism to 'borrow'
+by creating a shallow clone. See linkgit:git-clone[1].
+. You could be using the `objects/info/alternates` or
+`$GIT_ALTERNATE_OBJECT_DIRECTORIES` mechanisms to 'borrow'
objects from other object stores. A repository with this kind
of incomplete object store is not suitable to be published for
-use with dumb transports but otherwise is OK as long as
-`objects/info/alternates` points at the right object stores
-it borrows from.
+use with dumb transports but is otherwise OK as long as
+`objects/info/alternates` points at the right object stores.
objects/[0-9a-f][0-9a-f]::
Traditionally, each object is stored in its own file.
- They are split into 256 subdirectories using the first
- two letters from its object name to keep the number of
- directory entries `objects` directory itself needs to
- hold. Objects found here are often called 'unpacked'
- (or 'loose') objects.
+ The objects are splayed over 256 subdirectories using
+ the first two characters of the sha1 object name to
+ keep the number of directory entries in `objects`
+ itself to a manageable number. Objects found
+ here are often called 'unpacked' (or 'loose') objects.
objects/pack::
Packs (files that store many object in compressed form,
@@ -85,7 +83,7 @@ objects/info/http-alternates::
refs::
References are stored in subdirectories of this
- directory. The 'git prune' command knows to keep
+ directory. The 'git prune' command knows to preserve
objects reachable from refs found in this directory and
its subdirectories.
@@ -120,15 +118,15 @@ HEAD::
HEAD can also record a specific commit directly, instead of
being a symref to point at the current branch. Such a state
is often called 'detached HEAD', and almost all commands work
-identically as normal. See linkgit:git-checkout[1] for
+as they normally would. See linkgit:git-checkout[1] for
details.
branches::
A slightly deprecated way to store shorthands to be used
- to specify URL to 'git fetch', 'git pull' and 'git push'
- commands is to store a file in `branches/<name>` and
- give 'name' to these commands in place of 'repository'
- argument.
+ to specify a URL to 'git fetch', 'git pull' and 'git push'.
+ A file can be stored as `branches/<name>` and then
+ 'name' can be givent to these commands in place of
+ 'repository' argument.
hooks::
Hooks are customization scripts used by various git
@@ -173,9 +171,9 @@ info/exclude::
at it. See also: linkgit:gitignore[5].
remotes::
- Stores shorthands to be used to give URL and default
- refnames to interact with remote repository to
- 'git fetch', 'git pull' and 'git push' commands.
+ Stores shorthands for URL and default refnames for use
+ when interacting with remote repositories via 'git fetch',
+ 'git pull' and 'git push' commands.
logs::
Records of changes made to refs are stored in this
--
1.7.4.1
^ permalink raw reply related
* 'git submodule update' w/ .gitmodules 'update=merge' behaves differently on git 1.7.6 vs 1.7.2.5
From: nUxi Codes @ 2011-08-20 4:19 UTC (permalink / raw)
To: git
I have a repository with a submodule configured.
In .gitmodules, the "update = merge" option is set for the submodule.
I am cloning the repo down from, for example, GitHub.
After cloning the parent repo down, I run a:
git submodule init
git submodule update
With git 1.7.2.5 from Squeeze, the resulting submodule repo is
unexpectedly bare. The contents aren't there. 1.7.2.5 is printing:
... (git clone) ...
user@oldhost:~/parentdir$ git submodule init
Submodule 'mysubmodule' (git://github.com/user/submodule.git)
registered for path 'submoduledir'
user@oldhost:~/parentdir$ git submodule update
Cloning into submoduledir...
remote: Counting ....(skipping the obvious).... deltas: 100%
(###/###), done.
Already up-to-date.
Submodule path 'submodule': merged in
'450e1a4ca6705c193d92b34e247fb63d32416c81'
user@oldhost:~/parentdir$ ls submodule
.git
user@oldhost:~/parentdir$
With git 1.7.6 built on FreeBSD, the contents of the submodule are
there. It is not bare.
... (Same) ...
Submodule path 'bundle/pathogen': checked out
'450e1a4ca6705c193d92b34e247fb63d32416c81'
user@newhost:~/parentdir$ ls submodule
.git Stuff Things
.gitignore ...etc...
user@newhost:~/parentdir$
Why the difference? Was this fixed intentionally?
If so, why hasn't Debian backported the fix? It breaks a very common
way of setting things up.
^ permalink raw reply
* Re: [PATCH v4 1/2] push: Don't push a repository with unpushed submodules
From: Junio C Hamano @ 2011-08-20 6:32 UTC (permalink / raw)
To: Fredrik Gustafsson; +Cc: git, hvoigt, jens.lehmann
In-Reply-To: <7vwre9yodc.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> What I meant was more along the lines of the following, but I think we
> would need a new kind of callback that can take N-way parents (which is
> not depicted here).
>
> Let me cook up something and get back to you later tonight.
And here is a two-patch series to do just that.
The first one is meant for you to use, and the second one is a sample
application of the new machinery.
-- >8 --
Subject: [PATCH 1/2] combine-diff: support format_callback
This teaches combine-diff machinery to feed a combined merge to a callback
function when DIFF_FORMAT_CALLBACK is specified.
So far, format callback functions are not used for anything but 2-way
diffs. A callback is given a diff_queue_struct, which is an array of
diff_filepair. As its name suggests, a diff_filepair is a _pair_ of
diff_filespec that represents a single preimage and a single postimage.
Since "diff -c" is to compare N parents with a single merge result and
filter out any paths whose result match one (or more) of the parent(s),
its output has to be able to represent N preimages and 1 postimage. For
this reason, a callback function that inspects a diff_filepair that
results from this new infrastructure can and is expected to view the
preimage side (i.e. pair->one) as an array of diff_filespec. Each element
in the array, except for the last one, is marked with "has_more_entries"
bit, so that the same callback function can be used for 2-way diffs and
combined diffs.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
combine-diff.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diffcore.h | 2 +-
2 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/combine-diff.c b/combine-diff.c
index 655fa89..de88186 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -970,6 +970,72 @@ void show_combined_diff(struct combine_diff_path *p,
show_patch_diff(p, num_parent, dense, rev);
}
+static void free_combined_pair(struct diff_filepair *pair)
+{
+ free(pair->two);
+ free(pair);
+}
+
+/*
+ * A combine_diff_path expresses N parents on the LHS against 1 merge
+ * result. Synthesize a diff_filepair that has N entries on the "one"
+ * side and 1 entry on the "two" side.
+ *
+ * In the future, we might want to add more data to combine_diff_path
+ * so that we can fill fields we are ignoring (most notably, size) here,
+ * but currently nobody uses it, so this should suffice for now.
+ */
+static struct diff_filepair *combined_pair(struct combine_diff_path *p,
+ int num_parent)
+{
+ int i;
+ struct diff_filepair *pair;
+ struct diff_filespec *pool;
+
+ pair = xmalloc(sizeof(*pair));
+ pool = xcalloc(num_parent + 1, sizeof(struct diff_filespec));
+ pair->one = pool + 1;
+ pair->two = pool;
+
+ for (i = 0; i < num_parent; i++) {
+ pair->one[i].path = p->path;
+ pair->one[i].mode = p->parent[i].mode;
+ hashcpy(pair->one[i].sha1, p->parent[i].sha1);
+ pair->one[i].sha1_valid = !is_null_sha1(p->parent[i].sha1);
+ pair->one[i].has_more_entries = 1;
+ }
+ pair->one[num_parent - 1].has_more_entries = 0;
+
+ pair->two->path = p->path;
+ pair->two->mode = p->mode;
+ hashcpy(pair->two->sha1, p->sha1);
+ pair->two->sha1_valid = !is_null_sha1(p->sha1);
+ return pair;
+}
+
+static void handle_combined_callback(struct diff_options *opt,
+ struct combine_diff_path *paths,
+ int num_parent,
+ int num_paths)
+{
+ struct combine_diff_path *p;
+ struct diff_queue_struct q;
+ int i;
+
+ q.queue = xcalloc(num_paths, sizeof(struct diff_filepair *));
+ q.alloc = num_paths;
+ q.nr = num_paths;
+ for (i = 0, p = paths; p; p = p->next) {
+ if (!p->len)
+ continue;
+ q.queue[i++] = combined_pair(p, num_parent);
+ }
+ opt->format_callback(&q, opt, opt->format_callback_data);
+ for (i = 0; i < num_paths; i++)
+ free_combined_pair(q.queue[i]);
+ free(q.queue);
+}
+
void diff_tree_combined(const unsigned char *sha1,
const unsigned char parent[][20],
int num_parent,
@@ -1029,6 +1095,9 @@ void diff_tree_combined(const unsigned char *sha1,
else if (opt->output_format &
(DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT))
needsep = 1;
+ else if (opt->output_format & DIFF_FORMAT_CALLBACK)
+ handle_combined_callback(opt, paths, num_parent, num_paths);
+
if (opt->output_format & DIFF_FORMAT_PATCH) {
if (needsep)
putchar(opt->line_termination);
diff --git a/diffcore.h b/diffcore.h
index b8f1fde..8f32b82 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -45,7 +45,7 @@ struct diff_filespec {
unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */
#define DIRTY_SUBMODULE_UNTRACKED 1
#define DIRTY_SUBMODULE_MODIFIED 2
-
+ unsigned has_more_entries : 1; /* only appear in combined diff */
struct userdiff_driver *driver;
/* data should be considered "binary"; -1 means "don't know yet" */
int is_binary;
--
1.7.6.557.gcee42
^ permalink raw reply related
* [PATCH 2/2] demonstrate format-callback used in combined diff
From: Junio C Hamano @ 2011-08-20 6:34 UTC (permalink / raw)
To: Fredrik Gustafsson; +Cc: git, hvoigt, jens.lehmann
In-Reply-To: <7vwre9yodc.fsf@alter.siamese.dyndns.org>
This demonstrates how to use the format-callback machinery added
to combined diff.
$ ./git demo v1.7.6..maint
works like "git log" with the same revision-range arguments, but shows
list of paths that have contents in the child commit different from any of
its parent commit(s). As a consequence, when a trivial merge takes the
contents of a path as a whole from one parent, such a path is not shown.
Notice how the same function can be used to be called back for a two-way
diff (i.e. there is only one entry on the preimage "one" side) and also
for a combined diff.
Obviously not meant for inclusion.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin.h | 1 +
builtin/log.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
git.c | 1 +
3 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/builtin.h b/builtin.h
index 0e9da90..aef8917 100644
--- a/builtin.h
+++ b/builtin.h
@@ -59,6 +59,7 @@ extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_config(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_demo(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
diff --git a/builtin/log.c b/builtin/log.c
index 5c2af59..cc222c8 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -8,6 +8,7 @@
#include "color.h"
#include "commit.h"
#include "diff.h"
+#include "diffcore.h"
#include "revision.h"
#include "log-tree.h"
#include "builtin.h"
@@ -436,6 +437,53 @@ static void show_rev_tweak_rev(struct rev_info *rev, struct setup_revision_opt *
rev->diffopt.output_format = DIFF_FORMAT_PATCH;
}
+static void show_paths_callback(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ int i;
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *pair = q->queue[i];
+ struct diff_filespec *spec;
+ int j;
+
+ j = 0;
+ spec = pair->one;
+ while (1) {
+ printf("Parent[%d] %s (%s)\n",
+ j, spec->path, sha1_to_hex(spec->sha1));
+ if (!spec->has_more_entries)
+ break;
+ j++;
+ spec++;
+ }
+ printf("Result %s (%s)\n",
+ pair->two->path, sha1_to_hex(pair->two->sha1));
+ }
+}
+
+int cmd_demo(int argc, const char **argv, const char *prefix)
+{
+ struct rev_info rev;
+ struct setup_revision_opt opt;
+
+ init_revisions(&rev, prefix);
+ rev.diff = 1;
+ memset(&opt, 0, sizeof(opt));
+ opt.def = "HEAD";
+ cmd_log_init(argc, argv, prefix, &rev, &opt);
+
+ rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = show_paths_callback;
+ rev.diffopt.format_callback_data = NULL;
+ rev.diff = 1;
+ rev.combine_merges = 1;
+ rev.dense_combined_merges = 0;
+ rev.ignore_merges = 0;
+
+ return cmd_log_walk(&rev);
+}
+
int cmd_show(int argc, const char **argv, const char *prefix)
{
struct rev_info rev;
diff --git a/git.c b/git.c
index 89721d4..34d2381 100644
--- a/git.c
+++ b/git.c
@@ -346,6 +346,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config, RUN_SETUP_GENTLY },
{ "count-objects", cmd_count_objects, RUN_SETUP },
+ { "demo", cmd_demo, RUN_SETUP },
{ "describe", cmd_describe, RUN_SETUP },
{ "diff", cmd_diff },
{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
--
1.7.6.557.gcee42
^ permalink raw reply related
* Re: [PATCH v3] fast-import: do not write bad delta for replaced subtrees
From: Andreas Schwab @ 2011-08-20 9:08 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Dmitry Ivankov, git, Shawn O. Pearce, David Barr
In-Reply-To: <20110820010901.GA2512@elie.sbx02827.chicail.wayport.net>
Jonathan Nieder <jrnieder@gmail.com> writes:
> Thanks again for this. Abusing (S_ISDIR | S_ISUID) still leaves a bad
> taste in my mouth, but after your description I'm convinced that
> behavior-wise it's the right thing to do.
$ git grep S_ISUID
compat/mingw.h:#define S_ISUID 0
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ 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