From: Nazri Ramliy <ayiehere@gmail.com>
To: git@vger.kernel.org
Cc: Nazri Ramliy <ayiehere@gmail.com>
Subject: [PATCH 1/6] Teach --id/-d to "git status"
Date: Wed, 5 Aug 2009 17:51:41 +0800 [thread overview]
Message-ID: <1249465906-3940-2-git-send-email-ayiehere@gmail.com> (raw)
In-Reply-To: <1249465906-3940-1-git-send-email-ayiehere@gmail.com>
This patch adds a unique identifier for each file shown by "git status".
Subsequent operation (add/rm/checkout/commit/reset) may use these ids
to simplify specifying the files, provided that they are taught about
the --id option as well.
Example:
$ git status --id
# On branch local
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: builtin-add.c (m1)
# modified: builtin-checkout.c (m2)
# modified: builtin-commit.c (m3)
# modified: builtin-reset.c (m4)
# modified: builtin-rm.c (m5)
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# makefile.debug (x1)
# nazri.sh (x2)
no changes added to commit (use "git add" and/or "git commit -a")
$ git add --id m1
# Short for "git add builtin-add.c
$ git add --id m3,m5
# Short for "git add builtin-commit.c builtin-rm.c"
# Even shorter: -d is equivalent to --id
$ git add -d m3,m5
Signed-off-by: Nazri Ramliy <ayiehere@gmail.com>
---
cache.h | 1 +
path.c | 44 ++++++++++++++++++
wt-status.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
wt-status.h | 1 +
4 files changed, 181 insertions(+), 11 deletions(-)
diff --git a/cache.h b/cache.h
index e6c7f33..05817e3 100644
--- a/cache.h
+++ b/cache.h
@@ -649,6 +649,7 @@ const char *make_relative_path(const char *abs, const char *base);
int normalize_path_copy(char *dst, const char *src);
int longest_ancestor_length(const char *path, const char *prefix_list);
char *strip_path_suffix(const char *path, const char *suffix);
+char ** expand_file_ids(const char *file_id, int *argc, char **argv);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index 047fdb0..7824c4a 100644
--- a/path.c
+++ b/path.c
@@ -564,3 +564,47 @@ char *strip_path_suffix(const char *path, const char *suffix)
return NULL;
return xstrndup(path, chomp_trailing_dir_sep(path, path_len));
}
+
+char ** expand_file_ids(const char *file_id, int *argc, char **argv)
+{
+ FILE *fp;
+ const char *filename = git_path("FILE_IDS");
+ struct strbuf sb = STRBUF_INIT;
+ int i;
+
+ char **new_argv;
+
+ new_argv = (char **) xmalloc(*argc * sizeof(char *));
+ for (i = 0; i < *argc; i++) {
+ new_argv[i] = (char *) argv[i];
+ }
+
+ fp = fopen(filename, "r");
+ if (!fp)
+ die("cannot open %s: %s\n", filename, strerror(errno));
+
+ while (strbuf_getline(&sb, fp, '\n') == 0) {
+ char *b, *e;
+ if (sb.len == 0)
+ continue;
+ b = e = sb.buf;
+ while(*e && *e != ' ')
+ e++;
+ *e = '\0';
+ if(strstr(file_id, b)) {
+ (*argc)++;
+ new_argv = xrealloc(new_argv, (*argc) * sizeof(char *));
+ new_argv[*argc - 1] = xstrdup(e+1);
+ }
+ }
+ strbuf_release(&sb);
+
+ /*
+ * parse_options adds a NULL terminator at end of argv. Do the same for
+ * new_argv.
+ */
+ new_argv = xrealloc(new_argv, *argc + 1 * sizeof(char *));
+ new_argv[*argc] = NULL;
+
+ return new_argv;
+}
diff --git a/wt-status.c b/wt-status.c
index 47735d8..6013fbd 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -96,6 +96,106 @@ static void wt_status_print_trailer(struct wt_status *s)
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
}
+struct id_list {
+ struct id_list *next;
+ char status;
+ int nr;
+ char *name;
+};
+
+static struct id_list *wt_files = NULL;
+static struct id_list *wt_files_last = NULL;
+static int n_id_list = 0;
+
+static int get_id_list_id(char status)
+{
+ static int added = 0;
+ static int copied = 0;
+ static int deleted = 0;
+ static int modified = 0;
+ static int renamed = 0;
+ static int type_changed = 0;
+ static int unknown = 0;
+ static int unmerged = 0;
+
+ switch(status) {
+ case DIFF_STATUS_ADDED:
+ return ++added;
+ case DIFF_STATUS_COPIED:
+ return ++copied;
+ case DIFF_STATUS_DELETED:
+ return ++deleted;
+ case DIFF_STATUS_MODIFIED:
+ return ++modified;
+ case DIFF_STATUS_RENAMED:
+ return ++renamed;
+ case DIFF_STATUS_TYPE_CHANGED:
+ return ++type_changed;
+ case DIFF_STATUS_UNKNOWN:
+ return ++unknown;
+ case DIFF_STATUS_UNMERGED:
+ return ++unmerged;
+ }
+ die("bug: unhandled diff status %c", status);
+}
+
+static int add_to_id_list(char status, const char *name)
+{
+ struct id_list *new_entry;
+ if(wt_files_last == NULL) {
+ wt_files = xcalloc(1, sizeof(*wt_files));
+ wt_files_last = wt_files;
+ new_entry = wt_files_last;
+ } else {
+ wt_files_last->next = xcalloc(1, sizeof(*wt_files));
+ new_entry = wt_files_last->next;
+ wt_files_last = wt_files_last->next;
+ }
+ new_entry->name = xstrdup(name);
+ new_entry->nr = get_id_list_id(status);
+ new_entry->status = status;
+ new_entry->next = NULL;
+
+ n_id_list++;
+
+ return new_entry->nr;
+}
+
+static void store_id_list()
+{
+ FILE *fp;
+ struct id_list *p = wt_files;
+ const char *filename = git_path("FILE_IDS");
+
+ fp = fopen(filename, "w");
+ if (!fp)
+ die("cannot open %s: %s\n", filename, strerror(errno));
+
+ while (p) {
+ fprintf(fp, "%c%d %s\n",tolower(p->status), p->nr, p->name);
+ p = p->next;
+ }
+ fclose(fp);
+}
+
+static void free_id_list()
+{
+ struct id_list *p = wt_files;
+ struct id_list *next = p;
+ while (p) {
+ next = p->next;
+ free(p->name);
+ free(p);
+ p = next;
+ }
+ wt_files = NULL;
+}
+
+static void format_id(char *buf, char status, int nr)
+{
+ sprintf(buf, " (%c%d)", tolower(status), nr);
+}
+
#define quote_path quote_path_relative
static void wt_status_print_filepair(struct wt_status *s,
@@ -104,35 +204,48 @@ static void wt_status_print_filepair(struct wt_status *s,
const char *c = color(t);
const char *one, *two;
struct strbuf onebuf = STRBUF_INIT, twobuf = STRBUF_INIT;
+ char id[64] = ""; /* arbitrary limit, 64 should be enough for everybody ... */
+ int nr;
one = quote_path(p->one->path, -1, &onebuf, s->prefix);
two = quote_path(p->two->path, -1, &twobuf, s->prefix);
+ if (s->show_file_id) {
+ if ( p->status == DIFF_STATUS_RENAMED
+ || p->status == DIFF_STATUS_COPIED)
+ nr = add_to_id_list(p->status, two);
+ else
+ nr = add_to_id_list(p->status, one);
+ format_id(id, p->status, nr);
+ }
+
+
color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
switch (p->status) {
case DIFF_STATUS_ADDED:
- color_fprintf(s->fp, c, "new file: %s", one);
+ color_fprintf(s->fp, c, "new file: %s%s", one, id);
break;
case DIFF_STATUS_COPIED:
- color_fprintf(s->fp, c, "copied: %s -> %s", one, two);
+ color_fprintf(s->fp, c, "copied: %s -> %s%s", one, two, id);
break;
case DIFF_STATUS_DELETED:
- color_fprintf(s->fp, c, "deleted: %s", one);
+ color_fprintf(s->fp, c, "deleted: %s%s", one, id);
break;
case DIFF_STATUS_MODIFIED:
- color_fprintf(s->fp, c, "modified: %s", one);
+ color_fprintf(s->fp, c, "modified: %s%s", one, id);
+
break;
case DIFF_STATUS_RENAMED:
- color_fprintf(s->fp, c, "renamed: %s -> %s", one, two);
+ color_fprintf(s->fp, c, "renamed: %s -> %s%s", one, two, id);
break;
case DIFF_STATUS_TYPE_CHANGED:
- color_fprintf(s->fp, c, "typechange: %s", one);
+ color_fprintf(s->fp, c, "typechange: %s%s", one, id);
break;
case DIFF_STATUS_UNKNOWN:
- color_fprintf(s->fp, c, "unknown: %s", one);
+ color_fprintf(s->fp, c, "unknown: %s%s", one, id);
break;
case DIFF_STATUS_UNMERGED:
- color_fprintf(s->fp, c, "unmerged: %s", one);
+ color_fprintf(s->fp, c, "unmerged: %s%s", one, id);
break;
default:
die("bug: unhandled diff status %c", p->status);
@@ -247,6 +360,9 @@ static void wt_status_print_untracked(struct wt_status *s)
int i;
int shown_header = 0;
struct strbuf buf = STRBUF_INIT;
+ char id[64] = ""; /* arbitrary limit, 64 should be enough for everybody ... */
+ char *quoted;
+ int nr;
memset(&dir, 0, sizeof(dir));
@@ -266,9 +382,13 @@ static void wt_status_print_untracked(struct wt_status *s)
shown_header = 1;
}
color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
- color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%s",
- quote_path(ent->name, ent->len,
- &buf, s->prefix));
+ quoted = quote_path(ent->name, ent->len, &buf, s->prefix);
+ if (s->show_file_id) {
+ nr = add_to_id_list(DIFF_STATUS_UNKNOWN, quoted);
+ format_id(id, DIFF_STATUS_UNKNOWN, nr);
+ }
+ color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%s%s",
+ quoted, id);
}
strbuf_release(&buf);
}
@@ -370,6 +490,10 @@ void wt_status_print(struct wt_status *s)
else
printf("nothing to commit (working directory clean)\n");
}
+ if (s->show_file_id) {
+ store_id_list();
+ free_id_list();
+ }
}
int git_status_config(const char *k, const char *v, void *cb)
diff --git a/wt-status.h b/wt-status.h
index 78add09..efcb566 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -23,6 +23,7 @@ struct wt_status {
char *branch;
const char *reference;
int verbose;
+ int show_file_id;
int amend;
int untracked;
int nowarn;
--
1.6.4.13.ge6580
next prev parent reply other threads:[~2009-08-05 9:55 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-05 9:51 [PATCH] RFC - Say goodbye to the rodent Nazri Ramliy
2009-08-05 9:51 ` Nazri Ramliy [this message]
2009-08-05 9:51 ` [PATCH 2/6] Teach --id to "git add" Nazri Ramliy
2009-08-05 9:51 ` [PATCH 3/6] Teach --id to "git checkout" Nazri Ramliy
2009-08-05 9:51 ` [PATCH 4/6] Teach --d to "git commit" Nazri Ramliy
2009-08-05 9:51 ` [PATCH 5/6] Teach --id to "git rm" Nazri Ramliy
2009-08-05 9:51 ` [PATCH 6/6] Teach --id to "git reset" Nazri Ramliy
2009-08-05 18:11 ` [PATCH 1/6] Teach --id/-d to "git status" Alex Riesen
2009-08-05 18:25 ` Sverre Rabbelier
2009-08-05 18:27 ` Junio C Hamano
2009-08-05 18:30 ` Sverre Rabbelier
2009-08-05 18:33 ` Alex Riesen
2009-08-05 18:35 ` Sverre Rabbelier
2009-08-05 10:04 ` [PATCH] RFC - Say goodbye to the rodent Andreas Ericsson
2009-08-05 11:54 ` Matthieu Moy
2009-08-05 19:02 ` Jeff King
2009-08-05 20:01 ` Nicolas Pitre
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=1249465906-3940-2-git-send-email-ayiehere@gmail.com \
--to=ayiehere@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).