A better pull request
developer.atlassian.com
developer.atlassian.com
For the past couple of years I've only used GitHub's web-based PR tool for code discussion/peer review. Don't ever click that "merge" button.
Another reason I hate the merge button: It creates an extra commit solely for the merge.
Please let that sink in. Nobody ever tested the diff that this is going to be showing to the user.
I'd rather see the diff that's going to go into master (tested or not) than see a diff that effectively means nothing (as it will never be applied to anything).
c3ca093c99495d0ddbb3197c14e0cdf514266392 refs/pull/2/head 0f5993828108bd2960713dc34a9ac7bef6dbc653 refs/pull/2/merge
one is the head of the pull request, the other is the result of the merge that you will end up with. Though I'm not sure Github will trigger another build when the target branch moves.
That doesn't preclude running e.g. travis to get the branch's own status before the review happens.
https://bitbucket.org/tpettersen/abpr/pull-request/2/fixed-a...
EDIT: currently I always rebase our feature branches before submitting the PR to try and mitigate this and make sure review happens quickly after that. it doesn't fully solve the problem but it's the best flow I've found.
The GUIs by nature hide detail: the pull request becomes a thing to be "displayed" instead of "explored". It's a problem that requires careful attention to detail. I don't know that I actually disagree with Atlassian's decision, but the fact that it had to be made isn't evidence that it's the "right" solution either.
I rebase after the PR has been discussed and "approved" for merging. I feel having the individual commits during discussion time are useful for context, so long as team members are earnest enough to use them. Usually good commit messages can answer every "Why did you do it this way?" question before it even gets asked.
The best way to avoid this issue is automated testing. The second best way is to crack open the file itself, and review the entirety of any functions that changed. Even that approach assumes your encapsulation is nice and you're not introducing issues based on global state though.
While the BitBucket diff is better than nothing (and better than GitHub/GitLab), it's not sufficient to avoid these kinds of issues entirely.
Theoretically possible, Probability < 3%. Besides, if master has tests and your branch has a test for the branch's feature, and you still have this problem, then maybe the 2 developers are overlapping so much that they should pair.
The merge commit is the quickest way to see all the changes that came in from a branch, and if you do branching right, all the changes related to a particular feature by one developer.
Also, merge commits are much easier to roll back, no matter how rarely you need it.
We are on GH, it's quite annoying that they provide 0 support for rebase/squash style PR application. http://stackoverflow.com/q/27974175/1366219
If you squash all the commits you probably should summarize all the commits into that single commit message which is also work if done properly.
In the end it's preference and how your developers create commits and documment them.
Is the issue that the button knows if a pull will merge ok, because it does test on current master, but the diff shown in the UI is different from that, and not on current master, and just on the older commit? If so, I think this could have been clarified better in the post.
Even so, this means that sometimes the button should be red - can't merge, has conflicts - while the diff as shown looks fine. I've never seen that happen. So something is puzzling here.
To answer your earlier question more directly: the diff that is shown is a diff against an earlier master. (It's in fact a diff against the point where the branch forked off of master.)
But the point of the article is that the context shown in the files (diff) view on github is that of the common ancestor, and doesn't include later changes to the branch being merged into. In addition to not showing merge conflicts if they exist (even though it disables the merge button), it also hides logic conflicts. These are situations where a clean automatic merge is possible, but the result will be incorrect logic due to the slightly distant interaction of those not-shown later changes. The simplest example of this was in the blog post.
All that said, even the bitbucket diff view doesn't show you logic conflicts caused by changes in completely different files, or otherwise more-distant. Nothing really does, it would be too much.
So, in an ideal world, you thoroughly test the merged result (in addition to the feature branch itself) before actually merging into the upstream branch.
git fetch origin +refs/pull/$N/merge && git checkout FETCH_HEAD
However, in my experience I have seen both cases where GitHub makes new merge commits when the receiving branch changes (current master) and where it does not. Due to externalities in our test suite we sometimes have "current master" break and when we push a fix we sometimes see PRs go green and sometimes they do not. I haven't figured out why we see the two different behaviors.
Of course, it's not too hard for the person responsible for merging the pull request to replicate this themselves (branch off master, merge in feature branch, run tests).
(BTW, we love GitLab, congrats on the new UI layout, which has rave reviews coming back to me mere hours after the upgrade)
https://bitbucket.org/site/master/issue/2874/ability-to-sear...
The gamification and awkward "social coding" environment that GitHub provides just feels forced to me. It's distracting from your work and it makes you focus on pointless minutiae, but worse - it makes other people apply unnecessary weight on the significance of how "active" and "competitive" your profile is. Look at all the people who legitimately believe GitHub should be the be-all-end-all spot for software development, replacing your resume. Look at how Git the DVCS is becoming synonymous with GitHub the (centralized) platform.
With Bitbucket, I have none of that. I can focus on my project without any intervention from the peanut gallery, without all the pointless competition and addictive side jobs that GitHub conditions you into partaking in.
Also, I always found GitHub's issue tracker to be rather underdeveloped. I think it speaks about the "quick hack" culture of software development in general.
Oh, and I think Mercurial needs more attention. I use both hg and git.
I like git well enough. Github seems nice. What is this gamification of which you speak? I'm not saying that it isn't staring me in the face, but I'm probably looking right past it.
Code search is one, but I also find it harder to get to the exact diff or pull request that I want. I don't get Github's nice rendering of filetypes like STLs, and there's a lot less of the context-sensitive popups when you're mentioning users, issues, commits, etc.
Bitbucket's issue tracker is kind of limited from ever getting too good, because it's really just there as a teaser for JIRA.
[0] i.e. looks like http://blog.carbonfive.com/wp-content/uploads/2010/12/multip...
Personally I think, rebase + auto-squash/auto-fixit makes the history a lot easier when it's time to look back. It just happens so rarely I wonder if it's really worth the effort I expend on it.
Anyway, now I just don't do it anymore. Git is a pain in the ass.
I am curious what you use as an alternative.
About rebasing the feature branch onto master, my team doesn't do that, we squash the feature branch commits into one commit when merging to master.
(I don't use anything besides git, but that doesn't mean I can't hate it)
Now, it could be that I am just being a stickler for phrasing here. So, to clarify, if you are on the branch and run 'git rebase master', that is not rebasing master into the feature branch. That is rebasing the feature branch onto master.
So, is that what you were doing?
I can say that it is easy, once you understand it more. It will take some time.
Countering that point, though; if you have a codebase that is rapidly changing at all times... there really isn't anything git can do to help.
My teammates have suggested to simply merge master into the branch so I do that now. It adds a commit to the branch, but Github is smart enough not to litter up the PR diff with the merge commit.
Our codebase doesn't change that much, every commit to master has to go through a PR and get approved. So fortunately we don't have to contend with that.
That said, I will also say that any worries about having merge commits in the history should largely be overcome. They actually provide useful information and are easy to ignore if you want.
I have noticed that among people I respect, there is a strong correlation between using git-bisect and wanting a clean history.
The rebase strategy and merge strategy both have their places - neither is fit for "whenever we do a pull request" for all people everywhere.
I think rebasing is a good idea anyway, but it's a tradeoff.
Small issues can slip through, but on teams I've worked on, submitting a PR that is truly broken is really bad form. Sometimes that does mean submitting PRs is tedious, but that's just how it goes sometimes. Thankfully, it's not that often in my experience.
git config --global merge.conflictstyle diff3
http://gitster.livejournal.com/25801.htmlHaving used both GitHub and Stash, the difference in focus between the two companies comes across plainly, and these two blog posts only back it up.
[1]: https://github.com/blog/1943-how-to-write-the-perfect-pull-r...
In the case of Atlassian's solution, the "merged" social convention will have to be use to first use and personally verify the "triple dot" findings in order to review that the change to the branch is, in isolation, as expected - before proceeding through the "double dot" flow that now characterizes the pull request feature.
For Github, it's simply the inverse.
Either way, both are relatively easy to achieve with the command line or a diff tool like Meld or LiClipse.
If your decision about where to host your code repos is decided by how pretty the webpage to create pull-requests is, the wrong people are making decisions such in your business.
Having said all that, I'm currently using bitbucket for a private work repo because I'm cheap :)
The more GitHub seems to adjust itself, the less I enjoy it. The more BitBucket seems to try to copy GitHub, the less I enjoy it. At the end of the day, I probably want GitHub circa 2008. I find when they really became opinionated about things to be the inflection point about whether they pushed things that were truly more usable.
That's not to say your view of things is wrong for you. But I don't think it's clear that "in this case, it definitely bears out".
I want it too :) A time-machine style forward & back, showing changes to a file.
i.e. whether the gui is well designed.
When we were making the decision at my company, we went with Github because the dev team cared about having the little green squares show up on the "activity" chart for their account's... I know, petty, but it's something, and since most of us do FOSS projects, it's a status thing.
It used to be any commit that made it into a repo's master branch, the green squares showed up, even if it was a private repo (it just didn't show details of the repo to public users). But now, those don't show up to the public, only the user themselves sees them while logged in... so if we were making the decision today, I'd probably lean towards Bitbucket.
Just to clarify, GH's pricing doesn't actually grow exponentially. The per repo price gets lower the more you pay for:
5 private repos: $7
10 private repos: $12
20 private repos: $22
50 private repos: $50
For an internal-dev team which generates a great deal of new repos throughout the year (one-off scripts/programs for different departments, etc...), this adds up very quickly.
If you reach that 126th repo, it jumps to $450 monthly or $5,400 a year. At those prices you get questions from Accounting about why we aren't hosting this internally...
On the other hand, GitHub's stuff generally does feel nicer to use and better and more thoughtfully UX'd.
I assume it has some features that are paid (or only work with Bitbucket?), but I've found it brilliant for managing GH repos - one of the nicest free tools I use.
We have a little over a hundred repositories. This puts is in the $200/mo plan for GitHub (125 repository limit).
Atlassian prices per-user. Our small three person dev team costs us nothing. We'll reach the next pricing tier when we hit our 6th developer, at which point it will cost us $10/mo and will remain that cost up to 10 developers.
BitBucket's top plan is $200/mo. That gets you unlimited repositories and users compared to GitHub's 125 repositories.
In the middle tier, GitHub charges $50/mo for 20 repositories whereas BitBucket charges $50/mo for 50 users.
If you have few repositories but many users, GitHub's pricing is advantageous. If you have many repositories but few users, BitBucket makes way more sense.
WHY? Free private repos unlimited in number of repos only limited on how many can access them.
So all my .config files and anything private goes to BitBucket. Great product for my own use.
Assuming it’s for redundancy, why not just copy the folders as part of a normal backup?
You mean the version control system would be... distributed!?
My money would be on Dropbox busting your repo somehow. I don't think Dropbox is an ideal solution for pushing/pulling git repos from.
What is it telling us of? Are you implying something to the effect of Atlassian doesn't care about people working together (heck, maybe they hate humans, who knows) and Github loves community...?
$ git ls-remote
From https://github.com/cyaninc/git-fat.git
4c86c39bb5fca55a692d11680ed62fd5cb183921 refs/pull/14/head
cb850f9d0bd09f8bb903e1c5959cef24ceb51695 refs/pull/14/merge
The merge ref is what the code would be if you merged it.The merge button is only green if github could generate a merge commit, and that merge commit is made available. You can run your tests on either the branch before merge or the branch after merge, as you prefer.
You may want to do both and have the former block the latter: the merged head is going to change (and require a re-test) any time the target branch gets a new commit, no point in wasting cycle if the branch's own tests don't pass in the first place.
Otherwise, merges really are better from most perspectives. I can trust people doing pull requests to have tested their code. Looking at the log, I can get an idea of whether or not their code was tested with someone elses. Something I can not do with a pure "rebase and push" mentality.
Phabricator uses light colors to show changes not introduced in this patch but a rebase against master [1]. The experience is pretty good if the workflow is to always fast-forward and the patch author does rebase. Changes introduced by other people are in light green and red. Duplicated-line issue can be obviously seen.
[1]: https://secure.phabricator.com/book/phabricator/article/diff...
Showing merge conflicts inline like that is pretty cool, though.
The diff that bitbucket is showing you is one that has not been tested. That is, the diff against the merge base shows what the requester did and tested. The diff against the current tip, shows what will be the result.
I fully agree that it is important to bear that in mind. But, this is all the more reason for the merge to be done by another party before committing/pushing.
Consider, if you send a pull request for the kernel, Linus will do a local merge, then test, then push. In all of these gui apps, the final merged code is just there. No last second "fails sanity test, so not really going to merge."
It seems to me that this is the safest method as, when you add an automated testing tool to the mix, it's pretty much guaranteed that you cannot break the main branch when merging a PR.
I think rebase is not advertised enough, but it's the _de facto_ solution to most of these kinds of problems.
If it fails that test, then you push it back to the person doing the work saying so and they need to fix it.
I haven't been a committer on any other large GitHub projects, so I'm not sure how common this is.
It would seem to me that if a branch diffs against an older point in master, then the PR should be rejected as not properly tested. Merging into master should never create a merge conflict; the merge conflict should happen and be resolved on the feature branch first.
Or what am I missing?
With the Bitbucket approach, you get to see the conflict in the pull request UI, but you should still resolve it locally on your branch before merging to master.
The linux kernel averages >5 patches per hour. Even with multi-teired maintanership, good luck getting everyone to base their patch sets on the latest upstream head.
I know nobody other than the kernel actually uses git as a distributed system, but there are use cases where your ideal workflow can't actually exist.
Odd that they never mention this in the post, I was under the assumption that rebasing before creating the PR is standard practice, at least that's how we do it at work and on all the projects I've contributed to.
EDIT: I've never used bitbucket, so maybe this is just a github community thing with the rebasing?
I would think that in larger projects a better practice would be a distributed hierarchy of merges until a PR finally got submitted to master, not a massive blob of just send everything to master as a PR and let various maintainers merge whatever at will.
Shouldn't that take care of logic bugs?
Now, sure, you can say "well, God can get around that", but, unfortunately, there are real constraints that cannot be gotten around. Good design is how you deal with those constraints.
Jira is almost OK, but still has that enterprise stank of trying to do too much and inserting itself too much in your workflow, instead of helping you and getting out of your way. Some people are less generous toward Jira than I am: "Next time I'm looking for a job I think use of @jira might be a deal breaker."--Peter Seibel[1].
I have no generosity toward Confluence, their wiki. Bad UI choices, a weird & inconsistent markup language that again becomes another thing to wrestle with indefinitely instead of unobtrusively helping you. I've had to use it at two jobs, and there won't be a third.
Bamboo, their CI system, seems OK, but for some reason I end up debugging a lot of build failures having to do with leftover or broken state on the build machine, which seems like one of the first things a CI system should help you avoid.
[1]https://twitter.com/peterseibel/status/451758184470835200