git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 17/19] reset $sha1 $pathspec: require $sha1 only to be treeish

From
Martin von Zweigbergk <martinvonz@gmail.com>
Date
Jan 9, 2013, 08:16 UTC
Message-ID
<1357719376-16406-18-git-send-email-martinvonz@gmail.com>
In-Reply-To
<1357719376-16406-1-git-send-email-martinvonz@gmail.com>

Resetting with paths does not update HEAD and there is nothing else that a commit should be needed for. Relax the argument parsing so only a tree is required.

The sha1 is only passed to read_from_tree(), which already only requires a tree.

The "rev" variable we pass to run_add_interactive() will resolve to a tree. This is fine since interactive_reset only needs the parameter to be a treeish and doesn't use it for display purposes. --- Is it correct that interactive_reset does not use the revision specifier for display purposes? Or, worse, that it requires it to be a commit in some cases? I tried it and didn't see any problem.

Can the two blocks of code that look up commit or tree be made to share more? I'm not very familiar with what functions are available. I think I tried keeping a separate "struct object *object" to be able to put the last three lines outside the blocks, but didn't like the result.

 builtin/reset.c  | 46 ++++++++++++++++++++++++++--------------------
 t/t7102-reset.sh |  8 ++++++++
 2 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/builtin/reset.c b/builtin/reset.c
