Marcin Wosinek Definitely agree. Thanks for sharing your perspective as well!
The git reset --soft was a new command for me to pick up this year and I've found it very useful. Sometimes if you have a super complex merge you can also just use:
git diff HEAD origin/main >> changes.patch
git checkout main
git checkout -b feature-branch
git apply changes.patch
After all, a bunch of commits are just a text file with changes, and you can pipe it into a file, and apply it arbitrarily.
Patch files tend to be the most useful when I'm sharing in progress changes with another developer and I don't want them to deal with committing or asking someone to check out. I just take my in progress 75% working code and:
git diff HEAD origin/main >> changes.patch
- Send changes.patch over slack to developer
- Ask them to checkout main and git apply changes.patch
Most often I actually see this when working with Solutions engineers, client engineers, or sales engineers. It's an easy way to verify if the thing you are solving for them is actually accurate. That depends on those team members being actual developers though... but I digress.
It may be interesting to do a blog post on squash merges. When discussing requiring squash merges with developers I tend to reference
christopher.xyz/2020/07/13/squash-merge.html
and
blog.dnsimple.com/2019/01/two-years-of-squash-merge/
This one is non-negotiable for me as far as enforcement goes, but I have learned that others disagree, sometimes strongly. It would be interesting to see more blog posts on this topic in the future, regardless of stance!
Good post! I'd like to share an additional perspective when it comes to rebasing.
In this case and many others I often do the following:
Another way to do this:
These are simple ways to copy your commit history without dealing with some of the challenges that can come with collaborative rebases.
Probably the most common time I use this workflow is the following:
Developer A is working on feature A and opens a merge request.
Developer B needs code from feature A, and is in a dilemma of how to begin. Do they copy the code they need from feature A? Do they branch off feature A branch?
I recommend Developer B branches off Feature A branch. They can do their work and commit along the way.
When Feature A merges (probably a squash merge) the real problem enters. Developer B now has a bunch of commits from feature A in the Feature B branch that no longer exist in main due to the squash.
This can really challenge peoples git knowledge... but it's quite simple really. It's as easy as 1, 2, 3.
Again, I think if there are many commits you are better off doing an interactive rebase to squash the feature B commits into a single commit (as long as the history isn't important.). Or the lazy way, `git reset --soft HEAD~<commit count> (or alternatively, git reset --soft <SHA of the original HEAD commit of the main branch>). Then you create a new commit, copy the SHA, and cherry pick that onto your new branch.
In general I pretty strongly discourage force pushes on my teams to branches that have been pushed up to a remote. Squash and merge being enabled means that the commit cleanliness in main is preserved, and the commits in a branch can be as messy as they need to be (reality in development is rarely beautiful... why rewrite history anyways?) Very rarely are perfectly curated commit histories worth the time for a developer. I'd rather see beautiful code and a nice squash merge than a perfect few commit messages in a PR history. If you follow that line, then it's fine to have some merge commits in there anyways.
All in all, a great article. Just thought I'd share my thoughts on this as well. I stumbled here from the gitlab CI monorepo post. It will be a useful starting point for me tomorrow :).
What do you think Marcin Wosinek?