mbox series

[v2,0/4] Let the builtin rebase call the git am command directly

Message ID pull.24.v2.git.gitgitgadget@gmail.com (mailing list archive)
Headers show
Series Let the builtin rebase call the git am command directly | expand

Message

Bruce Perry via GitGitGadget Jan. 18, 2019, 3:09 p.m. UTC
Especially on Windows, where Unix shell scripting is a foreign endeavor, and
an expensive one at that, we really want to avoid running through the Bash.

This not only makes everything faster, but also more robust, as the Bash we
use on Windows relies on a derivative of the Cygwin runtime, which in turn
has to jump through a couple of hoops that are sometimes a little too tricky
to make things work. Read: the less we rely on Unix shell scripting, the
more likely Windows users will be able to enjoy our software.

Changes since v1:

 * Rebased on top of master to avoid merge conflicts.
 * Adjusted the commit message talking about double entries, to clarify that
   it talks about HEAD's reflog.
 * Replaced a misleading action parameter "checkout" for the reset_head() 
   function by the empty string: we do not check out here, we just update
   the refs, and certainly do not want any checkout functionality (such as
   hooks) to be involved.
 * Reused a just-prepared refs_only variable instead of repeating the value
   assigned to it.
 * Fixed a stale comment about the shell variable "$upstream" (which should
   have been negated to begin with).
 * Fixed error messages when files could not be opened.

Johannes Schindelin (4):
  rebase: move `reset_head()` into a better spot
  rebase: avoid double reflog entry when switching branches
  rebase: teach `reset_head()` to optionally skip the worktree
  built-in rebase: call `git am` directly

 builtin/rebase.c | 424 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 305 insertions(+), 119 deletions(-)


base-commit: 77556354bb7ac50450e3b28999e3576969869068
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-24%2Fdscho%2Fbuiltin-rebase--am-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-24/dscho/builtin-rebase--am-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/24

