For example, suppose I choose to use some library to accomplish some task. I will have to justify it to him, which is fine on its own, but there is unusually high resistance even if I can justify its usage. In general, I don't feel like I have my own autonomy for decision-making, which I feel should be granted; instead I feel like I am basically just his assistant.
In a team/company, you do not have your autonomy for decision making; at least not for high-level decisions such as picking a new technology, a new library, deciding on the architecture, ...
When working on a project in a team, you need to be replaceable. You could get ill/hit by a bus at any time, and another coworker should be able to step up and continue from where you were at.
The more familiarity said coworker has with your work, the better, which is why it matters that:
- you use the same 3rd party libraries as anyone else in the company,
- you structure your project the same as any other project in the company,
- ...
Of course, there is room for exploration. A new 3rd party library, a new structure, etc... can improve the statu quo, but they are disruptive, and therefore their benefits should largely offset their costs. This has to be a conscious decision on the part of the department/division/company. It's not yours to make, though you can champion it.
We have to approve each other's pull requests, therefore, if I do something he doesn't like, he has the option to reject it outright until I change it to meet his suggestions. If I have to get that feature through, I either have to stand my ground and spend a lot of time justifying it, or I have to just change it to what he suggests and move on with my life. kinda a rock and a hard place
If I may, I think that there is a working method issue here.
High-level design should be discussed prior to starting work; it's just a waste of time to work for a week on something, present it for approval, and have it rejected with the reason "Wait, have you considered the interaction with X? It'll never work!".
This means that before starting work, you need to agree as a team on a general direction. And if something comes up midway which requires a drastic change, you need to agree as a team on where to go from here.
Note: I've seen people argue for approving their PR because they had work a lot of it, despite the objections to its quality or design. It hurts to see your efforts rejected... which is why it's best to discuss things beforehand.
So, supposing that:
- you have management approval for technologies, 3rd-party libraries and project design,
- you have agreed beforehand on the general direction of the pull request.
Then the discussion on the pull request itself should be centered on:
- polishing the edge cases,
- cleaning up the implementation,
- clarifying the obscure bits.
Once in a blue moon, you may receive a comment like "Oh crap, we forgot to account for case X". It happens. It's a team mistake.
This doesn't, of course, magically resolve your ownership issue. Your coworker may still be intractable during the early discussion about the general direction of the pull request.
In general, whether one has "ownership" or not doesn't matter, you want consensus.
Your first objective should therefore be to understand why your coworker is being difficult:
- does he have a different vision?
- is he idealist?
- is he a control-freak?
- is he not trusting your skills?
- ...
and try to address the issue with him.
You need to align on the high-level vision for the project, gain his trust regarding your skills, ...
If all else fail, as a last resort1, you may want to involve your manager and have him divide the responsibilities. You mentioned you and he had different skill sets, so you should be able to split up the responsibilities in 3 areas: his area, your area and a common area. In your area, his opinion would be purely informative (and vice versa).
1 And I mean last, confrontation turn people sour.