I snipped the rest of this because I *dislike* and *recommend against* the use of `git stash` in the first place. If you want to use it that way, I am sure it is possible, but I recommend doing something else entirely. The rest of this message is all opinion! You seem to be looking for a recommended method, so I'm recommending mine.
Let's say for concreteness that your current branch is named "topic". Here is what I would do (though I might change strategies and use various short-cuts depending on various sub-scenarios; this is meant for illustrating how to do what you want, in a way that provides the most clarity):
git add (files as needed) git commit -m "final version, to be split up" git branch -m not-final-topic
Then:
# create a new topic branch git checkout -b new-topic <start-point>
# get a view of commits git log HEAD..topic
# copy some commits, up until some point git cherry-pick <some of those commits as desired>
# begin splitting a commit: git cherry-pick -n <hash>
# split it up: use a mix of the following:
git reset / git add -p / git reset -p
# as needed here to take part of the commit)# observe what's to be committed git diff --cached git commit # and write a commit message
git add -p ... # as needed again git diff --cached git commit # repeat until satisfied with broken up commit(s)
# make sure final result matches - optional: use the same # hash here as for the `git cherry-pick -n` command git diff HEAD <hash>
# repeat copying whole and partial commits:
git cherry-pick ... # add more whole commits as desired
git cherry-pick -n ... # add commit that is to be split up
# repeat the split-up process# When finally done, ensure that new-topic and not-final-topic # have the same contents. If they do, the split-up was successful. git diff not-final-topic HEAD
Note that there is no longer any branch named "topic" at this point: we have instead "not-final-topic" and "new-topic". We can now rename "new-topic" to "topic" and use `git push -f` or whatever else is appropriate for whatever review system(s) you may be using.
The entire process above can often be done with a single `git rebase -i` command, but that obscures the fundamental nature of what you're really doing. The repeated cherry-pick, reset, add -p, and/or reset -p sequence is what you're really doing: you are taking some set of existing commits, which are *close* to the commits you'd like to have, and rebuilding them to make a new set of commits (with different hash IDs) that represent what you really do want.
In the end, you will have Git *find* your commits by name: the name "topic" will name the last commit in a chain of commits. The names here are up to you, and you can change any name at any time using `git branch -m`. Both Git and any review system you use is going to use the *commits*, with their scary looking hash IDs, but like you they will *find* these commits by starting from a branch name: so by changing the hash ID stored in the branch name, you change the set of commits they (and you) find.
What `git stash` does is make several commits that are not on *any* branch. These commits are a little weird, requiring the use of the `git stash` command to access them. Ordinary commits on ordinary branches are not weird and do not need any special access, so that's what I prefer. But the fact that the stash commits are on *no* branch makes it easy to slide them from one branch to another without having to think about hash IDs; that's one reason some people prefer `git stash`. I'm just not one of those people.
Chris