builtin-branch.c 12.0 KB
Newer Older
L
Lars Hjemli 已提交
1 2 3 4 5 6 7 8
/*
 * Builtin "git branch"
 *
 * Copyright (c) 2006 Kristian Hgsberg <krh@redhat.com>
 * Based on git-branch.sh by Junio C Hamano.
 */

#include "cache.h"
9
#include "color.h"
L
Lars Hjemli 已提交
10 11 12 13 14
#include "refs.h"
#include "commit.h"
#include "builtin.h"

static const char builtin_branch_usage[] =
15
  "git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]]";
L
Lars Hjemli 已提交
16

17 18 19 20
#define REF_UNKNOWN_TYPE    0x00
#define REF_LOCAL_BRANCH    0x01
#define REF_REMOTE_BRANCH   0x02
#define REF_TAG             0x04
L
Lars Hjemli 已提交
21 22 23 24

static const char *head;
static unsigned char head_sha1[20];

A
Andy Parkins 已提交
25 26 27 28 29
static int branch_use_color;
static char branch_colors[][COLOR_MAXLEN] = {
	"\033[m",	/* reset */
	"",		/* PLAIN (normal) */
	"\033[31m",	/* REMOTE (red) */
30 31
	"",		/* LOCAL (normal) */
	"\033[32m",	/* CURRENT (green) */
A
Andy Parkins 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
};
enum color_branch {
	COLOR_BRANCH_RESET = 0,
	COLOR_BRANCH_PLAIN = 1,
	COLOR_BRANCH_REMOTE = 2,
	COLOR_BRANCH_LOCAL = 3,
	COLOR_BRANCH_CURRENT = 4,
};

static int parse_branch_color_slot(const char *var, int ofs)
{
	if (!strcasecmp(var+ofs, "plain"))
		return COLOR_BRANCH_PLAIN;
	if (!strcasecmp(var+ofs, "reset"))
		return COLOR_BRANCH_RESET;
	if (!strcasecmp(var+ofs, "remote"))
		return COLOR_BRANCH_REMOTE;
	if (!strcasecmp(var+ofs, "local"))
		return COLOR_BRANCH_LOCAL;
	if (!strcasecmp(var+ofs, "current"))
		return COLOR_BRANCH_CURRENT;
	die("bad config variable '%s'", var);
}

int git_branch_config(const char *var, const char *value)
{
	if (!strcmp(var, "color.branch")) {
		branch_use_color = git_config_colorbool(var, value);
		return 0;
	}
62
	if (!prefixcmp(var, "color.branch.")) {
A
Andy Parkins 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76
		int slot = parse_branch_color_slot(var, 13);
		color_parse(value, var, branch_colors[slot]);
		return 0;
	}
	return git_default_config(var, value);
}

const char *branch_get_color(enum color_branch ix)
{
	if (branch_use_color)
		return branch_colors[ix];
	return "";
}

