You can't (quite) get what you want, but what you do get may well be fine.
In Git, "squash" means "copy". More specifically, a "squash merge" uses Git's merge machinery, performing the merging action (the word merge as a verb), but then makes an ordinary commit. Suppose, for instance, you had this:
C3--C6 <-- feature
/
C1
\
C2--C5 <-- master
(note that a branch name like master or feature actually points only to one commit, namely the tip commit of the branch; and some commits are on both branches, such as C1). Running git checkout master && git merge --squash feature would then:
- choose
C1 as the last place the branches shared a commit;
- choose
C5 as the tip of the current branch master;
- choose
C6 as the tip of feature.
These are the inputs to the merging process ("merge" as a verb). Then Git will:
- compare
C1 vs C5: this is "what we changed";
- compare
C1 vs C6: this is "what they changed".
Git then attempts to combine both sets of changes. If all goes well, the result is placed in the index and the work-tree (is "staged for commit"). Since you used --squash which automatically turns on --no-commit, Git stops at this point, without making a commit, but does build a pre-loaded commit message.
You can now run git commit, which makes an ordinary commit (not a merge commit—this uses the word merge as an adjective, describing a type of commit). That ordinary commit would be just what you want:
C3--C6 <-- feature
/
C1
\
C2--C5--C7_which_is_3_plus_6 <-- master (HEAD)
At this point the only sensible thing to do with the branch name feature is delete it, abandoning original commits C3 and C6 (they will eventually, or perhaps even very soon, be garbage-collected: deleting the branch also delete's the branch's reflogs that protect them).
The log message for C7 is anything you want it to be, but depending on how you configure Git you can get it to default to combining existing log messages from C3 and C6 (set merge.log to true or a number that is at least 2, or use --log).
Note that the new commit C7 that takes what was done in original C3 and C6 (minus anything already duplicated by C5). This is what, presumably, makes it safe to delete feature entirely like this.
Unfortunately, that's not what you have. You already have a merge commit reachable from the tip of feature, giving the graph that you drew:
C3--C4--C6 <-- feature
/ /
C1--C2--C5 <-- master
The merge base of feature and master is now, not commit C1, but rather commit C2. This is because when we start from master and work backwards, we find commits C5, then C2, then C1; and when we start from feature and work backwards, we find C6, then C4, then both C3 and C2 simultaneously; and then C1.
This means that C2, not C1, is the "nearest" commit to both branch tips that is on both branches. Using git merge --squash when on master will then:
- diff
C2 vs C5: what we changed;
- diff
C2 vs C6: what they changed;
- combine the changes, and stop due to the implied
--no-commit
You can then make a new commit C7:
C3--C4--C6 <-- feature
/ /
C1--C2--C5----C7 <-- master
Again, the only sensible thing to do with feature is to delete it. The result will be the sequence ...--C1--C2--C5--C7. This is the same sequence of commits as before, and more importantly, the tree (source contents) associated with C7 should be the same as the tree you'd get without C4, as long as C4 itself is not an evil merge and C6 does not undo part of C4.
The reason for this is that C4 includes the changes from C3, and obviously C6 includes the changes from C6. This means that when Git ran git diff C2 C6 it saw the changes in both C3 and C6: those are part of one of the two inputs to the merge-as-a-verb process. Hence the new C7 contains all the changes you want.
What it doesn't have, depending on --log and merge.log settings, is automatic population of the log message. But you can edit the log message for C7 any way you like, including finding an earlier commit like C1 and using git log --pretty=short --no-merges <hash>..feature.