Exit status is 0 but autostash requires manual merging

后端 未结 2 1301
北荒
北荒 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
    

提交回复
热议问题