77
static int delete_branches(int argc, const char **argv, int force, int kinds)
L
Lars Hjemli 已提交
78
{
79
	struct commit *rev, *head_rev = head_rev;
L
Lars Hjemli 已提交
80
	unsigned char sha1[20];
81
	char *name = NULL;
82
	const char *fmt, *remote;
L
Lars Hjemli 已提交
83
	int i;
84
	int ret = 0;
L
Lars Hjemli 已提交
85

86 87 88 89 90 91 92 93 94 95 96 97 98
	switch (kinds) {
	case REF_REMOTE_BRANCH:
		fmt = "refs/remotes/%s";
		remote = "remote ";
		force = 1;
		break;
	case REF_LOCAL_BRANCH:
		fmt = "refs/heads/%s";
		remote = "";
		break;
	default:
		die("cannot use -a with -d");
	}
L
Lars Hjemli 已提交
99

100 101 102 103 104
	if (!force) {
		head_rev = lookup_commit_reference(head_sha1);
		if (!head_rev)
			die("Couldn't look up commit object for HEAD");
	}
L
Lars Hjemli 已提交
105
	for (i = 0; i < argc; i++) {
106 107 108 109 110 111 112 113 114
		if (kinds == REF_LOCAL_BRANCH && !strcmp(head, argv[i])) {
			error("Cannot delete the branch '%s' "
				"which you are currently on.", argv[i]);
			ret = 1;
			continue;
		}

		if (name)
			free(name);
L
Lars Hjemli 已提交
115

116
		name = xstrdup(mkpath(fmt, argv[i]));
117 118 119 120 121 122
		if (!resolve_ref(name, sha1, 1, NULL)) {
			error("%sbranch '%s' not found.",
					remote, argv[i]);
			ret = 1;
			continue;
		}
L
Lars Hjemli 已提交
123 124

		rev = lookup_commit_reference(sha1);
125 126 127 128 129
		if (!rev) {
			error("Couldn't look up commit object for '%s'", name);
			ret = 1;
			continue;
		}
L
Lars Hjemli 已提交
130 131 132 133 134 135 136

		/* This checks whether the merge bases of branch and
		 * HEAD contains branch -- which means that the HEAD
		 * contains everything in both.
		 */

		if (!force &&
137
		    !in_merge_bases(rev, &head_rev, 1)) {
138 139 140 141 142 143
			error("The branch '%s' is not a strict subset of "
				"your current HEAD.\n"
				"If you are sure you want to delete it, "
				"run 'git branch -D %s'.", argv[i], argv[i]);
			ret = 1;
			continue;
L
Lars Hjemli 已提交
144 145
		}

146 147
		if (delete_ref(name, sha1)) {
			error("Error deleting %sbranch '%s'", remote,
148
			       argv[i]);
149 150
			ret = 1;
		} else
151
			printf("Deleted %sbranch %s.\n", remote, argv[i]);
L
Lars Hjemli 已提交
152 153 154

	}

155 156 157 158
	if (name)
		free(name);

	return(ret);
L
Lars Hjemli 已提交
159 160
}

161 162 163
struct ref_item {
	char *name;
	unsigned int kind;
164
	unsigned char sha1[20];
165 166 167
};

struct ref_list {
168
	int index, alloc, maxwidth;
169 170 171 172 173
	struct ref_item *list;
	int kinds;
};

static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
L
Lars Hjemli 已提交
174
{
175 176 177
	struct ref_list *ref_list = (struct ref_list*)(cb_data);
	struct ref_item *newitem;
	int kind = REF_UNKNOWN_TYPE;
178
	int len;
179 180

	/* Detect kind */
181
	if (!prefixcmp(refname, "refs/heads/")) {
182 183
		kind = REF_LOCAL_BRANCH;
		refname += 11;
184
	} else if (!prefixcmp(refname, "refs/remotes/")) {
185 186
		kind = REF_REMOTE_BRANCH;
		refname += 13;
187
	} else if (!prefixcmp(refname, "refs/tags/")) {
188 189 190 191 192 193 194 195 196 197 198 199 200
		kind = REF_TAG;
		refname += 10;
	}

	/* Don't add types the caller doesn't want */
	if ((kind & ref_list->kinds) == 0)
		return 0;

	/* Resize buffer */
	if (ref_list->index >= ref_list->alloc) {
		ref_list->alloc = alloc_nr(ref_list->alloc);
		ref_list->list = xrealloc(ref_list->list,
				ref_list->alloc * sizeof(struct ref_item));
L
Lars Hjemli 已提交
201 202
	}

203 204 205 206
	/* Record the new item */
	newitem = &(ref_list->list[ref_list->index++]);
	newitem->name = xstrdup(refname);
	newitem->kind = kind;
207 208 209 210
	hashcpy(newitem->sha1, sha1);
	len = strlen(newitem->name);
	if (len > ref_list->maxwidth)
		ref_list->maxwidth = len;
L
Lars Hjemli 已提交
211 212 213 214

	return 0;
}

