From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH] log: new option decorate reflog of remote refs
Date: Thu, 19 Jan 2017 19:26:30 +0700 [thread overview]
Message-ID: <20170119122630.27645-1-pclouds@gmail.com> (raw)
This is most useful when you fork your branches off a remote ref and
rely on ref decoration to show your fork points in `git log`. Then you
do a "git fetch" and suddenly the remote decoration is gone because
remote refs are moved forward. With this, we can still see something
like "origin/foo@{1}"
This is for remote refs only because based on my experience, docorating
local reflog is just too noisy. You will most likely see HEAD@{1},
HEAD@{2} and so on. We can add that as a separate option in future if we
see a need for it.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
I've been using this for many weeks and it has proven its usefulness
(to me). Looks like good material to send upstream.
Documentation/git-log.txt | 5 +++++
builtin/log.c | 10 +++++++++-
log-tree.c | 43 +++++++++++++++++++++++++++++++++++++++----
log-tree.h | 2 +-
pretty.c | 4 ++--
revision.c | 2 +-
6 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index 32246fd..f5ee575 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -38,6 +38,11 @@ OPTIONS
are shown as if 'short' were given, otherwise no ref names are
shown. The default option is 'short'.
+--decorate-remote-reflog[=<n>]::
+ Decorate `<n>` most recent reflog entries on remote refs, up
+ to the specified number of entries. By default, only the most
+ recent reflog entry is decorated.
+
--source::
Print out the ref name given on the command line by which each
commit was reached.
diff --git a/builtin/log.c b/builtin/log.c
index 55d20cc..c208703 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -36,6 +36,7 @@ static int default_follow;
static int default_show_signature;
static int decoration_style;
static int decoration_given;
+static int decorate_remote_reflog;
static int use_mailmap_config;
static const char *fmt_patch_subject_prefix = "PATCH";
static const char *fmt_pretty;
@@ -141,6 +142,10 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
PARSE_OPT_OPTARG, decorate_callback},
+ { OPTION_INTEGER, 0, "decorate-remote-reflog",
+ &decorate_remote_reflog, N_("n"),
+ N_("decorate the last <n> reflog entries of remote refs"),
+ PARSE_OPT_OPTARG | PARSE_OPT_NONEG, NULL, 1 },
OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
N_("Process line range n,m in file, counting from 1"),
log_line_range_callback),
@@ -195,9 +200,12 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
rev->abbrev_commit = 0;
}
+ if (decorate_remote_reflog > 0 && !decoration_style)
+ decoration_style = DECORATE_SHORT_REFS;
if (decoration_style) {
rev->show_decorations = 1;
- load_ref_decorations(decoration_style);
+ load_ref_decorations(decoration_style,
+ decorate_remote_reflog);
}
if (rev->line_level_traverse)
diff --git a/log-tree.c b/log-tree.c
index 8c24157..3d85ebc 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -88,14 +88,37 @@ const struct name_decoration *get_name_decoration(const struct object *obj)
return lookup_decoration(&name_decoration, obj);
}
+struct reflog_cb {
+ int type;
+ int count;
+ int nth;
+ const char *refname;
+};
+
+static int add_nth_reflog(unsigned char *osha1, unsigned char *nsha1,
+ const char *email, unsigned long timestamp, int tz,
+ const char *message, void *cb_data)
+{
+ struct reflog_cb *cb = cb_data;
+ struct commit *commit;
+
+ commit = lookup_commit(nsha1);
+ if (commit && cb->nth) {
+ struct strbuf sb = STRBUF_INIT;
+ strbuf_addf(&sb, "%s@{%d}", cb->refname, cb->nth);
+ add_name_decoration(cb->type, sb.buf, &commit->object);
+ strbuf_release(&sb);
+ }
+ cb->nth++;
+ return cb->nth >= cb->count;
+}
+
static int add_ref_decoration(const char *refname, const struct object_id *oid,
int flags, void *cb_data)
{
struct object *obj;
enum decoration_type type = DECORATION_NONE;
- assert(cb_data == NULL);
-
if (starts_with(refname, git_replace_ref_base)) {
struct object_id original_oid;
if (!check_replace_refs)
@@ -135,6 +158,17 @@ static int add_ref_decoration(const char *refname, const struct object_id *oid,
parse_object(obj->oid.hash);
add_name_decoration(DECORATION_REF_TAG, refname, obj);
}
+
+ if (cb_data && type == DECORATION_REF_REMOTE) {
+ struct reflog_cb cb;
+
+ memset(&cb, 0, sizeof(cb));
+ cb.refname = refname;
+ cb.type = type;
+ cb.count = *(int *)cb_data + 1 /* for @{0} */;
+
+ for_each_reflog_ent_reverse(refname, add_nth_reflog, &cb);
+ }
return 0;
}
@@ -147,13 +181,14 @@ static int add_graft_decoration(const struct commit_graft *graft, void *cb_data)
return 0;
}
-void load_ref_decorations(int flags)
+void load_ref_decorations(int flags, int remote_reflog)
{
if (!decoration_loaded) {
+ void *cb = remote_reflog ? &remote_reflog : NULL;
decoration_loaded = 1;
decoration_flags = flags;
- for_each_ref(add_ref_decoration, NULL);
+ for_each_ref(add_ref_decoration, cb);
head_ref(add_ref_decoration, NULL);
for_each_commit_graft(add_graft_decoration, NULL);
}
diff --git a/log-tree.h b/log-tree.h
index c8116e6..bb46c53 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -25,7 +25,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
const char **subject_p,
const char **extra_headers_p,
int *need_8bit_cte_p);
-void load_ref_decorations(int flags);
+void load_ref_decorations(int flags, int reflog);
#define FORMAT_PATCH_NAME_MAX 64
void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *);
diff --git a/pretty.c b/pretty.c
index 5e68383..ec8e1cc 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1189,11 +1189,11 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
strbuf_addstr(sb, get_revision_mark(NULL, commit));
return 1;
case 'd':
- load_ref_decorations(DECORATE_SHORT_REFS);
+ load_ref_decorations(DECORATE_SHORT_REFS, 0);
format_decorations(sb, commit, c->auto_color);
return 1;
case 'D':
- load_ref_decorations(DECORATE_SHORT_REFS);
+ load_ref_decorations(DECORATE_SHORT_REFS, 0);
format_decorations_extended(sb, commit, c->auto_color, "", ", ", "");
return 1;
case 'g': /* reflog info */
diff --git a/revision.c b/revision.c
index b37dbec..4d5cbf5 100644
--- a/revision.c
+++ b/revision.c
@@ -1743,7 +1743,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->simplify_by_decoration = 1;
revs->limited = 1;
revs->prune = 1;
- load_ref_decorations(DECORATE_SHORT_REFS);
+ load_ref_decorations(DECORATE_SHORT_REFS, 0);
} else if (!strcmp(arg, "--date-order")) {
revs->sort_order = REV_SORT_BY_COMMIT_DATE;
revs->topo_order = 1;
--
2.8.2.524.g6ff3d78
next reply other threads:[~2017-01-19 12:26 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-19 12:26 Nguyễn Thái Ngọc Duy [this message]
2017-01-19 17:23 ` [PATCH] log: new option decorate reflog of remote refs Jeff King
2017-01-20 10:55 ` Duy Nguyen
2017-01-20 14:30 ` Jeff King
2017-01-20 22:00 ` Jacob Keller
2017-01-21 12:48 ` Duy Nguyen
2017-01-21 14:08 ` Jeff King
2017-01-25 12:50 ` [PATCH 0/5] Prep steps for --decorate-reflog Nguyễn Thái Ngọc Duy
2017-01-25 12:50 ` [PATCH 1/5] rev-list-options.txt: delete an empty line Nguyễn Thái Ngọc Duy
2017-01-25 12:50 ` [PATCH 2/5] revision.c: group ref selection options together Nguyễn Thái Ngọc Duy
2017-01-25 20:50 ` Jeff King
2017-01-26 9:18 ` Duy Nguyen
2017-01-26 14:19 ` Jeff King
2017-01-25 21:11 ` Junio C Hamano
2017-01-26 9:12 ` Duy Nguyen
2017-01-25 12:50 ` [PATCH 3/5] revision.c: allow to change pseudo opt parsing function Nguyễn Thái Ngọc Duy
2017-01-25 12:50 ` [PATCH 4/5] revision.c: refactor ref selection handler after --exclude Nguyễn Thái Ngọc Duy
2017-01-25 17:41 ` Jacob Keller
2017-01-25 20:57 ` Jeff King
2017-01-25 21:27 ` Jeff King
2017-01-25 21:30 ` Jacob Keller
2017-01-25 23:25 ` Junio C Hamano
2017-01-26 9:28 ` Duy Nguyen
2017-01-26 14:24 ` Jeff King
2017-01-26 18:43 ` Junio C Hamano
2017-01-25 21:15 ` Junio C Hamano
2017-01-25 12:50 ` [PATCH 5/5] revision.c: add --decorate-reflog Nguyễn Thái Ngọc Duy
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=20170119122630.27645-1-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/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.