Search code examples
gitgit-stashgit-checkout

Want to apply my stash to a new branch and override everything in it with what is in my stash


So i'm working in Git and trying to create a new branch where I can drop the contents of my stash, and favor my stash in any merge conflicts that occur when doing so. I am doing the following:

git checkout -b *newbranchname*
git stash apply

And it is telling me of merge conflicts in a file. How can I go about doing this in the terminal and automatically favor the stash in any conflicts without having to deal with them specifically?


Solution

  • In my opinion, the easiest method is "don't do that" :-)

    Instead, turn your git stash contents into a branch of its own:

    git stash branch newbr
    

    Now you have a new branch newbr, with the index ready to commit (if you had items git added to the index) and the work-tree modified as per the stash, ready to be git added and committed. If you had carefully added stuff before, go ahead and commit that now, then add everything else and commit again. If not, just add everything now and commit. Now you have a new branch newbr with one or two commits on it—how many depends on how many git commits you just did—which joins up with whatever commit was in place when you did the git stash.

    You can now make a different new branch from a different starting point, if that's what you want, and use git cherry-pick to bring over those commits, then discard the new branch. Or, you can use git rebase -i (with the <upstream> and, optionally, --onto arguments) to copy the commits elsewhere in the usual rebase fashion, discarding the original commits once the copies are done. Or, if the existing starting point of newbr is what you wanted after all, you are already all set.


    All that said, if you really do want to just check out the work-tree version of conflicted files, completely ignoring the current version of those files, you can do that quite easily. The thing to remember is that the reference name stash (or stash@{N} for some number N) refers to the work-tree commit that git stash made when it saved the i and w commits of the stash bag. Hence:

    git checkout stash -- path/to/file
    

    extracts the w version of path/to/file, writing it through the index (hence resolving any conflicted merge), completely ignoring the HEAD version of that file.

    (The index-commit versions of files are in stash^2, and if there is an untracked/all-files commit, those files are in stash^3, as I noted in that other answer. While w is technically a merge commit, it's not a normal merge, and the all-files commit in particular is very unusual, since it has only those files, and none of the index/work-tree files.)