215 216 217 218 219 220 221 222 223
static void free_ref_list(struct ref_list *ref_list)
{
	int i;

	for (i = 0; i < ref_list->index; i++)
		free(ref_list->list[i].name);
	free(ref_list->list);
}

L
Lars Hjemli 已提交
224 225
static int ref_cmp(const void *r1, const void *r2)
{
226 227 228 229 230 231
	struct ref_item *c1 = (struct ref_item *)(r1);
	struct ref_item *c2 = (struct ref_item *)(r2);

	if (c1->kind != c2->kind)
		return c1->kind - c2->kind;
	return strcmp(c1->name, c2->name);
L
Lars Hjemli 已提交
232 233
}

234 235
static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
			   int abbrev, int current)
236
{
237 238
	char c;
	int color;
239 240 241
	struct commit *commit;
	char subject[256];

242 243 244 245 246 247 248 249 250 251 252
	switch (item->kind) {
	case REF_LOCAL_BRANCH:
		color = COLOR_BRANCH_LOCAL;
		break;
	case REF_REMOTE_BRANCH:
		color = COLOR_BRANCH_REMOTE;
		break;
	default:
		color = COLOR_BRANCH_PLAIN;
		break;
	}
253

254 255 256 257 258
	c = ' ';
	if (current) {
		c = '*';
		color = COLOR_BRANCH_CURRENT;
	}
259

260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
	if (verbose) {
		commit = lookup_commit(item->sha1);
		if (commit && !parse_commit(commit))
			pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
					    subject, sizeof(subject), 0,
					    NULL, NULL, 0);
		else
			strcpy(subject, " **** invalid ref ****");
		printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color),
		       maxwidth, item->name,
		       branch_get_color(COLOR_BRANCH_RESET),
		       find_unique_abbrev(item->sha1, abbrev), subject);
	} else {
		printf("%c %s%s%s\n", c, branch_get_color(color), item->name,
		       branch_get_color(COLOR_BRANCH_RESET));
	}
276 277
}

L
Lars Hjemli 已提交
278
static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
L
Lars Hjemli 已提交
279 280
{
	int i;
281
	struct ref_list ref_list;
L
Lars Hjemli 已提交
282

283 284 285
	memset(&ref_list, 0, sizeof(ref_list));
	ref_list.kinds = kinds;
	for_each_ref(append_ref, &ref_list);
L
Lars Hjemli 已提交
286

287
	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
L
Lars Hjemli 已提交
288

L
Lars Hjemli 已提交
289 290 291 292 293 294 295 296 297 298 299
	detached = (detached && (kinds & REF_LOCAL_BRANCH));
	if (detached) {
		struct ref_item item;
		item.name = "(no branch)";
		item.kind = REF_LOCAL_BRANCH;
		hashcpy(item.sha1, head_sha1);
		if (strlen(item.name) > ref_list.maxwidth)
			      ref_list.maxwidth = strlen(item.name);
		print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);
	}

300
	for (i = 0; i < ref_list.index; i++) {
L
Lars Hjemli 已提交
301 302
		int current = !detached &&
			(ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
303 304 305
			!strcmp(ref_list.list[i].name, head);
		print_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose,
			       abbrev, current);
L
Lars Hjemli 已提交
306
	}
307 308

	free_ref_list(&ref_list);
L
Lars Hjemli 已提交
309 310
}

