author | Junio C Hamano <gitster@pobox.com> | |
Tue, 15 Apr 2008 06:15:09 +0000 (23:15 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 15 Apr 2008 06:15:09 +0000 (23:15 -0700) |
* maint:
git clean: Add test to verify directories aren't removed with a prefix
git clean: Don't automatically remove directories when run within subdirectory
git-submodule - possibly use branch name to describe a module
git clean: Add test to verify directories aren't removed with a prefix
git clean: Don't automatically remove directories when run within subdirectory
git-submodule - possibly use branch name to describe a module
27 files changed:
index 04c01c5fdca566b1760e8eed02687607017e89aa..fe43b12572fcb1a0b4b91972d2d504b2b594a4da 100644 (file)
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
The configuration variables in the 'imap' section are described
in linkgit:git-imap-send[1].
+receive.fsckObjects::
+ If it is set to true, git-receive-pack will check all received
+ objects. It will abort in the case of a malformed object or a
+ broken link. The result of an abort are only dangling objects.
+ Defaults to false.
+
receive.unpackLimit::
If the number of objects received in a push is below this
limit then the objects will be unpacked into loose object
index 96585ae8d9455654b63e83d61e7c34a7aeb94291..698ffde7ce844e38abe2719b2f8043783742f134 100644 (file)
The command takes various subcommands, and different options depending
on the subcommand:
+ git bisect help
git bisect start [<bad> [<good>...]] [--] [<paths>...]
git bisect bad [<rev>]
git bisect good [<rev>...]
binary search process to find which change introduced a bug, given an
old "good" commit object name and a later "bad" commit object name.
+Getting help
+~~~~~~~~~~~~
+
+Use "git bisect" to get a short usage description, and "git bisect
+help" or "git bisect -h" to get a long usage description.
+
Basic bisect commands: start, bad, good
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index b79be3fd4ced9dac416fb0fb7f97ab2d10775d01..3697896a06b460d9d29f962240dc46388487990a 100644 (file)
and make the best effort to recover as many objects as
possible.
+--strict::
+ Don't write objects with broken content or links.
+
Author
------
index 0193c3ce58de4f51a164d43e68023fdf5639a920..e8bea3e18e569e702233d0bb986fc7e52266d445 100644 (file)
- '%Creset': reset color
- '%m': left, right or boundary mark
- '%n': newline
+- '%x00': print a byte from a hex code
diff --git a/Makefile b/Makefile
index 7c70b00b826f8f51c0b39ca2454e960b2747c403..78b773862197d46247aa73e5e38aac30edceecc2 100644 (file)
--- a/Makefile
+++ b/Makefile
# default configuration for gitweb
GITWEB_CONFIG = gitweb_config.perl
+GITWEB_CONFIG_SYSTEM = /etc/gitweb.conf
GITWEB_HOME_LINK_STR = projects
GITWEB_SITENAME =
GITWEB_PROJECTROOT = /pub/git
-e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
-e 's|++GIT_BINDIR++|$(bindir)|g' \
-e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \
+ -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \
-e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
-e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
-e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
diff --git a/builtin-apply.c b/builtin-apply.c
index abe73a0f8194e95c2a10a27c2007560e6d57f3d5..c8ca41b68f8febb4856e3d6cc9a0ebef0a0a9973 100644 (file)
--- a/builtin-apply.c
+++ b/builtin-apply.c
static int git_apply_config(const char *var, const char *value)
{
- if (!strcmp(var, "apply.whitespace")) {
- if (!value)
- return config_error_nonbool(var);
- apply_default_whitespace = xstrdup(value);
- return 0;
- }
+ if (!strcmp(var, "apply.whitespace"))
+ return git_config_string(&apply_default_whitespace, var, value);
return git_default_config(var, value);
}
diff --git a/builtin-commit.c b/builtin-commit.c
index 05dfc6973aadf4d8a0250f839409c58e0d9cd77d..bcb7aaaa93bb11bfb965fe67a644e2dd46c21c1b 100644 (file)
--- a/builtin-commit.c
+++ b/builtin-commit.c
die("No paths with --include/--only does not make sense.");
if (argc == 0 && only && amend)
only_include_assumed = "Clever... amending the last one with dirty index.";
- if (argc > 0 && !also && !only) {
+ if (argc > 0 && !also && !only)
only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
- also = 0;
- }
if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
else if (!strcmp(cleanup_arg, "verbatim"))
diff --git a/builtin-config.c b/builtin-config.c
index c34bc8b6a6957ccee1db23a3c44c99e058384689..10447a704f7b3a1fb3b3053463a50ae2609a5684 100644 (file)
--- a/builtin-config.c
+++ b/builtin-config.c
#include "color.h"
static const char git_config_set_usage[] =
-"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]";
+"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int | --bool-or-int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]";
static char *key;
static regex_t *key_regexp;
static char delim = '=';
static char key_delim = ' ';
static char term = '\n';
-static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
+static enum { T_RAW, T_INT, T_BOOL, T_BOOL_OR_INT } type = T_RAW;
static int show_all_config(const char *key_, const char *value_)
{
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
else if (type == T_BOOL)
vptr = git_config_bool(key_, value_) ? "true" : "false";
+ else if (type == T_BOOL_OR_INT) {
+ int is_bool, v;
+ v = git_config_bool_or_int(key_, value_, &is_bool);
+ if (is_bool)
+ vptr = v ? "true" : "false";
+ else
+ sprintf(value, "%d", v);
+ }
else
vptr = value_?value_:"";
seen++;
else if (type == T_BOOL)
sprintf(normalized, "%s",
git_config_bool(key, value) ? "true" : "false");
+ else if (type == T_BOOL_OR_INT) {
+ int is_bool, v;
+ v = git_config_bool_or_int(key, value, &is_bool);
+ if (!is_bool)
+ sprintf(normalized, "%d", v);
+ else
+ sprintf(normalized, "%s", v ? "true" : "false");
+ }
}
return normalized;
type = T_INT;
else if (!strcmp(argv[1], "--bool"))
type = T_BOOL;
+ else if (!strcmp(argv[1], "--bool-or-int"))
+ type = T_BOOL_OR_INT;
else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) {
if (argc != 2)
usage(git_config_set_usage);
index 50e07faa12f495b3270e1446573b88a255336877..fecf0be7796f34fbb06a6bbbe61e9e3d042f6780 100644 (file)
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
#include "commit.h"
#include "tag.h"
#include "tree.h"
+#include "tree-walk.h"
#include "progress.h"
#include "decorate.h"
+#include "fsck.h"
-static int dry_run, quiet, recover, has_errors;
-static const char unpack_usage[] = "git-unpack-objects [-n] [-q] [-r] < pack-file";
+static int dry_run, quiet, recover, has_errors, strict;
+static const char unpack_usage[] = "git-unpack-objects [-n] [-q] [-r] [--strict] < pack-file";
/* We always read in 4kB chunks. */
static unsigned char buffer[4096];
static off_t consumed_bytes;
static SHA_CTX ctx;
+/*
+ * When running under --strict mode, objects whose reachability are
+ * suspect are kept in core without getting written in the object
+ * store.
+ */
struct obj_buffer {
char *buffer;
unsigned long size;
return lookup_decoration(&obj_decorate, base);
}
+static void add_object_buffer(struct object *object, char *buffer, unsigned long size)
+{
+ struct obj_buffer *obj;
+ obj = xcalloc(1, sizeof(struct obj_buffer));
+ obj->buffer = buffer;
+ obj->size = size;
+ if (add_decoration(&obj_decorate, object, obj))
+ die("object %s tried to add buffer twice!", sha1_to_hex(object->sha1));
+}
+
/*
* Make sure at least "min" bytes are available in the buffer, and
* return the pointer to the buffer.
struct obj_info {
off_t offset;
unsigned char sha1[20];
+ struct object *obj;
};
+#define FLAG_OPEN (1u<<20)
+#define FLAG_WRITTEN (1u<<21)
+
static struct obj_info *obj_list;
+unsigned nr_objects;
+
+/*
+ * Called only from check_object() after it verified this object
+ * is Ok.
+ */
+static void write_cached_object(struct object *obj)
+{
+ unsigned char sha1[20];
+ struct obj_buffer *obj_buf = lookup_object_buffer(obj);
+ if (write_sha1_file(obj_buf->buffer, obj_buf->size, typename(obj->type), sha1) < 0)
+ die("failed to write object %s", sha1_to_hex(obj->sha1));
+ obj->flags |= FLAG_WRITTEN;
+}
+
+/*
+ * At the very end of the processing, write_rest() scans the objects
+ * that have reachability requirements and calls this function.
+ * Verify its reachability and validity recursively and write it out.
+ */
+static int check_object(struct object *obj, int type, void *data)
+{
+ if (!obj)
+ return 0;
+
+ if (obj->flags & FLAG_WRITTEN)
+ return 1;
+
+ if (type != OBJ_ANY && obj->type != type)
+ die("object type mismatch");
+
+ if (!(obj->flags & FLAG_OPEN)) {
+ unsigned long size;
+ int type = sha1_object_info(obj->sha1, &size);
+ if (type != obj->type || type <= 0)
+ die("object of unexpected type");
+ obj->flags |= FLAG_WRITTEN;
+ return 1;
+ }
+
+ if (fsck_object(obj, 1, fsck_error_function))
+ die("Error in object");
+ if (!fsck_walk(obj, check_object, 0))
+ die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
+ write_cached_object(obj);
+ return 1;
+}
+
+static void write_rest(void)
+{
+ unsigned i;
+ for (i = 0; i < nr_objects; i++)
+ check_object(obj_list[i].obj, OBJ_ANY, 0);
+}
static void added_object(unsigned nr, enum object_type type,
void *data, unsigned long size);
+/*
+ * Write out nr-th object from the list, now we know the contents
+ * of it. Under --strict, this buffers structured objects in-core,
+ * to be checked at the end.
+ */
static void write_object(unsigned nr, enum object_type type,
void *buf, unsigned long size)
{
- if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
- die("failed to write object");
- added_object(nr, type, buf, size);
+ if (!strict) {
+ if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
+ die("failed to write object");
+ added_object(nr, type, buf, size);
+ free(buf);
+ obj_list[nr].obj = NULL;
+ } else if (type == OBJ_BLOB) {
+ struct blob *blob;
+ if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
+ die("failed to write object");
+ added_object(nr, type, buf, size);
+ free(buf);
+
+ blob = lookup_blob(obj_list[nr].sha1);
+ if (blob)
+ blob->object.flags |= FLAG_WRITTEN;
+ else
+ die("invalid blob object");
+ obj_list[nr].obj = NULL;
+ } else {
+ struct object *obj;
+ int eaten;
+ hash_sha1_file(buf, size, typename(type), obj_list[nr].sha1);
+ added_object(nr, type, buf, size);
+ obj = parse_object_buffer(obj_list[nr].sha1, type, size, buf, &eaten);
+ if (!obj)
+ die("invalid %s", typename(type));
+ add_object_buffer(obj, buf, size);
+ obj->flags |= FLAG_OPEN;
+ obj_list[nr].obj = obj;
+ }
}
static void resolve_delta(unsigned nr, enum object_type type,
die("failed to apply delta");
free(delta);
write_object(nr, type, result, result_size);
- free(result);
}
+/*
+ * We now know the contents of an object (which is nr-th in the pack);
+ * resolve all the deltified objects that are based on it.
+ */
static void added_object(unsigned nr, enum object_type type,
void *data, unsigned long size)
{
if (!dry_run && buf)
write_object(nr, type, buf, size);
- free(buf);
+ else
+ free(buf);
+}
+
+static int resolve_against_held(unsigned nr, const unsigned char *base,
+ void *delta_data, unsigned long delta_size)
+{
+ struct object *obj;
+ struct obj_buffer *obj_buffer;
+ obj = lookup_object(base);
+ if (!obj)
+ return 0;
+ obj_buffer = lookup_object_buffer(obj);
+ if (!obj_buffer)
+ return 0;
+ resolve_delta(nr, obj->type, obj_buffer->buffer,
+ obj_buffer->size, delta_data, delta_size);
+ return 1;
}
static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
void *delta_data, *base;
unsigned long base_size;
unsigned char base_sha1[20];
- struct object *obj;
if (type == OBJ_REF_DELTA) {
hashcpy(base_sha1, fill(20));
@@ -212,7 +339,13 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
free(delta_data);
return;
}
- if (!has_sha1_file(base_sha1)) {
+ if (has_sha1_file(base_sha1))
+ ; /* Ok we have this one */
+ else if (resolve_against_held(nr, base_sha1,
+ delta_data, delta_size))
+ return; /* we are done */
+ else {
+ /* cannot resolve yet --- queue it */
hashcpy(obj_list[nr].sha1, null_sha1);
add_delta_to_list(nr, base_sha1, 0, delta_data, delta_size);
return;
@@ -258,22 +391,18 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
}
}
if (!base_found) {
- /* The delta base object is itself a delta that
- has not been resolved yet. */
+ /*
+ * The delta base object is itself a delta that
+ * has not been resolved yet.
+ */
hashcpy(obj_list[nr].sha1, null_sha1);
add_delta_to_list(nr, null_sha1, base_offset, delta_data, delta_size);
return;
}
}
- obj = lookup_object(base_sha1);
- if (obj) {
- struct obj_buffer *obj_buf = lookup_object_buffer(obj);
- if (obj_buf) {
- resolve_delta(nr, obj->type, obj_buf->buffer, obj_buf->size, delta_data, delta_size);
- return;
- }
- }
+ if (resolve_against_held(nr, base_sha1, delta_data, delta_size))
+ return;
base = read_sha1_file(base_sha1, &type, &base_size);
if (!base) {
int i;
struct progress *progress = NULL;
struct pack_header *hdr = fill(sizeof(struct pack_header));
- unsigned nr_objects = ntohl(hdr->hdr_entries);
+
+ nr_objects = ntohl(hdr->hdr_entries);
if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE)
die("bad pack file");
if (!quiet)
progress = start_progress("Unpacking objects", nr_objects);
obj_list = xmalloc(nr_objects * sizeof(*obj_list));
+ memset(obj_list, 0, nr_objects * sizeof(*obj_list));
for (i = 0; i < nr_objects; i++) {
unpack_one(i);
display_progress(progress, i + 1);
recover = 1;
continue;
}
+ if (!strcmp(arg, "--strict")) {
+ strict = 1;
+ continue;
+ }
if (!prefixcmp(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;
unpack_all();
SHA1_Update(&ctx, buffer, offset);
SHA1_Final(sha1, &ctx);
+ if (strict)
+ write_rest();
if (hashcmp(fill(20), sha1))
die("final sha1 did not match");
use(20);
index 2a1e7ec6b2bf712af80813936b5aed434d02090e..50b28fad0126d14d012769d5e8b95eb9ab6853d3 100644 (file)
--- a/cache.h
+++ b/cache.h
extern int git_parse_ulong(const char *, unsigned long *);
extern int git_config_int(const char *, const char *);
extern unsigned long git_config_ulong(const char *, const char *);
+extern int git_config_bool_or_int(const char *, const char *, int *);
extern int git_config_bool(const char *, const char *);
extern int git_config_string(const char **, const char *, const char *);
extern int git_config_set(const char *, const char *);
diff --git a/config.c b/config.c
index 062449459e1a4cfc2a605c065ed281669e0e7452..b0ada515b9d839fc8691bc9af320353ff323b251 100644 (file)
--- a/config.c
+++ b/config.c
return ret;
}
-int git_config_bool(const char *name, const char *value)
+int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
{
+ *is_bool = 1;
if (!value)
return 1;
if (!*value)
return 1;
if (!strcasecmp(value, "false") || !strcasecmp(value, "no"))
return 0;
- return git_config_int(name, value) != 0;
+ *is_bool = 0;
+ return git_config_int(name, value);
+}
+
+int git_config_bool(const char *name, const char *value)
+{
+ int discard;
+ return !!git_config_bool_or_int(name, value, &discard);
}
int git_config_string(const char **dest, const char *var, const char *value)
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 31941bcbbf457fe02097f8c46d25f1f9fc7c4f9f..1369a5ec45349c1ef04e4df2d7d7d4dd28cd3596 100644 (file)
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
struct diff_score {
int src; /* index in rename_src */
int dst; /* index in rename_dst */
- int score;
- int name_score;
+ unsigned short score;
+ short name_score;
};
static int estimate_similarity(struct diff_filespec *src,
{
const struct diff_score *a = a_, *b = b_;
+ /* sink the unused ones to the bottom */
+ if (a->dst < 0)
+ return (0 <= b->dst);
+ else if (b->dst < 0)
+ return -1;
+
if (a->score == b->score)
return b->name_score - a->name_score;
return i;
}
+#define NUM_CANDIDATE_PER_DST 4
+static void record_if_better(struct diff_score m[], struct diff_score *o)
+{
+ int i, worst;
+
+ /* find the worst one */
+ worst = 0;
+ for (i = 1; i < NUM_CANDIDATE_PER_DST; i++)
+ if (score_compare(&m[i], &m[worst]) > 0)
+ worst = i;
+
+ /* is it better than the worst one? */
+ if (score_compare(&m[worst], o) > 0)
+ m[worst] = *o;
+}
+
void diffcore_rename(struct diff_options *options)
{
int detect_rename = options->detect_rename;
goto cleanup;
}
- mx = xmalloc(sizeof(*mx) * num_create * num_src);
+ mx = xcalloc(num_create * NUM_CANDIDATE_PER_DST, sizeof(*mx));
for (dst_cnt = i = 0; i < rename_dst_nr; i++) {
- int base = dst_cnt * num_src;
struct diff_filespec *two = rename_dst[i].two;
+ struct diff_score *m;
+
if (rename_dst[i].pair)
continue; /* dealt with exact match already. */
+
+ m = &mx[dst_cnt * NUM_CANDIDATE_PER_DST];
+ for (j = 0; j < NUM_CANDIDATE_PER_DST; j++)
+ m[j].dst = -1;
+
for (j = 0; j < rename_src_nr; j++) {
struct diff_filespec *one = rename_src[j].one;
- struct diff_score *m = &mx[base+j];
- m->src = j;
- m->dst = i;
- m->score = estimate_similarity(one, two,
- minimum_score);
- m->name_score = basename_same(one, two);
+ struct diff_score this_src;
+ this_src.score = estimate_similarity(one, two,
+ minimum_score);
+ this_src.name_score = basename_same(one, two);
+ this_src.dst = i;
+ this_src.src = j;
+ record_if_better(m, &this_src);
diff_free_filespec_blob(one);
}
/* We do not need the text anymore */
diff_free_filespec_blob(two);
dst_cnt++;
}
+
/* cost matrix sorted by most to least similar pair */
- qsort(mx, num_create * num_src, sizeof(*mx), score_compare);
- for (i = 0; i < num_create * num_src; i++) {
- struct diff_rename_dst *dst = &rename_dst[mx[i].dst];
- struct diff_filespec *src;
+ qsort(mx, dst_cnt * NUM_CANDIDATE_PER_DST, sizeof(*mx), score_compare);
+
+ for (i = 0; i < dst_cnt * NUM_CANDIDATE_PER_DST; i++) {
+ struct diff_rename_dst *dst;
+
+ if ((mx[i].dst < 0) ||
+ (mx[i].score < minimum_score))
+ break; /* there is no more usable pair. */
+ dst = &rename_dst[mx[i].dst];
if (dst->pair)
continue; /* already done, either exact or fuzzy. */
- if (mx[i].score < minimum_score)
- break; /* there is no more usable pair. */
- src = rename_src[mx[i].src].one;
- if (src->rename_used)
+ if (rename_src[mx[i].src].one->rename_used)
continue;
record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
rename_count++;
}
- for (i = 0; i < num_create * num_src; i++) {
- struct diff_rename_dst *dst = &rename_dst[mx[i].dst];
+
+ for (i = 0; i < dst_cnt * NUM_CANDIDATE_PER_DST; i++) {
+ struct diff_rename_dst *dst;
+
+ if ((mx[i].dst < 0) ||
+ (mx[i].score < minimum_score))
+ break; /* there is no more usable pair. */
+ dst = &rename_dst[mx[i].dst];
if (dst->pair)
continue; /* already done, either exact or fuzzy. */
- if (mx[i].score < minimum_score)
- break; /* there is no more usable pair. */
record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
rename_count++;
}
index a0a81f134a6288dfc1d87431698f29597ed5e488..903953e68e98535e754b5a5dd6ba22eb6074ef20 100755 (executable)
return @hunk;
}
+sub parse_diff_header {
+ my $src = shift;
+
+ my $head = { TEXT => [], DISPLAY => [] };
+ my $mode = { TEXT => [], DISPLAY => [] };
+
+ for (my $i = 0; $i < @{$src->{TEXT}}; $i++) {
+ my $dest = $src->{TEXT}->[$i] =~ /^(old|new) mode (\d+)$/ ?
+ $mode : $head;
+ push @{$dest->{TEXT}}, $src->{TEXT}->[$i];
+ push @{$dest->{DISPLAY}}, $src->{DISPLAY}->[$i];
+ }
+ return ($head, $mode);
+}
+
sub hunk_splittable {
my ($text) = @_;
my ($ix, $num);
my $path = shift;
my ($head, @hunk) = parse_diff($path);
+ ($head, my $mode) = parse_diff_header($head);
for (@{$head->{DISPLAY}}) {
print;
}
+
+ if (@{$mode->{TEXT}}) {
+ while (1) {
+ print @{$mode->{DISPLAY}};
+ print colored $prompt_color,
+ "Stage mode change [y/n/a/d/?]? ";
+ my $line = <STDIN>;
+ if ($line =~ /^y/i) {
+ $mode->{USE} = 1;
+ last;
+ }
+ elsif ($line =~ /^n/i) {
+ $mode->{USE} = 0;
+ last;
+ }
+ elsif ($line =~ /^a/i) {
+ $_->{USE} = 1 foreach ($mode, @hunk);
+ last;
+ }
+ elsif ($line =~ /^d/i) {
+ $_->{USE} = 0 foreach ($mode, @hunk);
+ last;
+ }
+ else {
+ help_patch_cmd('');
+ next;
+ }
+ }
+ }
+
$num = scalar @hunk;
$ix = 0;
my $n_lofs = 0;
my @result = ();
+ if ($mode->{USE}) {
+ push @result, @{$mode->{TEXT}};
+ }
for (@hunk) {
my $text = $_->{TEXT};
my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
diff --git a/git-bisect.sh b/git-bisect.sh
index 5177a2a11482af276ae5243c4d550b68bb0e2a28..408775a51e2ad7b3007ea8a0001516c26166318a 100755 (executable)
--- a/git-bisect.sh
+++ b/git-bisect.sh
#!/bin/sh
-USAGE='[start|bad|good|skip|next|reset|visualize|replay|log|run]'
-LONG_USAGE='git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
+USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
+LONG_USAGE='git bisect help
+ print this long help message.
+git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
reset bisect state and start bisection.
git bisect bad [<rev>]
mark <rev> a known-bad revision.
git bisect log
show bisect log.
git bisect run <cmd>...
- use <cmd>... to automatically bisect.'
+ use <cmd>... to automatically bisect.
+
+Please use "git help bisect" to get the full man page.'
OPTIONS_SPEC=
. git-sh-setup
cmd="$1"
shift
case "$cmd" in
+ help)
+ git bisect -h ;;
start)
bisect_start "$@" ;;
bad|good|skip)
diff --git a/git-rebase.sh b/git-rebase.sh
index 60c458f201f8f98bb1c6e115c009525659c2ee20..9b13b833cb5762542848ee3e85e23d3ca0f76fa6 100755 (executable)
--- a/git-rebase.sh
+++ b/git-rebase.sh
}
fi
-# If the branch to rebase is given, first switch to it.
+# If the branch to rebase is given, that is the branch we will rebase
+# $branch_name -- branch being rebased, or HEAD (already detached)
+# $orig_head -- commit object name of tip of the branch before rebasing
+# $head_name -- refs/heads/<that-branch> or "detached HEAD"
+switch_to=
case "$#" in
2)
+ # Is it "rebase other $branchname" or "rebase other $commit"?
branch_name="$2"
- git-checkout "$2" || usage
+ switch_to="$2"
+
+ if git show-ref --verify --quiet -- "refs/heads/$2" &&
+ branch=$(git rev-parse --verify "refs/heads/$2" 2>/dev/null)
+ then
+ head_name="refs/heads/$2"
+ elif branch=$(git rev-parse --verify "$2" 2>/dev/null)
+ then
+ head_name="detached HEAD"
+ else
+ usage
+ fi
;;
*)
+ # Do not need to switch branches, we are already on it.
if branch_name=`git symbolic-ref -q HEAD`
then
+ head_name=$branch_name
branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
else
+ head_name="detached HEAD"
branch_name=HEAD ;# detached
fi
+ branch=$(git rev-parse --verify "${branch_name}^0") || exit
;;
esac
-branch=$(git rev-parse --verify "${branch_name}^0") || exit
+orig_head=$branch
# Now we are rebasing commits $upstream..$branch on top of $onto
# linear history?
! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null
then
+ # Lazily switch to the target branch if needed...
+ test -z "$switch_to" || git checkout "$switch_to"
echo >&2 "Current branch $branch_name is up to date."
exit 0
fi
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
fi
-# move to a detached HEAD
-orig_head=$(git rev-parse HEAD^0)
-head_name=$(git symbolic-ref HEAD 2> /dev/null)
-case "$head_name" in
-'')
- head_name="detached HEAD"
- ;;
-*)
- git checkout "$orig_head" > /dev/null 2>&1 ||
- die "could not detach HEAD"
- ;;
-esac
-
-# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
+# Detach HEAD and reset the tree
echo "First, rewinding head to replay your work on top of it..."
-git-reset --hard "$onto"
+git checkout "$onto^0" >/dev/null 2>&1 ||
+ die "could not detach HEAD"
+# git reset --hard "$onto^0"
# If the $onto is a proper descendant of the tip of the branch, then
# we just fast forwarded.
if test -z "$do_merge"
then
- git format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD |
+ git format-patch -k --stdout --full-index --ignore-if-in-upstream \
+ "$upstream..$orig_head" |
git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
move_to_original_branch
ret=$?
echo "$head_name" > "$dotest/head-name"
msgnum=0
-for cmt in `git rev-list --reverse --no-merges "$upstream"..ORIG_HEAD`
+for cmt in `git rev-list --reverse --no-merges "$upstream..$orig_head"`
do
msgnum=$(($msgnum + 1))
echo "$cmt" > "$dotest/cmt.$msgnum"
diff --git a/git-send-email.perl b/git-send-email.perl
index be4a20d7cd562e9b00d93fe71313aed70afe50af..9e568bf9c012b610fd8db7e4444cb7ff8c6e0a0f 100755 (executable)
--- a/git-send-email.perl
+++ b/git-send-email.perl
# Example reply to:
#$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';
-my $repo = Git->repository();
+my $repo = eval { Git->repository() };
+my @repo = $repo ? ($repo) : ();
my $term = eval {
$ENV{"GIT_SEND_EMAIL_NOTTY"}
? new Term::ReadLine 'git-send-email', \*STDIN, \*STDOUT
foreach my $setting (keys %config_bool_settings) {
my $target = $config_bool_settings{$setting}->[0];
- $$target = $repo->config_bool("$prefix.$setting") unless (defined $$target);
+ $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target);
}
foreach my $setting (keys %config_settings) {
my $target = $config_settings{$setting};
if (ref($target) eq "ARRAY") {
unless (@$target) {
- my @values = $repo->config("$prefix.$setting");
+ my @values = Git::config(@repo, "$prefix.$setting");
@$target = @values if (@values && defined $values[0]);
}
}
else {
- $$target = $repo->config("$prefix.$setting") unless (defined $$target);
+ $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target);
}
}
}
# read configuration from [sendemail "$identity"], fall back on [sendemail]
-$identity = $repo->config("sendemail.identity") unless (defined $identity);
+$identity = Git::config(@repo, "sendemail.identity") unless (defined $identity);
read_config("sendemail.$identity") if (defined $identity);
read_config("sendemail");
}
}
-my ($repoauthor) = $repo->ident_person('author');
-my ($repocommitter) = $repo->ident_person('committer');
+my ($repoauthor, $repocommitter);
+($repoauthor) = Git::ident_person(@repo, 'author');
+($repocommitter) = Git::ident_person(@repo, 'committer');
# Verify the user input
my $prompting = 0;
if (!defined $sender) {
- $sender = $repoauthor || $repocommitter;
+ $sender = $repoauthor || $repocommitter || '';
while (1) {
$_ = $term->readline("Who should the emails appear to be from? [$sender] ");
EOT
close(C);
- my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
+ my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
system('sh', '-c', '$0 $@', $editor, $compose_filename);
open(C2,">",$compose_filename . ".final")
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 9cd5b0a2b111de7e252c407d1ad77e05722d8385..743f2d4442b48af3627c1117aaaf73c89da306be 100644 (file)
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
by default it is file named gitweb_config.perl in the same place as
gitweb.cgi script. You can control default place for config file
using GITWEB_CONFIG build configuration variable, and you can set it
- using GITWEB_CONFIG environmental variable.
+ using GITWEB_CONFIG environmental variable. If this file does not
+ exist, gitweb looks for a system-wide configuration file, normally
+ /etc/gitweb.conf. You can change the default using the
+ GITWEB_CONFIG_SYSTEM build configuration variable, and override it
+ through GITWEB_CONFIG_SYSTEM environmental variable.
- Gitweb config file is [fragment] of perl code. You can set variables
using "our $variable = value"; text from "#" character until the end
diff --git a/gitweb/README b/gitweb/README
index 2163071047a0f4a7620eebf2f4e18008f592c049..8dfe335f73c223fa0da8cd21db6227283adb95ba 100644 (file)
--- a/gitweb/README
+++ b/gitweb/README
is set when gitweb.cgi is executed, then the file specified in the
environment variable will be loaded instead of the file specified
when gitweb.cgi was created. [Default: gitweb_config.perl]
+ * GITWEB_CONFIG_SYSTEM
+ This Perl file will be loaded using 'do' as a fallback if GITWEB_CONFIG
+ does not exist. If the environment variable GITWEB_CONFIG_SYSTEM is set
+ when gitweb.cgi is executed, then the file specified in the environment
+ variable will be loaded instead of the file specified when gitweb.cgi was
+ created. [Default: /etc/gitweb.conf]
Runtime gitweb configuration
----------------------------
You can adjust gitweb behaviour using the file specified in `GITWEB_CONFIG`
-(defaults to 'gitweb_config.perl' in the same directory as the CGI).
+(defaults to 'gitweb_config.perl' in the same directory as the CGI), and
+as a fallback `GITWEB_CONFIG_SYSTEM` (defaults to /etc/gitweb.conf).
The most notable thing that is not configurable at compile time are the
optional features, stored in the '%features' variable.
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 73d098a433f4238c43603ab03c838c1356e7ab7a..e69d7fd07b74d2e1c06f26e98eb72c83183c19f8 100755 (executable)
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
}
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
-do $GITWEB_CONFIG if -e $GITWEB_CONFIG;
+if (-e $GITWEB_CONFIG) {
+ do $GITWEB_CONFIG;
+} else {
+ our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
+ do $GITWEB_CONFIG_SYSTEM if -e $GITWEB_CONFIG_SYSTEM;
+}
# version of the core git binary
our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown";
diff --git a/log-tree.c b/log-tree.c
index 5b2963998cc497177d913b6224799531d45dbb4a..9d54061601c2b378089a88142138ce3e0da1761e 100644 (file)
--- a/log-tree.c
+++ b/log-tree.c
if (opt->show_log_size)
printf("log size %i\n", (int)msgbuf.len);
- if (msgbuf.len)
- printf("%s%s%s", msgbuf.buf, extra, sep);
+ if (msgbuf.len) {
+ fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+ printf("%s%s", extra, sep);
+ }
strbuf_release(&msgbuf);
}
diff --git a/perl/Git.pm b/perl/Git.pm
index a2812ea612b997c1a76d89075dd1263a3af4fd37..2e7f896baec00d644903af5d967b6c781ee3503a 100644 (file)
--- a/perl/Git.pm
+++ b/perl/Git.pm
(exception is thrown otherwise), in array context returns allows the
variable to be set multiple times and returns all the values.
-Must be called on a repository instance.
-
This currently wraps command('config') so it is not so fast.
=cut
sub config {
- my ($self, $var) = @_;
- $self->repo_path()
- or throw Error::Simple("not a repository");
+ my ($self, $var) = _maybe_self(@_);
try {
+ my @cmd = ('config');
+ unshift @cmd, $self if $self;
if (wantarray) {
- return $self->command('config', '--get-all', $var);
+ return command(@cmd, '--get-all', $var);
} else {
- return $self->command_oneline('config', '--get', $var);
+ return command_oneline(@cmd, '--get', $var);
}
} catch Git::Error::Command with {
my $E = shift;
is usable as a boolean in perl (and C<undef> if it's not defined,
of course).
-Must be called on a repository instance.
-
This currently wraps command('config') so it is not so fast.
=cut
sub config_bool {
- my ($self, $var) = @_;
- $self->repo_path()
- or throw Error::Simple("not a repository");
+ my ($self, $var) = _maybe_self(@_);
try {
- my $val = $self->command_oneline('config', '--bool', '--get',
- $var);
+ my @cmd = ('config', '--bool', '--get', $var);
+ unshift @cmd, $self if $self;
+ my $val = command_oneline(@cmd);
return undef unless defined $val;
return $val eq 'true';
} catch Git::Error::Command with {
by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
It would return C<undef> if configuration variable is not defined,
-Must be called on a repository instance.
-
This currently wraps command('config') so it is not so fast.
=cut
sub config_int {
- my ($self, $var) = @_;
- $self->repo_path()
- or throw Error::Simple("not a repository");
+ my ($self, $var) = _maybe_self(@_);
try {
- return $self->command_oneline('config', '--int', '--get', $var);
+ my @cmd = ('config', '--int', '--get', $var);
+ unshift @cmd, $self if $self;
+ return command_oneline(@cmd);
} catch Git::Error::Command with {
my $E = shift;
if ($E->value() == 1) {
"$name <$email>" eq ident_person($name);
$time_tz =~ /^\d+ [+-]\d{4}$/;
-Both methods must be called on a repository instance.
-
=cut
sub ident {
- my ($self, $type) = @_;
+ my ($self, $type) = _maybe_self(@_);
my $identstr;
if (lc $type eq lc 'committer' or lc $type eq lc 'author') {
- $identstr = $self->command_oneline('var', 'GIT_'.uc($type).'_IDENT');
+ my @cmd = ('var', 'GIT_'.uc($type).'_IDENT');
+ unshift @cmd, $self if $self;
+ $identstr = command_oneline(@cmd);
} else {
$identstr = $type;
}
}
sub ident_person {
- my ($self, @ident) = @_;
- $#ident == 0 and @ident = $self->ident($ident[0]);
+ my ($self, @ident) = _maybe_self(@_);
+ $#ident == 0 and @ident = $self ? $self->ident($ident[0]) : ident($ident[0]);
return "$ident[0] <$ident[1]>";
}
diff --git a/pretty.c b/pretty.c
index 16bfb86cd3ce6d6b471cdc313114563ca78837dc..6c04176cb877bf78ca1336d40011edcba29996ae 100644 (file)
--- a/pretty.c
+++ b/pretty.c
const struct commit *commit = c->commit;
const char *msg = commit->buffer;
struct commit_list *p;
+ int h1, h2;
/* these are independent of the commit */
switch (placeholder[0]) {
case 'n': /* newline */
strbuf_addch(sb, '\n');
return 1;
+ case 'x':
+ /* %x00 == NUL, %x0a == LF, etc. */
+ if (0 <= (h1 = hexval_table[0xff & placeholder[1]]) &&
+ h1 <= 16 &&
+ 0 <= (h2 = hexval_table[0xff & placeholder[2]]) &&
+ h2 <= 16) {
+ strbuf_addch(sb, (h1<<4)|h2);
+ return 3;
+ } else
+ return 0;
}
/* these depend on the commit */
diff --git a/receive-pack.c b/receive-pack.c
index f83ae87e150ff93728da989f1d35ce0ad7c10f60..828d49001d6c8494ede35e4ebbcea4fe482802dd 100644 (file)
--- a/receive-pack.c
+++ b/receive-pack.c
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
static int deny_non_fast_forwards = 0;
+static int receive_fsck_objects;
static int receive_unpack_limit = -1;
static int transfer_unpack_limit = -1;
static int unpack_limit = 100;
return 0;
}
+ if (strcmp(var, "receive.fsckobjects") == 0) {
+ receive_fsck_objects = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value);
}
ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
if (ntohl(hdr.hdr_entries) < unpack_limit) {
- int code;
- const char *unpacker[3];
- unpacker[0] = "unpack-objects";
- unpacker[1] = hdr_arg;
- unpacker[2] = NULL;
+ int code, i = 0;
+ const char *unpacker[4];
+ unpacker[i++] = "unpack-objects";
+ if (receive_fsck_objects)
+ unpacker[i++] = "--strict";
+ unpacker[i++] = hdr_arg;
+ unpacker[i++] = NULL;
code = run_command_v_opt(unpacker, RUN_GIT_CMD);
switch (code) {
case 0:
return "unpacker exited with error code";
}
} else {
- const char *keeper[6];
- int s, status;
+ const char *keeper[7];
+ int s, status, i = 0;
char keep_arg[256];
struct child_process ip;
if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
strcpy(keep_arg + s, "localhost");
- keeper[0] = "index-pack";
- keeper[1] = "--stdin";
- keeper[2] = "--fix-thin";
- keeper[3] = hdr_arg;
- keeper[4] = keep_arg;
- keeper[5] = NULL;
+ keeper[i++] = "index-pack";
+ keeper[i++] = "--stdin";
+ if (receive_fsck_objects)
+ keeper[i++] = "--strict";
+ keeper[i++] = "--fix-thin";
+ keeper[i++] = hdr_arg;
+ keeper[i++] = keep_arg;
+ keeper[i++] = NULL;
memset(&ip, 0, sizeof(ip));
ip.argv = keeper;
ip.out = -1;
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index b36a9012ecb3a34761027de77635741e1cd80aab..a675cbb51b5dafad22dd494784a0b4c8ec396db3 100755 (executable)
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
rm .git/config
+cat >expect <<\EOF
+[bool]
+ true1 = true
+ true2 = true
+ false1 = false
+ false2 = false
+[int]
+ int1 = 0
+ int2 = 1
+ int3 = -1
+EOF
+
+test_expect_success 'get --bool-or-int' '
+ (
+ echo "[bool]"
+ echo true1
+ echo true2 = true
+ echo false = false
+ echo "[int]"
+ echo int1 = 0
+ echo int2 = 1
+ echo int3 = -1
+ ) >>.git/config &&
+ test $(git config --bool-or-int bool.true1) = true &&
+ test $(git config --bool-or-int bool.true2) = true &&
+ test $(git config --bool-or-int bool.false) = false &&
+ test $(git config --bool-or-int int.int1) = 0 &&
+ test $(git config --bool-or-int int.int2) = 1 &&
+ test $(git config --bool-or-int int.int3) = -1
+
+'
+
+rm .git/config
+cat >expect <<\EOF
+[bool]
+ true1 = true
+ false1 = false
+ true2 = true
+ false2 = false
+[int]
+ int1 = 0
+ int2 = 1
+ int3 = -1
+EOF
+
+test_expect_success 'set --bool-or-int' '
+ git config --bool-or-int bool.true1 true &&
+ git config --bool-or-int bool.false1 false &&
+ git config --bool-or-int bool.true2 yes &&
+ git config --bool-or-int bool.false2 no &&
+ git config --bool-or-int int.int1 0 &&
+ git config --bool-or-int int.int2 1 &&
+ git config --bool-or-int int.int3 -1 &&
+ test_cmp expect .git/config
+'
+
+rm .git/config
+
git config quote.leading " test"
git config quote.ending "test "
git config quote.semicolon "test;test"
index 77c90f6fa002ce00c3ffb30d0b79adaff46b3caa..f15be93e7709acbb517bb85020d4d6b94a50f725 100755 (executable)
grep "unchanged *+3/-0 file" output
'
+test_expect_success 'patch does not affect mode' '
+ git reset --hard &&
+ echo content >>file &&
+ chmod +x file &&
+ printf "n\\ny\\n" | git add -p &&
+ git show :file | grep content &&
+ git diff file | grep "new mode"
+'
+
+test_expect_success 'stage mode but not hunk' '
+ git reset --hard &&
+ echo content >>file &&
+ chmod +x file &&
+ printf "y\\nn\\n" | git add -p &&
+ git diff --cached file | grep "new mode" &&
+ git diff file | grep "+content"
+'
+
+
test_done
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index c955fe44f5b962ef305e49c21bc3fb0e5b58d462..983a39398f17dc2b261771e780e8c010f038a12a 100755 (executable)
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
packname_4=$(git pack-objects test-4 <obj-list) &&
test 3 = $(ls test-4-*.pack | wc -l)'
+test_expect_success 'unpacking with --strict' '
+
+ git config --unset pack.packsizelimit &&
+ for j in a b c d e f g
+ do
+ for i in 0 1 2 3 4 5 6 7 8 9
+ do
+ o=$(echo $j$i | git hash-object -w --stdin) &&
+ echo "100644 $o 0 $j$i"
+ done
+ done >LIST &&
+ rm -f .git/index &&
+ git update-index --index-info <LIST &&
+ LIST=$(git write-tree) &&
+ rm -f .git/index &&
+ head -n 10 LIST | git update-index --index-info &&
+ LI=$(git write-tree) &&
+ rm -f .git/index &&
+ tail -n 10 LIST | git update-index --index-info &&
+ ST=$(git write-tree) &&
+ PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
+ git pack-objects test-5 ) &&
+ PACK6=$( (
+ echo "$LIST"
+ echo "$LI"
+ echo "$ST"
+ ) | git pack-objects test-6 ) &&
+ test_create_repo test-5 &&
+ (
+ cd test-5 &&
+ git unpack-objects --strict <../test-5-$PACK5.pack &&
+ git ls-tree -r $LIST &&
+ git ls-tree -r $LI &&
+ git ls-tree -r $ST
+ ) &&
+ test_create_repo test-6 &&
+ (
+ # tree-only into empty repo -- many unreachables
+ cd test-6 &&
+ test_must_fail git unpack-objects --strict <../test-6-$PACK6.pack
+ ) &&
+ (
+ # already populated -- no unreachables
+ cd test-5 &&
+ git unpack-objects --strict <../test-6-$PACK6.pack
+ )
+'
+
+test_expect_success 'index-pack with --strict' '
+
+ for j in a b c d e f g
+ do
+ for i in 0 1 2 3 4 5 6 7 8 9
+ do
+ o=$(echo $j$i | git hash-object -w --stdin) &&
+ echo "100644 $o 0 $j$i"
+ done
+ done >LIST &&
+ rm -f .git/index &&
+ git update-index --index-info <LIST &&
+ LIST=$(git write-tree) &&
+ rm -f .git/index &&
+ head -n 10 LIST | git update-index --index-info &&
+ LI=$(git write-tree) &&
+ rm -f .git/index &&
+ tail -n 10 LIST | git update-index --index-info &&
+ ST=$(git write-tree) &&
+ PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
+ git pack-objects test-5 ) &&
+ PACK6=$( (
+ echo "$LIST"
+ echo "$LI"
+ echo "$ST"
+ ) | git pack-objects test-6 ) &&
+ test_create_repo test-7 &&
+ (
+ cd test-7 &&
+ git index-pack --strict --stdin <../test-5-$PACK5.pack &&
+ git ls-tree -r $LIST &&
+ git ls-tree -r $LI &&
+ git ls-tree -r $ST
+ ) &&
+ test_create_repo test-8 &&
+ (
+ # tree-only into empty repo -- many unreachables
+ cd test-8 &&
+ test_must_fail git index-pack --strict --stdin <../test-6-$PACK6.pack
+ ) &&
+ (
+ # already populated -- no unreachables
+ cd test-7 &&
+ git index-pack --strict --stdin <../test-6-$PACK6.pack
+ )
+'
+
test_done
index 0de0efa2aa3b216a0bc846135a54ed0dd0549f8b..c20ac919bdbe73c8cd7657d468d2dfbccf6d3aa2 100644 (file)
--- a/var.c
+++ b/var.c
int main(int argc, char **argv)
{
const char *val;
+ int nongit;
if (argc != 2) {
usage(var_usage);
}
- setup_git_directory();
+ setup_git_directory_gently(&nongit);
val = NULL;
if (strcmp(argv[1], "-l") == 0) {