All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pierre Habouzit <madcoder@debian.org>
To: Junio C Hamano <gitster@pobox.com>
Cc: Git ML <git@vger.kernel.org>
Subject: [PATCH v2] status: display "doing what" information in git status
Date: Fri,  6 May 2011 09:38:55 +0200	[thread overview]
Message-ID: <1304667535-4787-1-git-send-email-madcoder@debian.org> (raw)
In-Reply-To: <7vr58c4sip.fsf@alter.siamese.dyndns.org>
In-Reply-To: <7vr58c4sip.fsf@alter.siamese.dyndns.org>

This provides the same information as the git bash prompt about the
current operation that is going on: rebase, merge, am, cherry-pick or
bisect.

This is very useful for "beginners" who don't have their shell prompt set
up for git.

The logic has been largely borrowed from
contrib/completion/git-completion.bash

when hints are enabled, it also gives hints on how to abort or resolve
that pending situation. For example, with this patch and hints activated,
being in the middle of a `git rebase -i` looks like:

	$ git status
	# in the middle of a git rebase -i of master (detached head)
	#   (use "git rebase --abort" to abort current rebase or proceed)
	# Changes not staged for commit:
	#   (use "git add <file>..." to update what will be committed)
	#   (use "git checkout -- <file>..." to discard changes in working directory)
	#
	#       modified:   lib-common (new commits)
	#
	# Submodules changed but not updated:
	#
	# * lib-common 0b07a6b...11cdf27 (1):
	#   > Add t_sb_init().
	#
	# Untracked files:
	#   (use "git add <file>..." to include in what will be committed)
	#
	#       qdb/a/
	#       qkv/A/
	no changes added to commit (use "git add" and/or "git commit -a")

If we have an ongoing operation then:
- if we are on a branch it displays:
  # On branch $branch ($what_is_ongoing)
  #   ($ongoing_hint)
- if we are on a detached head it displays:
  # $what_is_ongoing (detached head)
  #   ($ongoing_hint)

If we have no ongoing operation the git status does as before:
- if we are on a branch it displays:
  # On branch $branch
- if we are on a detached head it displays:
  # Not currently on any branch.

Since the ongoing operation is usually something to be done with before
continuing with further git operations, the hint and ongoing operations
are displayed with the "WT_STATUS_NOBRANCH" color to be easy to spot.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 wt-status.c |  138 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 123 insertions(+), 15 deletions(-)

diff --git a/wt-status.c b/wt-status.c
index 9f4e0ba..91f6c7c 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -527,6 +527,128 @@ static void wt_status_print_unmerged(struct wt_status *s)
 
 }
 
