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 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.