> builtin/add.c | 42 +++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 41 insertions(+), 1 deletion(-) > > diff --git a/builtin/add.c b/builtin/add.c > index 5d5773d5cd..264f84dbe7 100644 > --- a/builtin/add.c > +++ b/builtin/add.c > @@ -26,6 +26,7 @@ static const char * const builtin_add_usage[] = { > }; > static int patch_interactive, add_interactive, edit_interactive; > static int take_worktree_changes; > +static int rehash; > > struct update_callback_data { > int flags; > @@ -121,6 +122,41 @@ int add_files_to_cache(const char *prefix, > return !!data.add_errors; > } > > +static int rehash_tracked_files(const char *prefix, const struct pathspec *pathspec, > + int flags) > +{ > + struct string_list paths = STRING_LIST_INIT_DUP; > + struct string_list_item *path; > + int i, retval = 0; > + > + for (i = 0; i < active_nr; i++) { > + struct cache_entry *ce = active_cache[i]; > + > + if (ce_stage(ce)) > + continue; /* do not touch unmerged paths */ > + if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode)) > + continue; /* do not touch non blobs */ > + if (pathspec && !ce_path_match(ce, pathspec, NULL)) > + continue; > + string_list_append(&paths, ce->name); > + } > + > + for_each_string_list_item(path, &paths) { > + /* > + * Having a blob contaminated with CR will trigger the > + * safe-crlf kludge, avoidance of which is the primary > + * thing this helper function exists. Remove it and > + * then re-add it. Note that this may lose executable > + * bit on a filesystem that lacks it. > + */ > + remove_file_from_cache(path->string); > + add_file_to_cache(path->string, flags); > + } > + > + string_list_clear(&paths, 0); > + return retval; > +} > + > static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix) > { > char *seen; > @@ -274,6 +310,7 @@ static struct option builtin_add_options[] = { > OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")), > OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")), > OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")), > + OPT_BOOL(0, "rehash", &rehash, N_("really update tracked files")), > OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")), > OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")), > { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit, > @@ -498,7 +535,10 @@ int cmd_add(int argc, const char **argv, const char *prefix) > > plug_bulk_checkin(); > > - exit_status |= add_files_to_cache(prefix, &pathspec, flags); > + if (rehash) > + exit_status |= rehash_tracked_files(prefix, &pathspec, flags); > + else > + exit_status |= add_files_to_cache(prefix, &pathspec, flags); > > if (add_new_files) > exit_status |= add_files(&dir, flags); That looks like a nice one. Before we put this into stone: Does it make sense to say "renormalize" instead of "rehash" ? (That term does exist already for merge. And rehash is more a technical term, rather then a user-point-of-view explanation)