2

Consider the following workflow: I created new (untracked) tests for a class after making changes to it which made the tests necessary and then realized that I need to change the logic of another set of tests which I thought would be a different commit, so I ran git stash save -u. Then, I realized that I need the stashed tests. How to get them as easy as possible?

My approach would be git stash branch and checkout the untracked test files (as described in How to get just one file from another branch), but that only works if no conflicts occur if the stash is applied (warning: git stash branch pops the stash anyway and messes up your working directory although failing with a verbose error message would be the way to go here).

I only want the untracked file(s) from the stash, but not the rest of it.

I'm using git 2.14.1 on Ubuntu 17.10.

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
  • 1
    You can apply a stash without removing it from the stash. – evolutionxbox Mar 09 '18 at 15:25
  • 2
    @evolutionxbox That leads me to the clarification in the last sentence, thank you (I'm assuming that `git stash apply` doesn't have a pathspec argument, at least I don't find one in the manpages). – Kalle Richter Mar 09 '18 at 15:27
  • So have you committed your other tests already? And you can't unstash due to a conflict right? – dimwittedanimal Mar 09 '18 at 15:29
  • 1
    @dimwittedanimal Nothing has been committed. The sequence is: changes on untracked and tracked files -> `stash save -u` -> changes on tracked files -> need untracked files from `stash@{0}` – Kalle Richter Mar 09 '18 at 15:31
  • 2
    Honestly I've started committing temporary stuff more than stashing. – evolutionxbox Mar 09 '18 at 15:32
  • 1
    I agree that this has it advantages, however the tradeoff is a messed up `reflog` which is a good aid when working on different feature branches for some time and then come back after a long time. – Kalle Richter Mar 09 '18 at 15:34

1 Answers1

1

Here's how I would solve this, based on comments.

git checkout -b <clean branch, before changes>
git stash apply

Here, you'll have tracked & untracked files. You can then use:

git reset HEAD <tracked files>
git checkout <clean branch> -- <"tracked files">

This should reset them to the clean branch state. Then you just need to:

git add <untracked files>
git commit -m "Tests"
git checkout <old, dirty branch>

Continue making changes, until ready for commit.

git commit -m "More Tests"
git merge <clean branch, before changes>

There's probably some errors here, but I hope you understand what I'm trying to say. At this point you'll likely have conflicts, that you can deal with however you deal with conflicts.

Edit: Of course, depending on how many changes you have, merging and dealing with conflicts may not be the best/fastest way to do this. If it's like one file that's changed, I'd do the same flow, but after removing the tracked files, I would just bring in the changes from the <old, dirty branch> into the <clean branch, with untracked changes, potentially already committed>.

dimwittedanimal
  • 656
  • 1
  • 13
  • 29
  • 1
    Looking good, thank you! I think I know what you mean with it, but the terms "clean" and "dirty" branch could use more clarity. I assume that by the first "clean branch, before changes" you mean a new branch, eventually stashing (or committing on a separate branch and going back) the changes after the first stash. – Kalle Richter Mar 09 '18 at 15:53
  • Yeah, so `clean branch` is meant to be whatever branch you were working off of, whether that be `development`, `dev`, whatever, up to date with the latest commits before you made your test changes. It's kinda hard because I wasn't given any branch names to utilize. – dimwittedanimal Mar 09 '18 at 15:56