18 ms·
Git rebase, what can go wrong
- jawns 3y agoI like how Atlassian puts it: > The golden rule of rebasing > Once you understand what rebasing is, the most important thing to learn is when not to do it. The golden rule of git rebase is to never use it on public branches. https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing https://www.atlassian.com/git/tutorials/merging-vs-rebasing#... For me, even though rebasing comes with some trappings, I still greatly prefer it to the alternative, which is to have merge commits cluttering up the commit history.
- recursive 3y agoSquash merges cut down the noise considerably.
- mablopoule 3y agoI actually hate squash merge because of all the noise it adds. Sure, the commit graph looks nicer, but it come with a terrible loss of information when doing git blame. I'm a big proponent of rebase and squash if it helps to make a commit more coherent, but we use squash merges by default in the current project I'm working on, and I die a little bit each time I try to understand what changes were related to a line when tracking down a bug.
- nerdponx 3y agoThis is the big one for me. destroying Commit information just to keep the graph tidy is a bad idea in my opinion. It would be better if Git provided better tools for filtering the log, e.g. providing some mechanism to elide commits from parents of any merge commit other than the 1st.
- diek 3y ago> destroying Commit information just to keep the graph tidy is a bad idea in my opinion The commit information I see when telling teams to squash their branches on merge is not valuable. * "fixing whitespace" * "incorporate review comments" * "fix broken test" * "fix other broken test" (note, the broken tests were broken by the changes in the PR) As soon as that PR is merged those commits are worthless. And there are branches with dozens of those "fixing X" commits that would otherwise pollute the commit graph.
- lelandfe 3y agoThose commits would be the bathwater one casts out alongside the useful commits in using squash merges.
- diek 3y agoIf the useful commits are the "baby" in your bathwater analogy, all the useful information in those commits is in the squashed commit. This assumes a branch being merged in represents one logical change (a feature/bugfix/etc) that is "right sized" to be represented by one commit.
- mablopoule 3y agoYes, but now it's mixed with the bathwater, and now morph into another metaphor as it become the needle in the haystack. It's okay to have 'low information' commits one can easily ignore in your history, as long as the 'high information' ones stay readable and coherent.
- gray_-_wolf 3y ago> * "fixing whitespace" * "incorporate review comments" * "fix broken test" * "fix other broken test" Things like this should not be standalone commits though, they should be incorporated into the previous branch by amending the original work. It takes some effort to have a useful git history, it does not just happen on its own.
- johnsbrayton 3y agoI do squash merges but keep the feature branches. So after determining that I made a change as part of a big pull request, I can then look at the commit/blame history for the pull request source branch if necessary.
- matijsvzuijlen 3y agoThis means having to keep these branches around cluttering up everything, and makes git bisect a lot more complicated.
- mvdtnz 3y agoI'm guessing you don't work on large projects. This would create an outrageous amount of noise in a busy repository.
- skybrian 3y agoThis all depends on the project. Sometimes you don’t look at history all that much. Sometimes the loss of information is acceptable.
- Izkata 3y agoIf you don't look at history much, why would you care about keeping it "clean"? Just keep the truth of the changes in the history for those of us who do use it, and you can continue ignoring it.
- diek 3y ago> I die a little bit each time I try to understand what changes were related to a line when tracking down a bug A change/feature/bug is a branch, which is squashed into a commit on your main branch, right? So your main branch should be a linear history of changes, one change per commit. How does that impact the ability to git blame?
- joshribakoff 3y agoBecause sometimes a PR touches more code than a single commit, and you lose the more granular context surrounding the more granular changes. You can always ask git to make the log more coarse, but once you “destroy” the granular history it is for all intents and purposes gone.
- js2 3y agoBecause unless it's the most trivial of features, you'll break it up into smaller commits which each explain what they are doing and make reviewing the change easier. As a simple example, I recently needed to update a json document that was a list of objects. I needed to add a new key/value to each object. The document had been hand edited over the years and had never been auto-formatted. My PR ended up being three commits: 1. Reformat the document with jq. Commit title explains it's a simple reformat of the document and that the next commit will add `.git-blame-ignore-revs` so that the history of the document isn't lost in `git blame` view. 2. Add `.git-blame-ignore-revs` with the commit ID of (1). 3. Finally, add the new key/value to each object. The PR then explains that a new key/value has been added, mentions that the document was reformatted through `jq` as part of the work, a recommends that the reviewer step through the commits to ignore the mechanical change made by (1). A followup PR added a pre-commit CI step to keep the document properly linted in the future.
- diek 3y agoIn general I agree with you, there are absolutely times where you want to retain commit history on a particular branch (although I try to keep the source tree from knowing about things like commit IDs). I would argue that those are by far the minority of PRs that I see. As I mentioned in another comment, _most_ PRs that I see have a ton of intermediary commits that are only useful for that branch/PR/review process (fixing tests, whitespace, etc). Generally the advice I give teams is, "squash by default" and then figure out where the exceptions to that rule are. That's mainly because, in my opinion, the downsides of a noisy commit graph filled with "addressing review comments" (or whatever) commits are a much bigger/frequent issue than the benefits you talk about. It really depends on the team.
- WirelessGigabit 3y agoMe too. I care a LOT about provenance. And squash merge completely breaks that. When my branch is up to date with `main` I can build an artifact, fast forward merge that branch into `main` and RETAIN the artifact, and merely update its tags to mark it as `merged` in. With a squash I lose that information. Now, GitHub does not allow me to do a fast-forward merge but I can still trace the 2 commits that are the parent of the resultant merge, and find the artifact based on that, and retag.
- Lio 3y agoGit blame confuses people even without squash merges. I've seen people forget to go back more than one commit and then blame the person who last indented a file instead of going back to the commit that actually wrote the code many times.
- erik_seaberg 3y agoWe shouldn’t tamper with code we don’t actually need to fix, it’s not a good use of time and it makes history less useful. Just because it doesn’t look like I wrote it doesn’t make it wrong.
- Lio 3y agoI’m thinking of situations where the surrounding structure of the code has been changed to correct a problem. That’s done by an automated tool. Correction of indentation is just a byproduct. I don’t consider that “tampering”.
- deleted 3y ago[deleted]
- WorldMaker 3y agoYou can deal with that through tooling. In a lot of my work I call those types of automated tool commits "wrench" commits personally and even have a simple shell script to help automate committing them. In my case I prefix the command line with a wrench emoji. At that point it's very obvious in git blame that if a line starts with a wrench it was last touched by an automated tool of some sort. You can also very easily at that point grep your git log for wrenches to dump commit hashes into a git-ignore-revs file and automate that part too so that those commits don't even show up in git blame at all.
- sodapopcan 3y ago> I've seen people forget to go back more than one commit and then blame the person who last indented a file instead of going back to the commit that actually wrote the code many times. I default my `git blame` to `git blame -w` which ignores whitespace commits. Though knowing how to jump back commits should be required knowledge.
- paulddraper 3y agoSquash merges are rebases.
- recursive 3y agoJust when I thought I was starting to understand git...
- Izkata 3y agoRebase essentially means "create new commits out of old commits", the original use being to "move" a set of commits from one branch to another (think of the name as meaning, to change the base these commits started from). There's a few special cases that have their own names, a common one is when you amend a commit - to do that manually you'd make a new commit, then use interactive rebase to squash the two commits together into a new one (or, use the "fixup" command available in that tool, which is a squash that automatically picks the first commit message instead of asking for a new one). Squash merges will squash a whole branch into a single commit, rebasing it onto the target in the process, and then fast-forward the target to the new commit. It's a tightly controlled use of rebase, and can be thought of a bit like how "for", "foreach", and "while" loops are a tightly controlled use of "goto", an abstraction built on top of a far more flexible tool.
- ksenzee 3y agoOnly metaphorically, maybe. You can squash merge in lots of cases where a rebase will fail.
- Izkata 3y agoThey are essentially rebase+squash, despite the name. There is no actual merge taking place. And for that matter, you'd manually do a squash with the interactive rebase tool anyway ("git rebase -i").
- ksenzee 3y agoImagine a feature branch where someone has been keeping it up to date by merging main into it regularly. Now the feature is ready to go into main. You can easily `git merge --squash` that branch into main. You can likely do the same thing manually (as you point out) by running `git rebase -i` if you squash all the commits in the branch. But you’ll never manage to do a genuine rebase, where every commit in the branch gets turned into a clean non-merge commit onto main.
- deleted 3y ago[deleted]
- dahart 3y agoWhat I think I see these days is squash merges being used lazily to avoid having to do anything to build a clean history with clearly semantically delineated commits. Squash merges are good compared to an alternative where people check in super messy noisy branches, but they unfortunately have a big downside because squash merges can make bisecting and history spelunking more difficult, when the branches that are squash merged were big.
- sidlls 3y agoWhat is a "semantically delineated commit"? What is a "clean history"? Why are these two things important?
- FeepingCreature 3y agoNot parent: there are technical commits, such as "fix review", "fix jenkins", "fix typo" etc. Those don't delineate a particular feature but a fix for a problem that arose from the workflow. This ends up with a history of "big feature commit that is wrong in three trivial ways" + "fix 1" + "fix 2" + "fix 3". Of those, "big feature commit" is the important one, but "fix 3" is the only working one. This is clearly silly; you should pretend you were perfect from the start and squash "fix 1" through "fix 3" into "big feature commit". Your typos and brainfarts are not of historical relevance.
- sidlls 3y agoPerhaps I'm missing something, but I don't see how your comment answers my questions. Do you mean that a "clean history" is one without "fix 1", "fix 2" and "fix 3"? Or is that a "semantically delineated commit"?
- ruds 3y agoA clean history is one where there is a single commit, "big feature commit", that produces a worktree that is the same as the one produced by "fix 3" in the "unclean" history.
- dkarl 3y agoI think squash merges are a last resort heavy-handed tool for dealing with developers who refuse to clean up their commit history before merging. Most developers can do better by hand. Git history should tell a simple, understandable story of each change. For example: 1) refactor existing code, 2) add feature. Or 1) add missing tests, 2) refactor existing code, 3) add feature. But since you're working on the fly with imperfect knowledge, it doesn't happen in such neat steps. Refactorings and behavior changes end up interleaved in your raw git history, so you need to do a little bit of cleanup by hand in order to present a simple story in the commit log. Of course if you have developers that don't do that and instead merge dozens of commits that just say wip, wip, wip, lol, fml, wip, wip, lol, yolo and you can't fire them or get them to change, then squash merges ftw.
- bogeholm 3y agoI ser it the other way around - why spend time on a ‘nice’ commit history in a (smallish) feature branch when you can squash merge later. I prefer one commit to main per feature, a long with a good description on the GitHub PR. Sometimes I’ll branch out from a feature branch for the occasional and infamous ‘get CI working’ round of 10 one-line commits though, to not make it too muddy.
- ufo 3y agoPrecisely, you want to keep it about one commit per feature. I think the parent comment was worried about monster merges that squash many features together.
- marcandre 3y agoThe classic example where this fails is when needing to revert something. An atomic commit for the migrations + some atomic commits for the implementation mean you can easily revert the implementation, and leave the migration intact (as should be) and add a reverse migration.
- gwright 3y ago> why spend time on a ‘nice’ commit history in a (smallish) feature branch when you can squash merge later. Several reasons: * facilitates much better code review discussions * enables use of git bisect to locate bugs * allows for informative commit messages associated with the changes * communicates clearly to future self about why changes were made
- jawns 3y agoMy rule of thumb for commits is that they should be of a size and scope suitable for cherry-picking. So, maybe I'm working on a small feature that entails three changes, and each of those three changes is useful in and of itself and could conceivably be cherry-picked by others. I would create three separate commits, generate a PR with all three, and merge in the work. Sure, I could squash merge and end up with one merge commit encompassing all three changes, but now none of those three changes is cherry-pickable.
- sodapopcan 3y agoNo one is mentioning: $ git log --merges Now you can see your features in a nice history and also have added benefit of seeing intermediary commits. Pro tip: merge commits aren't required to use the canned "Merge branch into..." message, you can give it any message you want, such as "feat: ..." or whatever your convention is. I hate that branch squashing has become something of a defacto. I actually do rewrite my history and often add context to my commits. `git blame` can be an incredibly useful tool to get context about a given small change. Getting a massive diff for a whole feature is much less so, especially since you can just look at the diff of the merge commit.
- Lio 3y ago> Squash merges cut down the noise considerably. They do but they have their own issues. e.g. having to delete local branches using git branch -D instead of git branch -d and getting the protection from deleting unmerged work. I still agree that on balance annoyances like that might still be worth putting up with for larger teams with mixed skill levels.
- mcv 3y agoThey also cut down the signal.
- richbell 3y ago> I still greatly prefer it to the alternative, which is to have merge commits cluttering up the commit history. GitHub recently added a feature that prompts people to update their branches via merge. It's frustrating because every PR now had dozens of merge commits polluting the history.
- spankalee 3y agoA PR with merges is fine by me, it lets me see how the PR has evolved. What I want is for GitHub to track changes between sets of commits in a PR so that you can do most of the review with merges and "address review comments" commits, and then rebase into well organized, logical commits and review that those have the same diff as the messy history after a force push.
- adhesive_wombat 3y agoAt least Gitlab does that when you push a new commit (force or not) to the branch: it'll show a list of value of the branch head commit and you can diff between them.
- smw 3y agoSo does Github, but it breaks if you fix via rebase and push -f. Gerrit and some other competitors manage this better.
- richbell 3y agoThe problem is PRs that have <5 lines of changes followed by dozens of pointless merges, because users are prompted to merge every time another PR is merged. It wouldn't be a problem if people took the time to organize the history prior to merging as you said, but most people don't do this.
- deleted 3y ago[deleted]
- pjc50 3y agoSome people have pull set to merge, which is a "I don't know how you can live like that" feature.
- ohwellhere 3y agoThe way I phrase and teach what I consider to be the important rule of git is: > Don't rewrite history on shared branches with proper communication. I don't teach "never", I don't teach that `main` is special, I don't teach that force pushing is forbidden, because I don't believe in those things. I highly prefer a rebase-heavy workflow. In addition to not "cluttering" the history, it's an invaluable tool to keep commits focused on "the right level" of atomic changes.
- jakelazaroff 3y agoI assume that “with” is meant to be “without”?
- joshribakoff 3y agoYou can simply pass flags to “git log” to hide merge commits, without needing to rewrite history to “destroy” that information. While they are often noisy, sometimes they can be useful. I usually prefer to hide information rather than destroy it.
- unlikelytomato 3y agoI read this justification in nearly every thread that pops up git rebase. I feel like a full because I cannot think of a real world example when this information crosses from signal to noise. Generally, branches that are not ready to merge tend to have enormous amounts of noise commits. Is there a blog post or some concrete examples I could work through that illustrate these benefits? I feel like workflows dramatically different from mine are likely the source of my struggle.
- fulafel 3y agoIt's a log of what happened in dev and supports reconstructing history to understand why something worked or didn't in retrospect. "It work when we tried it" "oh this dependency was updated in this merge commit that could have changed the behaviour"
- throw555chip 3y ago> For me, even though rebasing comes with some trappings, I still greatly prefer it to the alternative, which is to have merge commits cluttering up the commit history. The purpose of history is to remember. Rewriting history, whether git or in life, is bad; outside of the context of don't use it on public repos. Such advice is similar to saying, only point the shotgun away from you when firing. If you have to remember such a rule, it's best to avoid it.
- 0x6c6f6c 3y agoBut in unmerged branches, you aren't rewriting history, you're starting your work on a more recent commit in history.
- ozim 3y agoShush, don’t say those things because maybe people discussing merge vs rebase will realize they don’t discuss but just talk side by side. One and the other does not care what is the context and what they discuss but apparently each one just knows better. I also don’t mean those specific users - but in general any git discussion I saw for last 10+ years.
- oehpr 3y agoA history you can't understand is a history you can't remember.
- leptons 3y agoI don't mind merge commits, it's the 100 tiny individual commits some developers seem to like to do that really clutters things up. Yes, I know, git squash is a thing, but not committing until the feature is working and ready to commit is also a thing.
- lolinder 3y ago> not committing until the feature is working and ready to commit is also a thing That leaves you prone to losing work if you have a false start that you need to back out of. I prefer to commit early and often on my private branches, then before submitting a pull request I clean up the history to where there are a few good commits that form useful, standalone chunks (ideally the test suite fully passes on each commit).
- leptons 3y ago>That leaves you prone to losing work if you have a false start that you need to back out of. Hasn't happened to me in over 20 years of using version control. I always keep moving forward, there's really never been a need to go back to a previous commit that hitting crtl-Z wouldn't accomplish just the same. If I wanted to try a new direction I'd just clone the repo again and do the work there. Littering the git history with dozens of superfluous commits just seems pointless. Having to stop and think about writing a commit comment is also just a waste of time - in aggregate it wastes a lot of time. It adds a lot of churn to a workflow for something that may never really be of any value.
- lolinder 3y ago> Littering the git history with dozens of superfluous commits just seems pointless. This is where the final rebase comes in—you should be combining all the small commits into one. > Having to stop and think about writing a commit comment is also just a waste of time Most of my commits when I'm working like this are named "draft". The names don't matter when you're going to redo the history later. > I always keep moving forward, there's really never been a need to go back to a previous commit that hitting crtl-Z wouldn't accomplish just the same. You've never started down one path for solving a subproblem only to realize 30 minutes in that it's not going to work?
- sakarisson 3y ago> I still greatly prefer it to the alternative, which is to have merge commits cluttering up the commit history. I've heard this many times before, but haven't been able to figure out why this is a problem. In your workflow is it a problem to have a cluttered commit history? If so, could you explain how?
- h1fra 3y agoI might be lucky but in my whole developer life I have only used like 3 commands git stash, git pull --rebase and git merge. I'm not even sure I used git rebase once.
- lycos 3y agowhat do you think git pull --rebase does..
- saagarjha 3y agoMagic hocus pocus. What else?
- never_inline 3y agoI think the most cited drawback of rebase - public branch refs becoming obsolete - is not applicable when you only use it to pull from a canonical remote.
- h1fra 3y agowell it rebase but I never had to deal with everything in this article. It put my commits on top of HEAD and that's it, never had any issue.
- paulddraper 3y agoWell there are lots of useful commands out there you might want to try git branch git checkout git clone git diff git push
- gorjusborg 3y agoSure, there are situations when you can get by without rebase. I would even say 'stay away from rebase if you do not have a solid understanding of what it does'. However, life is much better with rebase than without it.
- ajkjk 3y agoI love rebase (I'm a tip-of-master-only person, no merges ever, squash all your commits with `rebase -i` before pushing and write one good commit message for the group). But there's one really, really irritating thing about them: You should not be able to use `--amend` during a rebase. For me editing all my changes onto the commit I'm working on with `git commit -a --amend` (or as I've aliased it, `gcaa`) is automatic; I do it 500 times a day, just to save my work. But I can't count how many times I've been in the middle of squashing commits and accidentally typed `gcaa` and amended someone else's commit after fixing a merge conflict, and it's super annoying to unwind (if you realize after typing `rebase --continue`) so usually I end up just giving up and starting over. I really wish amending to a commit that wasn't one of the ones you're rebasing was just totally disabled. I guess there are some other small complaints, like the annoying reversing of `--ours` and `--theirs` from what makes sense (yes, it makes sense if you have the internal model of rebase instead of the intuitive one, but that's stupid), rebase's tendency to pick the wrong parent commit if you've accidentally amended someone else's commit (and therefore lag a while and then produce a rebase log of 1000 commits or something), and the utter tedium of editing the rebase log to replace every instance of "pick" with "s" for squash except the first, since almost 100% of the time what I want to do is squash everything (and use the last commit message, not the first, and definitely not all of them munged together which is the default). I would love a separate command or a flag, like "git rebase --tip" that does all of this automatically for my otherwise extremely elegant workflow (and I'm gonna be really bummed if it turns out it exists and I didn't know about it for the last 5 years...).
- davedx 3y agoI’ve never understood the tradeoff of rebasing, squashing or otherwise “keeping a clean history”. It always seemed like tons of sometimes highly error prone work (sometimes you can wipe out a colleague’s work with it! Wtf!), for almost no gain (why does it matter that the git history is “clean”?).
- ajkjk 3y agoNever understood why you wouldn't want it clean. There's no benefit whatsoever to it being messy and it's a liability for a lot of reasons, whereas the clean version is free and easy and makes everything you do that interacts with git history simpler.
- haakonhr 3y agoIs it free though? I'm a fan of rebase myself, but understand the point made above. For me, the biggest pro of a clean history is when doing `git blame`. If the history is clean and the commits are good, it might solve my issue. On the other hand, if the commit in question is a huge mess of unrelated things it doesn't help me at all. I also find it way easier to review a PR with a clean, well-described history.
- ajkjk 3y agoWell I also object to multiple unrelated changes in the same commit. Those should be separate commits, and separate code reviews for that matter.
- rbehrends 3y agoYou can have it clean without rebasing. This is simply a matter of properly visualizing the history. Unfortunately, most of the major version control systems have decided to basically just dump a raw graph rather than presenting the history in a more user-friendly fashion.
- btilly 3y agoThere is a giant benefit to it being messy. And that is that the mess is the actual history. Every time you do a git rebase, you are literally asking your source control system to lie about history. If you mess up, and you eventually will, you're then forced to manually figure out what the history really was despite being lied to. If you mess it up, well, good luck. I used to work at a company where someone (we never figured out who) in another group would rebase every few weeks. We didn't find out about it until their stuff was pushed then released. The result was that features which we'd written, QAed, and released to production would simply disappear a few weeks later. With no history suggesting that it ever existed. Have you ever been pulled off of a project to go fix a project from a month ago which has disappeared from source control? You don't know what happened, you no longer have context, you've just got complaints because your stuff no longer works. Is your desire for a "clean history" worth potentially creating THAT disaster for other developers on your team???
- phoe-krk 3y ago* Regarding "splitting commits in an interactive rebase is hard" - I actually use `git reset` (to unmake a commit) followed by several instances of `git add -i` (to add individual changes into a commit) + `git commit` (to actually make the commits). If the commits to be split are in a middle of something, it's possible to do all of this inside a `git rebase -i`... ...which is exactly what is suggested in the section linked in the article, https://github.com/kimgr/git-rewrite-guide#split-a-commit https://github.com/kimgr/git-rewrite-guide#split-a-commit. * Regarding "weird interactions with merge commits" - `git rebase --rebase-merges` tends to help most of the time, since, during a rebase, merge commits are skipped by default (even if they contain changes).
- m3kw9 3y agoGit rebase is stupid, I’ve seen countless f ups because someone needed the git history to look good
- jzm2k 3y agogit-rebase is stupid because somebody doesn't know how to use it? I use it all the time and I really like how I can make garbage commits (wip, test) and then squash them into atomic commits which are easy to review and later on easy to bisect when inevitably mistakes happen. Sure I've fucked up too when I was learning on how to use it and those were some painful mistakes but only through using it and making those mistakes have I learned to use the tool to great advantage (clean history).
- gorjusborg 3y agoThe trouble with git rebase is that it can create havoc by those who don't understand what it is doing conceptually, and (probably more importantly) how to recover when things go wrong. When I hear people griping about rebase, I assume that nobody took the time to teach them how to use reflog first. Once I had an understanding of reflog, I could mess up all I wanted (without pushing) and recover. In that environment, rebase can become a very useful tool. Without being able to recover, rebase becomes a tool of confusing irreversible destruction.
- naasking 3y ago> git-rebase is stupid because somebody doesn't know how to use it? The whole purpose of source control is to reliably track code changes so you don't lose anything and can revert to any point or recover from bad merges. Since rebase permits you to violate this core purpose and literally lose the entire history of code changes, then yes, it is stupid.
- smw 3y agoIt doesn't. Reflog still exists.
- 3y ago
- lgeorget 3y agoA semi-relevant tip, instead of "HEAD^^^^^^", you can write "HEAD~6" to the same effect.
- sdfghswe 3y agoJust don't rebase something that you've shared with others. It's just rude.
- dewey 3y agoDo people not collaborate on feature branches?
- sdfghswe 3y agoDon't rebase ESPECIALLY stuff that people are collaborating on.
- dewey 3y agoWell aware of that, but in my experience I sometimes collaborate on feature branches with 1-2 people and we just communicate when there's a rebase happening (For example if there was a bigger change in main and we want to align our feature branch on it). I don't think that's very uncommon.
- lacrosse_tannin 3y agoPull requests after comments and revision?
- ender341341 3y agoDoing a squish merge on the actual merge, at least on github doing a rebase mid-pr makes the PR act funny (comments point at non-existent revisions and such). When I was at amazon their internal PR tool handled them just fine so I would do them in that case. There's more nuance to the OPs comment along the lines of > Don't rebase on branches others are working on On a pr branch I usually at most expect others to pull and do a build to run it locally so I'm not very worried about wiping out changes.
- Bukhmanizer 3y agoThis is nice to read because I’ve been recommended rebase by so many people who clearly have no idea what it does and what to do if it goes wrong.
- hoelter 3y agoI've found that consistently using the --onto flag when rebasing helps prevent errors by ensuring the target hash of the rebase is always explicitly specified. Particularly in situations where you may have a feature branch based on another feature branch, and that other feature branch had commits squashed into main so history/commit hashes have changed between main and your feature branch.
- otteromkram 3y agoNever have rebased. Get some updates, then merge master branch. Seems to be pretty straightforward to me. git fetch -p --all git pull git merge master (Handle merge conflicts in WE of choice.) git push Boom. I'll let the CI platform squash commits post-merge. Option for gitlab if it's a small change and you don't want to run a full suite of tests. git push -o ci.skip
- mbakke 3y agogit rerere only "automates" conflict solving after you already solved it. As in, it remembers previous merge resolutions, even if you undo the merge/rebase. It is particularly useful when doing difficult merges regularly. Invariably I'll find a mistake in the merge and start over (before pushing, obviously); the second "git merge" remembers the previous resolutions so I don't have to solve all the same conflicts again. Similar for difficult rebases that may need multiple attempts. Git remembers resolutions across branches and commits, so in the rare case where (say) a conflict was solved during a cherry-pick, rerere will automatically apply the same resolution for a merge with the same conflict. I think the reason it's not on by default is that the UI is confusing: when rerere solves for you, git still says there is a conflict in the file and you have to "git add" them manually. There is no way of seeing the resolutions, or even the original conflicts, and no hint that rerere fixed it for you. You just get a bunch of files with purported conflicts, yet no ==== markers. Have fun with that one if you forget that rerere was enabled.
- PaulDavisThe1st 3y ago> when rerere solves for you, git still says there is a conflict in the file and you have to "git add" them manually. been using rerere for years, never seen this behavior.
- anon23432343 3y agogit rebase is overrated... change my mind!
- deleted 3y ago[deleted]
- heisenberg302 3y agoI prefer rebase over merge because when merging since the commits are added to HEAD, when I add new commits after merge, I find it harder to understand what is being added with the current pull request. One thing that annoys people when rebasing is, if you need to rebase a couple of times and also you change the commit history of current branch, you might end up solving the same "conflicts". To avoid this, you can use git rerere, this basically saves your conflict resolution, and if the same conflict is encountered, it resolves it automatically: https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-rerere.html https://mirrors.edge.kernel.org/pub/software/scm/git/docs/gi...
- brunooliv 3y agoHaven't read the article yet. Whenever I'm working on a feature branch, I always tend to "merge master into the feature branch". The effect of this obviously being that I want to have the latest changes incorporated into my work to avoid conflicts and/or to proceed with my own feature work. This has always worked well for me and never failed me. If I understand what rebase does correctly, it just adds all my commits in my remote feature branch to the HEAD of the branch that's being rebased onto. That's why after doing it and finishing it, one needs to do a push force because the head of the remote feature branch would diverge. But... Why? How is this better or different than just merging master into the branch? Gitlab for example and Intellij show all the branch changes and commits with their hashes so it all can be cherry picked or reverted if needed quite easily... Has anybody who used to "merge master into" and now uses rebase that has a much different view on it being better?
- jihadjihad 3y agoSome people don't like having standalone merge commits that show up in the git history when merging master into feature
- nomel 3y agoWhy? Is it a visual thing, or practical?
- rhinoceraptor 3y agoThis is a simple example with only two feature branches, and it's already a bit hard to follow. Imagine it with even twelve which is not even that many branches: * Merge Branch 'B' into 'main' |\ * \ Merge Branch 'A' into 'main' |\ \ | | | | | * B Commit 2 | | * Merge remote-tracking branch 'upstream/main' | * | A commit 2 | * | Merge remote-tracking branch 'upstream/main' | | * B commit 1 | |/ | * A commit 1 |/ * Compared to a commit graph where feature branches are rebased to replay their commits against the tip of main before merging: * Merge branch 'B' into 'main' |\ | * B commit 2 | * B commit 1 |/ * Merge branch 'A' into 'main' |\ | * A commit 2 | * A commit 1 |/ *
- dataflow 3y agoSince everyone is bringing up squashing... There's a false dichotomy nobody addresses here, which is the notion that there needs to be such a thing as "the" history for you to get the benefits of a clean history. If all you really want is a linear history, then just do merges, and make sure the "first parent" is the main branch (which you can enforce with tooling). Now you can just traverse solely the (linear!) sequence of first parents, which is exactly the same view squashing would have given you, except without the information loss. If for some reason you can't stand the idea of something branching off your main branch at all, then set up a separate job that automatically squashes everything onto a branch that only it can write to (or branch from). Now you have a truly linear history with nothing branching off it, exactly as you would've had with squashing. And you can always reproduce it on demand. That way you avoid the information loss, and can always do archeology on the full evolution graph if needed.
- phinullfermata 3y agoUising squash merges has reduced my need to rebase a lot. I don't really care if I have merge commits on a feature branch for a PR if there's a reasonable history on the main branch when I'm troubleshooting an issue with git blame. Why squash merges? I have a number of team-mates who make local commits on feature branches that make the history look like a series of less-than-useful commit messages. E.g. wip, wip, wip, wip, make it work, wip, wip. All of the context for the change is actually on the PR, so it's really only helpful to see the PR message and have a link to the PR for the discussion on the change.
- mvdtnz 3y agoSquash merges are rebases.
- phinullfermata 3y agoMaybe under the hood, but it's an option on github if you use that, or you can run `git merge --squash` as well.
- gus_massa 3y ago> undoing a rebase is hard I do a lot of rebases, but they are trivial rebases in a feature branch, like changing the order of new features and fixups, and then squashing the fixups to make a nice PR. Don't try to do smart weird rebases!!! From time to time I have to make a smart weird rebase because my small commits order is just a mess, or I have to split a commit or something unusual. The important first step is to make a new brach as a backup to hold the version before the rebase. If I mess the rebase process I can just go back to my version before the rebase and start again.
- ender341341 3y ago> Don't try to do smart weird rebases!!! If I need to do a non-trivial rebase I always start by creating a backup branch so I can delete my fuck up and start over trivially, which was a hard learned lesson.
- heisenberg302 3y agoalso you can use git rerere if you need multiple goes for the rebase, it saves your conflict resolutions and applies them automatically when they occur again(you need to resolve the conflict when it happens for the first time).
- punkbit 3y agoI like to look at my repository and find a clear history, the projects story. Communication is extremely important for me, thus I use rebase wisely and squash before merging (fast forward) to develop and main. Conflicts are solved under feat/chore commit and never in develop or main. A repository shouldn't be a dump of unmeaningful commit messages, but a curation of best contributions at the time of commitment.
- AndrewDucker 3y agoI find it fascinating that people talk about "Having a history of what people did" in such emotive terms - "Cluttering", "Polluting". What matters is that you end up with working systems. That a lot of change happened is just, well, what happened. It doesn't need to be prettied up and made to look like your development occurred in a clockwork march of cleanliness. It literally does not matter unless you spend a lot of time doing git-bisect. Let it go. Accept that coding is not a smooth, robotic, endeavour, where everything is always tidy. And that's just fine.
- anonyme-honteux 3y agoIt’s ego
- __MatrixMan__ 3y agoWhat's worse, the desire for cleanliness ends up making things like `git bisect` less useful. If I had a bad day and introduced something stupid, I want a bisect to point me a the code I wrote on that bad day. If you squash liberally, perhaps because you want each commit to correspond with a release-note, you're going to lose that debugging granulariry.
- FeepingCreature 3y ago> What matters is that you end up with working systems. That a lot of change happened is just, well, what happened. It doesn't need to be prettied up and made to look like your development occurred in a clockwork march of cleanliness. It literally does not matter unless you spend a lot of time doing git-bisect. And git blame. And git checkout to a past state. It "doesn't matter" only if ease of understanding your project history doesn't matter.
- jjeaff 3y agohow often is "understanding your project history" something that actually comes up for you? In all my years of working with projects in git, I will occasionally look at my history to help me find a change that may have led to a bug, but it really only comes up for me once or twice a year and even then, it is rarely an extensive deep dive and never very far back in time.
- ravenstine 3y ago> force pushing makes code reviews harder On any code base I've worked on that's larger than a small FOSS project, I've found that this simply isn't avoidable. Yes, there's merge commits but, for reasons I won't go into, I think those are worse than the alternative of rebasing and making code reviews difficult. > One way to avoid this is to push new commits addressing the review comments, and then after the PR is approved do a rebase to reorganize everything. Not realistic when working on a code base where PRs are being squash-merged every hour and the code review lasts for days. The best middle-ground is to avoid rebasing until the current wave of feedback has been resolved, even if no one has actually approved yet.
- FeepingCreature 3y ago> Not realistic when working on a code base where PRs are being squash-merged every hour and the code review lasts for days. But if they collide, you have to resolve all the merge conflicts anyway, and then with rerere you should have relatively little additional work on the final rebase.
- timost 3y agoIMHO `--fixup` commits and `--autosquash` rebases make rebase much easier.
- nineplay 3y agoI lost patience with the various git commit cleanup tools and now I just go nuclear. I use git diff > output.file, make a new branch, get apply output.file. Fresh clean branch, no commit history, create pull request. I'm not convinced there's any value to incremental commit messages. This simple, clean, and undoable as long as I keep my initial branch
- diek 3y agoWhat you're describing is just doing a 'squash' merge
- jwmoz 3y agoNice to see no one agrees on how to use git correctly.
- davidrupp 3y agoAs far as I can tell, all of these are problems with deferring integration, not rebase per se. I prefer trunk-based development, partly because of all of this: https://trunkbaseddevelopment.com https://trunkbaseddevelopment.com
- evgpbfhnr 3y agoFWIW running `git commit` after a fixing a conflict during rebase is fine. git'll pick up the "in progress" commit's message by default so you'll get the exact same message editor as you would have with rebase --continue; and you can just run git rebase --continue afterwards to continue. If that was during an 'edit' phase and not a conflict, then you get a blank state, but you need to commit any change there anyway before applying the other patches so commit s also the right thing to do... If you had intended to amend instead of a new commit then you can just squash the commit again later, or reset (soft!) HEAD^ to undo the commit and add again/amend.
- lifeisstillgood 3y agoDo I have the wrong mental model of rebase? You want to "pretend" you all took turns at making the code better, like Alice goes first then everyone downs tools while Alice makes her chnages and then Bob picks up Alices work and does his changes, then Charlie starts The difference is that Bob can start while Alice is working and all he needs to do is right before checking his stuff in, he grabs her fixes from master, and then applies his fixes on top of hers as if he had started after she had finished. Sometimes they both worked on the same code and he needs to figure out what's safe but hey that happens any which way. As long as you ensure fast-forward merging onto master only it's kind of simple. Annoying. but simples.
- alkonaut 3y agoIf I were to write a blog post on this I’d make a few do’s and don’ts (why make a blog post when you can blog in HN comments?) Don’t merge the base branch into a feature branch. Rebase to “update”. Do use rerere and the curse of fixing the same conflict over and over is (almost) gone. Don’t rebase (or force push for other reasons) a shared branch. Rule of thumb here is you can probably rewrite history if you work with _one_ coworker in a branch but any more than that and you’re more likely than not to upset someone. Do rebase -I HEAD~N to reorder/reword/squash into easily reviewable sequences of commits. Don’t force push after review, until the review is complete. This keeps the history of the review process but you can later merge the fixups with the commits they logically belong in right before merging. Do use Merge, Squash and “Rebase+FF” as appropriate for merging PR. There is no best solution for every scenario so prescribing “always merge” or “never merge” or similar isn’t helpful. A good rule of thumb though is that IF a branch has merged from the parent branch to update (which I suggested was a “don’t”) then avoid merging it back. A branch that was updated that way is better to e.g squash when merging back.
- sethammons 3y ago> Don’t force push after review, until the review is complete. This keeps the history of the review process but you can later merge the fixups with the commits they logically belong in right before merging. I've had to talk to soooo many developers about this. I want to see what changed since my last review, not restart my review.
- bentley 3y agoWhen I force push to a branch on GitLab with an open merge request, GitLab retains the previous set of commits, and provides an interface within the merge request to compare the current set of commits to previous sets. I love this feature.
- haradion 3y ago`git range-diff` can be handy for the reviewer when trying to "recover from" a mid-review force-push.
- mattbillenstein 3y agoThere are just too many things you have to know about which commits are what and what's going on - especially with a larger team - it's not a good use of time imho to be fixing rebases when they go wrong. Like the big list of dos and don'ts at the end of this should be a red flag. Better alternative I've found is squash merge - topic/feature branches are squashed as a single commit instead of bringing down each individual commit or creating a merge commit. You're history is cleaner, you're able to revert stuff easily, and it's really hard to mess up since it's just an atomic last step you do in your workflow.
- js2 3y agoThe trick to using `rerere` with `rebase` is to merge first, resolve the conflict, record the resolution, then go back and do the rebase. It's explained here: https://www.git-scm.com/book/en/v2/Git-Tools-Rerere https://www.git-scm.com/book/en/v2/Git-Tools-Rerere It's often easier to resolve a conflict during a merge than during a rebase because it presents you with left, right, and the common ancestor. You're also only looking at the tips of each branch. With rebasing, you're replaying each commit one on top of the next so you lose the common ancestor information and you may also have conflicts that won't exist at the end. Another tip: if the other branch has changed a lot since you last rebased, even a single merge may have a lot more conflicts than you want to deal with all at once. In this case, consider a series of intermediate merges since you're going to throw them all away anyway.
- WorldMaker 3y agoIt's all fun and games until someone's rerere cache is spitting out spurious bug regressions that make little sense.
- gabeio 3y agogit --force needs to just be an alias of force-with-lease by default. having the default be the unsafer option seems... backwards. It should be something more like: git --force (acts like git --force-with-lease does now) git --force-anyway (acts like --force does now, "anyway" is just an example and should be harder/longer than -f/--force) I understand that force-with-lease didn't exist first but this needs to be rectified.
- awkward 3y agoI've largely come to a workflow of creating a feature branch and periodically merging main out to that branch. When it's done, I use the github squash and merge feature to bring changes back in. Cutting non-ancestor rebases out of my workflow has been great for my personal sanity.
- phendrenad2 3y agoI'm jealous of people who enjoy rebasing. Such a simple life they must lead. When I'm tasked with rebasing a feature branch with 1,000 commits, written by 10 different people, onto a new release branch with another 1,000 new unrelated commits, written by 10 different people, I really start to question my life choices.
- gitaarik 3y agoThe linked article actually has a section "rebasing a lot of commits is hard" and it's conclusion is to rather not do it, mostly regarding what is mentioned above that section. But if you know how to use rerere properly, like some of the commenters here have pointed out, it could very well make your life a lot easier if you really want to rebase so many commits. And btw, make sure nobody is working on any of these branches or forks of those branches anymore, because after the rebase they won't be able to merge anymore.
- phendrenad2 3y agoUnfortunately rerere only solves the tedium of this task. I'm much more annoyed by cases like this: Person1 modifies line of code A (commit 1). In the other branch, Person2 modifies that line (commit 2). Then, Person2 notices that the first person has made a change, and takes that into account by rewriting their own change (commit 3). When you try to rebase these two branches, you might have to resolve a conflict between Commits 1 and 2, which is pointless work because those were never intended to coexist.
- gitaarik 3y agoDoesn't what this comment says solve this for you? https://news.ycombinator.com/item?id=38166928 https://news.ycombinator.com/item?id=38166928
- Lio 3y ago> fixing the same conflict repeatedly is annoying This is usually caused by merging an upstream branch (e.g. develop) into your feature branch and then later trying rebase it. Effectively the commits you've merged in from develop undo the changes you've made in your feature branch. You fix them but the foreign commits undo the changes again. The solution is actually pretty easy. Use git rebase --interactive to remove any commits from the rebase that aren't directly part of the feature work. You may still have an odd merge conflict to fix but you'll only have to do it the once and everything should go smoothly. I would also recommend never using the same commit message twice. When you have a list of 10 commits all called "Wip" it's hard to tell which are obviously duplicates that can be deleted.
- PaulDavisThe1st 3y ago> The solution is actually pretty easy. git rerere is the even easier solution.
- Lio 3y agoI don't know, you still end up with a dirty branch full of commits you didn't write.
- PaulDavisThe1st 3y agoI was talking about a solution to the problem you quoted: > fixing the same conflict repeatedly is annoying
- WorldMaker 3y agoI've had to force people to clear their git rerere caches as debugging the situation when that cache is FUBAR is gross.
- deleted 3y ago[deleted]
- Am4TIfIsER0ppos 3y ago> HEAD^^^^^^^ Dude! Learn the tilde notation
- heisenberg302 3y agoResponses would make more sense if people included: - if they have done any cherry-picking - if they have done any backporting - if they have reverted any commit that made it to main - if they have ever used bi-sect I think rebase is harder to learn than merge, but once you get used to it, it lets you have history that is easier to debug, and use without extra effort
- pjungwir 3y agoI hope Julia keeps writing about git, because I'm sure it will teach me something! I'm still searching for a way to manage long-lived Postgres submissions, the most challenging git scenario I've encountered. Julia's post finally got me to brain-dump my current process, something I've meant to write down for a while now: https://illuminatedcomputing.com/posts/2023/11/git-for-postgres-hacking/ https://illuminatedcomputing.com/posts/2023/11/git-for-postg... This link could almost be an "Ask HN": if any of you have suggestions to improve my workflow, I'm all ears. (I asked around a bit last May at PGCon, but didn't get any concrete advice there. Maybe it's too complicated for a hallway off-the-cuff discussion.)
- jarek83 3y ago"Don't make me think" has been the best principal of coding for me for a long time. Looking at how much thinking overhead rebase is producing, I'd prefer to avoid it.
- PaulDavisThe1st 3y agoOne day you can suddenly get rebase, and then you almost never need to think about it ever again. Different people take longer/shorter to get to that point, and some people never make it.
- jarek83 3y agoI'm maintaining few projects and had really bad experience with rebase - it's about making sure that everyone in your team does rebase well and according to team rules, but it's just one mistake away to get into some drama, which I had been through few times. Once rebase has been disallowed, I never had to solve similar issues again.
- Tomis02 3y agoI think it applies to using git as a whole. It's best to use a VCS that, instead of making you work, gets out of your way.
- harry_ord 3y agoFirst time I tried that because fixing conflicts in merge was too hard. I rebased the wrong way round. Shared branches is a bit of a faff just due to coordinating.
- WorldMaker 3y ago> It also makes me wonder if there’s an easier workflow for cleaning up your commit history that’s harder to accidentally mess up. Use real merge commits and `--first-parent` as your default view. It's unfortunate that to make `--first-parent` default you have to either edit your git config or grow a few new habits, and I still think there should be at least few more UIs that are focused on `--first-parent` with optional "drill down" instead of raw subway map diagrams. Subway diagrams look cool in screenshots, but so much of the complaints about "clutter" and "mess" in git seem to be just that people don't actually want to read the subway diagrams.
- plasticeagle 3y agoI never rebase, ever. I branch, merge main in regularly, make a PR, squash back to main and delete the branch. Linear history, single commits for a single piece of work. Easy, clear, no fuss.
- deleted 3y ago[deleted]
- andyjohnson0 3y agoLooking at the comments here, it strikes me once again that argung about the best way to use git has quietly replaced arguing about coding conventions :)
- jiehong 3y agoI used to commit and then rebase -i to squash interactively, but I always had troubles with which commit is the oldest vs youngest and wether I need to pick one and squash the rest or squash them all. Now I make a single commit per PR that I commit —amend —no-edit until it’s merged. I sometimes have to rebase it onto main for conflicts but that’s easy.
- nojvek 3y agoSquash merge your PRs if using GH. Gives a nice linear history for each piece of work. Keep PRs small and focused to one kind of change. The PR itself contains full history of subwork. GH can recover branch from PR. No work is lost.
- brainzap 3y agoPlease write the spec for next generation version control. I feel like Git is great but we could have one which is easier to use and has built in concepts like Pull Prequest or deployed state.
- unregistereddev 3y agoThis is a short-sighted view in my opinion. Similar views often lead to reimplementing old bugs, rediscovering hidden requirements, and ultimately re-implementing most of the things that made the old system complicated. We've seen this in npm. Npm was supposed to be simpler than maven - then it slowly rediscovered the reasons we need package signing, support for circular dependencies, and all the other messy things that go into package management. While I don't have numbers, it seems like a huge percentage of the "this problem should be simple, let's build a new app" projects either fail or recreate the same gnarly problems that led the existing projects to be complicated.
- drdaeman 3y agoThere's a plenty of better*-designed systems, problem is no one (except a few opinionated geeks) cares [enough] so they're unlikely to ever beat Git unless a miracle happens (aka a major industry leader will make something trendy by promoting it). For example, Darcs (older) and Pijul (newer) are based on patch theory, so Git's rebase issues are moot there. *) Of course, "better" is subjective.
- Tomis02 3y ago> I feel like Git is great but we could have one which is easier to use FWIW, Mercurial's been there for almost 20 years.
- rstuart4133 3y agoI'm someone who was programming long before CVS was a thing. To me this is akin to a discussion of "1st world problems". We got a remarkable amount of code written without version control, and we saved a lot of time on discussions these. (They seem depressingly common.) That said, I would not be without git now - but it's the cherry on top, not the cake. Perhaps it gives me a different perspective. I'd rate the benefits of version control, in rough order of importance, as: * It allows multiple programmers to work on one body of code. This has always been it's main use. Rebase screws with this because multiple authors updating a rebased branch creates a cluster. The simple fix is rebases to a branch are only allowed when you are the sole person working on it. (Atlassian is wrong. The branch can be public. It's multiple writers that creates the problem, other people reading and reviewing a public branch isn't.) * A backup. I've lost more than enough work to know the importance of backups yet if I have to do it manually I still don't do it regularly enough. git==backup. Wonderful. * Assist in reviews. Actually, I'm not sure how you would do reviews without it, as version control system both highlights the differences and serves as a communication medium. Rebases help here, as they let the author parcel up a body of work to make the reviewers job a lot easier. * Make open source contributions auditable. To be fair I've never used this personally, but I use software that depends on it - like the kernel, so I rank it pretty highly. If becomes very difficult to anonymously introduce malicious changes when the version control system is tracking who made every modification. In an amazing coincidence, a branch is effectively a block chain which makes it hard to change. Rebases could muck this up of course if the "only personal branches may be rebased" rule isn't enforced - but it normally is. * Bug hunting. Blame and bisect are the main tools. In my experience compared to the previous points this gets used very rarely, but bisect in particular can save a lot of time on those rare occasions. Before version control we did bisects using by restoring backups. Notably git blame still works perfectly if you follow the "only rebase branches you own" rule. * Going by the discussion here, some people spend time on archaeological digs through source code repositories. It seems some of them prefer their digs to be dirty (aka rebase free) and others like it clean (rebased). Interestingly, most of the noise here comes from people arguing about the last point. That strikes me as about important as the colour of the bike shed. The only other place rebase effects is reviews. Reviews are a problem everywhere I've worked. Everybody prefers to be doing something else, so making them as friction free as possible is a worthwhile goal. Rebasing does that (and so does unit tests).
- jordigh 3y agoMercurial fixes pretty much all of these problems via changeset evolution: commits are marked as obsolete and the obsolescence marker says which commit replaces the obsolete commit. So you have a meta-graph of commits as they change. You can therefore undo, you can trace the history, and since obsolete commits aren't shared by default, they slowly fade away. https://www.mercurial-scm.org/doc/evolution/ https://www.mercurial-scm.org/doc/evolution/ It's a good idea that's been attempted to be ported into a git https://lwn.net/Articles/914041/ https://lwn.net/Articles/914041/
- 0xbadcafebee 3y agoThe most widely useful method to manage changes in repos is: 1. Open a new branch and do development there. You can rebase and force-push all you want. 2. When ready for review, open a PR of the branch, and never rebase again. 3. On approval, Squash-Merge your PRs and include a merge comment linking to the PR. This way you can "clean up" your development history in your branch, maintain history of changes requested in a PR, the entire development history is available at the PR link later, and you can revert an entire PR by reverting a single commit.
- m000 3y agoother developer: I hate rebase. me: Do you even git bro?
- yxhuvud 3y agoGood list of best practices. I only miss 'git rebase --preserve-merges' from the text. It is pretty nifty sometimes when you actually want the merges to stay around.
- expazl 3y agoAnother great point in this discussion is the page on why fossil deliberately does not have rebase: "Rebase considered Harmful" https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md
- Julesman 3y agoEverything. Everything can go wrong! :)
- qetuo13579 3y agoMy team of hardware and software engineers is relatively new to Git. I’m trying to get them to commit and push small changes daily to a shared personal branch e.g. james-wip instead of one monster commit every 2 or 3 weeks. I encourage them to rebase their “named” personal branches so they’re easier to review and merge into master when they’re ready.