Generally speaking if you have a
master branch and a
development branch, and you're following some process (instead of randomly doing things in git), you are most likely expected to branch from
dev instead of
This is because
main or whatever it's named) should represent a very stable state of code, ideally the same as the last release. On the other hand if you don't release often, and are working with multiple developers, the development branch could contain a lot of changes and be very different from master. Since you (hopefully) won't merge directly to master, you could end up developing on top of "stale" code (from master) and when merging to development you would notice that "oh no, I've written code that doesn't fit well with the code in development".
Since development will most likely be merged back to master to represent the new "release state", branching off of development allows you to develop on top of more up-to-date code than if you were to branch off of master. This means you'll have less merge conflicts.
There are different factors that affect how much of a difference this makes (e.g. if you have a daily build/release cycle, your master and development will never be very far from each other), but this is one logical reason (and not just a convention) why development should be used instead of master for branch root.
What I've described is your second situation, which follows gitflow at least in principle. Your first situation describes a different branching model. Git doesn't mandate that you do things in a specific way, but time has taught effective processes to use.
In your first situation you have to make sure that dev and master are synchronized, so you don't test code in dev that would then break in master. This may not be an issue, and it may be completely intentional if short release cycles are to be used. It may also mean that development can be "broken", if the idea is that features are pushed to dev and automated testing is done on that branch when new code is pushed. Ideally you wouldn't risk pushing broken code to dev, running tests locally before pushing, but if for example the test set is heavy, it might not be possible.
TL;DR a suitable branching model depends on a whole lot of things, such as the length of the release cycle, the amount of testing done, the amount of developers and of course the nature of the system. There are conventions and processes that are developed to minimize the complexity of multiple developers working on the same codebase, but there are no strict rules except for one.
"DON'T BREAK MASTER!".