For the sake of your future sanity (and your coworkers'), please stop trying to rewrite history for the sake of aesthetics. The defaults are what they are for a reason.
Additionally, if I do the aforementioned git pull, I have no way of turning the commit message into an informative one because I have no information regarding the commits. Is there a way to actually know it beforehand to turn that message into a meaningful one? If so, how would you do it? If it is possible, should I just have a list of all the commits' message in that one merge commit? Regardless, I see lots of "Merge branch ... of ... into ..." commit messages and they are not useful to me at all. Why do you think people keep doing it?
> Additionally, if I do the aforementioned git pull, I have no way of turning the commit message into an informative one because I have no information regarding the commits. Is there a way to actually know it beforehand to turn that message into a meaningful one?
If there are any conflicts then it will force you to stop and resolve them, which seems like a decent point to document anything that needs to be. Otherwise, you can always amend in a more relevant message afterwards.
Rebasing does this too. Can't we compromise, and agree to never allow "git pull" to spontaneously and unthinkingly create a merge commit with two parents?
Instead, let's do merges of our rebased feature branches, into the trunks that they are based on, but with "no-ff" – this retains the information you wanted about what feature branches have merged into what trunks, and when. But the history of each branch maintains linearity and no commit ever has more than one parent.
I don't have to work with either of you, but this is how we resolved this debate on my team, and we haven't looked back. It's not even worth having this conversation unless you need branches to be long-lived. But if someone else ever has to rebase your branch with merges in it, they'll thank you if you have honored this, and curse you under their breath if you have left these thoughtless merge commits around.
Do merge, but please only merge deliberately. (I also recommend checking out Deliberate Git for a great talk on Git, with similar ideas! https://vimeo.com/72762735)
No. Shorter-lived branches naturally bring a smaller window to create nonsense history, but the risk is still there, and the benefits are as absent as ever.
> But if someone else ever has to rebase your branch with merges in it, they'll thank you if you have honored this, and curse you under their breath if you have left these thoughtless merge commits around.
So.. don't? That seems like a good thing, software should discourage you from shooting yourself in the foot.
What is the simple diff content of a merge commit which solves a conflict between two parents? There isn't one, change my mind.
We both agree that software should discourage shooting yourself in the foot. We disagree about which one of us is using the feature that encapsulates the moment where shooting ourself in the foot happens. It's not nonsense history if it reflects the order that branches were actually merged, which is far more interesting than the order in which commits were written concurrently across disparate branches IMHO.
If you are working with other people that can't read your thoughts, especially those who are too distant to reach you to return the favor when you have inflicted pain on them, they will appreciate it if you rebase your feature branch before submitting your PR and don't send forward an unmerged conflict unless we actually need to talk it over for some reason.
On the other hand I don't know anyone who will be mad that you did this. The rebase feature exists for a reason, and so does amend, reset, squash, etc. How many of these features do you think I shouldn't use? I am only discouraging the use of one feature, the automatic octopus merge that happens when you thoughtlessly run "git pull".
Why do thoughtless things? Don't you want to review the code you've pulled?
Rebasing also guarantees that the commit your CI has tested is identical to the commit that becomes head after the branches merge. How do you guarantee that your branches still function properly after merges? Carefully running the tests by hand between merge and push? My test suite is too large, and we are too busy for that, friend.
If you care about patches then the structure or order of the history doesn't really matter as long as the dependencies of each patch are satisfied (they produce the same final file when applied, and no conflicts). Take this philosophy to its extreme, and you end up with Darcs or Pijul.
If you care about tree snapshots then each commit is a promise that "I have made these changes, and afterwards the entire combined codebase still works and makes sense". If you alter the untouched code then this still breaks the promise, because "the entire combined codebase" is now different. Take this philosophy further and you end up closer to Mercurial.
Personally I lean hard towards the latter. Code tends to make a lot of assumptions about its surroundings that won't show up in a naive text-based diff (and thus won't generate conflicts), such as "class X exists and contains method Y".
The confusing thing about git is that it doesn't really make a clear choice. Some commands only make sense in a diff-based world (such as rebase and friends), while some only make sense if you think in snapshots (such as bisect, which tests whether your app satisfies some expectation at a given snapshot, not whether your diff does what it claims to).
And besides..
> Rebasing also guarantees that the commit your CI has tested is identical to the commit that becomes head after the branches merge. How do you guarantee that your branches still function properly after merges? Carefully running the tests by hand between merge and push? My test suite is too large, and we are too busy for that, friend.
If you care about bisecting then a rebase requires you to retest each commit in the branch, while a merge only creates one new commit to test. As a wise person once said:
> My test suite is too large, and we are too busy for that, friend.
This is an unreasonably high bar to reach for each commit. This is the right test to apply (among others) for whether a PR has the right stuff to get merged into a trunk, or not.
Treat it as a squash where the individual commits can be recovered. Git treats commits as left-biased, so the branch you're merging into will be the primary parent.
I'm coming at this from my angle as a team lead, or mediator between novice contributors who are both pointing the finger at each other. If the two parent branches both passed, but the merge fails, and both upstream committers are gone, I no longer can have only one throat to choke. I have to check out both branches and confer with both contributors in order to resolve the conflict again.
One contributor or the other has broke the build. It will require additional investigation to decide which. If one branch has merged first, and the other second after rebase, then I never have this problem, and my debugging process has only one throat to choke. Delegation becomes much easier.
Whoever won the race to get their PR approved and merged first is not the one at fault. (This is the greatest incentive to get your stuff tested and merged, also!) The branch that has been rebased on the other one, then, must be at fault, because his merge came later. It's not a value judgement on a person, I am just keeping it simple. My one and only motivation for operating this way is to have 100% certainty that contributors' PRs which (we) have decided to merge after reviewing the test outcomes, are the same, so that all the intensive testing we performed and spent our time reviewing before the merges will not have been a waste.
I generally don't want merges in my feature branches, and I don't think you will convince me to want otherwise. But I appreciate you having engaged me in this debate. Every time I get to talk about my strongly held beliefs, I get a better perspective on why someone else might disagree. :+1:
My teams have usually been very small, and I can't say for sure that my strategy can scale. But we have scaled it successfully past 2 and into 4 developers. It requires everyone's cooperation, but once we have it this delegation subjectively seems about a thousand percent more reliable.
I have used this in projects and it worked great for the whole team for a long time. You can of course do something else which can work for you and your team.
Without using either flag rebase should update the commit date and preserve the author date.
If by rebase you meant GitHub's rebase merge option I think you're out of luck :-/