J
Junio C Hamano 已提交
311 312
static void create_branch(const char *name, const char *start_name,
			  unsigned char *start_sha1,
L
Lars Hjemli 已提交
313 314 315 316 317 318
			  int force, int reflog)
{
	struct ref_lock *lock;
	struct commit *commit;
	unsigned char sha1[20];
	char ref[PATH_MAX], msg[PATH_MAX + 20];
319
	int forcing = 0;
L
Lars Hjemli 已提交
320 321 322 323 324 325 326 327

	snprintf(ref, sizeof ref, "refs/heads/%s", name);
	if (check_ref_format(ref))
		die("'%s' is not a valid branch name.", name);

	if (resolve_ref(ref, sha1, 1, NULL)) {
		if (!force)
			die("A branch named '%s' already exists.", name);
328
		else if (!is_bare_repository() && !strcmp(head, name))
L
Lars Hjemli 已提交
329
			die("Cannot force update the current branch.");
330
		forcing = 1;
L
Lars Hjemli 已提交
331 332
	}

J
Junio C Hamano 已提交
333 334 335 336 337 338 339 340
	if (start_sha1)
		/* detached HEAD */
		hashcpy(sha1, start_sha1);
	else if (get_sha1(start_name, sha1))
		die("Not a valid object name: '%s'.", start_name);

	if ((commit = lookup_commit_reference(sha1)) == NULL)
		die("Not a valid branch point: '%s'.", start_name);
L
Lars Hjemli 已提交
341 342 343 344 345 346
	hashcpy(sha1, commit->object.sha1);

	lock = lock_any_ref_for_update(ref, NULL);
	if (!lock)
		die("Failed to lock ref for update: %s.", strerror(errno));

347
	if (reflog)
L
Lars Hjemli 已提交
348
		log_all_ref_updates = 1;
349 350 351 352 353

	if (forcing)
		snprintf(msg, sizeof msg, "branch: Reset from %s",
			 start_name);
	else
J
Junio C Hamano 已提交
354 355
		snprintf(msg, sizeof msg, "branch: Created from %s",
			 start_name);
L
Lars Hjemli 已提交
356 357 358 359 360

	if (write_ref_sha1(lock, sha1, msg) < 0)
		die("Failed to write ref: %s.", strerror(errno));
}

361 362
static void rename_branch(const char *oldname, const char *newname, int force)
{
363
	char oldref[PATH_MAX], newref[PATH_MAX], logmsg[PATH_MAX*2 + 100];
364 365
	unsigned char sha1[20];

J
Junio C Hamano 已提交
366
	if (!oldname)
P
Pavel Roskin 已提交
367
		die("cannot rename the current branch while not on any.");
J
Junio C Hamano 已提交
368

369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
	if (snprintf(oldref, sizeof(oldref), "refs/heads/%s", oldname) > sizeof(oldref))
		die("Old branchname too long");

	if (check_ref_format(oldref))
		die("Invalid branch name: %s", oldref);

	if (snprintf(newref, sizeof(newref), "refs/heads/%s", newname) > sizeof(newref))
		die("New branchname too long");

	if (check_ref_format(newref))
		die("Invalid branch name: %s", newref);

	if (resolve_ref(newref, sha1, 1, NULL) && !force)
		die("A branch named '%s' already exists.", newname);

384 385 386 387
	snprintf(logmsg, sizeof(logmsg), "Branch: renamed %s to %s",
		 oldref, newref);

	if (rename_ref(oldref, newref, logmsg))
388 389
		die("Branch rename failed");

390 391
	/* no need to pass logmsg here as HEAD didn't really move */
	if (!strcmp(oldname, head) && create_symref("HEAD", newref, NULL))
392 393 394
		die("Branch renamed to %s, but HEAD is not updated!", newname);
}

