Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Want to improve this question?
Update the question so it can be answered with facts and citations by
editing this post
.
Closed
last year
.
This post was edited and submitted for review
last year
and failed to reopen the post:
Original close reason(s) were not resolved
What are some Pros and Cons of various approaches (merge, rebase, ff only) when having a dev branch use as follows:
main
is production connected to auto-deploy in vercel
dev
is used to branch off of for any bug fixes or feature branches, which then get merged back into
dev
, then, when we want to make a release
dev
is merged into
main
for deployment.
Multiple people branch off
dev
and merge back into it, so need to keep your local dev up to date.
–
Depends how you work, myself I prefer to do a
rebase
when possible, that prevent having a merge commit while it is not needed.
When you have to merge, that's adding many commits difficult to track in the commit tree. Optimally you like to have something clean, with the smallest distance between your commit and the previous one.
The rebase will try to pull without your edits, and apply your edits on the top of the last commit.
local ┌─────
remote ──┴───╸
# Rebase :
local ┌─────
remote ──────┴
# Merge :
local ┌────┬
remote ──┴────┴
If you do it on long term, you would end up with this:
# Rebase :
local ┌─────
remote ─────────────────────┴
↑ linear upstream
# Merge :
local ┌────┬──┬────┬─────────┬
remote ──┴────┴──┴────┴─────────┴
↑ Non linear upstream
–
–
I'd like to present the no pull strategy and if you use Pull/Merge Requests to merge into shared branches, then you don't need to have a local copy of dev
at all!
Create a new branch:
git fetch
git switch -c my-branch origin/dev --no-track
Periodically update your branch:
# checkout your branch if not already
git fetch
git rebase origin/dev
Merging branches into dev:
When branches are ready to be PR'd/MR'd into dev
, assuming they will be up to date (perhaps because developers are rebasing their branches onto the latest origin/dev
to keep them up to date), then whether to allow fast-forward merges or force a merge commit is a matter of preference. If the merges only have a single commit there is less to gain by forcing the merge commit. If they have multiple commits my preference is to force a merge-commit (git merge --no-ff
). To summarize some of the advantages of using --no-ff
from another answer:
The merge (with --no-ff) forces a merge commit, and this is helpful because each PR contains the list of commits associated with just that PR, enabling you to view the first-parent history which shows all merges into the branch, and easily compare them. Another benefit of forcing the merge commit is that it's easy to revert an entire PR by simply reverting the merge commit, rather than individually reverting every commit that was in the original PR.
The only con of using --no-ff
is that if you don't care about any of the pros of using it, then you are needlessly adding extra merge commits.
Note: when merging dev
into main
I would recommend always using --no-ff
, just so you can use git log --first-parent
to see the differences between releases to production.
Why not keep a local copy of dev
?
The reasons I don't like to have a local copy of dev
are:
It is almost always out of date, and you might accidentally use an outdated version of it.
You don't have to waste time pulling to keep it up to date.
You don't ever actually need it because you can always use origin/dev
.
If you don't keep local copies of shared branches, you never have to git pull
.
The downside of using the no-pull strategy, is conceptually it takes a little time to get used to it.
Caveat:
If you don't use Pull/Merge Requests to merge into dev
, then I would add this step for merging into dev
:
git switch dev
git fetch
git reset --hard @{u}
git merge my-branch --no-ff
git push
I recommend setting pull.rebase
to true
or merges
. Here's why.
Merging work is significant, updating work is not.
Part of the point of version control is to help future programmers understand why things are the way they are. A merge commit retains the record that "these set of commits were done as a single unit of work" and it provides a spot to record what that unit was; a reference to a PR, for example. For that reason
But git pull
is just updating the branch, and nobody will care how many times you updated the branch. If git pull
merges, you've got all these extra merge commits cluttering up the history and hiding the significant merges. So do a rebase.
It's easier to resolve conflicts.
If you git pull
and it merges and there are conflicts, all those conflicts have to be resolved at once. And any consequences of those conflicts will be tangled up in there.
If you rebase, conflicts come one at a time. This breaks up the problem into small chunks, you can see exactly which commit caused the conflict. And they happen immediately before more work is piled on top of them, you can deal with them before more work is piled on top of it.
It's easier to review.
If you merge, your branch is written on a moving target. Earlier commits will be written on earlier parts of the upstream code, later commits will be written on later parts of the upstream code. If a reviewer wants to look through the branch commit-by-commit, they have to keep in mind which version of the upstream that commit was written against.
Rebasing on pull rewrites your code as if it were always on top of the latest upstream version all along. This forces you to rewrite each commit to work for the same version. Now if a reviewer looks at a commit they know it is written for a single version of the upstream.
I normally prefer git pull --rebase
. When you run git pull --rebase, your current local branch gets rebased on top of the last commit from the upstream . This will help you to achieve a linear history of changes.
When you do git pull -ff may result in a non-linear histories, by creating merge commits.
Then solve the conflicts if any.
Note that the two last operation can be done with git pull
put it is better to split the two especially in case of conflicts.
Recover stash changes:
git stash pop
You can check your dirty changes with git status
.
And then you can continue to work on your repo and eventually git add
, git commit
, git push
...
–