branch of the `git.git` repository.
Documentation for older releases are available here:
- * link:v2.4.10/git.html[documentation for release 2.4.10]
+* link:v2.5.4/git.html[documentation for release 2.5.4]
+
+* release notes for
+ link:RelNotes/2.5.4.txt[2.5.4],
+ link:RelNotes/2.5.3.txt[2.5.3],
+ link:RelNotes/2.5.2.txt[2.5.2],
+ link:RelNotes/2.5.1.txt[2.5.1],
+ link:RelNotes/2.5.0.txt[2.5].
+
+ * link:v2.4.11/git.html[documentation for release 2.4.11]
* release notes for
+ link:RelNotes/2.4.11.txt[2.4.11],
link:RelNotes/2.4.10.txt[2.4.10],
link:RelNotes/2.4.9.txt[2.4.9],
link:RelNotes/2.4.8.txt[2.4.8],
~~~~~~~~~~~~~~~~~~
These environment variables apply to 'all' core Git commands. Nb: it
is worth noting that they may be used/overridden by SCMS sitting above
-Git so take care if using Cogito etc.
+Git so take care if using a foreign front-end.
'GIT_INDEX_FILE'::
This environment allows the specification of an alternate
an explicit repository directory set via 'GIT_DIR' or on the
command line.
+'GIT_COMMON_DIR'::
+ If this variable is set to a path, non-worktree files that are
+ normally in $GIT_DIR will be taken from this path
+ instead. Worktree-specific files such as HEAD or index are
+ taken from $GIT_DIR. See linkgit:gitrepository-layout[5] and
+ linkgit:git-worktree[1] for
+ details. This variable has lower precedence than other path
+ variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY...
+
Git Commits
~~~~~~~~~~~
'GIT_AUTHOR_NAME'::
return WRITE_ONE_WRITTEN;
}
-static int mark_tagged(const char *path, const unsigned char *sha1, int flag,
+static int mark_tagged(const char *path, const struct object_id *oid, int flag,
void *cb_data)
{
unsigned char peeled[20];
- struct object_entry *entry = packlist_find(&to_pack, sha1, NULL);
+ struct object_entry *entry = packlist_find(&to_pack, oid->hash, NULL);
if (entry)
entry->tagged = 1;
#define ll_find_deltas(l, s, w, d, p) find_deltas(l, &s, w, d, p)
#endif
-static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int add_ref_tag(const char *path, const struct object_id *oid, int flag, void *cb_data)
{
- unsigned char peeled[20];
+ struct object_id peeled;
if (starts_with(path, "refs/tags/") && /* is a tag? */
- !peel_ref(path, peeled) && /* peelable? */
- packlist_find(&to_pack, peeled, NULL)) /* object packed? */
- add_object_entry(sha1, OBJ_TAG, NULL, 0);
+ !peel_ref(path, peeled.hash) && /* peelable? */
+ packlist_find(&to_pack, peeled.hash, NULL)) /* object packed? */
+ add_object_entry(oid->hash, OBJ_TAG, NULL, 0);
return 0;
}
index_commit_for_bitmap(commit);
}
- static void show_object(struct object *obj,
- const struct name_path *path, const char *last,
- void *data)
+ static void show_object(struct object *obj, const char *name, void *data)
{
- char *name = path_name(path, last);
-
add_preferred_base_object(name);
add_object_entry(obj->sha1, obj->type, name, 0);
obj->flags |= OBJECT_ADDED;
-
- /*
- * We will have generated the hash from the name,
- * but not saved a pointer to it - we can free it
- */
- free((char *)name);
}
static void show_edge(struct commit *commit)
}
static void record_recent_object(struct object *obj,
- const struct name_path *path,
- const char *last,
+ const char *name,
void *data)
{
sha1_array_append(&recent_objects, obj->sha1);
free_commit_buffer(commit);
}
- static void finish_object(struct object *obj,
- const struct name_path *path, const char *name,
- void *cb_data)
+ static void finish_object(struct object *obj, const char *name, void *cb_data)
{
struct rev_list_info *info = cb_data;
if (obj->type == OBJ_BLOB && !has_sha1_file(obj->sha1))
parse_object(obj->sha1);
}
- static void show_object(struct object *obj,
- const struct name_path *path, const char *component,
- void *cb_data)
+ static void show_object(struct object *obj, const char *name, void *cb_data)
{
struct rev_list_info *info = cb_data;
- finish_object(obj, path, component, cb_data);
+ finish_object(obj, name, cb_data);
if (info->flags & REV_LIST_QUIET)
return;
- show_object_with_name(stdout, obj, path, component);
+ show_object_with_name(stdout, obj, name);
}
static void show_edge(struct commit *commit)
revs.diff)
usage(rev_list_usage);
+ if (revs.show_notes)
+ die(_("rev-list does not support display of notes"));
+
save_commit_buffer = (revs.verbose_header ||
revs.grep_filter.pattern_list ||
revs.grep_filter.header_list);
#include "tree-walk.h"
#include "pathspec.h"
+#include "object.h"
struct rev_info;
struct diff_options;
int dirstat_permille;
int setup;
int abbrev;
+/* white-space error highlighting */
+#define WSEH_NEW 1
+#define WSEH_CONTEXT 2
+#define WSEH_OLD 4
+ unsigned ws_error_highlight;
const char *prefix;
int prefix_length;
const char *stat_sep;
struct combine_diff_path *next;
char *path;
unsigned int mode;
- unsigned char sha1[20];
+ struct object_id oid;
struct combine_diff_parent {
char status;
unsigned int mode;
- unsigned char sha1[20];
+ struct object_id oid;
} parent[FLEX_ARRAY];
};
#define combine_diff_path_size(n, l) \
- (sizeof(struct combine_diff_path) + \
- sizeof(struct combine_diff_parent) * (n) + (l) + 1)
+ st_add4(sizeof(struct combine_diff_path), (l), 1, \
+ st_mult(sizeof(struct combine_diff_parent), (n)))
extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
int dense, struct rev_info *);
#define unsigned_add_overflows(a, b) \
((b) > maximum_unsigned_value_of_type(a) - (a))
+ /*
+ * Returns true if the multiplication of "a" and "b" will
+ * overflow. The types of "a" and "b" must match and must be unsigned.
+ * Note that this macro evaluates "a" twice!
+ */
+ #define unsigned_mult_overflows(a, b) \
+ ((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
+
#ifdef __GNUC__
#define TYPEOF(x) (__typeof__(x))
#else
#elif defined(_MSC_VER)
#include "compat/msvc.h"
#else
+#include <sys/utsname.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/socket.h>
/* General helper functions */
extern void vreportf(const char *prefix, const char *err, va_list params);
-extern void vwritef(int fd, const char *prefix, const char *err, va_list params);
extern NORETURN void usage(const char *err);
extern NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
extern void set_error_routine(void (*routine)(const char *err, va_list params));
extern void set_die_is_recursing_routine(int (*routine)(void));
+extern void set_error_handle(FILE *);
extern int starts_with(const char *str, const char *prefix);
typedef void (*try_to_free_t)(size_t);
extern try_to_free_t set_try_to_free_routine(try_to_free_t);
+ static inline size_t st_add(size_t a, size_t b)
+ {
+ if (unsigned_add_overflows(a, b))
+ die("size_t overflow: %"PRIuMAX" + %"PRIuMAX,
+ (uintmax_t)a, (uintmax_t)b);
+ return a + b;
+ }
+ #define st_add3(a,b,c) st_add((a),st_add((b),(c)))
+ #define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d)))
+
+ static inline size_t st_mult(size_t a, size_t b)
+ {
+ if (unsigned_mult_overflows(a, b))
+ die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,
+ (uintmax_t)a, (uintmax_t)b);
+ return a * b;
+ }
+
+ static inline size_t st_sub(size_t a, size_t b)
+ {
+ if (a < b)
+ die("size_t underflow: %"PRIuMAX" - %"PRIuMAX,
+ (uintmax_t)a, (uintmax_t)b);
+ return a - b;
+ }
+
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
# define xalloca(size) (alloca(size))
# define SHELL_PATH "/bin/sh"
#endif
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#define flockfile(fh)
+#define funlockfile(fh)
+#define getc_unlocked(fh) getc(fh)
+#endif
+
#endif
display_progress(cp->progress, cp->count);
}
-static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int add_one_ref(const char *path, const struct object_id *oid,
+ int flag, void *cb_data)
{
- struct object *object = parse_object_or_die(sha1, path);
+ struct object *object = parse_object_or_die(oid->hash, path);
struct rev_info *revs = (struct rev_info *)cb_data;
add_pending_object(revs, object, "");
* The traversal will have already marked us as SEEN, so we
* only need to handle any progress reporting here.
*/
- static void mark_object(struct object *obj, const struct name_path *path,
- const char *name, void *data)
+ static void mark_object(struct object *obj, const char *name, void *data)
{
update_progress(data);
}
static void mark_commit(struct commit *c, void *data)
{
- mark_object(&c->object, NULL, NULL, data);
+ mark_object(&c->object, NULL, data);
}
struct recent_data {
volatile show_early_output_fn_t show_early_output;
- char *path_name(const struct name_path *path, const char *name)
+ void show_object_with_name(FILE *out, struct object *obj, const char *name)
{
- const struct name_path *p;
- char *n, *m;
- int nlen = strlen(name);
- int len = nlen + 1;
-
- for (p = path; p; p = p->up) {
- if (p->elem_len)
- len += p->elem_len + 1;
- }
- n = xmalloc(len);
- m = n + len - (nlen + 1);
- strcpy(m, name);
- for (p = path; p; p = p->up) {
- if (p->elem_len) {
- m -= p->elem_len + 1;
- memcpy(m, p->elem, p->elem_len);
- m[p->elem_len] = '/';
- }
- }
- return n;
- }
-
- static int show_path_component_truncated(FILE *out, const char *name, int len)
- {
- int cnt;
- for (cnt = 0; cnt < len; cnt++) {
- int ch = name[cnt];
- if (!ch || ch == '\n')
- return -1;
- fputc(ch, out);
- }
- return len;
- }
-
- static int show_path_truncated(FILE *out, const struct name_path *path)
- {
- int emitted, ours;
-
- if (!path)
- return 0;
- emitted = show_path_truncated(out, path->up);
- if (emitted < 0)
- return emitted;
- if (emitted)
- fputc('/', out);
- ours = show_path_component_truncated(out, path->elem, path->elem_len);
- if (ours < 0)
- return ours;
- return ours || emitted;
- }
-
- void show_object_with_name(FILE *out, struct object *obj,
- const struct name_path *path, const char *component)
- {
- struct name_path leaf;
- leaf.up = (struct name_path *)path;
- leaf.elem = component;
- leaf.elem_len = strlen(component);
+ const char *p;
fprintf(out, "%s ", sha1_to_hex(obj->sha1));
- show_path_truncated(out, &leaf);
+ for (p = name; *p && *p != '\n'; p++)
+ fputc(*p, out);
fputc('\n', out);
}
list = list->next;
if (commit->object.flags & UNINTERESTING)
continue;
- if (interesting_cache)
- *interesting_cache = commit;
+
+ *interesting_cache = commit;
return 0;
}
return 1;
return 0;
}
-static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int handle_one_ref(const char *path, const struct object_id *oid,
+ int flag, void *cb_data)
{
struct all_refs_cb *cb = cb_data;
struct object *object;
if (ref_excluded(cb->all_revs->ref_excludes, path))
return 0;
- object = get_reference(cb->all_revs, path, sha1, cb->all_flags);
+ object = get_reference(cb->all_revs, path, oid->hash, cb->all_flags);
add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags);
- add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags);
+ add_pending_sha1(cb->all_revs, path, oid->hash, cb->all_flags);
return 0;
}
return 0;
}
-static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int handle_one_reflog(const char *path, const struct object_id *oid,
+ int flag, void *cb_data)
{
struct all_refs_cb *cb = cb_data;
cb->warned_bad_reflog = 0;
void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
{
struct all_refs_cb cb;
+
cb.all_revs = revs;
cb.all_flags = flags;
for_each_reflog(handle_one_reflog, &cb);
return 1;
}
+static void NORETURN diagnose_missing_default(const char *def)
+{
+ unsigned char sha1[20];
+ int flags;
+ const char *refname;
+
+ refname = resolve_ref_unsafe(def, 0, sha1, &flags);
+ if (!refname || !(flags & REF_ISSYMREF) || (flags & REF_ISBROKEN))
+ die(_("your current branch appears to be broken"));
+
+ skip_prefix(refname, "refs/heads/", &refname);
+ die(_("your current branch '%s' does not have any commits yet"),
+ refname);
+}
+
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
struct object *object;
struct object_context oc;
if (get_sha1_with_context(revs->def, 0, sha1, &oc))
- die("bad default revision '%s'", revs->def);
+ diagnose_missing_default(revs->def);
object = get_reference(revs, revs->def, sha1, 0);
add_pending_object_with_mode(revs, object, revs->def, oc.mode);
}
{
struct combine_diff_parent *p0 = &p->parent[0];
if (p->mode && p0->mode) {
- opt->change(opt, p0->mode, p->mode, p0->sha1, p->sha1,
+ opt->change(opt, p0->mode, p->mode, p0->oid.hash, p->oid.hash,
1, 1, p->path, 0, 0);
}
else {
if (p->mode) {
addremove = '+';
- sha1 = p->sha1;
+ sha1 = p->oid.hash;
mode = p->mode;
} else {
addremove = '-';
- sha1 = p0->sha1;
+ sha1 = p0->oid.hash;
mode = p0->mode;
}
unsigned mode, const unsigned char *sha1)
{
struct combine_diff_path *p;
- int len = base->len + pathlen;
- int alloclen = combine_diff_path_size(nparent, len);
+ size_t len = st_add(base->len, pathlen);
+ size_t alloclen = combine_diff_path_size(nparent, len);
/* if last->next is !NULL - it is a pre-allocated memory, we can reuse */
p = last->next;
memcpy(p->path + base->len, path, pathlen);
p->path[len] = 0;
p->mode = mode;
- hashcpy(p->sha1, sha1 ? sha1 : null_sha1);
+ hashcpy(p->oid.hash, sha1 ? sha1 : null_sha1);
return p;
}
}
p->parent[i].mode = mode_i;
- hashcpy(p->parent[i].sha1, sha1_i ? sha1_i : null_sha1);
+ hashcpy(p->parent[i].oid.hash, sha1_i ? sha1_i : null_sha1);
}
keep = 1;