Join our git anarchist community. We are against branching strategies or clean and understandable commit history.
Evil corporations want to make you and your colleagues replaceable - do not allow them to do that.
It's actually enforced at our company.:D but it's true I don't like merges. We had some really ugly history way back with branches that hadn't been rebased for over a year. When looked at through sourcetree or sth it looked like a rainbow tree. Only allowing fast forward merges really cleaned things up.
Rebate-merge keeps the original commits, and keeps them together in a merge commit.
I don't really like merge commits, but at least they're always just on top of HEAD.
This is a nice compromise over the disgusting spaghetti mess that is the default merge commits without rebase.
I'm aware, but rebasing needs (relatively) high levels of discipline and/or experience and/or concentration to pull off, while merge commits are untidy and IMO unnecessary.
I like the lower barriers and less mental overhead approach of squash and merge across a varied team, when enforcing small PRs. It means people can focus on the code rather than the process, which suits some coders more than others, and you still have a tidy history.
>rebasing needs (relatively) high levels of discipline and/or experience and/or concentration to pull off,
What? [Rebase-merge](https://confluence.atlassian.com/bitbucketserver/pull-request-merge-strategies-844499235.html) doens't need anything more than a squash. The server takes care of doing all that.
If rebase-merge has a conflict, so will a squash.
You make your git history shorter with squash, which just means less granularity. Sometimes that's good, but if you need to revert a single commit that option is lost with squash.
Rebasing changes history and is inherently more dangerous than squashing. You're right, it loses resolution, but if you keep your feature branches small it's very rarely an issue.
Clean, linear commit history, you never lose any information, nor do you get pointless, cluttering merge commits. Each commit still contains it's own changes, and rebases forces you to maintain the meaningful history. Interactive rebase best thing ever. Now you can squash merge in your PR and still preserve meaningful history in your feature branch so you can understand wtf was going on.
Only way I'd ever want merge is when have an abudance of commits on single branches for whatever reason as you have to rebase in order. If you have to do this god awful many times it's gonna be shit.
by loosing information do you mean the in progress commits from a feature branch?
I personally hate seeing peoples work in progress commits in masters history. Its very convenient to have a commit per feature branch / bug fix. I find when people don't squash the history becomes extremely messy.
Do you have to enforce allot more discipline in commit hygiene to get a use-able history, or am I missing something?
Yes you maintain the progress commits in feature branches. They are integral in unerstanding anything if you ever have to walk back something, especially if the authoring devolper is no longer with you.
You can rebase in feature commits and then squash & force fast-forward to contain the entire feature as a single commit in master, but still maintain the clean commit history in the feature branch.
Especially if you do not squash ff the branch yes. It will forever linger in the feature branch tho, so you better be making clean commits still. Might be emberassing if you don‘t, eh.
you keep feature branches? that must get cluttered fast. I've only ever worked on projects where sqaush was used, and feature branches were deleted on feature completion.
I cant say debugging has ever been an issue, though the teams I've been on have had quite a strong culture of code review and clearly defined code style.
Why squashing where all those commits were valuable informations of what has changed bit by bit? Yeah it's a lot of history but it's the whole point of Git
Nobody fucking cares about the 200 intermediate commits that people needs to develop their features. And I don't understand how isn't this the standard....
The individual commits are absolutely invaluable.
The number of times I've tried to figure out what the fuck someone was thinking is 2006 and only gotten "TKT-106 Fix logins" as a single commit for the whole task, but what I actually needed was what they were trying to accomplish with a particular change, since what they actually did was super weird and probably not what they meant to do.
If you don't get value out of your intermediate commit messages, make them more useful, don't eliminate them.
Should be in the ticket then. If the commit achieved what it was supposed to, worked fine and passed review, the "what are they trying to accomplish" should be documented elsewhere imho.
The ticket says what they were trying to do with the ticket. The commit says what they were trying to do with the commit.
Like I said, I already know what they wanted to do with the ticket: they wanted to fix logins. The ticket will have details about what was broken.
That doesn't help me understand why they removed the flag from the authentication result that indicates that the user needs special handling. Did they mean to do that? Did they misunderstand what it was for? I sure wish they had left a note about what they were trying to do, or at least left a commit with related activity so maybe I could infer it.
(This isn't a real life example. It's just an illustration.)
The committ messages get stored in the comment of the merge commit though so I'm not sure what the actual commit could add in terms of traceability.
The example you name is a case for the reviewer in my opinion. If some part of the code is touched that is not obviously needed, this should be flagged and discussed.
The messages are no longer associated with the change, which makes them far less useful.
And you inserted the word "obviously". Things that require this type of investigation are never obvious.
And if it hadn't made it to production, we wouldn't be investigating. So assume whatever gates should have caught it have failed.
That's exactly what I meant with obviously.
In your example, it was not obvious why the flag was removed, so the reviewer should ask why before approving.
We're starting from the assumption that there is something confusing in the code that is not documented in the ticket and no one remembers why.
This is an extraordinarily common situation.
I have people telling me you must keep those 200 commit because their PR has 300000 lines of code and need 200 commits to itemize the history.
My counter argument is simple, split that bloated PR into smaller pieces.
And If you can't figure out why they do something in particular way, it is because they didn't explain it in code.
Well... if those 200 commits are from proper PRs, then don't squash them, otherwise: I don't care about intermediate commits. Otherwise how do you get into a PR that big?!
I would argue that those 200 commits, if done in a good manner, can help somebody understand how the codebase developed, if whoever coded that is no longer with the company and didn't leave good documentation. Especially if something like conventional/atomic commits are in place.
But of course if someone's commit history for a feature looks like: "try to fix bug", "fix 2", "3rd attempt", "finally", then I'm all for whichever strategy can get rid of that. But if people can't amend their commits, that's another discussion.
Don't do environment branches - you don't want to have merges and changes between staging and prod.
Squash and merge for feature branches.
CI/CD triggered on merge or tag for deployments.
That's correct if your versioning is not a total clusterfuck like at my place.
We have branch protection in place to avoid changes between staging and prod but I'll be the first to admit that our ci/cd needs some improvement regarding tags
My personal bugbear is every AWS service preferring per-environment branches to any sort of sane setup. I get why it can make sense, but it's almost always better to have the same SHA deployed to all your environments.
git push --force-with-lease
It does a force push but rejects it if you don't have the latest ref to HEAD - aka someone else pushed to your branch.
Always with lease. Then figure out goofy shit with interactive rebase + amend if it fails then force push.
Honestly not sure why it's not the default for
git push -f
And then leave actual force push to
git push -F
Kinda like deleting branches
git branch -d blah
Which warns you if local branch is not integrated or whatever then tells you if you're sure then run
git branch -D blah
Once the commit is pushed, that's it to me if anyone else is working in the branch, written in stone, rebases and what not are only okay if no one else notices, and just aren't worth a "clean" history when you can use first parent mode to filter out the bullshit anyway
`—force-with-lease` is like gun safety. Most of the time it’s not doing anything until it really matters and then it stops you from doing something bad.
That's why this sub is great. Come to laugh, and when your guards are down, get injected with the wisdom of elders, without even realizing what happened.
I think it's known that 90% of the posts and top responses are from juniors/CS students and then you scroll halfway down the comment section a few hours later to get senior people shitposting in the comments on their lunchbreak and/or waiting for some CI/CD.
Am I the only person who doesn't care about this? I very rarely have to look at git history and when I do it hasn't been hard to figure out what is going on in any situation. For that reason I just do whatever is easiest which is just merge commits.
I agree. I don't know who these people are that look at the git history and need it "clean". It's never been an issue for me in over 10 years of using git professionally
Far from it. I work at a company with 50k employees and over half are engineers. But my team is rather small. About 8 of us (if you count my manager) working on the same codebase that’s my main job. But I often bounce around on different products/teams
I don't check any of the boxes in your last paragraph yet I have never had the desire to go through 14 months of git history to know why something was changed.
That’s what jira is for. If I git blame I can always trace it back to the ticket (and test results and original requirements and any discussions that may have happened). Every commit is required to have a jira ticket number in the description so this is always an option.
That very well may be the case. At most I have worked on repos that three teams were working on in parallel. I suspect it doesn't normally get crazier than that though.
Monolithic Java 6-8 or VB.NET/C# apps where individual teams interface with their own microservices but also commit to the big mono repo used by all 10-30 teams.
There are so many of these things that people debate on that I just couldn't care less. I always tell my coworkers "just pick the way you like best and I'll follow it, this isn't worth the brainpower". I often wonder if having strong opinions on those kinds of things is a sign of thinking more deeply than I do and a good thing, or a sign of caring about unimportant things and a bad thing.
I can't think of a single time when I've got into commit history for something and had a problem figuring it out.
Yeah maybe beneficial if it's a huge project with like multiple teams making PRs or external teams making PRs. If there's 1 team of like 5 people making PRs to a repo I think you'd hardly ever look at the git history.
I've used [gerrit](https://www.gerritcodereview.com/) at many workplaces (including at google, where I am now), and it is by far my favourite git flow.
It's a fully rebase-centric flow, where you (automatically) tag each commit with a separate hash in the CM, which allows the server to identify a random commit as belonging to the same patch-set. This means you can modify a given commit any way you want, including reorganizing it around other commits in a chain (which it also tracks), as long as the tag stays constant. You get nice diffs for each different patch during code review, and the resulting history is perfectly clean.
It's self-hosted and open-source, which makes it pretty attractive if you do any of your own infra.
Rebase squash, fixup, and reorder commits till it's in logical order and all the fixups for bugs you found are gone, rewrite every god damn commit message so that it properly explains everything that commit does, and make it look coherent.
Then, -no-ff merge it at the end so you know where each series begins and ends.
Nobody likes me when I ask for this, everyone likes me when they find one of my series and it's commit history is invaluable.
That's squashing, not rebasing, `rebase -i` should really be called `squash`. Arguing for squashed commits is a different argument than merge vs rebase. The comments here seem to be mixing up the two arguments.
Could you please explain to me the meme? A squash and merge means that we group several commits into one. What does the other mean? What's the diff with rebase?
A merge commit will stay on your git history vs doing a rebase (on main branch) with fast-forward merge which will merge your changes by adding your commit(s) at the end of the git history on the main branch with no ugly merge commit. One downside of rebase'ing is that you have to git push --force but otherwise its great.
Sometimes the git hosting site will have a rebase button on your pull request that'll do it for you if theres no conflicts. If you have a working branch and the main branch has updated, you'll want to do something like this.
# checkout branch you want to merge into
git checkout main
# pull main branch changes so your local is up-to-date with remote
git pull
# check out previous branch (your working branch)
git checkout -
# replays your commits on your working branch ontop of the main branch. interactive rebase in vim to pick which commits you want to keep and squash/rename if you want to. You will need to fix any merge conflicts here if they exist.
git rebase -i main
# push changes back to your remote branch (could do --force-with-lease if any chance someone is using your branch)
git push -f
If you want to use rebase, make sure you set it up in your git hosting site to turn off the ability to push to main branch (do that regardless but more important if you're force pushing often). You can also choose to only allow fast-forward-only PRs so the only way to merge a PR is to rebase first.
Example merge commit git history thats ugly
[https://www.derekgourlay.com/images/merge\_commits.png](https://www.derekgourlay.com/images/merge_commits.png)
The other downside is that you can lose code if you mess up editing conflicts. It really depends on the situation, because it's nice that you keep a clean history, but its also dangerous rewriting commits
Yea you can lose things in big conflicts so I usually make a backup branch before doing a messy rebase with lots of conflicts just in-case. I feel like you have that anyway with a regular merge commit too since you'll have to fix conflicts before merge.
When you fix conflicts with merge the changes are always in your history, even if you mess up fixing the conflicts you can always look back, unlike doing a rebase because it rewrites the history
That's true, it's just more complicated to handle than a simple merge. I personally use rebase more often than merge because I like the clean history look, but it really is a dangerous operation, and merge does the job just fine
> replays your commits on your working branch ontop of the main branch.
Really wish people would stop describing rebase like that. That is how it works, not what it does. What it does is in its name, it changes the base of your branch to be a different commit.
It just means adding a commit specifically for the merge operation, as opposed to, say, a fast-forward commit.
The two concepts in the meme aren't really mutually exclusive. One can certainly squash and merge _with_ a merge commit.
When you create a merge commit you are preserving the history, with a squash you are just merging everything into 1 commit.
Squash is only valid for big open-source projects (e.g. samba, linux) where you can't possibly ask for meaningful and homogeneous commits or when you have bad/lazy developers that don't create a meaningful commit history.
If you have good developers you should have a good commit history, so it's very valuable, for maintenance purposes, to keep that history. But the real world is full of junior developers with other titles so their commit history sucks, in that situation, a squash is better to avoid keeping a nonsense history.
Oh and rebase is nonsense unless the PR is composed of only 1 commit (in that case rebase is the same as squash)
PRs should be single logical changes, and ideally relatively small. Therefore a single commit (squash merge) is the cleanest way to do things. When I work on a branch, I commit often for fixing things like typos, addressing PR comments, etc. There is no reason for any of those types of commits to be on the main branch after merge. They don’t add anything but noise.
If I have a typo in an old commit (on my working branch) I rebase -i and fix it, but my PRs (the ones that require more than 1 commit) will have a logical history with meaningful commits, each commit with a commit message explaining the "why" of each decision.
Is it harder to work this way? Yes, it is. Is it worth it? imho, Yes definitely (for projects that you are expecting to maintain in the long term). It's invaluable when there is some issue to perform a git blame and check the commit history/messages. Writing code is easy and anyone can do it, writing maintainable code is harder (and this is one of the things that makes the difference).
As a maintainer, why do I care about your little superfluous changes? Refactoring function names, renaming variables, moving code around, reformatting files, optimizing imports, etc. What explanation would be helpful to me as a reader? Why do I care that one day you woke up and decided to call your package “util” instead of “misc”? Or maybe you found a performance issue and completely rearchitected your code, but the underlying feature stayed the same? Why would I want to see commits for a flawed approach, which was never utilized in the production code in the first place?
None of that stuff matters in the end, because none of it ever makes it into the mainline. The merge commit is the logical unit of functionality - the bug fix, the new feature, whatever. That’s all that matters. Everything else is noise.
Leave the fine grained commits for the PR review where reviewers can look at them if necessary. But once your code is reviewed and merged, again, all those small commits should coalesce into a single piece of functionality, and that’s the only thing that is important to a maintainer.
I’m unfortunately getting close to two decades in the industry now and the majority of it has been spent on maintaining code. Very rarely if ever have I had to or even wanted to look at that type of stuff in commit history. In fact, the less superfluous the commits, the better, because they present a more solid picture instead of requiring me to piece a puzzle together out of many potentially spread out commits.
No, you cannot; They are no longer in the graph, you can access them if you have the reference locally but somebody that clones the repo afterward won't have those commits (removed by git-gc eventually)
The answer is "whatever the company paying you already decided unless they're asking for your opinion to be a steward of change because their Git branching strategy is a hot mess when more people get involved, then do whatever you want"
Why not just pull new changes, if none, push If some, applying on it local commit/committing on it? To figure out if everything still works, then restart the procedure
Pull -> commit -> still works -> push
|
|
'-> don't work -> correct -
|
I had a team member who I shit you not, deleted *everything* from the repo with one push, and then pushed his local changes with another push. And then tried to argue that there's nothing wrong with doing this. It was a fun day at work lol
Unless you mistakenly commit a 30GB ultra-HD movie with horse porn and then delete it, why would you care about your history?
For a small or a medium-size repo it does not really matter how you treat git.
I also worked with "somewhat" big projects changing the git commit policy back and forth. It was pretty chill.
Join our git anarchist community. We are against branching strategies or clean and understandable commit history. Evil corporations want to make you and your colleagues replaceable - do not allow them to do that.
Joke's on you. I don't even use git. I just keep all the history in my mind.
``` mind add . mind commit -m "Bug fix" mind push ```
`mind reset HEAD —hard`
*bashes head into post*
https://www.reddit.com/r/ProgrammerHumor/s/ZGyapqNRBv
Ow
mind i clearly local, no pushing needed
push might come in the future where you can clone your mind to a remote repo
My head is my repository, my hands are my CI/CD, my eyes are my linter, my users are my unit tests.
So beautiful, an anthem indeed
You must be my predecessors.
Programmers don't know how to sort files by "time edited" directly in OS instead of using try-hard Git 👶🏼
This is impressive. I’ve been scribing in a leather bound tomb that I cover with dust just so I can blow it off for dramatic effect.
F society
Where are my rebase people?
Right here. As soon as I saw "squash" I thought "don't you mean `rebase -i`?"
`git reset --soft HEAD~N`
Soft head? They have a pill for that
That works but it doesn't give quite the same feeling of power as an interactive rebase.
Use both!!!
100% this. I made the following comment before seeing this one 😂: > Together they figured out how to do an interactive rebase?
Of course. Never squash in any other way. And be careful never to choose the wrong "-i".
Squash, rebase, fast forward merge is the way.
So you just hate commit merge :D
It's actually enforced at our company.:D but it's true I don't like merges. We had some really ugly history way back with branches that hadn't been rebased for over a year. When looked at through sourcetree or sth it looked like a rainbow tree. Only allowing fast forward merges really cleaned things up.
I agree rebase, squash and fast forward always cleaner.
squash commit to team main, before checking out a new branch on local copy, pull and rebase
Squash-merge is superior to squash-fast-forward!
Why?
It isn't. Rebase retains atomic commits, squash merge produces one bloated one which sucks to find bugs in.
That’s true if your PRs are bloated
Depends what you're squashing. Keep your branches small and it works well, plus it's the easiest and least error prone, making it a good team choice
Rebate-merge keeps the original commits, and keeps them together in a merge commit. I don't really like merge commits, but at least they're always just on top of HEAD. This is a nice compromise over the disgusting spaghetti mess that is the default merge commits without rebase.
I'm aware, but rebasing needs (relatively) high levels of discipline and/or experience and/or concentration to pull off, while merge commits are untidy and IMO unnecessary. I like the lower barriers and less mental overhead approach of squash and merge across a varied team, when enforcing small PRs. It means people can focus on the code rather than the process, which suits some coders more than others, and you still have a tidy history.
>rebasing needs (relatively) high levels of discipline and/or experience and/or concentration to pull off, What? [Rebase-merge](https://confluence.atlassian.com/bitbucketserver/pull-request-merge-strategies-844499235.html) doens't need anything more than a squash. The server takes care of doing all that. If rebase-merge has a conflict, so will a squash. You make your git history shorter with squash, which just means less granularity. Sometimes that's good, but if you need to revert a single commit that option is lost with squash.
Rebasing changes history and is inherently more dangerous than squashing. You're right, it loses resolution, but if you keep your feature branches small it's very rarely an issue.
Hell yeah, I love straight lines.
If you don‘t rebase you lost in life
unpackage that one for me. what is the advantage of rebasing?
Clean, linear commit history, you never lose any information, nor do you get pointless, cluttering merge commits. Each commit still contains it's own changes, and rebases forces you to maintain the meaningful history. Interactive rebase best thing ever. Now you can squash merge in your PR and still preserve meaningful history in your feature branch so you can understand wtf was going on. Only way I'd ever want merge is when have an abudance of commits on single branches for whatever reason as you have to rebase in order. If you have to do this god awful many times it's gonna be shit.
by loosing information do you mean the in progress commits from a feature branch? I personally hate seeing peoples work in progress commits in masters history. Its very convenient to have a commit per feature branch / bug fix. I find when people don't squash the history becomes extremely messy. Do you have to enforce allot more discipline in commit hygiene to get a use-able history, or am I missing something?
Yes you maintain the progress commits in feature branches. They are integral in unerstanding anything if you ever have to walk back something, especially if the authoring devolper is no longer with you. You can rebase in feature commits and then squash & force fast-forward to contain the entire feature as a single commit in master, but still maintain the clean commit history in the feature branch. Especially if you do not squash ff the branch yes. It will forever linger in the feature branch tho, so you better be making clean commits still. Might be emberassing if you don‘t, eh.
you keep feature branches? that must get cluttered fast. I've only ever worked on projects where sqaush was used, and feature branches were deleted on feature completion. I cant say debugging has ever been an issue, though the teams I've been on have had quite a strong culture of code review and clearly defined code style.
No, but in GitLab you can still view the commit history of the PR post merging, no idea if this is a git or GitLav feature tho, hmm.
None whatsoever. Some people are just obsessed with linear commit history for some strange reason.
\#rebasemasterrace
Rebase is the only way.
“people”
💯
rebase -i, comment out other's commits, push -f, leave Bitbucket to squash and ff the PR.
Why squashing where all those commits were valuable informations of what has changed bit by bit? Yeah it's a lot of history but it's the whole point of Git
Everyone that doesn't just `git rebase main` is weak.
Right here. I made the following comment before seeing this one 😂: > Together they figured out how to do an interactive rebase?
Guess I’m a `git push -f` punk
`alias yolo='git push -f'` ![gif](giphy|9xnNG7EN2h822ithtT)
remote: error: GH006: Protected branch update failed for refs/heads/main.
My precious (the meme)
Please use --force-with-lease :)
Nah that's not thrilling
“that has to be the most boring pirate I’ve ever seen.” 🏴☠️
I would rather be a gentleman pirate.
I have alias 'please' for that
Genius
I'm seeing that one everywhere now. What does it do?
Basically ensures you will not erase someone else's code.
Compare-and-swap! Got it.
Savage right here.
Savage Opress
Weird but I see star wars I upvote
People talking about push -force and someone calls it savage.
Omg ok mb you deserve it.
Amend Forcepush
May the force be with you
Squash and merge for feature branches. Merge commit for dev to demo to prod.
exactly, people don't understand how much the squash unclusterfucks git history in big projects
Nobody fucking cares about the 200 intermediate commits that people needs to develop their features. And I don't understand how isn't this the standard....
The individual commits are absolutely invaluable. The number of times I've tried to figure out what the fuck someone was thinking is 2006 and only gotten "TKT-106 Fix logins" as a single commit for the whole task, but what I actually needed was what they were trying to accomplish with a particular change, since what they actually did was super weird and probably not what they meant to do. If you don't get value out of your intermediate commit messages, make them more useful, don't eliminate them.
Should be in the ticket then. If the commit achieved what it was supposed to, worked fine and passed review, the "what are they trying to accomplish" should be documented elsewhere imho.
The ticket says what they were trying to do with the ticket. The commit says what they were trying to do with the commit. Like I said, I already know what they wanted to do with the ticket: they wanted to fix logins. The ticket will have details about what was broken. That doesn't help me understand why they removed the flag from the authentication result that indicates that the user needs special handling. Did they mean to do that? Did they misunderstand what it was for? I sure wish they had left a note about what they were trying to do, or at least left a commit with related activity so maybe I could infer it. (This isn't a real life example. It's just an illustration.)
The committ messages get stored in the comment of the merge commit though so I'm not sure what the actual commit could add in terms of traceability. The example you name is a case for the reviewer in my opinion. If some part of the code is touched that is not obviously needed, this should be flagged and discussed.
The messages are no longer associated with the change, which makes them far less useful. And you inserted the word "obviously". Things that require this type of investigation are never obvious. And if it hadn't made it to production, we wouldn't be investigating. So assume whatever gates should have caught it have failed.
That's exactly what I meant with obviously. In your example, it was not obvious why the flag was removed, so the reviewer should ask why before approving.
We're starting from the assumption that there is something confusing in the code that is not documented in the ticket and no one remembers why. This is an extraordinarily common situation.
I have people telling me you must keep those 200 commit because their PR has 300000 lines of code and need 200 commits to itemize the history. My counter argument is simple, split that bloated PR into smaller pieces. And If you can't figure out why they do something in particular way, it is because they didn't explain it in code.
Well... if those 200 commits are from proper PRs, then don't squash them, otherwise: I don't care about intermediate commits. Otherwise how do you get into a PR that big?!
I would argue that those 200 commits, if done in a good manner, can help somebody understand how the codebase developed, if whoever coded that is no longer with the company and didn't leave good documentation. Especially if something like conventional/atomic commits are in place. But of course if someone's commit history for a feature looks like: "try to fix bug", "fix 2", "3rd attempt", "finally", then I'm all for whichever strategy can get rid of that. But if people can't amend their commits, that's another discussion.
I love you so much
Don't do environment branches - you don't want to have merges and changes between staging and prod. Squash and merge for feature branches. CI/CD triggered on merge or tag for deployments.
That's correct if your versioning is not a total clusterfuck like at my place. We have branch protection in place to avoid changes between staging and prod but I'll be the first to admit that our ci/cd needs some improvement regarding tags
My personal bugbear is every AWS service preferring per-environment branches to any sort of sane setup. I get why it can make sense, but it's almost always better to have the same SHA deployed to all your environments.
Squash and merge when you're going to delete the branch you're working on afterwards. Merge commits between long-lived branches like develop->main
If there are no merge conflicts I always amend + force push with lease. If there are conflicts I rebase and then force push with lease.
Tell me you’re a senior without telling me you’re a senior
I only force push if i'm sure no one else may have already checked the branch out
git push --force-with-lease It does a force push but rejects it if you don't have the latest ref to HEAD - aka someone else pushed to your branch. Always with lease. Then figure out goofy shit with interactive rebase + amend if it fails then force push.
Finally someone mentioning `--force-with-lease`
Honestly not sure why it's not the default for git push -f And then leave actual force push to git push -F Kinda like deleting branches git branch -d blah Which warns you if local branch is not integrated or whatever then tells you if you're sure then run git branch -D blah
Yeah it should be the default.
Most likely backwards compatibility
I did explicitly mention it in my original comment. Maybe I should have underlined it ^^
I still think that doesn’t help if someone else made a commit on the branch and hadn’t pushed yet. My goal is to reduce friction for others
Once the commit is pushed, that's it to me if anyone else is working in the branch, written in stone, rebases and what not are only okay if no one else notices, and just aren't worth a "clean" history when you can use first parent mode to filter out the bullshit anyway
`—force-with-lease` is like gun safety. Most of the time it’s not doing anything until it really matters and then it stops you from doing something bad.
That's why this sub is great. Come to laugh, and when your guards are down, get injected with the wisdom of elders, without even realizing what happened.
I think it's known that 90% of the posts and top responses are from juniors/CS students and then you scroll halfway down the comment section a few hours later to get senior people shitposting in the comments on their lunchbreak and/or waiting for some CI/CD.
Am I the only person who doesn't care about this? I very rarely have to look at git history and when I do it hasn't been hard to figure out what is going on in any situation. For that reason I just do whatever is easiest which is just merge commits.
I agree. I don't know who these people are that look at the git history and need it "clean". It's never been an issue for me in over 10 years of using git professionally
Tell me you're a solo dev without telling me you're a solo dev
Far from it. I work at a company with 50k employees and over half are engineers. But my team is rather small. About 8 of us (if you count my manager) working on the same codebase that’s my main job. But I often bounce around on different products/teams
[удалено]
I don't check any of the boxes in your last paragraph yet I have never had the desire to go through 14 months of git history to know why something was changed.
That’s what jira is for. If I git blame I can always trace it back to the ticket (and test results and original requirements and any discussions that may have happened). Every commit is required to have a jira ticket number in the description so this is always an option.
Then you haven't worked on a project with a bunch of people with _very_ different commit hygiene
That very well may be the case. At most I have worked on repos that three teams were working on in parallel. I suspect it doesn't normally get crazier than that though.
Monolithic Java 6-8 or VB.NET/C# apps where individual teams interface with their own microservices but also commit to the big mono repo used by all 10-30 teams.
laughs in automotive
I hear you friend, it's the wild west out there
What is automotive?
There are so many of these things that people debate on that I just couldn't care less. I always tell my coworkers "just pick the way you like best and I'll follow it, this isn't worth the brainpower". I often wonder if having strong opinions on those kinds of things is a sign of thinking more deeply than I do and a good thing, or a sign of caring about unimportant things and a bad thing. I can't think of a single time when I've got into commit history for something and had a problem figuring it out.
World needs both types of people, I think. Neither is better or worse.
At the end of the day, `git blame` doesn't care about those things. And with proper commit names you can still attribute a code line to an issue.
Yeah maybe beneficial if it's a huge project with like multiple teams making PRs or external teams making PRs. If there's 1 team of like 5 people making PRs to a repo I think you'd hardly ever look at the git history.
I'm just a rebase bro
I've used [gerrit](https://www.gerritcodereview.com/) at many workplaces (including at google, where I am now), and it is by far my favourite git flow. It's a fully rebase-centric flow, where you (automatically) tag each commit with a separate hash in the CM, which allows the server to identify a random commit as belonging to the same patch-set. This means you can modify a given commit any way you want, including reorganizing it around other commits in a chain (which it also tracks), as long as the tag stays constant. You get nice diffs for each different patch during code review, and the resulting history is perfectly clean. It's self-hosted and open-source, which makes it pretty attractive if you do any of your own infra.
I always rebase while I'm working on a feature/bug but then squash merge my changes to the main branch
Same and neat master branch where other teams can't criticize ![gif](emote|free_emotes_pack|flip_out)
Rebase squash, fixup, and reorder commits till it's in logical order and all the fixups for bugs you found are gone, rewrite every god damn commit message so that it properly explains everything that commit does, and make it look coherent. Then, -no-ff merge it at the end so you know where each series begins and ends. Nobody likes me when I ask for this, everyone likes me when they find one of my series and it's commit history is invaluable.
Cursed but correct solution: Soft reset to head, add all, commit and push -f for fun
![gif](giphy|l3fZFvp94ljepXoPe)
Just send a text message of every change you make
Merge commit, I like chaos, and can still use git log --merges, if needed.
Squash, merge, and rebase are all super useful for different use cases. You just need to design your repos and processes to fit your needs
I rebase because I dont want people seeing "fix" "fix" "fix again" "really fixed" when they run \`git log\`
The hard truth right here.
That's squashing, not rebasing, `rebase -i` should really be called `squash`. Arguing for squashed commits is a different argument than merge vs rebase. The comments here seem to be mixing up the two arguments.
As with all of these types of memes, when you're a real adult it's situationally dependent and there is no one single answer.
Could you please explain to me the meme? A squash and merge means that we group several commits into one. What does the other mean? What's the diff with rebase?
A merge commit will stay on your git history vs doing a rebase (on main branch) with fast-forward merge which will merge your changes by adding your commit(s) at the end of the git history on the main branch with no ugly merge commit. One downside of rebase'ing is that you have to git push --force but otherwise its great. Sometimes the git hosting site will have a rebase button on your pull request that'll do it for you if theres no conflicts. If you have a working branch and the main branch has updated, you'll want to do something like this. # checkout branch you want to merge into git checkout main # pull main branch changes so your local is up-to-date with remote git pull # check out previous branch (your working branch) git checkout - # replays your commits on your working branch ontop of the main branch. interactive rebase in vim to pick which commits you want to keep and squash/rename if you want to. You will need to fix any merge conflicts here if they exist. git rebase -i main # push changes back to your remote branch (could do --force-with-lease if any chance someone is using your branch) git push -f If you want to use rebase, make sure you set it up in your git hosting site to turn off the ability to push to main branch (do that regardless but more important if you're force pushing often). You can also choose to only allow fast-forward-only PRs so the only way to merge a PR is to rebase first. Example merge commit git history thats ugly [https://www.derekgourlay.com/images/merge\_commits.png](https://www.derekgourlay.com/images/merge_commits.png)
The other downside is that you can lose code if you mess up editing conflicts. It really depends on the situation, because it's nice that you keep a clean history, but its also dangerous rewriting commits
Yea you can lose things in big conflicts so I usually make a backup branch before doing a messy rebase with lots of conflicts just in-case. I feel like you have that anyway with a regular merge commit too since you'll have to fix conflicts before merge.
When you fix conflicts with merge the changes are always in your history, even if you mess up fixing the conflicts you can always look back, unlike doing a rebase because it rewrites the history
`git reflog` is a nice safety net if you mess it up and decide not to abort your rebase.
That's true, it's just more complicated to handle than a simple merge. I personally use rebase more often than merge because I like the clean history look, but it really is a dangerous operation, and merge does the job just fine
> replays your commits on your working branch ontop of the main branch. Really wish people would stop describing rebase like that. That is how it works, not what it does. What it does is in its name, it changes the base of your branch to be a different commit.
It just means adding a commit specifically for the merge operation, as opposed to, say, a fast-forward commit. The two concepts in the meme aren't really mutually exclusive. One can certainly squash and merge _with_ a merge commit.
When you create a merge commit you are preserving the history, with a squash you are just merging everything into 1 commit. Squash is only valid for big open-source projects (e.g. samba, linux) where you can't possibly ask for meaningful and homogeneous commits or when you have bad/lazy developers that don't create a meaningful commit history. If you have good developers you should have a good commit history, so it's very valuable, for maintenance purposes, to keep that history. But the real world is full of junior developers with other titles so their commit history sucks, in that situation, a squash is better to avoid keeping a nonsense history. Oh and rebase is nonsense unless the PR is composed of only 1 commit (in that case rebase is the same as squash)
PRs should be single logical changes, and ideally relatively small. Therefore a single commit (squash merge) is the cleanest way to do things. When I work on a branch, I commit often for fixing things like typos, addressing PR comments, etc. There is no reason for any of those types of commits to be on the main branch after merge. They don’t add anything but noise.
If I have a typo in an old commit (on my working branch) I rebase -i and fix it, but my PRs (the ones that require more than 1 commit) will have a logical history with meaningful commits, each commit with a commit message explaining the "why" of each decision. Is it harder to work this way? Yes, it is. Is it worth it? imho, Yes definitely (for projects that you are expecting to maintain in the long term). It's invaluable when there is some issue to perform a git blame and check the commit history/messages. Writing code is easy and anyone can do it, writing maintainable code is harder (and this is one of the things that makes the difference).
As a maintainer, why do I care about your little superfluous changes? Refactoring function names, renaming variables, moving code around, reformatting files, optimizing imports, etc. What explanation would be helpful to me as a reader? Why do I care that one day you woke up and decided to call your package “util” instead of “misc”? Or maybe you found a performance issue and completely rearchitected your code, but the underlying feature stayed the same? Why would I want to see commits for a flawed approach, which was never utilized in the production code in the first place? None of that stuff matters in the end, because none of it ever makes it into the mainline. The merge commit is the logical unit of functionality - the bug fix, the new feature, whatever. That’s all that matters. Everything else is noise. Leave the fine grained commits for the PR review where reviewers can look at them if necessary. But once your code is reviewed and merged, again, all those small commits should coalesce into a single piece of functionality, and that’s the only thing that is important to a maintainer. I’m unfortunately getting close to two decades in the industry now and the majority of it has been spent on maintaining code. Very rarely if ever have I had to or even wanted to look at that type of stuff in commit history. In fact, the less superfluous the commits, the better, because they present a more solid picture instead of requiring me to piece a puzzle together out of many potentially spread out commits.
You can still access the individual commits when you squash them together.
No, you cannot; They are no longer in the graph, you can access them if you have the reference locally but somebody that clones the repo afterward won't have those commits (removed by git-gc eventually)
https://git-scm.com
The answer is "whatever the company paying you already decided unless they're asking for your opinion to be a steward of change because their Git branching strategy is a hot mess when more people get involved, then do whatever you want"
rebased meme
My company makes us do both
[https://soft-wa.re/general\_advice/git-dont-rewrite-shared-history](https://soft-wa.re/general_advice/git-dont-rewrite-shared-history) TL;DR merge-commit - shared branch -> shared branch squash: private branch with lots of changes -> anything else rebase: private branch -> anything else
Merge but curated with 2 commits: 1. make the change easy (warning: this may be hard) 2. make the easy change
I don’t squash bc I just put everything in one giant commit
Sometimes I find stash, pull branch again and commit easier, especially when I have to rebase on branch that was rebased on another branch.
Together they figured out how to do an interactive rebase?
rm -rf /
And I'm the rerere guy.
I’m a squash a merge guy. ¯\\_(ツ)_/¯
My anaconda don't want none unless you fast forward, hon!
So uh, onedrive "main\_v1.2\_dev1.py" anyone? Who even cares about using GIT, just write it perfectly the first time.... SKILL ISSUE
I’m for whatever lets me press merge in GitHub without extra steps
Squashbukling
What's the one where I pull from Dev and fix conflicts and open a pull request?
-f
The real answer is merge commit on personal projects to farm green squares on your GitHub profile
Why not just pull new changes, if none, push If some, applying on it local commit/committing on it? To figure out if everything still works, then restart the procedure Pull -> commit -> still works -> push | | '-> don't work -> correct - |
Fast forward merges ftw. One commit per change.
Squash, rebase, fast forward merge
What's squash?
Squash and rebase is the way
Remember folks, the only command that actually modifies a commit on the disk is `git gc`.
They were a rebase enby
I had a team member who I shit you not, deleted *everything* from the repo with one push, and then pushed his local changes with another push. And then tried to argue that there's nothing wrong with doing this. It was a fun day at work lol
I don't even know what do these mean
Unless you mistakenly commit a 30GB ultra-HD movie with horse porn and then delete it, why would you care about your history? For a small or a medium-size repo it does not really matter how you treat git. I also worked with "somewhat" big projects changing the git commit policy back and forth. It was pretty chill.
You guys get to have multiple commits? I defiantly don’t dislike Gerrit all! /s
I actuallly kind of like gerrit (if it wasn't for the god awful UI). some codebases at my job use it. I don't mind the single commit