Skip to content

Commit

Permalink
Merge branch 'jc/cache-unmerge'
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Junio C Hamano committed Jan 20, 2010
2 parents 030b1a7 + dea4562 commit 6751e04
Show file tree
Hide file tree
Showing 14 changed files with 652 additions and 47 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ LIB_H += reflog-walk.h
LIB_H += refs.h
LIB_H += remote.h
LIB_H += rerere.h
LIB_H += resolve-undo.h
LIB_H += revision.h
LIB_H += run-command.h
LIB_H += sha1-lookup.h
Expand Down Expand Up @@ -592,6 +593,7 @@ LIB_OBJS += refs.o
LIB_OBJS += remote.o
LIB_OBJS += replace_object.o
LIB_OBJS += rerere.o
LIB_OBJS += resolve-undo.o
LIB_OBJS += revision.o
LIB_OBJS += run-command.o
LIB_OBJS += server-info.o
Expand Down
6 changes: 6 additions & 0 deletions builtin-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "blob.h"
#include "xdiff-interface.h"
#include "ll-merge.h"
#include "resolve-undo.h"

static const char * const checkout_usage[] = {
"git checkout [options] <branch>",
Expand Down Expand Up @@ -234,6 +235,10 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
if (report_path_error(ps_matched, pathspec, 0))
return 1;

/* "checkout -m path" to recreate conflicted state */
if (opts->merge)
unmerge_cache(pathspec);

/* Any unmerged paths? */
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
Expand Down Expand Up @@ -370,6 +375,7 @@ static int merge_working_tree(struct checkout_opts *opts,
if (read_cache_preload(NULL) < 0)
return error("corrupt index file");

resolve_undo_clear();
if (opts->force) {
ret = reset_tree(new->commit->tree, opts, 1);
if (ret)
Expand Down
43 changes: 42 additions & 1 deletion builtin-ls-files.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
#include "builtin.h"
#include "tree.h"
#include "parse-options.h"
#include "resolve-undo.h"
#include "string-list.h"

static int abbrev;
static int show_deleted;
static int show_cached;
static int show_others;
static int show_stage;
static int show_unmerged;
static int show_resolve_undo;
static int show_modified;
static int show_killed;
static int show_valid_bit;
Expand All @@ -38,6 +41,7 @@ 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)
{
Expand Down Expand Up @@ -156,6 +160,38 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
write_name_quoted(ce->name + offset, stdout, line_terminator);
}

static int show_one_ru(struct string_list_item *item, void *cbdata)
{
int offset = prefix_offset;
const char *path = item->string;
struct resolve_undo_info *ui = item->util;
int i, len;

len = strlen(path);
if (len < prefix_len)
return 0; /* outside of the prefix */
if (!match_pathspec(pathspec, path, len, prefix_len, ps_matched))
return 0; /* uninterested */
for (i = 0; i < 3; i++) {
if (!ui->mode[i])
continue;
printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
abbrev
? find_unique_abbrev(ui->sha1[i], abbrev)
: sha1_to_hex(ui->sha1[i]),
i + 1);
write_name_quoted(path + offset, stdout, line_terminator);
}
return 0;
}

static void show_ru_info(const char *prefix)
{
if (!the_index.resolve_undo)
return;
for_each_string_list(show_one_ru, the_index.resolve_undo, NULL);
}

static void show_files(struct dir_struct *dir, const char *prefix)
{
int i;
Expand Down Expand Up @@ -458,6 +494,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
DIR_HIDE_EMPTY_DIRECTORIES),
OPT_BOOLEAN('u', "unmerged", &show_unmerged,
"show unmerged files in the output"),
OPT_BOOLEAN(0, "resolve-undo", &show_resolve_undo,
"show resolve-undo information"),
{ OPTION_CALLBACK, 'x', "exclude", &dir.exclude_list[EXC_CMDL], "pattern",
"skip files matching pattern",
0, option_parse_exclude },
Expand Down Expand Up @@ -498,6 +536,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
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;
Expand Down Expand Up @@ -536,7 +575,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)

/* With no flags, we default to showing the cached files */
if (!(show_stage | show_deleted | show_others | show_unmerged |
show_killed | show_modified))
show_killed | show_modified | show_resolve_undo))
show_cached = 1;