L
Lars Hjemli 已提交
395 396
int cmd_branch(int argc, const char **argv, const char *prefix)
{
397
	int delete = 0, force_delete = 0, force_create = 0;
398
	int rename = 0, force_rename = 0;
L
Lars Hjemli 已提交
399
	int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
L
Lars Hjemli 已提交
400
	int reflog = 0;
401
	int kinds = REF_LOCAL_BRANCH;
L
Lars Hjemli 已提交
402 403
	int i;

A
Andy Parkins 已提交
404
	git_config(git_branch_config);
L
Lars Hjemli 已提交
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427

	for (i = 1; i < argc; i++) {
		const char *arg = argv[i];

		if (arg[0] != '-')
			break;
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
		if (!strcmp(arg, "-d")) {
			delete = 1;
			continue;
		}
		if (!strcmp(arg, "-D")) {
			delete = 1;
			force_delete = 1;
			continue;
		}
		if (!strcmp(arg, "-f")) {
			force_create = 1;
			continue;
		}
428 429 430 431 432 433 434 435 436
		if (!strcmp(arg, "-m")) {
			rename = 1;
			continue;
		}
		if (!strcmp(arg, "-M")) {
			rename = 1;
			force_rename = 1;
			continue;
		}
L
Lars Hjemli 已提交
437
		if (!strcmp(arg, "-r")) {
438 439 440 441 442
			kinds = REF_REMOTE_BRANCH;
			continue;
		}
		if (!strcmp(arg, "-a")) {
			kinds = REF_REMOTE_BRANCH | REF_LOCAL_BRANCH;
L
Lars Hjemli 已提交
443 444 445 446 447 448
			continue;
		}
		if (!strcmp(arg, "-l")) {
			reflog = 1;
			continue;
		}
449 450 451 452
		if (!prefixcmp(arg, "--no-abbrev")) {
			abbrev = 0;
			continue;
		}
453
		if (!prefixcmp(arg, "--abbrev=")) {
454 455 456 457 458
			abbrev = strtoul(arg + 9, NULL, 10);
			if (abbrev < MINIMUM_ABBREV)
				abbrev = MINIMUM_ABBREV;
			else if (abbrev > 40)
				abbrev = 40;
459 460 461 462 463 464
			continue;
		}
		if (!strcmp(arg, "-v")) {
			verbose = 1;
			continue;
		}
A
Andy Parkins 已提交
465 466 467 468 469 470 471 472
		if (!strcmp(arg, "--color")) {
			branch_use_color = 1;
			continue;
		}
		if (!strcmp(arg, "--no-color")) {
			branch_use_color = 0;
			continue;
		}
L
Lars Hjemli 已提交
473 474 475
		usage(builtin_branch_usage);
	}

476 477 478 479
	if ((delete && rename) || (delete && force_create) ||
	    (rename && force_create))
		usage(builtin_branch_usage);

L
Lars Hjemli 已提交
480 481 482
	head = xstrdup(resolve_ref("HEAD", head_sha1, 0, NULL));
	if (!head)
		die("Failed to resolve HEAD as a valid ref.");
L
Lars Hjemli 已提交
483 484 485 486
	if (!strcmp(head, "HEAD")) {
		detached = 1;
	}
	else {
487
		if (prefixcmp(head, "refs/heads/"))
L
Lars Hjemli 已提交
488 489 490
			die("HEAD not found below refs/heads!");
		head += 11;
	}
L
Lars Hjemli 已提交
491 492

	if (delete)
493
		return delete_branches(argc - i, argv + i, force_delete, kinds);
L
Lars Hjemli 已提交
494
	else if (i == argc)
L
Lars Hjemli 已提交
495
		print_ref_list(kinds, detached, verbose, abbrev);
496 497 498 499
	else if (rename && (i == argc - 1))
		rename_branch(head, argv[i], force_rename);
	else if (rename && (i == argc - 2))
		rename_branch(argv[i], argv[i + 1], force_rename);
L
Lars Hjemli 已提交
500
	else if (i == argc - 1)
J
Junio C Hamano 已提交
501
		create_branch(argv[i], head, head_sha1, force_create, reflog);
L
Lars Hjemli 已提交
502
	else if (i == argc - 2)
J
Junio C Hamano 已提交
503
		create_branch(argv[i], argv[i+1], NULL, force_create, reflog);
L
Lars Hjemli 已提交
504 505 506 507 508
	else
		usage(builtin_branch_usage);

	return 0;
}