summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-09-29 16:49:47 -0700
committerJunio C Hamano <gitster@pobox.com>2016-09-29 16:49:47 -0700
commit36f64036f647912c8037e625e9fe3cee6713b105 (patch)
tree6e0ec6e40eda4724fdc778b4697b705cfc112563 /builtin
parentbf3a55a21b85c04441e67ee1fa08e5eff41ebbe8 (diff)
parent40e0dc17ce6f8b699c0f9426438362ed658293dc (diff)
downloadgit-36f64036f647912c8037e625e9fe3cee6713b105.tar.gz
Merge branch 'tg/add-chmod+x-fix' into maint
"git add --chmod=+x <pathspec>" added recently only toggled the executable bit for paths that are either new or modified. This has been corrected to flip the executable bit for all paths that match the given pathspec. * tg/add-chmod+x-fix: t3700-add: do not check working tree file mode without POSIXPERM t3700-add: create subdirectory gently add: modify already added files when --chmod is given read-cache: introduce chmod_index_entry update-index: add test for chmod flags
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c47
-rw-r--r--builtin/checkout.c2
-rw-r--r--builtin/commit.c2
-rw-r--r--builtin/update-index.c18
4 files changed, 33 insertions, 36 deletions
diff --git a/builtin/add.c b/builtin/add.c
index b1dddb4ac6..e8fb80b36e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -26,10 +26,25 @@ static int patch_interactive, add_interactive, edit_interactive;
static int take_worktree_changes;
struct update_callback_data {
- int flags, force_mode;
+ int flags;
int add_errors;
};
+static void chmod_pathspec(struct pathspec *pathspec, int force_mode)
+{
+ int i;
+
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+
+ if (pathspec && !ce_path_match(ce, pathspec, NULL))
+ continue;
+
+ if (chmod_cache_entry(ce, force_mode) < 0)
+ fprintf(stderr, "cannot chmod '%s'", ce->name);
+ }
+}
+
static int fix_unmerged_status(struct diff_filepair *p,
struct update_callback_data *data)
{
@@ -65,8 +80,7 @@ static void update_callback(struct diff_queue_struct *q,
die(_("unexpected diff status %c"), p->status);
case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_TYPE_CHANGED:
- if (add_file_to_index(&the_index, path,
- data->flags, data->force_mode)) {
+ if (add_file_to_index(&the_index, path, data->flags)) {
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
die(_("updating files failed"));
data->add_errors++;
@@ -84,15 +98,14 @@ static void update_callback(struct diff_queue_struct *q,
}
}
-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec,
- int flags, int force_mode)
+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;
- data.force_mode = force_mode;
init_revisions(&rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
@@ -281,7 +294,7 @@ static int add_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
-static int add_files(struct dir_struct *dir, int flags, int force_mode)
+static int add_files(struct dir_struct *dir, int flags)
{
int i, exit_status = 0;
@@ -294,8 +307,7 @@ static int add_files(struct dir_struct *dir, int flags, int force_mode)
}
for (i = 0; i < dir->nr; i++)
- if (add_file_to_index(&the_index, dir->entries[i]->name,
- flags, force_mode)) {
+ if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
if (!ignore_add_errors)
die(_("adding files failed"));
exit_status = 1;
@@ -308,7 +320,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
int exit_status = 0;
struct pathspec pathspec;
struct dir_struct dir;
- int flags, force_mode;
+ int flags;
int add_new_files;
int require_pathspec;
char *seen = NULL;
@@ -342,13 +354,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (!show_only && ignore_missing)
die(_("Option --ignore-missing can only be used together with --dry-run"));
- if (!chmod_arg)
- force_mode = 0;
- else if (!strcmp(chmod_arg, "-x"))
- force_mode = 0666;
- else if (!strcmp(chmod_arg, "+x"))
- force_mode = 0777;
- else
+ if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') ||
+ chmod_arg[1] != 'x' || chmod_arg[2]))
die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
add_new_files = !take_worktree_changes && !refresh_only;
@@ -441,11 +448,13 @@ int cmd_add(int argc, const char **argv, const char *prefix)
plug_bulk_checkin();
- exit_status |= add_files_to_cache(prefix, &pathspec, flags, force_mode);
+ exit_status |= add_files_to_cache(prefix, &pathspec, flags);
if (add_new_files)
- exit_status |= add_files(&dir, flags, force_mode);
+ exit_status |= add_files(&dir, flags);
+ if (chmod_arg && pathspec.nr)
+ chmod_pathspec(&pathspec, chmod_arg[0]);
unplug_bulk_checkin();
finish:
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 0ad96786c9..32cf317ec2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -548,7 +548,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
* entries in the index.
*/
- add_files_to_cache(NULL, NULL, 0, 0);
+ add_files_to_cache(NULL, NULL, 0);
/*
* NEEDSWORK: carrying over local changes
* when branches have different end-of-line
diff --git a/builtin/commit.c b/builtin/commit.c
index 77e3dc8494..7a1ade0d27 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -387,7 +387,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
*/
if (all || (also && pathspec.nr)) {
hold_locked_index(&index_lock, 1);
- add_files_to_cache(also ? prefix : NULL, &pathspec, 0, 0);
+ add_files_to_cache(also ? prefix : NULL, &pathspec, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
diff --git a/builtin/update-index.c b/builtin/update-index.c
index ba04b197d8..9e9e04059c 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -419,30 +419,18 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
return 0;
}
-static void chmod_path(int flip, const char *path)
+static void chmod_path(char flip, const char *path)
{
int pos;
struct cache_entry *ce;
- unsigned int mode;
pos = cache_name_pos(path, strlen(path));
if (pos < 0)
goto fail;
ce = active_cache[pos];
- mode = ce->ce_mode;
- if (!S_ISREG(mode))
- goto fail;
- switch (flip) {
- case '+':
- ce->ce_mode |= 0111; break;
- case '-':
- ce->ce_mode &= ~0111; break;
- default:
+ if (chmod_cache_entry(ce, flip) < 0)
goto fail;
- }
- cache_tree_invalidate_path(&the_index, path);
- ce->ce_flags |= CE_UPDATE_IN_BASE;
- active_cache_changed |= CE_ENTRY_CHANGED;
+
report("chmod %cx '%s'", flip, path);
return;
fail: