branch of the `git.git` repository.
Documentation for older releases are available here:
- * link:v2.2.2/git.html[documentation for release 2.2.2]
+* link:v2.3.8/git.html[documentation for release 2.3.8]
+
+* release notes for
+ link:RelNotes/2.3.8.txt[2.3.8],
+ link:RelNotes/2.3.7.txt[2.3.7],
+ link:RelNotes/2.3.6.txt[2.3.6],
+ link:RelNotes/2.3.5.txt[2.3.5],
+ link:RelNotes/2.3.4.txt[2.3.4],
+ link:RelNotes/2.3.3.txt[2.3.3],
+ link:RelNotes/2.3.2.txt[2.3.2],
+ link:RelNotes/2.3.1.txt[2.3.1],
+ link:RelNotes/2.3.0.txt[2.3].
+
+ * link:v2.2.3/git.html[documentation for release 2.2.3]
* release notes for
+ link:RelNotes/2.2.3.txt[2.2.3],
link:RelNotes/2.2.2.txt[2.2.2],
link:RelNotes/2.2.1.txt[2.2.1],
link:RelNotes/2.2.0.txt[2.2].
'GIT_INDEX_VERSION'::
This environment variable allows the specification of an index
version for new repositories. It won't affect existing index
- files. By default index file version [23] is used.
+ files. By default index file version 2 or 3 is used. See
+ linkgit:git-update-index[1] for more information.
'GIT_OBJECT_DIRECTORY'::
If the object storage directory is specified via this
and the `core.editor` option in linkgit:git-config[1].
'GIT_SSH'::
- If this environment variable is set then 'git fetch'
- and 'git push' will use this command instead
- of 'ssh' when they need to connect to a remote system.
- The '$GIT_SSH' command will be given exactly two or
- four arguments: the 'username@host' (or just 'host')
- from the URL and the shell command to execute on that
- remote system, optionally preceded by '-p' (literally) and
- the 'port' from the URL when it specifies something other
- than the default SSH port.
+'GIT_SSH_COMMAND'::
+ If either of these environment variables is set then 'git fetch'
+ and 'git push' will use the specified command instead of 'ssh'
+ when they need to connect to a remote system.
+ The command will be given exactly two or four arguments: the
+ 'username@host' (or just 'host') from the URL and the shell
+ command to execute on that remote system, optionally preceded by
+ '-p' (literally) and the 'port' from the URL when it specifies
+ something other than the default SSH port.
+
-To pass options to the program that you want to list in GIT_SSH
-you will need to wrap the program and options into a shell script,
-then set GIT_SSH to refer to the shell script.
+`$GIT_SSH_COMMAND` takes precedence over `$GIT_SSH`, and is interpreted
+by the shell, which allows additional arguments to be included.
+`$GIT_SSH` on the other hand must be just the path to a program
+(which can be a wrapper shell script, if additional arguments are
+needed).
+
Usually it is easier to configure any desired options through your
personal `.ssh/config` file. Please consult your ssh documentation
and read the password from its STDOUT. See also the 'core.askpass'
option in linkgit:git-config[1].
+'GIT_TERMINAL_PROMPT'::
+ If this environment variable is set to `0`, git will not prompt
+ on the terminal (e.g., when asking for HTTP authentication).
+
'GIT_CONFIG_NOSYSTEM'::
Whether to skip reading settings from the system-wide
`$(prefix)/etc/gitconfig` file. This environment variable can
variable when it is invoked as the top level command by the
end user, to be recorded in the body of the reflog.
+`GIT_REF_PARANOIA`::
+ If set to `1`, include broken or badly named refs when iterating
+ over lists of refs. In a normal, non-corrupted repository, this
+ does nothing. However, enabling it may help git to detect and
+ abort some operations in the presence of broken refs. Git sets
+ this variable automatically when performing destructive
+ operations like linkgit:git-prune[1]. You should not need to set
+ it yourself unless you want to be paranoid about making sure
+ an operation has touched every ref (e.g., because you are
+ cloning a repository to make a backup).
+
Discussion[[Discussion]]
------------------------
#include "parse-options.h"
static const char* show_branch_usage[] = {
- N_("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>)...]"),
+ N_("git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order]\n"
+ " [--current] [--color[=<when>] | --no-color] [--sparse]\n"
+ " [--more=<n> | --list | --independent | --merge-base]\n"
+ " [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]"),
N_("git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]"),
NULL
};
if (reflog) {
unsigned char sha1[20];
- char nth_desc[256];
char *ref;
int base = 0;
unsigned int flags = 0;
for (i = 0; i < reflog; i++) {
char *logmsg;
+ char *nth_desc;
const char *msg;
unsigned long timestamp;
int tz;
show_date(timestamp, tz, 1),
msg);
free(logmsg);
- sprintf(nth_desc, "%s@{%d}", *av, base+i);
+
+ nth_desc = xstrfmt("%s@{%d}", *av, base+i);
append_ref(nth_desc, sha1, 1);
+ free(nth_desc);
}
free(ref);
}
return strcmp(a->path, b->path);
}
- static void add_non_note(struct notes_tree *t, const char *path,
+ /* note: takes ownership of path string */
+ static void add_non_note(struct notes_tree *t, char *path,
unsigned int mode, const unsigned char *sha1)
{
struct non_note *p = t->prev_non_note, *n;
n = (struct non_note *) xmalloc(sizeof(struct non_note));
n->next = NULL;
- n->path = xstrdup(path);
+ n->path = path;
n->mode = mode;
hashcpy(n->sha1, sha1);
t->prev_non_note = n;
* component.
*/
{
- char non_note_path[PATH_MAX];
- char *p = non_note_path;
+ struct strbuf non_note_path = STRBUF_INIT;
const char *q = sha1_to_hex(subtree->key_sha1);
int i;
for (i = 0; i < prefix_len; i++) {
- *p++ = *q++;
- *p++ = *q++;
- *p++ = '/';
+ strbuf_addch(&non_note_path, *q++);
+ strbuf_addch(&non_note_path, *q++);
+ strbuf_addch(&non_note_path, '/');
}
- strcpy(p, entry.path);
- add_non_note(t, non_note_path, entry.mode, entry.sha1);
+ strbuf_addstr(&non_note_path, entry.path);
+ add_non_note(t, strbuf_detach(&non_note_path, NULL),
+ entry.mode, entry.sha1);
}
}
free(buf);
if (string_list_add_note_lines(&sort_uniq_list, new_sha1))
goto out;
string_list_remove_empty_items(&sort_uniq_list, 0);
- sort_string_list(&sort_uniq_list);
+ string_list_sort(&sort_uniq_list);
string_list_remove_duplicates(&sort_uniq_list, 0);
/* create a new blob object from sort_uniq_list */
t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node));
t->first_non_note = NULL;
t->prev_non_note = NULL;
- t->ref = notes_ref ? xstrdup(notes_ref) : NULL;
+ t->ref = xstrdup_or_null(notes_ref);
t->combine_notes = combine_notes;
t->initialized = 1;
t->dirty = 0;
if (!sha1)
return;
- if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||
- type != OBJ_BLOB) {
+ if (!(msg = read_sha1_file(sha1, &type, &msglen)) || type != OBJ_BLOB) {
free(msg);
return;
}
char *map;
size_t mapsz;
struct stat st;
- const char alt_file_name[] = "info/alternates";
- /* Given that relative_base is no longer than PATH_MAX,
- ensure that "path" has enough space to append "/", the
- file name, "info/alternates", and a trailing NUL. */
- char path[PATH_MAX + 1 + sizeof alt_file_name];
+ char *path;
int fd;
- sprintf(path, "%s/%s", relative_base, alt_file_name);
+ path = xstrfmt("%s/info/alternates", relative_base);
fd = git_open_noatime(path);
+ free(path);
if (fd < 0)
return;
if (fstat(fd, &st) || (st.st_size == 0)) {
if (!report_garbage)
return;
- sort_string_list(list);
+ string_list_sort(list);
for (i = 0; i < list->nr; i++) {
const char *path = list->items[i].string;
}
/* Set it up */
- memset(&stream, 0, sizeof(stream));
git_deflate_init(&stream, zlib_compression_level);
stream.next_out = compressed;
stream.avail_out = sizeof(compressed);
return r;
}
-int for_each_loose_file_in_objdir(const char *path,
+int for_each_loose_file_in_objdir_buf(struct strbuf *path,
each_loose_object_fn obj_cb,
each_loose_cruft_fn cruft_cb,
each_loose_subdir_fn subdir_cb,
void *data)
{
- struct strbuf buf = STRBUF_INIT;
- size_t baselen;
+ size_t baselen = path->len;
int r = 0;
int i;
- strbuf_addstr(&buf, path);
- strbuf_addch(&buf, '/');
- baselen = buf.len;
-
for (i = 0; i < 256; i++) {
- strbuf_addf(&buf, "%02x", i);
- r = for_each_file_in_obj_subdir(i, &buf, obj_cb, cruft_cb,
+ strbuf_addf(path, "/%02x", i);
+ r = for_each_file_in_obj_subdir(i, path, obj_cb, cruft_cb,
subdir_cb, data);
- strbuf_setlen(&buf, baselen);
+ strbuf_setlen(path, baselen);
if (r)
break;
}
+ return r;
+}
+
+int for_each_loose_file_in_objdir(const char *path,
+ each_loose_object_fn obj_cb,
+ each_loose_cruft_fn cruft_cb,
+ each_loose_subdir_fn subdir_cb,
+ void *data)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int r;
+
+ strbuf_addstr(&buf, path);
+ r = for_each_loose_file_in_objdir_buf(&buf, obj_cb, cruft_cb,
+ subdir_cb, data);
strbuf_release(&buf);
+
return r;
}
void *vdata)
{
struct loose_alt_odb_data *data = vdata;
- return for_each_loose_file_in_objdir(alt->base,
- data->cb, NULL, NULL,
- data->data);
+ struct strbuf buf = STRBUF_INIT;
+ int r;
+
+ /* copy base not including trailing '/' */
+ strbuf_add(&buf, alt->base, alt->name - alt->base - 1);
+ r = for_each_loose_file_in_objdir_buf(&buf,
+ data->cb, NULL, NULL,
+ data->data);
+ strbuf_release(&buf);
+ return r;
}
int for_each_loose_object(each_loose_object_fn cb, void *data)
if (o->dst_index) {
discard_index(o->dst_index);
*o->dst_index = o->result;
+ } else {
+ discard_index(&o->result);
}
done:
if (!len)
return 0;
else if (len > 0) {
- char path[PATH_MAX + 1];
- memcpy(path, ce->name, len);
- path[len] = 0;
+ char *path;
+ int ret;
+
+ path = xmemdupz(ce->name, len);
if (lstat(path, &st))
- return error("cannot stat '%s': %s", path,
+ ret = error("cannot stat '%s': %s", path,
strerror(errno));
-
- return check_ok_to_remove(path, len, DT_UNKNOWN, NULL, &st,
- error_type, o);
+ else
+ ret = check_ok_to_remove(path, len, DT_UNKNOWN, NULL,
+ &st, error_type, o);
+ free(path);
+ return ret;
} else if (lstat(ce->name, &st)) {
if (errno != ENOENT)
return error("cannot stat '%s': %s", ce->name,