7 ms·
Merging vs. Rebasing
- leekh 10y agorebase for lyfe! Just don't force push on master.
- hashkb 10y agoI force push master when I know it's safe. If you aren't confident, don't do it. Don't piss off your coworkers. But this dogma is ridiculous.
- epmatsw 10y agoBut how can you know it's safe in a collaborative project? What if someone else merges a PR right before you push?
- sdegutis 10y ago1. Rebase onto master. 2. Pull master just before you push. 3. If there are new commits, rebase onto master again. If everyone on the team follows these 3 rules, it won't get too messy to untangle.
- realbarack 10y agoUnless I'm missing something, there's a race condition between "check if there are new commits to pull before force pushing" and "new commits come in". This workflow might work for a very small team but for a larger team it is bound to cause problems.
- reubano 10y agoHe may have editted his comment, but it doesnt mention `force`. As written, there is no race condition.
- to3m 10y agoBluff ;) - tell them they did something wrong. It's their fault. They don't know how to use git. There's an xkcd about this I think.
- TheCoelacanth 10y ago--force-with-lease instead of --force. It does the same thing as force but checks to make sure the branch hasn't changed since you fetched it. Still very likely to piss off your co-workers, though.
- hashkb 10y agoThis.
- abrezas 10y agoThe problem is not if someone merges a PR before you push, but if someone branches off of the current tip of master, works on it, you remove that tip, and your colleague now is based on a history that doesn't exist, has to resolve your conflicts.
- hashkb 10y agoThey're the same conflicts they'd have to fix if I pushed a new commit or merged a PR; assuming I made the same changes to code when I force pushed.
- hashkb 10y agoYou can use chat. Say "@channel I need to fix to master, nobody merge for a minute".
- juandazapata 10y ago`git push --force-with-lease`
- hashkb 10y agoThis article has been written a million times already. It's another holy war. Vim, spaces, rebase. The sad part is that IMO merge people are on that side because they are afraid of rebase or don't understand it.
- wwalser 10y agoTeaching anything has to be done many times. Depending on the audience the degree of specificity that one goes into while teaching is variable. I personally read this as an attempt to teach and that teaching to be directed at newcomers to git. Nothing more. Anyone reading something like this as a newcomer is free to go on to become an expert and for their own opinions and practices. For an experienced practitioner to read a "Tutorial" and deem it dogmatic because it doesn't adhere to their specific and experienced approach ignores the fact that the practitioner has the benefit of significant experience that a new learner does not.
- elsurudo 10y ago> The sad part is that IMO merge people are on that side because they are afraid of rebase or don't understand it. Not necessarily. I understand rebase, but it is often a much more complex operation than a marge, and for (often) little gain (cleaner log). So it's a tradeoff. When the team is small enough that log pollution isn't too much of an issue, it's not worth rebasing, IMO.
- hashkb 10y agoWith all respect, I disagree. For me rebase has identical difficulty but more flexibility. You could call that "much more complex" and I can call it "just as easy but way more powerful" and we'd both be right, I suppose. I use the rebase flow on my solo projects as well as advocate for it on large teams. Even (especially) when it's just me, having a tidy history saves me tons of time; especially when I'm prone to constant distraction by business-y things. Edit: s/I/I'm/
- tapan_k 10y agoWhy is this downvoted? (serious question) Where can I find the "code of conduct" for HN?
- epmatsw 10y agoNot sure how I feel about the not rebasing PRs rule, especially with CI on PRs becoming more common. I'd much rather have a PR get rebased than have an extra "Fix whitespace to satisfy linter" commit.
- wwalser 10y agoIt says to merge PRs but also mentions that rebasing the branch being pulled first is a good practice. This would be a fast forward merge, effectively serving the same purpose as a rebase, no? As for the example of a "linter" commit, I feel that lends itself more naturally to teaching git commit, git commit --amend, or rewriting history. Which the OP is not about.
- barrkel 10y agoClean project history is overrated. If you work on a sizeable team with code review before merge workflow, the tip of the repository will be moving faster than is pleasant or safe to rebase, and every so often, commits will exist in multiple different branches (in order to prevent blocking development pending a code review). You do not want to be rebasing commits such that they appear in multiple different branches with different hashes etc. It's a recipe for pain. And being blocked until code is reviewed and merged is hardly more productive. Even working like this, git bisect works just as well to find a commit, and git log on an individual file works just as poorly as it always does (e.g. changes in merge conflict resolution are hidden by default). Rebase if the commits only exist in your local repo. That's fine. But no more.
- sytse 10y agoI totally agree. I think your code should be clean and your history should be accurate. I think as developers we're very focussed on writing clean code and documentation. We should try to write clear commit messages that relay the intention. But we shouldn't worry about adding one more commit if it makes the code better. I wrote about it in detail in http://docs.gitlab.com/ce/workflow/gitlab_flow.html#squashing-commits-with-rebase http://docs.gitlab.com/ce/workflow/gitlab_flow.html#squashin... Of course rebasing is fine if you have not pushed your branch yet. BTW some teams do prefer a rebase workflow and we want to support them in GitLab too, showing a diff with the changes in an MR if the commit was overwritten
- sdegutis 10y ago> Clean project history is overrated. I go back and forth on this issue. On one hand, I like having commits that do one thing. Makes it easier to "read" a project's history, to revert things, to track down bug introductions. On the other hand, I like having a history of the mess of how I actually implemented something, because it's more accurate and more detailed, both of which help when I go all DETECTIVE-MODE: ACTIVATE. But on the other hand, the mess often includes such uselessly awful commit messages, and lots of terrible code that only existed for like 2 hours until I realized it was the wrong way to do it, and scrapped it. That's kind of a red earring. So I don't really have a firm opinion on it anymore. I just go with whatever I feel that day. That said, I'm a team of 1 and have been for about 4 years, so it doesn't matter too much in my case.
- jcoder 10y agoRebasing isn't just about a clean project history, IMO. I'd much rather find out about a merge conflict I've created when applying a small commit to the tip of master, than when smashing two development histories together.
- Freak_NL 10y agoAbsolutely. I can do without the monster-merge-from-hell (been there, done that). When rebasing is part of the established workflow, developers can rebase their feature-branches to be up-to-date with master when the time comes to offer it as a merge request (and solve any conflicts there with local knowledge of the branch). When developers are comfortable with rebasing, it is also easier to stimulate cleaning up the branch before offering it for inclusion by using interactive rebase to squash commits and edit commit messages.
- t1amat 10y agoThere is nothing stopping you from merging the mainline history into your feature branch to pull in the latest changes. In fact you should be doing this every-so-often for any long-lived feature branch, but always before merging into the mainline.
- jcoder 10y agoI do integrate every so often. By fetching master and rebasing on it ;)
- mcguire 10y agoNote: if you want to bring upstream changes into your fork, as in [1], use a rebase instead of a merge. Otherwise, you will be fighting with merge commits from now on. [1] https://help.github.com/articles/syncing-a-fork/ https://help.github.com/articles/syncing-a-fork/
- dahart 10y agoI quite like that this outlines the benefits of both non-judgementally, and provides guidelines about when to use each in different situations. I've seen too many discussions where people argue that one is better than the other, when as I see it, they are two different tools and they both have legitimate uses. There's a little overlap, a few cases where your own preferences can allow you to choose freely, but by and large they don't really contend with each other. You can largely have a clean and accurate history and a feature branch workflow with PRs, while using both rebasing and merging.
- VoiceOfWisdom 10y agoWe've started using mercurial evolve at my company. It feels like the best of both worlds. I can rebase and get all the nice clean history I want, but under the hood the original work is still there. It also allows for safely editing public history, without getting into a weird state where you edited a commit that someone else committed on top of.
- aokyler 10y agoWhere I work we merge with the no fast forward option - this keeps an accurate git feature topology where merges are represented as their own commit. We've found it gives us the best of best worlds: adding clarity/readability to the history while avoiding problematic rebases. I haven't personally really noticed any downsides with that approach, can anyone else think of any?
- breatheoften 10y agoFor our (smallish, fast moving) team we disabled history rewrites on all branches on the server, have all the developers manage their git workflow using the (very awesome) osx app called gitup, and have everybody rebase and resolve conflicts before pushing. We always rebase and only merge in unusual circumstances where preserving the merge conflict resolution decisions might make sense (which almost never occurs). Everybody on our team including very junior developers and designers are able to quickly pick up this workflow and almost never have problems - and when they do it's always obvious that they should get help from someone -- and typically this is exactly the scenario where some analysis is needed -- so its a good use of time for a second pair of eyes.
- vkjv 10y agoI'd be interested to know how this scales on a larger team. Looking at the number of open PRs on some of our repos, I would guess doing this in a larger organization would cause an unnecessary amount of busy work when everyone scrambles to rebase after each merge.
- breatheoften 10y agoI think it would scale pretty far based on my experience with the process on our team. I'd see more blockers to scaling team size coming more from other factors rather than the merge strategy -- things like the quality of tests and probability of problematic merge conflicts -- which I think would depend ultimately more on the code organization/team-member communication than the merge strategy. I think Facebook uses a souped up version of this strategy (based on how I interpret their presentation on it anyway). It seems like the engineer ships off a commit, and then it goes into a review branch where it gets automatically rebased against master continuously while waiting for review. When it passes review it goes onto master as the newest commit -- if a conflict happens before the review completes or during the final rebase then the engineer is notified to resolve the conflict and push again -- I think review needs to happen again in this case -- but it makes sense to do so as the first review was done without awareness of the change that caused the conflict ... I'm sure I don't describe their actual process accurately but I think it something along these lines ...
- kentosi 10y agoDid anyone else to the following when they were new to git and had to rebase? 1 - Rebase. If no conflicts, great! otherwise, 2 - Abort rebase and merge. :-) When I started using git I remembered feeling overwhelmed by rebase because with a merge you only resolved conflicts once, whereas with a rebase you had to continually fix conflicts without knowing when it would end. It took me a while to finally understand how rebase properly worked and I can finally use it correctly now.