Return to the state before git stash

2

Recently I discovered that git stash pop does not work as I expect / desire. git stash pop merges between the current state and what's in the most recent stash.

I would like to have a command or script that would return me to the previous state to do git stash .

That is, do the following.

  • If the current working directory is dirty or if there is something in the staging area, show an error message and stop.
  • Checkout the commit in which it was in the last stash. That is, the committee father of the last stash.
  • git checkout la_rama_en_que_estaba_si_estaba_en_alguna
  • git stash pop
  • Point 3 is especially problematic because git stash does not save what branch you were on. With what I'm afraid it will not be possible without doing another script for an alternative git stash. With which I accept answers that do not solve this point.

    In bash, the above would be something like this:

    #!/usr/bin/env bash
    #1a directorio sucio
    DIR_SUCIO=$(algunos_comandos)
    if [ $DIR_SUCIO -ne 0 ]; then
      echo "El directorio actual está sucio"
      exit 1
    fi
    #1b staging area
    STG_AREA=$(algunos_comandos)
    if [ $STG_AREA -ne 0 ]; then
      echo "La área de staging no está vacía"
      exit 1
    fi
    #2 Obtener el commit necesario
    COMMIT=$(algunos_comandos)
    git checkout $COMMIT
    #4 
    git stash pop
    

    For 1a git status does not work because it returns 0 whether the directory is empty or not. The same happens with 1b. If I do not find an appropriate command, I will have to resort to making parse of git status .
    Point 2 I see even more difficult.

        
    asked by Jose Antonio Dura Olmos 04.03.2017 в 11:03
    source

    1 answer

    -2

    For the first step I use three commands to check:

    • If there are unstaged changes
    • If there are uncommited changes
    • If there are untracked changes

    .

    #!/usr/bin/env bash
    git diff --exit-code > /dev/null 2>&1
    if [ $? -ne 0 ]; then
      git status
      echo "Hay cambios unstaged" 
      exit 1
    fi
    
    git diff --cached --exit-code >/dev/null 2>&1
    if [ $? -ne 0 ]; then
      git status
      echo "Hay cambios uncommited"
      exit 1
    fi
    
    untracked=$(git ls-files --others --exclude-standard --directory)
    if [ a"$untracked" != a ]; then
      git status
      echo "Hay cambios untracked"
      exit 1
    fi
    

    For the second step stash@{0} is the last stash. And once we're there HEAD ~ 1 is the commit from which that stash was made.

    git checkout stash@{0} >/dev/null 2>&1
    if [ $? -ne 0 ]; then
      echo "No hay ningún stash para hacer pop"
      exit 1
    fi
    
    git checkout HEAD~1 >/dev/null 2>&1
    if [ $? -ne 0 ]; then
      echo "Esto no debiera suceder. Fallo ir un commit atras desde el stash"
      exit 1
    fi
    

    For the third step I will identify the branches that are in the current commit as the intersection between those that are --contains and those that are --merged . If there is one I take those. If there is 0 or more than 1, you can not know which one to take. So I do not take any. I run out of branches.

    contains=$(mktemp)
    git branch --contains | grep -v "* (no branch)" | sort > $contains
    merged=$(mktemp)
    git branch --merged | grep -v "* (no branch)" | sort > $merged
    common=$(mktemp)
    comm -12 $contains $merged > $common
    size=$(wc $common | sed 's/[^0-9]*\([0-9]*\).*//')
    branch=$(head -1 $common)
    rm $contains
    rm $merged
    rm $common
    
    if [ $size -eq 1 ]; then
      git checkout $branch >/dev/null 2>&1
    fi
    

    And it only remains to do stash pop

    git stash pop
    if [ $? -ne 0 ]; then
      echo "git stash pop failed"
      exit 1
    fi
    
        
    answered by 10.03.2017 в 08:51