So I used git-subtree to have various branches of repoB in sub-directories of repoA, like so
git clone repoA
cd repoA
// some commits to repoA here
git subtree a
Ok, so I figured this out. It was a two-pronged problem. First of all, my tree actually looked like this:

I had a commit in my tree that touched src/dirA, but was not yet pushed when repoB/branchA had already moved on.
I discovered that git subtree pull would not find the right base, because it is looking for a common ancestor, hence it used the version when I had last merged the trees, i.e. when I called git subtree add initially.
Now, to resolve the common ancestor problem, one has to git subtree split --rejoin, which performs a perfunctory merge, so git finds the right base again, i.e. after the commits pushed from repoA to repoB/branchA.
However, as you can see in my case, a git subtree split --rejoin followed by a git subtree pull does not solve my problems:

Due to the fact that git subtree split creates a synthetic history of all commit that touch src/dirA irrespective of the fact whether or not they were pushed, the SHA-1 sums diverge. I split the synthetic history into its own branch split for demonstration purposes.
git subtree pull will of course succeed after git subtree split --rejoin. However, the next git subtree push will fail, because the histories of repoB and the synthetic tree are completely different after that.
Therefore, I had to go back before the offending non-pushed commit and pull the changes into my branch from there. This is complicated by the fact that git subtree split --rejoin is still necessary, because git subtree pull via git merge can still not figure out the correct base on its own.

So the way I currently resolved my issue was by checking out the commit directly before the offending non-pushed src/dirA commit. Then I did a git subtree split --rejoin followed by a git subtree pull. This of course adds two merges into my main tree, which I could not figure out how to squash into one merge, and from what I read in source code, there doesn't seem to be an easy solution to that problem.
After the successful git subtree pull, I rebased the remaining commits from my master branch onto master_fix. Now the SHA-1 sums match throughout the shared history of repoA/master_fix and repoB/branchA.
This of course has the usual drawbacks of a rebase: if somebody else was working on master, their history will be ruined by git branch -m master_fix master.