* [PATCH] RFC - Say goodbye to the rodent
@ 2009-08-05 9:51 Nazri Ramliy
2009-08-05 9:51 ` [PATCH 1/6] Teach --id/-d to "git status" Nazri Ramliy
` (3 more replies)
0 siblings, 4 replies; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git
Hello list,
Git status provides a list of modified/staged files etc.
Normally I use the mouse to cut and paste the filenames in subsequent git
operations.
Oftentimes I get tired of moving my hand away from the comfort of the home rows
of my keybard in order to grab the mouse to highlight the files that I'd like
to operate on.
This patch is my attempt at scratching this itch. It is, at best, works fine;
albeit a little bit experimental. I may have overlooked a dozen things -
variable names, places where I define the variables etc. If people find this useful
I'll look into polishing the code. All seem to work well. Running make test
does not break anything. I have not written test case for them.
The idea is that "git status --id" shows a unique id for each file in its output
(modified/staged/unknown/etc). The ids and the corresponding filenames are
stored in .git/FILE_IDS. This file gets overwritten everytime you run "git
status --id"
Subsequent git operations can be taught to accept the --id command line option
to tell them what files to operate on. They will read the FILE_IDS to find out
which file to operate based on the given id. In the patch series I have taught
the add, checkout, commit, rm and reset commands the --id option.
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-write-tree.c (m1)
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# file1.c (x1)
# file2.c (x2)
Note the id at the end of the files.
Now we can do the following:
$ git add --id m1
Ids are specified via the --id command line option, and can be separated with
commas if you want to specify more than one of them:
$ git add --id m1,x2
You get the idea ...
What do you guys think about this new approach of "cut-and-paste" from the
command line?
Where would be the best place to put the file id? end? beginning? before ':'?
The argument to --id could be improved so that it understand regexes for file ids.
Comments are welcomed.
Nazri.
--
builtin-add.c | 19 +++++--
builtin-checkout.c | 26 ++++++---
builtin-commit.c | 4 +-
builtin-reset.c | 32 +++++++----
builtin-rm.c | 11 ++++-
cache.h | 1 +
path.c | 44 ++++++++++++++++
wt-status.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++----
wt-status.h | 1 +
9 files changed, 245 insertions(+), 39 deletions(-)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/6] Teach --id/-d to "git status"
2009-08-05 9:51 [PATCH] RFC - Say goodbye to the rodent Nazri Ramliy
@ 2009-08-05 9:51 ` Nazri Ramliy
2009-08-05 9:51 ` [PATCH 2/6] Teach --id to "git add" Nazri Ramliy
2009-08-05 18:11 ` [PATCH 1/6] Teach --id/-d to "git status" Alex Riesen
2009-08-05 10:04 ` [PATCH] RFC - Say goodbye to the rodent Andreas Ericsson
` (2 subsequent siblings)
3 siblings, 2 replies; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git; +Cc: Nazri Ramliy
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
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/6] Teach --id to "git add"
2009-08-05 9:51 ` [PATCH 1/6] Teach --id/-d to "git status" Nazri Ramliy
@ 2009-08-05 9:51 ` Nazri Ramliy
2009-08-05 9:51 ` [PATCH 3/6] Teach --id to "git checkout" Nazri Ramliy
2009-08-05 18:11 ` [PATCH 1/6] Teach --id/-d to "git status" Alex Riesen
1 sibling, 1 reply; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git; +Cc: Nazri Ramliy
---
builtin-add.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index 581a2a1..1ed95d5 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -212,6 +212,7 @@ static const char ignore_error[] =
static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
static int ignore_add_errors, addremove, intent_to_add;
+static const char *file_id;
static struct option builtin_add_options[] = {
OPT__DRY_RUN(&show_only),
@@ -226,6 +227,7 @@ static struct option builtin_add_options[] = {
OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
+ OPT_STRING('d', "id", &file_id, "FILE_ID", "file id"),
OPT_END(),
};
@@ -268,27 +270,34 @@ int cmd_add(int argc, const char **argv, const char *prefix)
int flags;
int add_new_files;
int require_pathspec;
+ char **new_argv;
git_config(add_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_add_options,
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
+
+ if (file_id)
+ new_argv = (char **) expand_file_ids(file_id, &argc, (char **) argv);
+ else
+ new_argv = (char **) argv;
+
if (patch_interactive)
add_interactive = 1;
if (add_interactive)
- exit(interactive_add(argc - 1, argv + 1, prefix));
+ exit(interactive_add(argc - 1, (const char **) (new_argv + 1), prefix));
if (edit_interactive)
- return(edit_patch(argc, argv, prefix));
+ return(edit_patch(argc, (const char **) new_argv, prefix));
argc--;
- argv++;
+ new_argv++;
if (addremove && take_worktree_changes)
die("-A and -u are mutually incompatible");
if ((addremove || take_worktree_changes) && !argc) {
static const char *here[2] = { ".", NULL };
argc = 1;
- argv = here;
+ new_argv = (char **) here;
}
add_new_files = !take_worktree_changes && !refresh_only;
@@ -308,7 +317,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
fprintf(stderr, "Maybe you wanted to say 'git add .'?\n");
return 0;
}
- pathspec = validate_pathspec(argc, argv, prefix);
+ pathspec = validate_pathspec(argc, (const char **) new_argv, prefix);
if (read_cache() < 0)
die("index file corrupt");
--
1.6.4.13.ge6580
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/6] Teach --id to "git checkout"
2009-08-05 9:51 ` [PATCH 2/6] Teach --id to "git add" Nazri Ramliy
@ 2009-08-05 9:51 ` Nazri Ramliy
2009-08-05 9:51 ` [PATCH 4/6] Teach --d to "git commit" Nazri Ramliy
0 siblings, 1 reply; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git; +Cc: Nazri Ramliy
---
builtin-checkout.c | 26 +++++++++++++++++---------
1 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 8a9a474..94ef419 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -32,6 +32,7 @@ struct checkout_opts {
int writeout_error;
const char *new_branch;
+ const char *file_id;
int new_branch_log;
enum branch_track track;
};
@@ -583,6 +584,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
struct option options[] = {
OPT__QUIET(&opts.quiet),
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
+ OPT_STRING('d', "id", &opts.file_id, "FILE_ID", "file id"),
OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
OPT_SET_INT('t', "track", &opts.track, "track",
BRANCH_TRACK_EXPLICIT),
@@ -597,6 +599,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_END(),
};
int has_dash_dash;
+ char **new_argv;
memset(&opts, 0, sizeof(opts));
memset(&new, 0, sizeof(new));
@@ -608,9 +611,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
+ if (opts.file_id)
+ new_argv = (char **) expand_file_ids(opts.file_id, &argc, (char **) argv);
+ else
+ new_argv = (char **) argv;
+
/* --track without -b should DWIM */
if (0 < opts.track && !opts.new_branch) {
- const char *argv0 = argv[0];
+ const char *argv0 = new_argv[0];
if (!argc || !strcmp(argv0, "--"))
die ("--track needs a branch name");
if (!prefixcmp(argv0, "refs/"))
@@ -655,14 +663,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
*
*/
if (argc) {
- if (!strcmp(argv[0], "--")) { /* case (2) */
- argv++;
+ if (!strcmp(new_argv[0], "--")) { /* case (2) */
+ new_argv++;
argc--;
goto no_reference;
}
- arg = argv[0];
- has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
+ arg = new_argv[0];
+ has_dash_dash = (argc > 1) && !strcmp(new_argv[1], "--");
if (!strcmp(arg, "-"))
arg = "@{-1}";
@@ -674,7 +682,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
}
/* we can't end up being in (2) anymore, eat the argument */
- argv++;
+ new_argv++;
argc--;
new.name = arg;
@@ -702,14 +710,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
verify_non_filename(NULL, arg);
}
else {
- argv++;
+ new_argv++;
argc--;
}
}
no_reference:
if (argc) {
- const char **pathspec = get_pathspec(prefix, argv);
+ const char **pathspec = get_pathspec(prefix, (const char **) new_argv);
if (!pathspec)
die("invalid path specification");
@@ -717,7 +725,7 @@ no_reference:
/* Checkout paths */
if (opts.new_branch) {
if (argc == 1) {
- die("git checkout: updating paths is incompatible with switching branches.\nDid you intend to checkout '%s' which can not be resolved as commit?", argv[0]);
+ die("git checkout: updating paths is incompatible with switching branches.\nDid you intend to checkout '%s' which can not be resolved as commit?", new_argv[0]);
} else {
die("git checkout: updating paths is incompatible with switching branches.");
}
--
1.6.4.13.ge6580
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/6] Teach --d to "git commit"
2009-08-05 9:51 ` [PATCH 3/6] Teach --id to "git checkout" Nazri Ramliy
@ 2009-08-05 9:51 ` Nazri Ramliy
2009-08-05 9:51 ` [PATCH 5/6] Teach --id to "git rm" Nazri Ramliy
0 siblings, 1 reply; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git; +Cc: Nazri Ramliy
---
builtin-commit.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/builtin-commit.c b/builtin-commit.c
index 4bcce06..a0bda66 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -50,7 +50,7 @@ static const char *logfile, *force_author;
static const char *template_file;
static char *edit_message, *use_message;
static char *author_name, *author_email, *author_date;
-static int all, edit_flag, also, interactive, only, amend, signoff;
+static int all, edit_flag, also, interactive, only, amend, signoff, id_flag;
static int quiet, verbose, no_verify, allow_empty;
static char *untracked_files_arg;
/*
@@ -96,6 +96,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_FILENAME('t', "template", &template_file, "use specified template file"),
OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
+ OPT_BOOLEAN('d', "id", &id_flag, "show file id"),
OPT_GROUP("Commit contents options"),
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
@@ -352,6 +353,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
s.reference = "HEAD^1";
}
s.verbose = verbose;
+ s.show_file_id = id_flag;
s.untracked = (show_untracked_files == SHOW_ALL_UNTRACKED_FILES);
s.index_file = index_file;
s.fp = fp;
--
1.6.4.13.ge6580
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/6] Teach --id to "git rm"
2009-08-05 9:51 ` [PATCH 4/6] Teach --d to "git commit" Nazri Ramliy
@ 2009-08-05 9:51 ` Nazri Ramliy
2009-08-05 9:51 ` [PATCH 6/6] Teach --id to "git reset" Nazri Ramliy
0 siblings, 1 reply; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git; +Cc: Nazri Ramliy
---
builtin-rm.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/builtin-rm.c b/builtin-rm.c
index 57975db..d2982a0 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -137,6 +137,7 @@ static struct lock_file lock_file;
static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
static int ignore_unmatch = 0;
+static const char *file_id;
static struct option builtin_rm_options[] = {
OPT__DRY_RUN(&show_only),
@@ -146,6 +147,7 @@ static struct option builtin_rm_options[] = {
OPT_BOOLEAN('r', NULL, &recursive, "allow recursive removal"),
OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch,
"exit with a zero status even if nothing matched"),
+ OPT_STRING('d', "id", &file_id, "FILE_ID", "file id"),
OPT_END(),
};
@@ -154,11 +156,18 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
int i, newfd;
const char **pathspec;
char *seen;
+ char **new_argv;
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_rm_options,
builtin_rm_usage, 0);
+
+ if (file_id)
+ new_argv = (char **) expand_file_ids(file_id, &argc, (char **) argv);
+ else
+ new_argv = (char **) argv;
+
if (!argc)
usage_with_options(builtin_rm_usage, builtin_rm_options);
@@ -171,7 +180,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
die("index file corrupt");
refresh_cache(REFRESH_QUIET);
- pathspec = get_pathspec(prefix, argv);
+ pathspec = get_pathspec(prefix, (const char **) new_argv);
seen = NULL;
for (i = 0; pathspec[i] ; i++)
/* nothing */;
--
1.6.4.13.ge6580
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/6] Teach --id to "git reset"
2009-08-05 9:51 ` [PATCH 5/6] Teach --id to "git rm" Nazri Ramliy
@ 2009-08-05 9:51 ` Nazri Ramliy
0 siblings, 0 replies; 17+ messages in thread
From: Nazri Ramliy @ 2009-08-05 9:51 UTC (permalink / raw)
To: git; +Cc: Nazri Ramliy
---
builtin-reset.c | 32 ++++++++++++++++++++------------
1 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/builtin-reset.c b/builtin-reset.c
index 5fa1789..cad5cf5 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -183,6 +183,8 @@ static void prepend_reflog_action(const char *action, char *buf, size_t size)
int cmd_reset(int argc, const char **argv, const char *prefix)
{
int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
+ char *file_id;
+ char **new_argv;
const char *rev = "HEAD";
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
*old_orig = NULL, sha1_old_orig[20];
@@ -198,6 +200,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
"reset HEAD, index and working tree", MERGE),
OPT_BOOLEAN('q', NULL, &quiet,
"disable showing new HEAD in hard reset and progress message"),
+ OPT_STRING('d', "id", &file_id, "FILE_ID", "file id"),
OPT_END()
};
@@ -205,7 +208,12 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, git_reset_usage,
PARSE_OPT_KEEP_DASHDASH);
- reflog_action = args_to_str(argv);
+ if (file_id)
+ new_argv = (char **) expand_file_ids(file_id, &argc, (char **) argv);
+ else
+ new_argv = (char **) argv;
+
+ reflog_action = args_to_str((const char **) new_argv);
setenv("GIT_REFLOG_ACTION", reflog_action, 0);
/*
@@ -216,30 +224,30 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
* git reset [-opts] -- <paths>...
* git reset [-opts] <paths>...
*
- * At this point, argv[i] points immediately after [-opts].
+ * At this point, new_argv[i] points immediately after [-opts].
*/
if (i < argc) {
- if (!strcmp(argv[i], "--")) {
+ if (!strcmp(new_argv[i], "--")) {
i++; /* reset to HEAD, possibly with paths */
- } else if (i + 1 < argc && !strcmp(argv[i+1], "--")) {
- rev = argv[i];
+ } else if (i + 1 < argc && !strcmp(new_argv[i+1], "--")) {
+ rev = new_argv[i];
i += 2;
}
/*
- * Otherwise, argv[i] could be either <rev> or <paths> and
+ * Otherwise, new_argv[i] could be either <rev> or <paths> and
* has to be unambiguous.
*/
- else if (!get_sha1(argv[i], sha1)) {
+ else if (!get_sha1(new_argv[i], sha1)) {
/*
- * Ok, argv[i] looks like a rev; it should not
+ * Ok, new_argv[i] looks like a rev; it should not
* be a filename.
*/
- verify_non_filename(prefix, argv[i]);
- rev = argv[i++];
+ verify_non_filename(prefix, new_argv[i]);
+ rev = new_argv[i++];
} else {
/* Otherwise we treat this as a filename */
- verify_filename(prefix, argv[i]);
+ verify_filename(prefix, new_argv[i]);
}
}
@@ -260,7 +268,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
else if (reset_type != NONE)
die("Cannot do %s reset with paths.",
reset_type_names[reset_type]);
- return read_from_tree(prefix, argv + i, sha1,
+ return read_from_tree(prefix, (const char **) argv + i, sha1,
quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
}
if (reset_type == NONE)
--
1.6.4.13.ge6580
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] RFC - Say goodbye to the rodent
2009-08-05 9:51 [PATCH] RFC - Say goodbye to the rodent Nazri Ramliy
2009-08-05 9:51 ` [PATCH 1/6] Teach --id/-d to "git status" Nazri Ramliy
@ 2009-08-05 10:04 ` Andreas Ericsson
2009-08-05 11:54 ` Matthieu Moy
2009-08-05 19:02 ` Jeff King
3 siblings, 0 replies; 17+ messages in thread
From: Andreas Ericsson @ 2009-08-05 10:04 UTC (permalink / raw)
To: Nazri Ramliy; +Cc: git
Nazri Ramliy wrote:
>
> What do you guys think about this new approach of "cut-and-paste" from the
> command line?
>
Dunno, really. Tab-completion's working just fine for me, so I doubt I'll
use it. It's definitely novel, but how much aggravation will it cause if
not all file-managing programs support it?
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] RFC - Say goodbye to the rodent
2009-08-05 9:51 [PATCH] RFC - Say goodbye to the rodent Nazri Ramliy
2009-08-05 9:51 ` [PATCH 1/6] Teach --id/-d to "git status" Nazri Ramliy
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
3 siblings, 0 replies; 17+ messages in thread
From: Matthieu Moy @ 2009-08-05 11:54 UTC (permalink / raw)
To: Nazri Ramliy; +Cc: git
Nazri Ramliy <ayiehere@gmail.com> writes:
> Oftentimes I get tired of moving my hand away from the comfort of the home rows
> of my keybard in order to grab the mouse to highlight the files that I'd like
> to operate on.
Usually, when you cut-and-paste from $(git status), it's to run a
staging/unstaging command, or to view a diff.
Actually, "git add -i" is already a pretty good way of doing this,
with few keystrokes.
> 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-write-tree.c (m1)
> #
> # Untracked files:
> # (use "git add <file>..." to include in what will be committed)
> #
> # file1.c (x1)
> # file2.c (x2)
$ git add -i
staged unstaged path
1: unchanged +1/-0 builtin-write-tree.c
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked
5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp
> Now we can do the following:
>
> $ git add --id m1
What now> u
staged unstaged path
1: unchanged +1/-0 [b]uiltin-write-tree.c
Update>> 1
staged unstaged path
* 1: unchanged +1/-0 [b]uiltin-write-tree.c
Update>>
updated one path
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked
5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp
> Ids are specified via the --id command line option, and can be separated with
> commas if you want to specify more than one of them:
>
> $ git add --id m1,x2
What now> a
1: file1.c
2: file2.c
Add untracked>> 1
* 1: file1.c
2: file2.c
Add untracked>> 2
* 1: file1.c
* 2: file2.c
Add untracked>>
added 2 paths
for these examples, I have far fewer keystrokes with "git add -i" than
you have. I don't think it's worth adding yet-another-option to most
Git commands since it doesn't really bring much IMHO.
--
Matthieu
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] Teach --id/-d to "git status"
2009-08-05 9:51 ` [PATCH 1/6] Teach --id/-d to "git status" Nazri Ramliy
2009-08-05 9:51 ` [PATCH 2/6] Teach --id to "git add" Nazri Ramliy
@ 2009-08-05 18:11 ` Alex Riesen
2009-08-05 18:25 ` Sverre Rabbelier
1 sibling, 1 reply; 17+ messages in thread
From: Alex Riesen @ 2009-08-05 18:11 UTC (permalink / raw)
To: Nazri Ramliy; +Cc: git
On Wed, Aug 5, 2009 at 11:51, Nazri Ramliy<ayiehere@gmail.com> wrote:
> 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.
What is it for?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] Teach --id/-d to "git status"
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:33 ` Alex Riesen
0 siblings, 2 replies; 17+ messages in thread
From: Sverre Rabbelier @ 2009-08-05 18:25 UTC (permalink / raw)
To: Alex Riesen; +Cc: Nazri Ramliy, git
Heya,
On Wed, Aug 5, 2009 at 11:11, Alex Riesen<raa.lkml@gmail.com> wrote:
> What is it for?
See [PATCH 0/6].
--
Cheers,
Sverre Rabbelier
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] Teach --id/-d to "git status"
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
1 sibling, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2009-08-05 18:27 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Alex Riesen, Nazri Ramliy, git
Sverre Rabbelier <srabbelier@gmail.com> writes:
> On Wed, Aug 5, 2009 at 11:11, Alex Riesen<raa.lkml@gmail.com> wrote:
>> What is it for?
>
> See [PATCH 0/6].
Sounds useless.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] Teach --id/-d to "git status"
2009-08-05 18:27 ` Junio C Hamano
@ 2009-08-05 18:30 ` Sverre Rabbelier
0 siblings, 0 replies; 17+ messages in thread
From: Sverre Rabbelier @ 2009-08-05 18:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Alex Riesen, Nazri Ramliy, git
Heya,
On Wed, Aug 5, 2009 at 11:27, Junio C Hamano<gitster@pobox.com> wrote:
> Sounds useless.
It's actually called "[PATCH] RFC - Say goodbye to the rodent"; can't
find it on GMane though.
--
Cheers,
Sverre Rabbelier
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] Teach --id/-d to "git status"
2009-08-05 18:25 ` Sverre Rabbelier
2009-08-05 18:27 ` Junio C Hamano
@ 2009-08-05 18:33 ` Alex Riesen
2009-08-05 18:35 ` Sverre Rabbelier
1 sibling, 1 reply; 17+ messages in thread
From: Alex Riesen @ 2009-08-05 18:33 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Nazri Ramliy, git
Sverre Rabbelier, Wed, Aug 05, 2009 20:25:43 +0200:
> Heya,
>
> On Wed, Aug 5, 2009 at 11:11, Alex Riesen<raa.lkml@gmail.com> wrote:
> > What is it for?
>
> See [PATCH 0/6].
>
Complicated solution to a non-existing problem.
Nazri, have you ever tried "git gui"? (or tig, for console?)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/6] Teach --id/-d to "git status"
2009-08-05 18:33 ` Alex Riesen
@ 2009-08-05 18:35 ` Sverre Rabbelier
0 siblings, 0 replies; 17+ messages in thread
From: Sverre Rabbelier @ 2009-08-05 18:35 UTC (permalink / raw)
To: Alex Riesen; +Cc: Nazri Ramliy, git
Heya,
On Wed, Aug 5, 2009 at 11:33, Alex Riesen<raa.lkml@gmail.com> wrote:
> Complicated solution to a non-existing problem.
That's harsh; obviously it is an existing problem for Nazri, or they
wouldn't have spent the time writing these patches. So at worst it's a
complicated solution for an _already solved_ problem (tig, git add -i,
etc), but definitely not non-existing ;).
--
Cheers,
Sverre Rabbelier
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] RFC - Say goodbye to the rodent
2009-08-05 9:51 [PATCH] RFC - Say goodbye to the rodent Nazri Ramliy
` (2 preceding siblings ...)
2009-08-05 11:54 ` Matthieu Moy
@ 2009-08-05 19:02 ` Jeff King
2009-08-05 20:01 ` Nicolas Pitre
3 siblings, 1 reply; 17+ messages in thread
From: Jeff King @ 2009-08-05 19:02 UTC (permalink / raw)
To: Nazri Ramliy; +Cc: git
On Wed, Aug 05, 2009 at 05:51:40PM +0800, Nazri Ramliy wrote:
> The idea is that "git status --id" shows a unique id for each file in
> its output (modified/staged/unknown/etc). The ids and the
> corresponding filenames are stored in .git/FILE_IDS. This file gets
> overwritten everytime you run "git status --id"
But files _already_ have a unique id: the filename. You never say why
those unique ids must be cut-and-pasted using the mouse when your unique
ids would be suitable for typing, but I'll assume it's because your
unique ids are much shorter than your filenames.
There are already two classes of solutions to this problem:
1. Make typing the filenames easier. Generally, this is accomplished
by tab completion. Even stock bash (and other shells) should
complete filenames easily, but you can also complete much more
using the programmable bash completion included with git.
The main advantage of this approach is that it is totally
generalizable. Anytime you have to input a filename, you can use
it.
2. Structure your workflow to iterate over the list of items to be
acted on, and then select actions for each item. This is what "git
add -i" does, as well as "git mergetool" and "git difftool".
This can save a lot of typing over (1), but requires a new script
for every such workflow (e.g., the scripts above cover only adding,
resolving merges, and diffing; you would need a new script to
iterate over files, doing "git checkout" on each one, for example).
I think your solution is a third class, which is to assign a mapping of
shorter ids to items that persists over multiple commands. But it's not
clear to me where it has an advantage over the existing two solutions.
It is actually less general than (1), because you have to have assigned
the mappings beforehand. But it is not nearly as convenient as (2).
In addition, it's more complicated to implement and use, because you
have to care about the persistence of the mapping (i.e., how long does
it last, which commands reset it, etc).
So while it is somewhat clever, I don't think it is worth merging to
mainline git; it introduces complexity to solve a problem that already
has overlapping solutions.
-Peff
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] RFC - Say goodbye to the rodent
2009-08-05 19:02 ` Jeff King
@ 2009-08-05 20:01 ` Nicolas Pitre
0 siblings, 0 replies; 17+ messages in thread
From: Nicolas Pitre @ 2009-08-05 20:01 UTC (permalink / raw)
To: Jeff King; +Cc: Nazri Ramliy, git
On Wed, 5 Aug 2009, Jeff King wrote:
> On Wed, Aug 05, 2009 at 05:51:40PM +0800, Nazri Ramliy wrote:
>
> > The idea is that "git status --id" shows a unique id for each file in
> > its output (modified/staged/unknown/etc). The ids and the
> > corresponding filenames are stored in .git/FILE_IDS. This file gets
> > overwritten everytime you run "git status --id"
>
> But files _already_ have a unique id: the filename. You never say why
> those unique ids must be cut-and-pasted using the mouse when your unique
> ids would be suitable for typing, but I'll assume it's because your
> unique ids are much shorter than your filenames.
>
> There are already two classes of solutions to this problem:
>
> 1. Make typing the filenames easier. Generally, this is accomplished
> by tab completion. Even stock bash (and other shells) should
> complete filenames easily, but you can also complete much more
> using the programmable bash completion included with git.
>
> The main advantage of this approach is that it is totally
> generalizable. Anytime you have to input a filename, you can use
> it.
>
> 2. Structure your workflow to iterate over the list of items to be
> acted on, and then select actions for each item. This is what "git
> add -i" does, as well as "git mergetool" and "git difftool".
>
> This can save a lot of typing over (1), but requires a new script
> for every such workflow (e.g., the scripts above cover only adding,
> resolving merges, and diffing; you would need a new script to
> iterate over files, doing "git checkout" on each one, for example).
BTW I often use this incantation:
xargs git add
[paste list of files obtained from git status output]
^D
Nicolas
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2009-08-05 20:01 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-05 9:51 [PATCH] RFC - Say goodbye to the rodent Nazri Ramliy
2009-08-05 9:51 ` [PATCH 1/6] Teach --id/-d to "git status" Nazri Ramliy
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
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).