Re: [PATCH v2] Be more user-friendly when refusing to do something because of conflict.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Matthieu Moy <Matthieu.Moy@xxxxxxx> writes:

> Various commands refuse to run in the presence of conflicts (commit,
> merge, pull, cherry-pick/revert). They all used to provide rough, and
> inconsistant error messages.
>
> A new variable advice.resolveconflict is introduced, and allows more
> verbose messages, pointing the user to the appropriate solution.
>
> For commit, the error message used to look like this:
>
> $ git commit
> foo.txt: needs merge
> foo.txt: unmerged (c34a92682e0394bc0d6f4d4a67a8e2d32395c169)
> foo.txt: unmerged (3afcd75de8de0bb5076942fcb17446be50451030)
> foo.txt: unmerged (c9785d77b76dfe4fb038bf927ee518f6ae45ede4)
> error: Error building trees
>
> The "need merge" line is given by refresh_cache. We add the IN_PORCELAIN
> option to make the output more consistant with the other porcelain
> commands, and catch the error in return, to stop with a clean error
> message. The next lines were displayed by a call to cache_tree_update(),
> which is not reached anymore if we noticed the conflict.

"The new output looks like this, which is much better..." is missing
here.

> @@ -27,3 +29,13 @@ int git_default_advice_config(const char *var, const char *value)
>  
>  	return 0;
>  }
> +
> +void NORETURN die_resolve_conflict(const char *me)
> +{
> +	if (advice_resolve_conflict)
> +		die("'%s' is not possible because you have unmerged files.\n"
> +		    "Please, fix them up in the work tree, and then use 'git add/rm <file>'\n"
> +		    "as appropriate to mark resolution, or use 'git commit -a'.", me);
> +	else
> +		die("'%s' is not possible because you have unmerged files.", me);
> +}

Nice, but the advice contrasts between squirrels and oranges.

One advice, "use add/rm as appropriate to mark resolution" goes only as
far as making the index in order, without recording it in a commit.  The
other, "commit -a", will make a commit, I suspect that "commit -a" needs
to be matched with "commit" if the user chooses to take the first advice
of resolving paths incrementally.  IOW

    use 'git add/rm <file>' as appropriate to mark resolution and make a
    commit, or use 'commit -a', before running me again.

might be more appropriate.

> diff --git a/builtin-commit.c b/builtin-commit.c
> index 3dfcd77..a4977ac 100644
> --- a/builtin-commit.c
> +++ b/builtin-commit.c
> @@ -235,6 +235,17 @@ static void create_base_index(void)
>  		exit(128); /* We've already reported the error, finish dying */
>  }
>  
> +static void refresh_cache_or_die(int refresh_flags)
> +{
> +	/*
> +	 * refresh_flags contains REFRESH_QUIET, so the only errors
> +	 * are for unmerged entries.
> +	*/

Mixed indentation.

> +	if(refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN)) {

SP after "if".

What should we see upon "commit --dry-run" and what does the code after
the patch produce?  Are we sure refresh_flags always lack REFRESH_UNMERGED
that allows unmerged entries and produces the unmerged error messages when
needed?

> diff --git a/builtin-merge.c b/builtin-merge.c
> index f1c84d7..abe6c03 100644
> --- a/builtin-merge.c
> +++ b/builtin-merge.c
> @@ -847,11 +847,16 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
>  	const char *best_strategy = NULL, *wt_strategy = NULL;
>  	struct commit_list **remotes = &remoteheads;
>  
> -	if (file_exists(git_path("MERGE_HEAD")))
> -		die("You have not concluded your merge. (MERGE_HEAD exists)");
> -	if (read_cache_unmerged())
> -		die("You are in the middle of a conflicted merge."
> -				" (index unmerged)");
> +	if (read_cache_unmerged()) {
> +		die_resolve_conflict("merge");
> +	}
> +	if (file_exists(git_path("MERGE_HEAD"))) {
> +		if (advice_resolve_conflict)
> +			die("You have not concluded your merge (MERGE_HEAD exists).\n"
> +			    "Please, commit your changes before you can merge.");
> +		else
> +			die("You have not concluded your merge (MERGE_HEAD exists).");
> +	}

It is not a very big deal, but why are these checked in different order
after the patch?  Unless the new order is justifiably better, I'd rather
see the order kept as before.  Otherwise please justify it in the proposed
commit log message.

Note that the user might have already run "add -u" to mark everything
resolved, in which case MERGE_HEAD will still exist even though the index
is free of ummerged entries.

> diff --git a/builtin-revert.c b/builtin-revert.c

Nice.

> diff --git a/git-pull.sh b/git-pull.sh
> index 9e69ada..54ce0af 100755
> --- a/git-pull.sh
> +++ b/git-pull.sh
> @@ -13,8 +13,29 @@ set_reflog_action "pull $*"
>  require_work_tree
>  cd_to_toplevel
>  
> -test -z "$(git ls-files -u)" ||
> -	die "You are in the middle of a conflicted merge."
> +
> +die_conflict () {
> +    git diff-index --cached --name-status -r --ignore-submodules HEAD --
> +    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
> +	die "Pull is not possible because you have unmerged files.
> +Please, fix them up in the work tree, and then use 'git add/rm <file>'
> +as appropriate to mark resolution, or use 'git commit -a'."
> +    else
> +	die "Pull is not possible because you have unmerged files."
> +    fi
> +}
> +
> +die_merge () {
> +    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
> +	die "You have not concluded your merge (MERGE_HEAD exists).
> +Please, commit your changes before you can merge."
> +    else
> +	die "You have not concluded your merge (MERGE_HEAD exists)."
> +    fi
> +}
> +
> +test -z "$(git ls-files -u)" || die_conflict
> +test -f "$GIT_DIR/MERGE_HEAD" && die_merge

Nice.  Maybe we want to handle other cases like:

	$ git rebase master
        ... conflicted
        ... called away for a 30-minutes meeting
        ... forgot the user was in the middle of the rebase
        $ git pull

and the "pull" refused to run because the earlier "rebase" hasn't been
concluded (I suspect an earlier "am" failure would be the same issue).

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]