summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c210
-rw-r--r--builtin/apply.c199
-rw-r--r--builtin/blame.c1013
-rw-r--r--builtin/branch.c12
-rw-r--r--builtin/cat-file.c15
-rw-r--r--builtin/checkout-index.c4
-rw-r--r--builtin/checkout.c34
-rw-r--r--builtin/clean.c8
-rw-r--r--builtin/clone.c63
-rw-r--r--builtin/commit-tree.c16
-rw-r--r--builtin/commit.c363
-rw-r--r--builtin/config.c149
-rw-r--r--builtin/describe.c54
-rw-r--r--builtin/diff-tree.c12
-rw-r--r--builtin/fast-export.c354
-rw-r--r--builtin/fetch.c56
-rw-r--r--builtin/fmt-merge-msg.c22
-rw-r--r--builtin/for-each-ref.c22
-rw-r--r--builtin/fsck.c16
-rw-r--r--builtin/gc.c95
-rw-r--r--builtin/grep.c7
-rw-r--r--builtin/help.c3
-rw-r--r--builtin/index-pack.c106
-rw-r--r--builtin/init-db.c40
-rw-r--r--builtin/log.c74
-rw-r--r--builtin/ls-files.c2
-rw-r--r--builtin/ls-remote.c4
-rw-r--r--builtin/mailinfo.c6
-rw-r--r--builtin/mailsplit.c17
-rw-r--r--builtin/merge-tree.c18
-rw-r--r--builtin/merge.c53
-rw-r--r--builtin/mktree.c5
-rw-r--r--builtin/mv.c181
-rw-r--r--builtin/name-rev.c7
-rw-r--r--builtin/notes.c19
-rw-r--r--builtin/pack-objects.c515
-rw-r--r--builtin/patch-id.c74
-rw-r--r--builtin/prune-packed.c2
-rw-r--r--builtin/prune.c4
-rw-r--r--builtin/push.c42
-rw-r--r--builtin/read-tree.c18
-rw-r--r--builtin/receive-pack.c48
-rw-r--r--builtin/reflog.c4
-rw-r--r--builtin/remote-ext.c3
-rw-r--r--builtin/remote.c63
-rw-r--r--builtin/repack.c66
-rw-r--r--builtin/replace.c380
-rw-r--r--builtin/rerere.c2
-rw-r--r--builtin/reset.c57
-rw-r--r--builtin/rev-list.c44
-rw-r--r--builtin/rev-parse.c30
-rw-r--r--builtin/revert.c2
-rw-r--r--builtin/rm.c11
-rw-r--r--builtin/send-pack.c27
-rw-r--r--builtin/show-branch.c13
-rw-r--r--builtin/tag.c223
-rw-r--r--builtin/unpack-objects.c4
-rw-r--r--builtin/update-index.c109
-rw-r--r--builtin/update-ref.c452
-rw-r--r--builtin/verify-commit.c93
-rw-r--r--builtin/verify-pack.c10
61 files changed, 3627 insertions, 1928 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 672adc01ff..352b85e8db 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -15,6 +15,7 @@
#include "diffcore.h"
#include "revision.h"
#include "bulk-checkin.h"
+#include "argv-array.h"
static const char * const builtin_add_usage[] = {
N_("git add [options] [--] <pathspec>..."),
@@ -26,55 +27,8 @@ static int take_worktree_changes;
struct update_callback_data {
int flags;
int add_errors;
- const char *implicit_dot;
- size_t implicit_dot_len;
-
- /* only needed for 2.0 transition preparation */
- int warn_add_would_remove;
};
-static const char *option_with_implicit_dot;
-static const char *short_option_with_implicit_dot;
-
-static void warn_pathless_add(void)
-{
- static int shown;
- assert(option_with_implicit_dot && short_option_with_implicit_dot);
-
- if (shown)
- return;
- shown = 1;
-
- /*
- * To be consistent with "git add -p" and most Git
- * commands, we should default to being tree-wide, but
- * this is not the original behavior and can't be
- * changed until users trained themselves not to type
- * "git add -u" or "git add -A". For now, we warn and
- * keep the old behavior. Later, the behavior can be changed
- * to tree-wide, keeping the warning for a while, and
- * eventually we can drop the warning.
- */
- warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
- "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
- "To add content for the whole tree, run:\n"
- "\n"
- " git add %s :/\n"
- " (or git add %s :/)\n"
- "\n"
- "To restrict the command to the current directory, run:\n"
- "\n"
- " git add %s .\n"
- " (or git add %s .)\n"
- "\n"
- "With the current Git version, the command is restricted to "
- "the current directory.\n"
- ""),
- option_with_implicit_dot, short_option_with_implicit_dot,
- option_with_implicit_dot, short_option_with_implicit_dot,
- option_with_implicit_dot, short_option_with_implicit_dot);
-}
-
static int fix_unmerged_status(struct diff_filepair *p,
struct update_callback_data *data)
{
@@ -96,49 +50,15 @@ static int fix_unmerged_status(struct diff_filepair *p,
return DIFF_STATUS_MODIFIED;
}
-static const char *add_would_remove_warning = N_(
- "You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n"
-"whose behaviour will change in Git 2.0 with respect to paths you removed.\n"
-"Paths like '%s' that are\n"
-"removed from your working tree are ignored with this version of Git.\n"
-"\n"
-"* 'git add --ignore-removal <pathspec>', which is the current default,\n"
-" ignores paths you removed from your working tree.\n"
-"\n"
-"* 'git add --all <pathspec>' will let you also record the removals.\n"
-"\n"
-"Run 'git status' to check the paths you removed from your working tree.\n");
-
-static void warn_add_would_remove(const char *path)
-{
- warning(_(add_would_remove_warning), path);
-}
-
static void update_callback(struct diff_queue_struct *q,
struct diff_options *opt, void *cbdata)
{
int i;
struct update_callback_data *data = cbdata;
- const char *implicit_dot = data->implicit_dot;
- size_t implicit_dot_len = data->implicit_dot_len;
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
const char *path = p->one->path;
- /*
- * Check if "git add -A" or "git add -u" was run from a
- * subdirectory with a modified file outside that directory,
- * and warn if so.
- *
- * "git add -u" will behave like "git add -u :/" instead of
- * "git add -u ." in the future. This warning prepares for
- * that change.
- */
- if (implicit_dot &&
- strncmp_icase(path, implicit_dot, implicit_dot_len)) {
- warn_pathless_add();
- continue;
- }
switch (fix_unmerged_status(p, data)) {
default:
die(_("unexpected diff status %c"), p->status);
@@ -151,10 +71,6 @@ static void update_callback(struct diff_queue_struct *q,
}
break;
case DIFF_STATUS_DELETED:
- if (data->warn_add_would_remove) {
- warn_add_would_remove(path);
- data->warn_add_would_remove = 0;
- }
if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
break;
if (!(data->flags & ADD_CACHE_PRETEND))
@@ -166,37 +82,28 @@ static void update_callback(struct diff_queue_struct *q,
}
}
-static void update_files_in_cache(const char *prefix,
- const struct pathspec *pathspec,
- struct update_callback_data *data)
+int add_files_to_cache(const char *prefix,
+ const struct pathspec *pathspec, int flags)
{
+ struct update_callback_data data;
struct rev_info rev;
+ memset(&data, 0, sizeof(data));
+ data.flags = flags;
+
init_revisions(&rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
if (pathspec)
copy_pathspec(&rev.prune_data, pathspec);
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
- rev.diffopt.format_callback_data = data;
+ rev.diffopt.format_callback_data = &data;
rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
-}
-
-int add_files_to_cache(const char *prefix,
- const struct pathspec *pathspec, int flags)
-{
- struct update_callback_data data;
-
- memset(&data, 0, sizeof(data));
- data.flags = flags;
- update_files_in_cache(prefix, pathspec, &data);
return !!data.add_errors;
}
-#define WARN_IMPLICIT_DOT (1u << 0)
-static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
- int prefix, unsigned flag)
+static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
{
char *seen;
int i;
@@ -210,16 +117,6 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
struct dir_entry *entry = *src++;
if (dir_path_match(entry, pathspec, prefix, seen))
*dst++ = entry;
- else if (flag & WARN_IMPLICIT_DOT)
- /*
- * "git add -A" was run from a subdirectory with a
- * new file outside that directory.
- *
- * "git add -A" will behave like "git add -A :/"
- * instead of "git add -A ." in the future.
- * Warn about the coming behavior change.
- */
- warn_pathless_add();
}
dir->nr = dst - dir->entries;
add_pathspec_matches_against_index(pathspec, seen);
@@ -245,23 +142,21 @@ static void refresh(int verbose, const struct pathspec *pathspec)
int run_add_interactive(const char *revision, const char *patch_mode,
const struct pathspec *pathspec)
{
- int status, ac, i;
- const char **args;
+ int status, i;
+ struct argv_array argv = ARGV_ARRAY_INIT;
- args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
- ac = 0;
- args[ac++] = "add--interactive";
+ argv_array_push(&argv, "add--interactive");
if (patch_mode)
- args[ac++] = patch_mode;
+ argv_array_push(&argv, patch_mode);
if (revision)
- args[ac++] = revision;
- args[ac++] = "--";
+ argv_array_push(&argv, revision);
+ argv_array_push(&argv, "--");
for (i = 0; i < pathspec->nr; i++)
/* pass original pathspec, to be re-parsed */
- args[ac++] = pathspec->items[i].original;
+ argv_array_push(&argv, pathspec->items[i].original);
- status = run_command_v_opt(args, RUN_GIT_CMD);
- free(args);
+ status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
+ argv_array_clear(&argv);
return status;
}
@@ -285,7 +180,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
char *file = git_pathdup("ADD_EDIT.patch");
const char *apply_argv[] = { "apply", "--recount", "--cached",
NULL, NULL };
- struct child_process child;
+ struct child_process child = CHILD_PROCESS_INIT;
struct rev_info rev;
int out;
struct stat st;
@@ -319,7 +214,6 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
if (!st.st_size)
die(_("Empty patch. Aborted."));
- memset(&child, 0, sizeof(child));
child.git_cmd = 1;
child.argv = apply_argv;
if (run_command(&child))
@@ -338,7 +232,7 @@ N_("The following paths are ignored by one of your .gitignore files:\n");
static int verbose, show_only, ignored_too, refresh_only;
static int ignore_add_errors, intent_to_add, ignore_missing;
-#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
+#define ADDREMOVE_DEFAULT 1
static int addremove = ADDREMOVE_DEFAULT;
static int addremove_explicit = -1; /* unspecified */
@@ -404,15 +298,12 @@ static int add_files(struct dir_struct *dir, int flags)
int cmd_add(int argc, const char **argv, const char *prefix)
{
int exit_status = 0;
- int newfd;
struct pathspec pathspec;
struct dir_struct dir;
int flags;
int add_new_files;
int require_pathspec;
char *seen = NULL;
- int implicit_dot = 0;
- struct update_callback_data update_data;
git_config(add_config, NULL);
@@ -436,50 +327,30 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (addremove && take_worktree_changes)
die(_("-A and -u are mutually incompatible"));
- /*
- * Warn when "git add pathspec..." was given without "-u" or "-A"
- * and pathspec... covers a removed path.
- */
- memset(&update_data, 0, sizeof(update_data));
- if (!take_worktree_changes && addremove_explicit < 0)
- update_data.warn_add_would_remove = 1;
-
if (!take_worktree_changes && addremove_explicit < 0 && argc)
- /*
- * Turn "git add pathspec..." to "git add -A pathspec..."
- * in Git 2.0 but not yet
- */
- ; /* addremove = 1; */
+ /* Turn "git add pathspec..." to "git add -A pathspec..." */
+ addremove = 1;
if (!show_only && ignore_missing)
die(_("Option --ignore-missing can only be used together with --dry-run"));
- if (addremove) {
- option_with_implicit_dot = "--all";
- short_option_with_implicit_dot = "-A";
- }
- if (take_worktree_changes) {
- option_with_implicit_dot = "--update";
- short_option_with_implicit_dot = "-u";
- }
- if (option_with_implicit_dot && !argc) {
- static const char *here[2] = { ".", NULL };
+
+ if ((0 < addremove_explicit || take_worktree_changes) && !argc) {
+ static const char *whole[2] = { ":/", NULL };
argc = 1;
- argv = here;
- implicit_dot = 1;
+ argv = whole;
}
add_new_files = !take_worktree_changes && !refresh_only;
require_pathspec = !take_worktree_changes;
- newfd = hold_locked_index(&lock_file, 1);
+ hold_locked_index(&lock_file, 1);
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
(show_only ? ADD_CACHE_PRETEND : 0) |
(intent_to_add ? ADD_CACHE_INTENT : 0) |
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
(!(addremove || take_worktree_changes)
- ? ADD_CACHE_IGNORE_REMOVAL : 0)) |
- (implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
+ ? ADD_CACHE_IGNORE_REMOVAL : 0));
if (require_pathspec && argc == 0) {
fprintf(stderr, _("Nothing specified, nothing added.\n"));
@@ -513,18 +384,15 @@ int cmd_add(int argc, const char **argv, const char *prefix)
memset(&empty_pathspec, 0, sizeof(empty_pathspec));
/* This picks up the paths that are not tracked */
- baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec);
+ baselen = fill_directory(&dir, &pathspec);
if (pathspec.nr)
- seen = prune_directory(&dir, &pathspec, baselen,
- implicit_dot ? WARN_IMPLICIT_DOT : 0);
+ seen = prune_directory(&dir, &pathspec, baselen);
}
if (refresh_only) {
refresh(verbose, &pathspec);
goto finish;
}
- if (implicit_dot && prefix)
- refresh_cache(REFRESH_QUIET);
if (pathspec.nr) {
int i;
@@ -564,21 +432,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
plug_bulk_checkin();
- if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) {
- /*
- * Check for modified files throughout the worktree so
- * update_callback has a chance to warn about changes
- * outside the cwd.
- */
- update_data.implicit_dot = prefix;
- update_data.implicit_dot_len = strlen(prefix);
- free_pathspec(&pathspec);
- memset(&pathspec, 0, sizeof(pathspec));
- }
- update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
- update_files_in_cache(prefix, &pathspec, &update_data);
+ exit_status |= add_files_to_cache(prefix, &pathspec, flags);
- exit_status |= !!update_data.add_errors;
if (add_new_files)
exit_status |= add_files(&dir, flags);
@@ -586,8 +441,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
finish:
if (active_cache_changed) {
- if (write_cache(newfd, active_cache, active_nr) ||
- commit_locked_index(&lock_file))
+ if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
die(_("Unable to write new index file"));
}
diff --git a/builtin/apply.c b/builtin/apply.c
index 6013e1913c..f204cca5d2 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -300,11 +300,13 @@ static int fuzzy_matchlines(const char *s1, size_t n1,
while ((*last2 == '\r') || (*last2 == '\n'))
last2--;
- /* skip leading whitespace */
- while (isspace(*s1) && (s1 <= last1))
- s1++;
- while (isspace(*s2) && (s2 <= last2))
- s2++;
+ /* skip leading whitespaces, if both begin with whitespace */
+ if (s1 <= last1 && s2 <= last2 && isspace(*s1) && isspace(*s2)) {
+ while (isspace(*s1) && (s1 <= last1))
+ s1++;
+ while (isspace(*s2) && (s2 <= last2))
+ s2++;
+ }
/* early return if both lines are empty */
if ((s1 > last1) && (s2 > last2))
return 1;
@@ -1073,7 +1075,7 @@ static int gitdiff_index(const char *line, struct patch *patch)
line = ptr + 2;
ptr = strchr(line, ' ');
- eol = strchr(line, '\n');
+ eol = strchrnul(line, '\n');
if (!ptr || eol < ptr)
ptr = eol;
@@ -1279,9 +1281,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
*/
patch->def_name = git_header_name(line, len);
if (patch->def_name && root) {
- char *s = xmalloc(root_len + strlen(patch->def_name) + 1);
- strcpy(s, root);
- strcpy(s + root_len, patch->def_name);
+ char *s = xstrfmt("%s%s", root, patch->def_name);
free(patch->def_name);
patch->def_name = s;
}
@@ -1920,6 +1920,66 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
return used;
}
+static void prefix_one(char **name)
+{
+ char *old_name = *name;
+ if (!old_name)
+ return;
+ *name = xstrdup(prefix_filename(prefix, prefix_length, *name));
+ free(old_name);
+}
+
+static void prefix_patch(struct patch *p)
+{
+ if (!prefix || p->is_toplevel_relative)
+ return;
+ prefix_one(&p->new_name);
+ prefix_one(&p->old_name);
+}
+
+/*
+ * include/exclude
+ */
+
+static struct string_list limit_by_name;
+static int has_include;
+static void add_name_limit(const char *name, int exclude)
+{
+ struct string_list_item *it;
+
+ it = string_list_append(&limit_by_name, name);
+ it->util = exclude ? NULL : (void *) 1;
+}
+
+static int use_patch(struct patch *p)
+{
+ const char *pathname = p->new_name ? p->new_name : p->old_name;
+ int i;
+
+ /* Paths outside are not touched regardless of "--include" */
+ if (0 < prefix_length) {
+ int pathlen = strlen(pathname);
+ if (pathlen <= prefix_length ||
+ memcmp(prefix, pathname, prefix_length))
+ return 0;
+ }
+
+ /* See if it matches any of exclude/include rule */
+ for (i = 0; i < limit_by_name.nr; i++) {
+ struct string_list_item *it = &limit_by_name.items[i];
+ if (!wildmatch(it->string, pathname, 0, NULL))
+ return (it->util != NULL);
+ }
+
+ /*
+ * If we had any include, a path that does not match any rule is
+ * not used. Otherwise, we saw bunch of exclude rules (or none)
+ * and such a path is used.
+ */
+ return !has_include;
+}
+
+
/*
* Read the patch text in "buffer" that extends for "size" bytes; stop
* reading after seeing a single patch (i.e. changes to a single file).
@@ -1935,21 +1995,20 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
if (offset < 0)
return offset;
- patch->ws_rule = whitespace_rule(patch->new_name
- ? patch->new_name
- : patch->old_name);
+ prefix_patch(patch);
+
+ if (!use_patch(patch))
+ patch->ws_rule = 0;
+ else
+ patch->ws_rule = whitespace_rule(patch->new_name
+ ? patch->new_name
+ : patch->old_name);
patchsize = parse_single_patch(buffer + offset + hdrsize,
size - offset - hdrsize, patch);
if (!patchsize) {
- static const char *binhdr[] = {
- "Binary files ",
- "Files ",
- NULL,
- };
static const char git_binary[] = "GIT binary patch\n";
- int i;
int hd = hdrsize + offset;
unsigned long llen = linelen(buffer + hd, size - hd);
@@ -1965,6 +2024,12 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
patchsize = 0;
}
else if (!memcmp(" differ\n", buffer + hd + llen - 8, 8)) {
+ static const char *binhdr[] = {
+ "Binary files ",
+ "Files ",
+ NULL,
+ };
+ int i;
for (i = 0; binhdr[i]; i++) {
int len = strlen(binhdr[i]);
if (len < size - hd &&
@@ -2867,9 +2932,7 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)
case BINARY_LITERAL_DEFLATED:
clear_image(img);
img->len = fragment->size;
- img->buf = xmalloc(img->len+1);
- memcpy(img->buf, fragment->patch, img->len);
- img->buf[img->len] = '\0';
+ img->buf = xmemdupz(fragment->patch, img->len);
return 0;
}
return -1;
@@ -3084,13 +3147,15 @@ static void prepare_fn_table(struct patch *patch)
}
}
-static int checkout_target(struct cache_entry *ce, struct stat *st)
+static int checkout_target(struct index_state *istate,
+ struct cache_entry *ce, struct stat *st)
{
struct checkout costate;
memset(&costate, 0, sizeof(costate));
costate.base_dir = "";
costate.refresh_cache = 1;
+ costate.istate = istate;
if (checkout_entry(ce, &costate, NULL) || lstat(ce->name, st))
return error(_("cannot checkout %s"), ce->name);
return 0;
@@ -3257,7 +3322,7 @@ static int load_current(struct image *image, struct patch *patch)
if (lstat(name, &st)) {
if (errno != ENOENT)
return error(_("%s: %s"), name, strerror(errno));
- if (checkout_target(ce, &st))
+ if (checkout_target(&the_index, ce, &st))
return -1;
}
if (verify_index_match(ce, &st))
@@ -3411,7 +3476,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
}
*ce = active_cache[pos];
if (stat_ret < 0) {
- if (checkout_target(*ce, st))
+ if (checkout_target(&the_index, *ce, st))
return -1;
}
if (!cached && verify_index_match(*ce, st))
@@ -3644,7 +3709,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)
{
struct patch *patch;
struct index_state result = { NULL };
- int fd;
+ static struct lock_file lock;
/* Once we start supporting the reverse patch, it may be
* worth showing the new sha1 prefix, but until then...
@@ -3682,8 +3747,8 @@ static void build_fake_ancestor(struct patch *list, const char *filename)