Exit status is 0 but autostash requires manual merging

后端 未结 2 1299
北荒
北荒 2021-01-14 22:35

When I do:

git pull --rebase --autostash

Sometimes I get a message that there was a conflict applying the stash and I\'ll need to merge it

相关标签:
2条回答
  • 2021-01-14 23:09

    My script to work around this issue is non-trivial. I post it here to both help others and in the hope for comments for improvement.

    Call this ~/bin/git-pull-autostash and invoke it as git pull-autostash:


    #!/bin/bash
    
    # Work around 0 exit if autostash doesn't apply
    # https://stackoverflow.com/questions/52538050/exit-status-is-0-but-autostash-requires-manual-merging
    # Work around 0 exit if no stash is created
    # https://stackoverflow.com/questions/52568548/git-stash-exits-0-but-no-stash-created
    
    set -euo pipefail
    
    if [ -z "$(git status --porcelain  --untracked-files=no)" ]; then
      # Working directory and index are clean
      git pull --rebase "$@"
      exit 0
    fi
    
    # If we get to here, a stash is required.
    
    exit_code_autostash_unpopped=4
    exit_code_autostash_error=70  # https://unix.stackexchange.com/a/254747/143394
    
    stash_msg="pull-autostash on $(git rev-parse --short @)"
    
    get_stash_top() {
      local top
      if top=$(git rev-parse stash@\{0\} 2>/dev/null); then
        echo "$top"
      fi
      # Null output if there is no stash
    }
    
    prev_stash_top=$(get_stash_top)
    git stash push -m "$stash_msg" > /dev/null
    new_stash_top=$(get_stash_top)
    stash_desc="${new_stash_top:0:7}: \"$stash_msg\""
    
    # Minimise race conditions - have trap function ready before it is required
    warn_pop_required() {
      local exit_code=$?  # Non-zero if invoked from trap
      if [[ -n ${pop_required-} ]]; then
        git stash list >&2
        printf '\nWARNING: autostash %s remains to be applied\n' "$stash_desc" >&2
        exit "$exit_code_autostash_unpopped"
      fi
      exit "$exit_code"
    }
    trap warn_pop_required EXIT
    
    
    if [[ $new_stash_top != "$prev_stash_top" ]]; then
      # A stash was created
      pop_required=true  # flag for trap function
      printf 'Created stash %s\n' "$stash_desc"
    fi
    
    
    pop_stash() {
      local exit_code=$?
      if [[ $(get_stash_top) != "$new_stash_top" ]]; then
        printf 'WARNING: autostash %s is no longer at the top of the stack\n' "$stash_desc" >&2
        exit "$exit_code_autostash_error"
      else
        git stash pop --quiet
        unset pop_required
        printf 'Successfully popped stash %s\n' "$stash_desc"
      fi
      if [[ $exit_code -ne 0 ]]; then  # We were called from a signal
        exit "$exit_code"
      fi
    }
    trap pop_stash INT ERR TERM QUIT  # Pop stash on termination during pull
    
    git pull --no-autostash --rebase "$@"
    trap - INT ERR TERM QUIT  # Don't try to pop stash twice
    pop_stash
    
    0 讨论(0)
  • 2021-01-14 23:25

    With non-zero exit code you cannot distinguish pull error from stash pop error.

    My advice is to avoid autostash. It seems convenient when it works but is problematic when it doesn't. And if you do things like

    git stash push
    git pull --rebase
    git stash pop
    

    you can create a bash script or a git alias:

    git alias.pull-autostash '!git stash push && git pull --rebase && git stash pop'
    

    Usage:

    git pull-autostash
    
    0 讨论(0)
提交回复
热议问题