+static int wt_has_file(const char *what)
+{
+	char path[PATH_MAX];
+
+	return access(git_snpath(path, sizeof(path), "%s", what), F_OK) == 0;
+}
+
+static void wt_status_print_doingwhat(struct wt_status *s)
+{
+	const char *status_nobranch = color(WT_STATUS_NOBRANCH, s);
+	const char *branch_name = s->branch;
+	const char *advice = NULL;
+
+	const char * const rebase_advice =
+		_("use \"git rebase --abort\" to abort current rebase or proceed");
+	const char * const am_advice =
+		_("use \"git am --abort\" to abort current mailbox apply or proceed");
+	const char * const merge_advice =
+		_("use \"git reset --hard\" to abort, or resolve conflicts and commit");
+
+	struct strbuf sb = STRBUF_INIT;
+	char path[PATH_MAX];
+
+	if (!prefixcmp(branch_name, "refs/heads/"))
+		branch_name += 11;
+	else if (!strcmp(branch_name, "HEAD")) {
+		branch_name = NULL;
+	}
+
+	status_printf(s, color(WT_STATUS_HEADER, s), "");
+	if (branch_name) {
+		const char *status_onbranch = color(WT_STATUS_ONBRANCH, s);
+
+		status_printf_more(s, status_onbranch, _("On branch "));
+		status_printf_more(s, status_onbranch, "%s", branch_name);
+	}
+	if (wt_has_file("rebase-merge")) {
+		git_snpath(path, sizeof(path), "%s", "rebase-merge/head-name");
+		strbuf_read_file(&sb, path, 0);
+		strbuf_rtrim(&sb);
+
+		if (branch_name)
+			status_printf_more(s, status_nobranch, " (");
+		status_printf_more(s, status_nobranch,
+				   _("in the middle of a git rebase -%c of %s"),
+				   wt_has_file("rebase-merge/interactive") ? 'i' : 'm',
+				   prefixcmp(sb.buf, "refs/heads/") == 0 ?
+				   sb.buf + 11 : sb.buf);
+		advice = rebase_advice;
+	} else if (wt_has_file("rebase-apply")) {
+		if (branch_name)
+			status_printf_more(s, status_nobranch, " (");
+		if (wt_has_file("rebase-apply/rebasing")) {
+			status_printf_more(s, status_nobranch,
+					   _("in the middle of a git rebase"));
+			advice = rebase_advice;
+		} else if (wt_has_file("rebase-apply/applying")) {
+			status_printf_more(s, status_nobranch,
+					   _("in the middle of a git am"));
+			advice = am_advice;
+		} else {
+			status_printf_more(s, status_nobranch,
+					   _("in the middle of a git rebase/am"));
+			advice = am_advice;
+		}
+	} else if (wt_has_file("MERGE_HEAD")) {
+		git_snpath(path, sizeof(path), "%s", "MERGE_HEAD");
+		strbuf_read_file(&sb, path, 0);
+		strbuf_rtrim(&sb);
+
+		if (branch_name)
+			status_printf_more(s, status_nobranch, " (");
+		status_printf_more(s, status_nobranch,
+				   _("resolving merge with %s"),
+				   prefixcmp(sb.buf, "refs/heads/") == 0 ?
+				   sb.buf + 11 : sb.buf);
+		advice = merge_advice;
+	} else if (wt_has_file("CHERRY_PICK_HEAD")) {
+		unsigned char sha1buf[20];
+
+		git_snpath(path, sizeof(path), "%s", "CHERRY_PICK_HEAD");
+		strbuf_read_file(&sb, path, 0);
+		strbuf_rtrim(&sb);
+
+		if (branch_name)
+			status_printf_more(s, status_nobranch, " (");
+		if (sb.len == 40 && get_sha1_hex(sb.buf, sha1buf) == 0) {
+			status_printf_more(s, status_nobranch,
+					   _("resolving cherry-pick of %s"),
+					   find_unique_abbrev(sha1buf, DEFAULT_ABBREV));
+		} else {
+			status_printf_more(s, status_nobranch,
+					   _("resolving cherry-pick of %s"),
+					   sb.buf);
+		}
+		advice = merge_advice;
+	} else if (wt_has_file("BISECT_LOG")) {
+		if (branch_name)
+			status_printf_more(s, status_nobranch, " (");
+		status_printf_more(s, status_nobranch,
+					   _("in the middle of a git bisect"));
+	} else {
+		if (!branch_name) {
+			status_printf_more(s, status_nobranch,
+					   _("Not currently on any branch."));
+		}
+		status_printf_more(s, "", "\n");
+		return;
+	}
+
+	if (branch_name) {
+		status_printf_more(s, status_nobranch, ")\n");
+	} else {
+		status_printf_more(s, status_nobranch, _(" (detached head)\n"));
+	}
+	if (advice && advice_status_hints) {
+		status_printf(s, color(WT_STATUS_HEADER, s), "");
+		status_printf_more(s, status_nobranch, "  (%s)\n", advice);
+	}
+	strbuf_release(&sb);
+}
+
 static void wt_status_print_updated(struct wt_status *s)
 {
 	int shown_header = 0;
@@ -706,22 +828,8 @@ static void wt_status_print_tracking(struct wt_status *s)
 
 void wt_status_print(struct wt_status *s)
 {
-	const char *branch_color = color(WT_STATUS_ONBRANCH, s);
-	const char *branch_status_color = color(WT_STATUS_HEADER, s);
-
 	if (s->branch) {
-		const char *on_what = _("On branch ");
-		const char *branch_name = s->branch;
-		if (!prefixcmp(branch_name, "refs/heads/"))
-			branch_name += 11;
-		else if (!strcmp(branch_name, "HEAD")) {
-			branch_name = "";
-			branch_status_color = color(WT_STATUS_NOBRANCH, s);
-			on_what = _("Not currently on any branch.");
-		}
-		status_printf(s, color(WT_STATUS_HEADER, s), "");
-		status_printf_more(s, branch_status_color, "%s", on_what);
-		status_printf_more(s, branch_color, "%s\n", branch_name);
+		wt_status_print_doingwhat(s);
 		if (!s->is_initial)
 			wt_status_print_tracking(s);
 	}
-- 
1.7.5.1.290.gfe86e2.dirty

  parent reply	other threads:[~2011-05-06  7:39 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-05 21:48 [PATCH 1/1] status: display "doing what" information in git status Pierre Habouzit
2011-05-05 23:06 ` Sverre Rabbelier
2011-05-05 23:26   ` Pierre Habouzit
2011-05-06  7:48     ` Michael J Gruber
2011-05-06  8:04       ` Pierre Habouzit
2011-05-05 23:37 ` Junio C Hamano
2011-05-05 23:39   ` Pierre Habouzit
2011-05-05 23:47     ` Pierre Habouzit
2011-05-05 23:49     ` Junio C Hamano
2011-05-05 23:51       ` Pierre Habouzit
2011-05-06  7:38       ` Pierre Habouzit [this message]
2011-05-06 10:13         ` [PATCH v2] " Jakub Narebski
2011-05-06 17:40           ` Pierre Habouzit
2011-05-06 17:29         ` Junio C Hamano
2011-05-06 17:36           ` Pierre Habouzit
2011-05-06 18:24             ` Junio C Hamano
2011-05-06 18:40         ` Matthieu Moy
2011-05-06 18:44           ` Pierre Habouzit
2011-05-06 19:15             ` Matthieu Moy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1304667535-4787-1-git-send-email-madcoder@debian.org \
    --to=madcoder@debian.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.