From: Junio C Hamano Date: Wed, 20 Jan 2010 22:44:31 +0000 (-0800) Subject: Merge branch 'jc/cache-unmerge' X-Git-Tag: v1.7.0-rc0~61 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=6751e0471df1bdc4a1d5e5a3929a531c74e95aeb;p=git.git Merge branch 'jc/cache-unmerge' * jc/cache-unmerge: rerere forget path: forget recorded resolution rerere: refactor rerere logic to make it independent from I/O rerere: remove silly 1024-byte line limit resolve-undo: teach "update-index --unresolve" to use resolve-undo info resolve-undo: "checkout -m path" uses resolve-undo information resolve-undo: allow plumbing to clear the information resolve-undo: basic tests resolve-undo: record resolved conflicts in a new index extension section builtin-merge.c: use standard active_cache macros Conflicts: builtin-ls-files.c builtin-merge.c builtin-rerere.c --- 6751e0471df1bdc4a1d5e5a3929a531c74e95aeb diff --cc builtin-ls-files.c index 738215768,ef3a06889..b06506139 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@@ -37,7 -40,7 +40,8 @@@ static const char *tag_removed = "" static const char *tag_other = ""; static const char *tag_killed = ""; static const char *tag_modified = ""; +static const char *tag_skip_worktree = ""; + static const char *tag_resolve_undo = ""; static void show_dir_entry(const char *tag, struct dir_entry *ent) { @@@ -497,7 -528,7 +535,8 @@@ int cmd_ls_files(int argc, const char * tag_modified = "C "; tag_other = "? "; tag_killed = "K "; + tag_skip_worktree = "S "; + tag_resolve_undo = "U "; } if (show_modified || show_others || show_deleted || (dir.flags & DIR_SHOW_IGNORED) || show_killed) require_work_tree = 1; diff --cc builtin-merge.c index 6f1311414,6bc2f7af0..9f60ffa2c --- a/builtin-merge.c +++ b/builtin-merge.c @@@ -849,21 -848,12 +850,22 @@@ int cmd_merge(int argc, const char **ar const char *best_strategy = NULL, *wt_strategy = NULL; struct commit_list **remotes = &remoteheads; - if (file_exists(git_path("MERGE_HEAD"))) - die("You have not concluded your merge. (MERGE_HEAD exists)"); - if (read_cache_unmerged()) - die("You are in the middle of a conflicted merge." - " (index unmerged)"); + if (read_cache_unmerged()) { + die_resolve_conflict("merge"); + } + if (file_exists(git_path("MERGE_HEAD"))) { + /* + * There is no unmerged entry, don't advise 'git + * add/rm ', just 'git commit'. + */ + if (advice_resolve_conflict) + die("You have not concluded your merge (MERGE_HEAD exists).\n" + "Please, commit your changes before you can merge."); + else + die("You have not concluded your merge (MERGE_HEAD exists)."); + } + + resolve_undo_clear(); /* * Check if we are _not_ on a detached HEAD, i.e. if there is a * current branch. diff --cc builtin-rerere.c index 502813889,0253abf9b..25f507a2f --- a/builtin-rerere.c +++ b/builtin-rerere.c @@@ -103,24 -103,17 +103,27 @@@ static int diff_two(const char *file1, int cmd_rerere(int argc, const char **argv, const char *prefix) { struct string_list merge_rr = { NULL, 0, 0, 1 }; - int i, fd; - + int i, fd, flags = 0; + + if (2 < argc) { + if (!strcmp(argv[1], "-h")) + usage(git_rerere_usage); + if (!strcmp(argv[1], "--rerere-autoupdate")) + flags = RERERE_AUTOUPDATE; + else if (!strcmp(argv[1], "--no-rerere-autoupdate")) + flags = RERERE_NOAUTOUPDATE; + if (flags) { + argc--; + argv++; + } + } if (argc < 2) - return rerere(); + return rerere(flags); - if (!strcmp(argv[1], "-h")) - usage(git_rerere_usage); - else if (!strcmp(argv[1], "forget")) ++ if (!strcmp(argv[1], "forget")) + return rerere_forget(argv + 2); + - fd = setup_rerere(&merge_rr); + fd = setup_rerere(&merge_rr, flags); if (fd < 0) return 0; diff --cc read-cache.c index f4512967b,9e0fb0407..edd995943 --- a/read-cache.c +++ b/read-cache.c @@@ -14,9 -14,8 +14,10 @@@ #include "diffcore.h" #include "revision.h" #include "blob.h" + #include "resolve-undo.h" +static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really); + /* Index extensions. * * The first letter should be 'A'..'Z' for extensions that are not diff --cc rerere.c index e0ac5bcae,d92990a6b..70d0f7aff --- a/rerere.c +++ b/rerere.c @@@ -394,3 -518,52 +520,52 @@@ int rerere(int flags return 0; return do_plain_rerere(&merge_rr, fd); } + + static int rerere_forget_one_path(const char *path, struct string_list *rr) + { + const char *filename; + char *hex; + unsigned char sha1[20]; + int ret; + + ret = handle_cache(path, sha1, NULL); + if (ret < 1) + return error("Could not parse conflict hunks in '%s'", path); + hex = xstrdup(sha1_to_hex(sha1)); + filename = rerere_path(hex, "postimage"); + if (unlink(filename)) + return (errno == ENOENT + ? error("no remembered resolution for %s", path) + : error("cannot unlink %s: %s", filename, strerror(errno))); + + handle_cache(path, sha1, rerere_path(hex, "preimage")); + fprintf(stderr, "Updated preimage for '%s'\n", path); + + + string_list_insert(path, rr)->util = hex; + fprintf(stderr, "Forgot resolution for %s\n", path); + return 0; + } + + int rerere_forget(const char **pathspec) + { + int i, fd; + struct string_list conflict = { NULL, 0, 0, 1 }; + struct string_list merge_rr = { NULL, 0, 0, 1 }; + + if (read_cache() < 0) + return error("Could not read index"); + - fd = setup_rerere(&merge_rr); ++ fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); + + unmerge_cache(pathspec); + find_conflict(&conflict); + for (i = 0; i < conflict.nr; i++) { + struct string_list_item *it = &conflict.items[i]; + if (!match_pathspec(pathspec, it->string, strlen(it->string), + 0, NULL)) + continue; + rerere_forget_one_path(it->string, &merge_rr); + } + return write_rr(&merge_rr, fd); + } diff --cc rerere.h index 10a94a4ea,36560ff2f..eaa9004dc --- a/rerere.h +++ b/rerere.h @@@ -3,15 -3,10 +3,16 @@@ #include "string-list.h" -extern int setup_rerere(struct string_list *); -extern int rerere(void); +#define RERERE_AUTOUPDATE 01 +#define RERERE_NOAUTOUPDATE 02 + +extern int setup_rerere(struct string_list *, int); +extern int rerere(int); extern const char *rerere_path(const char *hex, const char *file); extern int has_rerere_resolution(const char *hex); + extern int rerere_forget(const char **); +#define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \ + "update the index with reused conflict resolution if possible") + #endif