Xcode 11 Git Stashing

I’ve never been a big user of the version control integration with Xcode. I like being able to see and compare changes in the editor but I prefer the command-line or an external Git client for branch and repository management.

There is a new feature in Xcode 11 that I have found myself using. Here’s a quick look at how stashing works and a bonus tip!

Git Stashing

In the real world, things can get messy:

  • “I’ll just fix this while I’m here” – I’m about to commit some changes but I notice while reviewing my work that I made an unrelated change that doesn’t belong in this commit.

  • “There must be an easier way” – I’m deep into a set of changes and realise I may be going in the wrong direction. I don’t want to commit the changes but I’m not ready to throw them away either.

  • “You need to fix this now” – I have to interrupt what I’m working on and switch branches but I’m not ready to commit my changes.

Git has a solution for this. It’s called stashing. From the Pro Git book:

Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time (even on a different branch).

Stashing with Xcode

Most git clients allow you to do this and now you can also do it directly in Xcode 11. Assuming I’ve made some changes to my source code (see Swift 5.1 two quick tips):

Source code with changes

To save these changes without committing, from the Xcode menu Source Control > Stash Changes...:

Xcode source control menu

Add a message for the stash:

Stash message

Git saves stashed changes to the repository and Xcode lists them in the source control navigator:

Stash in source control navigator

Then when you’re ready, right-clicking on the stash in the navigator gives you options to apply or delete the stash. When you apply a stash you have the option to keep or remove it:

Apply stash

Stashing from the command-line

If you want more control, you always have the option to use the command-line as long you can remember how. Here’s a quick stashing cheat list:

  • Stash tracked changes and remove from index (git stash and git stash push are equivalent):

    $ git stash
    $ git stash push -m <message>
    
  • Stash tracked changes but leave files in the working directory:

    $ git stash --keep-index
    
  • Also stash any untracked files:

    $ git stash -u     # --include-untracked
    
  • Stash everything including ignored files:

    $ git stash -a     # --all
    
  • Interactively choose which changes to stash:

    $ git stash -p     # --patch
    
  • List and show stashes:

    $ git stash list
    $ git stash show           # show latest stash {0}
    $ git stash show stash@{1} # show stash {1}
    
  • Apply stash. Note that changes that were staged when stashed are not staged by default when applied:

    $ git stash apply           # apply latest stash
    $ git stash apply stash@{1} # apply stash {1}
    $ git stash apply --index   # apply and stage
    
  • Drop stash:

    $ git stash drop           # drop latest stash
    $ git stash drop stash@{1} # drop stash {1}
    $ git stash clear          # remove all stashes
    
  • Apply and drop stash (if there are no conflicts):

    $ git stash pop            # Apply and drop latest
    $ git stash pop stash@{1}  # Apply and drop stash {1}
    
  • Apply stash on a new branch. This creates a new branch from the original commit where you created the stash and then applies the stash.

    $ git stash branch <branchname>
    

A Bonus Tip

As usual, I’m sure you all know this but just in case…

For those situations where you don’t want to stash a change but just discard it. You can revert a whole file but sometimes I want to keep some changes to a file and discard others. You can do this from the code review assistant editor but I stumbled on a way I like more this week:

Hover over the change bar in the margin of the source code editor to highlight a change:

Highlighted change in source code

Click on the blue change bar to show a popup action menu:

Change action menu

If you select “Show Change” the source code editor shows the original code inline with the change:

Show change in source code

Select “Discard Change” to revert this change without touching any other changes in the file.

Read More