Say we have a repository with a master branch and a feature branch. Since the feature branch has come off master, there have been no other changes added. Also, the master branch is the currently checked out branch and we can see that because HEAD points to master.
So, we want to bring in the changes from the feature branch to the master branch so we issue a simple git merge feature. Even if you use the -m flag to add a message to this merge a terse message appear saying that there has been a fast-forward. What has happened is that since there are no other changes, there is no merge and the master branch is just moved to point to the tip of the feature branch. Since HEAD points at master, it follows along. So the position is this.
Nice and simple, and makes sense. But it can annoy some users who like to work on a feature in a branch but want that loop to exist after merging it back in the main line. It can make it easier to see the changeset in one glance and more convenient to back out later if needed. Git has a way of fixing that. If instead of git merge feature we change the command to git merge --no-ff feature (note the --no-ff flag) and the branch is merged instead.
Personally, I’m comfortable with a rebase based workflow, so I don’t use this flag, but it’s just another example of the annoying flexibility of Git.