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.

Having said that when Git stashing was added in Xcode 11 I have found myself using it. 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):

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

Add a message for the stash:

Git saves stashed changes to the repository and Xcode lists them in the 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:

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:

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

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

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

Read More