Hi Paul,

On Fri, 31 Aug 2018, Paul-Sebastian Ungureanu wrote:

> diff --git a/builtin/stash--helper.c b/builtin/stash--helper.c
> index 02b593e0cd..87568b0f34 100644
> --- a/builtin/stash--helper.c
> +++ b/builtin/stash--helper.c
> @@ -723,6 +728,54 @@ static int show_stash(int argc, const char **argv, const 
> char *prefix)
>       return diff_result_code(&rev.diffopt, 0);
>  }
>  
> +static int do_store_stash(const char *w_commit, const char *stash_msg,
> +                       int quiet)
> +{
> +     int ret = 0;
> +     int need_to_free = 0;

Not worth sending another iteration, but if you end up doing so, I found
an alternative paradigm more useful: instead of having a Boolean to
indicate whether you need to free, have a `char *to_free` that is
initialized to `NULL`, then unconditionally release that:

        char *to_free = NULL;

        if (!stash_msg)
                stash_msg = to_free = xstrdup("Created via \"git stash 
store\".");

        [...]

        free(to_free);
        return ret;

This works because `free(NULL)` is defined as a no-op.

> +     struct object_id obj;
> +
> +     if (!stash_msg) {
> +             need_to_free = 1;
> +             stash_msg  = xstrdup("Created via \"git stash store\".");
> +     }
> +
> +     ret = get_oid(w_commit, &obj);

Is `get_oid()` non-quiet? If so, we might need to shut it up when the
`quiet` variable is non-zero. If it is quiet, we should probably mention
something here when `quiet` is zero and `ret` indicates an error with
`get_oid()`.

> +     if (!ret) {
> +             ret = update_ref(stash_msg, ref_stash, &obj, NULL,
> +                              REF_FORCE_CREATE_REFLOG,
> +                              quiet ? UPDATE_REFS_QUIET_ON_ERR :
> +                              UPDATE_REFS_MSG_ON_ERR);
> +     }
> +     if (ret && !quiet)
> +             fprintf_ln(stderr, _("Cannot update %s with %s"),
> +                        ref_stash, w_commit);
> +     if (need_to_free)
> +             free((char *) stash_msg);

Okay, so all we need `stash_msg` for is the `update_ref()` call? And the
fall-back message is constant. So how about

        if (!stash_msg)
                stash_msg = "Created via \"git stash store\".";

? No need to allocate/release memory at all...

> +     return ret;
> +}
> +
> +static int store_stash(int argc, const char **argv, const char *prefix)
> +{
> +     const char *stash_msg = NULL;
> +     struct option options[] = {
> +             OPT__QUIET(&quiet, N_("be quiet, only report errors")),
> +             OPT_STRING('m', "message", &stash_msg, "message", N_("stash 
> message")),
> +             OPT_END()
> +     };
> +
> +     argc = parse_options(argc, argv, prefix, options,
> +                          git_stash_helper_store_usage,
> +                          PARSE_OPT_KEEP_UNKNOWN);
> +
> +     if (argc != 1) {
> +             fprintf_ln(stderr, _("\"git stash store\" requires one <commit> 
> argument"));
> +             return -1;
> +     }
> +
> +     return do_store_stash(argv[0], stash_msg, quiet);
> +}

I guess `store_stash()` and `do_store_stash()` are separate functions to
discern between the higher-level function that parses the command-line,
and the lower-level function that is already libified?

If so:

1. I like it. Your code is already so much better prepared to serve as a proper
   internal API than even some Git old-timers'.

2. It might make sense to move the `get_oid()` call to `store_stash()`, as
   it is also parsing: it is parsing the plain-text representation of the
   revision into the internal representation (object ID).

Neither of these suggestions are blockers, though.

Thanks,
Dscho

>  int cmd_stash__helper(int argc, const char **argv, const char *prefix)
>  {
>       pid_t pid = getpid();
> @@ -757,6 +810,8 @@ int cmd_stash__helper(int argc, const char **argv, const 
> char *prefix)
>               return !!list_stash(argc, argv, prefix);
>       else if (!strcmp(argv[0], "show"))
>               return !!show_stash(argc, argv, prefix);
> +     else if (!strcmp(argv[0], "store"))
> +             return !!store_stash(argc, argv, prefix);
>  
>       usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
>                     git_stash_helper_usage, options);
> diff --git a/git-stash.sh b/git-stash.sh
> index 0d05cbc1e5..5739c51527 100755
> --- a/git-stash.sh
> +++ b/git-stash.sh
> @@ -191,45 +191,6 @@ create_stash () {
>       die "$(gettext "Cannot record working tree state")"
>  }
>  
> -store_stash () {
> -     while test $# != 0
> -     do
> -             case "$1" in
> -             -m|--message)
> -                     shift
> -                     stash_msg="$1"
> -                     ;;
> -             -m*)
> -                     stash_msg=${1#-m}
> -                     ;;
> -             --message=*)
> -                     stash_msg=${1#--message=}
> -                     ;;
> -             -q|--quiet)
> -                     quiet=t
> -                     ;;
> -             *)
> -                     break
> -                     ;;
> -             esac
> -             shift
> -     done
> -     test $# = 1 ||
> -     die "$(eval_gettext "\"$dashless store\" requires one <commit> 
> argument")"
> -
> -     w_commit="$1"
> -     if test -z "$stash_msg"
> -     then
> -             stash_msg="Created via \"git stash store\"."
> -     fi
> -
> -     git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit
> -     ret=$?
> -     test $ret != 0 && test -z "$quiet" &&
> -     die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
> -     return $ret
> -}
> -
>  push_stash () {
>       keep_index=
>       patch_mode=
> @@ -308,7 +269,7 @@ push_stash () {
>               clear_stash || die "$(gettext "Cannot initialize stash")"
>  
>       create_stash -m "$stash_msg" -u "$untracked" -- "$@"
> -     store_stash -m "$stash_msg" -q $w_commit ||
> +     git stash--helper store -m "$stash_msg" -q $w_commit ||
>       die "$(gettext "Cannot save the current status")"
>       say "$(eval_gettext "Saved working directory and index state 
> \$stash_msg")"
>  
> @@ -468,7 +429,7 @@ create)
>       ;;
>  store)
>       shift
> -     store_stash "$@"
> +     git stash--helper store "$@"
>       ;;
>  drop)
>       shift
> -- 
> 2.19.0.rc0.22.gc26283d74e
> 
> 

Reply via email to