summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/branch.c2
-rw-r--r--builtin/checkout.c24
-rw-r--r--builtin/commit.c4
-rw-r--r--builtin/fetch.c56
-rw-r--r--builtin/for-each-ref.c77
-rw-r--r--builtin/grep.c3
-rw-r--r--builtin/hash-object.c8
-rw-r--r--builtin/init-db.c9
-rw-r--r--builtin/mailinfo.c3
-rw-r--r--builtin/pack-objects.c49
-rw-r--r--builtin/prune.c25
-rw-r--r--builtin/push.c2
-rw-r--r--builtin/reflog.c6
-rw-r--r--builtin/rev-list.c5
-rw-r--r--builtin/rev-parse.c11
-rw-r--r--builtin/send-pack.c191
-rw-r--r--builtin/shortlog.c19
-rw-r--r--builtin/show-branch.c4
-rw-r--r--builtin/var.c4
19 files changed, 174 insertions, 328 deletions
diff --git a/builtin/branch.c b/builtin/branch.c
index a28a139..6cf7e72 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -610,7 +610,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
BRANCH_TRACK_EXPLICIT),
OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
BRANCH_TRACK_OVERRIDE),
- OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
+ OPT__COLOR(&branch_use_color, "use colored output"),
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),
{
diff --git a/builtin/checkout.c b/builtin/checkout.c
index c5ab783..acefaaf 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -128,24 +128,6 @@ static int checkout_stage(int stage, struct cache_entry *ce, int pos,
(stage == 2) ? "our" : "their");
}
-/* NEEDSWORK: share with merge-recursive */
-static void fill_mm(const unsigned char *sha1, mmfile_t *mm)
-{
- unsigned long size;
- enum object_type type;
-
- if (!hashcmp(sha1, null_sha1)) {
- mm->ptr = xstrdup("");
- mm->size = 0;
- return;
- }
-
- mm->ptr = read_sha1_file(sha1, &type, &size);
- if (!mm->ptr || type != OBJ_BLOB)
- die("unable to read blob object %s", sha1_to_hex(sha1));
- mm->size = size;
-}
-
static int checkout_merged(int pos, struct checkout *state)
{
struct cache_entry *ce = active_cache[pos];
@@ -163,9 +145,9 @@ static int checkout_merged(int pos, struct checkout *state)
ce_stage(active_cache[pos+2]) != 3)
return error("path '%s' does not have all 3 versions", path);
- fill_mm(active_cache[pos]->sha1, &ancestor);
- fill_mm(active_cache[pos+1]->sha1, &ours);
- fill_mm(active_cache[pos+2]->sha1, &theirs);
+ read_mmblob(&ancestor, active_cache[pos]->sha1);
+ read_mmblob(&ours, active_cache[pos+1]->sha1);
+ read_mmblob(&theirs, active_cache[pos+2]->sha1);
status = ll_merge(&result_buf, path, &ancestor,
&ours, "ours", &theirs, "theirs", 0);
diff --git a/builtin/commit.c b/builtin/commit.c
index 55676fd..f4c7344 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -41,7 +41,7 @@ static const char implicit_ident_advice[] =
"on your username and hostname. Please check that they are accurate.\n"
"You can suppress this message by setting them explicitly:\n"
"\n"
-" git config --global user.name Your Name\n"
+" git config --global user.name \"Your Name\"\n"
" git config --global user.email you@example.com\n"
"\n"
"If the identity used for this commit is wrong, you can fix it with:\n"
@@ -1046,7 +1046,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (*argv)
s.pathspec = get_pathspec(prefix, argv);
- read_cache();
+ read_cache_preload(s.pathspec);
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
s.in_merge = in_merge;
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8654fa7..b6c5b34 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -11,6 +11,7 @@
#include "run-command.h"
#include "parse-options.h"
#include "sigchain.h"
+#include "transport.h"
static const char * const builtin_fetch_usage[] = {
"git fetch [options] [<repository> <refspec>...]",
@@ -205,7 +206,6 @@ static int s_update_ref(const char *action,
return 0;
}
-#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
#define REFCOL_WIDTH 10
static int update_local_ref(struct ref *ref,
@@ -224,7 +224,7 @@ static int update_local_ref(struct ref *ref,
if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
if (verbosity > 0)
- sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
+ sprintf(display, "= %-*s %-*s -> %s", TRANSPORT_SUMMARY_WIDTH,
"[up to date]", REFCOL_WIDTH, remote,
pretty_ref);
return 0;
@@ -239,7 +239,7 @@ static int update_local_ref(struct ref *ref,
* the head, and the old value of the head isn't empty...
*/
sprintf(display, "! %-*s %-*s -> %s (can't fetch in current branch)",
- SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
+ TRANSPORT_SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
pretty_ref);
return 1;
}
@@ -249,7 +249,7 @@ static int update_local_ref(struct ref *ref,
int r;
r = s_update_ref("updating tag", ref, 0);
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '-',
- SUMMARY_WIDTH, "[tag update]", REFCOL_WIDTH, remote,
+ TRANSPORT_SUMMARY_WIDTH, "[tag update]", REFCOL_WIDTH, remote,
pretty_ref, r ? " (unable to update local ref)" : "");
return r;
}
@@ -271,7 +271,7 @@ static int update_local_ref(struct ref *ref,
r = s_update_ref(msg, ref, 0);
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '*',
- SUMMARY_WIDTH, what, REFCOL_WIDTH, remote, pretty_ref,
+ TRANSPORT_SUMMARY_WIDTH, what, REFCOL_WIDTH, remote, pretty_ref,
r ? " (unable to update local ref)" : "");
return r;
}
@@ -284,7 +284,7 @@ static int update_local_ref(struct ref *ref,
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
r = s_update_ref("fast-forward", ref, 1);
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
- SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
+ TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
pretty_ref, r ? " (unable to update local ref)" : "");
return r;
} else if (force || ref->force) {
@@ -295,13 +295,13 @@ static int update_local_ref(struct ref *ref,
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
r = s_update_ref("forced-update", ref, 1);
sprintf(display, "%c %-*s %-*s -> %s (%s)", r ? '!' : '+',
- SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
+ TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
pretty_ref,
r ? "unable to update local ref" : "forced update");
return r;
} else {
sprintf(display, "! %-*s %-*s -> %s (non-fast-forward)",
- SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
+ TRANSPORT_SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
pretty_ref);
return 1;
}
@@ -393,7 +393,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
rc |= update_local_ref(ref, what, note);
else
sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
- SUMMARY_WIDTH, *kind ? kind : "branch",
+ TRANSPORT_SUMMARY_WIDTH, *kind ? kind : "branch",
REFCOL_WIDTH, *what ? what : "HEAD");
if (*note) {
if (verbosity >= 0 && !shown_url) {
@@ -514,7 +514,7 @@ static int prune_refs(struct transport *transport, struct ref *ref_map)
result |= delete_ref(ref->name, NULL, 0);
if (verbosity >= 0) {
fprintf(stderr, " x %-*s %-*s -> %s\n",
- SUMMARY_WIDTH, "[deleted]",
+ TRANSPORT_SUMMARY_WIDTH, "[deleted]",
REFCOL_WIDTH, "(none)", prettify_refname(ref->name));
warn_dangling_symref(stderr, dangling_msg, ref->name);
}
@@ -651,6 +651,17 @@ static void check_not_current_branch(struct ref *ref_map)
"of non-bare repository", current_branch->refname);
}
+static int truncate_fetch_head(void)
+{
+ char *filename = git_path("FETCH_HEAD");
+ FILE *fp = fopen(filename, "w");
+
+ if (!fp)
+ return error("cannot open %s: %s\n", filename, strerror(errno));
+ fclose(fp);
+ return 0;
+}
+
static int do_fetch(struct transport *transport,
struct refspec *refs, int ref_count)
{
@@ -672,11 +683,9 @@ static int do_fetch(struct transport *transport,
/* if not appending, truncate FETCH_HEAD */
if (!append && !dry_run) {
- char *filename = git_path("FETCH_HEAD");
- FILE *fp = fopen(filename, "w");
- if (!fp)
- return error("cannot open %s: %s\n", filename, strerror(errno));
- fclose(fp);
+ int errcode = truncate_fetch_head();
+ if (errcode)
+ return errcode;
}
ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
@@ -784,13 +793,19 @@ static int add_remote_or_group(const char *name, struct string_list *list)
static int fetch_multiple(struct string_list *list)
{
int i, result = 0;
- const char *argv[] = { "fetch", NULL, NULL, NULL, NULL, NULL, NULL };
- int argc = 1;
+ const char *argv[11] = { "fetch", "--append" };
+ int argc = 2;
if (dry_run)
argv[argc++] = "--dry-run";
if (prune)
argv[argc++] = "--prune";
+ if (update_head_ok)
+ argv[argc++] = "--update-head-ok";
+ if (force)
+ argv[argc++] = "--force";
+ if (keep)
+ argv[argc++] = "--keep";
if (verbosity >= 2)
argv[argc++] = "-v";
if (verbosity >= 1)
@@ -798,9 +813,16 @@ static int fetch_multiple(struct string_list *list)
else if (verbosity < 0)
argv[argc++] = "-q";
+ if (!append && !dry_run) {
+ int errcode = truncate_fetch_head();
+ if (errcode)
+ return errcode;
+ }
+
for (i = 0; i < list->nr; i++) {
const char *name = list->items[i].string;
argv[argc] = name;
+ argv[argc + 1] = NULL;
if (verbosity >= 0)
printf("Fetching %s\n", name);
if (run_command_v_opt(argv, RUN_GIT_CMD)) {
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index a5a83f1..62be1bb 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -33,6 +33,8 @@ struct ref_sort {
struct refinfo {
char *refname;
unsigned char objectname[20];
+ int flag;
+ const char *symref;
struct atom_value *value;
};
@@ -68,6 +70,8 @@ static struct {
{ "body" },
{ "contents" },
{ "upstream" },
+ { "symref" },
+ { "flag" },
};
/*
@@ -82,7 +86,7 @@ static struct {
*/
static const char **used_atom;
static cmp_type *used_atom_type;
-static int used_atom_cnt, sort_atom_limit, need_tagged;
+static int used_atom_cnt, sort_atom_limit, need_tagged, need_symref;
/*
* Used to parse format string and sort specifiers
@@ -133,6 +137,10 @@ static int parse_atom(const char *atom, const char *ep)
(sizeof(*used_atom_type) * used_atom_cnt));
used_atom[at] = xmemdupz(atom, ep - atom);
used_atom_type[at] = valid_atom[i].cmp_type;
+ if (*atom == '*')
+ need_tagged = 1;
+ if (!strcmp(used_atom[at], "symref"))
+ need_symref = 1;
return at;
}
@@ -143,7 +151,8 @@ static const char *find_next(const char *cp)
{
while (*cp) {
if (*cp == '%') {
- /* %( is the start of an atom;
+ /*
+ * %( is the start of an atom;
* %% is a quoted per-cent.
*/
if (cp[1] == '(')
@@ -420,7 +429,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru
grab_date(wholine, v, name);
}
- /* For a tag or a commit object, if "creator" or "creatordate" is
+ /*
+ * For a tag or a commit object, if "creator" or "creatordate" is
* requested, do something special.
*/
if (strcmp(who, "tagger") && strcmp(who, "committer"))
@@ -502,7 +512,8 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
}
}
-/* We want to have empty print-string for field requests
+/*
+ * We want to have empty print-string for field requests
* that do not apply (e.g. "authordate" for a tag object)
*/
static void fill_missing_values(struct atom_value *val)
@@ -548,6 +559,13 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, v
}
}
+static inline char *copy_advance(char *dst, const char *src)
+{
+ while (*src)
+ *dst++ = *src++;
+ return dst;
+}
+
/*
* Parse the object referred by ref, and grab needed value.
*/
@@ -561,6 +579,16 @@ static void populate_value(struct refinfo *ref)
ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
+ if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
+ unsigned char unused1[20];
+ const char *symref;
+ symref = resolve_ref(ref->refname, unused1, 1, NULL);
+ if (symref)
+ ref->symref = xstrdup(symref);
+ else
+ ref->symref = "";
+ }
+
/* Fill in specials first */
for (i = 0; i < used_atom_cnt; i++) {
const char *name = used_atom[i];
@@ -576,6 +604,8 @@ static void populate_value(struct refinfo *ref)
if (!prefixcmp(name, "refname"))
refname = ref->refname;
+ else if (!prefixcmp(name, "symref"))
+ refname = ref->symref ? ref->symref : "";
else if (!prefixcmp(name, "upstream")) {
struct branch *branch;
/* only local branches may have an upstream */
@@ -588,6 +618,20 @@ static void populate_value(struct refinfo *ref)
continue;
refname = branch->merge[0]->dst;
}
+ else if (!strcmp(name, "flag")) {
+ char buf[256], *cp = buf;
+ if (ref->flag & REF_ISSYMREF)
+ cp = copy_advance(cp, ",symref");
+ if (ref->flag & REF_ISPACKED)
+ cp = copy_advance(cp, ",packed");
+ if (cp == buf)
+ v->s = "";
+ else {
+ *cp = '\0';
+ v->s = xstrdup(buf + 1);
+ }
+ continue;
+ }
else
continue;
@@ -633,18 +677,21 @@ static void populate_value(struct refinfo *ref)
if (!eaten)
free(buf);
- /* If there is no atom that wants to know about tagged
+ /*
+ * If there is no atom that wants to know about tagged
* object, we are done.
*/
if (!need_tagged || (obj->type != OBJ_TAG))
return;
- /* If it is a tag object, see if we use a value that derefs
+ /*
+ * If it is a tag object, see if we use a value that derefs
* the object, and if we do grab the object it refers to.
*/
tagged = ((struct tag *)obj)->tagged->sha1;
- /* NEEDSWORK: This derefs tag only once, which
+ /*
+ * NEEDSWORK: This derefs tag only once, which
* is good to deal with chains of trust, but
* is not consistent with what deref_tag() does
* which peels the onion to the core.
@@ -681,9 +728,8 @@ struct grab_ref_cbdata {
};
/*
- * A call-back given to for_each_ref(). It is unfortunate that we
- * need to use global variables to pass extra information to this
- * function.
+ * A call-back given to for_each_ref(). Filter refs and keep them for
+ * later object processing.
*/
static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
@@ -711,13 +757,15 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
return 0;
}
- /* We do not open the object yet; sort may only need refname
+ /*
+ * We do not open the object yet; sort may only need refname
* to do its job and the resulting list may yet to be pruned
* by maxcount logic.
*/
ref = xcalloc(1, sizeof(*ref));
ref->refname = xstrdup(refname);
hashcpy(ref->objectname, sha1);
+ ref->flag = flag;
cnt = cb->grab_cnt;
cb->grab_array = xrealloc(cb->grab_array,
@@ -938,13 +986,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
refs = cbdata.grab_array;
num_refs = cbdata.grab_cnt;
- for (i = 0; i < used_atom_cnt; i++) {
- if (used_atom[i][0] == '*') {
- need_tagged = 1;
- break;
- }
- }
-
sort_refs(sort, refs, num_refs);
if (!maxcount || num_refs < maxcount)
diff --git a/builtin/grep.c b/builtin/grep.c
index 552ef1f..40b9a93 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -811,7 +811,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
"print NUL after filenames"),
OPT_BOOLEAN('c', "count", &opt.count,
"show the number of matches instead of matching lines"),
- OPT_SET_INT(0, "color", &opt.color, "highlight matches", 1),
+ OPT__COLOR(&opt.color, "highlight matches"),
OPT_GROUP(""),
OPT_CALLBACK('C', NULL, &opt, "n",
"show <n> context lines before and after matches",
@@ -868,6 +868,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
opt.relative = 1;
opt.pathname = 1;
opt.pattern_tail = &opt.pattern_list;
+ opt.header_tail = &opt.header_list;
opt.regflags = REG_NEWLINE;
opt.max_depth = -1;
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 6a5f5b5..080af1a 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -33,6 +33,8 @@ static void hash_object(const char *path, const char *type, int write_object,
hash_fd(fd, type, write_object, vpath);
}
+static int no_filters;
+
static void hash_stdin_paths(const char *type, int write_objects)
{
struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT;
@@ -44,7 +46,8 @@ static void hash_stdin_paths(const char *type, int write_objects)
die("line is badly quoted");
strbuf_swap(&buf, &nbuf);
}
- hash_object(buf.buf, type, write_objects, buf.buf);
+ hash_object(buf.buf, type, write_objects,
+ no_filters ? NULL : buf.buf);
}
strbuf_release(&buf);
strbuf_release(&nbuf);
@@ -60,7 +63,6 @@ static const char *type;
static int write_object;
static int hashstdin;
static int stdin_paths;
-static int no_filters;
static const char *vpath;
static const struct option hash_object_options[] = {
@@ -100,8 +102,6 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
errstr = "Can't specify files with --stdin-paths";
else if (vpath)
errstr = "Can't use --stdin-paths with --path";
- else if (no_filters)
- errstr = "Can't use --stdin-paths with --no-filters";
}
else {
if (hashstdin > 1)
diff --git a/builtin/init-db.c b/builtin/init-db.c
index dd84cae..aae7a4d 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -331,11 +331,14 @@ int init_db(const char *template_dir, unsigned int flags)
git_config_set("receive.denyNonFastforwards", "true");
}
- if (!(flags & INIT_DB_QUIET))
- printf("%s%s Git repository in %s/\n",
+ if (!(flags & INIT_DB_QUIET)) {
+ const char *git_dir = get_git_dir();
+ int len = strlen(git_dir);
+ printf("%s%s Git repository in %s%s\n",
reinit ? "Reinitialized existing" : "Initialized empty",
shared_repository ? " shared" : "",
- get_git_dir());
+ git_dir, len && git_dir[len-1] != '/' ? "/" : "");
+ }
return 0;
}
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index a50ac22..ce2ef6b 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -779,8 +779,7 @@ static int handle_commit_msg(struct strbuf *line)
return 0;
if (still_looking) {
- strbuf_ltrim(line);
- if (!line->len)
+ if (!line->len || (line->len == 1 && line->buf[0] == '\n'))
return 0;
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index e1d3adf..9780258 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -155,33 +155,6 @@ static unsigned long do_compress(void **pptr, unsigned long size)
}
/*
- * The per-object header is a pretty dense thing, which is
- * - first byte: low four bits are "size", then three bits of "type",
- * and the high bit is "size continues".
- * - each byte afterwards: low seven bits are size continuation,
- * with the high bit being "size continues"
- */
-static int encode_header(enum object_type type, unsigned long size, unsigned char *hdr)
-{
- int n = 1;
- unsigned char c;
-
- if (type < OBJ_COMMIT || type > OBJ_REF_DELTA)
- die("bad type %d", type);
-
- c = (type << 4) | (size & 15);
- size >>= 4;
- while (size) {
- *hdr++ = c | 0x80;
- c = size & 0x7f;
- size >>= 7;
- n++;
- }
- *hdr = c;
- return n;
-}
-
-/*
* we are going to reuse the existing object data as is. make
* sure it is not corrupt.
*/
@@ -321,7 +294,7 @@ static unsigned long write_object(struct sha1file *f,
* The object header is a byte of 'type' followed by zero or
* more bytes of length.
*/
- hdrlen = encode_header(type, size, header);
+ hdrlen = encode_in_pack_object_header(type, size, header);
if (type == OBJ_OFS_DELTA) {
/*
@@ -372,7 +345,7 @@ static unsigned long write_object(struct sha1file *f,
if (entry->delta)
type = (allow_ofs_delta && entry->delta->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
- hdrlen = encode_header(type, entry->size, header);
+ hdrlen = encode_in_pack_object_header(type, entry->size, header);
offset = entry->in_pack_offset;
revidx = find_pack_revindex(p, offset);
@@ -464,9 +437,6 @@ static int write_one(struct sha1file *f,
return 1;
}
-/* forward declaration for write_pack_file */
-static int adjust_perm(const char *path, mode_t mode);
-
static void write_pack_file(void)
{
uint32_t i = 0, j;
@@ -523,21 +493,17 @@ static void write_pack_file(void)
}
if (!pack_to_stdout) {
- mode_t mode = umask(0);
struct stat st;
const char *idx_tmp_name;
char tmpname[PATH_MAX];
- umask(mode);
- mode = 0444 & ~mode;
-
idx_tmp_name = write_idx_file(NULL, written_list,
nr_written, sha1);
snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
base_name, sha1_to_hex(sha1));
free_pack_by_name(tmpname);
- if (adjust_perm(pack_tmp_name, mode))
+ if (adjust_shared_perm(pack_tmp_name))
die_errno("unable to make temporary pack file readable");
if (rename(pack_tmp_name, tmpname))
die_errno("unable to rename temporary pack file");
@@ -565,7 +531,7 @@ static void write_pack_file(void)
snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
base_name, sha1_to_hex(sha1));
- if (adjust_perm(idx_tmp_name, mode))
+ if (adjust_shared_perm(idx_tmp_name))
die_errno("unable to make temporary index file readable");
if (rename(idx_tmp_name, tmpname))
die_errno("unable to rename temporary index file");
@@ -2125,13 +2091,6 @@ static void get_object_list(int ac, const char **av)
loosen_unused_packed_objects(&revs);
}
-static int adjust_perm(const char *path, mode_t mode)
-{
- if (chmod(path, mode))
- return -1;
- return adjust_shared_perm(path);
-}
-
int cmd_pack_objects(int argc, const char **argv, const char *prefix)
{
int use_internal_rev_list = 0;
diff --git a/builtin/prune.c b/builtin/prune.c
index 4675f60..81f915ec 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -18,13 +18,11 @@ static unsigned long expire;
static int prune_tmp_object(const char *path, const char *filename)
{
const char *fullpath = mkpath("%s/%s", path, filename);
- if (expire) {
- struct stat st;
- if (lstat(fullpath, &st))
- return error("Could not stat '%s'", fullpath);
- if (st.st_mtime > expire)
- return 0;
- }
+ struct stat st;
+ if (lstat(fullpath, &st))
+ return error("Could not stat '%s'", fullpath);
+ if (st.st_mtime > expire)
+ return 0;
printf("Removing stale temporary file %s\n", fullpath);
if (!show_only)
unlink_or_warn(fullpath);
@@ -34,13 +32,11 @@ static int prune_tmp_object(const char *path, const char *filename)
static int prune_object(char *path, const char *filename, const unsigned char *sha1)
{
const char *fullpath = mkpath("%s/%s", path, filename);
- if (expire) {
- struct stat st;
- if (lstat(fullpath, &st))
- return error("Could not stat '%s'", fullpath);
- if (st.st_mtime > expire)
- return 0;
- }
+ struct stat st;
+ if (lstat(fullpath, &st))
+ return error("Could not stat '%s'", fullpath);
+ if (st.st_mtime > expire)
+ return 0;
if (show_only || verbose) {
enum object_type type = sha1_object_info(sha1, NULL);
printf("%s %s\n", sha1_to_hex(sha1),
@@ -139,6 +135,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
};
char *s;
+ expire = ULONG_MAX;
save_commit_buffer = 0;
read_replace_refs = 0;
init_revisions(&revs, prefix);
diff --git a/builtin/push.c b/builtin/push.c
index 5633f0a..f7bc2b2 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -68,7 +68,7 @@ static void setup_push_tracking(void)
struct branch *branch = branch_get(NULL);
if (!branch)
die("You are not currently on a branch.");
- if (!branch->merge_nr)
+ if (!branch->merge_nr || !branch->merge)
die("The current branch %s is not tracking anything.",
branch->name);
if (branch->merge_nr != 1)
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 7498210..64e45bd 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -530,16 +530,14 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
int i, status, do_all;
int explicit_expiry = 0;
+ default_reflog_expire_unreachable = now - 30 * 24 * 3600;
+ default_reflog_expire = now - 90 * 24 * 3600;
git_config(reflog_expire_config, NULL);
save_commit_buffer = 0;
do_all = status = 0;
memset(&cb, 0, sizeof(cb));
- if (!default_reflog_expire_unreachable)
- default_reflog_expire_unreachable = now - 30 * 24 * 3600;
- if (!default_reflog_expire)
- default_reflog_expire = now - 90 * 24 * 3600;
cb.expire_total = default_reflog_expire;
cb.expire_unreachable = default_reflog_expire_unreachable;
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index c924b3a..5679170 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -371,8 +371,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
revs.diff)
usage(rev_list_usage);
- save_commit_buffer = revs.verbose_header ||
- revs.grep_filter.pattern_list;
+ save_commit_buffer = (revs.verbose_header ||
+ revs.grep_filter.pattern_list ||
+ revs.grep_filter.header_list);
if (bisect_list)
revs.limited = 1;
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index a8c5043..8fbf9d0 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -455,6 +455,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (argc > 1 && !strcmp("--sq-quote", argv[1]))
return cmd_sq_quote(argc - 2, argv + 2);
+ if (argc == 2 && !strcmp("--local-env-vars", argv[1])) {
+ int i;
+ for (i = 0; local_repo_env[i]; i++)
+ printf("%s\n", local_repo_env[i]);
+ return 0;
+ }
+
if (argc > 1 && !strcmp("-h", argv[1]))
usage(builtin_rev_parse_usage);
@@ -637,6 +644,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!strcmp(arg, "--git-dir")) {
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
static char cwd[PATH_MAX];
+ int len;
if (gitdir) {
puts(gitdir);
continue;
@@ -647,7 +655,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!getcwd(cwd, PATH_MAX))
die_errno("unable to get current working directory");
- printf("%s/.git\n", cwd);
+ len = strlen(cwd);
+ printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
continue;
}
if (!strcmp(arg, "--is-inside-git-dir")) {
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 2183a47..6019eac 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -7,6 +7,7 @@
#include "remote.h"
#include "send-pack.h"
#include "quote.h"
+#include "transport.h"
static const char send_pack_usage[] =
"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -169,156 +170,6 @@ static int receive_status(int in, struct ref *refs)
return ret;
}
-static void update_tracking_ref(struct remote *remote, struct ref *ref)
-{
- struct refspec rs;
-
- if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
- return;
-
- rs.src = ref->name;
- rs.dst = NULL;
-
- if (!remote_find_tracking(remote, &rs)) {
- if (args.verbose)
- fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
- if (ref->deletion) {
- delete_ref(rs.dst, NULL, 0);
- } else
- update_ref("update by push", rs.dst,
- ref->new_sha1, NULL, 0, 0);
- free(rs.dst);
- }
-}
-
-#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
-
-static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg)
-{
- fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
- if (from)
- fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
- else
- fputs(prettify_refname(to->name), stderr);
- if (msg) {
- fputs(" (", stderr);
- fputs(msg, stderr);
- fputc(')', stderr);
- }
- fputc('\n', stderr);
-}
-
-static const char *status_abbrev(unsigned char sha1[20])
-{
- return find_unique_abbrev(sha1, DEFAULT_ABBREV);
-}
-
-static void print_ok_ref_status(struct ref *ref)
-{
- if (ref->deletion)
- print_ref_status('-', "[deleted]", ref, NULL, NULL);
- else if (is_null_sha1(ref->old_sha1))
- print_ref_status('*',
- (!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
- "[new branch]"),
- ref, ref->peer_ref, NULL);
- else {
- char quickref[84];
- char type;
- const char *msg;
-
- strcpy(quickref, status_abbrev(ref->old_sha1));
- if (ref->nonfastforward) {
- strcat(quickref, "...");
- type = '+';
- msg = "forced update";
- } else {
- strcat(quickref, "..");
- type = ' ';
- msg = NULL;
- }
- strcat(quickref, status_abbrev(ref->new_sha1));
-
- print_ref_status(type, quickref, ref, ref->peer_ref, msg);
- }
-}
-
-static int print_one_push_status(struct ref *ref, const char *dest, int count)
-{
- if (!count)
- fprintf(stderr, "To %s\n", dest);
-
- switch(ref->status) {
- case REF_STATUS_NONE:
- print_ref_status('X', "[no match]", ref, NULL, NULL);
- break;
- case REF_STATUS_REJECT_NODELETE:
- print_ref_status('!', "[rejected]", ref, NULL,
- "remote does not support deleting refs");
- break;
- case REF_STATUS_UPTODATE:
- print_ref_status('=', "[up to date]", ref,
- ref->peer_ref, NULL);
- break;
- case REF_STATUS_REJECT_NONFASTFORWARD:
- print_ref_status('!', "[rejected]", ref, ref->peer_ref,
- "non-fast-forward");
- break;
- case REF_STATUS_REMOTE_REJECT:
- print_ref_status('!', "[remote rejected]", ref,
- ref->deletion ? NULL : ref->peer_ref,
- ref->remote_status);
- break;
- case REF_STATUS_EXPECTING_REPORT:
- print_ref_status('!', "[remote failure]", ref,
- ref->deletion ? NULL : ref->peer_ref,
- "remote failed to report status");
- break;
- case REF_STATUS_OK:
- print_ok_ref_status(ref);
- break;
- }
-
- return 1;
-}
-
-static void print_push_status(const char *dest, struct ref *refs)
-{
- struct ref *ref;
- int n = 0;
-
- if (args.verbose) {
- for (ref = refs; ref; ref = ref->next)
- if (ref->status == REF_STATUS_UPTODATE)
- n += print_one_push_status(ref, dest, n);
- }
-
- for (ref = refs; ref; ref = ref->next)
- if (ref->status == REF_STATUS_OK)
- n += print_one_push_status(ref, dest, n);
-
- for (ref = refs; ref; ref = ref->next) {
- if (ref->status != REF_STATUS_NONE &&
- ref->status != REF_STATUS_UPTODATE &&
- ref->status != REF_STATUS_OK)
- n += print_one_push_status(ref, dest, n);
- }
-}
-
-static int refs_pushed(struct ref *ref)
-{
- for (; ref; ref = ref->next) {
- switch(ref->status) {
- case REF_STATUS_NONE:
- case REF_STATUS_UPTODATE:
- break;
- default:
- return 1;
- }
- }
- return 0;
-}
-
static void print_helper_status(struct ref *ref)
{
struct strbuf buf = STRBUF_INIT;
@@ -523,37 +374,6 @@ int send_pack(struct send_pack_args *args,
return 0;
}
-static void verify_remote_names(int nr_heads, const char **heads)
-{
- int i;
-
- for (i = 0; i < nr_heads; i++) {
- const char *local = heads[i];
- const char *remote = strrchr(heads[i], ':');
-
- if (*local == '+')
- local++;
-
- /* A matching refspec is okay. */
- if (remote == local && remote[1] == '\0')
- continue;
-
- remote = remote ? (remote + 1) : local;
- switch (check_ref_format(remote)) {
- case 0: /* ok */
- case CHECK_REF_FORMAT_ONELEVEL:
- /* ok but a single level -- that is fine for
- * a match pattern.
- */
- case CHECK_REF_FORMAT_WILDCARD:
- /* ok but ends with a pattern-match character */
- continue;
- }
- die("remote part of refspec is not a valid name in %s",
- heads[i]);
- }
-}
-
int cmd_send_pack(int argc, const char **argv, const char *prefix)
{
int i, nr_refspecs = 0;
@@ -570,6 +390,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
int send_all = 0;
const char *receivepack = "git-receive-pack";
int flags;
+ int nonfastforward = 0;
argv++;
for (i = 1; i < argc; i++, argv++) {
@@ -662,7 +483,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
get_remote_heads(fd[0], &remote_refs, 0, NULL, REF_NORMAL,
&extra_have);
- verify_remote_names(nr_refspecs, refspecs);
+ transport_verify_remote_names(nr_refspecs, refspecs);
local_refs = get_local_heads();
@@ -691,15 +512,15 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
ret |= finish_connect(conn);
if (!helper_status)
- print_push_status(dest, remote_refs);
+ transport_print_push_status(dest, remote_refs, args.verbose, 0, &nonfastforward);
if (!args.dry_run && remote) {
struct ref *ref;
for (ref = remote_refs; ref; ref = ref->next)
- update_tracking_ref(remote, ref);
+ transport_update_tracking_ref(remote, ref, args.verbose);
}
- if (!ret && !refs_pushed(remote_refs))
+ if (!ret && !transport_refs_pushed(remote_refs))
fprintf(stderr, "Everything up-to-date\n");
return ret;
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index b3b055f..06320f5 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -295,6 +295,8 @@ parse_done:
if (!nongit && !rev.pending.nr && isatty(0))
add_head_to_pending(&rev);
if (rev.pending.nr == 0) {
+ if (isatty(0))
+ fprintf(stderr, "(reading log message from standard input)\n");
read_from_stdin(&log);
}
else
@@ -304,9 +306,19 @@ parse_done:
return 0;
}
+static void add_wrapped_shortlog_msg(struct strbuf *sb, const char *s,
+ const struct shortlog *log)
+{
+ int col = strbuf_add_wrapped_text(sb, s, log->in1, log->in2, log->wrap);
+ if (col != log->wrap)
+ strbuf_addch(sb, '\n');
+}
+
void shortlog_output(struct shortlog *log)
{
int i, j;
+ struct strbuf sb = STRBUF_INIT;
+
if (log->sort_by_number)
qsort(log->list.items, log->list.nr, sizeof(struct string_list_item),
compare_by_number);
@@ -321,9 +333,9 @@ void shortlog_output(struct shortlog *log)
const char *msg = onelines->items[j].string;
if (log->wrap_lines) {
- int col = print_wrapped_text(msg, log->in1, log->in2, log->wrap);
- if (col != log->wrap)
- putchar('\n');
+ strbuf_reset(&sb);
+ add_wrapped_shortlog_msg(&sb, msg, log);
+ fwrite(sb.buf, sb.len, 1, stdout);
}
else
printf(" %s\n", msg);
@@ -337,6 +349,7 @@ void shortlog_output(struct shortlog *log)
log->list.items[i].util = NULL;
}
+ strbuf_release(&sb);
log->list.strdup_strings = 1;
string_list_clear(&log->list, 1);
clear_mailmap(&log->mailmap);
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 35a709e..e20fcf3 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -6,7 +6,7 @@
#include "parse-options.h"
static const char* show_branch_usage[] = {
- "git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [<rev> | <glob>]...",
+ "git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [<rev> | <glob>]...",
"git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]",
NULL
};
@@ -661,7 +661,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
"show remote-tracking and local branches"),
OPT_BOOLEAN('r', "remotes", &all_remotes,
"show remote-tracking branches"),
- OPT_BOOLEAN(0, "color", &showbranch_use_color,
+ OPT__COLOR(&showbranch_use_color,
"color '*!+-' corresponding to the branch"),
{ OPTION_INTEGER, 0, "more", &extra, "n",
"show <n> more commits after the common ancestor",
diff --git a/builtin/var.c b/builtin/var.c
index 2280518..70fdb4d 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -6,7 +6,7 @@
#include "cache.h"
#include "exec_cmd.h"
-static const char var_usage[] = "git var [-l | <variable>]";
+static const char var_usage[] = "git var (-l | <variable>)";
static const char *editor(int flag)
{
@@ -20,7 +20,7 @@ static const char *editor(int flag)
static const char *pager(int flag)
{
- const char *pgm = git_pager();
+ const char *pgm = git_pager(1);
if (!pgm)
pgm = "cat";