Update: The poster changed the question after I composed this answer. This update answers to one of the questions the rest of the answer doesn't cover.
OK.. Now, weird thing is; now I call "git status"; it says I'm 4 commits ahead of the remote branch. How is this happening? Shouldn't I be only one commit ahead?
After you merged (--no-ff) the commits A and D into E, the local branch is 4 commits ahead of the remote branch (I suppose the remote branch still points to A). This is correct.
Let's count the commits that are on the local branch (now pointing to E) and aren't on the remote branch (pointing to A). E is obviously one of them. E, being a merge commit, has two parents: A (existing on the remote branch) and D (not existing on the remote branch). When git pushes E to the remote server it needs to push both its parents (otherwise E is invalid on the remote server).
D requires C (its parent) that requires B that requires A. A already exists on the remote server and the chain ends here. B, C, D and E do not exist on the remote server. All of them must be pushed in order to keep the consistency of the data on the remote server.
The rest of the response treats the original question that was not very clear defined. The poster made references to git log --graph and (probably) Atlassian Stash. Both these tools (and all the other git interfaces I know) present the most recent commit first in the commit history. This answer uses the same convention.
git merge --no-ff doesn't have any effect in the situation you described.
Having br1 as current branch, git merge br2 brings into br1 the changes introduced by the commits that are reachable from br2 and are not reachable from br1. Depending on the relative position of br1 regarding br2, git merge can create a new commit (that contains all the changes introduced by the commits unreachable from br1) or it can just move the br1 branch head into a new position (and doesn't create any new commit).
In your situation, br2 is behind br1 with 1 commit and because A is a merge commit, all the commits accessible from br2 can also be reached from br1.
Anyway, git merge --no-ff is used in a different situation.
Let's say we have this graph:
B <-- br2
|
C
|
D
|
E <-- br1
|
...
The branch br2 was created from branch br1 (both were at commit E at that time) then br2 was checked out and three new commits (D, C and B) were added.
In this situation, the commands:
git checkout br1
git merge br2
do not create a new branch. The branch br1 is moved to commit B (where br2 is) and that's all. Now all the commits that are reachable from br2 are also accessible from br1. br2 was successfully merged into br1.
This is how the graph looks like:
br1 --> B <-- br2
|
C
|
D
|
E
|
...
This kind of merge is called fast-forward because the branch br1 was moved "fast forward" from its previous position to a new position (probably opposed to branch b2 that moved from E to B one commit at a time). It is possible only if br2 is the only one child path of br1 (starting from E, each commit has a single child commit and the path reaches B).
Here comes --no-ff into play. If you want this merge to create a merge commit that contains all the changes introduced by commits D, C and B then you run:
git checkout br1
git merge --no-ff br2
The presence of --no-ff option prohibits the fast forwarding of branch b1 and forces the creation of a new merge commit. The graph will look like this:
A <-- br1
|\
| B <-- br2
| |
| C
| |
| D
|/
E
|
...