Git Branches for Multi-root Projects

Sometimes there is a need to have multiple Git repositories within a single project. Since long ago IntelliJ IDEA is able to execute many Git operations on all roots at once: Commit, Update Project, Push. Now multi-repository support has come to branches.

In IntelliJ IDEA 11.1 we have implemented two different approaches for multi-root branches.

Most people who use multi-root setup probably have a single repository for project development and several repositories for libraries. They may be included as submodules or just as nested roots, it doesn’t matter for now. For these everything is simple. When you invoke Git Branches popup, you see all branches in the current repository. Other repositories are accessible from the popup as sub-popups with all branches listed there for each repository, with all usual branch actions available for them.

What is the current repository? If you have explicitly selected a file or folder in the Project View or elsewhere, we take the root under which the file is located. Otherwise (if you clicked on the status bar widget or from the main menu) we take the root of the file currently open in the editor.

Synchronous branch control

There is also another case: when users have several repositories in one project that are connected. We at Jetbrains have a configuration like this in one of our projects. There are 3 repositories in a single project, and these repositories are controlled synchronously, i.e. we commit, push and apply other operations to all 3 repositories at once. For such projects IntelliJ IDEA allows to control branches synchronously. It means performing all branch operations on several repositories simultaneously, as it would be a single repository.

When you invoke Git Branches for the first time, IDEA looks at the repositories registered in the project, and if they all are on branches with same names, proposes to control branches synchronously.

If you don’t need it, you may disable it right away or later in the Settings | Version Control | Git | Control branches from different roots synchronously.

If the setting is enabled, all operations on Git branches will be executed for all repositories at once. On the root level of Git Branches popup there will be listed only those local and remote branches which are common for all repositories in the project. Creating new branch from the popup will create it on all repositories, checking out a branch will checkout it on all repositories, etc. This applies to all actions including checkout, merge and delete. Compare just shows the standard dialog with additional selector to choose the root.

You may still control branches individually for each root by using repository selector in the popup. If you happen to checkout a branch only on one of the roots, you’ll get the warning that branches have diverged. Of course, you won’t get this warning if you have disabled synchronous branch control.


There is one more nice feature for synchronous branch management. If you decided to checkout a branch on several roots, and checkout failed for some of them, but has already succeeded for others, you’re in the situation when branches diverge: for example, you are on master in one repository and on feature branch in the other.

To prevent this, the IDE offers to rollback successful checkout. Rollback checkout means just checkout back to the previous branch.

Rollback is offered for checkout, merge and other branch actions.

That’s all about Git branches for today.

We are looking forward for your feedback about the Git branch control interface in IntelliJ IDEA. Your suggestions are welcome. Please submit bug reports directly to our issue tracker.

Comments below can no longer be edited.