Range-diff vs v1:

 1:  175dc7d29a ! 1:  e886ae3de5 rebase: move `reset_head()` into a better spot
     @@ -91,7 +91,7 @@
      +	}
      +
      +	tree = parse_tree_indirect(oid);
     -+	prime_cache_tree(the_repository->index, tree);
     ++	prime_cache_tree(the_repository, the_repository->index, tree);
      +
      +	if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) {
      +		ret = error(_("could not write index"));
     @@ -217,7 +217,7 @@
      -	}
      -
      -	tree = parse_tree_indirect(oid);
     --	prime_cache_tree(the_repository->index, tree);
     +-	prime_cache_tree(the_repository, the_repository->index, tree);
      -
      -	if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) {
      -		ret = error(_("could not write index"));
 2:  4c5f87b9dc ! 2:  3a68f1c509 rebase: avoid double reflog entry when switching branches
     @@ -3,8 +3,8 @@
          rebase: avoid double reflog entry when switching branches
      
          When switching a branch *and* updating said branch to a different
     -    revision, let's avoid a double entry by first updating the branch and
     -    then adjusting the symbolic ref HEAD.
     +    revision, let's avoid a double entry in HEAD's reflog by first updating
     +    the branch and then adjusting the symbolic ref HEAD.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
 3:  21939140e0 ! 3:  387071dcd7 rebase: teach `reset_head()` to optionally skip the worktree
     @@ -40,7 +40,7 @@
       	if (!oid)
       		oid = &head_oid;
       
     -+	if (flags & RESET_HEAD_REFS_ONLY)
     ++	if (refs_only)
      +		goto reset_head_refs;
      +
       	memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
 4:  2b5ece8263 ! 4:  3c40318682 built-in rebase: call `git am` directly
     @@ -16,6 +16,10 @@
          itself a derivative of the Cygwin runtime): when no shell script is
          called, the POSIX emulation layer is avoided altogether.
      
     +    Note: we pass an empty action to `reset_head()` here when moving back to
     +    the original branch, as no other action is applicable, really. This
     +    parameter is used to initialize `unpack_trees()`' messages.
     +
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
       diff --git a/builtin/rebase.c b/builtin/rebase.c
     @@ -78,8 +82,7 @@
      +		    opts->head_name, oid_to_hex(&opts->onto->object.oid));
      +	strbuf_addf(&head_reflog, "rebase finished: returning to %s",
      +		    opts->head_name);
     -+	ret = reset_head(NULL, "checkout", opts->head_name,
     -+			 RESET_HEAD_REFS_ONLY,
     ++	ret = reset_head(NULL, "", opts->head_name, RESET_HEAD_REFS_ONLY,
      +			 orig_head_reflog.buf, head_reflog.buf);
      +
      +	strbuf_release(&orig_head_reflog);
     @@ -114,7 +117,6 @@
      +		if (status)
      +			return status;
      +
     -+		discard_cache();
      +		return move_to_original_branch(opts);
      +	}
      +	if (opts->action && !strcmp("skip", opts->action)) {
     @@ -124,7 +126,6 @@
      +		if (status)
      +			return status;
      +
     -+		discard_cache();
      +		return move_to_original_branch(opts);
      +	}
      +	if (opts->action && !strcmp("show-current-patch", opts->action)) {
     @@ -134,7 +135,7 @@
      +
      +	strbuf_addf(&revisions, "%s...%s",
      +		    oid_to_hex(opts->root ?
     -+			       /* this is now equivalent to ! -z "$upstream" */
     ++			       /* this is now equivalent to !opts->upstream */
      +			       &opts->onto->object.oid :
      +			       &opts->upstream->object.oid),
      +		    oid_to_hex(&opts->orig_head));
     @@ -143,7 +144,7 @@
      +	format_patch.out = open(rebased_patches,
      +				O_WRONLY | O_CREAT | O_TRUNC, 0666);
      +	if (format_patch.out < 0) {
     -+		status = error_errno(_("could not write '%s'"),
     ++		status = error_errno(_("could not open '%s' for writing"),
      +				     rebased_patches);
      +		free(rebased_patches);
      +		argv_array_clear(&am.args);
     @@ -185,7 +186,7 @@
      +
      +	am.in = open(rebased_patches, O_RDONLY);
      +	if (am.in < 0) {
     -+		status = error_errno(_("could not read '%s'"),
     ++		status = error_errno(_("could not open '%s' for reading"),
      +				     rebased_patches);
      +		free(rebased_patches);
      +		argv_array_clear(&am.args);
     @@ -207,7 +208,6 @@
      +	free(rebased_patches);
      +
      +	if (!status) {
     -+		discard_cache();
      +		return move_to_original_branch(opts);
      +	}
      +

Comments

Junio C Hamano Jan. 18, 2019, 6:06 p.m. UTC | #1
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> Especially on Windows, where Unix shell scripting is a foreign endeavor, and
> an expensive one at that, we really want to avoid running through the Bash.
>
> This not only makes everything faster, but also more robust, as the Bash we
> use on Windows relies on a derivative of the Cygwin runtime, which in turn
> has to jump through a couple of hoops that are sometimes a little too tricky
> to make things work. Read: the less we rely on Unix shell scripting, the
> more likely Windows users will be able to enjoy our software.
>
> Changes since v1:
>
>  * Rebased on top of master to avoid merge conflicts.

I do not appreciate this very much.  

We already have a good resolution prepared when merging this to
either 'next' or 'master', which also resolves conflict with the
other topic that requires this topic to add "--topo-order" in its
call.  Rebasing series means invalidating the previous work recorded
in rerere.

	side note. The rerere database entry can be recovered from
	master..pu with contrib/rerere-train.sh).

>  * Adjusted the commit message talking about double entries, to clarify that
>    it talks about HEAD's reflog.

Good.

>  * Replaced a misleading action parameter "checkout" for the reset_head() 
>    function by the empty string: we do not check out here, we just update
>    the refs, and certainly do not want any checkout functionality (such as
>    hooks) to be involved.

OK.

>  * Reused a just-prepared refs_only variable instead of repeating the value
>    assigned to it.

OK.

>  * Fixed a stale comment about the shell variable "$upstream" (which should
>    have been negated to begin with).
>  * Fixed error messages when files could not be opened.

Good.

Will take a look.  Thanks.
Junio C Hamano Jan. 18, 2019, 8:13 p.m. UTC | #2
Junio C Hamano <gitster@pobox.com> writes:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
>> Especially on Windows, where Unix shell scripting is a foreign endeavor, and
>> an expensive one at that, we really want to avoid running through the Bash.
>>
>> This not only makes everything faster, but also more robust, as the Bash we
>> use on Windows relies on a derivative of the Cygwin runtime, which in turn
>> has to jump through a couple of hoops that are sometimes a little too tricky
>> to make things work. Read: the less we rely on Unix shell scripting, the
>> more likely Windows users will be able to enjoy our software.
>>
>> Changes since v1:
>>
>>  * Rebased on top of master to avoid merge conflicts.
>
> I do not appreciate this very much.  
>
> We already have a good resolution prepared when merging this to
> either 'next' or 'master', which also resolves conflict with the
> other topic that requires this topic to add "--topo-order" in its
> call.  Rebasing series means invalidating the previous work recorded
> in rerere.
>
> 	side note. The rerere database entry can be recovered from
> 	master..pu with contrib/rerere-train.sh).

I prepared a set of patches rebased back on top of the previous base
and applied them on top of the previous base (call the result X).

Applying the posted patches directly on top of master, and merging X
into master, produces the same tree.

So I'll keep the X (i.e. these patches backward-rebased to the
previous base) and replace js/rebase-am with it.  That is safer when
recreating 'pu' and merging it to 'next', which I hope we can do
soonish.

> Will take a look.  Thanks.

They were pleasant and smooth read.  Crafted nicely.

Thanks.
Johannes Schindelin Jan. 18, 2019, 8:31 p.m. UTC | #3
Hi Junio,

On Fri, 18 Jan 2019, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
> 
> > Especially on Windows, where Unix shell scripting is a foreign endeavor, and
> > an expensive one at that, we really want to avoid running through the Bash.
> >
> > This not only makes everything faster, but also more robust, as the Bash we
> > use on Windows relies on a derivative of the Cygwin runtime, which in turn
> > has to jump through a couple of hoops that are sometimes a little too tricky
> > to make things work. Read: the less we rely on Unix shell scripting, the
> > more likely Windows users will be able to enjoy our software.
> >
> > Changes since v1:
> >
> >  * Rebased on top of master to avoid merge conflicts.
> 
> I do not appreciate this very much.  
> 
> We already have a good resolution prepared when merging this to
> either 'next' or 'master', which also resolves conflict with the
> other topic that requires this topic to add "--topo-order" in its
> call.  Rebasing series means invalidating the previous work recorded
> in rerere.

You misunderstand. The PR had merge conflicts with `master`. As such, the
Azure Pipeline that tests it on Windows, macOS and Linux could not give me
enough confidence. So I *had* to rebase.

Besides, I think it is a terrible idea to leave the resolution of merge
conflicts to you. You are not in the best position to judge how to resolve
them, and as a consequence you spend more time and effort on this than
necessary. Of course, it's your call if you want to do it, as a
contributor I'd rather be certain that *I* resolved the conflicts.

Ciao,
Dscho

> 	side note. The rerere database entry can be recovered from
> 	master..pu with contrib/rerere-train.sh).
> 
> >  * Adjusted the commit message talking about double entries, to clarify that
> >    it talks about HEAD's reflog.
> 
> Good.
> 
> >  * Replaced a misleading action parameter "checkout" for the reset_head() 
> >    function by the empty string: we do not check out here, we just update
> >    the refs, and certainly do not want any checkout functionality (such as
> >    hooks) to be involved.
> 
> OK.
> 
> >  * Reused a just-prepared refs_only variable instead of repeating the value
> >    assigned to it.
> 
> OK.
> 
> >  * Fixed a stale comment about the shell variable "$upstream" (which should
> >    have been negated to begin with).
> >  * Fixed error messages when files could not be opened.
> 
> Good.
> 
> Will take a look.  Thanks.
> 
>