git_config_maybe_bool()
[gitweb.git] / read-cache.c
index f4512967b8393e7934812e667d42a97f4d67ba8c..f1f789b7b87643245f1772d15b3f1cb321af324c 100644 (file)
 #include "dir.h"
 #include "tree.h"
 #include "commit.h"
-#include "diff.h"
-#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);
 
@@ -28,6 +26,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int reall
 
 #define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) )
 #define CACHE_EXT_TREE 0x54524545      /* "TREE" */
+#define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */
 
 struct index_state the_index;
 
@@ -456,6 +455,7 @@ int remove_index_entry_at(struct index_state *istate, int pos)
 {
        struct cache_entry *ce = istate->cache[pos];
 
+       record_resolve_undo(istate, ce);
        remove_name_hash(ce);
        istate->cache_changed = 1;
        istate->cache_nr--;
@@ -612,7 +612,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
                /* Nothing changed, really */
                free(ce);
-               ce_mark_uptodate(alias);
+               if (!S_ISGITLINK(alias->ce_mode))
+                       ce_mark_uptodate(alias);
                alias->ce_flags |= CE_ADDED;
                return 0;
        }
@@ -1050,7 +1051,8 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
                         * because CE_UPTODATE flag is in-core only;
                         * we are not going to write this change out.
                         */
-                       ce_mark_uptodate(ce);
+                       if (!S_ISGITLINK(ce->ce_mode))
+                               ce_mark_uptodate(ce);
                        return ce;
                }
        }
@@ -1183,6 +1185,9 @@ static int read_index_extension(struct index_state *istate,
        case CACHE_EXT_TREE:
                istate->cache_tree = cache_tree_read(data, sz);
                break;
+       case CACHE_EXT_RESOLVE_UNDO:
+               istate->resolve_undo = resolve_undo_read(data, sz);
+               break;
        default:
                if (*ext < 'A' || 'Z' < *ext)
                        return error("index uses %.4s extension, which we do not understand",
@@ -1362,6 +1367,7 @@ int is_index_unborn(struct index_state *istate)
 
 int discard_index(struct index_state *istate)
 {
+       resolve_undo_clear_index(istate);
        istate->cache_nr = 0;
        istate->cache_changed = 0;
        istate->timestamp.sec = 0;
@@ -1587,6 +1593,17 @@ int write_index(struct index_state *istate, int newfd)
                if (err)
                        return -1;
        }
+       if (istate->resolve_undo) {
+               struct strbuf sb = STRBUF_INIT;
+
+               resolve_undo_write(&sb, istate->resolve_undo);
+               err = write_index_ext_header(&c, newfd, CACHE_EXT_RESOLVE_UNDO,
+                                            sb.len) < 0
+                       || ce_write(&c, newfd, sb.buf, sb.len) < 0;
+               strbuf_release(&sb);
+               if (err)
+                       return -1;
+       }
 
        if (ce_flush(&c, newfd) || fstat(newfd, &st))
                return -1;
@@ -1630,81 +1647,6 @@ int read_index_unmerged(struct index_state *istate)
        return unmerged;
 }
 
-struct update_callback_data
-{
-       int flags;
-       int add_errors;
-};
-
-static void update_callback(struct diff_queue_struct *q,
-                           struct diff_options *opt, void *cbdata)
-{
-       int i;
-       struct update_callback_data *data = cbdata;
-
-       for (i = 0; i < q->nr; i++) {
-               struct diff_filepair *p = q->queue[i];
-               const char *path = p->one->path;
-               switch (p->status) {
-               default:
-                       die("unexpected diff status %c", p->status);
-               case DIFF_STATUS_UNMERGED:
-                       /*
-                        * ADD_CACHE_IGNORE_REMOVAL is unset if "git
-                        * add -u" is calling us, In such a case, a
-                        * missing work tree file needs to be removed
-                        * if there is an unmerged entry at stage #2,
-                        * but such a diff record is followed by
-                        * another with DIFF_STATUS_DELETED (and if
-                        * there is no stage #2, we won't see DELETED
-                        * nor MODIFIED).  We can simply continue
-                        * either way.
-                        */
-                       if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))
-                               continue;
-                       /*
-                        * Otherwise, it is "git add path" is asking
-                        * to explicitly add it; we fall through.  A
-                        * missing work tree file is an error and is
-                        * caught by add_file_to_index() in such a
-                        * case.
-                        */
-               case DIFF_STATUS_MODIFIED:
-               case DIFF_STATUS_TYPE_CHANGED:
-                       if (add_file_to_index(&the_index, path, data->flags)) {
-                               if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
-                                       die("updating files failed");
-                               data->add_errors++;
-                       }
-                       break;
-               case DIFF_STATUS_DELETED:
-                       if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
-                               break;
-                       if (!(data->flags & ADD_CACHE_PRETEND))
-                               remove_file_from_index(&the_index, path);
-                       if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
-                               printf("remove '%s'\n", path);
-                       break;
-               }
-       }
-}
-
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
-{
-       struct update_callback_data data;
-       struct rev_info rev;
-       init_revisions(&rev, prefix);
-       setup_revisions(0, NULL, &rev, NULL);
-       rev.prune_data = pathspec;
-       rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
-       rev.diffopt.format_callback = update_callback;
-       data.flags = flags;
-       data.add_errors = 0;
-       rev.diffopt.format_callback_data = &data;
-       run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
-       return !!data.add_errors;
-}
-
 /*
  * Returns 1 if the path is an "other" path with respect to
  * the index; that is, the path is not mentioned in the index at all,