index a2e69eb..4c223bd 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -177,9 +177,10 @@ const char **parse_args(int argc, const char **argv, const char *prefix, const c
 	/*
 	 * Possible arguments are:
 	 *
-	 * git reset [-opts] <rev> <paths>...
-	 * git reset [-opts] <rev> -- <paths>...
-	 * git reset [-opts] -- <paths>...
+	 * git reset [-opts] [<rev>]
+	 * git reset [-opts] <tree> [<paths>...]
+	 * git reset [-opts] <tree> -- [<paths>...]
+	 * git reset [-opts] -- [<paths>...]
 	 * git reset [-opts] <paths>...
 	 *
 	 * At this point, argv points immediately after [-opts].
@@ -194,11 +195,13 @@ const char **parse_args(int argc, const char **argv, const char *prefix, const c
 		}
 		/*
 		 * Otherwise, argv[0] could be either <rev> or <paths> and
-		 * has to be unambiguous.
+		 * has to be unambiguous. If there is a single argument, it
+		 * can not be a tree
 		 */
-		else if (!get_sha1_committish(argv[0], unused)) {
+		else if ((argc == 1 && !get_sha1_committish(argv[0], unused)) ||
+			 (argc > 1 && !get_sha1_treeish(argv[0], unused))) {
 			/*
-			 * Ok, argv[0] looks like a rev; it should not
+			 * Ok, argv[0] looks like a commit/tree; it should not
 			 * be a filename.
 			 */
 			verify_non_filename(prefix, argv[0]);
@@ -240,7 +243,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
 	const char *rev;
 	unsigned char sha1[20];
 	const char **pathspec = NULL;
-	struct commit *commit;
+	struct commit *commit = NULL;
 	const struct option options[] = {
 		OPT__QUIET(&quiet, N_("be quiet, only report errors")),
 		OPT_SET_INT(0, "mixed", &reset_type,
@@ -262,19 +265,22 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
 						PARSE_OPT_KEEP_DASHDASH);
 	pathspec = parse_args(argc, argv, prefix, &rev);
 
-	if (get_sha1_committish(rev, sha1))
-		die(_("Failed to resolve '%s' as a valid ref."), rev);
-
-	/*
-	 * NOTE: As "git reset $treeish -- $path" should be usable on
-	 * any tree-ish, this is not strictly correct. We are not
-	 * moving the HEAD to any commit; we are merely resetting the
-	 * entries in the index to that of a treeish.
-	 */
-	commit = lookup_commit_reference(sha1);
-	if (!commit)
-		die(_("Could not parse object '%s'."), rev);
-	hashcpy(sha1, commit->object.sha1);
+	if (!pathspec) {
+		if (get_sha1_committish(rev, sha1))
+			die(_("Failed to resolve '%s' as a valid revision."), rev);
+		commit = lookup_commit_reference(sha1);
+		if (!commit)
+			die(_("Could not parse object '%s'."), rev);
+		hashcpy(sha1, commit->object.sha1);
+	} else {
+		struct tree *tree;
+		if (get_sha1_treeish(rev, sha1))
+			die(_("Failed to resolve '%s' as a valid tree."), rev);
+		tree = parse_tree_indirect(sha1);
+		if (!tree)
+			die(_("Could not parse object '%s'."), rev);
+		hashcpy(sha1, tree->object.sha1);
+	}
 
 	if (patch_mode) {
 		if (reset_type != NONE)
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index 81b2570..1fa2a5f 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -497,4 +497,12 @@ test_expect_success 'disambiguation (4)' '
 	test ! -f secondfile
 '
 
+test_expect_success 'reset with paths accepts tree' '
+	# for simpler tests, drop last commit containing added files
+	git reset --hard HEAD^ &&
+	git reset HEAD^^{tree} -- . &&
+	git diff --cached HEAD^ --exit-code &&
+	git diff HEAD --exit-code
+'
+
 test_done
-- 
1.8.1.rc3.331.g1ef2165
Previous: Junio C HamanoNext: Junio C Hamano
Message 41 of 68 in “reset improvements”
  1. 00/19 reset improvementsMartin von Zweigbergk, Jan 9, 2013
  2. 01/19 reset $pathspec: no need to discard indexMartin von Zweigbergk, Jan 9, 2013
  3. 02/19 reset $pathspec: exit with code 0 if successfulMartin von Zweigbergk, Jan 9, 2013
  4. 03/19 reset.c: pass pathspec around instead of (prefix, argv) pairMartin von Zweigbergk, Jan 9, 2013
  5. Matt KraaiJan 9, 2013
  6. Junio C HamanoJan 9, 2013
  7. Duy NguyenJan 10, 2013
  8. Junio C HamanoJan 10, 2013
  9. Duy NguyenJan 11, 2013
  10. 04/19 reset: don't allow "git reset -- $pathspec" in bare repoMartin von Zweigbergk, Jan 9, 2013
  11. Junio C HamanoJan 9, 2013
  12. Martin von ZweigbergkJan 10, 2013
  13. Junio C HamanoJan 10, 2013
  14. 05/19 reset.c: extract function for parsing argumentsMartin von Zweigbergk, Jan 9, 2013
  15. 06/19 reset.c: remove unnecessary variable 'i'Martin von Zweigbergk, Jan 9, 2013
  16. Junio C HamanoJan 9, 2013
  17. Martin von ZweigbergkJan 10, 2013
  18. 07/19 reset.c: extract function for updating {ORIG,}HEADMartin von Zweigbergk, Jan 9, 2013
  19. Matt KraaiJan 9, 2013
  20. 08/19 reset.c: share call to die_if_unmerged_cache()Martin von Zweigbergk, Jan 9, 2013
  21. Junio C HamanoJan 9, 2013
  22. Martin von ZweigbergkJan 10, 2013
  23. 09/19 reset.c: replace switch by if-elseMartin von Zweigbergk, Jan 9, 2013
  24. Junio C HamanoJan 9, 2013
  25. Martin von ZweigbergkJan 11, 2013
  26. Junio C HamanoJan 11, 2013
  27. 10/19 reset --keep: only write index file onceMartin von Zweigbergk, Jan 9, 2013
  28. Junio C HamanoJan 9, 2013
  29. 11/19 reset: avoid redundant error messageMartin von Zweigbergk, Jan 9, 2013
  30. 12/19 reset.c: move update_index_refresh() call out of read_from_tree()Martin von Zweigbergk, Jan 9, 2013
  31. 13/19 reset.c: move lock, write and commit out of update_index_refresh()Martin von Zweigbergk, Jan 9, 2013
  32. 14/19 reset [--mixed]: don't write index file twiceMartin von Zweigbergk, Jan 9, 2013
  33. 15/19 reset.c: finish entire cmd_reset() whether or not pathspec is givenMartin von Zweigbergk, Jan 9, 2013
  34. Junio C HamanoJan 9, 2013
  35. 16/19 reset [--mixed] --quiet: don't refresh indexMartin von Zweigbergk, Jan 9, 2013
  36. Jeff KingJan 9, 2013
  37. Martin von ZweigbergkJan 9, 2013
  38. Junio C HamanoJan 9, 2013
  39. Martin von ZweigbergkJan 9, 2013
  40. Junio C HamanoJan 9, 2013
  41. 17/19 reset $sha1 $pathspec: require $sha1 only to be treeishMartin von Zweigbergk, Jan 9, 2013
  42. Junio C HamanoJan 9, 2013
  43. 18/19 reset: allow reset on unborn branchMartin von Zweigbergk, Jan 9, 2013
  44. 19/19 reset [--mixed]: use diff-based reset whether or not pathspec was givenMartin von Zweigbergk, Jan 9, 2013
  45. Junio C HamanoJan 9, 2013
  46. 00/19 reset improvementsMartin von Zweigbergk, Jan 15, 2013
  47. 01/19 reset $pathspec: no need to discard indexMartin von Zweigbergk, Jan 15, 2013
  48. 02/19 reset $pathspec: exit with code 0 if successfulMartin von Zweigbergk, Jan 15, 2013
  49. 03/19 reset.c: pass pathspec around instead of (prefix, argv) pairMartin von Zweigbergk, Jan 15, 2013
  50. 04/19 reset: don't allow "git reset -- $pathspec" in bare repoMartin von Zweigbergk, Jan 15, 2013
  51. 05/19 reset.c: extract function for parsing argumentsMartin von Zweigbergk, Jan 15, 2013
  52. 06/19 reset.c: remove unnecessary variable 'i'Martin von Zweigbergk, Jan 15, 2013
  53. 07/19 reset.c: extract function for updating {ORIG_,}HEADMartin von Zweigbergk, Jan 15, 2013
  54. 08/19 reset.c: share call to die_if_unmerged_cache()Martin von Zweigbergk, Jan 15, 2013
  55. 09/19 reset --keep: only write index file onceMartin von Zweigbergk, Jan 15, 2013
  56. 10/19 reset: avoid redundant error messageMartin von Zweigbergk, Jan 15, 2013
  57. 11/19 reset.c: replace switch by if-elseMartin von Zweigbergk, Jan 15, 2013
  58. 12/19 reset.c: move update_index_refresh() call out of read_from_tree()Martin von Zweigbergk, Jan 15, 2013
  59. 13/19 reset.c: move lock, write and commit out of update_index_refresh()Martin von Zweigbergk, Jan 15, 2013
  60. 14/19 reset [--mixed]: only write index file onceMartin von Zweigbergk, Jan 15, 2013
  61. 15/19 reset.c: finish entire cmd_reset() whether or not pathspec is givenMartin von Zweigbergk, Jan 15, 2013
  62. 16/19 reset.c: inline update_index_refresh()Martin von Zweigbergk, Jan 15, 2013
  63. 17/19 reset $sha1 $pathspec: require $sha1 only to be treeishMartin von Zweigbergk, Jan 15, 2013
  64. 17/19 fixup! reset $sha1 $pathspec: require $sha1 only to be treeishMartin von Zweigbergk, Jan 16, 2013
  65. Martin von ZweigbergkJan 16, 2013
  66. 18/19 reset: allow reset on unborn branchMartin von Zweigbergk, Jan 15, 2013
  67. 19/19 reset [--mixed]: use diff-based reset whether or not pathspec was givenMartin von Zweigbergk, Jan 15, 2013
  68. Martin von ZweigbergkJan 15, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.