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

Re: [PATCH/RFC] commit: new option to abort -a something is already staged

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 20, 2018, 15:55 UTC
Message-ID
<xmqqwoslav7z.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<20180820154120.19297-1-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:
> +commit.preciousDirtyIndex::
> +	If some changes are partially staged in the index (i.e.
> +	"git commit -a" and "git commit" commit different changes), reject
> +	"git commit -a".

Or perhaps better yet, go into yes/no interaction to confirm if you have access to interactive terminal at fd #0/#1, perhaps?

Show 22 quoted lines
> diff --git a/builtin/commit.c b/builtin/commit.c
> index 213fca2d8e..489e4b9f50 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -98,6 +98,7 @@ static const char *author_message, *author_message_buffer;
>  static char *edit_message, *use_message;
>  static char *fixup_message, *squash_message;
>  static int all, also, interactive, patch_interactive, only, amend, signoff;
> +static int allow_dirty_index = 1;
>  static int edit_flag = -1; /* unspecified */
>  static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
>  static int config_commit_verbose = -1; /* unspecified */
> @@ -385,10 +386,24 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
>  	 * (B) on failure, rollback the real index.
>  	 */
>  	if (all || (also && pathspec.nr)) {
> +		int compare_oid = all && !allow_dirty_index;
> +		struct object_id previous_oid;
> +
> +		if (compare_oid) {
> +			if (update_main_cache_tree(0) || !the_index.cache_tree)
> +				die(_("error building trees"));

Hmph, when we conclude a conflicted merge with "commit -a", wouldn't we fail to compute the "before" picture, with higher-stage entries stil in the index?

> +			if (the_index.cache_tree->entry_count >= 0)
> +				oidcpy(&previous_oid, &the_index.cache_tree->oid);
> +			else
> +				oidclr(&previous_oid);

The cache-tree covers no entry, meaning the index has no cache entries? Shouldn't we setting EMPTY_TREE_SHA1_BIN or something instead?

Show 8 quoted lines
> +		}
>  		hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
>  		add_files_to_cache(also ? prefix : NULL, &pathspec, 0);
>  		refresh_cache_or_die(refresh_flags);
>  		update_main_cache_tree(WRITE_TREE_SILENT);
> +		if (compare_oid && the_index.cache_tree &&
> +		    oidcmp(&previous_oid, &the_index.cache_tree->oid))
> +			die(_("staged content is different, aborting"));

I was hoping that it is an easy change to teach add_files_to_cache() to report how many paths it actually has "added" (modifications and removals are of course also counted), which allows us not to waste computing a throw-away tree object once more.

There only are three existing callers to the function, and only one of them rely on the current "non-zero is error, zero is good" semantics, so updating that caller (and perhaps vetting the other callers to see if they also _should_ pay attention to the return value, at least to detect errors of not number of paths updated) shouldn't be that much more effort, and would be a good update to the API regardless of this new feature, I would think.

Show 14 quoted lines
>  		if (write_locked_index(&the_index, &index_lock, 0))
>  			die(_("unable to write new_index file"));
>  		commit_style = COMMIT_NORMAL;
> @@ -1413,6 +1428,10 @@ static int git_commit_config(const char *k, const char *v, void *cb)
>  		config_commit_verbose = git_config_bool_or_int(k, v, &is_bool);
>  		return 0;
>  	}
> +	if (!strcmp(k, "commit.preciousdirtyindex")) {
> +		allow_dirty_index = !git_config_bool(k, v);
> +		return 0;
> +	}
>  
>  	status = git_gpg_config(k, v, NULL);
>  	if (status)
Previous: Nguyễn Thái Ngọc DuyNext: Eric Sunshine
Message 2 of 28 in “commit: new option to abort -a something is already staged”
  1. commit: new option to abort -a something is already stagedNguyễn Thái Ngọc Duy, Aug 20, 2018
  2. Junio C HamanoAug 20, 2018
  3. Eric SunshineAug 20, 2018
  4. Jonathan NiederAug 20, 2018
  5. Duy NguyenAug 21, 2018
  6. Jonathan NiederAug 23, 2018
  7. Jonathan NiederAug 23, 2018
  8. Duy NguyenAug 23, 2018
  9. Junio C HamanoAug 23, 2018
  10. Jacob KellerAug 24, 2018
  11. Duy NguyenAug 24, 2018
  12. Jacob KellerAug 24, 2018
  13. Jacob KellerAug 24, 2018
  14. 0/1 Make 'git commit' not accidentally lose staged contentNguyễn Thái Ngọc Duy, Sep 16, 2018
  15. 1/1 commit: do not clobber the indexNguyễn Thái Ngọc Duy, Sep 16, 2018
  16. Junio C HamanoSep 17, 2018
  17. Duy NguyenSep 17, 2018
  18. Jeff KingSep 17, 2018
  19. Duy NguyenSep 17, 2018
  20. Jeff KingSep 18, 2018
  21. Jacob KellerSep 18, 2018
  22. Jeff KingSep 18, 2018
  23. Duy NguyenSep 19, 2018
  24. Jeff KingSep 19, 2018
  25. Junio C HamanoSep 17, 2018
  26. Jacob KellerSep 18, 2018
  27. Eckhard MaaßSep 18, 2018
  28. Jacob KellerSep 18, 2018

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.