20 Responses to Git Branches for Multi-root Projects

  1. Avatar

    Geoffrey De Smet says:

    August 2, 2012

    Very nice, this feature will make me more efficient.
    Will this issue also fix the issue that “Open Github URL in browser” of a selected file does not work for multi-root git projects ( http://youtrack.jetbrains.com/issue/IDEA-67488 )?

  2. Avatar

    Kirill Likhodedov says:

    August 2, 2012

    Unfortunately, this is a separate issue, it will be fixed later.

  3. Avatar

    Gordon Tyler says:

    August 2, 2012

    Synchronous branch control is great! I was wishing for something like that just the other day. 🙂

  4. Avatar

    Xav says:

    August 18, 2012

    Will this feature be available for Mercurial also ?

  5. Avatar

    Kirill Likhodedov says:

    August 20, 2012

    We plan to implement a similar interface for Mercurial, but not immediately.

  6. Avatar

    Xav says:

    September 5, 2012

    It is planned for 12 ?

  7. Avatar

    Kirill Likhodedov says:

    September 6, 2012

    No, unfortunately, such interface for Mercurial is not planned for IntelliJ IDEA 12.

  8. Avatar

    Peter K says:

    April 30, 2013

    Is it possible to save this flag to default to ON when all the repositories are initially checked out from master ??

  9. Avatar

    Kirill Likhodedov says:

    May 2, 2013

    @Peter K
    This is already done. If you haven’t touched the flag manually, when you invoke Git | Branches the first time, it analyzes current branches of your repositories and sets itself to ON, if they all are on the same branch.

  10. Avatar

    Nishant says:

    February 7, 2014

    Is this feature available on webstorm?

    • Avatar

      Kirill Likhodedov says:

      February 12, 2014

      Yes, it is.

  11. Avatar

    Bojan says:

    June 25, 2014

    Is there any specific reason why new branches can be created simultaneously in multiple repositories only when they are all on the same branch name? And than branches are being created on all repos, even those in which modules I didn’t do any changes.

    Am I doing something wrong and there is a way to make new branches only in repositories that have new changes or this is not a possibility yet? If so, is there a plan to implement this option in the future?

    • Avatar

      Kirill Likhodedov says:

      June 26, 2014

      Currently IntelliJ IDEA supports two common workflows: all repositories are independent, and all repositories are synchronised.
      We will probably implement the possibility to switch to some common branch in all repositories even if they have diverged (i.e. are on different branches).

      But synchronous operations with only a subgroup of repositories is not supported, and we are not sure if it is much needed. Could you please share your use case: why do you need to switch branches only in a subset of repositories? do you have a fixed subset of repositories you wish to “synchronize”, or this set is always different?

      • Avatar

        Gustavo Vilera says:

        June 26, 2014

        Hi Kirill,

        I’ll explain you my user-case, as I also would like to have the feature requested by Bojan.

        So… right now, I have a AS3 project with over 10 modules inside… some of the modules are libraries developed my me, others are Applications that partially implement the other modules.

        Let’s say I have 3 App (1 for Web, 1 for smart phones, 1 for Tablets) My other 17 or so modules (in-house developed libraries) are used in the compilation of this 3 Apps, some of them are CORE for all 3 others are exclusive for 1 or 2.

        Some of my 17 in-house developed modules are dependant on another of this modules… So I’ll have the case where Web-App includes ModuleTablets1 which requieres ModuleMobile7 which requieres ModuleCore1.

        NOW!!!… And here is where the magic begins… each of this libraries/modules have their own GIT. The same as the 3 App modules also have.

        So now you start having the picture… When I’m working on an issue that addresses the Tablets, I need to do changes on different modules… and finally I want to commit this changes.

        As it is right now, I have to do this:

        Since I don’t know at the beginning which are all the modules I need to touch until I fix the BUG or I clear a HOT -FIX… I just create a new “Changelist” where I’ll be able to see all changes.
        After I’m finished… I go to my newly created issue-specific “changelist” and see all the modules/repos I touched and go manually to each of them (They are usually at the “dev” branch at this point since I encourage and implement the use of the “Git-flow”) and create a new branch called after the JIRA ID of the issue “BJF-121” on each of them and then commit to them the changes, just before I merge it back to “dev” to start over again.

        After I do this… I wish intelliJ could not only implement the “git-flow”, but most importantly that it would create a new branch on the touched selected repos (or at least the selected ones from my changelist) with the specific issue name, let me comment them all at ones and handle the necessary “git-flow” steps for me to be ready again to continue.

        Also…. Last but DEFINITELY not less important…. (I don’t even know if I should adress this to you guys or to GIT people directly 🙂 But since you are the Amazing tool we use at the office… 😉 )
        I would like that my App repo would somehow pass or commit the states (commit-id) of ALL the repos of the modules (the repos of the repos of the repos of my module ;)) at the time that I pull/push my app commit.

        The issue is obvious, we have core libraries/modules and App modules that are being compiled with together and we don’t know by just pulling one of the repos which changes are required for which change in this dependencies.

        BTW… Any ideas or proposals for a different Workflow are also VERY welcome! If you handle this “Inception” of git repos in a successful way, I would be more than glad to know how!! 😀

        • Avatar

          Kirill Likhodedov says:

          June 27, 2014

          Your workflow looks valid. Let me summarize it in a feature request: http://youtrack.jetbrains.com/issue/IDEA-126654 “Make Git branch operations context aware”. Feel free to comment there if you feel that you need something more or different.

          As about “connecting” repositories – you may want to try Git submodules. They are far from perfect and have many drawbacks, but may suit you. Be warned though that IntelliJ IDEA doesn’t support submodules yet. We plan to fix it in the next release, but you may have problems when using submodules in IDEA 13.1 or previous versions.

          • Avatar

            Eugene says:

            June 27, 2014

            The most up-voted feature request finally coming in idea14! Yay!

  12. Avatar

    Maciej M says:

    July 3, 2014

    Use subtree instead of submodule, git submodules sucks

    • Avatar

      Leroy says:

      October 28, 2015

      I agree, I have experienced a whole world of pain trying to use submodules. If you have a multiuser repo and tend to remove and add repos regularly, you have to issue multiple commands to update any submodules within a repo. Using subtree you only have to issue one. +1 for subtrees… …if only Maven or Git allowed us to update sub-trees (or submodules for that matter) using a single pull method.

  13. Avatar

    Arkadiy Belousov says:

    February 9, 2018

    The option name in the settings changed. It’s no longer “Control branches from different roots synchronously”, it’s “Execute branch operations on all roots”. Could you update the article?

    • Avatar

      Lucas Campelo says:

      August 27, 2018

      Arkadiy Belousov it’s right.

Discover more