示例#1
0
文件: branch.c 项目: ebruck/tig
static void
branch_select(struct view *view, struct line *line)
{
	struct branch *branch = line->data;

	if (branch_is_all(branch)) {
		string_copy(view->ref, BRANCH_ALL_NAME);
		return;
	}
	string_copy_rev(view->ref, branch->ref->id);
	string_copy_rev(view->env->commit, branch->ref->id);
	string_copy_rev(view->env->head, branch->ref->id);
	string_copy_rev(view->env->branch, branch->ref->name);
}
示例#2
0
文件: refdb.c 项目: ChunHungLiu/tig
void
ref_update_env(struct argv_env *env, const struct ref *ref, bool recurse)
{
	bool clear = recurse ? !ref->next : true;

	if (recurse && ref->next)
		ref_update_env(env, ref->next, true);

	if (clear)
		env->tag[0] = env->remote[0] = env->branch[0] = 0;

	string_copy_rev(env->commit, ref->id);

	if (ref_is_tag(ref)) {
		string_ncopy(env->tag, ref->name, strlen(ref->name));

	} else if (ref_is_remote(ref)) {
		const char *sep = strchr(ref->name, '/');

		if (!sep)
			return;
		string_ncopy(env->remote, ref->name, sep - ref->name);
		string_ncopy(env->branch, sep + 1, strlen(sep + 1));

	} else if (ref->type == REFERENCE_BRANCH || ref->type == REFERENCE_HEAD) {
		string_ncopy(env->branch, ref->name, strlen(ref->name));
	}
}
示例#3
0
文件: refdb.c 项目: JakeSc/tig
struct ref_list *
get_ref_list(const char *id)
{
	struct ref_list *list;
	size_t i;

	for (i = 0; i < ref_lists_size; i++)
		if (!strcmp(id, ref_lists[i]->id))
			return ref_lists[i];

	if (!realloc_ref_lists(&ref_lists, ref_lists_size, 1))
		return NULL;
	list = calloc(1, sizeof(*list));
	if (!list)
		return NULL;
	string_copy_rev(list->id, id);

	for (i = 0; i < refs_size; i++) {
		if (!strcmp(id, refs[i]->id) &&
		    realloc_refs_list(&list->refs, list->size, 1))
			list->refs[list->size++] = refs[i];
	}

	if (!list->refs) {
		free(list);
		return NULL;
	}

	qsort(list->refs, list->size, sizeof(*list->refs), compare_refs);
	ref_lists[ref_lists_size++] = list;
	return list;
}
示例#4
0
文件: main.c 项目: apieum/tig
static void
main_register_commit(struct view *view, struct commit *commit, const char *ids, bool is_boundary)
{
	struct main_state *state = view->private;

	string_copy_rev(commit->id, ids);
	if (state->with_graph)
		graph_add_commit(&state->graph, &commit->graph, commit->id, ids, is_boundary);
}
示例#5
0
文件: pager.c 项目: Yair-Karmy/tig
void
pager_select(struct view *view, struct line *line)
{
	if (line->type == LINE_COMMIT) {
		string_copy_rev_from_commit_line(view->env->commit, line->data);
		if (!view_has_flags(view, VIEW_NO_REF))
			string_copy_rev(view->ref, view->env->commit);
	}
}
示例#6
0
文件: blame.c 项目: peff/tig
static enum request
blame_request(struct view *view, enum request request, struct line *line)
{
	enum open_flags flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT;
	struct blame *blame = line->data;

	switch (request) {
	case REQ_VIEW_BLAME:
	case REQ_PARENT:
		if (!check_blame_commit(blame, TRUE))
			break;
		blame_go_forward(view, blame, request == REQ_PARENT);
		break;

	case REQ_BACK:
		blame_go_back(view);
		break;

	case REQ_ENTER:
		if (!check_blame_commit(blame, FALSE))
			break;

		if (view_is_displayed(VIEW(REQ_VIEW_DIFF)) &&
		    !strcmp(blame->commit->id, VIEW(REQ_VIEW_DIFF)->ref))
			break;

		if (string_rev_is_null(blame->commit->id)) {
			struct view *diff = VIEW(REQ_VIEW_DIFF);
			const char *diff_parent_argv[] = {
				GIT_DIFF_BLAME(encoding_arg,
					opt_diff_context_arg,
					opt_ignore_space_arg, view->vid)
			};
			const char *diff_no_parent_argv[] = {
				GIT_DIFF_BLAME_NO_PARENT(encoding_arg,
					opt_diff_context_arg,
					opt_ignore_space_arg, view->vid)
			};
			const char **diff_index_argv = *blame->commit->parent_id
				? diff_parent_argv : diff_no_parent_argv;

			open_argv(view, diff, diff_index_argv, NULL, flags);
			if (diff->pipe)
				string_copy_rev(diff->ref, NULL_ID);
		} else {
			open_view(view, REQ_VIEW_DIFF, flags);
		}
		break;

	default:
		return request;
	}

	return REQ_NONE;
}
示例#7
0
文件: tree.c 项目: Oblomov/tig
static void
tree_select(struct view *view, struct line *line)
{
	struct tree_entry *entry = line->data;

	if (line->type == LINE_HEADER) {
		string_format(view->ref, "Files in /%s", view->env->directory);
		return;
	}

	if (line->type == LINE_DIRECTORY && tree_path_is_parent(entry->name)) {
		string_copy(view->ref, "Open parent directory");
		view->env->blob[0] = 0;
		return;
	}

	if (line->type == LINE_FILE) {
		string_copy_rev(view->env->blob, entry->id);
		string_format(view->env->file, "%s%s", view->env->directory, tree_path(line));
	}

	string_copy_rev(view->ref, entry->id);
}
示例#8
0
文件: refdb.c 项目: JakeSc/tig
void
ref_update_env(struct argv_env *env, const struct ref *ref, bool clear)
{
	if (clear)
		env->tag[0] = env->remote[0] = env->branch[0] = 0;

	string_copy_rev(env->commit, ref->id);

	if (ref_is_tag(ref)) {
		string_copy_rev(env->tag, ref->name);

	} else if (ref_is_remote(ref)) {
		const char *sep = strchr(ref->name, '/');

		if (!sep)
			return;
		string_ncopy(env->remote, ref->name, sep - ref->name);
		string_copy_rev(env->branch, sep + 1);

	} else if (ref->type == REFERENCE_BRANCH) {
		string_copy_rev(env->branch, ref->name);
	}
}
示例#9
0
文件: blame.c 项目: peff/tig
static void
blame_select(struct view *view, struct line *line)
{
	struct blame *blame = line->data;
	struct blame_commit *commit = blame->commit;

	if (!commit)
		return;

	if (string_rev_is_null(commit->id))
		string_ncopy(view->env->commit, "HEAD", 4);
	else
		string_copy_rev(view->env->commit, commit->id);
}
示例#10
0
文件: main.c 项目: Avinash-Bhat/tig
static void
main_register_commit(struct view *view, struct commit *commit, const char *ids, bool is_boundary)
{
	struct main_state *state = view->private;

	string_copy_rev(commit->id, ids);

	/* FIXME: lazily check index state here instead of in main_open. */
	if ((state->add_changes_unstaged || state->add_changes_staged) && is_head_commit(commit->id)) {
		main_add_changes(view, state, ids);
		state->add_changes_unstaged = state->add_changes_staged = FALSE;
	}

	if (state->with_graph)
		graph_add_commit(state->graph, &commit->graph, commit->id, ids, is_boundary);
}
示例#11
0
文件: tree.c 项目: Oblomov/tig
static struct line *
tree_entry(struct view *view, enum line_type type, const char *path,
	   const char *mode, const char *id, unsigned long size)
{
	bool custom = type == LINE_HEADER || tree_path_is_parent(path);
	struct tree_entry *entry;
	struct line *line = add_line_alloc(view, &entry, type, strlen(path), custom);

	if (!line)
		return NULL;

	strncpy(entry->name, path, strlen(path));
	if (mode)
		entry->mode = strtoul(mode, NULL, 8);
	if (id)
		string_copy_rev(entry->id, id);
	entry->size = size;

	return line;
}
示例#12
0
文件: log.c 项目: ChunHungLiu/tig
static void
log_select(struct view *view, struct line *line)
{
	struct log_state *state = view->private;
	int last_lineno = state->last_lineno;

	if (!last_lineno || abs(last_lineno - line->lineno) > 1
	    || (state->last_type == LINE_COMMIT && last_lineno > line->lineno)) {
		struct line *commit_line = find_prev_line_by_type(view, line, LINE_COMMIT);

		if (commit_line)
			log_copy_rev(view, commit_line);
	}

	if (line->type == LINE_COMMIT && !view_has_flags(view, VIEW_NO_REF))
		log_copy_rev(view, line);
	string_copy_rev(view->env->commit, view->ref);
	state->last_lineno = line->lineno;
	state->last_type = line->type;
}
示例#13
0
文件: parse.c 项目: Avinash-Bhat/tig
bool
parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *line)
{
	if (match_blame_header("author ", &line)) {
		string_ncopy_do(author, SIZEOF_STR, line, strlen(line));

	} else if (match_blame_header("author-mail ", &line)) {
		char *end = strchr(line, '>');

		if (end)
			*end = 0;
		if (*line == '<')
			line++;
		commit->author = get_author(author, line);
		author[0] = 0;

	} else if (match_blame_header("author-time ", &line)) {
		parse_timesec(&commit->time, line);

	} else if (match_blame_header("author-tz ", &line)) {
		parse_timezone(&commit->time, line);

	} else if (match_blame_header("summary ", &line)) {
		string_ncopy(commit->title, line, strlen(line));

	} else if (match_blame_header("previous ", &line)) {
		if (strlen(line) <= SIZEOF_REV)
			return FALSE;
		string_copy_rev(commit->parent_id, line);
		line += SIZEOF_REV;
		commit->parent_filename = get_path(line);
		if (!commit->parent_filename)
			return TRUE;

	} else if (match_blame_header("filename ", &line)) {
		commit->filename = get_path(line);
		return TRUE;
	}

	return FALSE;
}
示例#14
0
文件: string.c 项目: phschoen/tig
void
string_copy_rev_from_commit_line(char *dst, const char *src)
{
	string_copy_rev(dst, src + STRING_SIZE("commit "));
}
示例#15
0
文件: tree.c 项目: Oblomov/tig
static bool
tree_read_date(struct view *view, struct buffer *buf, struct tree_state *state)
{
	char *text = buf ? buf->data : NULL;

	if (!text && state->read_date) {
		state->read_date = FALSE;
		return TRUE;

	} else if (!text) {
		/* Find next entry to process */
		const char *log_file[] = {
			"git", "log", encoding_arg, "--no-color", "--pretty=raw",
				"--cc", "--raw", view->ops->id, "--", "%(directory)", NULL
		};

		if (!view->lines) {
			tree_entry(view, LINE_HEADER, view->env->directory, NULL, NULL, 0);
			tree_entry(view, LINE_DIRECTORY, "..", "040000", view->ref, 0);
			report("Tree is empty");
			return TRUE;
		}

		if (!begin_update(view, repo.cdup, log_file, OPEN_EXTRA)) {
			report("Failed to load tree data");
			return TRUE;
		}

		state->read_date = TRUE;
		return FALSE;

	} else if (*text == 'c' && get_line_type(text) == LINE_COMMIT) {
		string_copy_rev_from_commit_line(state->commit, text);

	} else if (*text == 'a' && get_line_type(text) == LINE_AUTHOR) {
		parse_author_line(text + STRING_SIZE("author "),
				  &state->author, &state->author_time);

	} else if (*text == ':') {
		char *pos;
		size_t annotated = 1;
		size_t i;

		pos = strrchr(text, '\t');
		if (!pos)
			return TRUE;
		text = pos + 1;
		if (*view->env->directory && !strncmp(text, view->env->directory, strlen(view->env->directory)))
			text += strlen(view->env->directory);
		pos = strchr(text, '/');
		if (pos)
			*pos = 0;

		for (i = 1; i < view->lines; i++) {
			struct line *line = &view->line[i];
			struct tree_entry *entry = line->data;

			annotated += !!entry->author;
			if (entry->author || strcmp(entry->name, text))
				continue;

			string_copy_rev(entry->commit, state->commit);
			entry->author = state->author;
			entry->time = state->author_time;
			line->dirty = 1;
			view_column_info_update(view, line);
			break;
		}

		if (annotated == view->lines)
			io_kill(view->pipe);
	}
	return TRUE;
}
示例#16
0
文件: blame.c 项目: peff/tig
static bool
blame_open(struct view *view, enum open_flags flags)
{
	struct blame_state *state = view->private;
	const char *file_argv[] = { repo.cdup, view->env->file , NULL };
	char path[SIZEOF_STR];
	size_t i;

	if (is_initial_view(view)) {
		/* Finish validating and setting up blame options */
		if (!opt_file_argv || opt_file_argv[1] || (opt_rev_argv && opt_rev_argv[1]))
			usage("Invalid number of options to blame");

		if (opt_rev_argv) {
			string_ncopy(view->env->ref, opt_rev_argv[0], strlen(opt_rev_argv[0]));
		}

		string_ncopy(view->env->file, opt_file_argv[0], strlen(opt_file_argv[0]));

		opt_blame_options = opt_cmdline_argv;
		opt_cmdline_argv = NULL;
	}

	if (!view->env->file[0]) {
		report("No file chosen, press %s to open tree view",
			get_view_key(view, REQ_VIEW_TREE));
		return FALSE;
	}

	if (!view->prev && *repo.prefix && !(flags & (OPEN_RELOAD | OPEN_REFRESH))) {
		string_copy(path, view->env->file);
		if (!string_format(view->env->file, "%s%s", repo.prefix, path)) {
			report("Failed to setup the blame view");
			return FALSE;
		}
	}

	if (*view->env->ref || !begin_update(view, repo.cdup, file_argv, flags)) {
		const char *blame_cat_file_argv[] = {
			"git", "cat-file", "blob", "%(ref):%(file)", NULL
		};

		if (!begin_update(view, repo.cdup, blame_cat_file_argv, flags))
			return FALSE;
	}

	/* First pass: remove multiple references to the same commit. */
	for (i = 0; i < view->lines; i++) {
		struct blame *blame = view->line[i].data;

		if (blame->commit && blame->commit->id[0])
			blame->commit->id[0] = 0;
		else
			blame->commit = NULL;
	}

	/* Second pass: free existing references. */
	for (i = 0; i < view->lines; i++) {
		struct blame *blame = view->line[i].data;

		if (blame->commit)
			free(blame->commit);
	}

	if (!(flags & OPEN_RELOAD))
		reset_view_history(&blame_view_history);
	string_copy_rev(state->history_state.id, view->env->ref);
	state->history_state.filename = get_path(view->env->file);
	if (!state->history_state.filename)
		return FALSE;
	string_format(view->vid, "%s", view->env->file);
	string_format(view->ref, "%s ...", view->env->file);

	return TRUE;
}