if (prefix)
Expand All @@ -551,6 +590,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
overlay_tree_on_cache(with_tree, prefix);
}
show_files(&dir, prefix);
if (show_resolve_undo)
show_ru_info(prefix);

if (ps_matched) {
int bad;
Expand Down
8 changes: 5 additions & 3 deletions builtin-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "rerere.h"
#include "help.h"
#include "merge-recursive.h"
#include "resolve-undo.h"

#define DEFAULT_TWOHEAD (1<<0)
#define DEFAULT_OCTOPUS (1<<1)
Expand Down Expand Up @@ -606,6 +607,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
discard_cache();
if (read_cache() < 0)
die("failed to read the cache");
resolve_undo_clear();
return ret;
}
}
Expand All @@ -620,11 +622,10 @@ static void count_diff_files(struct diff_queue_struct *q,

static int count_unmerged_entries(void)
{
const struct index_state *state = &the_index;
int i, ret = 0;

for (i = 0; i < state->cache_nr; i++)
if (ce_stage(state->cache[i]))
for (i = 0; i < active_nr; i++)
if (ce_stage(active_cache[i]))
ret++;

return ret;
Expand Down Expand Up @@ -864,6 +865,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
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.
Expand Down
2 changes: 2 additions & 0 deletions builtin-read-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "dir.h"
#include "builtin.h"
#include "parse-options.h"
#include "resolve-undo.h"

static int nr_trees;
static struct tree *trees[MAX_UNPACK_TREES];
Expand Down Expand Up @@ -124,6 +125,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
die("You need to resolve your current index first");
stage = opts.merge = 1;
}
resolve_undo_clear();

for (i = 0; i < argc; i++) {
const char *arg = argv[i];
Expand Down
3 changes: 3 additions & 0 deletions builtin-rerere.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
if (argc < 2)
return rerere(flags);

if (!strcmp(argv[1], "forget"))
return rerere_forget(argv + 2);

fd = setup_rerere(&merge_rr, flags);
if (fd < 0)
return 0;
Expand Down
18 changes: 17 additions & 1 deletion builtin-update-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "tree-walk.h"
#include "builtin.h"
#include "refs.h"
#include "resolve-undo.h"

/*
* Default to not allowing changes to the list of files. The
Expand Down Expand Up @@ -440,7 +441,18 @@ static int unresolve_one(const char *path)

/* See if there is such entry in the index. */
pos = cache_name_pos(path, namelen);
if (pos < 0) {
if (0 <= pos) {
/* already merged */
pos = unmerge_cache_entry_at(pos);
if (pos < active_nr) {
struct cache_entry *ce = active_cache[pos];
if (ce_stage(ce) &&
ce_namelen(ce) == namelen &&
!memcmp(ce->name, path, namelen))
return 0;
}
/* no resolve-undo information; fall back */
} else {
/* If there isn't, either it is unmerged, or
* resolved as "removed" by mistake. We do not
* want to do anything in the former case.
Expand Down Expand Up @@ -719,6 +731,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
verbose = 1;
continue;
}
if (!strcmp(path, "--clear-resolve-undo")) {
resolve_undo_clear();
continue;
}
if (!strcmp(path, "-h") || !strcmp(path, "--help"))
usage(update_index_usage);
die("unknown option %s", path);
Expand Down
4 changes: 4 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ static inline int ce_to_dtype(const struct cache_entry *ce)
struct index_state {
struct cache_entry **cache;
unsigned int cache_nr, cache_alloc, cache_changed;
struct string_list *resolve_undo;
struct cache_tree *cache_tree;
struct cache_time timestamp;
void *alloc;
Expand Down Expand Up @@ -342,6 +343,9 @@ static inline void remove_name_hash(struct cache_entry *ce)
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
#define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))
#define resolve_undo_clear() resolve_undo_clear_index(&the_index)
#define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)
#define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)
#endif

enum object_type {
Expand Down
18 changes: 18 additions & 0 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#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);

Expand All @@ -28,6 +29,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 /* "REUN" */

struct index_state the_index;

Expand Down Expand Up @@ -456,6 +458,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--;
Expand Down Expand Up @@ -1183,6 +1186,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",
Expand Down Expand Up @@ -1362,6 +1368,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;
Expand Down Expand Up @@ -1587,6 +1594,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;
Expand Down
Loading

0 comments on commit 6751e04

Please sign in to comment.