Features that facilitate collaboration are one of Magit's weak spots. That is somewhat embarrassing, considering that this is were many other Git tools shine.
The primary reason for this is that I at some point decided to delay implementing such features because I already had enough on my hands and had to draw the line somewhere. It was easy to draw the line here because Magit didn't offer much here to begin with, and because Magit is primarily an interface to Git and Github et al. are not Git. I also put a lot of hope into some of the packages that set out to fill the gap.
But now the time has come for fully integrated collaboration tools. Here's a quick run-down on what I intend to do.
The following two work-flows are currently in widespread use. I won't go into the pros and cons of either. Whatever your preference is, you may be forced to use the other approach to contribute to a particular project.
Web-based and centralized solutions, primarily "git forges" such as Github, Gitlab, and Bitbucket.
Work-flows centered around a mailing-list.
A third alternative does exist, but is not in wide-spread use.
Distributed code review systems.
The idea behind tools like git-appraise is to store code reviews, and possibly issues as well, inside the repository as git objects. I find that idea very appealing, but I think that for most projects this approach is not feasible, mainly because it requires contributors to get familiar with yet another new work-flow and a new tool before even being able to contribute.
So why am I mentioning those three approaches here? And which is Magit going to support? All three!
The title of the preceding section was "Support multiple back-ends/work-flows" and you might have gotten the impression that I was unsure which term was more appropriate and so just used both. But the reason I did it is that I am under the impression that, in this context, most users believe that a certain back-end dictates a certain work-flow, and that's an assumption that I would like Magit to challenge.
As a back-end, a git forge store information about pull-requests and provide a mechanism for transferring them using an api. The pull-request branch and its commits are commonly stored and transferred using git.
A mailing-list is not much more than a transfer mechanism. Everything beyond that are conventions, which may differ between projects. Which means that it is not possible to e.g. simply request a list of pull-requests; instead they have to be somehow identified and then extracted from maildir (or another email format). That may fail and also requires some configuration.
Like forges a distributed code review system (DCRS) stores and transfers pull-request branches using git. Unlike forges it does the same for additional information about pull-requests, such as conversations about them and metadata such as labels.
When using a mailing-lists or a DCRS one basically does everything locally.
When using a DCRS the work-flow is, to some extend, defined by that tool. The drawback is that the tool is required. Unlike for forges there is no simple alternative interface that covers at least the most basic tasks. This unfortunately makes DCRS unsuitable for most projects.
When a projects uses a mailing-list not only for talking about issues but also for submitting patches, then the basic interface essentially consists of the git commands am, imap-send, send-mail, and request-pull.
Those commands are quite appropriate, and I think the primary issue many users are having with them, are that they require some initial setup and that, unless one uses them on a daily basis, using them may very well involve consulting the man pages.
Finally forges. They provide very well defined and simple to use work-flows. But they also enforce them. If you want to do something more complicated or something that just isn't supported, then you have to do so locally. The manual steps required to do so can be quite involved.
Like with a DCRS each repository will contain all the required data. However there will be multiple ways for it to get there, depending on the back-end.
The first transfer mechanism to be implemented will be to import it from a git forge by using its API. Conceptually this will be the same as git fetch and the result is that local git objects are updated, but git isn't used to do it (except for the fetching the actual pull-request branches).
The second transfer mechanism will be to actually git fetch from the canonical repository. Later it should also be possible to do without a canonical repository, at which point we will have implemented a full DCRS.
For project that use a mailing list, it will be possible to manually create a pull-request branch for a particular series of patches found in a mail thread, or to import all pull-request threads at once. So the "fetch" step will be implemented by importing from a local maildir (or other email format) into git.
This will do a bit more than git branch ...; git am .... We also need to save some additional information that will teach e.g. a subsequent magit-push-current-to-pushremote to "push" by sending a new version to the mailing-list.
To take part in the conversation about an issue or a pull-request you will continue to have to use your email client. But basic information about issues and pull-requests will still be imported into git. This will e.g. allow displaying a list of open pull-requests in Magit and you will be able to initiate the process of replying on a pr/issue from Magit. But you will use your email program to actually write and send your reply.
After making local changes, they have to be "pushed". When using the DCRS approach this is literally done by pushing, when using a forge, then some of the information is made accessible to others by using the forge's api.
However, even though this is redundant in most cases data should also be literally pushed when not using the DCRS approach, for the following reasons:
For projects that use a mailing-list, this is the only way to share metadata, such as issue labels, with others. This data will only be available to users of Magit, not all users of the mailing list (and at least initially it will only be displayed inside Magit but not your email program), but this might still be useful.
When using a forge, then that back-end might not support storing all the data we have to store. For example, I think it is highly desirable when doing code review to keep old versions of the pull-request branch as well as the associated conversations easily accessible. Unfortunately at least Github doesn't really do that.
As a backup mechanism.
This leaves a lot of details unanswered. I will study existing DCRS tools to learn from them. However I do not plan to use one of them. I think that would not be appropriate because I don't add a pure DCRS to Magit. Instead Magit will contain a versioned code review system. Eventually one of the supported back-ends will be a DCRS, another will be a versioned but centralized code review system, and the one that will be implemented first and end up being used the most will be the one that uses a forge as back-end.
Wrapping e.g. git-appraise would only make that harder, since it only tries to be a pure DCRS. However learning from it is very important, and we should try to make it compatible by using the same ref names and such.
So far I have said little about the user interface that Magit will provide. I do have mentioned that I would like the interface to be mostly the same regardless of back-end, and that mailing-lists pose some challenges in this regard.
Instead of, or at least before, giving too many details here (which may change), I would like to emphasize one important point: newly added features will be tightly integrated into existing functionality, to the point of them becoming not much more than special cases of features that already exist.
As an example, consider pull-request branches. Magit already supports setting up both the push-remote and upstream when you checkout a branch created by someone else. But only if that branch existed in the origin, e.g. when it was created by someone with commit access.
In the future it will do the same for pull requests. You will be able to see logs of unpushed and unpulled commits right in the status buffer, or push after you made some changes using p p. It will work exactly as for other branches, even though pushing, for example, might actually involve sending emails.
Other features are so obvious that you can just expect them to be implemented. Of course there will be lists of open issues, and the will be implemented using "section inserters" which will allow putting them directly into the status buffer or some dedicated buffer, which ever you prefer. Standard Magit stuff.
If you ever noticed that in a list of submodules you can expand an individual submodule to list the "unpulled" commits in that repository, then you are right to assume that you will be able to do the same for pull-request branches.
And if you ever pressed RET on a list of submodules and were taken to a tabulated-list-mode buffer with additional details, then yes, the same will happen for the list of pull-requests.
Originally this post consisted of the introduction at the top and the following list. I am keeping this list for the time being because most things haven't made it into the above description yet.
git fetch.branch.pushRemote).master being the most likely one. Conflicts will likely cause some lose of functionality, more specifically there won't be a branch.pushRemote`remote.fetch accordingly.branch.<name>.pr.refs/heads/, refs/pr/<pr>/<version> maybe?pull_request webhook and will have to suffer.refs/heads/ without Github zapping them?git-commit-mode, the major mode would be markdown-mode obviously.tabulated-list-mode.tabulated-list-mode.bug-reference package. #2949name or user/name can be used to specify remote instead of url.origin for a fork.If something essential is missing from the above list, then fear not. It isn't complete. I do intend to make it possible to do everything in Emacs that can be done in the browser. Just more comfortably and integrated with the tool you already use to create and store the changes ;-) But yes, it will take a while until we get there.
Also I won't implementing as many features as quickly as possible but concentrate on getting the core infrastructure right. A solid, easy to configure, authentication method will come first. Some of the features mentioned above are already implemented by some existing package. Checkout this list. I would also like to encourage the authors of these packages to continue their work. Some competition won't hurt. Of course you are also welcome to "rebase" your package onto Magit, once I am done with the ground work. Either as part of Magit or an extension. Or not at all, that is perfectly fine too.
However there is one thing that I hope we can all agree on after some discussion: how we store credentials, see #2973.
You do not mention Gerrit above, not sure whether that is a gitforge or a DCRS or a mix of both.
Some projects use patchwork (http://jk.ozlabs.org/projects/patchwork/) as a complement to mailing lists.
It would be good if the design is aware of these tools so it is possible to write backends for them.
Some other relevant tools and discussions:
Some only marginally related tools and discussions:
Some ideas that have come up along the way:
After reading more about these tools, you might be wondering, why not just adopt one of them? Well, I might, but what I am currently envisioning is both less and more portable.
It would be limited to Magit users, since it isn't just a wrapper around some tool that can also be used by itself.
At the same time nobody would actually have to use it, non-Emacs users could continue to use the webinterface provided by Github/Bitbucket/... and would never have to know that you are using something else. (Except if a project goes with the fully distributed back-end.)
A major benefit of that approach would be that you could use it with any project, even when project actually uses some web- or mail-based approach. org-sync appears to follow that approach too, so I might adapt that.
I'm really excited abut this one! Being able to do code review in emacs will be a massive improvement to my workflow.
I once tried to hack a pull request commenting interface onto https://github.com/sigma/magit-gh-pulls, so I'd love to be able to do code review within Emacs! It'd be much faster with big PRs which would be awesome.
this might not be the right issue for this suggestion, but here goes.
motivation:
https://twitter.com/devonzuegel/status/946490569374625792
proposal:
M-x magit-url-for-current-location constructs a URL to the current repo/branch/file/line in the back-end web service, typically Github.
By default it saves the URL to the kill ring and places it in the system copy buffer. With a C-u argument, it calls browse-url upon the URL as well.
For that feature, https://github.com/rmuslimov/browse-at-remote works really well in my experience.
FYI, I've been using https://github.com/sshaw/git-link, which basically does the same.
Also on that list is: https://github.com/osener/github-browse-file, nice to know there are several!
Found an interesting article today via reddit that may provide some about of inspiration: https://blog.janestreet.com/putting-the-i-back-in-ide-towards-a-github-explorer/
And this is my response on that reddit thread: https://www.reddit.com/r/emacs/comments/88b51s/putting_the_i_back_in_ide_jane_sts_emacsbased/dwkwcg9/.
And since I am in the mood for creating quick drafts I have also created one with basic browse-url support: https://github.com/magit/magit/pull/3408.
I feel like for completeness someone should mention here your forge package, which is at least a start along these lines...
Most helpful comment
I'm really excited abut this one! Being able to do code review in emacs will be a massive improvement to my workflow.