Re: GIT vs Other: Need argument

Subsystems: the rest

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: GIT vs Other: Need argument

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:43:06

Steven Grimm [off-list ref] writes:
When git pull --continue does the commit, it *might* be nice for it to
do a variant of commit -a: if the user has modified all the
conflicting files, *and* not done an update-index on any of them
manually,...
How do you propose to detect that?  We do not record the
conflicted semi-merged state we leave the user to sort out
anywhere else, and I do not think we would want to stash away a
hidden duplicates of all unmerged files somewhere only for this
application.  That feels too wasteful and messy.  You also need
to worry about how to garbage collect such copies if you go that
route.

-- >8 --
By the way, I've been wondering if giving "git add" an ability
to do "git commit -a" without actual committing.

	$ edit edit edit
        $ git add -u

would run "git add" for all modified (and deleted) files.

I picked "-u" instead of "-a" because I wanted to stress that
this is about "updating" (which has connotation that it is
relative to something, and in this case it is relative to the
current "index"), and not about "all", which "-a" would imply.

Hmm?

 builtin-add.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 57 insertions(+), 1 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index 9ec2925..5e6748f 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -8,10 +8,15 @@
 #include "dir.h"
 #include "exec_cmd.h"
 #include "cache-tree.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "commit.h"
+#include "revision.h"
 
 static const char builtin_add_usage[] =
-"git-add [-n] [-v] [-f] [--interactive | -i] [--] <filepattern>...";
+"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--] <filepattern>...";
 
+static int take_all_worktree_changes;
 static const char *excludes_file;
 
 static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
@@ -92,6 +97,44 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec)
 		prune_directory(dir, pathspec, baselen);
 }
 
+static void update_callback(struct diff_queue_struct *q,
+			    struct diff_options *opt, void *cbdata)
+{
+	int i, verbose;
+
+	verbose = *((int *)cbdata);
+	for (i = 0; i < q->nr; i++) {
+		struct diff_filepair *p = q->queue[i];
+		const char *path = p->one->path;
+		switch (p->status) {
+		default:
+			die("unexpacted diff status %c", p->status);
+		case DIFF_STATUS_UNMERGED:
+		case DIFF_STATUS_MODIFIED:
+			add_file_to_cache(path, verbose);
+			break;
+		case DIFF_STATUS_DELETED:
+			remove_file_from_cache(path);
+			if (verbose)
+				printf("remove '%s'\n", path);
+			break;
+		}
+	}
+}
+
+static void update_all(int verbose)
+{
+	struct rev_info rev;
+	init_revisions(&rev, "");
+	setup_revisions(0, NULL, &rev, NULL);
+	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
+	rev.diffopt.format_callback = update_callback;
+	rev.diffopt.format_callback_data = &verbose;
+	if (read_cache() < 0)
+		die("index file corrupt");
+	run_diff_files(&rev, 0);
+}
+
 static int git_add_config(const char *var, const char *value)
 {
 	if (!strcmp(var, "core.excludesfile")) {
@@ -156,8 +199,20 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 			verbose = 1;
 			continue;
 		}
+		if (!strcmp(arg, "-u")) {
+			take_all_worktree_changes = 1;
+			continue;
+		}
 		usage(builtin_add_usage);
 	}
+
+	if (take_all_worktree_changes) {
+		if (i < argc)
+			die("-u and explicit paths are incompatible");
+		update_all(verbose);
+		goto finish;
+	}
+
 	if (argc <= i) {
 		fprintf(stderr, "Nothing specified, nothing added.\n");
 		fprintf(stderr, "Maybe you wanted to say 'git add .'?\n");
@@ -207,6 +262,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	for (i = 0; i < dir.nr; i++)
 		add_file_to_cache(dir.entries[i]->name, verbose);
 
+ finish:
 	if (active_cache_changed) {
 		if (write_cache(newfd, active_cache, active_nr) ||
 		    close(newfd) || commit_locked_index(&lock_file))

Re: GIT vs Other: Need argument

From: Steven Grimm <hidden>
Date: 2016-06-15 22:43:06

Junio C Hamano wrote:
How do you propose to detect that?  We do not record the
conflicted semi-merged state we leave the user to sort out
anywhere else, and I do not think we would want to stash away a
hidden duplicates of all unmerged files somewhere only for this
application.  That feels too wasteful and messy.  You also need
to worry about how to garbage collect such copies if you go that
route.
  
We wouldn't need to store duplicates. Just the SHA1s of the semi-merged 
files would suffice. Actually, just the modification times would 
probably suffice, but the hashes are cheap to compute and slightly more 
robust. We could put those in a single file (the same place we'd record 
the fact that the user is in the middle of a conflicted pull) which is 
removed by --continue or --abort.

Alternately, we could rerun the merge that produced the semi-merged 
files in the first place; presumably it will produce exactly the same 
results it did the first time and we can compare that against the 
working copy. But I like storing the hashes better since it's cheaper 
and less convoluted.
By the way, I've been wondering if giving "git add" an ability
to do "git commit -a" without actual committing.

	$ edit edit edit
        $ git add -u

would run "git add" for all modified (and deleted) files.
  
I'm not sure I'd ever use this, personally. Pretty much the only time I 
find the "add everything" functionality useful is when I'm about to 
commit, and commit -a covers that case fine. But other people might find 
it helpful.

-Steve
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help