Commit a7c9878d5b0e7770339e76efc0821897fe7a6be8

Stefan Sperling 2019-08-08T08:40:38

make stage -p show the number of changes in a file

diff --git a/got/got.c b/got/got.c
index 3f39bc9..022dc36 100644
--- a/got/got.c
+++ b/got/got.c
@@ -5193,7 +5193,8 @@ print_stage(void *arg, unsigned char status, unsigned char staged_status,
 }
 
 static const struct got_error *
-show_change(unsigned char status, const char *path, FILE *patch_file)
+show_change(unsigned char status, const char *path, FILE *patch_file, int n,
+    int nchanges)
 {
 	char *line = NULL;
 	size_t linesize = 0;
@@ -5215,7 +5216,8 @@ show_change(unsigned char status, const char *path, FILE *patch_file)
 		if (ferror(patch_file))
 			return got_error_from_errno("getline");
 		printf(GOT_COMMIT_SEP_STR);
-		printf("M  %s\nstage this change? [y/n/q] ", path);
+		printf("M  %s (change %d of %d)\nstage this change? [y/n/q] ",
+		    path, n, nchanges);
 		break;
 	default:
 		return got_error_path(path, GOT_ERR_FILE_STATUS);
@@ -5226,7 +5228,7 @@ show_change(unsigned char status, const char *path, FILE *patch_file)
 
 static const struct got_error *
 choose_patch(int *choice, void *arg, unsigned char status, const char *path,
-    FILE *patch_file)
+    FILE *patch_file, int n, int nchanges)
 {
 	const struct got_error *err = NULL;
 	char *line = NULL;
@@ -5248,7 +5250,7 @@ choose_patch(int *choice, void *arg, unsigned char status, const char *path,
 		nl = strchr(line, '\n');
 		if (nl)
 			*nl = '\0';
-		err = show_change(status, path, patch_file);
+		err = show_change(status, path, patch_file, n, nchanges);
 		if (err)
 			return err;
 		if (strcmp(line, "y") == 0) {
@@ -5268,7 +5270,7 @@ choose_patch(int *choice, void *arg, unsigned char status, const char *path,
 	}
 
 	while (resp != 'y' && resp != 'n' && resp != 'q') {
-		err = show_change(status, path, patch_file);
+		err = show_change(status, path, patch_file, n, nchanges);
 		if (err)
 			return err;
 		resp = getchar();
diff --git a/include/got_worktree.h b/include/got_worktree.h
index c4b9425..b07be00 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -375,7 +375,7 @@ const struct got_error *got_worktree_get_histedit_script_path(char **,
 
 /* A callback function which is used to select or reject a patch. */
 typedef const struct got_error *(*got_worktree_patch_cb)(int *, void *,
-    unsigned char, const char *, FILE *);
+    unsigned char, const char *, FILE *, int, int);
 
 /* Values for result output parameter of got_wortree_patch_cb. */
 #define GOT_PATCH_CHOICE_NONE	0
diff --git a/lib/got_lib_diff.h b/lib/got_lib_diff.h
index 496525c..e3af9a1 100644
--- a/lib/got_lib_diff.h
+++ b/lib/got_lib_diff.h
@@ -93,7 +93,7 @@ struct got_diff_change {
 };
 
 struct got_diff_changes {
-	size_t nchanges;
+	int nchanges;
 	SIMPLEQ_HEAD(, got_diff_change) entries;
 };
 
diff --git a/lib/worktree.c b/lib/worktree.c
index 7de42bb..73c9e65 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -5177,10 +5177,11 @@ skip_one_line(FILE *f)
 }
 
 static const struct got_error *
-apply_or_reject_change(int *choice, struct got_diff_change *change,
-    struct got_diff_state *ds, struct got_diff_args *args, int diff_flags,
-    const char *relpath, FILE *f1, FILE *f2, int *line_cur1, int *line_cur2,
-    FILE *outfile, got_worktree_patch_cb patch_cb, void *patch_arg)
+apply_or_reject_change(int *choice, struct got_diff_change *change, int n,
+    int nchanges, struct got_diff_state *ds, struct got_diff_args *args,
+    int diff_flags, const char *relpath, FILE *f1, FILE *f2, int *line_cur1,
+    int *line_cur2, FILE *outfile, got_worktree_patch_cb patch_cb,
+    void *patch_arg)
 {
 	const struct got_error *err = NULL;
 	int start_old = change->cv.a;
@@ -5216,7 +5217,7 @@ apply_or_reject_change(int *choice, struct got_diff_change *change,
 	}
 
 	err = (*patch_cb)(choice, patch_arg, GOT_STATUS_MODIFY, relpath,
-	    hunkfile);
+	    hunkfile, n, nchanges);
 	if (err)
 		goto done;
 
@@ -5308,6 +5309,7 @@ create_staged_content(char **path_outfile, struct got_object_id *blob_id,
 	struct got_diff_args *args = NULL;
 	struct got_diff_change *change;
 	int diff_flags = 0, line_cur1 = 1, line_cur2 = 1, have_content = 0;
+	int n = 0;
 
 	*path_outfile = NULL;
 
@@ -5357,8 +5359,9 @@ create_staged_content(char **path_outfile, struct got_object_id *blob_id,
 		return got_ferror(f2, GOT_ERR_IO);
 	SIMPLEQ_FOREACH(change, &changes->entries, entry) {
 		int choice;
-		err = apply_or_reject_change(&choice, change, ds, args,
-		    diff_flags, relpath, f1, f2, &line_cur1, &line_cur2,
+		err = apply_or_reject_change(&choice, change, ++n,
+		    changes->nchanges, ds, args, diff_flags, relpath,
+		    f1, f2, &line_cur1, &line_cur2,
 		    outfile, patch_cb, patch_arg);
 		if (err)
 			goto done;
@@ -5433,7 +5436,7 @@ stage_path(void *arg, unsigned char status,
 			if (status == GOT_STATUS_ADD) {
 				int choice = GOT_PATCH_CHOICE_NONE;
 				err = (*a->patch_cb)(&choice, a->patch_arg,
-				    status, ie->path, NULL);
+				    status, ie->path, NULL, 1, 1);
 				if (err)
 					break;
 				if (choice != GOT_PATCH_CHOICE_YES)
@@ -5469,7 +5472,7 @@ stage_path(void *arg, unsigned char status,
 		if (a->patch_cb) {
 			int choice = GOT_PATCH_CHOICE_NONE;
 			err = (*a->patch_cb)(&choice, a->patch_arg, status,
-			    ie->path, NULL);
+			    ie->path, NULL, 1, 1);
 			if (err)
 				break;
 			if (choice != GOT_PATCH_CHOICE_YES)
diff --git a/regress/cmdline/stage.sh b/regress/cmdline/stage.sh
index 83c66f0..3d1f624 100755
--- a/regress/cmdline/stage.sh
+++ b/regress/cmdline/stage.sh
@@ -1180,7 +1180,7 @@ function test_stage_patch {
  4
  5
 -----------------------------------------------
-M  numbers
+M  numbers (change 1 of 3)
 stage this change? [y/n/q] n
 -----------------------------------------------
 @@ -4,7 +4,7 @@
@@ -1193,7 +1193,7 @@ stage this change? [y/n/q] n
  9
  10
 -----------------------------------------------
-M  numbers
+M  numbers (change 2 of 3)
 stage this change? [y/n/q] n
 -----------------------------------------------
 @@ -13,4 +13,4 @@
@@ -1203,7 +1203,7 @@ stage this change? [y/n/q] n
 -16
 +c
 -----------------------------------------------
-M  numbers
+M  numbers (change 3 of 3)
 stage this change? [y/n/q] n
 EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
@@ -1239,7 +1239,7 @@ EOF
  4
  5
 -----------------------------------------------
-M  numbers
+M  numbers (change 1 of 3)
 stage this change? [y/n/q] n
 -----------------------------------------------
 @@ -4,7 +4,7 @@
@@ -1252,7 +1252,7 @@ stage this change? [y/n/q] n
  9
  10
 -----------------------------------------------
-M  numbers
+M  numbers (change 2 of 3)
 stage this change? [y/n/q] y
 -----------------------------------------------
 @@ -13,4 +13,4 @@
@@ -1262,7 +1262,7 @@ stage this change? [y/n/q] y
 -16
 +c
 -----------------------------------------------
-M  numbers
+M  numbers (change 3 of 3)
 stage this change? [y/n/q] n
 EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
@@ -1345,7 +1345,7 @@ EOF
  4
  5
 -----------------------------------------------
-M  numbers
+M  numbers (change 1 of 3)
 stage this change? [y/n/q] n
 -----------------------------------------------
 @@ -4,7 +4,7 @@
@@ -1358,7 +1358,7 @@ stage this change? [y/n/q] n
  9
  10
 -----------------------------------------------
-M  numbers
+M  numbers (change 2 of 3)
 stage this change? [y/n/q] n
 -----------------------------------------------
 @@ -13,4 +13,4 @@
@@ -1368,7 +1368,7 @@ stage this change? [y/n/q] n
 -16
 +c
 -----------------------------------------------
-M  numbers
+M  numbers (change 3 of 3)
 stage this change? [y/n/q] y
 EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
@@ -1572,7 +1572,7 @@ function test_stage_patch_quit {
  4
  5
 -----------------------------------------------
-M  numbers
+M  numbers (change 1 of 3)
 stage this change? [y/n/q] y
 -----------------------------------------------
 @@ -4,7 +4,7 @@
@@ -1585,7 +1585,7 @@ stage this change? [y/n/q] y
  9
  10
 -----------------------------------------------
-M  numbers
+M  numbers (change 2 of 3)
 stage this change? [y/n/q] q
 EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout